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

View file

@ -189,8 +189,8 @@ class FGActionManager {
return !(context instanceof FunctionGraphVertexLocationInFullViewModeActionContext);
}
};
zoomOutAction.setPopupMenuData(
new MenuData(new String[] { "Zoom Out" }, popuEndPopupGroup));
zoomOutAction
.setPopupMenuData(new MenuData(new String[] { "Zoom Out" }, popuEndPopupGroup));
zoomOutAction.setKeyBindingData(new KeyBindingData(
KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, DockingUtils.CONTROL_KEY_MODIFIER_MASK)));
zoomOutAction.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Zoom"));
@ -325,8 +325,8 @@ class FGActionManager {
menuData.setMenuSubGroup(Integer.toString(vertexGroupingSubgroupOffset++));
editLabelAction.setDescription("Change the label for the code block");
editLabelAction.setPopupMenuData(menuData);
editLabelAction.setHelpLocation(
new HelpLocation("FunctionGraphPlugin", "Vertex_Action_Label"));
editLabelAction
.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Vertex_Action_Label"));
DockingAction fullViewAction = new DockingAction("Vertex View Mode", plugin.getName()) {
@Override
@ -717,8 +717,8 @@ class FGActionManager {
};
selectHoveredEdgesAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "From Hovered Edges" }, popupSelectionGroup2));
selectHoveredEdgesAction.setHelpLocation(
new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
selectHoveredEdgesAction
.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
DockingAction selectFocusedEdgesAction =
new DockingAction("Make Selection From Focused Edges", plugin.getName()) {
@ -751,8 +751,8 @@ class FGActionManager {
};
selectFocusedEdgesAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "From Focused Edges" }, popupSelectionGroup2));
selectFocusedEdgesAction.setHelpLocation(
new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
selectFocusedEdgesAction
.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
DockingAction clearCurrentSelectionAction =
new DockingAction("Clear Current Selection", plugin.getName()) {
@ -775,8 +775,8 @@ class FGActionManager {
};
clearCurrentSelectionAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "Clear Graph Selection" }, popupSelectionGroup3));
clearCurrentSelectionAction.setHelpLocation(
new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
clearCurrentSelectionAction
.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Path_Selection"));
DockingAction selectAllAction =
new DockingAction("Select All Code Units", plugin.getName()) {
@ -815,12 +815,12 @@ class FGActionManager {
return isValidContext(context);
}
};
selectAllAction.setKeyBindingData(
new KeyBindingData(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
selectAllAction
.setKeyBindingData(new KeyBindingData(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
selectAllAction.setPopupMenuData(new MenuData(
new String[] { selectionMenuName, "Select All Code Units" }, popupSelectionGroup3));
selectAllAction.setHelpLocation(
new HelpLocation("FunctionGraphPlugin", "Code_Unit_Selection"));
selectAllAction
.setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Code_Unit_Selection"));
provider.addLocalAction(chooseFormatsAction);
provider.addLocalAction(homeAction);
@ -885,9 +885,7 @@ class FGActionManager {
// icon to be blank in the menu, but to use this icon on the toolbar.
layoutAction.setDefaultIcon(ResourceManager.loadImage("images/preferences-system.png"));
List<ActionState<FGLayoutProvider>> actionStates =
loadActionStatesForLayoutProviders();
List<ActionState<FGLayoutProvider>> actionStates = loadActionStatesForLayoutProviders();
for (ActionState<FGLayoutProvider> actionState : actionStates) {
layoutAction.addActionState(actionState);
}
@ -900,15 +898,19 @@ class FGActionManager {
}
private List<ActionState<FGLayoutProvider>> loadActionStatesForLayoutProviders() {
List<FGLayoutProvider> layoutInstances = plugin.getLayoutProviders();
return createActionStates(layoutInstances);
}
private List<ActionState<FGLayoutProvider>> createActionStates(
List<FGLayoutProvider> layoutProviders) {
List<ActionState<FGLayoutProvider>> list = new ArrayList<>();
HelpLocation layoutHelpLocation =
new HelpLocation("FunctionGraphPlugin", "Function_Graph_Action_Layout");
for (FGLayoutProvider layout : layoutInstances) {
for (FGLayoutProvider layout : layoutProviders) {
ActionState<FGLayoutProvider> layoutState = new ActionState<>(
layout.getLayoutName(), layout.getActionIcon(), layout);
ActionState<FGLayoutProvider> layoutState =
new ActionState<>(layout.getLayoutName(), layout.getActionIcon(), layout);
layoutState.setHelpLocation(layoutHelpLocation);
list.add(layoutState);
}
@ -1157,8 +1159,7 @@ class FGActionManager {
private void makeSelectionFromAddresses(AddressSet addresses) {
ProgramSelection selection = new ProgramSelection(addresses);
plugin.getTool()
.firePluginEvent(
new ProgramSelectionPluginEvent("Spoof!", selection,
.firePluginEvent(new ProgramSelectionPluginEvent("Spoof!", selection,
provider.getCurrentProgram()));
}
@ -1214,6 +1215,11 @@ class FGActionManager {
layoutAction.setCurrentActionState(state);
}
void setLayouts(List<FGLayoutProvider> layouts) {
List<ActionState<FGLayoutProvider>> states = createActionStates(layouts);
layoutAction.setActionStates(states);
}
ActionState<FGLayoutProvider> getCurrentLayoutState() {
return layoutAction.getCurrentState();
}

View file

@ -54,6 +54,7 @@ import ghidra.app.plugin.core.clipboard.ClipboardPlugin;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.plugin.core.functiongraph.graph.*;
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.mvc.*;
import ghidra.app.services.*;
@ -74,6 +75,7 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.test.*;
import ghidra.util.Msg;
import ghidra.util.exception.AssertException;
import ghidra.util.task.RunManager;
public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedIntegrationTest {
@ -552,11 +554,19 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
protected void showFunctionGraphProvider() {
ComponentProvider provider = tool.getComponentProvider("Function Graph");
FGProvider provider = (FGProvider) tool.getComponentProvider("Function Graph");
tool.showComponentProvider(provider, true);
graphProvider = waitForComponentProvider(FGProvider.class);
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() {
@ -1222,12 +1232,6 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
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
FGData funtionGraphData = graphFunction("100415a");
@ -1998,21 +2002,21 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
private void setMinCrossLayout() {
Object actionManager = getInstanceField("actionManager", graphProvider);
@SuppressWarnings("unchecked")
final MultiStateDockingAction<Class<? extends FGLayoutProvider>> action =
(MultiStateDockingAction<Class<? extends FGLayoutProvider>>) getInstanceField(
"layoutAction", actionManager);
final MultiStateDockingAction<FGLayoutProvider> action =
(MultiStateDockingAction<FGLayoutProvider>) getInstanceField("layoutAction",
actionManager);
runSwing(() -> {
List<ActionState<Class<? extends FGLayoutProvider>>> states =
action.getAllActionStates();
for (ActionState<Class<? extends FGLayoutProvider>> state : states) {
Class<? extends FGLayoutProvider> layoutClass = state.getUserData();
if (layoutClass.getSimpleName().contains("MinCross")) {
List<ActionState<FGLayoutProvider>> states = action.getAllActionStates();
for (ActionState<FGLayoutProvider> state : states) {
FGLayoutProvider layoutProvider = state.getUserData();
if (layoutProvider.getLayoutName().contains("MinCross")) {
action.setCurrentActionState(state);
return;
}
}
throw new AssertException("Unable to find MinCross layout");
});
}
protected FGData triggerPersistenceAndReload(String functionAddress) {

View file

@ -838,11 +838,6 @@ public class FunctionGraphGroupVertices1Test extends AbstractFunctionGraphTest {
assertEquals(alpha, alphAfterGroup);
}
@Test
public void testSymbolAddedWhenGrouped_SymbolOutsideOfGroupNode() {
// TODO
}
//==================================================================================================
// Private Methods
//==================================================================================================

View file

@ -50,7 +50,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
private static Icon EMPTY_ICON = new EmptyIcon(16, 16);
private List<ActionState<T>> actionStates = new ArrayList<>();
private int currentStateIndex = 0;
private int currentStateIndex = -1;
private MultiActionDockingActionIf multiActionGenerator;
private MultipleActionDockingToolbarButton multipleButton;
@ -270,10 +270,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
}
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);
}
ToolBarData tbd = getToolBarData();
tbd.setIcon(getIcon(actionState));
@ -317,6 +314,16 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
private void setButtonState(ActionState<T> actionState) {
if (multipleButton == null) {
return;
}
if (actionState == null) {
multipleButton.setIcon(null);
multipleButton.setToolTipText(null);
return;
}
Icon icon = getIcon(actionState);
multipleButton.setIcon(icon);
multipleButton.setToolTipText(actionState.getName());
@ -337,6 +344,9 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
}
public String getToolTipText() {
if (actionStates.isEmpty()) {
return getName() + ": <no action states installed>";
}
return getName() + ": " + getCurrentState().getName();
}
@ -355,8 +365,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
setSelected(isSelected);
setMenuBarData(
new MenuData(new String[] { actionState.getName() }));
setMenuBarData(new MenuData(new String[] { actionState.getName() }));
HelpLocation helpLocation = actionState.getHelpLocation();
if (helpLocation != null) {
setHelpLocation(helpLocation);