diff --git a/Ghidra/Features/Base/ghidra_scripts/DeleteFunctionDefaultPlates.java b/Ghidra/Features/Base/ghidra_scripts/DeleteFunctionDefaultPlatesScript.java similarity index 86% rename from Ghidra/Features/Base/ghidra_scripts/DeleteFunctionDefaultPlates.java rename to Ghidra/Features/Base/ghidra_scripts/DeleteFunctionDefaultPlatesScript.java index 70d29dd513..bdd851f67a 100644 --- a/Ghidra/Features/Base/ghidra_scripts/DeleteFunctionDefaultPlates.java +++ b/Ghidra/Features/Base/ghidra_scripts/DeleteFunctionDefaultPlatesScript.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,20 +22,18 @@ import ghidra.program.model.address.AddressSetView; import ghidra.program.model.listing.Function; import ghidra.program.model.listing.FunctionIterator; -public class DeleteFunctionDefaultPlates extends GhidraScript { +public class DeleteFunctionDefaultPlatesScript extends GhidraScript { private static String DEFAULT_PLATE = " FUNCTION"; - /* (non-Javadoc) - * @see ghidra.app.script.GhidraScript#run() - */ + @Override - public void run() throws Exception { + public void run() throws Exception { AddressSetView set = currentProgram.getMemory(); if (currentSelection != null && !currentSelection.isEmpty()) { set = currentSelection; } - int updateCount=0; + int updateCount = 0; FunctionIterator iter = currentProgram.getFunctionManager().getFunctions(set, true); while (iter.hasNext()) { Function function = iter.next(); @@ -47,7 +44,7 @@ public class DeleteFunctionDefaultPlates extends GhidraScript { } } if (updateCount > 0) { - String cmt = updateCount > 1? "comments" : "comment"; + String cmt = updateCount > 1 ? "comments" : "comment"; println("Removed " + updateCount + " default plate " + cmt + "."); } else { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreePlugin.java index 57b6ea4eed..fd3574bc5a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreePlugin.java @@ -148,6 +148,14 @@ public class CallTreePlugin extends ProgramPlugin { tool.showComponentProvider(provider, true); } + CallTreeProvider getPrimaryProvider() { + return primaryProvider; + } + + DockingAction getShowCallTreeFromMenuAction() { + return showCallTreeFromMenuAction; + } + ProgramLocation getCurrentLocation() { return currentLocation; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreeProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreeProvider.java index f61684e6e8..f66e9e4a8c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreeProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/calltree/CallTreeProvider.java @@ -876,6 +876,7 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain // changes, which means we will get here while setting the location, but our program // will have been null'ed out. currentProgram = plugin.getCurrentProgram(); + currentProgram.addListener(this); } Function function = plugin.getFunction(location); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java index 084d6ec6e4..0d5259ff24 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java @@ -915,18 +915,13 @@ public class CodeBrowserPlugin extends Plugin } }; + // note: this action gets added later when the TableService is added tableFromSelectionAction.setEnabled(false); tableFromSelectionAction.setMenuBarData(new MenuData( new String[] { ToolConstants.MENU_SELECTION, "Create Table From Selection" }, null, "SelectUtils")); - tableFromSelectionAction - .setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Selection_Table")); - - // don't add the actions initially if the service isn't there - TableService tableService = tool.getService(TableService.class); - if (tableService != null) { - tool.addAction(tableFromSelectionAction); - } + tableFromSelectionAction.setHelpLocation( + new HelpLocation("CodeBrowserPlugin", "Selection_Table")); } private GhidraProgramTableModel
createTableModel(CodeUnitIterator iterator, @@ -1001,8 +996,8 @@ public class CodeBrowserPlugin extends Plugin public boolean goToField(Address a, String fieldName, int occurrence, int row, int col, boolean scroll) { - boolean result = SystemUtilities - .runSwingNow(() -> doGoToField(a, fieldName, occurrence, row, col, scroll)); + boolean result = SystemUtilities.runSwingNow( + () -> doGoToField(a, fieldName, occurrence, row, col, scroll)); return result; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java index bee0678a85..430302b29a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java @@ -36,7 +36,6 @@ import docking.widgets.fieldpanel.FieldPanel; import docking.widgets.fieldpanel.HoverHandler; import docking.widgets.fieldpanel.internal.FieldPanelCoordinator; import docking.widgets.fieldpanel.support.*; -import ghidra.GhidraOptions; import ghidra.app.nav.*; import ghidra.app.plugin.core.clipboard.CodeBrowserClipboardProvider; import ghidra.app.plugin.core.codebrowser.actions.*; @@ -63,8 +62,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter private static final String TITLE = "Listing: "; - private static final String OPERAND_OPTIONS_PREFIX = GhidraOptions.OPERAND_GROUP_TITLE + "."; - private static final Icon LISTING_FORMAT_EXPAND_ICON = ResourceManager.loadImage("images/field.header.down.png"); private static final Icon LISTING_FORMAT_COLLAPSE_ICON = @@ -93,9 +90,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter private ProgramDropProvider curDropProvider; private ToggleDockingAction toggleHoverAction; - //TODO - Need to improve CodeUnit.getRepresentation format options interface before adding this - //TODO private ToggleOperandMarkupAction[] toggleOperandMarkupActions; - private ProgramLocation currentLocation; private ListingPanel otherPanel; @@ -976,9 +970,9 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter } } - class ToggleHoverAction extends ToggleDockingAction { + private class ToggleHoverAction extends ToggleDockingAction { ToggleHoverAction() { - super("Toggle Mouse Hover Popups", CodeViewerProvider.this.getName()); + super("Toggle Mouse Hover Popups", CodeViewerProvider.this.getOwner()); setEnabled(true); setToolBarData(new ToolBarData(HOVER_ON_ICON, "yyyz")); setSelected(true); @@ -998,31 +992,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter } } - class ToggleOperandMarkupAction extends ToggleDockingAction { - final String optionName; - - ToggleOperandMarkupAction(String operandOption) { - super(operandOption, CodeViewerProvider.this.getName()); - this.optionName = OPERAND_OPTIONS_PREFIX + operandOption; - boolean state = - tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS).getBoolean(optionName, true); - setMenuBarData(new MenuData(new String[] { operandOption })); - setSelected(state); - setEnabled(true); - setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Operands_Field")); - } - - public Object getOptionName() { - return optionName; - } - - @Override - public void actionPerformed(ActionContext context) { - boolean state = isSelected(); - tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS).setBoolean(optionName, state); - } - } - /** * A class that allows clients to install transient highlighters while keeping the * middle-mouse highlighting on at the same time. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/CollapseAllDataAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/CollapseAllDataAction.java index aef5cd1983..b9e6e82b17 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/CollapseAllDataAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/CollapseAllDataAction.java @@ -39,7 +39,7 @@ public class CollapseAllDataAction extends ProgramLocationContextAction { private CodeViewerProvider provider; public CollapseAllDataAction(CodeViewerProvider provider) { - super("Collapse All Data", provider.getName()); + super("Collapse All Data", provider.getOwner()); this.provider = provider; setPopupMenuData(new MenuData(new String[] { "Collapse All Data" }, null, "Structure")); @@ -95,8 +95,7 @@ public class CollapseAllDataAction extends ProgramLocationContextAction { ProgramLocation location = context.getLocation(); Data data = getTopLevelComponentData(location); - TaskLauncher.launchModal("Collapse Data", - monitor -> model.closeAllData(data, monitor)); + TaskLauncher.launchModal("Collapse Data", monitor -> model.closeAllData(data, monitor)); } private ListingModel getModel() { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ExpandAllDataAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ExpandAllDataAction.java index 3983a5138a..47e02c433e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ExpandAllDataAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ExpandAllDataAction.java @@ -36,7 +36,7 @@ public class ExpandAllDataAction extends ProgramLocationContextAction { private CodeViewerProvider provider; public ExpandAllDataAction(CodeViewerProvider provider) { - super("Expand All Data", provider.getName()); + super("Expand All Data", provider.getOwner()); this.provider = provider; setPopupMenuData(new MenuData(new String[] { "Expand All Data" }, null, "Structure")); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ToggleExpandCollapseDataAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ToggleExpandCollapseDataAction.java index 537455f59c..93ffe7558b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ToggleExpandCollapseDataAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/actions/ToggleExpandCollapseDataAction.java @@ -39,7 +39,7 @@ public class ToggleExpandCollapseDataAction extends ProgramLocationContextAction private CodeViewerProvider provider; public ToggleExpandCollapseDataAction(CodeViewerProvider provider) { - super("Toggle Expand/Collapse Data", provider.getName()); + super("Toggle Expand/Collapse Data", provider.getOwner()); this.provider = provider; setPopupMenuData( diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/script/GhidraScriptActionManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/script/GhidraScriptActionManager.java index a04d236cda..de3105d085 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/script/GhidraScriptActionManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/script/GhidraScriptActionManager.java @@ -466,7 +466,6 @@ class GhidraScriptActionManager { if (action == null) { action = new ScriptAction(plugin, script); actionMap.put(script, action); - plugin.getTool().addAction(action); } return action; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java index 41be28e348..e6f57bbfd8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java @@ -347,7 +347,7 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener { private void createSymActions() { String popupGroup = "1"; - openRefsAction = new DockingAction("Symbol References", getName()) { + openRefsAction = new DockingAction("Symbol References", getName(), KeyBindingType.SHARED) { @Override public void actionPerformed(ActionContext context) { refProvider.open(); @@ -359,7 +359,7 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener { new MenuData(new String[] { "Symbol References" }, icon, popupGroup)); openRefsAction.setToolBarData(new ToolBarData(icon)); - openRefsAction.setDescription("Symbol References"); + openRefsAction.setDescription("Display Symbol References"); tool.addLocalAction(symProvider, openRefsAction); deleteAction = new DockingAction("Delete Symbols", getName()) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/PluginConstants.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/PluginConstants.java index fb77119627..98fbd60360 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/PluginConstants.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/PluginConstants.java @@ -62,7 +62,7 @@ public interface PluginConstants { */ char ANYSINGLECHAR_WILDCARD_CHAR = '?'; - String CODE_BROWSER = "CodeBrowserPlugin"; + String CODE_BROWSER = "Listing"; String MEMORY_MAP = "Memory Map"; String BYTE_VIEWER = "ByteViewerPlugin"; String BOOKMARKS = "Bookmarks"; diff --git a/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java b/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java index 4878d33f0a..e2a716518c 100644 --- a/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java @@ -159,6 +159,25 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio assertMenuItemHasKeyStroke(newKs); } + @Test + public void testSetKeyBinding_ViaDialog_FromWindowMenu_ToAlreadyBoundAction() { + + // + // Test the conflicting key binding use case + // + + HasDefaultKeyBindingComponentProvider otherProvider = + new HasDefaultKeyBindingComponentProvider(tool); + otherProvider.setVisible(true); + + showProvider(); + + KeyStroke newKs = CONTROL_T; + applyBindingToDialog_FromWindowsMenu(newKs); + + assertCollisionsWithKeyStroke(); + } + @Test public void testSetKeyBinding_ViaOptions_WithoutToolbarAction() { @@ -235,6 +254,14 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio } } + @Test + public void testDefaultKeyBindingAppearsInWindowMenu() { + + provider.setDefaultKeyBinding(new KeyBindingData(CONTROL_T)); + showProvider(); + assertWindowMenuActionHasKeyBinding(CONTROL_T); + } + //================================================================================================== // Private Methods //================================================================================================== @@ -279,7 +306,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio .stream() .filter(a -> a.getOwner().equals(DockingWindowManager.DOCKING_WINDOWS_OWNER)) .findFirst() - .get() + .orElseGet(() -> null) ; //@formatter:on }); @@ -310,7 +337,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio } private void assertNoToolbarAction() { - assertNotNull("No toolbar action found for provider", getToolbarShowProviderAction()); + assertNull("No toolbar action found for provider", getToolbarShowProviderAction()); } private void assertToolbarAction() { @@ -341,6 +368,13 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio expected, action.getMenuBarData().getMenuIcon()); } + private void assertWindowMenuActionHasKeyBinding(KeyStroke ks) { + DockingActionIf action = getWindowMenuShowProviderAction(); + assertEquals( + "Windows menu key bindings for provider does not match the value set on the provider", + ks, action.getKeyBinding()); + } + private void assertCannotShowKeyBindingDialog_FromWindowsMenu() { // simulate the user mousing over the 'Window' menu's action DockingActionIf windowMenuAction = getWindowMenuShowProviderAction(); @@ -367,6 +401,24 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio assertFalse("Invalid key stroke: " + ks, runSwing(() -> dialog.isVisible())); } + private void applyBindingToDialog_FromWindowsMenu(KeyStroke ks) { + DockingActionIf windowMenuAction = getWindowMenuShowProviderAction(); + DockingWindowManager.setMouseOverAction(windowMenuAction); + + performLaunchKeyStrokeDialogAction(); + KeyEntryDialog dialog = waitForDialogComponent(KeyEntryDialog.class); + + runSwing(() -> dialog.setKeyStroke(ks)); + } + + private void assertCollisionsWithKeyStroke() { + KeyEntryDialog dialog = waitForDialogComponent(KeyEntryDialog.class); + + JTextPane collisionPane = (JTextPane) getInstanceField("collisionPane", dialog); + String collisionText = runSwing(() -> collisionPane.getText()); + assertTrue(collisionText.contains("Actions mapped to")); + } + private void assertMenuItemHasKeyStroke(KeyStroke expected) { DockingActionIf action = getWindowMenuShowProviderAction(); @@ -415,6 +467,21 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio public JComponent getComponent() { return component; } + } + private class HasDefaultKeyBindingComponentProvider extends ComponentProvider { + private JComponent component = new JTextField("Hey!"); + + HasDefaultKeyBindingComponentProvider(DockingTool tool) { + super(tool, HasDefaultKeyBindingComponentProvider.class.getSimpleName(), + "Fooberry Plugin"); + + setDefaultKeyBinding(new KeyBindingData(CONTROL_T)); + } + + @Override + public JComponent getComponent() { + return component; + } } } diff --git a/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java index d2014732bb..e5031119fc 100644 --- a/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java @@ -18,6 +18,7 @@ package docking.action; import static org.junit.Assert.*; import java.awt.event.KeyEvent; +import java.util.Map; import javax.swing.*; @@ -25,6 +26,7 @@ import org.junit.*; import docking.*; import docking.actions.KeyEntryDialog; +import docking.actions.ToolActions; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.data.DataPlugin; import ghidra.app.plugin.core.function.FunctionPlugin; @@ -186,20 +188,26 @@ public class KeyEntryDialogTest extends AbstractGhidraHeadedIntegrationTest { } public DockingAction getKeyBindingAction() { - DockingWindowManager dwm = DockingWindowManager.getInstance(tool.getToolFrame()); - ActionToGuiMapper dockingActionManager = - (ActionToGuiMapper) getInstanceField("actionManager", dwm); - return (DockingAction) getInstanceField("keyBindingsAction", dockingActionManager); + + ToolActions toolActions = tool.getToolActions(); + KeyBindingsManager kbm = + (KeyBindingsManager) getInstanceField("keyBindingsManager", toolActions); + Map dockingKeyMap = + (Map) getInstanceField("dockingKeyMap", kbm); + KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0); + DockingKeyBindingAction dockingAction = dockingKeyMap.get(ks); + DockingAction f4Action = (DockingAction) getInstanceField("docakbleAction", dockingAction); + return f4Action; } private void showDialog(final DockingAction actionToEdit) throws Exception { - final DockingAction keyBindingAction = getKeyBindingAction(); + DockingAction keyBindingAction = getKeyBindingAction(); executeOnSwingWithoutBlocking(() -> { DockingWindowManager.setMouseOverAction(actionToEdit); performAction(keyBindingAction, false); }); - keyEntryDialog = waitForDialogComponent(tool.getToolFrame(), KeyEntryDialog.class, 2000); + keyEntryDialog = waitForDialogComponent(KeyEntryDialog.class); assertNotNull(keyEntryDialog); collisionPane = (JTextPane) getInstanceField("collisionPane", keyEntryDialog); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/bookmark/BookmarkPluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/bookmark/BookmarkPluginTest.java index aef5b20654..25724c56e2 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/bookmark/BookmarkPluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/bookmark/BookmarkPluginTest.java @@ -718,7 +718,7 @@ public class BookmarkPluginTest extends AbstractGhidraHeadedIntegrationTest { } private void showBookmarkProvider() throws Exception { - DockingActionIf action = getAction(plugin, "Show Bookmarks"); + DockingActionIf action = getAction(plugin, "Bookmarks"); performAction(action, true); table = plugin.getBookmarkTable(); waitForTable(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/calltree/CallTreePluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/calltree/CallTreePluginTest.java index a5e2a57ea3..d6858474de 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/calltree/CallTreePluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/calltree/CallTreePluginTest.java @@ -46,7 +46,6 @@ import ghidra.framework.plugintool.PluginTool; import ghidra.program.database.ProgramBuilder; import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressFactory; import ghidra.program.model.data.DataType; import ghidra.program.model.data.PointerDataType; import ghidra.program.model.listing.Function; @@ -62,7 +61,6 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { private TestEnv env; private CodeBrowserPlugin codeBrowserPlugin; private PluginTool tool; - private ProgramDB program; private CallTreePlugin callTreePlugin; private CallTreeProvider provider; private List providers; @@ -70,14 +68,10 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { private GTree incomingTree; private GTree outgoingTree; - private DockingAction showProviderAction; + private ProgramBuilder builder; + private ProgramDB program; private GoToService goToService; - private AddressFactory addressFactory; - - public CallTreePluginTest() { - super(); - } @SuppressWarnings("unchecked") // cast to list @@ -91,7 +85,6 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { callTreePlugin = env.getPlugin(CallTreePlugin.class); providers = (List) getInstanceField("providers", callTreePlugin); - showProviderAction = (DockingAction) getInstanceField("showProviderAction", callTreePlugin); GoToServicePlugin goToPlugin = env.getPlugin(GoToServicePlugin.class); goToService = (GoToService) invokeInstanceMethod("getGotoService", goToPlugin); @@ -100,20 +93,18 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { env.showTool(); program = createProgram(); - addressFactory = program.getAddressFactory(); ProgramManager pm = tool.getService(ProgramManager.class); pm.openProgram(program.getDomainFile()); // setup a good start location goTo(addr("5000")); - provider = getProvider(); + provider = callTreePlugin.getPrimaryProvider(); + tool.showComponentProvider(provider, true); incomingTree = (GTree) getInstanceField("incomingTree", provider); outgoingTree = (GTree) getInstanceField("outgoingTree", provider); } - ProgramBuilder builder; - private ProgramDB createProgram() throws Exception { builder = new ProgramBuilder("Call Trees", ProgramBuilder._TOY); @@ -385,21 +376,21 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { assertNotNull("Provider did not update its information when made visible", providerFunction()); - final ToggleDockingAction navigateIncomingLoctionsAction = + ToggleDockingAction navigateIncomingLoctionsAction = (ToggleDockingAction) getAction("Navigation Incoming Location Changes"); - assertTrue(!navigateIncomingLoctionsAction.isSelected()); + setToggleActionSelected(navigateIncomingLoctionsAction, provider.getActionContext(null), + false); assertEquals("Provider's location does not match that of the listing.", currentFunction(), providerFunction()); goTo(addr("0x6000")); - assertTrue("Provider's location matches that of the listing when not following " + - "location changes.", !currentFunction().equals(providerFunction())); - + assertNotEquals("Provider's location matches that of the listing when not following " + + "location changes", currentFunction(), providerFunction()); performAction(navigateIncomingLoctionsAction, true); - assertEquals("Provider's location does not match that of the listing.", currentFunction(), + assertEquals("Provider's location does not match that of the listing", currentFunction(), providerFunction()); } @@ -779,21 +770,6 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { return functionManager.getFunctionAt(address); } - private CallTreeProvider getProvider() { - final AtomicReference ref = new AtomicReference<>(); - - // run in swing, as two threads are accessing/manipulating a variable - runSwing(() -> { - if (providers.size() == 0) { - ref.set(showProvider()); - } - else { - ref.set(providers.get(0)); - } - }); - return ref.get(); - } - private CallTreeProvider getProvider(final String address) { final CallTreeProvider[] providerBox = new CallTreeProvider[1]; @@ -939,13 +915,13 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { } private void fullyExpandIncomingNode(GTreeNode node) { - DockingActionIf expandAction = getAction(callTreePlugin, "Fully Expand Selected Nodes"); + DockingActionIf expandAction = getLocalAction(provider, "Fully Expand Selected Nodes"); performAction(expandAction, new ActionContext(provider, incomingTree), false); waitForTree(node.getTree()); } private void fullyExpandOutgoingNode(GTreeNode node) { - DockingActionIf expandAction = getAction(callTreePlugin, "Fully Expand Selected Nodes"); + DockingActionIf expandAction = getLocalAction(provider, "Fully Expand Selected Nodes"); performAction(expandAction, new ActionContext(provider, outgoingTree), false); waitForTree(node.getTree()); } @@ -1054,11 +1030,11 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { String name = child.getName(); Integer integer = map.get(name); if (integer == null) { - integer = new Integer(0); + integer = 0; } int asInt = integer; asInt++; - map.put(name, new Integer(asInt)); + map.put(name, asInt); } return map; } @@ -1088,10 +1064,7 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { } private DockingActionIf getAction(String actionName) { - // make sure there is a provider from which to get actions - getProvider(); - - DockingActionIf action = getAction(tool, "CallTreePlugin", actionName); + DockingActionIf action = getLocalAction(provider, actionName); return action; } @@ -1121,20 +1094,14 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest { } } - /** - * Shows and returns a provider for the current address. - */ - private CallTreeProvider showProvider() { - performAction(showProviderAction, true); - return getProvider(); - } - /** * Shows and returns a provider for the specified address. */ private CallTreeProvider showProvider(String address) { goTo(addr(address)); - performAction(showProviderAction, true); + + DockingAction action = callTreePlugin.getShowCallTreeFromMenuAction(); + performAction(action); return getProvider(address); } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/CodeBrowserScreenMovementTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/CodeBrowserScreenMovementTest.java index 19de6dd5b0..b4b0b56ee5 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/CodeBrowserScreenMovementTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/CodeBrowserScreenMovementTest.java @@ -61,6 +61,9 @@ public class CodeBrowserScreenMovementTest extends AbstractProgramBasedTest { @Before public void setUp() throws Exception { + // warning: this test is sensitive to size and layout of the visible component providers; + // any layout changes may affect the values being tested below + initialize(); fp = codeBrowser.getFieldPanel(); @@ -115,6 +118,9 @@ public class CodeBrowserScreenMovementTest extends AbstractProgramBasedTest { @Test public void testBasicControls() throws Exception { + // warning: this test is sensitive to size and layout of the visible component providers; + // any layout changes may affect the values being tested below + fp = codeBrowser.getFieldPanel(); ListingPanel panel = codeBrowser.getListingPanel(); JScrollBar scrollbar = panel.getVerticalScrollBar(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/ExpandCollapseDataActionsTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/ExpandCollapseDataActionsTest.java index 533cbab14f..30c892aad8 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/ExpandCollapseDataActionsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/codebrowser/ExpandCollapseDataActionsTest.java @@ -68,7 +68,7 @@ public class ExpandCollapseDataActionsTest extends AbstractGhidraHeadedIntegrati pm.openProgram(program.getDomainFile()); addrFactory = program.getAddressFactory(); env.showTool(); - provider = (CodeViewerProvider) tool.getComponentProvider("CodeBrowserPlugin"); + provider = (CodeViewerProvider) tool.getComponentProvider("Listing"); listingModel = provider.getListingPanel().getListingModel(); CodeBrowserPlugin plugin = getPlugin(tool, CodeBrowserPlugin.class); toggleExpand = getAction(plugin, "Toggle Expand/Collapse Data"); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorArchiveTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorArchiveTest.java index 579053f4e1..188830ed15 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorArchiveTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorArchiveTest.java @@ -62,7 +62,7 @@ public class StructureEditorArchiveTest extends AbstractStructureEditorTest { tool.addPlugin(DataTypeManagerPlugin.class.getName()); dtmService = tool.getService(DataTypeManagerService.class); plugin = (DataTypeManagerPlugin) dtmService; - manageDts = getAction(plugin, "Data Type Manager"); + manageDts = getAction(plugin, "DataTypes Provider"); DataTypesProvider dataTypesProvider = plugin.getProvider(); dtTree = dataTypesProvider.getGTree(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/ArchiveRemappedHeadedTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/ArchiveRemappedHeadedTest.java index 6398057965..77e531847f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/ArchiveRemappedHeadedTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/ArchiveRemappedHeadedTest.java @@ -55,14 +55,6 @@ public class ArchiveRemappedHeadedTest extends AbstractGhidraHeadedIntegrationTe private File vs12ArchiveFile; private File vs9ArchiveFile; - /** - * Constructor for ArchiveRemappedTest. - * @param testName - */ - public ArchiveRemappedHeadedTest() { - super(); - } - @Before public void setUp() throws Exception { @@ -97,10 +89,9 @@ public class ArchiveRemappedHeadedTest extends AbstractGhidraHeadedIntegrationTe env.showTool(); - tool.showComponentProvider(provider, true); - waitForPostedSwingRunnables(); - provider = plugin.getProvider(); + tool.showComponentProvider(provider, true); + tree = provider.getGTree(); waitForTree(tree); } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java index e0b69ccf3f..a6f1c6bc5f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java @@ -87,7 +87,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { @Test public void testActionEnabled() { - DockingActionIf action = getAction(plugin, "View Memory Map"); + DockingActionIf action = getAction(plugin, "Memory Map"); assertTrue(action.isEnabled()); } @@ -99,7 +99,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { Set actions = getActionsByOwner(tool, plugin.getName()); for (DockingActionIf action : actions) { if (action.getName().equals("Add Block") || action.getName().equals("Set Image Base") || - action.getName().equals("View Memory Map")) { + action.getName().equals("Memory Map")) { assertTrue(action.isEnabledForContext(provider.getActionContext(null))); } else { @@ -116,7 +116,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { assertEquals(0, table.getModel().getRowCount()); Set actions = getActionsByOwner(tool, plugin.getName()); for (DockingActionIf action : actions) { - if (!action.getName().equals("View Memory Map")) { + if (!action.getName().equals("Memory Map")) { assertTrue(!action.isEnabledForContext(provider.getActionContext(null))); } } @@ -297,7 +297,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { ///////////////////////////////////////////////////////////////////////// private void showProvider() { - DockingActionIf action = getAction(plugin, "View Memory Map"); + DockingActionIf action = getAction(plugin, "Memory Map"); performAction(action, true); provider = plugin.getMemoryMapProvider(); } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider1Test.java index 528773a745..69f95b362f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider1Test.java @@ -137,7 +137,7 @@ public class MemoryMapProvider1Test extends AbstractGhidraHeadedIntegrationTest String name = action.getName(); if (name.equals("Add Block") || name.equals("Merge Blocks") || name.equals("Delete Block") || name.equals("Set Image Base") || - name.equals("View Memory Map")) { + name.equals("Memory Map")) { assertTrue(action.isEnabled()); } else { @@ -667,7 +667,7 @@ public class MemoryMapProvider1Test extends AbstractGhidraHeadedIntegrationTest ///////////////////////////////////////////////////////////////////// private void showProvider() { - DockingActionIf action = getAction(plugin, "View Memory Map"); + DockingActionIf action = getAction(plugin, "Memory Map"); performAction(action, true); waitForPostedSwingRunnables(); provider = plugin.getMemoryMapProvider(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider2Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider2Test.java index 6341a1da80..8209a275ad 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider2Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider2Test.java @@ -1332,7 +1332,7 @@ public class MemoryMapProvider2Test extends AbstractGhidraHeadedIntegrationTest /////////////////////////////////////////////////////////////////// private void showProvider() { - DockingActionIf action = getAction(plugin, "View Memory Map"); + DockingActionIf action = getAction(plugin, "Memory Map"); performAction(action, true); provider = plugin.getMemoryMapProvider(); table = provider.getTable(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java index fdc1c9c132..6df271bd1b 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java @@ -886,7 +886,7 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest /////////////////////////////////////////////////////////////////// private void showProvider() { - DockingActionIf action = getAction(plugin, "View Memory Map"); + DockingActionIf action = getAction(plugin, "Memory Map"); performAction(action, true); waitForPostedSwingRunnables(); provider = plugin.getMemoryMapProvider(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider4Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider4Test.java index 7b64ee0d31..940bf06e0e 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider4Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider4Test.java @@ -54,10 +54,6 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest private JTable table; private TableModel model; - public MemoryMapProvider4Test() { - super(); - } - private Program buildProgram(String programName) throws Exception { ProgramBuilder builder = new ProgramBuilder(programName, ProgramBuilder._TOY); builder.createMemory(".text", Long.toHexString(0x1001000), 0x6600); @@ -247,7 +243,7 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest } private void showProvider() { - DockingActionIf action = getAction(plugin, "View Memory Map"); + DockingActionIf action = getAction(plugin, "Memory Map"); performAction(action, true); waitForPostedSwingRunnables(); provider = plugin.getMemoryMapProvider(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/navigation/NextPrevAddressPluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/navigation/NextPrevAddressPluginTest.java index 17add00a55..8794cae194 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/navigation/NextPrevAddressPluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/navigation/NextPrevAddressPluginTest.java @@ -71,8 +71,7 @@ public class NextPrevAddressPluginTest extends AbstractGhidraHeadedIntegrationTe NextPrevAddressPlugin plugin = env.getPlugin(NextPrevAddressPlugin.class); previousAction = (MultiActionDockingAction) TestUtils.getInstanceField("previousAction", plugin); - nextAction = - (MultiActionDockingAction) TestUtils.getInstanceField("nextAction", plugin); + nextAction = (MultiActionDockingAction) TestUtils.getInstanceField("nextAction", plugin); GoToAddressLabelPlugin goToPlugin = env.getPlugin(GoToAddressLabelPlugin.class); dialog = goToPlugin.getDialog(); @@ -355,9 +354,9 @@ public class NextPrevAddressPluginTest extends AbstractGhidraHeadedIntegrationTe @SuppressWarnings("unchecked") // let caution fly private JButton findButtonForAction(DockingWindowManager windowManager, DockingAction action) { - Object actionManager = TestUtils.getInstanceField("actionManager", windowManager); + Object actionToGuiMapper = TestUtils.getInstanceField("actionToGuiMapper", windowManager); Object menuAndToolBarManager = - TestUtils.getInstanceField("menuAndToolBarManager", actionManager); + TestUtils.getInstanceField("menuAndToolBarManager", actionToGuiMapper); Map map = (Map) TestUtils.getInstanceField( "windowToActionManagerMap", menuAndToolBarManager); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/DeleteFunctionDefaultPlatesTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/DeleteFunctionDefaultPlatesScriptTest.java similarity index 89% rename from Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/DeleteFunctionDefaultPlatesTest.java rename to Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/DeleteFunctionDefaultPlatesScriptTest.java index 81b3e5f6d0..73d2eaf02c 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/DeleteFunctionDefaultPlatesTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/DeleteFunctionDefaultPlatesScriptTest.java @@ -37,12 +37,9 @@ import ghidra.program.util.ProgramSelection; import ghidra.test.*; /** - * Test for deleting default plate comments on a function. - * - * - * + * Test for deleting default plate comments on a function */ -public class DeleteFunctionDefaultPlatesTest extends AbstractGhidraHeadedIntegrationTest { +public class DeleteFunctionDefaultPlatesScriptTest extends AbstractGhidraHeadedIntegrationTest { private TestEnv env; private PluginTool tool; @@ -50,13 +47,6 @@ public class DeleteFunctionDefaultPlatesTest extends AbstractGhidraHeadedIntegra private File script; private ToyProgramBuilder builder; - public DeleteFunctionDefaultPlatesTest() { - super(); - } - - /* - * @see TestCase#setUp() - */ @Before public void setUp() throws Exception { env = new TestEnv(); @@ -71,11 +61,8 @@ public class DeleteFunctionDefaultPlatesTest extends AbstractGhidraHeadedIntegra ProgramManager pm = tool.getService(ProgramManager.class); pm.openProgram(program.getDomainFile()); - //script = - // new File(Application.getApplicationRootDirectory().getFile(), - // "Features/Base/ghidra_scripts/DeleteFunctionDefaultPlates.java"); script = Application.getModuleFile("Base", - "ghidra_scripts/DeleteFunctionDefaultPlates.java").getFile(true); + "ghidra_scripts/DeleteFunctionDefaultPlatesScript.java").getFile(true); env.showTool(); } @@ -97,9 +84,6 @@ public class DeleteFunctionDefaultPlatesTest extends AbstractGhidraHeadedIntegra return builder.getProgram(); } - /* - * @see TestCase#tearDown() - */ @After public void tearDown() throws Exception { env.dispose(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreePlugin1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreePlugin1Test.java index 72828b5064..54a1cf0ff4 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreePlugin1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreePlugin1Test.java @@ -90,7 +90,7 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest { tool.addPlugin(SymbolTreePlugin.class.getName()); plugin = env.getPlugin(SymbolTreePlugin.class); - symTreeAction = getAction(plugin, "Display Symbol Tree"); + symTreeAction = getAction(plugin, "Symbol Tree"); cbPlugin = env.getPlugin(CodeBrowserPlugin.class); util = new SymbolTreeTestUtils(plugin); @@ -107,15 +107,6 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest { env.dispose(); } - @Test - public void testActionEnabled() { - assertTrue(symTreeAction.isEnabledForContext(null)); - - util.openProgram(); - - assertTrue(symTreeAction.isEnabledForContext(null)); - } - @Test public void testShowDisplay() throws Exception { showSymbolTree(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreeTestUtils.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreeTestUtils.java index 0eaa3dd2d8..3d8dd8e9d2 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreeTestUtils.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symboltree/SymbolTreeTestUtils.java @@ -90,14 +90,14 @@ class SymbolTreeTestUtils { this.plugin = plugin; this.program = buildProgram(); - symTreeAction = getAction(plugin, "Display Symbol Tree"); + symTreeAction = getAction(plugin, "Symbol Tree"); } SymbolTreeTestUtils(SymbolTreePlugin plugin, Program program) { this.plugin = plugin; this.program = program; - symTreeAction = getAction(plugin, "Display Symbol Tree"); + symTreeAction = getAction(plugin, "Symbol Tree"); } public static Program buildProgram() throws Exception { diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symtable/SymbolTablePluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symtable/SymbolTablePluginTest.java index 785139cd12..08416bc884 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symtable/SymbolTablePluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/symtable/SymbolTablePluginTest.java @@ -21,6 +21,7 @@ import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.function.BiConsumer; import javax.swing.*; @@ -59,6 +60,7 @@ import ghidra.util.table.GhidraTableFilterPanel; import ghidra.util.table.ProgramTableModel; import ghidra.util.table.field.AddressBasedLocation; import ghidra.util.xml.XmlUtilities; +import util.CollectionUtils; public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest { @@ -93,8 +95,14 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest { plugin = env.getPlugin(SymbolTablePlugin.class); provider = (SymbolProvider) getInstanceField("symProvider", plugin); - viewSymAction = getAction(plugin, "View Symbol Table"); - viewRefAction = getAction(plugin, "View Symbol References"); + viewSymAction = getAction(plugin, "Symbol Table"); + + // this action is actually in the tool twice: once for the provider and once as a + // local action in the Symbol Table header, so we must pick one + Set symbolReferencesActions = + getActionsByOwnerAndName(tool, plugin.getName(), "Symbol References"); + viewRefAction = CollectionUtils.any(symbolReferencesActions); + deleteAction = getAction(plugin, "Delete Symbols"); makeSelectionAction = getAction(plugin, "Make Selection"); setFilterAction = getAction(plugin, "Set Filter"); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/ActionManager2Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/ActionManager2Test.java deleted file mode 100644 index 2a47bd67fe..0000000000 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/ActionManager2Test.java +++ /dev/null @@ -1,390 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.framework.main.datatree; - -import static org.junit.Assert.*; - -import java.awt.Container; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.*; -import javax.swing.tree.DefaultTreeCellEditor; -import javax.swing.tree.TreePath; - -import org.junit.*; - -import docking.ActionContext; -import docking.action.DockingActionIf; -import docking.action.ToggleDockingAction; -import docking.test.AbstractDockingTest; -import docking.widgets.OptionDialog; -import docking.widgets.tree.GTreeNode; -import docking.widgets.tree.GTreeRootNode; -import docking.widgets.tree.support.BreadthFirstIterator; -import ghidra.framework.data.DomainObjectAdapter; -import ghidra.framework.main.FrontEndTool; -import ghidra.framework.model.DomainFile; -import ghidra.framework.model.DomainFolder; -import ghidra.program.database.ProgramBuilder; -import ghidra.program.database.ProgramDB; -import ghidra.program.model.listing.Program; -import ghidra.test.AbstractGhidraHeadedIntegrationTest; -import ghidra.test.TestEnv; -import ghidra.util.task.TaskMonitorAdapter; -import resources.MultiIcon; -import resources.ResourceManager; - -/** - * - * Mores Tests for actions in the front end (Ghidra project window). - * - */ -public class ActionManager2Test extends AbstractGhidraHeadedIntegrationTest { - - private FrontEndTool frontEndTool; - private TestEnv env; - private DataTree tree; - private DomainFolder rootFolder; - private GTreeRootNode rootNode; - - @Before - public void setUp() throws Exception { - env = new TestEnv(); - - frontEndTool = env.getFrontEndTool(); - env.showFrontEndTool(); - tree = findComponent(frontEndTool.getToolFrame(), DataTree.class); - rootFolder = env.getProject().getProjectData().getRootFolder(); - - Program p = createDefaultProgram("p1", ProgramBuilder._TOY, this); - - rootFolder.createFile("notepad", p, TaskMonitorAdapter.DUMMY_MONITOR); - p.release(this); - - p = createDefaultProgram("p2", ProgramBuilder._TOY, this); - rootFolder.createFile("X07", p, TaskMonitorAdapter.DUMMY_MONITOR); - p.release(this); - - rootNode = tree.getRootNode(); - - expandPath(rootNode.getTreePath()); - } - - @After - public void tearDown() throws Exception { - env.dispose(); - } - - @Test - public void testRenameFolder() throws Exception { - rootFolder.createFolder("myFolder"); - waitForSwing(); - - final GTreeNode myNode = rootNode.getChild("myFolder"); - setSelectionPath(myNode.getTreePath()); - - DockingActionIf renameAction = getAction("Rename"); - performAction(renameAction, getDomainFileActionContext(), true); - waitForTree(); - - // select "Rename" action - SwingUtilities.invokeAndWait(() -> { - int row = tree.getRowForPath(myNode.getTreePath()); - JTree jTree = (JTree) getInstanceField("tree", tree); - DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor(); - Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, myNode, - true, true, false, row); - JTextField textField = (JTextField) container.getComponent(0); - - textField.setText("MyNewFolder"); - tree.stopEditing(); - }); - waitForSwing(); - assertNotNull(rootNode.getChild("MyNewFolder")); - assertNull(rootNode.getChild("myFolder")); - } - - @Test - public void testRenameFile() throws Exception { - final GTreeNode npNode = rootNode.getChild("notepad"); - setSelectionPath(npNode.getTreePath()); - - DockingActionIf renameAction = getAction("Rename"); - performAction(renameAction, getDomainFileActionContext(), true); - waitForTree(); - - // select "Rename" action - SwingUtilities.invokeAndWait(() -> { - int row = tree.getRowForPath(npNode.getTreePath()); - DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor(); - JTree jTree = (JTree) getInstanceField("tree", tree); - Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, npNode, - true, true, false, row); - JTextField textField = (JTextField) container.getComponent(0); - - textField.setText("My_notepad"); - tree.stopEditing(); - }); - waitForSwing(); - assertNotNull(rootNode.getChild("My_notepad")); - assertNull(rootNode.getChild("notepad")); - - } - - @Test - public void testRenameFileInUse() throws Exception { - final GTreeNode npNode = rootNode.getChild("notepad"); - DomainFile df = ((DomainFileNode) npNode).getDomainFile(); - - setInUse(df); - - setSelectionPath(npNode.getTreePath()); - - DockingActionIf renameAction = getAction("Rename"); - executeOnSwingWithoutBlocking( - () -> performAction(renameAction, getDomainFileActionContext(), true)); - waitForSwing(); - OptionDialog dlg = waitForDialogComponent(OptionDialog.class); - assertEquals("Rename Not Allowed", dlg.getTitle()); - pressButtonByText(dlg.getComponent(), "OK"); - assertNotNull(rootNode.getChild("notepad")); - } - - private void setInUse(DomainFile df) throws Exception { - setInUse(df, "/notepad"); - } - - private void setInUse(DomainFile df, final String path) throws Exception { - ProgramDB program = createDefaultProgram("test1", ProgramBuilder._TOY, this); - - // - // Unusual Code Alert! - // We are calling an internal method to trigger the 'in use' state, as it is much - // faster to do this than it is to open a program in a tool! - // - - //@formatter:off - Object projectFileManager = getInstanceField("fileManager", df); - invokeInstanceMethod("setDomainObject", projectFileManager, - new Class[] { String.class, DomainObjectAdapter.class }, - new Object[] { path, program } - ); - //@formatter:on - } - - @Test - public void testRenameFolderInUse() throws Exception { - // folder contains a file that is in use - DomainFolder f = rootFolder.createFolder("myFolder"); - f = f.createFolder("A"); - f = f.createFolder("B"); - f = f.createFolder("C"); - - Program p = createDefaultProgram("new", ProgramBuilder._TOY, this); - - DomainFile df = f.createFile("notepad", p, TaskMonitorAdapter.DUMMY_MONITOR); - waitForSwing(); - - final GTreeNode myNode = rootNode.getChild("myFolder"); - ((DomainFolderNode) myNode).getDomainFolder().createFile("notepad", p, - TaskMonitorAdapter.DUMMY_MONITOR); - p.release(this); - - waitForSwing(); - tree.expandPath(myNode.getTreePath()); - assertNotNull(myNode.getChild("notepad")); - - setInUse(df, "/myFolder/notepad"); - - setSelectionPath(myNode.getTreePath()); - - final DockingActionIf renameAction = getAction("Rename"); - performAction(renameAction, getDomainFileActionContext(), true); - waitForTree(); - - // attempt to rename "myFolder" - SwingUtilities.invokeLater(() -> { - int row = tree.getRowForPath(myNode.getTreePath()); - DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor(); - JTree jTree = (JTree) getInstanceField("tree", tree); - Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, myNode, - true, true, false, row); - JTextField textField = (JTextField) container.getComponent(0); - - textField.setText("My_Newfolder"); - tree.stopEditing(); - }); - - waitForSwing(); - - OptionDialog d = - waitForDialogComponent(frontEndTool.getToolFrame(), OptionDialog.class, 2000); - assertNotNull(d); - assertEquals("Rename Failed", d.getTitle()); - pressButtonByText(d.getComponent(), "OK"); - assertNotNull(rootNode.getChild("myFolder")); - } - - @Test - public void testExpandAll() throws Exception { - DomainFolder f = rootFolder.createFolder("myFolder"); - f = f.createFolder("A"); - f = f.createFolder("B"); - f = f.createFolder("C"); - waitForSwing(); - - GTreeNode myNode = rootNode.getChild("myFolder"); - setSelectionPath(rootNode.getTreePath()); - DockingActionIf expandAction = getAction("Expand All"); - performAction(expandAction, getDomainFileActionContext(), true); - GTreeNode aNode = myNode.getChild("A"); - assertNotNull(aNode); - GTreeNode bNode = aNode.getChild("B"); - assertNotNull(bNode); - GTreeNode cNode = bNode.getChild("C"); - assertNotNull(cNode); - } - - @Test - public void testCollapseAll() throws Exception { - DomainFolder f = rootFolder.createFolder("myFolder"); - f = f.createFolder("A"); - f = f.createFolder("B"); - f = f.createFolder("C"); - waitForSwing(); - - GTreeNode myNode = rootNode.getChild("myFolder"); - setSelectionPath(myNode.getTreePath()); - DockingActionIf expandAction = getAction("Expand All"); - performAction(expandAction, getDomainFileActionContext(), true); - waitForTree(); - - DockingActionIf collapseAction = getAction("Collapse All"); - performAction(collapseAction, getDomainFileActionContext(), true); - waitForTree(); - assertTrue(!tree.isExpanded(myNode.getTreePath())); - GTreeNode aNode = myNode.getChild("A"); - assertTrue(!tree.isExpanded(aNode.getTreePath())); - GTreeNode bNode = aNode.getChild("B"); - assertTrue(!tree.isExpanded(bNode.getTreePath())); - GTreeNode cNode = bNode.getChild("C"); - assertNotNull(cNode); - assertTrue(!tree.isExpanded(cNode.getTreePath())); - } - - @Test - public void testSelectAll() throws Exception { - DomainFolder f = rootFolder.createFolder("myFolder"); - f = f.createFolder("A"); - f = f.createFolder("B"); - f = f.createFolder("C"); - waitForSwing(); - - setSelectionPath(rootNode.getTreePath()); - DockingActionIf selectAction = getAction("Select All"); - performAction(selectAction, getDomainFileActionContext(), true); - waitForTree(); - - BreadthFirstIterator it = new BreadthFirstIterator(tree, rootNode); - while (it.hasNext()) { - GTreeNode node = it.next(); - assertTrue(tree.isPathSelected(node.getTreePath())); - } - } - - @Test - public void testSetReadOnly() throws Exception { - GTreeNode npNode = rootNode.getChild("notepad"); - setSelectionPath(npNode.getTreePath()); - ToggleDockingAction readOnlyAction = (ToggleDockingAction) getAction("Read-Only"); - readOnlyAction.setSelected(true); - performAction(readOnlyAction, getDomainFileActionContext(), true); - - assertTrue(((DomainFileNode) npNode).getDomainFile().isReadOnly()); - ImageIcon icon = ResourceManager.loadImage("fileIcons/ProgramReadOnly.gif"); - icon = ResourceManager.getScaledIcon(icon, 16, 16); - - assertTrue(npNode.getIcon(false) instanceof MultiIcon); - } - - @Test - public void testSetReadOnlyInUse() throws Exception { - GTreeNode npNode = rootNode.getChild("notepad"); - DomainFile df = ((DomainFileNode) npNode).getDomainFile(); - setInUse(df); - - setSelectionPath(npNode.getTreePath()); - ToggleDockingAction readOnlyAction = (ToggleDockingAction) getAction("Read-Only"); - readOnlyAction.setSelected(true); - performAction(readOnlyAction, getDomainFileActionContext(), true); - - assertTrue(((DomainFileNode) npNode).getDomainFile().isReadOnly()); - } - -//================================================================================================== -// Private Methods -//================================================================================================== - - private ActionContext getDomainFileActionContext() { - List fileList = new ArrayList<>(); - List folderList = new ArrayList<>(); - - TreePath[] paths = tree.getSelectionPaths(); - for (TreePath path : paths) { - - GTreeNode node = (GTreeNode) path.getLastPathComponent(); - if (node instanceof DomainFileNode) { - fileList.add(((DomainFileNode) node).getDomainFile()); - } - else if (node instanceof DomainFolderNode) { - folderList.add(((DomainFolderNode) node).getDomainFolder()); - } - } - - return new ProjectDataTreeActionContext(null, null, paths, folderList, fileList, tree, - true); - } - - private DockingActionIf getAction(String actionName) { - DockingActionIf action = - AbstractDockingTest.getAction(frontEndTool, "FrontEndPlugin", actionName); - return action; - } - - private void setSelectionPath(final TreePath path) throws Exception { - tree.setSelectionPath(path); - waitForTree(); - } - - private void expandPath(TreePath treePath) { - tree.expandPath(treePath); - waitForTree(); - } - - private void waitForTree() { - waitForSwing(); - while (tree.isBusy()) { - try { - Thread.sleep(10); - } - catch (InterruptedException e) { - // try again - } - } - waitForSwing(); - } -} diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/ActionManager1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/FrontEndPluginActionsTest.java similarity index 71% rename from Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/ActionManager1Test.java rename to Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/FrontEndPluginActionsTest.java index b28418ace8..b8f442cb6f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/ActionManager1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/main/datatree/FrontEndPluginActionsTest.java @@ -30,12 +30,12 @@ import org.junit.*; import docking.ActionContext; import docking.action.DockingActionIf; +import docking.action.ToggleDockingAction; import docking.test.AbstractDockingTest; import docking.widgets.OptionDialog; import docking.widgets.tree.GTreeNode; import docking.widgets.tree.GTreeRootNode; -import docking.widgets.tree.support.GTreeDragNDropHandler; -import docking.widgets.tree.support.GTreeNodeTransferable; +import docking.widgets.tree.support.*; import ghidra.framework.data.DomainObjectAdapter; import ghidra.framework.main.FrontEndTool; import ghidra.framework.model.DomainFile; @@ -46,11 +46,13 @@ import ghidra.program.model.listing.Program; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.TestEnv; import ghidra.util.task.TaskMonitor; +import resources.MultiIcon; +import resources.ResourceManager; /** - * Tests for actions in the front end (Ghidra project window). + * Tests for actions in the front end (Ghidra project window) */ -public class ActionManager1Test extends AbstractGhidraHeadedIntegrationTest { +public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTest { private FrontEndTool frontEndTool; private TestEnv env; @@ -58,10 +60,6 @@ public class ActionManager1Test extends AbstractGhidraHeadedIntegrationTest { private DomainFolder rootFolder; private GTreeRootNode rootNode; - public ActionManager1Test() { - super(); - } - @Before public void setUp() throws Exception { @@ -533,10 +531,237 @@ public class ActionManager1Test extends AbstractGhidraHeadedIntegrationTest { assertNull(getChild(rootNode, "tms")); } + @Test + public void testRenameFolder() throws Exception { + rootFolder.createFolder("myFolder"); + waitForSwing(); + + final GTreeNode myNode = rootNode.getChild("myFolder"); + setSelectionPath(myNode.getTreePath()); + + DockingActionIf renameAction = getAction("Rename"); + performAction(renameAction, getDomainFileActionContext(), true); + waitForTree(); + + // select "Rename" action + SwingUtilities.invokeAndWait(() -> { + int row = tree.getRowForPath(myNode.getTreePath()); + JTree jTree = (JTree) getInstanceField("tree", tree); + DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor(); + Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, myNode, + true, true, false, row); + JTextField textField = (JTextField) container.getComponent(0); + + textField.setText("MyNewFolder"); + tree.stopEditing(); + }); + waitForSwing(); + assertNotNull(rootNode.getChild("MyNewFolder")); + assertNull(rootNode.getChild("myFolder")); + } + + @Test + public void testRenameFile() throws Exception { + final GTreeNode npNode = rootNode.getChild("notepad"); + setSelectionPath(npNode.getTreePath()); + + DockingActionIf renameAction = getAction("Rename"); + performAction(renameAction, getDomainFileActionContext(), true); + waitForTree(); + + // select "Rename" action + SwingUtilities.invokeAndWait(() -> { + int row = tree.getRowForPath(npNode.getTreePath()); + DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor(); + JTree jTree = (JTree) getInstanceField("tree", tree); + Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, npNode, + true, true, false, row); + JTextField textField = (JTextField) container.getComponent(0); + + textField.setText("My_notepad"); + tree.stopEditing(); + }); + waitForSwing(); + assertNotNull(rootNode.getChild("My_notepad")); + assertNull(rootNode.getChild("notepad")); + + } + + @Test + public void testRenameFileInUse() throws Exception { + final GTreeNode npNode = rootNode.getChild("notepad"); + DomainFile df = ((DomainFileNode) npNode).getDomainFile(); + + setInUse(df); + + setSelectionPath(npNode.getTreePath()); + + DockingActionIf renameAction = getAction("Rename"); + executeOnSwingWithoutBlocking( + () -> performAction(renameAction, getDomainFileActionContext(), true)); + waitForSwing(); + OptionDialog dlg = waitForDialogComponent(OptionDialog.class); + assertEquals("Rename Not Allowed", dlg.getTitle()); + pressButtonByText(dlg.getComponent(), "OK"); + assertNotNull(rootNode.getChild("notepad")); + } + + @Test + public void testRenameFolderInUse() throws Exception { + // folder contains a file that is in use + DomainFolder f = rootFolder.createFolder("myFolder"); + f = f.createFolder("A"); + f = f.createFolder("B"); + f = f.createFolder("C"); + + Program p = createDefaultProgram("new", ProgramBuilder._TOY, this); + + DomainFile df = f.createFile("notepad", p, TaskMonitor.DUMMY); + waitForSwing(); + + final GTreeNode myNode = rootNode.getChild("myFolder"); + ((DomainFolderNode) myNode).getDomainFolder().createFile("notepad", p, TaskMonitor.DUMMY); + p.release(this); + + waitForSwing(); + tree.expandPath(myNode.getTreePath()); + assertNotNull(myNode.getChild("notepad")); + + setInUse(df, "/myFolder/notepad"); + + setSelectionPath(myNode.getTreePath()); + + final DockingActionIf renameAction = getAction("Rename"); + performAction(renameAction, getDomainFileActionContext(), true); + waitForTree(); + + // attempt to rename "myFolder" + SwingUtilities.invokeLater(() -> { + int row = tree.getRowForPath(myNode.getTreePath()); + DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor(); + JTree jTree = (JTree) getInstanceField("tree", tree); + Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, myNode, + true, true, false, row); + JTextField textField = (JTextField) container.getComponent(0); + + textField.setText("My_Newfolder"); + tree.stopEditing(); + }); + + waitForSwing(); + + OptionDialog d = waitForDialogComponent(OptionDialog.class); + assertNotNull(d); + assertEquals("Rename Failed", d.getTitle()); + pressButtonByText(d.getComponent(), "OK"); + assertNotNull(rootNode.getChild("myFolder")); + } + + @Test + public void testExpandAll() throws Exception { + DomainFolder f = rootFolder.createFolder("myFolder"); + f = f.createFolder("A"); + f = f.createFolder("B"); + f = f.createFolder("C"); + waitForSwing(); + + GTreeNode myNode = rootNode.getChild("myFolder"); + setSelectionPath(rootNode.getTreePath()); + DockingActionIf expandAction = getAction("Expand All"); + performAction(expandAction, getDomainFileActionContext(), true); + GTreeNode aNode = myNode.getChild("A"); + assertNotNull(aNode); + GTreeNode bNode = aNode.getChild("B"); + assertNotNull(bNode); + GTreeNode cNode = bNode.getChild("C"); + assertNotNull(cNode); + } + + @Test + public void testCollapseAll() throws Exception { + DomainFolder f = rootFolder.createFolder("myFolder"); + f = f.createFolder("A"); + f = f.createFolder("B"); + f = f.createFolder("C"); + waitForSwing(); + + GTreeNode myNode = rootNode.getChild("myFolder"); + setSelectionPath(myNode.getTreePath()); + DockingActionIf expandAction = getAction("Expand All"); + performAction(expandAction, getDomainFileActionContext(), true); + waitForTree(); + + DockingActionIf collapseAction = getAction("Collapse All"); + performAction(collapseAction, getDomainFileActionContext(), true); + waitForTree(); + assertTrue(!tree.isExpanded(myNode.getTreePath())); + GTreeNode aNode = myNode.getChild("A"); + assertTrue(!tree.isExpanded(aNode.getTreePath())); + GTreeNode bNode = aNode.getChild("B"); + assertTrue(!tree.isExpanded(bNode.getTreePath())); + GTreeNode cNode = bNode.getChild("C"); + assertNotNull(cNode); + assertTrue(!tree.isExpanded(cNode.getTreePath())); + } + + @Test + public void testSelectAll() throws Exception { + DomainFolder f = rootFolder.createFolder("myFolder"); + f = f.createFolder("A"); + f = f.createFolder("B"); + f = f.createFolder("C"); + waitForSwing(); + + setSelectionPath(rootNode.getTreePath()); + DockingActionIf selectAction = getAction("Select All"); + performAction(selectAction, getDomainFileActionContext(), true); + waitForTree(); + + BreadthFirstIterator it = new BreadthFirstIterator(tree, rootNode); + while (it.hasNext()) { + GTreeNode node = it.next(); + assertTrue(tree.isPathSelected(node.getTreePath())); + } + } + + @Test + public void testSetReadOnly() throws Exception { + GTreeNode npNode = rootNode.getChild("notepad"); + setSelectionPath(npNode.getTreePath()); + ToggleDockingAction readOnlyAction = (ToggleDockingAction) getAction("Read-Only"); + readOnlyAction.setSelected(true); + performAction(readOnlyAction, getDomainFileActionContext(), true); + + assertTrue(((DomainFileNode) npNode).getDomainFile().isReadOnly()); + ImageIcon icon = ResourceManager.loadImage("fileIcons/ProgramReadOnly.gif"); + icon = ResourceManager.getScaledIcon(icon, 16, 16); + + assertTrue(npNode.getIcon(false) instanceof MultiIcon); + } + + @Test + public void testSetReadOnlyInUse() throws Exception { + GTreeNode npNode = rootNode.getChild("notepad"); + DomainFile df = ((DomainFileNode) npNode).getDomainFile(); + setInUse(df); + + setSelectionPath(npNode.getTreePath()); + ToggleDockingAction readOnlyAction = (ToggleDockingAction) getAction("Read-Only"); + readOnlyAction.setSelected(true); + performAction(readOnlyAction, getDomainFileActionContext(), true); + + assertTrue(((DomainFileNode) npNode).getDomainFile().isReadOnly()); + } + //================================================================================================== // Private Methods //================================================================================================== + private void setSelectionPath(final TreePath path) throws Exception { + tree.setSelectionPath(path); + waitForTree(); + } + private void pressDelete() { DockingActionIf deleteAction = getAction("Delete"); performAction(deleteAction, getDomainFileActionContext(), false); diff --git a/Ghidra/Features/Base/src/test/java/ghidra/test/DummyToolActions.java b/Ghidra/Features/Base/src/test/java/ghidra/test/DummyToolActions.java index 81a680cb91..3b4b216106 100644 --- a/Ghidra/Features/Base/src/test/java/ghidra/test/DummyToolActions.java +++ b/Ghidra/Features/Base/src/test/java/ghidra/test/DummyToolActions.java @@ -43,6 +43,11 @@ public class DummyToolActions implements DockingToolActions { // stub } + @Override + public DockingActionIf getLocalAction(ComponentProvider provider, String actionName) { + return null; + } + @Override public Set getActions(String owner) { return null; @@ -62,5 +67,4 @@ public class DummyToolActions implements DockingToolActions { public void removeActions(ComponentProvider provider) { // stub } - } diff --git a/Ghidra/Features/Base/src/test/resources/defaultTools/TestCodeBrowser.tool b/Ghidra/Features/Base/src/test/resources/defaultTools/TestCodeBrowser.tool index 48608084a9..ece29faf92 100644 --- a/Ghidra/Features/Base/src/test/resources/defaultTools/TestCodeBrowser.tool +++ b/Ghidra/Features/Base/src/test/resources/defaultTools/TestCodeBrowser.tool @@ -26,7 +26,7 @@ - + diff --git a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/decompiler/component/DecompilerCachingTest.java b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/decompiler/component/DecompilerCachingTest.java index 54a765a8ff..7ba195b376 100644 --- a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/decompiler/component/DecompilerCachingTest.java +++ b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/decompiler/component/DecompilerCachingTest.java @@ -27,7 +27,7 @@ import org.junit.*; import com.google.common.cache.*; -import docking.action.DockingAction; +import docking.ComponentProvider; import generic.test.TestUtils; import ghidra.app.decompiler.DecompileResults; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; @@ -201,10 +201,8 @@ public class DecompilerCachingTest extends AbstractGhidraHeadedIntegrationTest { } private void showDecompilerProvider() { - DockingAction showDecompileAction = - (DockingAction) TestUtils.getInstanceField("decompileAction", decompilePlugin); - performAction(showDecompileAction, true); - + ComponentProvider decompiler = tool.getComponentProvider("Decompiler"); + tool.showComponentProvider(decompiler, true); decompilerProvider = waitForComponentProvider(DecompilerProvider.class); } diff --git a/Ghidra/Features/FunctionGraph/src/test/java/ghidra/app/plugin/core/functiongraph/AbstractFunctionGraphTest.java b/Ghidra/Features/FunctionGraph/src/test/java/ghidra/app/plugin/core/functiongraph/AbstractFunctionGraphTest.java index 6fdf0efd3f..c04d27552a 100644 --- a/Ghidra/Features/FunctionGraph/src/test/java/ghidra/app/plugin/core/functiongraph/AbstractFunctionGraphTest.java +++ b/Ghidra/Features/FunctionGraph/src/test/java/ghidra/app/plugin/core/functiongraph/AbstractFunctionGraphTest.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.functiongraph; -import static ghidra.graph.viewer.GraphViewerUtils.*; +import static ghidra.graph.viewer.GraphViewerUtils.getGraphScale; import static org.junit.Assert.*; import java.awt.*; @@ -552,9 +552,9 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte } protected void showFunctionGraphProvider() { - DockingAction showGraphAction = - (DockingAction) TestUtils.getInstanceField("showFunctionGraphAction", graphPlugin); - performAction(showGraphAction, true); + + ComponentProvider provider = tool.getComponentProvider("Function Graph"); + tool.showComponentProvider(provider, true); graphProvider = waitForComponentProvider(FGProvider.class); assertNotNull("Graph not shown", graphProvider); diff --git a/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/DiffActionManager.java b/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/DiffActionManager.java index a0c5edbec4..0168a7ea50 100644 --- a/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/DiffActionManager.java +++ b/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/DiffActionManager.java @@ -51,7 +51,7 @@ class DiffActionManager { static final String IGNORE_DIFFS_NEXT_ACTION = "Ignore Selection and Goto Next Difference"; static final String NEXT_DIFF_ACTION = "Next Difference"; static final String PREVIOUS_DIFF_ACTION = "Previous Difference"; - static final String DIFF_DETAILS_ACTION = "Diff Location Details"; + static final String DIFF_DETAILS_ACTION = "Show Diff Location Details"; static final String SHOW_DIFF_SETTINGS_ACTION = "Show Diff Apply Settings"; static final String GET_DIFFS_ACTION = "Get Differences"; static final String SELECT_ALL_DIFFS_ACTION = "Select All Differences"; diff --git a/Ghidra/Features/ProgramDiff/src/test.slow/java/ghidra/app/plugin/core/diff/DiffTest.java b/Ghidra/Features/ProgramDiff/src/test.slow/java/ghidra/app/plugin/core/diff/DiffTest.java index 0b49fafef5..b4ed548e7e 100644 --- a/Ghidra/Features/ProgramDiff/src/test.slow/java/ghidra/app/plugin/core/diff/DiffTest.java +++ b/Ghidra/Features/ProgramDiff/src/test.slow/java/ghidra/app/plugin/core/diff/DiffTest.java @@ -665,7 +665,7 @@ public class DiffTest extends DiffTestAdapter { checkDiffAction("Ignore Selection and Goto Next Difference", true, false); checkDiffAction("Next Difference", true, true); checkDiffAction("Previous Difference", true, false); - checkDiffAction("Diff Location Details", true, true); + checkDiffAction("Show Diff Location Details", true, true); checkDiffAction("Show Diff Apply Settings", true, true); checkDiffAction("Get Differences", true, true); checkDiffAction("Select All Differences", true, true); @@ -699,7 +699,7 @@ public class DiffTest extends DiffTestAdapter { checkDiffAction("Ignore Selection and Goto Next Difference", false, false); checkDiffAction("Next Difference", false, false); checkDiffAction("Previous Difference", false, false); - checkDiffAction("Diff Location Details", false, false); + checkDiffAction("Show Diff Location Details", false, false); checkDiffAction("Show Diff Apply Settings", false, false); checkDiffAction("Get Differences", false, false); checkDiffAction("Select All Differences", false, false); @@ -715,7 +715,7 @@ public class DiffTest extends DiffTestAdapter { checkDiffAction("Ignore Selection and Goto Next Difference", false, false); checkDiffAction("Next Difference", false, false); checkDiffAction("Previous Difference", false, false); - checkDiffAction("Diff Location Details", false, false); + checkDiffAction("Show Diff Location Details", false, false); checkDiffAction("Show Diff Apply Settings", false, false); checkDiffAction("Get Differences", false, false); checkDiffAction("Select All Differences", false, false); @@ -732,7 +732,7 @@ public class DiffTest extends DiffTestAdapter { checkDiffAction("Ignore Selection and Goto Next Difference", true, false); checkDiffAction("Next Difference", true, true); checkDiffAction("Previous Difference", true, true); - checkDiffAction("Diff Location Details", true, true); + checkDiffAction("Show Diff Location Details", true, true); checkDiffAction("Show Diff Apply Settings", true, true); checkDiffAction("Get Differences", true, true); checkDiffAction("Select All Differences", true, true); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java b/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java index 3152821c5a..893ad0be06 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java @@ -67,6 +67,7 @@ public abstract class AbstractDockingTool implements DockingTool { @Override public void removeComponentProvider(ComponentProvider provider) { Runnable r = () -> { + toolActions.removeGlobalAction(provider.getShowProviderAction()); toolActions.removeActions(provider); winMgr.removeComponent(provider); }; diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java b/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java index 38e0c22807..365b26435f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java @@ -168,7 +168,8 @@ class DockableToolBarManager { private DockableComponent dockableComponent; ToolBarCloseAction(DockableComponent dockableComponent) { - super("Close Window", DockingWindowManager.DOCKING_WINDOWS_OWNER); + super("Close Window", DockingWindowManager.DOCKING_WINDOWS_OWNER, + KeyBindingType.UNSUPPORTED); this.dockableComponent = dockableComponent; setDescription("Close Window"); setToolBarData(new ToolBarData(closeIcon, null)); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java b/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java index 0ec208edcc..7799c80bf1 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java @@ -47,16 +47,14 @@ import util.CollectionUtils; * Manages the "Docking" arrangement of a set of components and actions. The components can be "docked" * together or exist in their own window. Actions can be associated with components so they * "move" with the component as it moved from one location to another. - * + *

* Components are added via ComponentProviders. A ComponentProvider is an interface for getting * a component and its related information. The docking window manager will get the component * from the provider as needed. It is up to the provider if it wants to reuse the component or - * recreate a new one when the component is requested. When the user "hides" (by using - * the x button on the component area) a component, the docking window manager removes all + * recreate a new one when the component is requested. When the user hides a component (by using + * the x button on the component header), the docking window manager removes all * knowledge of the component and will request it again from the provider if the component - * becomes "unhidden". The provider is also notified whenever a component is hidden. Some - * providers will use the notification to remove the provider from the docking window manager so - * that the can not "unhide" the component using the built-in window menu. + * is again shown. The provider is also notified whenever a component is hidden and shown. */ public class DockingWindowManager implements PropertyChangeListener, PlaceholderInstaller { @@ -712,8 +710,11 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder ComponentPlaceholder placeholder = getActivePlaceholder(provider); if (placeholder != null) { showComponent(placeholder, visibleState, true); + return; } - else { + + if (visibleState) { + // a null placeholder implies the client is trying to show a provider that has not // been added to the tool Msg.warn(this, "Attempting to show an unknown Component Provider '" + diff --git a/Ghidra/Framework/Docking/src/main/java/docking/ShowComponentAction.java b/Ghidra/Framework/Docking/src/main/java/docking/ShowComponentAction.java index 5fb3afc650..569a19691a 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/ShowComponentAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/ShowComponentAction.java @@ -76,11 +76,7 @@ class ShowComponentAction extends DockingAction implements Comparable(); } - public void addAction(DockingActionIf action, ComponentProvider optionalProvider) { + public void addAction(ComponentProvider optionalProvider, DockingActionIf action) { action.addPropertyChangeListener(this); if (optionalProvider != null) { actionToProviderMap.put(action, optionalProvider); @@ -48,7 +48,7 @@ public class KeyBindingsManager implements PropertyChangeListener { KeyStroke keyBinding = action.getKeyBinding(); if (keyBinding != null) { - addKeyBinding(action, optionalProvider, keyBinding); + addKeyBinding(optionalProvider, action, keyBinding); } } @@ -67,7 +67,7 @@ public class KeyBindingsManager implements PropertyChangeListener { removeKeyBinding(action.getKeyBinding(), action); } - private void addKeyBinding(DockingActionIf action, ComponentProvider provider, + private void addKeyBinding(ComponentProvider provider, DockingActionIf action, KeyStroke keyStroke) { if (ReservedKeyBindings.isReservedKeystroke(keyStroke)) { throw new AssertException("Cannot assign action to a reserved keystroke. " + @@ -145,7 +145,7 @@ public class KeyBindingsManager implements PropertyChangeListener { if (newKeyData != null) { KeyStroke ks = newKeyData.getKeyBinding(); if (ks != null) { - addKeyBinding(action, actionToProviderMap.get(action), ks); + addKeyBinding(actionToProviderMap.get(action), action, ks); } } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java index cb97c5fed5..d7bc3a5395 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java @@ -63,6 +63,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { throw new IllegalArgumentException( "KeyStrokes don't match - was: " + keyStroke + " new: " + keyBinding); } + actions.add(new ActionData(action, provider)); } @@ -273,5 +274,10 @@ public class MultipleKeyAction extends DockingKeyBindingAction { boolean isMyProvider(ComponentProvider otherProvider) { return provider == otherProvider; } + + @Override + public String toString() { + return provider.toString() + " - " + action; + } } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/DockingToolActions.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/DockingToolActions.java index 2666ad2161..2de77f96e0 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/DockingToolActions.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/DockingToolActions.java @@ -34,6 +34,15 @@ public interface DockingToolActions { */ public void addLocalAction(ComponentProvider provider, DockingActionIf action); + /** + * Gets the provider action by the given name + * + * @param provider the provider + * @param actionName the action name + * @return the action + */ + public DockingActionIf getLocalAction(ComponentProvider provider, String actionName); + /** * Removes the given provider's local action * diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyEntryDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyEntryDialog.java index 38b1207c81..110c3a22f6 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyEntryDialog.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyEntryDialog.java @@ -155,6 +155,7 @@ public class KeyEntryDialog extends DialogComponentProvider { KeyStroke existingKeyStroke = action.getKeyBinding(); if (Objects.equals(existingKeyStroke, newKeyStroke)) { + setStatusText("Key binding unchanged"); return; } @@ -177,11 +178,18 @@ public class KeyEntryDialog extends DialogComponentProvider { } private void updateCollisionPane(KeyStroke ks) { + clearStatusText(); collisionPane.setText(""); if (ks == null) { return; } + KeyStroke existingKeyStroke = action.getKeyBinding(); + if (Objects.equals(existingKeyStroke, ks)) { + setStatusText("Key binding unchanged"); + return; + } + List list = getManagedActionsForKeyStroke(ks); if (list.size() == 0) { return; @@ -193,7 +201,7 @@ public class KeyEntryDialog extends DialogComponentProvider { for (int i = 0; i < list.size(); i++) { DockingActionIf a = list.get(i); - String collisionStr = "\t" + a.getName() + " (" + a.getOwner() + ")\n"; + String collisionStr = "\t" + a.getName() + " (" + a.getOwnerDescription() + ")\n"; int offset = doc.getLength(); doc.insertString(offset, collisionStr, textAttrSet); doc.setParagraphAttributes(offset, 1, tabAttrSet, false); @@ -211,6 +219,7 @@ public class KeyEntryDialog extends DialogComponentProvider { if (multiAction == null) { return Collections.emptyList(); } + List list = multiAction.getActions(); Map nameMap = new HashMap<>(list.size()); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedStubKeyBindingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedStubKeyBindingAction.java index 40bf3bebf6..d16ebce648 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedStubKeyBindingAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedStubKeyBindingAction.java @@ -85,13 +85,14 @@ public class SharedStubKeyBindingAction extends DockingAction implements Options updateActionKeyStrokeFromOptions(action, defaultKs); } - public String getOwnersDescription() { + @Override + public String getOwnerDescription() { List owners = getDistinctOwners(); Collections.sort(owners); if (owners.size() == 1) { return owners.get(0); } - return '(' + StringUtils.join(owners, ", ") + ')'; + return StringUtils.join(owners, ", "); } private List getDistinctOwners() { @@ -99,6 +100,11 @@ public class SharedStubKeyBindingAction extends DockingAction implements Options Set actions = clientActions.keySet(); for (DockingActionIf action : actions) { String owner = action.getOwner(); + if (DockingWindowManager.DOCKING_WINDOWS_OWNER.equals(owner)) { + // special case: this is the owner for special system-level actions + continue; + } + if (!results.contains(owner)) { results.add(owner); } @@ -139,12 +145,16 @@ public class SharedStubKeyBindingAction extends DockingAction implements Options private void updateActionKeyStrokeFromOptions(DockingActionIf action, KeyStroke defaultKs) { + KeyStroke stubKs = defaultKs; KeyStroke optionsKs = getKeyStrokeFromOptions(defaultKs); if (!Objects.equals(defaultKs, optionsKs)) { // we use the 'unvalidated' call since this value is provided by the user--we assume // that user input is correct; we only validate programmer input action.setUnvalidatedKeyBindingData(new KeyBindingData(optionsKs)); + stubKs = optionsKs; } + + setUnvalidatedKeyBindingData(new KeyBindingData(stubKs)); } private KeyStroke getKeyStrokeFromOptions(KeyStroke validatedKeyStroke) { diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java index 9bb89d0d84..12d701837e 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java @@ -115,27 +115,21 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { action.addPropertyChangeListener(this); addActionToMap(action); - setKeyBindingOption(action); - keyBindingsManager.addAction(action, provider); + initializeKeyBinding(provider, action); actionGuiHelper.addLocalAction(provider, action); } - /** - * Adds the action to the tool. - * @param action the action to be added. - */ @Override public synchronized void addGlobalAction(DockingActionIf action) { checkForAlreadyAddedAction(null, action); action.addPropertyChangeListener(this); addActionToMap(action); - setKeyBindingOption(action); - keyBindingsManager.addAction(action, null); + initializeKeyBinding(null, action); actionGuiHelper.addToolAction(action); } - private void setKeyBindingOption(DockingActionIf action) { + private void initializeKeyBinding(ComponentProvider provider, DockingActionIf action) { KeyBindingType type = action.getKeyBindingType(); if (!type.supportsKeyBindings()) { @@ -143,7 +137,7 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { } if (type.isShared()) { - installSharedKeyBinding(action); + installSharedKeyBinding(provider, action); return; } @@ -154,9 +148,11 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { if (!Objects.equals(ks, newKs)) { action.setUnvalidatedKeyBindingData(new KeyBindingData(newKs)); } + + keyBindingsManager.addAction(provider, action); } - private void installSharedKeyBinding(DockingActionIf action) { + private void installSharedKeyBinding(ComponentProvider provider, DockingActionIf action) { String name = action.getName(); KeyStroke defaultKeyStroke = action.getKeyBinding(); @@ -172,6 +168,9 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { }); stub.addClientAction(action); + + // note: only put the stub in the manager, not the actual action + keyBindingsManager.addAction(provider, stub); } /** @@ -318,10 +317,12 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { for (DockingActionIf action : set) { removeLocalAction(provider, action); } - } private void removeAction(DockingActionIf action) { + + keyBindingsManager.removeAction(action); + getActionStorage(action).remove(action); if (!action.getKeyBindingType().isShared()) { return; @@ -370,6 +371,19 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { } } + @Override + public DockingActionIf getLocalAction(ComponentProvider provider, String actionName) { + + Iterator it = actionGuiHelper.getComponentActions(provider); + while (it.hasNext()) { + DockingActionIf action = it.next(); + if (action.getName().equals(actionName)) { + return action; + } + } + return null; + } + public Action getAction(KeyStroke ks) { return keyBindingsManager.getDockingKeyAction(ks); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java b/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java index ecfcb37a57..bff919d5b7 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java @@ -43,6 +43,7 @@ import com.google.common.collect.Sets; import docking.*; import docking.action.DockingActionIf; import docking.action.ToggleDockingActionIf; +import docking.actions.DockingToolActions; import docking.dnd.GClipboard; import docking.framework.DockingApplicationConfiguration; import docking.menu.DockingToolbarButton; @@ -1195,8 +1196,18 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { return CollectionUtils.any(actions); } + /** + * Returns the action by the given name that belongs to the given provider + * + * @param provider the provider + * @param actionName the action name + * @return the action + */ public static DockingActionIf getLocalAction(ComponentProvider provider, String actionName) { - return getAction(provider.getTool(), provider.getName(), actionName); + DockingTool tool = provider.getTool(); + DockingToolActions toolActions = tool.getToolActions(); + DockingActionIf action = toolActions.getLocalAction(provider, actionName); + return action; } /** @@ -1850,10 +1861,12 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * * @param tool the tool in which the provider lives * @param name the name of the provider to show + * @return the newly shown provider */ - public void showProvider(DockingTool tool, String name) { + public ComponentProvider showProvider(DockingTool tool, String name) { ComponentProvider provider = tool.getComponentProvider(name); tool.showComponentProvider(provider, true); + return provider; } /** diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/KeyBindingsPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/KeyBindingsPanel.java index d5ca1146ed..56fe52455e 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/KeyBindingsPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/KeyBindingsPanel.java @@ -32,7 +32,6 @@ import docking.KeyEntryTextField; import docking.action.DockingActionIf; import docking.action.KeyBindingData; import docking.actions.KeyBindingUtils; -import docking.actions.SharedStubKeyBindingAction; import docking.tool.util.DockingToolConstants; import docking.widgets.MultiLineLabel; import docking.widgets.OptionDialog; @@ -708,18 +707,11 @@ public class KeyBindingsPanel extends JPanel { } return ""; case PLUGIN_NAME: - return getOwner(action); + return action.getOwnerDescription(); } return "Unknown Column!"; } - private String getOwner(DockingActionIf action) { - if (action instanceof SharedStubKeyBindingAction) { - return ((SharedStubKeyBindingAction) action).getOwnersDescription(); - } - return action.getOwner(); - } - @Override public List getModelData() { return tableActions;