mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GT-2960 - Docking Actions - review fixes
This commit is contained in:
parent
154fa39cc2
commit
d8c234d5d0
27 changed files with 200 additions and 169 deletions
|
@ -23,8 +23,7 @@ import java.util.List;
|
|||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.WindowPosition;
|
||||
import docking.*;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.actions.PopupActionProvider;
|
||||
|
||||
|
@ -55,7 +54,7 @@ public class ListingMergePanelProvider extends ComponentProviderAdapter implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
ListingPanel resultPanel = mergePanel.getResultPanel();
|
||||
if (resultPanel != null) {
|
||||
return resultPanel.getHeaderActions(getName());
|
||||
|
|
|
@ -22,6 +22,7 @@ import javax.swing.Icon;
|
|||
import javax.swing.SwingUtilities;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DockingTool;
|
||||
import docking.action.*;
|
||||
import docking.actions.PopupActionProvider;
|
||||
import docking.widgets.table.GTable;
|
||||
|
@ -493,7 +494,7 @@ public class BookmarkPlugin extends ProgramPlugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
Object contextObject = context.getContextObject();
|
||||
if (!(contextObject instanceof MarkerLocation)) {
|
||||
return null;
|
||||
|
|
|
@ -952,7 +952,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
if (context.getComponentProvider() == this) {
|
||||
return listingPanel.getHeaderActions(getName());
|
||||
}
|
||||
|
|
|
@ -557,6 +557,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
|||
setVisible(false);
|
||||
}
|
||||
model.removeCompositeEditorModelListener(this);
|
||||
table.dispose();
|
||||
}
|
||||
|
||||
private void createTable() {
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.swing.SwingUtilities;
|
|||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DockingTool;
|
||||
import docking.action.*;
|
||||
import docking.actions.PopupActionProvider;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
|
@ -48,7 +49,8 @@ import ghidra.framework.Application;
|
|||
import ghidra.framework.main.OpenVersionedFileDialog;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.PluginInfo;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.program.database.DataTypeArchiveContentHandler;
|
||||
import ghidra.program.database.data.ProgramDataTypeManager;
|
||||
|
@ -700,7 +702,7 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool dockingTool, ActionContext context) {
|
||||
if (!(context instanceof DataTypesActionContext)) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.*;
|
|||
import javax.swing.Icon;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DockingTool;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.actions.PopupActionProvider;
|
||||
|
@ -221,7 +222,7 @@ public class FunctionComparisonProvider extends ComponentProviderAdapter impleme
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
if (context.getComponentProvider() == this) {
|
||||
ListingCodeComparisonPanel dualListingPanel =
|
||||
functionComparisonPanel.getDualListingPanel();
|
||||
|
|
|
@ -17,13 +17,11 @@ package ghidra.app.plugin.core.instructionsearch.ui;
|
|||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DockingWindowManager;
|
||||
import docking.*;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import ghidra.app.plugin.core.instructionsearch.InstructionSearchPlugin;
|
||||
|
@ -102,8 +100,8 @@ public class InstructionTable extends AbstractInstructionTable {
|
|||
* (which is all of them).
|
||||
*/
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
return new ArrayList<>();
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public InsertBytesWidget getInsertBytesWidget() {
|
||||
|
|
|
@ -136,10 +136,10 @@ public class PreviewTable extends AbstractInstructionTable {
|
|||
* any existing menus; it simply adds to them.
|
||||
*/
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
|
||||
// Invoke the base class method to add default menu options.
|
||||
List<DockingActionIf> list = super.getPopupActions(context);
|
||||
List<DockingActionIf> list = super.getPopupActions(tool, context);
|
||||
|
||||
// And now add our own.
|
||||
addCustomMenuItems(list);
|
||||
|
|
|
@ -202,6 +202,20 @@ public class TableServicePlugin extends ProgramPlugin
|
|||
}
|
||||
}
|
||||
|
||||
void removeDialog(MyTableChooserDialog dialog) {
|
||||
Iterator<Program> iter = programToDialogMap.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Program p = iter.next();
|
||||
List<TableChooserDialog> list = programToDialogMap.get(p);
|
||||
if (list.remove(dialog)) {
|
||||
if (list.size() == 0) {
|
||||
programToDialogMap.remove(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||
updateMgr.update();
|
||||
|
@ -263,17 +277,4 @@ public class TableServicePlugin extends ProgramPlugin
|
|||
return dialog;
|
||||
}
|
||||
|
||||
public void removeDialog(MyTableChooserDialog dialog) {
|
||||
Iterator<Program> iter = programToDialogMap.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Program p = iter.next();
|
||||
List<TableChooserDialog> list = programToDialogMap.get(p);
|
||||
if (list.remove(dialog)) {
|
||||
if (list.size() == 0) {
|
||||
programToDialogMap.remove(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,7 @@ public class TableChooserDialog extends DialogComponentProvider
|
|||
if (navigatable != null) {
|
||||
navigatable.removeNavigatableListener(this);
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -319,6 +320,11 @@ public class TableChooserDialog extends DialogComponentProvider
|
|||
return rowObjects;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
table.dispose();
|
||||
workers.forEach(w -> w.cancel(true));
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
|
|
@ -544,7 +544,7 @@ public class BookmarkPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
applyCmd(program, cmd);
|
||||
|
||||
List<DockingActionIf> actions = runSwing(() -> plugin.getPopupActions(
|
||||
new ActionContext(null, new MarkerLocation(null, addr("0100b6db"), 0, 0))));
|
||||
null, new ActionContext(null, new MarkerLocation(null, addr("0100b6db"), 0, 0))));
|
||||
assertEquals(10, actions.size());
|
||||
}
|
||||
|
||||
|
|
|
@ -359,6 +359,12 @@ public class DummyTool implements Tool {
|
|||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuGroup(String[] menuPath, String group, String menuSubGroup) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextChanged(ComponentProvider provider) {
|
||||
//do nothing
|
||||
|
|
|
@ -28,8 +28,7 @@ import javax.swing.event.TableModelEvent;
|
|||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.table.JTableHeader;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.WindowPosition;
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.actions.PopupActionProvider;
|
||||
import docking.menu.ActionState;
|
||||
|
@ -216,7 +215,7 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
if (context.getComponentProvider() == this) {
|
||||
ListingCodeComparisonPanel dualListingPanel =
|
||||
functionComparisonPanel.getDualListingPanel();
|
||||
|
|
|
@ -452,7 +452,7 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
if (context.getComponentProvider() == this && dualListingPanel != null) {
|
||||
ListingPanel sourcePanel = dualListingPanel.getLeftPanel();
|
||||
|
|
|
@ -185,6 +185,25 @@ public abstract class AbstractDockingTool implements DockingTool {
|
|||
winMgr.updateTitle(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu group associated with a cascaded submenu. This allows
|
||||
* a cascading menu item to be grouped with a specific set of actions.
|
||||
* The default group for a cascaded submenu is the name of the submenu.
|
||||
*
|
||||
* @param menuPath menu name path where the last element corresponds
|
||||
* to the specified group name.
|
||||
* @param group group name
|
||||
* @see #setMenuGroup(String[], String, String)
|
||||
*/
|
||||
public void setMenuGroup(String[] menuPath, String group) {
|
||||
setMenuGroup(menuPath, group, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuGroup(String[] menuPath, String group, String menuSubGroup) {
|
||||
winMgr.setMenuGroup(menuPath, group, menuSubGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextChanged(ComponentProvider provider) {
|
||||
winMgr.contextChanged(provider);
|
||||
|
|
|
@ -110,10 +110,6 @@ public class ActionToGuiMapper {
|
|||
globalActions.clear();
|
||||
}
|
||||
|
||||
void setMenuGroup(String[] menuPath, String group) {
|
||||
menuGroupMap.setMenuGroup(menuPath, group);
|
||||
}
|
||||
|
||||
void setMenuGroup(String[] menuPath, String group, String menuSubGroup) {
|
||||
menuGroupMap.setMenuGroup(menuPath, group, menuSubGroup);
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ public interface ComponentLoadedListener {
|
|||
/**
|
||||
* Called when the component is made displayable
|
||||
*
|
||||
* @param windowManager the window manager associated with the loaded component; this can
|
||||
* be null when dialogs are used without a tool or window manager
|
||||
* @param windowManager the window manager associated with the loaded component
|
||||
*/
|
||||
public void componentLoaded(DockingWindowManager windowManager);
|
||||
}
|
||||
|
|
|
@ -104,6 +104,20 @@ public interface DockingTool {
|
|||
*/
|
||||
public void clearStatusInfo();
|
||||
|
||||
/**
|
||||
* Set the menu group associated with a cascaded submenu. This allows
|
||||
* a cascading menu item to be grouped with a specific set of actions.
|
||||
* <p>
|
||||
* The default group for a cascaded submenu is the name of the submenu.
|
||||
* <p>
|
||||
*
|
||||
* @param menuPath menu name path where the last element corresponds to the specified group name.
|
||||
* @param group group name
|
||||
* @param menuSubGroup the name used to sort the cascaded menu within other menu items at
|
||||
* its level
|
||||
*/
|
||||
public void setMenuGroup(String[] menuPath, String group, String menuSubGroup);
|
||||
|
||||
/**
|
||||
* Adds the action to the tool.
|
||||
* @param action the action to be added.
|
||||
|
|
|
@ -41,6 +41,7 @@ import ghidra.util.datastruct.*;
|
|||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.task.SwingUpdateManager;
|
||||
import util.CollectionUtils;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
/**
|
||||
* Manages the "Docking" arrangement of a set of components and actions. The components can be "docked"
|
||||
|
@ -70,7 +71,8 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
*/
|
||||
private static HelpService helpService = new DefaultHelpService();
|
||||
|
||||
private static List<DockingWindowManager> instanceList = new ArrayList<>();
|
||||
// we use a list to maintain order
|
||||
private static List<DockingWindowManager> instances = new ArrayList<>();
|
||||
|
||||
private DockingTool tool;
|
||||
private RootNode root;
|
||||
|
@ -172,11 +174,11 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
}
|
||||
|
||||
private static synchronized void addInstance(DockingWindowManager winMgr) {
|
||||
instanceList.add(winMgr);
|
||||
instances.add(winMgr);
|
||||
}
|
||||
|
||||
private static synchronized void removeInstance(DockingWindowManager winMgr) {
|
||||
instanceList.remove(winMgr);
|
||||
instances.remove(winMgr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +192,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
return null;
|
||||
}
|
||||
|
||||
Iterator<DockingWindowManager> iter = instanceList.iterator();
|
||||
Iterator<DockingWindowManager> iter = instances.iterator();
|
||||
while (iter.hasNext()) {
|
||||
DockingWindowManager winMgr = iter.next();
|
||||
if (winMgr.root.getFrame() == win) {
|
||||
|
@ -242,8 +244,8 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
// most active. Any time we change the active manager, it will be placed
|
||||
// in the back of the list.
|
||||
//
|
||||
for (int i = instanceList.size() - 1; i >= 0; i--) {
|
||||
DockingWindowManager mgr = instanceList.get(i);
|
||||
for (int i = instances.size() - 1; i >= 0; i--) {
|
||||
DockingWindowManager mgr = instances.get(i);
|
||||
if (mgr.root.isVisible()) {
|
||||
return mgr;
|
||||
}
|
||||
|
@ -256,7 +258,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
* @return a new list of all DockingWindowManager instances know to exist.
|
||||
*/
|
||||
public static synchronized List<DockingWindowManager> getAllDockingWindowManagers() {
|
||||
return new ArrayList<>(instanceList);
|
||||
return new ArrayList<>(instances);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,8 +266,8 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
* @param mgr the window manager that became active.
|
||||
*/
|
||||
static synchronized void setActiveManager(DockingWindowManager mgr) {
|
||||
if (instanceList.remove(mgr)) {
|
||||
instanceList.add(mgr);
|
||||
if (instances.remove(mgr)) {
|
||||
instances.add(mgr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1937,26 +1939,13 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu group associated with a cascaded submenu. This allows
|
||||
* a cascading menu item to be grouped with a specific set of actions.
|
||||
* The default group for a cascaded submenu is the name of the submenu.
|
||||
* @param menuPath menu name path where the last element corresponds
|
||||
* to the specified group name.
|
||||
* @param group group name
|
||||
*/
|
||||
public void setMenuGroup(String[] menuPath, String group) {
|
||||
doSetMenuGroup(menuPath, group);
|
||||
scheduleUpdate();
|
||||
}
|
||||
|
||||
/*
|
||||
* A version of setMenuGroup() that does *not* trigger an update. When clients call the
|
||||
* public API, an update is needed. This method is used during the rebuilding process
|
||||
* when we know that an update is not need, as we are in the middle of an update.
|
||||
*/
|
||||
void doSetMenuGroup(String[] menuPath, String group) {
|
||||
actionToGuiMapper.setMenuGroup(menuPath, group);
|
||||
actionToGuiMapper.setMenuGroup(menuPath, group, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2122,7 +2111,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
|
||||
List<DockingActionIf> actionList = new ArrayList<>();
|
||||
for (PopupActionProvider pl : popupActionProviders) {
|
||||
List<DockingActionIf> actions = pl.getPopupActions(context);
|
||||
List<DockingActionIf> actions = pl.getPopupActions(tool, context);
|
||||
if (actions != null) {
|
||||
actionList.addAll(actions);
|
||||
}
|
||||
|
@ -2149,9 +2138,10 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
|
||||
/**
|
||||
* Registers a callback to be notified when the given component has been parented to
|
||||
* a docking window manager.
|
||||
* @param component the component that will be parented in a docking window system.
|
||||
* @param listener the listener to be notified the component was parented.
|
||||
* a docking window manager
|
||||
*
|
||||
* @param component the component that will be parented in a docking window system
|
||||
* @param listener the listener to be notified the component was parented
|
||||
*/
|
||||
public static void registerComponentLoadedListener(Component component,
|
||||
ComponentLoadedListener listener) {
|
||||
|
@ -2160,16 +2150,32 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||
@Override
|
||||
public void hierarchyChanged(HierarchyEvent e) {
|
||||
long changeFlags = e.getChangeFlags();
|
||||
if (HierarchyEvent.DISPLAYABILITY_CHANGED == (changeFlags &
|
||||
|
||||
if (HierarchyEvent.DISPLAYABILITY_CHANGED != (changeFlags &
|
||||
HierarchyEvent.DISPLAYABILITY_CHANGED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for the first time we are put together
|
||||
boolean isDisplayable = component.isDisplayable();
|
||||
if (isDisplayable) {
|
||||
component.removeHierarchyListener(this);
|
||||
DockingWindowManager windowManager = getInstance(component);
|
||||
listener.componentLoaded(windowManager);
|
||||
if (!isDisplayable) {
|
||||
return;
|
||||
}
|
||||
|
||||
component.removeHierarchyListener(this);
|
||||
DockingWindowManager dwm = getInstance(component);
|
||||
if (dwm != null) {
|
||||
listener.componentLoaded(dwm);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unable to find the manager. This can happen during testing; only report if
|
||||
// it is unexpected
|
||||
if (!instances.isEmpty()) {
|
||||
Msg.debug(DockingWindowManager.class,
|
||||
"Unable to find Docking Window Manager for " +
|
||||
component.getClass().getSimpleName(),
|
||||
ReflectionUtilities.createJavaFilteredThrowable());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,10 +24,11 @@ import java.util.*;
|
|||
import javax.swing.JPopupMenu;
|
||||
|
||||
import docking.action.*;
|
||||
import docking.actions.PopupActionProvider;
|
||||
import docking.menu.*;
|
||||
|
||||
public class PopupActionManager implements PropertyChangeListener {
|
||||
private List<DockingActionIf> popupActions = new ArrayList<DockingActionIf>();
|
||||
private List<DockingActionIf> popupActions = new ArrayList<>();
|
||||
private DockingWindowManager windowManager;
|
||||
private MenuGroupMap menuGroupMap;
|
||||
|
||||
|
@ -94,23 +95,11 @@ public class PopupActionManager implements PropertyChangeListener {
|
|||
popupMenu.show(c, e.getX(), e.getY());
|
||||
}
|
||||
|
||||
private void populatePopupMenuActions(ComponentPlaceholder info,
|
||||
ActionContext actionContext, MenuManager menuMgr) {
|
||||
private void populatePopupMenuActions(ComponentPlaceholder info, ActionContext actionContext,
|
||||
MenuManager menuMgr) {
|
||||
|
||||
// Include unregistered actions
|
||||
Object source = actionContext.getSourceObject();
|
||||
if (source instanceof DockingActionProviderIf) {
|
||||
DockingActionProviderIf actionProvider = (DockingActionProviderIf) source;
|
||||
List<DockingActionIf> dockingActions = actionProvider.getDockingActions();
|
||||
for (DockingActionIf action : dockingActions) {
|
||||
MenuData popupMenuData = action.getPopupMenuData();
|
||||
if (popupMenuData != null && action.isValidContext(actionContext) &&
|
||||
action.isAddToPopup(actionContext)) {
|
||||
action.setEnabled(action.isEnabledForContext(actionContext));
|
||||
menuMgr.addAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Unregistered actions are those used by special-needs components, on-the-fly
|
||||
addUnregisteredActions(actionContext, menuMgr);
|
||||
|
||||
// Include temporary actions
|
||||
List<DockingActionIf> tempActions = windowManager.getTemporaryPopupActions(actionContext);
|
||||
|
@ -152,6 +141,42 @@ public class PopupActionManager implements PropertyChangeListener {
|
|||
}
|
||||
}
|
||||
|
||||
private void addUnregisteredActions(ActionContext actionContext, MenuManager menuMgr) {
|
||||
|
||||
Object source = actionContext.getSourceObject();
|
||||
|
||||
// this interface is deprecated in favor of the next block
|
||||
if (source instanceof DockingActionProviderIf) {
|
||||
DockingActionProviderIf actionProvider = (DockingActionProviderIf) source;
|
||||
List<DockingActionIf> dockingActions = actionProvider.getDockingActions();
|
||||
for (DockingActionIf action : dockingActions) {
|
||||
MenuData popupMenuData = action.getPopupMenuData();
|
||||
if (popupMenuData != null && action.isValidContext(actionContext) &&
|
||||
action.isAddToPopup(actionContext)) {
|
||||
action.setEnabled(action.isEnabledForContext(actionContext));
|
||||
menuMgr.addAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// note: this is temporary; there is only one client that needs this. This will be
|
||||
// removed in a future ticket when that client uses the standard tool action system
|
||||
if (source instanceof PopupActionProvider) {
|
||||
PopupActionProvider actionProvider = (PopupActionProvider) source;
|
||||
DockingTool tool = windowManager.getTool();
|
||||
List<DockingActionIf> dockingActions =
|
||||
actionProvider.getPopupActions(tool, actionContext);
|
||||
for (DockingActionIf action : dockingActions) {
|
||||
MenuData popupMenuData = action.getPopupMenuData();
|
||||
if (popupMenuData != null && action.isValidContext(actionContext) &&
|
||||
action.isAddToPopup(actionContext)) {
|
||||
action.setEnabled(action.isEnabledForContext(actionContext));
|
||||
menuMgr.addAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRemovingFromPopup(MenuData oldData, MenuData newData) {
|
||||
return oldData != null && newData == null;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,9 @@ import docking.action.DockingActionIf;
|
|||
* Most clients will register actions directly with the tool. However, clients that have numerous
|
||||
* actions that vary greatly with the context can use this method to only create those actions
|
||||
* on demand as the popup is about to be shown, and only if their context is active. This
|
||||
* mechanism can reduce the tool's action management overhead.
|
||||
* mechanism can reduce the tool's action management overhead. Once you have created an
|
||||
* implementation of this class, you must register it with
|
||||
* {@link DockingTool#addPopupActionProvider(PopupActionProvider)}.
|
||||
*/
|
||||
public interface PopupActionProvider {
|
||||
|
||||
|
@ -40,8 +42,9 @@ public interface PopupActionProvider {
|
|||
* included in the menu if they have a valid popup menu path and respond true to the
|
||||
* {@link DockingActionIf#isValidContext(ActionContext)} call.
|
||||
*
|
||||
* @param tool the tool requesting the actions
|
||||
* @param context the ActionContext
|
||||
* @return list of temporary popup actions; return null if there are no popup actions
|
||||
*/
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context);
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -25,19 +24,8 @@ import docking.action.MenuData;
|
|||
* Maps menuPaths to groups
|
||||
*/
|
||||
public class MenuGroupMap {
|
||||
private Map<String, String> preferredMenuGroups = new HashMap<String, String>();
|
||||
private Map<String, String> preferredMenuSubGroups = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* Sets the group for the given menuPath
|
||||
* @param menuPath the menuPath for which to assign a group
|
||||
* @param group the name of the group for the action with the given menu path
|
||||
*
|
||||
* @see #setMenuGroup(String[], String, String)
|
||||
*/
|
||||
public void setMenuGroup(String[] menuPath, String group) {
|
||||
setMenuGroup(menuPath, group, MenuData.NO_SUBGROUP);
|
||||
}
|
||||
private Map<String, String> preferredMenuGroups = new HashMap<>();
|
||||
private Map<String, String> preferredMenuSubGroups = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Sets the group for the given menuPath
|
||||
|
@ -66,6 +54,7 @@ public class MenuGroupMap {
|
|||
/**
|
||||
* Returns the group for the given menu path
|
||||
* @param menuPath the menu path for which to find its group
|
||||
* @return the menu group
|
||||
*/
|
||||
public String getMenuGroup(String[] menuPath) {
|
||||
return preferredMenuGroups.get(getMenuPathKey(menuPath));
|
||||
|
@ -76,6 +65,7 @@ public class MenuGroupMap {
|
|||
* sorting of menu items that exist in the same group.
|
||||
*
|
||||
* @param menuPath the menu path for which to find its group
|
||||
* @return the menu sub-group
|
||||
*/
|
||||
public String getMenuSubGroup(String[] menuPath) {
|
||||
return preferredMenuSubGroups.get(getMenuPathKey(menuPath));
|
||||
|
|
|
@ -511,13 +511,12 @@ public class GTable extends JTable implements KeyStrokeConsumer, PopupActionProv
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
|
||||
// we want these top-level groups to all appear together, with no separator
|
||||
DockingWindowManager dwm = DockingWindowManager.getInstance(this);
|
||||
dwm.setMenuGroup(new String[] { "Copy" }, actionMenuGroup, "1");
|
||||
dwm.setMenuGroup(new String[] { "Export" }, actionMenuGroup, "2");
|
||||
dwm.setMenuGroup(new String[] { "Select All" }, actionMenuGroup, "3");
|
||||
tool.setMenuGroup(new String[] { "Copy" }, actionMenuGroup, "1");
|
||||
tool.setMenuGroup(new String[] { "Export" }, actionMenuGroup, "2");
|
||||
tool.setMenuGroup(new String[] { "Select All" }, actionMenuGroup, "3");
|
||||
|
||||
List<DockingActionIf> list = new ArrayList<>();
|
||||
list.add(copyAction);
|
||||
|
@ -579,15 +578,6 @@ public class GTable extends JTable implements KeyStrokeConsumer, PopupActionProv
|
|||
|
||||
createPopupActions();
|
||||
initializeRowHeight();
|
||||
|
||||
DockingWindowManager.registerComponentLoadedListener(this, dwm -> {
|
||||
|
||||
if (dwm == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
dwm.getTool().addPopupActionProvider(this);
|
||||
});
|
||||
}
|
||||
|
||||
private void initializeHeader(JTableHeader header) {
|
||||
|
|
|
@ -25,8 +25,7 @@ import java.util.List;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.*;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.help.Help;
|
||||
import docking.help.HelpService;
|
||||
|
@ -490,7 +489,7 @@ public class ProjectDataTablePanel extends JPanel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(ActionContext context) {
|
||||
public List<DockingActionIf> getPopupActions(DockingTool tool, ActionContext context) {
|
||||
|
||||
// TODO we should at least add the 'copy' action
|
||||
|
||||
|
|
|
@ -1009,8 +1009,8 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
|||
action.setEnabled(true);
|
||||
addAction(action);
|
||||
|
||||
DockingAction userAgreementAction =
|
||||
new DockingAction("User Agreement", ToolConstants.TOOL_OWNER) {
|
||||
DockingAction userAgreementAction = new DockingAction("User Agreement",
|
||||
ToolConstants.TOOL_OWNER, KeyBindingType.UNSUPPORTED) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
DockingWindowManager.showDialog(new UserAgreementDialog(false, false));
|
||||
|
@ -1355,36 +1355,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
|||
winMgr.showEditWindow(defaultText, comp, rect, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu group associated with a cascaded submenu. This allows
|
||||
* a cascading menu item to be grouped with a specific set of actions.
|
||||
* The default group for a cascaded submenu is the name of the submenu.
|
||||
*
|
||||
* @param menuPath menu name path where the last element corresponds
|
||||
* to the specified group name.
|
||||
* @param group group name
|
||||
* @see #setMenuGroup(String[], String, String)
|
||||
*/
|
||||
public void setMenuGroup(String[] menuPath, String group) {
|
||||
winMgr.setMenuGroup(menuPath, group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu group associated with a cascaded submenu. This allows
|
||||
* a cascading menu item to be grouped with a specific set of actions.
|
||||
* <p>
|
||||
* The default group for a cascaded submenu is the name of the submenu.
|
||||
* <p>
|
||||
*
|
||||
* @param menuPath menu name path where the last element corresponds to the specified group name.
|
||||
* @param group group name
|
||||
* @param menuSubGroup the name used to sort the cascaded menu within other menu items at
|
||||
* its level
|
||||
*/
|
||||
public void setMenuGroup(String[] menuPath, String group, String menuSubGroup) {
|
||||
winMgr.setMenuGroup(menuPath, group, menuSubGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the current task in the tool.
|
||||
*/
|
||||
|
|
|
@ -59,7 +59,7 @@ public class KeyBindingsPanel extends JPanel {
|
|||
private static final int FONT_SIZE = 11;
|
||||
|
||||
private JTextPane statusLabel;
|
||||
private JTable actionTable;
|
||||
private GTable actionTable;
|
||||
private JPanel infoPanel;
|
||||
private MultiLineLabel collisionLabel;
|
||||
private KeyBindingsTableModel tableModel;
|
||||
|
@ -96,6 +96,7 @@ public class KeyBindingsPanel extends JPanel {
|
|||
public void dispose() {
|
||||
tableFilterPanel.dispose();
|
||||
tableModel.dispose();
|
||||
actionTable.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.jdom.Element;
|
|||
|
||||
import docking.options.editor.OptionsDialog;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.tool.util.DockingToolConstants;
|
||||
import ghidra.framework.options.*;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
@ -242,12 +243,16 @@ public class OptionsManager implements OptionsService, OptionsChangeListener {
|
|||
return null;
|
||||
}
|
||||
|
||||
Options keyBindingOptions = getOptions(DockingToolConstants.KEY_BINDINGS);
|
||||
TreePath path = null;
|
||||
if (optionsDialog != null) {
|
||||
path = optionsDialog.getSelectedPath();
|
||||
optionsDialog.dispose();
|
||||
|
||||
OptionsEditor oldEditor = keyBindingOptions.getOptionsEditor();
|
||||
oldEditor.dispose();
|
||||
}
|
||||
|
||||
Options keyBindingOptions = getOptions(ToolConstants.KEY_BINDINGS);
|
||||
keyBindingOptions.registerOptionsEditor(new KeyBindingOptionsEditor());
|
||||
dialog = new OptionsDialog("Options for " + tool.getName(), "Options", getEditableOptions(),
|
||||
null, true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue