GT-2869 - Key Bindings - refactor of methods to provide all actions

This commit is contained in:
dragonmacher
2019-06-04 18:15:16 -04:00
parent c1de98304a
commit 43fa7e3f92
75 changed files with 1243 additions and 1049 deletions
@@ -20,6 +20,7 @@ import java.io.*;
import java.util.*; import java.util.*;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.actions.KeyBindingUtils;
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.Plugin;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@@ -30,9 +31,9 @@ public class CreateHelpTemplateScript extends GhidraScript {
@Override @Override
protected void run() throws Exception { protected void run() throws Exception {
PluginTool tool = state.getTool(); PluginTool tool = state.getTool();
Plugin[] plugins = getSortedPlugins(tool); List<Plugin> plugins = getSortedPlugins(tool);
Plugin selectedPlugin = Plugin selectedPlugin =
askChoice("Select Plugin To Use To Generate Help", "Plugin", plugins, plugins[0]); askChoice("Select Plugin To Use To Generate Help", "Plugin", plugins, plugins.get(0));
if (selectedPlugin == null) { if (selectedPlugin == null) {
printerr("no plugin selected, no help template created."); printerr("no plugin selected, no help template created.");
return; return;
@@ -101,7 +102,8 @@ public class CreateHelpTemplateScript extends GhidraScript {
} }
private List<DockingActionIf> getActions(PluginTool tool, Plugin plugin) { private List<DockingActionIf> getActions(PluginTool tool, Plugin plugin) {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = KeyBindingUtils.getKeyBindingActions(tool, plugin.getName());
List<DockingActionIf> list = new ArrayList<>(actions);
Comparator<DockingActionIf> comparator = (action1, action2) -> { Comparator<DockingActionIf> comparator = (action1, action2) -> {
try { try {
return action1.getName().compareTo(action2.getName()); return action1.getName().compareTo(action2.getName());
@@ -110,14 +112,12 @@ public class CreateHelpTemplateScript extends GhidraScript {
return 0; return 0;
} }
}; };
Collections.sort(actions, comparator); Collections.sort(list, comparator);
return actions; return list;
} }
private Plugin[] getSortedPlugins(PluginTool tool) { private List<Plugin> getSortedPlugins(PluginTool tool) {
List<Plugin> list = tool.getManagedPlugins(); List<Plugin> list = tool.getManagedPlugins();
Plugin[] plugins = new Plugin[list.size()];
list.toArray(plugins);
Comparator<Plugin> comparator = (plugin1, plugin2) -> { Comparator<Plugin> comparator = (plugin1, plugin2) -> {
try { try {
return plugin1.getName().compareTo(plugin2.getName()); return plugin1.getName().compareTo(plugin2.getName());
@@ -126,8 +126,9 @@ public class CreateHelpTemplateScript extends GhidraScript {
return 0; return 0;
} }
}; };
Arrays.sort(plugins, comparator);
return plugins; Collections.sort(list, comparator);
return list;
} }
} }
@@ -21,9 +21,7 @@ import java.awt.datatransfer.Transferable;
import java.awt.dnd.*; import java.awt.dnd.*;
import java.awt.event.*; import java.awt.event.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.*;
import java.util.EventObject;
import java.util.List;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.Border; import javax.swing.border.Border;
@@ -33,10 +31,10 @@ import javax.swing.table.*;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.actions.KeyBindingUtils;
import docking.dnd.*; import docking.dnd.*;
import docking.help.Help; import docking.help.Help;
import docking.help.HelpService; import docking.help.HelpService;
import docking.util.KeyBindingUtils;
import docking.widgets.DropDownSelectionTextField; import docking.widgets.DropDownSelectionTextField;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.fieldpanel.support.FieldRange; import docking.widgets.fieldpanel.support.FieldRange;
@@ -1519,17 +1517,18 @@ public abstract class CompositeEditorPanel extends JPanel
@Override @Override
public boolean isKeyConsumed(KeyStroke keyStroke) { public boolean isKeyConsumed(KeyStroke keyStroke) {
if (isEditing()) { if (isEditing()) {
// don't let actions through when editing our table
return true; return true;
} }
// don't let actions through when editing our table // TODO this should no longer be needed
return !hasLocalActionForKeyStroke(keyStroke); return !hasLocalActionForKeyStroke(keyStroke);
} }
private boolean hasLocalActionForKeyStroke(KeyStroke keyStroke) { private boolean hasLocalActionForKeyStroke(KeyStroke keyStroke) {
Plugin plugin = provider.getPlugin(); Plugin plugin = provider.getPlugin();
PluginTool tool = plugin.getTool(); PluginTool tool = plugin.getTool();
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName());
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
if (!(action instanceof CompositeEditorTableAction)) { if (!(action instanceof CompositeEditorTableAction)) {
continue; continue;
@@ -32,8 +32,8 @@ import javax.swing.undo.UndoableEdit;
import docking.ActionContext; import docking.ActionContext;
import docking.ComponentProvider; import docking.ComponentProvider;
import docking.action.*; import docking.action.*;
import docking.actions.KeyBindingUtils;
import docking.options.editor.FontPropertyEditor; import docking.options.editor.FontPropertyEditor;
import docking.util.KeyBindingUtils;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import ghidra.framework.options.SaveState; import ghidra.framework.options.SaveState;
@@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -28,7 +27,7 @@ import javax.swing.*;
import javax.swing.event.*; import javax.swing.event.*;
import javax.swing.text.*; import javax.swing.text.*;
import docking.util.KeyBindingUtils; import docking.actions.KeyBindingUtils;
class FunctionSignatureTextField extends JTextPane { class FunctionSignatureTextField extends JTextPane {
private static final String ENTER_ACTION_NAME = "ENTER"; private static final String ENTER_ACTION_NAME = "ENTER";
@@ -24,7 +24,7 @@ import java.util.Map.Entry;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.*; import javax.swing.border.*;
import docking.util.KeyBindingUtils; import docking.actions.KeyBindingUtils;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import docking.widgets.label.GIconLabel; import docking.widgets.label.GIconLabel;
import generic.util.WindowUtilities; import generic.util.WindowUtilities;
@@ -26,8 +26,8 @@ import javax.swing.*;
import javax.swing.tree.*; import javax.swing.tree.*;
import docking.DockingUtils; import docking.DockingUtils;
import docking.actions.KeyBindingUtils;
import docking.dnd.*; import docking.dnd.*;
import docking.util.KeyBindingUtils;
import docking.widgets.table.AutoscrollAdapter; import docking.widgets.table.AutoscrollAdapter;
/** /**
@@ -30,8 +30,8 @@ import javax.swing.tree.*;
import docking.DockingUtils; import docking.DockingUtils;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.actions.KeyBindingUtils;
import docking.dnd.DropTgtAdapter; import docking.dnd.DropTgtAdapter;
import docking.util.KeyBindingUtils;
import docking.widgets.JTreeMouseListenerDelegate; import docking.widgets.JTreeMouseListenerDelegate;
import ghidra.app.util.SelectionTransferData; import ghidra.app.util.SelectionTransferData;
import ghidra.app.util.SelectionTransferable; import ghidra.app.util.SelectionTransferable;
@@ -28,9 +28,9 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.actions.KeyBindingUtils;
import docking.dnd.DropTgtAdapter; import docking.dnd.DropTgtAdapter;
import docking.dnd.Droppable; import docking.dnd.Droppable;
import docking.util.KeyBindingUtils;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.viewer.field.BrowserCodeUnitFormat; import ghidra.app.util.viewer.field.BrowserCodeUnitFormat;
@@ -43,7 +43,6 @@ import utilities.util.FileUtilities;
class GhidraScriptActionManager { class GhidraScriptActionManager {
public static final String RERUN_LAST_SHARED_ACTION_NAME = "Rerun Last Script"; public static final String RERUN_LAST_SHARED_ACTION_NAME = "Rerun Last Script";
public static final String GLOBAL_RERUN_LAST_SHARED_ACTION_NAME = "Global Rerun Last Script";
private static final KeyStroke RERUN_LAST_SCRIPT_KEYSTROKE = KeyStroke.getKeyStroke( private static final KeyStroke RERUN_LAST_SCRIPT_KEYSTROKE = KeyStroke.getKeyStroke(
KeyEvent.VK_R, DockingUtils.CONTROL_KEY_MODIFIER_MASK | InputEvent.SHIFT_DOWN_MASK); KeyEvent.VK_R, DockingUtils.CONTROL_KEY_MODIFIER_MASK | InputEvent.SHIFT_DOWN_MASK);
private static final String SCRIPT_ACTIONS_KEY = "Scripts_Actions_Key"; private static final String SCRIPT_ACTIONS_KEY = "Scripts_Actions_Key";
@@ -29,8 +29,8 @@ import javax.swing.undo.UndoableEdit;
import docking.*; import docking.*;
import docking.action.*; import docking.action.*;
import docking.actions.KeyBindingUtils;
import docking.options.editor.FontPropertyEditor; import docking.options.editor.FontPropertyEditor;
import docking.util.KeyBindingUtils;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.app.script.GhidraScriptUtil; import ghidra.app.script.GhidraScriptUtil;
@@ -28,7 +28,7 @@ import docking.widgets.label.GDLabel;
* components (usually icon buttons) * components (usually icon buttons)
*/ */
public class TitledPanel extends JPanel { public class TitledPanel extends JPanel {
private JLabel title; private JLabel title; // GDLabel or GHtmlLabel
private JPanel titlePanel; private JPanel titlePanel;
private JPanel iconPanel; private JPanel iconPanel;
private JComponent bottomComp; private JComponent bottomComp;
@@ -37,16 +37,27 @@ public class TitledPanel extends JPanel {
/** /**
* Creates a new TitlePanel * Creates a new TitlePanel
* @param name the name of the panel * @param name the name of the panel
* @param panel the component to wrap. * @param panel the component to wrap
* @param margin the size of the margin to use. * @param margin the size of the margin to use
*/ */
public TitledPanel(String name, JComponent panel, int margin) { public TitledPanel(String name, JComponent panel, int margin) {
this(new GDLabel(name), panel, margin);
}
/**
* Creates a new TitlePanel
*
* @param titleLabel the title label for the panel; this allow clients to provide HTML-based
* title text. Note: it is up to the client to escape this text as needed for safety
* @param panel the component to wrap
* @param margin the size of the margin to use
*/
public TitledPanel(JLabel titleLabel, JComponent panel, int margin) {
super(new BorderLayout()); super(new BorderLayout());
titlePanel = new JPanel(new BorderLayout()); titlePanel = new JPanel(new BorderLayout());
iconPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 1)); iconPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 1));
iconPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); iconPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
title = new GDLabel(name); title = titleLabel;
title.setToolTipText(name);
JLabel filler = new GDLabel(); JLabel filler = new GDLabel();
filler.setPreferredSize(new Dimension(margin, filler.getPreferredSize().height)); filler.setPreferredSize(new Dimension(margin, filler.getPreferredSize().height));
titlePanel.add(filler, BorderLayout.WEST); titlePanel.add(filler, BorderLayout.WEST);
@@ -212,9 +212,8 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
public void performAction(String actionName, String owner, ComponentProvider contextProvider, public void performAction(String actionName, String owner, ComponentProvider contextProvider,
boolean wait) { boolean wait) {
String fullActionName = actionName + " (" + owner + ")"; DockingActionIf action = getAction(tool, owner, actionName);
List<DockingActionIf> action = tool.getDockingActionsByFullActionName(fullActionName); performAction(action, contextProvider, wait);
performAction(action.get(0), contextProvider, wait);
} }
public void showOptions(final String optionsCategoryName) { public void showOptions(final String optionsCategoryName) {
@@ -359,12 +359,11 @@ public abstract class GhidraScreenShotGenerator extends AbstractScreenShotGenera
} }
public void performFrontEndAction(String actionName, String owner, boolean wait) { public void performFrontEndAction(String actionName, String owner, boolean wait) {
String fullActionName = actionName + " (" + owner + ")";
FrontEndTool frontEnd = getFrontEndTool(); FrontEndTool frontEnd = getFrontEndTool();
List<DockingActionIf> action = frontEnd.getDockingActionsByFullActionName(fullActionName);
DockingActionIf action = getAction(frontEnd, owner, actionName);
ComponentProvider compProvider = ComponentProvider compProvider =
(ComponentProvider) getInstanceField("compProvider", frontEnd); (ComponentProvider) getInstanceField("compProvider", frontEnd);
performAction(action.get(0), compProvider, wait); performAction(action, compProvider, wait);
} }
} }
@@ -18,7 +18,7 @@ package ghidra.app.plugin.core.algorithmtree;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.List; import java.util.Set;
import org.junit.*; import org.junit.*;
@@ -33,6 +33,7 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.ProgramModule; import ghidra.program.model.listing.ProgramModule;
import ghidra.program.util.GroupPath; import ghidra.program.util.GroupPath;
import ghidra.test.*; import ghidra.test.*;
import util.CollectionUtils;
/** /**
* Test the module algorithm plugin gui elements. * Test the module algorithm plugin gui elements.
@@ -43,7 +44,7 @@ public class ModuleAlgorithmPluginTest extends AbstractGhidraHeadedIntegrationTe
private PluginTool tool; private PluginTool tool;
private Program program; private Program program;
private ModuleAlgorithmPlugin plugin; private ModuleAlgorithmPlugin plugin;
private List<DockingActionIf> actions; private Set<DockingActionIf> actions;
private ProgramTreeService service; private ProgramTreeService service;
private Object context; private Object context;
@@ -58,7 +59,7 @@ public class ModuleAlgorithmPluginTest extends AbstractGhidraHeadedIntegrationTe
tool.addPlugin(ProgramTreePlugin.class.getName()); tool.addPlugin(ProgramTreePlugin.class.getName());
tool.addPlugin(ModuleAlgorithmPlugin.class.getName()); tool.addPlugin(ModuleAlgorithmPlugin.class.getName());
plugin = env.getPlugin(ModuleAlgorithmPlugin.class); plugin = env.getPlugin(ModuleAlgorithmPlugin.class);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
service = tool.getService(ProgramTreeService.class); service = tool.getService(ProgramTreeService.class);
} }
@@ -98,7 +99,7 @@ public class ModuleAlgorithmPluginTest extends AbstractGhidraHeadedIntegrationTe
getContextObject(vps); getContextObject(vps);
performAction(actions.get(0), new ActionContext(null, context), true); performAction(CollectionUtils.any(actions), new ActionContext(null, context), true);
waitForTasks(); waitForTasks();
program.flushEvents(); program.flushEvents();
@@ -1090,10 +1090,9 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
private DockingActionIf getAction(String actionName) { private DockingActionIf getAction(String actionName) {
// make sure there is a provider from which to get actions // make sure there is a provider from which to get actions
getProvider(); getProvider();
String fullActionName = actionName + " (CallTreePlugin)";
List<DockingActionIf> actions = tool.getDockingActionsByFullActionName(fullActionName); DockingActionIf action = getAction(tool, "CallTreePlugin", actionName);
Assert.assertTrue("Could not find action: " + fullActionName, actions.size() > 0); return action;
return actions.get(0);
} }
private void myWaitForTree(GTree gTree, CallTreeProvider treeProvider) { private void myWaitForTree(GTree gTree, CallTreeProvider treeProvider) {
@@ -165,7 +165,7 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
builtInDataTypesManager.setFavorite(root.getDataType("word"), true); builtInDataTypesManager.setFavorite(root.getDataType("word"), true);
} }
protected void checkActions(List<DockingActionIf> actions, boolean enabled, String caseStr) { protected void checkActions(Set<DockingActionIf> actions, boolean enabled, String caseStr) {
checkAction(actions, CREATE_STRUCTURE, enabled, caseStr); checkAction(actions, CREATE_STRUCTURE, enabled, caseStr);
checkAction(actions, EDIT_DATA_TYPE, enabled, caseStr); checkAction(actions, EDIT_DATA_TYPE, enabled, caseStr);
checkAction(actions, CREATE_ARRAY, enabled, caseStr); checkAction(actions, CREATE_ARRAY, enabled, caseStr);
@@ -1063,7 +1063,7 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
ProgramSelection sel = getCurrentSelection(); ProgramSelection sel = getCurrentSelection();
boolean useSelection = (sel != null && !sel.isEmpty()); boolean useSelection = (sel != null && !sel.isEmpty());
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf element : actions) { for (DockingActionIf element : actions) {
MenuData menuBarData = element.getMenuBarData(); MenuData menuBarData = element.getMenuBarData();
@@ -1113,31 +1113,6 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
} }
} }
// if (useSelection) {
//
// checkAction(actions, CREATE_STRUCTURE, true, caseName);
// checkAction(actions, EDIT_STRUCTURE, false, caseName);
// checkAction(actions, CREATE_ARRAY, true, caseName);
// checkAction(actions, DEFAULT_DATA_SETTINGS, false, caseName);
// checkAction(actions, DATA_SETTINGS, false, caseName);
// checkAction(actions, CYCLE_FLOAT_DOUBLE, true, caseName);
// checkAction(actions, CYCLE_BYTE_WORD_DWORD_QWORD, true, caseName);
// checkAction(actions, CYCLE_CHAR_STRING_UNICODE, true, caseName);
// checkAction(actions, DEFINE_BYTE, true, caseName);
// checkAction(actions, DEFINE_WORD, true, caseName);
// checkAction(actions, DEFINE_DWORD, true, caseName);
// checkAction(actions, DEFINE_QWORD, true, caseName);
// checkAction(actions, DEFINE_FLOAT, true, caseName);
// checkAction(actions, DEFINE_DOUBLE, true, caseName);
// checkAction(actions, DEFINE_TERM_CSTRING, true, caseName);
// checkAction(actions, DEFINE_POINTER, true, caseName);
//
// PluginAction recentlyUsedAction = getAction(RECENTLY_USED);
// if (recentlyUsedAction != null) {
// checkAction(recentlyUsedAction, false, caseName);
// }
// return;
// }
if (data != null) { if (data != null) {
DataType dt = data.getDataType(); DataType dt = data.getDataType();
@@ -1184,10 +1159,10 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
} }
protected void checkOnUndefined(List<DockingActionIf> actions) { protected void checkOnUndefined(Set<DockingActionIf> actions) {
if (actions == null) { if (actions == null) {
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
} }
Data data = getContextData(); Data data = getContextData();
@@ -1223,10 +1198,10 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
} }
protected void checkOnDefined(List<DockingActionIf> actions, Class<?> expectedDataType) { protected void checkOnDefined(Set<DockingActionIf> actions, Class<?> expectedDataType) {
if (actions == null) { if (actions == null) {
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
} }
String dtName = expectedDataType.getName(); String dtName = expectedDataType.getName();
@@ -1287,10 +1262,10 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
checkAction(actions, DEFINE_POINTER, true, caseName); checkAction(actions, DEFINE_POINTER, true, caseName);
} }
protected void checkOnArray(List<DockingActionIf> actions, DataType interiorDt, int arraySize) { protected void checkOnArray(Set<DockingActionIf> actions, DataType interiorDt, int arraySize) {
if (actions == null) { if (actions == null) {
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
} }
Data d = getContextData(); Data d = getContextData();
@@ -1356,10 +1331,10 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
* @param actions * @param actions
* @param structSize structure size or -1 to disable size check * @param structSize structure size or -1 to disable size check
*/ */
protected void checkOnStructure(List<DockingActionIf> actions, int structSize) { protected void checkOnStructure(Set<DockingActionIf> actions, int structSize) {
if (actions == null) { if (actions == null) {
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
} }
Data d = getContextData(); Data d = getContextData();
@@ -1400,7 +1375,7 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
} }
protected DockingActionIf getAction(String name) { protected DockingActionIf getAction(String name) {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf element : actions) { for (DockingActionIf element : actions) {
String actionName = element.getName(); String actionName = element.getName();
int pos = actionName.indexOf(" ("); int pos = actionName.indexOf(" (");
@@ -1439,7 +1414,7 @@ public abstract class AbstractDataActionTest extends AbstractGhidraHeadedIntegra
} }
protected void checkAction(List<DockingActionIf> actions, String name, boolean isEnabled, protected void checkAction(Set<DockingActionIf> actions, String name, boolean isEnabled,
String caseName) { String caseName) {
for (DockingActionIf element : actions) { for (DockingActionIf element : actions) {
String actionName = element.getName(); String actionName = element.getName();
@@ -17,7 +17,7 @@ package ghidra.app.plugin.core.data;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.List; import java.util.Set;
import org.junit.Test; import org.junit.Test;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
@@ -39,13 +39,13 @@ public class DataAction4Test extends AbstractDataActionTest {
@Test @Test
public void testNotepadLocations() { public void testNotepadLocations() {
List<DockingActionIf> actions; Set<DockingActionIf> actions;
program.addConsumer(this); // allow program to survive close program.addConsumer(this); // allow program to survive close
try { try {
closeProgram(); closeProgram();
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkActions(actions, false, "Start"); checkActions(actions, false, "Start");
@@ -60,7 +60,7 @@ public class DataAction4Test extends AbstractDataActionTest {
closeProgram(); closeProgram();
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkActions(actions, false, "Start"); checkActions(actions, false, "Start");
} }
@@ -73,13 +73,13 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_BYTE, true); doAction(DEFINE_BYTE, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
undo(program); undo(program);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnUndefined(actions); checkOnUndefined(actions);
gotoLocation(0x010069f2); gotoLocation(0x010069f2);
@@ -107,7 +107,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_WORD, true); doAction(DEFINE_WORD, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, WordDataType.class); checkOnDefined(actions, WordDataType.class);
@@ -138,7 +138,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_DWORD, true); doAction(DEFINE_DWORD, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, DWordDataType.class); checkOnDefined(actions, DWordDataType.class);
@@ -169,7 +169,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_QWORD, true); doAction(DEFINE_QWORD, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, QWordDataType.class); checkOnDefined(actions, QWordDataType.class);
@@ -200,7 +200,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_FLOAT, true); doAction(DEFINE_FLOAT, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
@@ -231,7 +231,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_DOUBLE, true); doAction(DEFINE_DOUBLE, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, DoubleDataType.class); checkOnDefined(actions, DoubleDataType.class);
@@ -264,7 +264,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(CYCLE_CHAR_STRING_UNICODE, true); doAction(CYCLE_CHAR_STRING_UNICODE, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, CharDataType.class); checkOnDefined(actions, CharDataType.class);
@@ -283,15 +283,15 @@ public class DataAction4Test extends AbstractDataActionTest {
checkOnDefined(actions, CharDataType.class); checkOnDefined(actions, CharDataType.class);
doAction(CYCLE_CHAR_STRING_UNICODE, true); doAction(CYCLE_CHAR_STRING_UNICODE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, StringDataType.class); checkOnDefined(actions, StringDataType.class);
doAction(CYCLE_CHAR_STRING_UNICODE, true); doAction(CYCLE_CHAR_STRING_UNICODE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, UnicodeDataType.class); checkOnDefined(actions, UnicodeDataType.class);
doAction(CYCLE_CHAR_STRING_UNICODE, true); doAction(CYCLE_CHAR_STRING_UNICODE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, CharDataType.class); checkOnDefined(actions, CharDataType.class);
clearLocation(0x01006a00); clearLocation(0x01006a00);
@@ -326,7 +326,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
@@ -345,19 +345,19 @@ public class DataAction4Test extends AbstractDataActionTest {
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, WordDataType.class); checkOnDefined(actions, WordDataType.class);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, DWordDataType.class); checkOnDefined(actions, DWordDataType.class);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, QWordDataType.class); checkOnDefined(actions, QWordDataType.class);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
clearLocation(0x01006a00); clearLocation(0x01006a00);
@@ -387,19 +387,19 @@ public class DataAction4Test extends AbstractDataActionTest {
// Test cycle when it does not fit // Test cycle when it does not fit
gotoLocation(0x010069f0); gotoLocation(0x010069f0);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnUndefined(actions); checkOnUndefined(actions);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, WordDataType.class); checkOnDefined(actions, WordDataType.class);
doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true); doAction(CYCLE_BYTE_WORD_DWORD_QWORD, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnUndefined(actions); checkOnUndefined(actions);
} }
@@ -414,7 +414,7 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(CYCLE_FLOAT_DOUBLE, true); doAction(CYCLE_FLOAT_DOUBLE, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(ACTION_COUNT, actions.size()); assertEquals(ACTION_COUNT, actions.size());
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
@@ -433,11 +433,11 @@ public class DataAction4Test extends AbstractDataActionTest {
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
doAction(CYCLE_FLOAT_DOUBLE, true); doAction(CYCLE_FLOAT_DOUBLE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, DoubleDataType.class); checkOnDefined(actions, DoubleDataType.class);
doAction(CYCLE_FLOAT_DOUBLE, true); doAction(CYCLE_FLOAT_DOUBLE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
clearLocation(0x01006a00); clearLocation(0x01006a00);
@@ -461,15 +461,15 @@ public class DataAction4Test extends AbstractDataActionTest {
// Test cycle when it does not fit // Test cycle when it does not fit
gotoLocation(0x010069ee); gotoLocation(0x010069ee);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnUndefined(actions); checkOnUndefined(actions);
doAction(CYCLE_FLOAT_DOUBLE, true); doAction(CYCLE_FLOAT_DOUBLE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
doAction(CYCLE_FLOAT_DOUBLE, true); doAction(CYCLE_FLOAT_DOUBLE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnUndefined(actions); checkOnUndefined(actions);
} }
@@ -495,7 +495,7 @@ public class DataAction4Test extends AbstractDataActionTest {
waitForPostedSwingRunnables(); waitForPostedSwingRunnables();
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkOnArray(actions, null, 0x20); checkOnArray(actions, null, 0x20);
// Test action disablement on array element location // Test action disablement on array element location
@@ -524,7 +524,7 @@ public class DataAction4Test extends AbstractDataActionTest {
waitForPostedSwingRunnables(); waitForPostedSwingRunnables();
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnArray(actions, new ByteDataType(), 0x10); checkOnArray(actions, new ByteDataType(), 0x10);
} }
@@ -541,7 +541,7 @@ public class DataAction4Test extends AbstractDataActionTest {
clearSelection();// Remove selection to allow array check to work clearSelection();// Remove selection to allow array check to work
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkOnArray(actions, null, 0x20); checkOnArray(actions, null, 0x20);
// Create Byte[0x10] array // Create Byte[0x10] array
@@ -555,7 +555,7 @@ public class DataAction4Test extends AbstractDataActionTest {
clearSelection();// Remove selection to allow array check to work clearSelection();// Remove selection to allow array check to work
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnArray(actions, new ByteDataType(), 0x10); checkOnArray(actions, new ByteDataType(), 0x10);
} }
@@ -565,10 +565,7 @@ public class DataAction4Test extends AbstractDataActionTest {
gotoLocation(0x01006c00); gotoLocation(0x01006c00);
List<DockingActionIf> actions = DockingActionIf recentlyUsedAction = getAction(tool, plugin.getName(), RECENTLY_USED);
tool.getDockingActionsByFullActionName(RECENTLY_USED + " (" + plugin.getName() + ")");
assertEquals(1, actions.size());
DockingActionIf recentlyUsedAction = actions.get(0);
String caseName = "On Structure at: " + getCurrentLocation(); String caseName = "On Structure at: " + getCurrentLocation();
checkAction(recentlyUsedAction, false, caseName); checkAction(recentlyUsedAction, false, caseName);
@@ -591,7 +588,7 @@ public class DataAction4Test extends AbstractDataActionTest {
clearSelection(); clearSelection();
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkOnStructure(actions, 0x20); checkOnStructure(actions, 0x20);
gotoLocation(0x01006c00); gotoLocation(0x01006c00);
@@ -708,14 +705,14 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_BYTE, true); doAction(DEFINE_BYTE, true);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
gotoLocation(0x01006a01, new int[] { 1 }); gotoLocation(0x01006a01, new int[] { 1 });
doAction(DEFINE_FLOAT, true); doAction(DEFINE_FLOAT, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
Data pdata = getContextData().getParent(); Data pdata = getContextData().getParent();
@@ -757,7 +754,7 @@ public class DataAction4Test extends AbstractDataActionTest {
waitForPostedSwingRunnables(); waitForPostedSwingRunnables();
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkOnArray(actions, structDt, 5); checkOnArray(actions, structDt, 5);
// Expand structure // Expand structure
@@ -772,14 +769,14 @@ public class DataAction4Test extends AbstractDataActionTest {
doAction(DEFINE_BYTE, true); doAction(DEFINE_BYTE, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, ByteDataType.class); checkOnDefined(actions, ByteDataType.class);
gotoLocation(0x01006a01, new int[] { 0, 1 }); gotoLocation(0x01006a01, new int[] { 0, 1 });
doAction(DEFINE_FLOAT, true); doAction(DEFINE_FLOAT, true);
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
checkOnDefined(actions, FloatDataType.class); checkOnDefined(actions, FloatDataType.class);
Data pdata = getContextData().getParent(); Data pdata = getContextData().getParent();
@@ -37,7 +37,7 @@ import org.junit.*;
import docking.DockingUtils; import docking.DockingUtils;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.action.ToggleDockingActionIf; import docking.action.ToggleDockingActionIf;
import docking.util.KeyBindingUtils; import docking.actions.KeyBindingUtils;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.combobox.GhidraComboBox; import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.dialogs.InputWithChoicesDialog; import docking.widgets.dialogs.InputWithChoicesDialog;
@@ -17,7 +17,7 @@ package ghidra.app.plugin.core.equate;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.List; import java.util.Set;
import javax.swing.JTextField; import javax.swing.JTextField;
@@ -115,11 +115,10 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
// for selection containing a function stack address // for selection containing a function stack address
builder.setBytes("0x01004bbd", "c2 08 00"); // return of previous function builder.setBytes("0x01004bbd", "c2 08 00"); // return of previous function
builder.setBytes("0x01004bc0", builder.setBytes("0x01004bc0", "53 8b 5c 24 08 56 8b 35 b8 10 00 01 57 ff 35 78 80 00 01 " +
"53 8b 5c 24 08 56 8b 35 b8 10 00 01 57 ff 35 78 80 00 01 " + "53 ff d6 8b 3d e0 10 00 01 53 ff d7 8d 5c 43 02 68 9c 13 00 01 53 ff d6 53 ff d7 " +
"53 ff d6 8b 3d e0 10 00 01 53 ff d7 8d 5c 43 02 68 9c 13 00 01 53 ff d6 53 ff d7 " + "ff 35 7c 80 00 01 8d 5c 43 02 53 ff d6 53 ff d7 8d 5c 43 02 68 e0 17 00 01 53 ff " +
"ff 35 7c 80 00 01 8d 5c 43 02 53 ff d6 53 ff d7 8d 5c 43 02 68 e0 17 00 01 53 ff " + "d6 53 ff d7 66 83 64 43 02 00 8d 44 43 02 5f 5e 5b c2 04 00");
"d6 53 ff d7 66 83 64 43 02 00 8d 44 43 02 5f 5e 5b c2 04 00");
builder.disassemble(new AddressSet(builder.getProgram(), builder.addr("0x01004bc0"), builder.disassemble(new AddressSet(builder.getProgram(), builder.addr("0x01004bc0"),
builder.addr("0x01004c1a")), true); builder.addr("0x01004c1a")), true);
builder.createFunction("0x01004bc0"); builder.createFunction("0x01004bc0");
@@ -203,8 +202,6 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
env.dispose(); env.dispose();
} }
//================================================================================================= //=================================================================================================
// Private Methods // Private Methods
//================================================================================================= //=================================================================================================
@@ -218,8 +215,7 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
ComponentProvider provider = tool.getComponentProvider(PluginConstants.CODE_BROWSER); ComponentProvider provider = tool.getComponentProvider(PluginConstants.CODE_BROWSER);
DockingActionIf action = getAction(equatePlugin, "Apply Enum"); DockingActionIf action = getAction(equatePlugin, "Apply Enum");
performAction(action, provider, false); performAction(action, provider, false);
ApplyEnumDialog d = ApplyEnumDialog d = waitForDialogComponent(ApplyEnumDialog.class);
waitForDialogComponent(tool.getToolFrame(), ApplyEnumDialog.class, DEFAULT_WAIT_DELAY);
return d; return d;
} }
@@ -231,7 +227,7 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
} }
protected void assertConvertActionsInPopup(boolean inPopup) { protected void assertConvertActionsInPopup(boolean inPopup) {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String actionName = action.getName(); String actionName = action.getName();
if (actionName.startsWith("Convert")) { if (actionName.startsWith("Convert")) {
@@ -242,7 +238,7 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
} }
protected void assertNonFloatConvertActionsInPopup() { protected void assertNonFloatConvertActionsInPopup() {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String actionName = action.getName(); String actionName = action.getName();
if (actionName.startsWith("Convert")) { if (actionName.startsWith("Convert")) {
@@ -255,7 +251,7 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
} }
protected void assertConvertNonCharNonSignedActionsInPopup() { protected void assertConvertNonCharNonSignedActionsInPopup() {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
for (DockingActionIf element : actions) { for (DockingActionIf element : actions) {
String name = element.getName(); String name = element.getName();
if (name.startsWith("Convert") && if (name.startsWith("Convert") &&
@@ -266,7 +262,7 @@ public abstract class AbstractEquatePluginTest extends AbstractProgramBasedTest
} }
protected void assertConvertNonSignedActionsInPopup() { protected void assertConvertNonSignedActionsInPopup() {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String name = action.getName(); String name = action.getName();
if (name.startsWith("Convert") && name.indexOf("Signed") < 0) { if (name.startsWith("Convert") && name.indexOf("Signed") < 0) {
@@ -19,6 +19,7 @@ import static org.junit.Assert.*;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.TableModel; import javax.swing.table.TableModel;
@@ -841,7 +842,7 @@ public class EquatePlugin1Test extends AbstractEquatePluginTest {
putCursorOnOperand(0x010064ae, 1); putCursorOnOperand(0x010064ae, 1);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
int found = 0; int found = 0;
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String name = action.getName(); String name = action.getName();
@@ -892,7 +893,7 @@ public class EquatePlugin1Test extends AbstractEquatePluginTest {
putCursorOnOperand(0x010064a3, 0); putCursorOnOperand(0x010064a3, 0);
int found = 0; int found = 0;
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String name = action.getName(); String name = action.getName();
if (!name.startsWith("Convert") || !action.isAddToPopup(getListingContext())) { if (!name.startsWith("Convert") || !action.isAddToPopup(getListingContext())) {
@@ -944,7 +945,7 @@ public class EquatePlugin1Test extends AbstractEquatePluginTest {
putCursorOnOperand(0x01003a94, 0); putCursorOnOperand(0x01003a94, 0);
int found = 0; int found = 0;
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("EquatePlugin"); Set<DockingActionIf> actions = getActionsByOwner(tool, "EquatePlugin");
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String name = action.getName(); String name = action.getName();
if (!name.startsWith("Convert") || !action.isAddToPopup(getListingContext())) { if (!name.startsWith("Convert") || !action.isAddToPopup(getListingContext())) {
@@ -17,7 +17,7 @@ package ghidra.app.plugin.core.fallthrough;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.util.List; import java.util.Set;
import org.junit.*; import org.junit.*;
@@ -37,7 +37,8 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.test.*; import ghidra.test.*;
public class FallThroughActionTest extends AbstractGhidraHeadedIntegrationTest implements LocationCallback { public class FallThroughActionTest extends AbstractGhidraHeadedIntegrationTest
implements LocationCallback {
private Program program; private Program program;
private TestEnv env; private TestEnv env;
private PluginTool tool; private PluginTool tool;
@@ -70,7 +71,7 @@ public class FallThroughActionTest extends AbstractGhidraHeadedIntegrationTest i
@Test @Test
public void testNotepadLocations() { public void testNotepadLocations() {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkAction(actions, AUTO_OVERRIDE, false, "Start"); checkAction(actions, AUTO_OVERRIDE, false, "Start");
checkAction(actions, CLEAR_FALLTHROUGH, false, "Start"); checkAction(actions, CLEAR_FALLTHROUGH, false, "Start");
@@ -96,7 +97,7 @@ public class FallThroughActionTest extends AbstractGhidraHeadedIntegrationTest i
new ProgramSelectionPluginEvent("Test", selection, program); new ProgramSelectionPluginEvent("Test", selection, program);
tool.firePluginEvent(ev); tool.firePluginEvent(ev);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
checkAction(actions, AUTO_OVERRIDE, true, "selection"); checkAction(actions, AUTO_OVERRIDE, true, "selection");
checkAction(actions, CLEAR_FALLTHROUGH, true, "selection"); checkAction(actions, CLEAR_FALLTHROUGH, true, "selection");
@@ -110,7 +111,7 @@ public class FallThroughActionTest extends AbstractGhidraHeadedIntegrationTest i
@Override @Override
public void locationGenerated(ProgramLocation loc) { public void locationGenerated(ProgramLocation loc) {
tool.firePluginEvent(new ProgramLocationPluginEvent("test", loc, program)); tool.firePluginEvent(new ProgramLocationPluginEvent("test", loc, program));
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
ListingActionContext actionContext = ListingActionContext actionContext =
(ListingActionContext) cb.getProvider().getActionContext(null); (ListingActionContext) cb.getProvider().getActionContext(null);
@@ -126,7 +127,7 @@ public class FallThroughActionTest extends AbstractGhidraHeadedIntegrationTest i
} }
private void checkAction(List<DockingActionIf> actions, String name, boolean isValidContext, private void checkAction(Set<DockingActionIf> actions, String name, boolean isValidContext,
String caseName) { String caseName) {
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String actionName = action.getName(); String actionName = action.getName();
@@ -19,7 +19,7 @@ import static org.junit.Assert.*;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.List; import java.util.Set;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JTextField; import javax.swing.JTextField;
@@ -96,7 +96,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
env.close(program); env.close(program);
program = buildProgram("sdk"); program = buildProgram("sdk");
env.open(program); env.open(program);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
if (action.getName().equals("Add Block") || action.getName().equals("Set Image Base") || if (action.getName().equals("Add Block") || action.getName().equals("Set Image Base") ||
action.getName().equals("View Memory Map")) { action.getName().equals("View Memory Map")) {
@@ -114,7 +114,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
env.close(program); env.close(program);
JTable table = provider.getTable(); JTable table = provider.getTable();
assertEquals(0, table.getModel().getRowCount()); assertEquals(0, table.getModel().getRowCount());
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
if (!action.getName().equals("View Memory Map")) { if (!action.getName().equals("View Memory Map")) {
assertTrue(!action.isEnabledForContext(provider.getActionContext(null))); assertTrue(!action.isEnabledForContext(provider.getActionContext(null)));
@@ -19,7 +19,6 @@ import static org.junit.Assert.*;
import java.awt.*; import java.awt.*;
import java.util.*; import java.util.*;
import java.util.List;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.JTableHeader; import javax.swing.table.JTableHeader;
@@ -117,7 +116,7 @@ public class MemoryMapProvider1Test extends AbstractGhidraHeadedIntegrationTest
// select first row // select first row
// all actions except "merge" should be enabled // all actions except "merge" should be enabled
table.addRowSelectionInterval(0, 0); table.addRowSelectionInterval(0, 0);
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
if (action.getName().equals("Merge Blocks")) { if (action.getName().equals("Merge Blocks")) {
assertTrue(!action.isEnabled()); assertTrue(!action.isEnabled());
@@ -133,7 +132,7 @@ public class MemoryMapProvider1Test extends AbstractGhidraHeadedIntegrationTest
table.addRowSelectionInterval(0, 1); table.addRowSelectionInterval(0, 1);
assertEquals(2, table.getSelectedRowCount()); assertEquals(2, table.getSelectedRowCount());
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
String name = action.getName(); String name = action.getName();
if (name.equals("Add Block") || name.equals("Merge Blocks") || if (name.equals("Add Block") || name.equals("Merge Blocks") ||
@@ -18,8 +18,7 @@ package ghidra.app.plugin.core.module;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.Arrays; import java.util.*;
import java.util.List;
import org.junit.*; import org.junit.*;
@@ -42,7 +41,7 @@ public class ModuleSortPluginTest extends AbstractGhidraHeadedIntegrationTest {
private PluginTool tool; private PluginTool tool;
private Program program; private Program program;
private ModuleSortPlugin plugin; private ModuleSortPlugin plugin;
private List<DockingActionIf> actions; private Set<DockingActionIf> actions;
private ProgramTreeService service; private ProgramTreeService service;
public ModuleSortPluginTest() { public ModuleSortPluginTest() {
@@ -63,7 +62,7 @@ public class ModuleSortPluginTest extends AbstractGhidraHeadedIntegrationTest {
break; break;
} }
} }
actions = tool.getDockingActionsByOwnerName(plugin.getName()); actions = getActionsByOwner(tool, plugin.getName());
service = tool.getService(ProgramTreeService.class); service = tool.getService(ProgramTreeService.class);
ProgramBuilder builder = new ProgramBuilder("notepad", ProgramBuilder._TOY); ProgramBuilder builder = new ProgramBuilder("notepad", ProgramBuilder._TOY);
@@ -17,8 +17,7 @@ package ghidra.app.plugin.core.navigation;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import javax.swing.*; import javax.swing.*;
@@ -65,7 +64,7 @@ import ghidra.util.Msg;
import ghidra.util.table.GhidraProgramTableModel; import ghidra.util.table.GhidraProgramTableModel;
import ghidra.util.table.field.LabelTableColumn; import ghidra.util.table.field.LabelTableColumn;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter; import util.CollectionUtils;
public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest { public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env; private TestEnv env;
@@ -104,20 +103,20 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
@Test @Test
public void testActionEnablement() throws Exception { public void testActionEnablement() throws Exception {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(plugin.getName()); Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
assertEquals(1, actions.size()); assertEquals(1, actions.size());
assertEquals("Go To Address/Label", actions.get(0).getName()); assertEquals("Go To Address/Label", CollectionUtils.any(actions).getName());
ActionContext actionContext = getActionContext(); ActionContext actionContext = getActionContext();
assertTrue(!actions.get(0).isEnabledForContext(actionContext)); assertTrue(!CollectionUtils.any(actions).isEnabledForContext(actionContext));
loadProgram("x86"); loadProgram("x86");
actionContext = getActionContext(); actionContext = getActionContext();
assertTrue(actions.get(0).isEnabledForContext(actionContext)); assertTrue(CollectionUtils.any(actions).isEnabledForContext(actionContext));
final ProgramManager pm = tool.getService(ProgramManager.class); final ProgramManager pm = tool.getService(ProgramManager.class);
SwingUtilities.invokeAndWait(() -> pm.closeProgram(program, true)); runSwing(() -> pm.closeProgram(program, true));
actionContext = getActionContext(); actionContext = getActionContext();
assertTrue(!actions.get(0).isEnabledForContext(actionContext)); assertTrue(!CollectionUtils.any(actions).isEnabledForContext(actionContext));
} }
@Test @Test
@@ -476,7 +475,7 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
performOkCallback(); performOkCallback();
assertEquals("No results for xyzabc*", dialog.getStatusText()); assertEquals("No results for xyzabc*", dialog.getStatusText());
SwingUtilities.invokeAndWait(() -> dialog.close()); runSwing(() -> dialog.close());
} }
@Test @Test
@@ -561,7 +560,7 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
final JCheckBox cb = findComponent(dialog, JCheckBox.class); final JCheckBox cb = findComponent(dialog, JCheckBox.class);
SwingUtilities.invokeAndWait(() -> { runSwing(() -> {
cb.setSelected(false); cb.setSelected(false);
dialog.setText("COm*"); dialog.setText("COm*");
@@ -831,7 +830,7 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
Assert.assertNotNull(program); Assert.assertNotNull(program);
final ProgramManager pm = tool.getService(ProgramManager.class); final ProgramManager pm = tool.getService(ProgramManager.class);
SwingUtilities.invokeAndWait(() -> pm.openProgram(program.getDomainFile())); runSwing(() -> pm.openProgram(program.getDomainFile()));
program.release(this); program.release(this);
addrFactory = program.getAddressFactory(); addrFactory = program.getAddressFactory();
} }
@@ -965,7 +964,7 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
try { try {
Memory memory = program.getMemory(); Memory memory = program.getMemory();
return memory.createInitializedBlock(name, addr(address), size, (byte) 0, return memory.createInitializedBlock(name, addr(address), size, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, true); TaskMonitor.DUMMY, true);
} }
finally { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
@@ -1023,7 +1022,7 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void setText(final String text) throws Exception { private void setText(final String text) throws Exception {
SwingUtilities.invokeAndWait(() -> dialog.setText(text)); runSwing(() -> dialog.setText(text));
} }
private void performOkCallback() throws Exception { private void performOkCallback() throws Exception {
@@ -1035,17 +1034,7 @@ public class GoToPluginTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void waitForOKCallback() { private void waitForOKCallback() {
int numWaits = 0; waitForCondition(() -> runSwing(() -> okButton.isEnabled()));
while (++numWaits < 50 && !okButton.isEnabled()) {
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
// no biggie, will try again
}
}
Assert.assertNotEquals("Timed-out waiting for Go To dialog to finish", 50, numWaits);
} }
private void assumeCurrentAddressSpace(boolean b) { private void assumeCurrentAddressSpace(boolean b) {
@@ -20,8 +20,7 @@ import static org.junit.Assert.*;
import java.awt.Window; import java.awt.Window;
import java.io.*; import java.io.*;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.List; import java.util.*;
import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -60,6 +59,7 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.table.GhidraTable; import ghidra.util.table.GhidraTable;
import ghidra.util.table.GhidraTableFilterPanel; import ghidra.util.table.GhidraTableFilterPanel;
import ghidra.util.task.*; import ghidra.util.task.*;
import util.CollectionUtils;
import utilities.util.FileUtilities; import utilities.util.FileUtilities;
public abstract class AbstractGhidraScriptMgrPluginTest public abstract class AbstractGhidraScriptMgrPluginTest
@@ -272,10 +272,18 @@ public abstract class AbstractGhidraScriptMgrPluginTest
assertTrue(message, fullText.contains(piece)); assertTrue(message, fullText.contains(piece));
} }
protected void assertRunLastActionEnabled(boolean enabled) { private DockingActionIf getRunLastScriptAction() {
final DockingActionIf runLastAction = getAction(plugin, "Rerun Last Script"); // note: this provider adds 2 versions of the same action--pick either
assertNotNull(runLastAction); Set<DockingActionIf> actions =
getActionsByOwnerAndName(plugin.getTool(), plugin.getName(), "Rerun Last Script");
assertFalse(actions.isEmpty());
DockingActionIf runLastAction = CollectionUtils.any(actions);
return runLastAction;
}
protected void assertRunLastActionEnabled(boolean enabled) {
DockingActionIf runLastAction = getRunLastScriptAction();
final AtomicReference<Boolean> ref = new AtomicReference<>(); final AtomicReference<Boolean> ref = new AtomicReference<>();
runSwing(() -> ref.set(runLastAction.isEnabledForContext(new ActionContext()))); runSwing(() -> ref.set(runLastAction.isEnabledForContext(new ActionContext())));
assertEquals("Run Last Action not enabled as expected", enabled, ref.get()); assertEquals("Run Last Action not enabled as expected", enabled, ref.get());
@@ -557,17 +565,15 @@ public abstract class AbstractGhidraScriptMgrPluginTest
} }
protected void pressRunLastScriptButton() { protected void pressRunLastScriptButton() {
DockingActionIf action = DockingActionIf runLastAction = getRunLastScriptAction();
getAction(plugin, GhidraScriptActionManager.RERUN_LAST_SHARED_ACTION_NAME); performAction(runLastAction, false);
performAction(action, false);
waitForSwing(); waitForSwing();
} }
protected void performGlobalRunLastScriptAction() { protected void performGlobalRunLastScriptAction() {
DockingActionIf action = // note: this action used to be different from the 'run last script'; currently they are
getAction(plugin, GhidraScriptActionManager.GLOBAL_RERUN_LAST_SHARED_ACTION_NAME); // the same
performAction(action, false); pressRunLastScriptButton();
waitForSwing();
} }
protected KeyBindingInputDialog pressKeyBindingAction() { protected KeyBindingInputDialog pressKeyBindingAction() {
@@ -1293,7 +1299,7 @@ public abstract class AbstractGhidraScriptMgrPluginTest
protected void assertToolKeyBinding(KeyStroke ks) { protected void assertToolKeyBinding(KeyStroke ks) {
String actionOwner = GhidraScriptMgrPlugin.class.getSimpleName(); String actionOwner = GhidraScriptMgrPlugin.class.getSimpleName();
PluginTool tool = env.getTool(); PluginTool tool = env.getTool();
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName(actionOwner); Set<DockingActionIf> actions = getActionsByOwner(tool, actionOwner);
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
KeyStroke keyBinding = action.getKeyBinding(); KeyStroke keyBinding = action.getKeyBinding();
if (keyBinding == null) { if (keyBinding == null) {
@@ -684,8 +684,8 @@ public class SearchTextPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
final GTable table = threadedTablePanel.getTable(); final GTable table = threadedTablePanel.getTable();
Random random = new Random(); Random random = new Random();
final int randomRow = random.nextInt(model.getRowCount()); final int randomRow = random.nextInt(model.getRowCount());
DockingActionIf deleteRowAction =
tool.getDockingActionsByFullActionName("Remove Items (TableServicePlugin)").get(0); DockingActionIf deleteRowAction = getAction(tool, "TableServicePlugin", "Remove Items");
ProgramLocation toBeDeleted = model.getRowObject(randomRow); ProgramLocation toBeDeleted = model.getRowObject(randomRow);
runSwing(() -> table.setRowSelectionInterval(randomRow, randomRow)); runSwing(() -> table.setRowSelectionInterval(randomRow, randomRow));
performAction(deleteRowAction, true); performAction(deleteRowAction, true);
@@ -1306,11 +1306,8 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
private void setupSymbolTableFilterToShowParameters() throws Exception { private void setupSymbolTableFilterToShowParameters() throws Exception {
// get the filter action - "Set Filter" // get the filter action - "Set Filter"
List<DockingActionIf> actions =
tool.getDockingActionsByFullActionName("Set Filter (SymbolTablePlugin)"); DockingActionIf filterAction = getAction(tool, "SymbolTablePlugin", "Set Filter");
assertNotNull(actions);
assertTrue(actions.size() > 0);
DockingActionIf filterAction = actions.get(0);
// execute // execute
performAction(filterAction, false); performAction(filterAction, false);
@@ -30,6 +30,7 @@ import org.junit.*;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.test.AbstractDockingTest;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.tree.GTreeNode; import docking.widgets.tree.GTreeNode;
import docking.widgets.tree.GTreeRootNode; import docking.widgets.tree.GTreeRootNode;
@@ -596,10 +597,9 @@ public class ActionManager1Test extends AbstractGhidraHeadedIntegrationTest {
} }
private DockingActionIf getAction(String actionName) { private DockingActionIf getAction(String actionName) {
List<DockingActionIf> a = DockingActionIf action =
frontEndTool.getDockingActionsByFullActionName(actionName + " (FrontEndPlugin)"); AbstractDockingTest.getAction(frontEndTool, "FrontEndPlugin", actionName);
Assert.assertEquals(1, a.size()); return action;
return a.get(0);
} }
private void expandTreePath(TreePath path) { private void expandTreePath(TreePath path) {
@@ -30,6 +30,7 @@ import org.junit.*;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.action.ToggleDockingAction; import docking.action.ToggleDockingAction;
import docking.test.AbstractDockingTest;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.tree.GTreeNode; import docking.widgets.tree.GTreeNode;
import docking.widgets.tree.GTreeRootNode; import docking.widgets.tree.GTreeRootNode;
@@ -60,10 +61,6 @@ public class ActionManager2Test extends AbstractGhidraHeadedIntegrationTest {
private DomainFolder rootFolder; private DomainFolder rootFolder;
private GTreeRootNode rootNode; private GTreeRootNode rootNode;
public ActionManager2Test() {
super();
}
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
env = new TestEnv(); env = new TestEnv();
@@ -363,10 +360,9 @@ public class ActionManager2Test extends AbstractGhidraHeadedIntegrationTest {
} }
private DockingActionIf getAction(String actionName) { private DockingActionIf getAction(String actionName) {
List<DockingActionIf> a = DockingActionIf action =
frontEndTool.getDockingActionsByFullActionName(actionName + " (FrontEndPlugin)"); AbstractDockingTest.getAction(frontEndTool, "FrontEndPlugin", actionName);
assertEquals(1, a.size()); return action;
return a.get(0);
} }
private void setSelectionPath(final TreePath path) throws Exception { private void setSelectionPath(final TreePath path) throws Exception {
@@ -30,10 +30,10 @@ import javax.swing.tree.TreePath;
import org.junit.*; import org.junit.*;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.actions.KeyBindingUtils;
import docking.options.editor.OptionsDialog; import docking.options.editor.OptionsDialog;
import docking.options.editor.OptionsPanel; import docking.options.editor.OptionsPanel;
import docking.tool.util.DockingToolConstants; import docking.tool.util.DockingToolConstants;
import docking.util.KeyBindingUtils;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.tree.GTree; import docking.widgets.tree.GTree;
import generic.io.NullWriter; import generic.io.NullWriter;
@@ -228,13 +228,13 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
// import the original values file through the tool // import the original values file through the tool
importOptionsWithGUI(saveFile, true); importOptionsWithGUI(saveFile, true);
// get the updated values that have not been applied // get the updated values that have not been applied
Map<?, ?> optionsMap = (Map<?, ?>) getInstanceField("actionMap", panel); Map<String, KeyStroke> keyStrokeMap = panel.getKeyStrokeMap();
debug("f"); debug("f");
// verify the data is the same as it was before the changes // verify the data is the same as it was before the changes
boolean same = compareOptionsWithKeyStrokeMap(originalOptions, optionsMap); boolean same = compareOptionsWithKeyStrokeMap(originalOptions, keyStrokeMap);
assertTrue("The Options object contains different data than was " + "imported.", same); assertTrue("The Options object contains different data than was imported.", same);
debug("g"); debug("g");
@@ -405,26 +405,26 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void setKeyBinding(String keyText, int keyCode) throws Exception { private void setKeyBinding(String keyText, int keyCode) throws Exception {
List<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
DockingActionIf action = null; DockingActionIf arbitraryAction = null;
for (int i = 0; i < list.size(); i++) { for (DockingActionIf action : list) {
action = list.get(i);
if (action.isKeyBindingManaged() && action.getKeyBinding() == null) { if (action.isKeyBindingManaged() && action.getKeyBinding() == null) {
arbitraryAction = action;
break; break;
} }
} }
if (action == null) { if (arbitraryAction == null) {
Assert.fail("Unable to find an action for which to set a key binding."); Assert.fail("Unable to find an action for which to set a key binding.");
} }
selectRowForAction(action); selectRowForAction(arbitraryAction);
triggerText(keyField, keyText); triggerText(keyField, keyText);
assertEquals(keyText.toUpperCase(), keyField.getText()); assertEquals(keyText.toUpperCase(), keyField.getText());
runSwing(() -> panel.apply()); runSwing(() -> panel.apply());
assertEquals(KeyStroke.getKeyStroke(keyCode, 0), action.getKeyBinding()); assertEquals(KeyStroke.getKeyStroke(keyCode, 0), arbitraryAction.getKeyBinding());
} }
private void selectRowForAction(DockingActionIf action) throws Exception { private void selectRowForAction(DockingActionIf action) throws Exception {
@@ -533,20 +533,19 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
// compares the provided options with the mapping of property names to // compares the provided options with the mapping of property names to
// keystrokes (the map is obtained from the key bindings panel after an // keystrokes (the map is obtained from the key bindings panel after an
// import is done). // import is done).
private boolean compareOptionsWithKeyStrokeMap(Options options, Map<?, ?> optionsMap) { private boolean compareOptionsWithKeyStrokeMap(Options options,
Map<String, KeyStroke> panelKeyStrokeMap) {
List<String> propertyNames = options.getOptionNames(); List<String> propertyNames = options.getOptionNames();
for (String element : propertyNames) { for (String element : propertyNames) {
boolean match = optionsMap.containsKey(element); boolean match = panelKeyStrokeMap.containsKey(element);
Object value = invokeInstanceMethod("getKeyStroke", options, KeyStroke optionsKs = options.getKeyStroke(element, null);
new Class[] { String.class, KeyStroke.class }, new Object[] { element, null }); KeyStroke panelKs = panelKeyStrokeMap.get(element);
Object value2 = optionsMap.get(element);
// if the value is null, then it would not have been placed into the // if the value is null, then it would not have been placed into the options map
// options map in the key bindings panel, so we only care about // in the key bindings panel, so we only care about non-null values
// non-null values if (optionsKs != null) {
if (value != null) { match &= (optionsKs.equals(panelKs));
match &= (value.equals(value2));
} }
else { else {
match = true; match = true;
@@ -20,7 +20,7 @@ import static org.junit.Assert.*;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.List; import java.util.Set;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.*; import javax.swing.table.*;
@@ -29,10 +29,10 @@ import org.junit.*;
import docking.KeyEntryTextField; import docking.KeyEntryTextField;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.tool.util.DockingToolConstants;
import docking.widgets.MultiLineLabel; import docking.widgets.MultiLineLabel;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.ToolConstants;
import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv; import ghidra.test.TestEnv;
import ghidra.util.Msg; import ghidra.util.Msg;
@@ -102,9 +102,8 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
@Test @Test
public void testManagedKeyBindings() { public void testManagedKeyBindings() {
List<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
for (int i = 0; i < list.size(); i++) { for (DockingActionIf action : list) {
DockingActionIf action = list.get(i);
if (action.isKeyBindingManaged()) { if (action.isKeyBindingManaged()) {
assertTrue(actionInTable(action)); assertTrue(actionInTable(action));
} }
@@ -128,10 +127,8 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
@Test @Test
public void testActionNotSelected() throws Exception { public void testActionNotSelected() throws Exception {
table.clearSelection(); table.clearSelection();
List<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
DockingActionIf action = null; for (DockingActionIf action : list) {
for (int i = 0; i < list.size(); i++) {
action = list.get(i);
KeyStroke ks = getKeyStroke(action); KeyStroke ks = getKeyStroke(action);
if (isKeyBindingManaged(action) && ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) { if (isKeyBindingManaged(action) && ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) {
break; break;
@@ -318,10 +315,8 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
} }
private DockingActionIf getKeyBindingPluginAction() { private DockingActionIf getKeyBindingPluginAction() {
List<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
DockingActionIf action = null; for (DockingActionIf action : list) {
for (int i = 0; i < list.size(); i++) {
action = list.get(i);
KeyStroke ks = action.getKeyBinding(); KeyStroke ks = action.getKeyBinding();
if (action.isKeyBindingManaged() && ks != null && if (action.isKeyBindingManaged() && ks != null &&
ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) { ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) {
@@ -372,7 +367,7 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
private void setUpDialog() throws Exception { private void setUpDialog() throws Exception {
runSwing(() -> { runSwing(() -> {
panel = new KeyBindingsPanel(tool, tool.getOptions(ToolConstants.KEY_BINDINGS)); panel = new KeyBindingsPanel(tool, tool.getOptions(DockingToolConstants.KEY_BINDINGS));
dialog = new JDialog(tool.getToolFrame(), "Test KeyBindings", false); dialog = new JDialog(tool.getToolFrame(), "Test KeyBindings", false);
dialog.getContentPane().add(panel); dialog.getContentPane().add(panel);
@@ -391,10 +386,8 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void grabActionsWithoutKeybinding() { private void grabActionsWithoutKeybinding() {
List<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
DockingActionIf action = null; for (DockingActionIf action : list) {
for (int i = 0; i < list.size(); i++) {
action = list.get(i);
if (!action.isKeyBindingManaged()) { if (!action.isKeyBindingManaged()) {
continue; continue;
} }
@@ -20,8 +20,6 @@ import static org.junit.Assert.*;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.swing.SwingUtilities;
import org.junit.*; import org.junit.*;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
@@ -74,7 +72,7 @@ public class ManageFrontEndToolTest extends AbstractGhidraHeadedIntegrationTest
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
SwingUtilities.invokeAndWait(() -> { runSwing(() -> {
tool.setConfigChanged(false); tool.setConfigChanged(false);
provider.close(); provider.close();
}); });
@@ -99,33 +97,27 @@ public class ManageFrontEndToolTest extends AbstractGhidraHeadedIntegrationTest
final Plugin p = getPlugin(tool, ArchivePlugin.class); final Plugin p = getPlugin(tool, ArchivePlugin.class);
assertNotNull(p); assertNotNull(p);
SwingUtilities.invokeAndWait(() -> { runSwing(() -> {
provider.close(); provider.close();
tool.removePlugins(new Plugin[] { p }); tool.removePlugins(new Plugin[] { p });
}); });
showProvider(); showProvider();
List<DockingActionIf> actions = DockingActionIf action = getAction(tool, plugin.getName(), "Save Project");
tool.getDockingActionsByFullActionName("Save Project (" + plugin.getName() + ")"); performAction(action, true);
assertEquals(1, actions.size());
performAction(actions.get(0), true);
actions = action = getAction(tool, plugin.getName(), "Close Project");
tool.getDockingActionsByFullActionName("Close Project (" + plugin.getName() + ")"); performAction(action, true);
assertEquals(1, actions.size());
performAction(actions.get(0), true);
assertTrue(!provider.isVisible()); assertTrue(!provider.isVisible());
} }
private void showProvider() throws Exception { private void showProvider() throws Exception {
List<DockingActionIf> actions =
tool.getDockingActionsByFullActionName("Configure Tool (Project Window)");
assertEquals(1, actions.size());
performAction(actions.get(0), true); DockingActionIf action = getAction(tool, "Project Window", "Configure Tool");
performAction(action, true);
waitForPostedSwingRunnables(); waitForPostedSwingRunnables();
SwingUtilities.invokeAndWait(() -> tool.showConfig(false, false)); runSwing(() -> tool.showConfig(false, false));
provider = tool.getManagePluginsDialog(); provider = tool.getManagePluginsDialog();
pluginManagerComponent = (PluginManagerComponent) getInstanceField("comp", provider); pluginManagerComponent = (PluginManagerComponent) getInstanceField("comp", provider);
@@ -254,11 +254,9 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void showProvider() { private void showProvider() {
List<DockingActionIf> actions =
tool.getDockingActionsByFullActionName("Configure Tool (Tool)");
assertEquals(1, actions.size());
performAction(actions.get(0), true); DockingActionIf action = getAction(tool, "Tool", "Configure Tool");
performAction(action, true);
waitForSwing(); waitForSwing();
provider = tool.getManagePluginsDialog(); provider = tool.getManagePluginsDialog();
pluginManagerComponent = (PluginManagerComponent) getInstanceField("comp", provider); pluginManagerComponent = (PluginManagerComponent) getInstanceField("comp", provider);
@@ -18,7 +18,6 @@ package ghidra.framework.project.tool;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.awt.Window; import java.awt.Window;
import java.util.List;
import org.junit.*; import org.junit.*;
@@ -56,7 +55,7 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest {
public void tearDown() throws Exception { public void tearDown() throws Exception {
executeOnSwingWithoutBlocking(() -> env.dispose()); executeOnSwingWithoutBlocking(() -> env.dispose());
closeAllWindowsAndFrames(); closeAllWindows();
} }
@@ -138,7 +137,7 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest {
closeTool(tool); closeTool(tool);
// check for warning dialog // check for warning dialog
Window window = waitForWindow(tool.getToolFrame(), "Tool Busy", 2000); Window window = waitForWindow("Tool Busy");
assertNotNull("Did not get tool busy dialog", window); assertNotNull("Did not get tool busy dialog", window);
closeWindow(window); closeWindow(window);
@@ -146,7 +145,7 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest {
closeProgram(tool, program); closeProgram(tool, program);
// check for warning dialog // check for warning dialog
window = waitForWindow(tool.getToolFrame(), "Close notepad Failed", 2000); window = waitForWindow("Close notepad Failed");
assertNotNull("Did not get \"close failed\" dialog", window); assertNotNull("Did not get \"close failed\" dialog", window);
closeWindow(window); closeWindow(window);
@@ -169,11 +168,9 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void closeProgram(final PluginTool tool, final ProgramDB program) { private void closeProgram(final PluginTool tool, final ProgramDB program) {
List<DockingActionIf> actionList =
tool.getDockingActionsByFullActionName("Close File (ProgramManagerPlugin)");
assertTrue(!actionList.isEmpty());
performAction(actionList.get(0), new ProgramActionContext(null, program), false); DockingActionIf action = getAction(tool, "ProgramManagerPlugin", "Close File");
performAction(action, new ProgramActionContext(null, program), false);
waitForPostedSwingRunnables(); waitForPostedSwingRunnables();
} }
@@ -201,10 +201,9 @@ public class DateEditorTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void showProgramOptions() { private void showProgramOptions() {
List<DockingActionIf> list = tool.getAllActions(); // TODO change to getAction("Program Options")
for (int i = 0; i < list.size(); i++) { Set<DockingActionIf> list = tool.getAllActions();
for (DockingActionIf action : list) {
DockingActionIf action = list.get(i);
if (action.getName().equals("Program Options")) { if (action.getName().equals("Program Options")) {
performAction(action, plugin.getProvider(), false); performAction(action, plugin.getProvider(), false);
break; break;
@@ -988,10 +988,9 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest {
} }
private void showOptionsDialog(PluginTool pluginTool) throws Exception { private void showOptionsDialog(PluginTool pluginTool) throws Exception {
List<DockingActionIf> list = pluginTool.getAllActions(); // TODO change to getAction("Edit Options")
for (int i = 0; i < list.size(); i++) { Set<DockingActionIf> list = pluginTool.getAllActions();
for (DockingActionIf action : list) {
DockingActionIf action = list.get(i);
if (action.getName().equals("Edit Options")) { if (action.getName().equals("Edit Options")) {
performAction(action, false); performAction(action, false);
break; break;
@@ -19,7 +19,7 @@ import java.awt.Window;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException; import java.beans.PropertyVetoException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.Set;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
@@ -438,18 +438,13 @@ public class DummyTool implements Tool {
} }
@Override @Override
public List<DockingActionIf> getAllActions() { public Set<DockingActionIf> getAllActions() {
return Collections.emptyList(); return Collections.emptySet();
} }
@Override @Override
public List<DockingActionIf> getDockingActionsByOwnerName(String owner) { public Set<DockingActionIf> getDockingActionsByOwnerName(String owner) {
return Collections.emptyList(); return Collections.emptySet();
}
@Override
public List<DockingActionIf> getDockingActionsByFullActionName(String fullActionName) {
return Collections.emptyList();
} }
@Override @Override
@@ -21,7 +21,6 @@ import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.List;
import javax.swing.*; import javax.swing.*;
@@ -97,9 +96,9 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
tc.remove("MyTestTool"); tc.remove("MyTestTool");
tc.remove("TestTool"); tc.remove("TestTool");
waitForPostedSwingRunnables(); waitForSwing();
tool.setConfigChanged(false); tool.setConfigChanged(false);
SwingUtilities.invokeAndWait(() -> saveDialog.close()); runSwing(() -> saveDialog.close());
env.dispose(); env.dispose();
} }
@@ -125,7 +124,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
pressButtonByText(saveDialog, "Save"); pressButtonByText(saveDialog, "Save");
assertTrue(!tool.hasConfigChanged()); assertTrue(!tool.hasConfigChanged());
waitForPostedSwingRunnables(); waitForSwing();
assertTrue(!saveDialog.isVisible()); assertTrue(!saveDialog.isVisible());
ToolChest tc = tool.getProject().getLocalToolChest(); ToolChest tc = tool.getProject().getLocalToolChest();
ToolTemplate config = tc.getToolTemplate("MyTestTool"); ToolTemplate config = tc.getToolTemplate("MyTestTool");
@@ -142,7 +141,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
while (saveDialog.isVisible()) { while (saveDialog.isVisible()) {
Thread.sleep(5); Thread.sleep(5);
} }
waitForPostedSwingRunnables(); waitForSwing();
assertEquals("Name cannot have spaces.", msg); assertEquals("Name cannot have spaces.", msg);
} }
@@ -156,7 +155,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
pressButtonByText(saveDialog, "Save"); pressButtonByText(saveDialog, "Save");
assertTrue(!tool.hasConfigChanged()); assertTrue(!tool.hasConfigChanged());
waitForPostedSwingRunnables(); waitForSwing();
assertTrue(!saveDialog.isVisible()); assertTrue(!saveDialog.isVisible());
ToolChest tc = tool.getProject().getLocalToolChest(); ToolChest tc = tool.getProject().getLocalToolChest();
ToolTemplate template = tc.getToolTemplate("MyTestTool"); ToolTemplate template = tc.getToolTemplate("MyTestTool");
@@ -180,7 +179,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
while (saveDialog.isVisible()) { while (saveDialog.isVisible()) {
Thread.sleep(5); Thread.sleep(5);
} }
waitForPostedSwingRunnables(); waitForSwing();
} }
@Test @Test
@@ -208,8 +207,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
final JButton browseButton = (JButton) findComponentByName(saveDialog, "BrowseButton"); final JButton browseButton = (JButton) findComponentByName(saveDialog, "BrowseButton");
pressButton(browseButton, false); pressButton(browseButton, false);
final GhidraFileChooser chooser = final GhidraFileChooser chooser = waitForDialogComponent(GhidraFileChooser.class);
waitForDialogComponent(GhidraFileChooser.class);
assertNotNull(chooser); assertNotNull(chooser);
runSwing(() -> chooser.setSelectedFile(destFile)); runSwing(() -> chooser.setSelectedFile(destFile));
@@ -240,7 +238,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
while (tc.getToolTemplate("MyTestTool") == null) { while (tc.getToolTemplate("MyTestTool") == null) {
Thread.sleep(10); Thread.sleep(10);
} }
waitForPostedSwingRunnables(); waitForSwing();
setText(toolNameField, "MyTestTool", false); setText(toolNameField, "MyTestTool", false);
@@ -256,10 +254,9 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
JButton saveButton = findButtonByText(saveDialog, "Save"); JButton saveButton = findButtonByText(saveDialog, "Save");
saveButton.getActionListeners()[0].actionPerformed(null); saveButton.getActionListeners()[0].actionPerformed(null);
}); });
waitForPostedSwingRunnables(); waitForSwing();
final OptionDialog d = final OptionDialog d = waitForDialogComponent(OptionDialog.class);
waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
assertNotNull(d); assertNotNull(d);
assertEquals("Overwrite Tool?", d.getTitle()); assertEquals("Overwrite Tool?", d.getTitle());
pressButtonByText(d.getComponent(), "Overwrite"); pressButtonByText(d.getComponent(), "Overwrite");
@@ -267,7 +264,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
while (d.isVisible()) { while (d.isVisible()) {
Thread.sleep(10); Thread.sleep(10);
} }
waitForPostedSwingRunnables(); waitForSwing();
assertTrue(!tool.hasConfigChanged()); assertTrue(!tool.hasConfigChanged());
} }
@@ -282,11 +279,11 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
while (tc.getToolTemplate("MyTestTool") == null) { while (tc.getToolTemplate("MyTestTool") == null) {
Thread.sleep(10); Thread.sleep(10);
} }
waitForPostedSwingRunnables(); waitForSwing();
setText(toolNameField, "MyTestTool", false); setText(toolNameField, "MyTestTool", false);
SwingUtilities.invokeAndWait(() -> { runSwing(() -> {
// force a change to the tool config // force a change to the tool config
try { try {
tool.addPlugin(ByteViewerPlugin.class.getName()); tool.addPlugin(ByteViewerPlugin.class.getName());
@@ -301,10 +298,9 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
JButton saveButton = findButtonByText(saveDialog, "Save"); JButton saveButton = findButtonByText(saveDialog, "Save");
saveButton.getActionListeners()[0].actionPerformed(null); saveButton.getActionListeners()[0].actionPerformed(null);
}); });
waitForPostedSwingRunnables(); waitForSwing();
final OptionDialog d = final OptionDialog d = waitForDialogComponent(OptionDialog.class);
waitForDialogComponent(OptionDialog.class);
assertNotNull(d); assertNotNull(d);
assertEquals("Overwrite Tool?", d.getTitle()); assertEquals("Overwrite Tool?", d.getTitle());
pressButtonByText(d.getComponent(), "Cancel"); pressButtonByText(d.getComponent(), "Cancel");
@@ -312,17 +308,16 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
while (d.isVisible()) { while (d.isVisible()) {
Thread.sleep(10); Thread.sleep(10);
} }
waitForPostedSwingRunnables(); waitForSwing();
assertTrue(tool.hasConfigChanged()); assertTrue(tool.hasConfigChanged());
} }
/////////////////////////////////////////////////////////////////////
private void showDialogs() throws Exception { private void showDialogs() throws Exception {
List<DockingActionIf> actions =
tool.getDockingActionsByFullActionName("Save Tool As (Tool)"); DockingActionIf action = getAction(tool, "Tool", "Save Tool As");
performAction(actions.get(0), false); performAction(action, false);
waitForPostedSwingRunnables(); waitForSwing();
saveDialog = waitForDialogComponent(SaveToolConfigDialog.class); saveDialog = waitForDialogComponent(SaveToolConfigDialog.class);
@@ -335,7 +330,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
private void setText(final JTextField field, final String text, final boolean doAction) private void setText(final JTextField field, final String text, final boolean doAction)
throws Exception { throws Exception {
SwingUtilities.invokeAndWait(() -> { runSwing(() -> {
field.setText(text); field.setText(text);
if (doAction) { if (doAction) {
ActionListener[] listeners = field.getActionListeners(); ActionListener[] listeners = field.getActionListeners();
@@ -344,6 +339,6 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
} }
} }
}); });
waitForPostedSwingRunnables(); waitForSwing();
} }
} }
@@ -27,6 +27,7 @@ import docking.action.DockingAction;
import docking.widgets.fieldpanel.FieldPanel; import docking.widgets.fieldpanel.FieldPanel;
import docking.widgets.fieldpanel.internal.FieldPanelCoordinator; import docking.widgets.fieldpanel.internal.FieldPanelCoordinator;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.label.GDHtmlLabel;
import ghidra.app.decompiler.DecompileOptions; import ghidra.app.decompiler.DecompileOptions;
import ghidra.app.util.viewer.listingpanel.ProgramLocationListener; import ghidra.app.util.viewer.listingpanel.ProgramLocationListener;
import ghidra.app.util.viewer.util.CodeComparisonPanel; import ghidra.app.util.viewer.util.CodeComparisonPanel;
@@ -255,8 +256,13 @@ public abstract class DecompilerCodeComparisonPanel<T extends DualDecompilerFiel
String leftTitle1 = FunctionUtility.getFunctionTitle(functions[LEFT]); String leftTitle1 = FunctionUtility.getFunctionTitle(functions[LEFT]);
String rightTitle1 = FunctionUtility.getFunctionTitle(functions[RIGHT]); String rightTitle1 = FunctionUtility.getFunctionTitle(functions[RIGHT]);
titlePanels[LEFT] = new TitledPanel(leftTitle1, cPanels[LEFT], 5);
titlePanels[RIGHT] = new TitledPanel(rightTitle1, cPanels[RIGHT], 5); // use mutable labels, as the titles update when functions are selected
GDHtmlLabel leftTitleLabel = new GDHtmlLabel(leftTitle1);
GDHtmlLabel rightTitleLabel = new GDHtmlLabel(rightTitle1);
titlePanels[LEFT] = new TitledPanel(leftTitleLabel, cPanels[LEFT], 5);
titlePanels[RIGHT] = new TitledPanel(rightTitleLabel, cPanels[RIGHT], 5);
// Set the MINIMUM_PANEL_WIDTH for the left and right panel to prevent the split pane's // Set the MINIMUM_PANEL_WIDTH for the left and right panel to prevent the split pane's
// divider from becoming locked (can't be moved) due to extra long title names. // divider from becoming locked (can't be moved) due to extra long title names.
@@ -177,10 +177,8 @@ public class FunctionGraphPlugin2Test extends AbstractFunctionGraphTest {
GraphPerspectiveInfo<FGVertex, FGEdge> primaryPerspective = GraphPerspectiveInfo<FGVertex, FGEdge> primaryPerspective =
primaryController.getGraphPerspective(location); primaryController.getGraphPerspective(location);
List<DockingActionIf> actions = tool.getDockingActionsByFullActionName( DockingActionIf snapshotAction =
"Function Graph Clone (" + graphPlugin.getName() + ")"); getAction(tool, graphPlugin.getName(), "Function Graph Clone");
assertEquals(1, actions.size());
DockingActionIf snapshotAction = actions.get(0);
performAction(snapshotAction, true); performAction(snapshotAction, true);
assertEquals(1, disconnectedProviders.size()); assertEquals(1, disconnectedProviders.size());
@@ -21,7 +21,7 @@ import java.awt.*;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.Set;
import javax.swing.*; import javax.swing.*;
@@ -589,7 +589,7 @@ public class DiffTestAdapter extends AbstractGhidraHeadedIntegrationTest {
} }
public static DockingActionIf getToolAction(PluginTool tool, String name) { public static DockingActionIf getToolAction(PluginTool tool, String name) {
List<DockingActionIf> actions = tool.getDockingActionsByOwnerName("Tool"); Set<DockingActionIf> actions = getActionsByOwner(tool, "Tool");
for (DockingActionIf action : actions) { for (DockingActionIf action : actions) {
if (name.equals(action.getName())) { if (name.equals(action.getName())) {
return action; return action;
@@ -17,9 +17,11 @@ package ghidra.feature.vt.gui.plugin;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.swing.*; import javax.swing.*;
import docking.action.DockingActionIf;
import docking.help.Help; import docking.help.Help;
import docking.help.HelpService; import docking.help.HelpService;
import docking.wizard.WizardManager; import docking.wizard.WizardManager;
@@ -121,14 +123,29 @@ public class VTPlugin extends Plugin {
createActions(); createActions();
registerServiceProvided(VTController.class, controller); registerServiceProvided(VTController.class, controller);
tool.setUnconfigurable(); tool.setUnconfigurable();
tool.removeAction(tool.getDockingActionsByFullActionName("Save Tool As (Tool)").get(0));
tool.removeAction(tool.getDockingActionsByFullActionName("Export Tool (Tool)").get(0)); DockingActionIf saveAs = getToolAction("Save Tool As");
tool.removeAction(saveAs);
DockingActionIf export = getToolAction("Export Tool");
tool.removeAction(export);
new MatchStatusUpdaterAssociationHook(controller); new MatchStatusUpdaterAssociationHook(controller);
new ImpliedMatchAssociationHook(controller); new ImpliedMatchAssociationHook(controller);
initializeOptions(); initializeOptions();
} }
private DockingActionIf getToolAction(String actionName) {
Set<DockingActionIf> actions = tool.getDockingActionsByOwnerName("Tool");
for (DockingActionIf action : actions) {
if (action.getName().equals(actionName)) {
return action;
}
}
throw new IllegalArgumentException("Unable to find Tool action '" + actionName + "'");
}
private void initializeOptions() { private void initializeOptions() {
Options options = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY); Options options = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
options.registerOptionsEditor(new ListingDisplayOptionsEditor(this, options)); options.registerOptionsEditor(new ListingDisplayOptionsEditor(this, options));
@@ -17,8 +17,7 @@ package ghidra.feature.vt.gui.plugin;
import java.awt.Component; import java.awt.Component;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
@@ -27,6 +26,7 @@ import org.jdom.output.XMLOutputter;
import docking.ActionContext; import docking.ActionContext;
import docking.action.*; import docking.action.*;
import docking.tool.util.DockingToolConstants;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.fieldpanel.FieldPanel; import docking.widgets.fieldpanel.FieldPanel;
import docking.widgets.fieldpanel.support.FieldSelection; import docking.widgets.fieldpanel.support.FieldSelection;
@@ -153,17 +153,17 @@ public class VTSubToolManager implements VTControllerListener, OptionsChangeList
catch (PluginException e) { catch (PluginException e) {
Msg.error(this, "Failed to create subordinate tool: " + toolName); Msg.error(this, "Failed to create subordinate tool: " + toolName);
} }
newTool.setToolName(toolName); newTool.setToolName(toolName);
newTool.removeAction(newTool.getDockingActionsByFullActionName("Save Tool (Tool)").get(0));
newTool.removeAction( DockingActionIf save = getToolAction(newTool, "Save Tool");
newTool.getDockingActionsByFullActionName("Save Tool As (Tool)").get(0)); newTool.removeAction(save);
// newTool.removeAction(newTool.getDockableActionsByFullActionName("Export
// Tool (Tool)").get(0));
createMarkupActions(newTool); createMarkupActions(newTool);
newTool.setConfigChanged(false); newTool.setConfigChanged(false);
ToolOptions options = newTool.getOptions(ToolConstants.KEY_BINDINGS); ToolOptions options = newTool.getOptions(DockingToolConstants.KEY_BINDINGS);
options.addOptionsChangeListener(this); options.addOptionsChangeListener(this);
// custom VT actions // custom VT actions
@@ -172,6 +172,16 @@ public class VTSubToolManager implements VTControllerListener, OptionsChangeList
return newTool; return newTool;
} }
private DockingActionIf getToolAction(Tool tool, String actionName) {
Set<DockingActionIf> actions = tool.getDockingActionsByOwnerName("Tool");
for (DockingActionIf action : actions) {
if (action.getName().equals(actionName)) {
return action;
}
}
throw new IllegalArgumentException("Unable to find Tool action '" + actionName + "'");
}
@Override @Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue, public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) { Object newValue) {
@@ -17,7 +17,6 @@ package docking;
import java.awt.*; import java.awt.*;
import java.util.*; import java.util.*;
import java.util.List;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -116,22 +115,16 @@ public abstract class AbstractDockingTool implements DockingTool {
} }
@Override @Override
public List<DockingActionIf> getAllActions() { public Set<DockingActionIf> getAllActions() {
return actionMgr.getAllActions(); Set<DockingActionIf> actions = actionMgr.getAllActions();
} DockingActionManager am = winMgr.getActionManager();
actions.addAll(am.getAllActions());
@Override
public List<DockingActionIf> getDockingActionsByOwnerName(String owner) {
List<DockingActionIf> actions = actionMgr.getActions(owner);
return actions; return actions;
} }
@Override @Override
public List<DockingActionIf> getDockingActionsByFullActionName(String fullActionName) { public Set<DockingActionIf> getDockingActionsByOwnerName(String owner) {
Set<DockingActionIf> set = new HashSet<>(); return actionMgr.getActions(owner);
set.addAll(actionMgr.getDockingActionsByFullActionName(fullActionName));
set.addAll(winMgr.getActions(fullActionName));
return new ArrayList<>(set);
} }
@Override @Override
@@ -28,6 +28,8 @@ import org.jdesktop.animation.timing.TimingTargetAdapter;
import docking.action.ActionContextProvider; import docking.action.ActionContextProvider;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.actions.ActionAdapter;
import docking.actions.KeyBindingUtils;
import docking.event.mouse.GMouseListenerAdapter; import docking.event.mouse.GMouseListenerAdapter;
import docking.menu.DockingToolbarButton; import docking.menu.DockingToolbarButton;
import docking.util.*; import docking.util.*;
@@ -44,11 +44,6 @@ public class DockingActionManager {
private PopupActionManager popupActionManager; private PopupActionManager popupActionManager;
private DockingAction keyBindingsAction; private DockingAction keyBindingsAction;
/**
* Constructs a new ActionManager
* @param frame the frame to contain the menu and toolbar.
* @param enableDiagnosticActions if true additional diagnostic actions will enabled
*/
DockingActionManager(DockingWindowManager winMgr) { DockingActionManager(DockingWindowManager winMgr) {
menuGroupMap = new MenuGroupMap(); menuGroupMap = new MenuGroupMap();
@@ -90,9 +85,10 @@ public class DockingActionManager {
/** /**
* Register a specific Help content location for a component. * Register a specific Help content location for a component.
* The DocWinListener will be notified with the help location if the specified * The DocWinListener will be notified with the help location if the specified
* component 'c' has focus and the help key is pressed. * component 'c' has focus and the help key is pressed.
*
* @param c component * @param c component
* @param helpURL help content URL * @param helpLocation the help location
*/ */
static void setHelpLocation(JComponent c, HelpLocation helpLocation) { static void setHelpLocation(JComponent c, HelpLocation helpLocation) {
DockingWindowManager.getHelpService().registerHelp(c, helpLocation); DockingWindowManager.getHelpService().registerHelp(c, helpLocation);
@@ -149,41 +145,18 @@ public class DockingActionManager {
globalActions.remove(action); globalActions.remove(action);
} }
public List<DockingActionIf> getAllDockingActionsByFullActionName(String fullActionName) { public Set<DockingActionIf> getAllActions() {
// Note: this method is called by non-Swing test code. Synchronize access to the // Note: this method is called by non-Swing test code. Synchronize access to the
// data structures in this class in order to prevent concurrent mod exceptions. // data structures in this class in order to prevent concurrent mod exceptions.
List<DockingActionIf> actions = new ArrayList<>(); Set<DockingActionIf> actions = new HashSet<>();
SystemUtilities.runSwingNow(() -> { SystemUtilities.runSwingNow(() -> {
actions.addAll(getGlobalDockingActionsByFullActionName(fullActionName)); actions.addAll(globalActions);
actions.addAll(getLocalDockingActionsByFullActionName(fullActionName)); actions.addAll(keyBindingsManager.getLocalActions());
}); });
return actions; return actions;
} }
private List<DockingActionIf> getGlobalDockingActionsByFullActionName(String fullActionName) {
List<DockingActionIf> matchingActions = new ArrayList<>();
ArrayList<DockingActionIf> existingAction = new ArrayList<>(globalActions);
for (DockingActionIf action : existingAction) {
if (fullActionName.equals(action.getFullName())) {
matchingActions.add(action);
}
}
return matchingActions;
}
private List<DockingActionIf> getLocalDockingActionsByFullActionName(String fullActionName) {
List<DockingActionIf> matchingActions = new ArrayList<>();
ArrayList<DockingActionIf> existingAction =
new ArrayList<>(keyBindingsManager.getLocalActions());
for (DockingActionIf action : existingAction) {
if (fullActionName.equals(action.getFullName())) {
matchingActions.add(action);
}
}
return matchingActions;
}
public Action getDockingKeyAction(KeyStroke keyStroke) { public Action getDockingKeyAction(KeyStroke keyStroke) {
return keyBindingsManager.getDockingKeyAction(keyStroke); return keyBindingsManager.getDockingKeyAction(keyStroke);
} }
@@ -16,13 +16,17 @@
package docking; package docking;
import java.awt.Window; import java.awt.Window;
import java.util.List; import java.util.Set;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
/**
* Generic tool interface for managing {@link ComponentProvider}s and
* {@link DockingActionIf actions}
*/
public interface DockingTool { public interface DockingTool {
/** /**
@@ -125,25 +129,27 @@ public interface DockingTool {
public void removeLocalAction(ComponentProvider componentProvider, DockingActionIf action); public void removeLocalAction(ComponentProvider componentProvider, DockingActionIf action);
/** /**
* Return a list of all actions in the tool. * Return a set of all actions in the tool.
* @return list of all actions *
* <p>Note: the result may contain conceptually duplicate actions, which is when multiple
* actions exist that share the same full name (the full name is the action name with the
* owner name, such as "My Action (MyPlugin)".
*
* @return set of all actions
*/ */
public List<DockingActionIf> getAllActions(); public Set<DockingActionIf> getAllActions();
/** /**
* Returns all actions for the given owner * Returns all actions for the given owner
*
* <p>Note: the result may contain conceptually duplicate actions, which is when multiple
* actions exist that share the same full name (the full name is the action name with the
* owner name, such as "My Action (MyPlugin)".
*
* @param owner the action owner's name * @param owner the action owner's name
* @return the actions * @return the actions
*/ */
public List<DockingActionIf> getDockingActionsByOwnerName(String owner); public Set<DockingActionIf> getDockingActionsByOwnerName(String owner);
/**
* Return an list of actions with the given full name
* @param fullActionName action name that includes the owner's name in
* parentheses, e.g. "MyAction (MyPlugin)"
* @return the actions
*/
public List<DockingActionIf> getDockingActionsByFullActionName(String fullActionName);
/** /**
* Shows or hides the component provider in the tool * Shows or hides the component provider in the tool
@@ -666,22 +666,6 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
scheduleUpdate(); scheduleUpdate();
} }
/**
* Adds an action that will be associated with the given provider. These actions will
* appear in the local header for the component as a toolbar button or a drop-down menu
* item if it has an icon and menu path respectively.
* @param provider the provider whose header on which the action is to be placed.
* @param action the action to add to the providers header bar.
*/
public void addLocalAction(ComponentProvider provider, DockingActionIf action) {
ComponentPlaceholder placeholder = getActivePlaceholder(provider);
if (placeholder == null) {
throw new IllegalArgumentException("Unknown component provider: " + provider);
}
placeholder.addAction(action);
actionManager.addLocalAction(action, provider);
}
/** /**
* Removes the action from the given provider's header bar. * Removes the action from the given provider's header bar.
* @param provider the provider whose header bar from which the action should be removed. * @param provider the provider whose header bar from which the action should be removed.
@@ -695,13 +679,33 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
} }
} }
//==================================================================================================
// Package-level Action Methods
//==================================================================================================
/**
* Adds an action that will be associated with the given provider. These actions will
* appear in the local header for the component as a toolbar button or a drop-down menu
* item if it has an icon and menu path respectively.
* @param provider the provider whose header on which the action is to be placed.
* @param action the action to add to the providers header bar.
*/
void addLocalAction(ComponentProvider provider, DockingActionIf action) {
ComponentPlaceholder placeholder = getActivePlaceholder(provider);
if (placeholder == null) {
throw new IllegalArgumentException("Unknown component provider: " + provider);
}
placeholder.addAction(action);
actionManager.addLocalAction(action, provider);
}
/** /**
* Adds an action to the global menu or toolbar which appear in the main frame. If * Adds an action to the global menu or toolbar which appear in the main frame. If
* the action has a menu path, it will be in the menu. If it has an icon, it will * the action has a menu path, it will be in the menu. If it has an icon, it will
* appear in the toolbar. * appear in the toolbar.
* @param action the action to be added. * @param action the action to be added.
*/ */
public void addToolAction(DockingActionIf action) { void addToolAction(DockingActionIf action) {
actionManager.addToolAction(action); actionManager.addToolAction(action);
scheduleUpdate(); scheduleUpdate();
} }
@@ -710,15 +714,23 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
* Removes the given action from the global menu and toolbar. * Removes the given action from the global menu and toolbar.
* @param action the action to be removed. * @param action the action to be removed.
*/ */
public void removeToolAction(DockingActionIf action) { void removeToolAction(DockingActionIf action) {
actionManager.removeToolAction(action); actionManager.removeToolAction(action);
scheduleUpdate(); scheduleUpdate();
} }
public Collection<DockingActionIf> getActions(String fullActionName) { /**
return actionManager.getAllDockingActionsByFullActionName(fullActionName); * Returns all actions registered with this manager
* @return the actions
*/
public Set<DockingActionIf> getAllActions() {
return actionManager.getAllActions();
} }
//==================================================================================================
// End Package-level Methods
//==================================================================================================
/** /**
* Hides or shows the component associated with the given provider. * Hides or shows the component associated with the given provider.
* <p><br> * <p><br>

Some files were not shown because too many files have changed in this diff Show More