mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-18 00:20:10 +00:00
Merge remote-tracking branch 'origin/GT_153_ghidravore_changing_graph_api--SQUASHED' into Ghidra_9.2
This commit is contained in:
commit
14d7e1f908
@ -15,8 +15,7 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.graph;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import docking.widgets.EventTrigger;
|
||||
@ -29,8 +28,7 @@ import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.service.graph.GraphDisplay;
|
||||
import ghidra.service.graph.GraphDisplayListener;
|
||||
import ghidra.service.graph.*;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
/**
|
||||
@ -40,7 +38,7 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
implements GraphDisplayListener, PluginEventListener, DomainObjectListener {
|
||||
|
||||
protected PluginTool tool;
|
||||
private GraphDisplay graphDisplay;
|
||||
protected GraphDisplay graphDisplay;
|
||||
protected Program program;
|
||||
private SymbolTable symbolTable;
|
||||
private String name;
|
||||
@ -63,8 +61,8 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationFocusChanged(String vertexId) {
|
||||
Address address = getAddressForVertexId(vertexId);
|
||||
public void locationFocusChanged(AttributedVertex vertex) {
|
||||
Address address = getAddress(vertex);
|
||||
if (address != null) {
|
||||
ProgramLocation location = new ProgramLocation(program, address);
|
||||
tool.firePluginEvent(new ProgramLocationPluginEvent(name, location, program));
|
||||
@ -72,8 +70,8 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(List<String> vertexIds) {
|
||||
AddressSet addressSet = getAddressSetForVertices(vertexIds);
|
||||
public void selectionChanged(Set<AttributedVertex> vertices) {
|
||||
AddressSet addressSet = getAddresses(vertices);
|
||||
if (addressSet != null) {
|
||||
ProgramSelection selection = new ProgramSelection(addressSet);
|
||||
ProgramSelectionPluginEvent event =
|
||||
@ -99,16 +97,16 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
ProgramLocationPluginEvent ev = (ProgramLocationPluginEvent) event;
|
||||
if (isMyProgram(ev.getProgram())) {
|
||||
ProgramLocation location = ev.getLocation();
|
||||
String id = getVertexIdForAddress(location.getAddress());
|
||||
AttributedVertex vertex = getVertex(location.getAddress());
|
||||
// update graph location, but tell it not to send out event
|
||||
graphDisplay.setLocationFocus(id, EventTrigger.INTERNAL_ONLY);
|
||||
graphDisplay.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
|
||||
}
|
||||
}
|
||||
else if (event instanceof ProgramSelectionPluginEvent) {
|
||||
ProgramSelectionPluginEvent ev = (ProgramSelectionPluginEvent) event;
|
||||
if (isMyProgram(ev.getProgram())) {
|
||||
ProgramSelection selection = ev.getSelection();
|
||||
List<String> selectedVertices = getVertices(selection);
|
||||
Set<AttributedVertex> selectedVertices = getVertices(selection);
|
||||
if (selectedVertices != null) {
|
||||
// since we are responding to an event, tell the GraphDisplay not to send event
|
||||
graphDisplay.selectVertices(selectedVertices, EventTrigger.INTERNAL_ONLY);
|
||||
@ -117,7 +115,15 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
}
|
||||
}
|
||||
|
||||
protected String getVertexIdForAddress(Address address) {
|
||||
public AttributedVertex getVertex(Address address) {
|
||||
if (address == null) {
|
||||
return null;
|
||||
}
|
||||
String id = getVertexId(address);
|
||||
return graphDisplay.getGraph().getVertex(id);
|
||||
}
|
||||
|
||||
protected String getVertexId(Address address) {
|
||||
// vertex ids for external locations use symbol names since they don't have meaningful addresses.
|
||||
if (address.isExternalAddress()) {
|
||||
Symbol s = symbolTable.getPrimarySymbol(address);
|
||||
@ -153,13 +159,16 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
|
||||
}
|
||||
|
||||
protected Address getAddressForVertexId(String vertexId) {
|
||||
return getAddress(vertexId);
|
||||
protected Address getAddress(AttributedVertex vertex) {
|
||||
if (vertex == null) {
|
||||
return null;
|
||||
}
|
||||
return getAddress(vertex.getId());
|
||||
}
|
||||
|
||||
protected abstract List<String> getVertices(AddressSetView selection);
|
||||
protected abstract Set<AttributedVertex> getVertices(AddressSetView selection);
|
||||
|
||||
protected abstract AddressSet getAddressSetForVertices(List<String> vertexIds);
|
||||
protected abstract AddressSet getAddresses(Set<AttributedVertex> vertexIds);
|
||||
|
||||
private boolean isMyProgram(Program p) {
|
||||
return p == program;
|
||||
@ -192,15 +201,18 @@ public abstract class AddressBasedGraphDisplayListener
|
||||
}
|
||||
|
||||
private void handleSymbolAddedOrRenamed(Address address, Symbol symbol) {
|
||||
String id = getVertexIdForAddress(address);
|
||||
graphDisplay.updateVertexName(id, symbol.getName());
|
||||
AttributedVertex vertex = getVertex(address);
|
||||
graphDisplay.updateVertexName(vertex, symbol.getName());
|
||||
}
|
||||
|
||||
private void handleSymbolRemoved(Address address) {
|
||||
String id = getVertexIdForAddress(address);
|
||||
AttributedVertex vertex = getVertex(address);
|
||||
if (vertex == null) {
|
||||
return;
|
||||
}
|
||||
Symbol symbol = program.getSymbolTable().getPrimarySymbol(address);
|
||||
String displayName = symbol == null ? address.toString() : symbol.getName();
|
||||
graphDisplay.updateVertexName(id, displayName);
|
||||
graphDisplay.updateVertexName(vertex, displayName);
|
||||
}
|
||||
|
||||
private void dispose() {
|
||||
|
@ -232,16 +232,15 @@ public class GraphAST extends GhidraScript {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getVertices(AddressSetView selection) {
|
||||
List<String> ids = new ArrayList<String>();
|
||||
return ids;
|
||||
protected Set<AttributedVertex> getVertices(AddressSetView selection) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddressSet getAddressSetForVertices(List<String> vertexIds) {
|
||||
protected AddressSet getAddresses(Set<AttributedVertex> vertices) {
|
||||
AddressSet set = new AddressSet();
|
||||
for (String id : vertexIds) {
|
||||
Address address = getAddressForVertexId(id);
|
||||
for (AttributedVertex vertex : vertices) {
|
||||
Address address = getAddress(vertex);
|
||||
if (address != null) {
|
||||
set.add(address);
|
||||
}
|
||||
@ -250,7 +249,11 @@ public class GraphAST extends GhidraScript {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Address getAddressForVertexId(String vertexId) {
|
||||
protected Address getAddress(AttributedVertex vertex) {
|
||||
if (vertex == null) {
|
||||
return null;
|
||||
}
|
||||
String vertexId = vertex.getId();
|
||||
int firstcolon = vertexId.indexOf(':');
|
||||
if (firstcolon == -1) {
|
||||
return null;
|
||||
|
@ -17,8 +17,7 @@ package ghidra.app.plugin.core.decompile.actions;
|
||||
|
||||
import static ghidra.app.plugin.core.decompile.actions.ASTGraphTask.GraphType.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.plugin.core.decompile.actions.ASTGraphTask.GraphType;
|
||||
import ghidra.app.plugin.core.graph.AddressBasedGraphDisplayListener;
|
||||
@ -26,8 +25,7 @@ import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeBlockBasic;
|
||||
import ghidra.service.graph.GraphDisplay;
|
||||
import ghidra.service.graph.GraphDisplayListener;
|
||||
import ghidra.service.graph.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
/**
|
||||
@ -45,33 +43,37 @@ public class ASTGraphDisplayListener extends AddressBasedGraphDisplayListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getVertices(AddressSetView selection) {
|
||||
protected Set<AttributedVertex> getVertices(AddressSetView selection) {
|
||||
if (graphType != CONTROL_FLOW_GRAPH) {
|
||||
return null;
|
||||
}
|
||||
List<String> vertices = new ArrayList<>();
|
||||
Set<AttributedVertex> vertices = new HashSet<>();
|
||||
List<PcodeBlockBasic> blocks = hfunction.getBasicBlocks();
|
||||
for (PcodeBlockBasic block : blocks) {
|
||||
Address start = block.getStart();
|
||||
Address stop = block.getStop();
|
||||
if (selection.intersects(start, stop)) {
|
||||
vertices.add(Integer.toString(block.getIndex()));
|
||||
String id = Integer.toString(block.getIndex());
|
||||
AttributedVertex vertex = graphDisplay.getGraph().getVertex(id);
|
||||
if (vertex != null) {
|
||||
vertices.add(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddressSet getAddressSetForVertices(List<String> vertexIds) {
|
||||
protected AddressSet getAddresses(Set<AttributedVertex> vertices) {
|
||||
if (graphType != CONTROL_FLOW_GRAPH) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AddressSet set = new AddressSet();
|
||||
List<PcodeBlockBasic> blocks = hfunction.getBasicBlocks();
|
||||
for (String vertixId : vertexIds) {
|
||||
for (AttributedVertex vertex : vertices) {
|
||||
try {
|
||||
int index = Integer.parseInt(vertixId);
|
||||
int index = Integer.parseInt(vertex.getId());
|
||||
PcodeBlockBasic block = blocks.get(index);
|
||||
Address start = block.getStart();
|
||||
set.addRange(start, block.getStop());
|
||||
@ -84,7 +86,7 @@ public class ASTGraphDisplayListener extends AddressBasedGraphDisplayListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getVertexIdForAddress(Address address) {
|
||||
protected String getVertexId(Address address) {
|
||||
if (graphType != CONTROL_FLOW_GRAPH) {
|
||||
return null;
|
||||
}
|
||||
@ -96,25 +98,25 @@ public class ASTGraphDisplayListener extends AddressBasedGraphDisplayListener {
|
||||
return Integer.toString(block.getIndex());
|
||||
}
|
||||
}
|
||||
return super.getVertexIdForAddress(address);
|
||||
return super.getVertexId(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Address getAddressForVertexId(String vertexId) {
|
||||
protected Address getAddress(AttributedVertex vertex) {
|
||||
List<PcodeBlockBasic> blocks = hfunction.getBasicBlocks();
|
||||
|
||||
try {
|
||||
int index = Integer.parseInt(vertexId);
|
||||
int index = Integer.parseInt(vertex.getId());
|
||||
PcodeBlockBasic block = blocks.get(index);
|
||||
return block.getStart();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new AssertException("Bad vertex id, expected a number but got " + vertexId);
|
||||
throw new AssertException("Bad vertex id, expected a number but got " + vertex.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDisplayListener cloneWith(GraphDisplay graphDisplay) {
|
||||
public GraphDisplayListener cloneWith(GraphDisplay display) {
|
||||
return new ASTGraphDisplayListener(tool, graphDisplay, hfunction, graphType);
|
||||
}
|
||||
|
||||
|
@ -124,9 +124,9 @@ public class ASTGraphTask extends Task {
|
||||
display.setGraph(graph, description, false, monitor);
|
||||
// set the graph location
|
||||
if (location != null) {
|
||||
String id = displayListener.getVertexIdForAddress(location);
|
||||
AttributedVertex vertex = displayListener.getVertex(location);
|
||||
// update graph location, but don't have it send out event
|
||||
display.setLocationFocus(id, EventTrigger.INTERNAL_ONLY);
|
||||
display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
package ghidra.graph.export;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jgrapht.Graph;
|
||||
|
||||
@ -57,15 +58,7 @@ class ExportAttributedGraphDisplay implements GraphDisplay {
|
||||
// This display is not interactive, so N/A
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectVertices(List<String> vertexList, EventTrigger eventTrigger) {
|
||||
// This display is not interactive, so N/A
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocationFocus(String vertexID, EventTrigger eventTrigger) {
|
||||
// This display is not interactive, so N/A
|
||||
}
|
||||
|
||||
/**
|
||||
* set the {@link AttributedGraph} for visualization
|
||||
@ -108,7 +101,7 @@ class ExportAttributedGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVertexName(String id, String newName) {
|
||||
public void updateVertexName(AttributedVertex vertex, String newName) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@ -123,13 +116,28 @@ class ExportAttributedGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFocusedVertexId() {
|
||||
public AttributedVertex getFocusedVertex() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSelectedVertexIds() {
|
||||
public Set<AttributedVertex> getSelectedVertices() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocusedVertex(AttributedVertex vertex, EventTrigger eventTrigger) {
|
||||
// not interactive, so N/A
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributedGraph getGraph() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectVertices(Set<AttributedVertex> vertexList, EventTrigger eventTrigger) {
|
||||
// not interactive, so N/A
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -539,9 +539,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
});
|
||||
Set<AttributedVertex> selected = selectedVertexState.getSelected();
|
||||
List<String> selectedIds =
|
||||
selected.stream().map(AttributedVertex::getId).collect(Collectors.toList());
|
||||
notifySelectionChanged(selectedIds);
|
||||
notifySelectionChanged(selected);
|
||||
}
|
||||
finally {
|
||||
switchableSelectionListener.setEnabled(true);
|
||||
@ -716,17 +714,18 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
setFocusedVertex(vertex, EventTrigger.API_CALL);
|
||||
}
|
||||
|
||||
protected void setFocusedVertex(AttributedVertex vertex, EventTrigger eventTrigger) {
|
||||
@Override
|
||||
public void setFocusedVertex(AttributedVertex vertex, EventTrigger eventTrigger) {
|
||||
boolean changed = this.focusedVertex != vertex;
|
||||
this.focusedVertex = vertex;
|
||||
if (focusedVertex != null) {
|
||||
if (changed && eventTrigger != EventTrigger.INTERNAL_ONLY) {
|
||||
notifyLocationFocusChanged(focusedVertex.getId());
|
||||
notifyLocationFocusChanged(focusedVertex);
|
||||
}
|
||||
// make sure the vertex is visible, even if the vertex has not changed
|
||||
scrollToSelected(focusedVertex);
|
||||
viewer.repaint();
|
||||
}
|
||||
viewer.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -769,22 +768,22 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
|
||||
/**
|
||||
* fire an event to notify the selected vertices changed
|
||||
* @param vertexIds the list of vertexes
|
||||
* @param selected the list of selected vertices
|
||||
*/
|
||||
private void notifySelectionChanged(List<String> vertexIds) {
|
||||
Swing.runLater(() -> listener.selectionChanged(vertexIds));
|
||||
private void notifySelectionChanged(Set<AttributedVertex> selected) {
|
||||
Swing.runLater(() -> listener.selectionChanged(selected));
|
||||
}
|
||||
|
||||
/**
|
||||
* fire and event to say the focused vertex changed
|
||||
* @param vertexId the id of the focused vertex
|
||||
* @param vertex the new focused vertex
|
||||
*/
|
||||
private void notifyLocationFocusChanged(String vertexId) {
|
||||
Swing.runLater(() -> listener.locationFocusChanged(vertexId));
|
||||
private void notifyLocationFocusChanged(AttributedVertex vertex) {
|
||||
Swing.runLater(() -> listener.locationFocusChanged(vertex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectVertices(List<String> vertexIdList, EventTrigger eventTrigger) {
|
||||
public void selectVertices(Set<AttributedVertex> selected, EventTrigger eventTrigger) {
|
||||
// if we are not to fire events, turn off the selection listener we provided to the
|
||||
// graphing library.
|
||||
switchableSelectionListener.setEnabled(eventTrigger != EventTrigger.INTERNAL_ONLY);
|
||||
@ -792,8 +791,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
try {
|
||||
MutableSelectedState<AttributedVertex> nodeSelectedState =
|
||||
viewer.getSelectedVertexState();
|
||||
Set<AttributedVertex> selected = getVertices(vertexIdList);
|
||||
if (vertexIdList.isEmpty()) {
|
||||
if (selected.isEmpty()) {
|
||||
nodeSelectedState.clear();
|
||||
}
|
||||
else if (!Arrays.asList(nodeSelectedState.getSelectedObjects()).containsAll(selected)) {
|
||||
@ -809,30 +807,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param vertexIds vertex ids of interest
|
||||
* @return a {@code Set} containing the {@code AttributedVertex} for ths supplied ids
|
||||
*/
|
||||
private Set<AttributedVertex> getVertices(Collection<String> vertexIds) {
|
||||
Set<String> vertexSet = new HashSet<>(vertexIds);
|
||||
return graph.vertexSet()
|
||||
.stream()
|
||||
.filter(v -> vertexSet.contains(v.getId()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocationFocus(String vertexID, EventTrigger eventTrigger) {
|
||||
Optional<AttributedVertex> vertexToFocus =
|
||||
graph.vertexSet().stream().filter(v -> vertexID.equals(v.getId())).findFirst();
|
||||
log.fine("picking address:" + vertexID + " returned " + vertexToFocus);
|
||||
viewer.repaint();
|
||||
vertexToFocus.ifPresent(v -> {
|
||||
setFocusedVertex(v, eventTrigger);
|
||||
});
|
||||
viewer.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* set the {@link AttributedGraph} for visualization
|
||||
@ -1066,23 +1040,15 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
/**
|
||||
* process a request to update the name attribute value of the vertex with the
|
||||
* supplied id
|
||||
* @param id the vertix id
|
||||
* @param vertex the vertex to update
|
||||
* @param newName the new name of the vertex
|
||||
*/
|
||||
@Override
|
||||
public void updateVertexName(String id, String newName) {
|
||||
// find the vertex, if present, change the name
|
||||
Optional<AttributedVertex> optional = graph.vertexSet()
|
||||
.stream()
|
||||
.filter(v -> v.getId().equals(id))
|
||||
.findFirst();
|
||||
if (optional.isPresent()) {
|
||||
AttributedVertex vertex = optional.get();
|
||||
vertex.setName(newName);
|
||||
vertex.clearCache();
|
||||
iconCache.evict(vertex);
|
||||
viewer.repaint();
|
||||
}
|
||||
public void updateVertexName(AttributedVertex vertex, String newName) {
|
||||
vertex.setName(newName);
|
||||
vertex.clearCache();
|
||||
iconCache.evict(vertex);
|
||||
viewer.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1225,8 +1191,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
// vertices
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
Collection<AttributedVertex> selectedVertices = getVertices(e.getItem());
|
||||
List<String> selectedVertexIds = toVertexIds(selectedVertices);
|
||||
notifySelectionChanged(selectedVertexIds);
|
||||
notifySelectionChanged(new HashSet<AttributedVertex>(selectedVertices));
|
||||
|
||||
if (selectedVertices.size() == 1) {
|
||||
// if only one vertex was selected, make it the focused vertex
|
||||
@ -1239,7 +1204,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
}
|
||||
else if (e.getStateChange() == ItemEvent.DESELECTED) {
|
||||
notifySelectionChanged(Collections.emptyList());
|
||||
notifySelectionChanged(Collections.emptySet());
|
||||
}
|
||||
viewer.repaint();
|
||||
}
|
||||
@ -1255,14 +1220,13 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFocusedVertexId() {
|
||||
return focusedVertex == null ? null : focusedVertex.getId();
|
||||
public AttributedVertex getFocusedVertex() {
|
||||
return focusedVertex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSelectedVertexIds() {
|
||||
Set<AttributedVertex> selectedVertices = getSelectedVertices();
|
||||
return selectedVertices.stream().map(v -> v.getId()).collect(Collectors.toSet());
|
||||
public Set<AttributedVertex> getSelectedVertices() {
|
||||
return viewer.getSelectedVertexState().getSelected();
|
||||
}
|
||||
|
||||
public ActionContext getActionContext(MouseEvent e) {
|
||||
@ -1284,9 +1248,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
|
||||
}
|
||||
|
||||
private Set<AttributedVertex> getSelectedVertices() {
|
||||
return viewer.getSelectedVertexState().getSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the hide selected action states to determine what vertices are shown:
|
||||
@ -1321,4 +1282,8 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
viewer.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributedGraph getGraph() {
|
||||
return graph;
|
||||
}
|
||||
}
|
||||
|
@ -157,13 +157,13 @@ public class BlockGraphTask extends Task {
|
||||
|
||||
if (location != null) {
|
||||
// initialize the graph location, but don't have the graph send an event
|
||||
String id = listener.getVertexIdForAddress(location.getAddress());
|
||||
display.setLocationFocus(id, EventTrigger.INTERNAL_ONLY);
|
||||
AttributedVertex vertex = listener.getVertex(location.getAddress());
|
||||
display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
|
||||
}
|
||||
if (selection != null && !selection.isEmpty()) {
|
||||
List<String> selectedVertices = listener.getVertices(selection);
|
||||
Set<AttributedVertex> selectedVertices = listener.getVertices(selection);
|
||||
if (selectedVertices != null) {
|
||||
// intialize the graph selection, but don't have the graph send an event
|
||||
// initialize the graph selection, but don't have the graph send an event
|
||||
display.selectVertices(selectedVertices, EventTrigger.INTERNAL_ONLY);
|
||||
}
|
||||
}
|
||||
|
@ -54,28 +54,28 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getVertexIdForAddress(Address address) {
|
||||
protected String getVertexId(Address address) {
|
||||
try {
|
||||
CodeBlock[] blocks = blockModel.getCodeBlocksContaining(address, TaskMonitor.DUMMY);
|
||||
if (blocks != null && blocks.length > 0) {
|
||||
return super.getVertexIdForAddress(blocks[0].getFirstStartAddress());
|
||||
return super.getVertexId(blocks[0].getFirstStartAddress());
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// Will not happen with dummyMonitor
|
||||
// Model has already done the work when the graph was created
|
||||
}
|
||||
return super.getVertexIdForAddress(address);
|
||||
return super.getVertexId(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getVertices(AddressSetView addrSet) {
|
||||
protected Set<AttributedVertex> getVertices(AddressSetView addrSet) {
|
||||
if (addrSet.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
// Identify all blocks which have an entry point within the selection address set
|
||||
ArrayList<String> blockList = new ArrayList<String>();
|
||||
Set<AttributedVertex> vertices = new HashSet<>();
|
||||
try {
|
||||
SymbolTable symTable = program.getSymbolTable();
|
||||
CodeBlockIterator cbIter =
|
||||
@ -91,7 +91,10 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
||||
else {
|
||||
addrString = addr.toString();
|
||||
}
|
||||
blockList.add(addrString);
|
||||
AttributedVertex vertex = graphDisplay.getGraph().getVertex(addrString);
|
||||
if (vertex != null) {
|
||||
vertices.add(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
@ -99,18 +102,18 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
||||
// Model has already done the work when the graph was created
|
||||
}
|
||||
|
||||
return blockList;
|
||||
return vertices;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddressSet getAddressSetForVertices(List<String> vertexIds) {
|
||||
protected AddressSet getAddresses(Set<AttributedVertex> vertices) {
|
||||
AddressSet addrSet = new AddressSet();
|
||||
|
||||
try {
|
||||
// for each address string, translate it into a block
|
||||
// and add it to the address set.
|
||||
for (String vertexId : vertexIds) {
|
||||
Address blockAddr = getAddressForVertexId(vertexId);
|
||||
for (AttributedVertex vertex : vertices) {
|
||||
Address blockAddr = getAddress(vertex);
|
||||
if (!isValidAddress(blockAddr)) {
|
||||
continue;
|
||||
}
|
||||
@ -150,8 +153,8 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
||||
}
|
||||
|
||||
private void updateVertexName(VertexGraphActionContext context) {
|
||||
String vertexId = context.getClickedVertex().getId();
|
||||
Address address = getAddressForVertexId(vertexId);
|
||||
AttributedVertex vertex = context.getClickedVertex();
|
||||
Address address = getAddress(vertex);
|
||||
Symbol symbol = program.getSymbolTable().getPrimarySymbol(address);
|
||||
|
||||
if (symbol == null) {
|
||||
@ -165,8 +168,8 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDisplayListener cloneWith(GraphDisplay graphDisplay) {
|
||||
return new BlockModelGraphDisplayListener(tool, blockModel, graphDisplay);
|
||||
public GraphDisplayListener cloneWith(GraphDisplay newGraphDisplay) {
|
||||
return new BlockModelGraphDisplayListener(tool, blockModel, newGraphDisplay);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ package ghidra.graph.program;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@ -27,6 +28,7 @@ import ghidra.program.model.block.CodeBlockModel;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.service.graph.AttributedGraph;
|
||||
import ghidra.service.graph.AttributedVertex;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class BlockGraphEventTest extends AbstractBlockGraphTest {
|
||||
@ -54,13 +56,13 @@ public class BlockGraphEventTest extends AbstractBlockGraphTest {
|
||||
@Test
|
||||
public void testGhidraLocationChanged() {
|
||||
codeBrowser.goTo(new ProgramLocation(program, addr(0x1002239)));
|
||||
assertEquals("01002239", display.getFocusedVertex());
|
||||
assertEquals("01002239", display.getFocusedVertex().getId());
|
||||
codeBrowser.goTo(new ProgramLocation(program, addr(0x1002200)));
|
||||
assertEquals("01002200", display.getFocusedVertex());
|
||||
assertEquals("01002200", display.getFocusedVertex().getId());
|
||||
|
||||
// also try a location that is not the start of a block
|
||||
codeBrowser.goTo(new ProgramLocation(program, addr(0x100223a)));
|
||||
assertEquals("01002239", display.getFocusedVertex());
|
||||
assertEquals("01002239", display.getFocusedVertex().getId());
|
||||
}
|
||||
|
||||
|
||||
@ -71,38 +73,38 @@ public class BlockGraphEventTest extends AbstractBlockGraphTest {
|
||||
@Test
|
||||
public void testGhidraSelectionChanged() {
|
||||
setSelection(addrSet(0x1002239, 0x1002241));
|
||||
Set<String> selected = new HashSet<>(display.getSelectedVertices());
|
||||
Set<AttributedVertex> selected = new HashSet<>(display.getSelectedVertices());
|
||||
assertEquals(3, selected.size());
|
||||
assertTrue(selected.contains("01002239"));
|
||||
assertTrue(selected.contains("0100223c"));
|
||||
assertTrue(selected.contains("0100223e"));
|
||||
assertTrue(selected.contains(graph.getVertex("01002239")));
|
||||
assertTrue(selected.contains(graph.getVertex("0100223c")));
|
||||
assertTrue(selected.contains(graph.getVertex("0100223e")));
|
||||
|
||||
setSelection(new AddressSet(addr(0x1002200), addr(0x1002210)));
|
||||
selected = new HashSet<>(display.getSelectedVertices());
|
||||
assertEquals(2, selected.size());
|
||||
assertTrue(selected.contains("01002200"));
|
||||
assertTrue(selected.contains("01002203"));
|
||||
assertTrue(selected.contains(graph.getVertex("01002200")));
|
||||
assertTrue(selected.contains(graph.getVertex("01002203")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGraphNodeFocused() {
|
||||
display.focusChanged("01002203");
|
||||
display.focusChanged(graph.getVertex("01002203"));
|
||||
assertEquals(addr(0x01002203), codeBrowser.getCurrentLocation().getAddress());
|
||||
|
||||
display.focusChanged("0100223c");
|
||||
display.focusChanged(graph.getVertex("0100223c"));
|
||||
assertEquals(addr(0x0100223c), codeBrowser.getCurrentLocation().getAddress());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGraphNodesSelected() {
|
||||
display.selectionChanged(Arrays.asList("01002239", "0100223c"));
|
||||
display.selectionChanged(Set.of(graph.getVertex("01002239"), graph.getVertex("0100223c")));
|
||||
ProgramSelection selection = codeBrowser.getCurrentSelection();
|
||||
assertEquals(addr(0x01002239), selection.getMinAddress());
|
||||
assertEquals(addr(0x0100223d), selection.getMaxAddress());
|
||||
|
||||
display.selectionChanged(Arrays.asList("01002200", "01002203"));
|
||||
display.selectionChanged(Set.of(graph.getVertex("01002200"), graph.getVertex("01002203")));
|
||||
selection = codeBrowser.getCurrentSelection();
|
||||
assertEquals(addr(0x01002200), selection.getMinAddress());
|
||||
assertEquals(addr(0x01002204), selection.getMaxAddress());
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
package ghidra.graph.program;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import docking.action.DockingAction;
|
||||
import docking.widgets.EventTrigger;
|
||||
@ -26,12 +27,11 @@ import ghidra.util.task.TaskMonitor;
|
||||
public class TestGraphDisplay implements GraphDisplay {
|
||||
private Set<String> definedVertexAttributes = new HashSet<>();
|
||||
private Set<String> definedEdgeAttributes = new HashSet<>();
|
||||
private String vertexAttributeName;
|
||||
private AttributedGraph graph;
|
||||
private String graphDescription;
|
||||
private GraphDisplayListener listener;
|
||||
private String currentFocusedVertex;
|
||||
private List<String> currentSelection;
|
||||
private AttributedVertex focusedVertex;
|
||||
private Set<AttributedVertex> currentSelection;
|
||||
|
||||
@Override
|
||||
public void setGraphDisplayListener(GraphDisplayListener listener) {
|
||||
@ -39,20 +39,22 @@ public class TestGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocationFocus(String vertexID, EventTrigger eventTrigger) {
|
||||
currentFocusedVertex = vertexID;
|
||||
}
|
||||
|
||||
public String getFocusedVertex() {
|
||||
return currentFocusedVertex;
|
||||
public void setFocusedVertex(AttributedVertex vertex, EventTrigger eventTrigger) {
|
||||
focusedVertex = vertex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectVertices(List<String> vertexList, EventTrigger eventTrigger) {
|
||||
public AttributedVertex getFocusedVertex() {
|
||||
return focusedVertex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectVertices(Set<AttributedVertex> vertexList, EventTrigger eventTrigger) {
|
||||
currentSelection = vertexList;
|
||||
}
|
||||
|
||||
public List<String> getSelectedVertices() {
|
||||
@Override
|
||||
public Set<AttributedVertex> getSelectedVertices() {
|
||||
return currentSelection;
|
||||
}
|
||||
|
||||
@ -74,7 +76,7 @@ public class TestGraphDisplay implements GraphDisplay {
|
||||
@Override
|
||||
public void setVertexLabel(String attributeName, int alignment, int size, boolean monospace,
|
||||
int maxLines) {
|
||||
vertexAttributeName = attributeName;
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,7 +93,7 @@ public class TestGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVertexName(String id, String newName) {
|
||||
public void updateVertexName(AttributedVertex vertex, String newName) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
@ -100,16 +102,17 @@ public class TestGraphDisplay implements GraphDisplay {
|
||||
return graphDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributedGraph getGraph() {
|
||||
return graph;
|
||||
}
|
||||
|
||||
public void focusChanged(String vertexId) {
|
||||
listener.locationFocusChanged(vertexId);
|
||||
public void focusChanged(AttributedVertex vertex) {
|
||||
listener.locationFocusChanged(vertex);
|
||||
}
|
||||
|
||||
public void selectionChanged(List<String> vertexIds) {
|
||||
listener.selectionChanged(vertexIds);
|
||||
public void selectionChanged(Set<AttributedVertex> vertices) {
|
||||
listener.selectionChanged(vertices);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,14 +120,4 @@ public class TestGraphDisplay implements GraphDisplay {
|
||||
// do nothing, actions are not supported by this display
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFocusedVertexId() {
|
||||
return currentFocusedVertex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSelectedVertexIds() {
|
||||
return new HashSet<String>(currentSelection);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package ghidra.service.graph;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DummyGraphDisplayListener implements GraphDisplayListener {
|
||||
|
||||
@ -24,19 +24,19 @@ public class DummyGraphDisplayListener implements GraphDisplayListener {
|
||||
// I'm a dummy
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(List<String> vertexIds) {
|
||||
// I'm a dummy
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationFocusChanged(String vertexId) {
|
||||
// I'm a dummy
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDisplayListener cloneWith(GraphDisplay graphDisplay) {
|
||||
return new DummyGraphDisplayListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(Set<AttributedVertex> vertices) {
|
||||
// I'm a dummy
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationFocusChanged(AttributedVertex vertex) {
|
||||
// I'm a dummy
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package ghidra.service.graph;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import docking.action.DockingAction;
|
||||
@ -46,41 +45,46 @@ public interface GraphDisplay {
|
||||
/**
|
||||
* Tells the graph display window to focus the vertex with the given id.
|
||||
*
|
||||
* @param vertexID the id of the vertex to focus
|
||||
* @param vertex the vertex to focus
|
||||
* @param eventTrigger Provides a hint to the GraphDisplay as to why we are updating the
|
||||
* graph location so that the GraphDisplay can decide if it should send out a notification via
|
||||
* the {@link GraphDisplayListener#locationFocusChanged(String)}. For example, if we are updating
|
||||
* the the location due to an event from the main application, we don't want to notify the
|
||||
* application the graph changed to avoid event cycles. See {@link EventTrigger} for more
|
||||
* information.
|
||||
*
|
||||
* the {@link GraphDisplayListener#locationFocusChanged(AttributedVertex)}. For example, if we
|
||||
* are updating the the location due to an event from the main application, we don't want to
|
||||
* notify the application the graph changed to avoid event cycles. See {@link EventTrigger} for
|
||||
* more information.
|
||||
*/
|
||||
public void setLocationFocus(String vertexID, EventTrigger eventTrigger);
|
||||
public void setFocusedVertex(AttributedVertex vertex, EventTrigger eventTrigger);
|
||||
|
||||
/**
|
||||
* Returns the currently focused vertexID or null if no vertex is focussed.
|
||||
* @return the currently focused vertexID or null if no vertex is focussed.
|
||||
* Returns the graph for this display
|
||||
* @return the graph for this display
|
||||
*/
|
||||
public String getFocusedVertexId();
|
||||
public AttributedGraph getGraph();
|
||||
|
||||
/**
|
||||
* Returns the currently focused vertex or null if no vertex is focused
|
||||
* @return the currently focused vertex or null if no vertex is focused.
|
||||
*/
|
||||
public AttributedVertex getFocusedVertex();
|
||||
|
||||
/**
|
||||
* Tells the graph display window to select the vertices with the given ids
|
||||
*
|
||||
* @param vertexList the list of vertex ids to select
|
||||
* @param vertexSet the set of vertices to select
|
||||
* @param eventTrigger Provides a hint to the GraphDisplay as to why we are updating the
|
||||
* graph location so that the GraphDisplay can decide if it should send out a notification via
|
||||
* the {@link GraphDisplayListener#locationFocusChanged(String)}. For example, if we are updating
|
||||
* the {@link GraphDisplayListener#selectionChanged(Set)}. For example, if we are updating
|
||||
* the the location due to an event from the main application, we don't want to notify the
|
||||
* application the graph changed to avoid event cycles. See {@link EventTrigger} for more
|
||||
* information.
|
||||
*/
|
||||
public void selectVertices(List<String> vertexList, EventTrigger eventTrigger);
|
||||
public void selectVertices(Set<AttributedVertex> vertexSet, EventTrigger eventTrigger);
|
||||
|
||||
/**
|
||||
* Returns a list of vertex ids for all the currently selected vertices
|
||||
* @return a list of vertex ids for all the currently selected vertices
|
||||
* Returns a set of vertex ids for all the currently selected vertices
|
||||
* @return a set of vertex ids for all the currently selected vertices
|
||||
*/
|
||||
public Set<String> getSelectedVertexIds();
|
||||
public Set<AttributedVertex> getSelectedVertices();
|
||||
|
||||
/**
|
||||
* Closes this graph display window.
|
||||
@ -131,10 +135,10 @@ public interface GraphDisplay {
|
||||
|
||||
/**
|
||||
* Updates a vertex to a new name
|
||||
* @param id the vertex id
|
||||
* @param newName the new name of the vertex
|
||||
* @param vertex the vertex to rename
|
||||
* @param newName the new name for the vertex
|
||||
*/
|
||||
public void updateVertexName(String id, String newName);
|
||||
public void updateVertexName(AttributedVertex vertex, String newName);
|
||||
|
||||
/**
|
||||
* Returns the description of the current graph
|
||||
@ -148,4 +152,5 @@ public interface GraphDisplay {
|
||||
* @param action the action to add.
|
||||
*/
|
||||
public void addAction(DockingAction action);
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package ghidra.service.graph;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface for being notified when the user interacts with a visual graph display
|
||||
@ -27,17 +27,17 @@ public interface GraphDisplayListener {
|
||||
public void graphClosed();
|
||||
|
||||
/**
|
||||
* Notification that the list of selected vertices has changed
|
||||
* Notification that the set of selected vertices has changed
|
||||
*
|
||||
* @param vertexIds the list of vertex ids for the currently selected vertices
|
||||
* @param vertices the set of currently selected vertices
|
||||
*/
|
||||
public void selectionChanged(List<String> vertexIds);
|
||||
public void selectionChanged(Set<AttributedVertex> vertices);
|
||||
|
||||
/**
|
||||
* Notification that the "focused" (active) vertex has changed
|
||||
* @param vertexId the vertex id of the currently "focused" vertex
|
||||
* @param vertex the vertex that is currently "focused"
|
||||
*/
|
||||
public void locationFocusChanged(String vertexId);
|
||||
public void locationFocusChanged(AttributedVertex vertex);
|
||||
|
||||
/**
|
||||
* Makes a new GraphDisplayListener of the same type as the specific
|
||||
|
@ -40,6 +40,12 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
private AttributedGraph graph;
|
||||
private ComponentProvider graphComponentProvider;
|
||||
private GraphDisplay display;
|
||||
private AttributedVertex a;
|
||||
private AttributedVertex b;
|
||||
private AttributedVertex c;
|
||||
private AttributedVertex d;
|
||||
private AttributedVertex e;
|
||||
private AttributedVertex f;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@ -60,7 +66,7 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void testSelectVertexAction() {
|
||||
assertTrue(display.getSelectedVertexIds().isEmpty());
|
||||
assertTrue(display.getSelectedVertices().isEmpty());
|
||||
|
||||
DockingActionIf action = getAction(tool, "Select Vertex");
|
||||
VertexGraphActionContext context =
|
||||
@ -68,25 +74,24 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
graph.getVertex("B"));
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVertexIds = display.getSelectedVertexIds();
|
||||
assertEquals(1, selectedVertexIds.size());
|
||||
assertTrue(selectedVertexIds.contains(graph.getVertex("B").getId()));
|
||||
Set<AttributedVertex> selectedVertices = display.getSelectedVertices();
|
||||
assertEquals(1, selectedVertices.size());
|
||||
assertTrue(selectedVertices.contains(b));
|
||||
|
||||
// now try and select a second vertex
|
||||
context = new VertexGraphActionContext(graphComponentProvider, graph, null, null,
|
||||
graph.getVertex("D"));
|
||||
context = new VertexGraphActionContext(graphComponentProvider, graph, null, null,d);
|
||||
performAction(action, context, true);
|
||||
selectedVertexIds = display.getSelectedVertexIds();
|
||||
assertEquals(2, selectedVertexIds.size());
|
||||
assertTrue(selectedVertexIds.contains(graph.getVertex("B").getId()));
|
||||
assertTrue(selectedVertexIds.contains(graph.getVertex("D").getId()));
|
||||
selectedVertices = display.getSelectedVertices();
|
||||
assertEquals(2, selectedVertices.size());
|
||||
assertTrue(selectedVertices.contains(b));
|
||||
assertTrue(selectedVertices.contains(d));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeSelectVertexAction() {
|
||||
display.selectVertices(Arrays.asList("A", "B", "C", "D"), EventTrigger.API_CALL);
|
||||
assertEquals(4, display.getSelectedVertexIds().size());
|
||||
select(a, b, c, d);
|
||||
assertEquals(4, display.getSelectedVertices().size());
|
||||
|
||||
DockingActionIf action = getAction(tool, "Deselect Vertex");
|
||||
VertexGraphActionContext context =
|
||||
@ -94,18 +99,18 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
graph.getVertex("B"));
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVerticeIds = display.getSelectedVertexIds();
|
||||
assertEquals(3, selectedVerticeIds.size());
|
||||
assertTrue(selectedVerticeIds.contains(graph.getVertex("A").getId()));
|
||||
assertTrue(selectedVerticeIds.contains(graph.getVertex("D").getId()));
|
||||
assertTrue(selectedVerticeIds.contains(graph.getVertex("D").getId()));
|
||||
assertFalse(selectedVerticeIds.contains(graph.getVertex("B").getId()));
|
||||
Set<AttributedVertex> selected = display.getSelectedVertices();
|
||||
assertEquals(3, selected.size());
|
||||
assertTrue(selected.contains(a));
|
||||
assertTrue(selected.contains(c));
|
||||
assertTrue(selected.contains(d));
|
||||
assertFalse(selected.contains(b));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectEdgeAction() {
|
||||
assertTrue(display.getSelectedVertexIds().isEmpty());
|
||||
assertTrue(display.getSelectedVertices().isEmpty());
|
||||
|
||||
DockingActionIf action = getAction(tool, "Select Edge");
|
||||
EdgeGraphActionContext context =
|
||||
@ -113,10 +118,10 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
graph.getEdge(graph.getVertex("A"), graph.getVertex("B")));
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVerticeIds = display.getSelectedVertexIds();
|
||||
Set<AttributedVertex> selectedVerticeIds = display.getSelectedVertices();
|
||||
assertEquals(2, selectedVerticeIds.size());
|
||||
assertTrue(selectedVerticeIds.contains(graph.getVertex("A").getId()));
|
||||
assertTrue(selectedVerticeIds.contains(graph.getVertex("B").getId()));
|
||||
assertTrue(selectedVerticeIds.contains(a));
|
||||
assertTrue(selectedVerticeIds.contains(b));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -127,85 +132,85 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
graph.getEdge(graph.getVertex("A"), graph.getVertex("B")));
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVerticeIds = display.getSelectedVertexIds();
|
||||
assertEquals(2, selectedVerticeIds.size());
|
||||
Set<AttributedVertex> selectedVertices = display.getSelectedVertices();
|
||||
assertEquals(2, selectedVertices.size());
|
||||
|
||||
action = getAction(tool, "Deselect Edge");
|
||||
|
||||
performAction(action, context, true);
|
||||
|
||||
selectedVerticeIds = display.getSelectedVertexIds();
|
||||
assertEquals(0, selectedVerticeIds.size());
|
||||
|
||||
selectedVertices = display.getSelectedVertices();
|
||||
assertEquals(0, selectedVertices.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectEdgeSource() {
|
||||
display.setLocationFocus("D", EventTrigger.INTERNAL_ONLY);
|
||||
setFocusedVertex(d);
|
||||
DockingActionIf action = getAction(tool, "Edge Source");
|
||||
EdgeGraphActionContext context =
|
||||
new EdgeGraphActionContext(graphComponentProvider, graph, null, null,
|
||||
graph.getEdge(graph.getVertex("A"), graph.getVertex("B")));
|
||||
performAction(action, context, true);
|
||||
|
||||
assertEquals("A", display.getFocusedVertexId());
|
||||
assertEquals(a, display.getFocusedVertex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectEdgeTarget() {
|
||||
display.setLocationFocus("D", EventTrigger.INTERNAL_ONLY);
|
||||
setFocusedVertex(d);
|
||||
DockingActionIf action = getAction(tool, "Edge Target");
|
||||
EdgeGraphActionContext context =
|
||||
new EdgeGraphActionContext(graphComponentProvider, graph, null, null,
|
||||
graph.getEdge(graph.getVertex("A"), graph.getVertex("B")));
|
||||
graph.getEdge(a, b));
|
||||
performAction(action, context, true);
|
||||
|
||||
assertEquals("B", display.getFocusedVertexId());
|
||||
assertEquals(b, display.getFocusedVertex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvertSelection() {
|
||||
display.selectVertices(List.of("A", "C", "E"), EventTrigger.INTERNAL_ONLY);
|
||||
select(a, c, e);
|
||||
DockingActionIf action = getAction(tool, "Invert Selection");
|
||||
GraphActionContext context =
|
||||
new GraphActionContext(graphComponentProvider, graph, null, null);
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVerticeIds = display.getSelectedVertexIds();
|
||||
assertEquals(3, selectedVerticeIds.size());
|
||||
assertTrue(selectedVerticeIds.contains("B"));
|
||||
assertTrue(selectedVerticeIds.contains("D"));
|
||||
assertTrue(selectedVerticeIds.contains("F"));
|
||||
Set<AttributedVertex> selectedVertices = display.getSelectedVertices();
|
||||
assertEquals(3, selectedVertices.size());
|
||||
assertTrue(selectedVertices.contains(b));
|
||||
assertTrue(selectedVertices.contains(d));
|
||||
assertTrue(selectedVertices.contains(f));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrowSelectionOut() {
|
||||
display.selectVertices(List.of("A"), EventTrigger.INTERNAL_ONLY);
|
||||
select(a);
|
||||
DockingActionIf action = getAction(tool, "Grow Selection To Targets");
|
||||
GraphActionContext context =
|
||||
new GraphActionContext(graphComponentProvider, graph, null, null);
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVerticeIds = display.getSelectedVertexIds();
|
||||
Set<AttributedVertex> selectedVerticeIds = display.getSelectedVertices();
|
||||
assertEquals(3, selectedVerticeIds.size());
|
||||
assertTrue(selectedVerticeIds.contains("A"));
|
||||
assertTrue(selectedVerticeIds.contains("B"));
|
||||
assertTrue(selectedVerticeIds.contains("C"));
|
||||
assertTrue(selectedVerticeIds.contains(a));
|
||||
assertTrue(selectedVerticeIds.contains(b));
|
||||
assertTrue(selectedVerticeIds.contains(c));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGrowSelectionIn() {
|
||||
display.selectVertices(List.of("D"), EventTrigger.INTERNAL_ONLY);
|
||||
select(d);
|
||||
DockingActionIf action = getAction(tool, "Grow Selection From Sources");
|
||||
GraphActionContext context =
|
||||
new GraphActionContext(graphComponentProvider, graph, null, null);
|
||||
performAction(action, context, true);
|
||||
|
||||
Set<String> selectedVerticeIds = display.getSelectedVertexIds();
|
||||
assertEquals(3, selectedVerticeIds.size());
|
||||
assertTrue(selectedVerticeIds.contains("D"));
|
||||
assertTrue(selectedVerticeIds.contains("B"));
|
||||
assertTrue(selectedVerticeIds.contains("C"));
|
||||
Set<AttributedVertex> selectedVertices = display.getSelectedVertices();
|
||||
assertEquals(3, selectedVertices.size());
|
||||
assertTrue(selectedVertices.contains(d));
|
||||
assertTrue(selectedVertices.contains(b));
|
||||
assertTrue(selectedVertices.contains(c));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -216,7 +221,7 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
assertEquals(1, graphProviders.size());
|
||||
DefaultGraphDisplayComponentProvider original = graphProviders.get(0);
|
||||
|
||||
display.selectVertices(List.of("B", "C", "D"), EventTrigger.INTERNAL_ONLY);
|
||||
select(b, c, d);
|
||||
DockingActionIf action = getAction(tool, "Create Subgraph");
|
||||
GraphActionContext context =
|
||||
new GraphActionContext(graphComponentProvider, graph, null, null);
|
||||
@ -241,8 +246,8 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
assertFalse(contains(newGraph, "F"));
|
||||
}
|
||||
|
||||
private boolean contains(AttributedGraph graph, String vertexId) {
|
||||
return graph.getVertex(vertexId) != null;
|
||||
private boolean contains(AttributedGraph g, String vertexId) {
|
||||
return g.getVertex(vertexId) != null;
|
||||
}
|
||||
|
||||
private void showGraph() throws Exception {
|
||||
@ -253,6 +258,17 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
display.setGraphDisplayListener(new TestGraphDisplayListener("test"));
|
||||
}
|
||||
|
||||
private void select(AttributedVertex... vertices) {
|
||||
runSwing(() -> {
|
||||
Set<AttributedVertex> vetexSet = new HashSet<>(Arrays.asList(vertices));
|
||||
display.selectVertices(vetexSet, EventTrigger.INTERNAL_ONLY);
|
||||
});
|
||||
}
|
||||
|
||||
private void setFocusedVertex(AttributedVertex vertex) {
|
||||
runSwing(() -> display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY));
|
||||
}
|
||||
|
||||
class TestGraphDisplayListener implements GraphDisplayListener {
|
||||
|
||||
private String name;
|
||||
@ -267,20 +283,20 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(List<String> vertexIds) {
|
||||
public void selectionChanged(Set<AttributedVertex> verrtices) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(name);
|
||||
buf.append(": selected: ");
|
||||
for (String id : vertexIds) {
|
||||
buf.append(id);
|
||||
for (AttributedVertex vertex : verrtices) {
|
||||
buf.append(vertex.getId());
|
||||
buf.append(",");
|
||||
}
|
||||
listenerCalls.add(buf.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationFocusChanged(String vertexId) {
|
||||
listenerCalls.add(name + ": focus: " + vertexId);
|
||||
public void locationFocusChanged(AttributedVertex vertex) {
|
||||
listenerCalls.add(name + ": focus: " + vertex.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -292,12 +308,12 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
private AttributedGraph createGraph() {
|
||||
AttributedGraph g = new AttributedGraph();
|
||||
AttributedVertex a = g.addVertex("A");
|
||||
AttributedVertex b = g.addVertex("B");
|
||||
AttributedVertex c = g.addVertex("C");
|
||||
AttributedVertex d = g.addVertex("D");
|
||||
AttributedVertex e = g.addVertex("E");
|
||||
AttributedVertex f = g.addVertex("F");
|
||||
a = g.addVertex("A");
|
||||
b = g.addVertex("B");
|
||||
c = g.addVertex("C");
|
||||
d = g.addVertex("D");
|
||||
e = g.addVertex("E");
|
||||
f = g.addVertex("F");
|
||||
|
||||
g.addEdge(a, b);
|
||||
g.addEdge(a, c);
|
||||
|
Loading…
Reference in New Issue
Block a user