mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-4295: Fix plot column range. Prohibit nav to future.
This commit is contained in:
parent
0820d96ec4
commit
9cc9659817
7 changed files with 99 additions and 6 deletions
|
@ -48,6 +48,7 @@ public abstract class AbstractQueryTableModel<T> extends ThreadedTableModel<T, T
|
|||
}
|
||||
|
||||
protected void objectRestored(DomainObjectChangeRecord record) {
|
||||
AbstractQueryTableModel.this.maxSnapChanged();
|
||||
reload();
|
||||
}
|
||||
|
||||
|
|
|
@ -273,9 +273,14 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
|||
|
||||
private final SeekListener seekListener = pos -> {
|
||||
long snap = Math.round(pos);
|
||||
if (current.getTrace() == null || snap < 0) {
|
||||
if (snap < 0) {
|
||||
snap = 0;
|
||||
}
|
||||
long max =
|
||||
current.getTrace() == null ? 0 : current.getTrace().getTimeManager().getMaxSnap();
|
||||
if (snap > max) {
|
||||
snap = max;
|
||||
}
|
||||
traceManager.activateSnap(snap);
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.app.plugin.core.debug.gui.model.columns;
|
|||
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener;
|
||||
import generic.Span;
|
||||
import generic.Span.SpanSet;
|
||||
import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow;
|
||||
import ghidra.docking.settings.Settings;
|
||||
|
@ -59,6 +60,10 @@ public class TraceValueLifePlotColumn
|
|||
headerRenderer.setFullRange(fullRange);
|
||||
}
|
||||
|
||||
public Span<Long, ?> getFullRange() {
|
||||
return cellRenderer.getFullRange();
|
||||
}
|
||||
|
||||
public void setSnap(long snap) {
|
||||
headerRenderer.setCursorPosition(snap);
|
||||
}
|
||||
|
|
|
@ -274,9 +274,14 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
|||
|
||||
headerRenderer.addSeekListener(seekListener = pos -> {
|
||||
long snap = Math.round(pos);
|
||||
if (current.getTrace() == null || snap < 0) {
|
||||
if (snap < 0) {
|
||||
snap = 0;
|
||||
}
|
||||
long max =
|
||||
current.getTrace() == null ? 0 : current.getTrace().getTimeManager().getMaxSnap();
|
||||
if (snap > max) {
|
||||
snap = max;
|
||||
}
|
||||
traceManager.activateSnap(snap);
|
||||
myActionContext = new DebuggerSnapActionContext(current.getTrace(), snap);
|
||||
provider.legacyThreadsPanelContextChanged();
|
||||
|
|
|
@ -170,9 +170,14 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
|||
|
||||
private final SeekListener seekListener = pos -> {
|
||||
long snap = Math.round(pos);
|
||||
if (current.getTrace() == null || snap < 0) {
|
||||
if (snap < 0) {
|
||||
snap = 0;
|
||||
}
|
||||
long max =
|
||||
current.getTrace() == null ? 0 : current.getTrace().getTimeManager().getMaxSnap();
|
||||
if (snap > max) {
|
||||
snap = max;
|
||||
}
|
||||
traceManager.activateSnap(snap);
|
||||
};
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.*;
|
||||
|
||||
import org.jdom.JDOMException;
|
||||
import org.junit.*;
|
||||
|
@ -36,6 +36,7 @@ import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.PrimitiveRow;
|
|||
import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow;
|
||||
import ghidra.app.plugin.core.debug.gui.model.ObjectTreeModel.AbstractNode;
|
||||
import ghidra.app.plugin.core.debug.gui.model.PathTableModel.PathRow;
|
||||
import ghidra.app.plugin.core.debug.gui.model.columns.TraceValueLifePlotColumn;
|
||||
import ghidra.app.plugin.core.debug.gui.model.columns.TraceValueValColumn;
|
||||
import ghidra.dbg.target.TargetEventScope;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
|
@ -1162,4 +1163,75 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
|||
waitForPass(() -> assertEquals(14,
|
||||
modelProvider.elementsTablePanel.tableModel.getModelData().size()));
|
||||
}
|
||||
|
||||
protected Stream<DynamicTableColumn<?, ?, ?>> streamColumns(
|
||||
GDynamicColumnTableModel<?, ?> model) {
|
||||
return IntStream.range(0, model.getColumnCount()).mapToObj(model::getColumn);
|
||||
}
|
||||
|
||||
protected <T extends DynamicTableColumn<?, ?, ?>> T findColumnOfType(
|
||||
GDynamicColumnTableModel<?, ?> model, Class<T> type) {
|
||||
return streamColumns(model)
|
||||
.flatMap(c -> type.isInstance(c) ? Stream.of(type.cast(c)) : Stream.of())
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifePlotColumnFitsSnapshotsOnActivate() throws Throwable {
|
||||
TraceValueLifePlotColumn plotCol = findColumnOfType(
|
||||
modelProvider.elementsTablePanel.tableModel, TraceValueLifePlotColumn.class);
|
||||
createTraceAndPopulateObjects();
|
||||
|
||||
traceManager.activateTrace(tb.trace);
|
||||
waitForSwing();
|
||||
|
||||
// NB. The plot adds a margin of 1
|
||||
assertEquals(Lifespan.span(0, 21), plotCol.getFullRange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifePlotColumnFitsSnapshotsOnAddSnapshot() throws Throwable {
|
||||
TraceValueLifePlotColumn plotCol = findColumnOfType(
|
||||
modelProvider.elementsTablePanel.tableModel, TraceValueLifePlotColumn.class);
|
||||
createTraceAndPopulateObjects();
|
||||
|
||||
traceManager.activateTrace(tb.trace);
|
||||
waitForSwing();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getTimeManager().getSnapshot(30, true);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
|
||||
// NB. The plot adds a margin of 1
|
||||
assertEquals(Lifespan.span(0, 31), plotCol.getFullRange());
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getTimeManager().getSnapshot(31, true);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
|
||||
assertEquals(Lifespan.span(0, 32), plotCol.getFullRange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifePlotColumnFitsSnapshotsOnAddSnapshotSupressEvents() throws Throwable {
|
||||
TraceValueLifePlotColumn plotCol = findColumnOfType(
|
||||
modelProvider.elementsTablePanel.tableModel, TraceValueLifePlotColumn.class);
|
||||
createTraceAndPopulateObjects();
|
||||
|
||||
traceManager.activateTrace(tb.trace);
|
||||
waitForSwing();
|
||||
|
||||
tb.trace.setEventsEnabled(false);
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getTimeManager().getSnapshot(30, true);
|
||||
}
|
||||
tb.trace.setEventsEnabled(true);
|
||||
waitForDomainObject(tb.trace);
|
||||
|
||||
// NB. The plot adds a margin of 1
|
||||
assertEquals(Lifespan.span(0, 31), plotCol.getFullRange());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ public class RangeCursorTableHeaderRenderer<N extends Number & Comparable<N>>
|
|||
if ((e.getButton() != MouseEvent.BUTTON1)) {
|
||||
return;
|
||||
}
|
||||
doSeek(e);
|
||||
e.consume();
|
||||
doSeek(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,8 +53,8 @@ public class RangeCursorTableHeaderRenderer<N extends Number & Comparable<N>>
|
|||
if ((e.getModifiersEx() & (onmask | offmask)) != onmask) {
|
||||
return;
|
||||
}
|
||||
doSeek(e);
|
||||
e.consume();
|
||||
doSeek(e);
|
||||
}
|
||||
|
||||
protected void doSeek(MouseEvent e) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue