Test fixes for recent FG layout updates

This commit is contained in:
dragonmacher
2021-09-22 10:02:50 -04:00
parent 9c952ed154
commit a7f8cd3acd
4 changed files with 225 additions and 211 deletions
@@ -189,8 +189,8 @@ class FGActionManager {
return !(context instanceof FunctionGraphVertexLocationInFullViewModeActionContext); return !(context instanceof FunctionGraphVertexLocationInFullViewModeActionContext);
} }
}; };
zoomOutAction.setPopupMenuData( zoomOutAction
new MenuData(new String[] { "Zoom Out" }, popuEndPopupGroup)); .setPopupMenuData(new MenuData(new String[] { "Zoom Out" }, popuEndPopupGroup));
zoomOutAction.setKeyBindingData(new KeyBindingData( zoomOutAction.setKeyBindingData(new KeyBindingData(
KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, DockingUtils.CONTROL_KEY_MODIFIER_MASK))); KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, DockingUtils.CONTROL_KEY_MODIFIER_MASK)));
zoomOutAction.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Zoom")); zoomOutAction.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Zoom"));
@@ -325,8 +325,8 @@ class FGActionManager {
menuData.setMenuSubGroup(Integer.toString(vertexGroupingSubgroupOffset++)); menuData.setMenuSubGroup(Integer.toString(vertexGroupingSubgroupOffset++));
editLabelAction.setDescription("Change the label for the code block"); editLabelAction.setDescription("Change the label for the code block");
editLabelAction.setPopupMenuData(menuData); editLabelAction.setPopupMenuData(menuData);
editLabelAction.setHelpLocation( editLabelAction
new HelpLocation("FunctionGraphPlugin", "Vertex_Action_Label")); .setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Vertex_Action_Label"));
DockingAction fullViewAction = new DockingAction("Vertex View Mode", plugin.getName()) { DockingAction fullViewAction = new DockingAction("Vertex View Mode", plugin.getName()) {
@Override @Override
@@ -717,8 +717,8 @@ class FGActionManager {
}; };
selectHoveredEdgesAction.setPopupMenuData(new MenuData( selectHoveredEdgesAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "From Hovered Edges" }, popupSelectionGroup2)); new String[] { selectionMenuName, "From Hovered Edges" }, popupSelectionGroup2));
selectHoveredEdgesAction.setHelpLocation( selectHoveredEdgesAction
new HelpLocation("FunctionGraphPlugin", "Path_Selection")); .setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
DockingAction selectFocusedEdgesAction = DockingAction selectFocusedEdgesAction =
new DockingAction("Make Selection From Focused Edges", plugin.getName()) { new DockingAction("Make Selection From Focused Edges", plugin.getName()) {
@@ -751,8 +751,8 @@ class FGActionManager {
}; };
selectFocusedEdgesAction.setPopupMenuData(new MenuData( selectFocusedEdgesAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "From Focused Edges" }, popupSelectionGroup2)); new String[] { selectionMenuName, "From Focused Edges" }, popupSelectionGroup2));
selectFocusedEdgesAction.setHelpLocation( selectFocusedEdgesAction
new HelpLocation("FunctionGraphPlugin", "Path_Selection")); .setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
DockingAction clearCurrentSelectionAction = DockingAction clearCurrentSelectionAction =
new DockingAction("Clear Current Selection", plugin.getName()) { new DockingAction("Clear Current Selection", plugin.getName()) {
@@ -775,8 +775,8 @@ class FGActionManager {
}; };
clearCurrentSelectionAction.setPopupMenuData(new MenuData( clearCurrentSelectionAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "Clear Graph Selection" }, popupSelectionGroup3)); new String[] { selectionMenuName, "Clear Graph Selection" }, popupSelectionGroup3));
clearCurrentSelectionAction.setHelpLocation( clearCurrentSelectionAction
new HelpLocation("FunctionGraphPlugin", "Path_Selection")); .setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
DockingAction selectAllAction = DockingAction selectAllAction =
new DockingAction("Select All Code Units", plugin.getName()) { new DockingAction("Select All Code Units", plugin.getName()) {
@@ -815,12 +815,12 @@ class FGActionManager {
return isValidContext(context); return isValidContext(context);
} }
}; };
selectAllAction.setKeyBindingData( selectAllAction
new KeyBindingData(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK)); .setKeyBindingData(new KeyBindingData(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
selectAllAction.setPopupMenuData(new MenuData( selectAllAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "Select All Code Units" }, popupSelectionGroup3)); new String[] { selectionMenuName, "Select All Code Units" }, popupSelectionGroup3));
selectAllAction.setHelpLocation( selectAllAction
new HelpLocation("FunctionGraphPlugin", "Code_Unit_Selection")); .setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Code_Unit_Selection"));
provider.addLocalAction(chooseFormatsAction); provider.addLocalAction(chooseFormatsAction);
provider.addLocalAction(homeAction); provider.addLocalAction(homeAction);
@@ -885,9 +885,7 @@ class FGActionManager {
// icon to be blank in the menu, but to use this icon on the toolbar. // icon to be blank in the menu, but to use this icon on the toolbar.
layoutAction.setDefaultIcon(ResourceManager.loadImage("images/preferences-system.png")); layoutAction.setDefaultIcon(ResourceManager.loadImage("images/preferences-system.png"));
List<ActionState<FGLayoutProvider>> actionStates = List<ActionState<FGLayoutProvider>> actionStates = loadActionStatesForLayoutProviders();
loadActionStatesForLayoutProviders();
for (ActionState<FGLayoutProvider> actionState : actionStates) { for (ActionState<FGLayoutProvider> actionState : actionStates) {
layoutAction.addActionState(actionState); layoutAction.addActionState(actionState);
} }
@@ -900,15 +898,19 @@ class FGActionManager {
} }
private List<ActionState<FGLayoutProvider>> loadActionStatesForLayoutProviders() { private List<ActionState<FGLayoutProvider>> loadActionStatesForLayoutProviders() {
List<FGLayoutProvider> layoutInstances = plugin.getLayoutProviders(); List<FGLayoutProvider> layoutInstances = plugin.getLayoutProviders();
return createActionStates(layoutInstances);
}
private List<ActionState<FGLayoutProvider>> createActionStates(
List<FGLayoutProvider> layoutProviders) {
List<ActionState<FGLayoutProvider>> list = new ArrayList<>(); List<ActionState<FGLayoutProvider>> list = new ArrayList<>();
HelpLocation layoutHelpLocation = HelpLocation layoutHelpLocation =
new HelpLocation("FunctionGraphPlugin", "Function_Graph_Action_Layout"); new HelpLocation("FunctionGraphPlugin", "Function_Graph_Action_Layout");
for (FGLayoutProvider layout : layoutInstances) { for (FGLayoutProvider layout : layoutProviders) {
ActionState<FGLayoutProvider> layoutState = new ActionState<>( ActionState<FGLayoutProvider> layoutState =
layout.getLayoutName(), layout.getActionIcon(), layout); new ActionState<>(layout.getLayoutName(), layout.getActionIcon(), layout);
layoutState.setHelpLocation(layoutHelpLocation); layoutState.setHelpLocation(layoutHelpLocation);
list.add(layoutState); list.add(layoutState);
} }
@@ -1157,8 +1159,7 @@ class FGActionManager {
private void makeSelectionFromAddresses(AddressSet addresses) { private void makeSelectionFromAddresses(AddressSet addresses) {
ProgramSelection selection = new ProgramSelection(addresses); ProgramSelection selection = new ProgramSelection(addresses);
plugin.getTool() plugin.getTool()
.firePluginEvent( .firePluginEvent(new ProgramSelectionPluginEvent("Spoof!", selection,
new ProgramSelectionPluginEvent("Spoof!", selection,
provider.getCurrentProgram())); provider.getCurrentProgram()));
} }
@@ -1214,6 +1215,11 @@ class FGActionManager {
layoutAction.setCurrentActionState(state); layoutAction.setCurrentActionState(state);
} }
void setLayouts(List<FGLayoutProvider> layouts) {
List<ActionState<FGLayoutProvider>> states = createActionStates(layouts);
layoutAction.setActionStates(states);
}
ActionState<FGLayoutProvider> getCurrentLayoutState() { ActionState<FGLayoutProvider> getCurrentLayoutState() {
return layoutAction.getCurrentState(); return layoutAction.getCurrentState();
} }
@@ -54,6 +54,7 @@ import ghidra.app.plugin.core.clipboard.ClipboardPlugin;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.plugin.core.functiongraph.graph.*; import ghidra.app.plugin.core.functiongraph.graph.*;
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider; import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider;
import ghidra.app.plugin.core.functiongraph.graph.layout.TestFGLayoutProvider;
import ghidra.app.plugin.core.functiongraph.graph.vertex.*; import ghidra.app.plugin.core.functiongraph.graph.vertex.*;
import ghidra.app.plugin.core.functiongraph.mvc.*; import ghidra.app.plugin.core.functiongraph.mvc.*;
import ghidra.app.services.*; import ghidra.app.services.*;
@@ -74,6 +75,7 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.test.*; import ghidra.test.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.AssertException;
import ghidra.util.task.RunManager; import ghidra.util.task.RunManager;
public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedIntegrationTest { public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedIntegrationTest {
@@ -552,11 +554,19 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
protected void showFunctionGraphProvider() { protected void showFunctionGraphProvider() {
ComponentProvider provider = tool.getComponentProvider("Function Graph"); FGProvider provider = (FGProvider) tool.getComponentProvider("Function Graph");
tool.showComponentProvider(provider, true); tool.showComponentProvider(provider, true);
graphProvider = waitForComponentProvider(FGProvider.class); graphProvider = waitForComponentProvider(FGProvider.class);
assertNotNull("Graph not shown", graphProvider); assertNotNull("Graph not shown", graphProvider);
installTestGraphLayout(provider);
}
protected void installTestGraphLayout(FGProvider provider) {
FGActionManager actionManager = provider.getActionManager();
List<FGLayoutProvider> layouts = List.of(new TestFGLayoutProvider());
runSwing(() -> actionManager.setLayouts(layouts));
} }
protected ProgramSelection makeSingleVertexSelectionInCodeBrowser() { protected ProgramSelection makeSingleVertexSelectionInCodeBrowser() {
@@ -1222,12 +1232,6 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
protected FGData create12345Graph() { protected FGData create12345Graph() {
//
// Note: we are manipulating the graph for testing by removing vertices. Some layouts
// do not handle this well, so we will use one we know works.
//
setMinCrossLayout();
// function sscanf // function sscanf
FGData funtionGraphData = graphFunction("100415a"); FGData funtionGraphData = graphFunction("100415a");
@@ -1998,21 +2002,21 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
private void setMinCrossLayout() { private void setMinCrossLayout() {
Object actionManager = getInstanceField("actionManager", graphProvider); Object actionManager = getInstanceField("actionManager", graphProvider);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final MultiStateDockingAction<Class<? extends FGLayoutProvider>> action = final MultiStateDockingAction<FGLayoutProvider> action =
(MultiStateDockingAction<Class<? extends FGLayoutProvider>>) getInstanceField( (MultiStateDockingAction<FGLayoutProvider>) getInstanceField("layoutAction",
"layoutAction", actionManager); actionManager);
runSwing(() -> { runSwing(() -> {
List<ActionState<Class<? extends FGLayoutProvider>>> states = List<ActionState<FGLayoutProvider>> states = action.getAllActionStates();
action.getAllActionStates(); for (ActionState<FGLayoutProvider> state : states) {
for (ActionState<Class<? extends FGLayoutProvider>> state : states) { FGLayoutProvider layoutProvider = state.getUserData();
Class<? extends FGLayoutProvider> layoutClass = state.getUserData(); if (layoutProvider.getLayoutName().contains("MinCross")) {
if (layoutClass.getSimpleName().contains("MinCross")) {
action.setCurrentActionState(state); action.setCurrentActionState(state);
return;
} }
} }
throw new AssertException("Unable to find MinCross layout");
}); });
} }
protected FGData triggerPersistenceAndReload(String functionAddress) { protected FGData triggerPersistenceAndReload(String functionAddress) {
@@ -838,11 +838,6 @@ public class FunctionGraphGroupVertices1Test extends AbstractFunctionGraphTest {
assertEquals(alpha, alphAfterGroup); assertEquals(alpha, alphAfterGroup);
} }
@Test
public void testSymbolAddedWhenGrouped_SymbolOutsideOfGroupNode() {
// TODO
}
//================================================================================================== //==================================================================================================
// Private Methods // Private Methods
//================================================================================================== //==================================================================================================
@@ -50,7 +50,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
private static Icon EMPTY_ICON = new EmptyIcon(16, 16); private static Icon EMPTY_ICON = new EmptyIcon(16, 16);
private List<ActionState<T>> actionStates = new ArrayList<>(); private List<ActionState<T>> actionStates = new ArrayList<>();
private int currentStateIndex = 0; private int currentStateIndex = -1;
private MultiActionDockingActionIf multiActionGenerator; private MultiActionDockingActionIf multiActionGenerator;
private MultipleActionDockingToolbarButton multipleButton; private MultipleActionDockingToolbarButton multipleButton;
@@ -270,10 +270,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
} }
currentStateIndex = indexOf; currentStateIndex = indexOf;
// we set the icon here to handle the odd case where this action is not used in a toolbar
if (multipleButton != null) {
setButtonState(actionState); setButtonState(actionState);
}
ToolBarData tbd = getToolBarData(); ToolBarData tbd = getToolBarData();
tbd.setIcon(getIcon(actionState)); tbd.setIcon(getIcon(actionState));
@@ -317,6 +314,16 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
private void setButtonState(ActionState<T> actionState) { private void setButtonState(ActionState<T> actionState) {
if (multipleButton == null) {
return;
}
if (actionState == null) {
multipleButton.setIcon(null);
multipleButton.setToolTipText(null);
return;
}
Icon icon = getIcon(actionState); Icon icon = getIcon(actionState);
multipleButton.setIcon(icon); multipleButton.setIcon(icon);
multipleButton.setToolTipText(actionState.getName()); multipleButton.setToolTipText(actionState.getName());
@@ -337,6 +344,9 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
} }
public String getToolTipText() { public String getToolTipText() {
if (actionStates.isEmpty()) {
return getName() + ": <no action states installed>";
}
return getName() + ": " + getCurrentState().getName(); return getName() + ": " + getCurrentState().getName();
} }
@@ -355,8 +365,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
setSelected(isSelected); setSelected(isSelected);
setMenuBarData( setMenuBarData(new MenuData(new String[] { actionState.getName() }));
new MenuData(new String[] { actionState.getName() }));
HelpLocation helpLocation = actionState.getHelpLocation(); HelpLocation helpLocation = actionState.getHelpLocation();
if (helpLocation != null) { if (helpLocation != null) {
setHelpLocation(helpLocation); setHelpLocation(helpLocation);