Merge branch 'GT-3485_ghidravore_action_context'

Conflicts:
	Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java
This commit is contained in:
ghidravore 2020-01-24 17:28:47 -05:00
commit 5dc7df71b3
33 changed files with 128 additions and 289 deletions

View file

@ -17,9 +17,11 @@ package ghidra.app.context;
import java.util.Set; import java.util.Set;
import docking.ActionContext; import docking.*;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.action.KeyBindingType; import docking.action.KeyBindingType;
import ghidra.app.nav.Navigatable;
import ghidra.app.services.GoToService;
public abstract class NavigatableContextAction extends DockingAction { public abstract class NavigatableContextAction extends DockingAction {
@ -33,23 +35,61 @@ public abstract class NavigatableContextAction extends DockingAction {
@Override @Override
public boolean isEnabledForContext(ActionContext context) { public boolean isEnabledForContext(ActionContext context) {
if (!(context instanceof NavigatableActionContext)) { NavigatableActionContext appropriateContext = getAppropriateContext(context);
if (appropriateContext == null) {
return false; return false;
} }
return isEnabledForContext((NavigatableActionContext) context); return isEnabledForContext(appropriateContext);
} }
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
actionPerformed((NavigatableActionContext) context); actionPerformed(getAppropriateContext(context));
}
private NavigatableActionContext getAppropriateContext(ActionContext context) {
if (context instanceof NavigatableActionContext &&
isValidNavigationContext((NavigatableActionContext) context)) {
return (NavigatableActionContext) context;
}
return getGlobalNavigationContext(context);
} }
@Override @Override
public boolean isValidContext(ActionContext context) { public final boolean isValidContext(ActionContext context) {
if (!(context instanceof NavigatableActionContext)) { return true;
return false; }
protected boolean isValidNavigationContext(NavigatableActionContext context) {
return true;
}
private NavigatableActionContext getGlobalNavigationContext(ActionContext context) {
DockingTool tool = getTool(context.getComponentProvider());
if (tool == null) {
return null;
} }
return isValidContext((NavigatableActionContext) context); GoToService service = tool.getService(GoToService.class);
if (service == null) {
return null;
}
Navigatable defaultNavigatable = service.getDefaultNavigatable();
if (defaultNavigatable.getProgram() == null) {
return null;
}
return new NavigatableActionContext(null, defaultNavigatable);
}
private DockingTool getTool(ComponentProvider provider) {
if (provider != null) {
return provider.getTool();
}
DockingWindowManager manager = DockingWindowManager.getActiveInstance();
if (manager != null) {
return manager.getTool();
}
return null;
} }
@Override @Override
@ -60,10 +100,6 @@ public abstract class NavigatableContextAction extends DockingAction {
return isAddToPopup((NavigatableActionContext) context); return isAddToPopup((NavigatableActionContext) context);
} }
protected boolean isValidContext(NavigatableActionContext context) {
return true;
}
protected boolean isEnabledForContext(NavigatableActionContext context) { protected boolean isEnabledForContext(NavigatableActionContext context) {
return true; return true;
} }

View file

@ -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.
@ -16,6 +15,8 @@
*/ */
package ghidra.app.nav; package ghidra.app.nav;
import java.util.Set;
import ghidra.app.context.*; import ghidra.app.context.*;
import ghidra.app.plugin.core.navigation.NavigationOptions; import ghidra.app.plugin.core.navigation.NavigationOptions;
import ghidra.app.services.GoToService; import ghidra.app.services.GoToService;
@ -24,8 +25,6 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.CodeUnit; import ghidra.program.model.listing.CodeUnit;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import java.util.Set;
public abstract class NextRangeAction extends NavigatableContextAction { public abstract class NextRangeAction extends NavigatableContextAction {
private PluginTool tool; private PluginTool tool;
@ -39,7 +38,7 @@ public abstract class NextRangeAction extends NavigatableContextAction {
} }
@Override @Override
protected boolean isValidContext(NavigatableActionContext context) { protected boolean isValidNavigationContext(NavigatableActionContext context) {
// //
// We want the nav actions to work in the current view that supports this, which right // We want the nav actions to work in the current view that supports this, which right
// now is the ListingActionContext. If the current context does not support that, then // now is the ListingActionContext. If the current context does not support that, then
@ -51,13 +50,12 @@ public abstract class NextRangeAction extends NavigatableContextAction {
@Override @Override
public boolean isEnabledForContext(NavigatableActionContext context) { public boolean isEnabledForContext(NavigatableActionContext context) {
Address currentAddress = context.getAddress(); Address currentAddress = context.getAddress();
ListingActionContext listingContext = (ListingActionContext) context; ProgramSelection selection = getSelection(context);
ProgramSelection selection = getSelection(listingContext);
if (selection == null || selection.isEmpty() || currentAddress == null) { if (selection == null || selection.isEmpty() || currentAddress == null) {
return false; return false;
} }
CodeUnit cu = listingContext.getProgram().getListing().getCodeUnitAt(currentAddress); CodeUnit cu = context.getProgram().getListing().getCodeUnitAt(currentAddress);
if (cu != null) { if (cu != null) {
currentAddress = cu.getMaxAddress(); currentAddress = cu.getMaxAddress();
} }
@ -71,13 +69,10 @@ public abstract class NextRangeAction extends NavigatableContextAction {
@Override @Override
public void actionPerformed(NavigatableActionContext context) { public void actionPerformed(NavigatableActionContext context) {
// Note: we verified above that the context we are grabbing here is the correct type Address goToAddress = getGoToAddress(context);
ListingActionContext listingContext = (ListingActionContext) context;
Address goToAddress = getGoToAddress(listingContext);
GoToService service = tool.getService(GoToService.class); GoToService service = tool.getService(GoToService.class);
if (service != null) { if (service != null) {
service.goTo(listingContext.getNavigatable(), goToAddress); service.goTo(context.getNavigatable(), goToAddress);
} }
} }

View file

@ -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.
@ -16,6 +15,8 @@
*/ */
package ghidra.app.nav; package ghidra.app.nav;
import java.util.Set;
import ghidra.app.context.*; import ghidra.app.context.*;
import ghidra.app.plugin.core.navigation.NavigationOptions; import ghidra.app.plugin.core.navigation.NavigationOptions;
import ghidra.app.services.GoToService; import ghidra.app.services.GoToService;
@ -23,8 +24,6 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import java.util.Set;
public abstract class PreviousRangeAction extends NavigatableContextAction { public abstract class PreviousRangeAction extends NavigatableContextAction {
private PluginTool tool; private PluginTool tool;
@ -39,7 +38,7 @@ public abstract class PreviousRangeAction extends NavigatableContextAction {
} }
@Override @Override
protected boolean isValidContext(NavigatableActionContext context) { protected boolean isValidNavigationContext(NavigatableActionContext context) {
// //
// We want the nav actions to work in the current view that supports this, which right // We want the nav actions to work in the current view that supports this, which right
// now is the ListingActionContext. If the current context does not support that, then // now is the ListingActionContext. If the current context does not support that, then
@ -58,9 +57,8 @@ public abstract class PreviousRangeAction extends NavigatableContextAction {
} }
private Address getGoToAddress(NavigatableActionContext context) { private Address getGoToAddress(NavigatableActionContext context) {
ListingActionContext listingContext = (ListingActionContext) context; ProgramSelection selection = getSelection(context);
ProgramSelection selection = getSelection(listingContext); Address currentAddress = context.getAddress();
Address currentAddress = listingContext.getAddress();
AddressRangeIterator it = selection.getAddressRanges(currentAddress, false); AddressRangeIterator it = selection.getAddressRanges(currentAddress, false);
if (!it.hasNext()) { if (!it.hasNext()) {
@ -94,8 +92,7 @@ public abstract class PreviousRangeAction extends NavigatableContextAction {
@Override @Override
public boolean isEnabledForContext(NavigatableActionContext context) { public boolean isEnabledForContext(NavigatableActionContext context) {
Address currentAddress = context.getAddress(); Address currentAddress = context.getAddress();
ListingActionContext listingContext = (ListingActionContext) context; ProgramSelection selection = getSelection(context);
ProgramSelection selection = getSelection(listingContext);
if (selection == null || selection.isEmpty() || currentAddress == null) { if (selection == null || selection.isEmpty() || currentAddress == null) {
return false; return false;
} }

View file

@ -26,7 +26,7 @@ import ghidra.app.context.ListingContextAction;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.*; import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSet;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
@ -264,12 +264,6 @@ public class ClearPlugin extends Plugin {
} }
return false; return false;
} }
@Override
public boolean isValidGlobalContext(ActionContext context) {
// it's too dangerous to let the clear action work globally
return false;
}
}; };
int menuOrdinal = 1; int menuOrdinal = 1;

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.comments;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext;
import docking.action.*; import docking.action.*;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.cmd.comments.SetCommentCmd; import ghidra.app.cmd.comments.SetCommentCmd;
@ -187,11 +186,6 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
getPopupMenuData().setMenuPath(new String[] { "Comments", "Delete" }); getPopupMenuData().setMenuPath(new String[] { "Comments", "Delete" });
return false; return false;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
}; };
deleteAction.setPopupMenuData(new MenuData(DELETE_MENUPATH, null, "comments")); deleteAction.setPopupMenuData(new MenuData(DELETE_MENUPATH, null, "comments"));
deleteAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0)); deleteAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));

View file

@ -19,7 +19,6 @@ import java.awt.event.KeyEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import docking.ActionContext;
import docking.action.*; import docking.action.*;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
@ -374,8 +373,8 @@ public class EquatePlugin extends Plugin {
Program program = context.getProgram(); Program program = context.getProgram();
List<Integer> opIndices = getInstructionMatches(program, inst, equate); List<Integer> opIndices = getInstructionMatches(program, inst, equate);
Address addr = inst.getAddress(); Address addr = inst.getAddress();
for (int i = 0; i < opIndices.size(); i++) { for (Integer opIndice : opIndices) {
bgCmd.add(createRenameCmd(oldName, newName, addr, opIndices.get(i))); bgCmd.add(createRenameCmd(oldName, newName, addr, opIndice));
} }
} }
else if (cu instanceof Data) { else if (cu instanceof Data) {
@ -429,9 +428,9 @@ public class EquatePlugin extends Plugin {
Program program = context.getProgram(); Program program = context.getProgram();
List<Integer> opIndexes = getInstructionMatches(program, instr, equate); List<Integer> opIndexes = getInstructionMatches(program, instr, equate);
for (int i = 0; i < opIndexes.size(); i++) { for (Integer opIndexe : opIndexes) {
bckCmd.add( bckCmd.add(
new ClearEquateCmd(equate.getName(), instr.getAddress(), opIndexes.get(i))); new ClearEquateCmd(equate.getName(), instr.getAddress(), opIndexe));
} }
} }
else if (cu instanceof Data) { else if (cu instanceof Data) {
@ -728,12 +727,6 @@ public class EquatePlugin extends Plugin {
protected boolean isEnabledForContext(ListingActionContext context) { protected boolean isEnabledForContext(ListingActionContext context) {
return getEquate(context) != null; return getEquate(context) != null;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
}; };
removeAction.setPopupMenuData(new MenuData(REMOVE_MENUPATH, null, GROUP_NAME)); removeAction.setPopupMenuData(new MenuData(REMOVE_MENUPATH, null, GROUP_NAME));
removeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0)); removeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.action.MenuData; import docking.action.MenuData;
import ghidra.app.cmd.function.DeleteFunctionCmd; import ghidra.app.cmd.function.DeleteFunctionCmd;
@ -71,9 +70,4 @@ class DeleteFunctionAction extends ListingContextAction {
return false; return false;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
} }

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.action.MenuData; import docking.action.MenuData;
import ghidra.app.cmd.function.CallDepthChangeInfo; import ghidra.app.cmd.function.CallDepthChangeInfo;
@ -73,9 +72,4 @@ class RemoveStackDepthChangeAction extends ListingContextAction {
context.getAddress()) != null; context.getAddress()) != null;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
} }

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.action.KeyBindingType; import docking.action.KeyBindingType;
import ghidra.app.cmd.function.SetVariableCommentCmd; import ghidra.app.cmd.function.SetVariableCommentCmd;
@ -89,8 +88,4 @@ class VariableCommentDeleteAction extends ListingContextAction {
return (loc instanceof VariableCommentFieldLocation); return (loc instanceof VariableCommentFieldLocation);
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
} }

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.action.MenuData; import docking.action.MenuData;
import ghidra.app.cmd.function.DeleteVariableCmd; import ghidra.app.cmd.function.DeleteVariableCmd;
@ -105,9 +104,4 @@ class VariableDeleteAction extends ListingContextAction {
} }
return null; return null;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
} }

View file

@ -60,7 +60,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
* Creates a new instance of the <CODE>GoToServicePlugin</CODE> * Creates a new instance of the <CODE>GoToServicePlugin</CODE>
*/ */
public GoToServicePlugin(PluginTool plugintool) { public GoToServicePlugin(PluginTool plugintool) {
super(plugintool, true, false); super(plugintool, true, true);
gotoService = new GoToServiceImpl(this, new DefaultNavigatable()); gotoService = new GoToServiceImpl(this, new DefaultNavigatable());

View file

@ -245,7 +245,7 @@ public class InstructionSearchPlugin extends ProgramPlugin {
} }
@Override @Override
protected boolean isValidContext(NavigatableActionContext context) { protected boolean isValidNavigationContext(NavigatableActionContext context) {
return !(context instanceof RestrictedAddressSetContext); return !(context instanceof RestrictedAddressSetContext);
} }
}; };

View file

@ -19,7 +19,6 @@ import java.awt.event.KeyEvent;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import docking.ActionContext;
import docking.action.*; import docking.action.*;
import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingActionContext;
import ghidra.app.context.ListingContextAction; import ghidra.app.context.ListingContextAction;
@ -66,11 +65,6 @@ class RemoveLabelAction extends ListingContextAction {
return !plugin.isOnExternalReference(context) && isOnSymbol(context); return !plugin.isOnExternalReference(context) && isOnSymbol(context);
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
boolean isOnSymbol(ListingActionContext context) { boolean isOnSymbol(ListingActionContext context) {
Symbol s = plugin.getSymbol(context); Symbol s = plugin.getSymbol(context);
return ((s instanceof CodeSymbol) && !s.isDynamic()) || return ((s instanceof CodeSymbol) && !s.isDynamic()) ||

View file

@ -316,16 +316,6 @@ public class NextPrevAddressPlugin extends Plugin {
setDescription(isNext ? "Go to next location" : "Go to previous location"); setDescription(isNext ? "Go to next location" : "Go to previous location");
} }
@Override
public boolean isValidContext(ActionContext context) {
return false;
}
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return (globalContext instanceof NavigatableActionContext);
}
@Override @Override
public boolean isEnabledForContext(ActionContext context) { public boolean isEnabledForContext(ActionContext context) {
Navigatable navigatable = getNavigatable(context); Navigatable navigatable = getNavigatable(context);
@ -426,16 +416,6 @@ public class NextPrevAddressPlugin extends Plugin {
setMenuBarData(menuData); setMenuBarData(menuData);
} }
@Override
public boolean isValidContext(ActionContext context) {
return false;
}
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return (globalContext instanceof NavigatableActionContext);
}
@Override @Override
public boolean isEnabledForContext(ActionContext context) { public boolean isEnabledForContext(ActionContext context) {
Navigatable navigatable = getNavigatable(context); Navigatable navigatable = getNavigatable(context);

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.references;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.action.MenuData; import docking.action.MenuData;
import ghidra.app.cmd.refs.RemoveAllReferencesCmd; import ghidra.app.cmd.refs.RemoveAllReferencesCmd;
@ -116,10 +115,4 @@ public class DeleteReferencesAction extends ListingContextAction {
} }
return actionOK; return actionOK;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
} }

View file

@ -167,11 +167,6 @@ public class RegisterPlugin extends ProgramPlugin {
} }
return false; return false;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
return false; // only work on active provider context.
}
}; };
deleteRegisterRangeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0)); deleteRegisterRangeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));

View file

@ -145,7 +145,7 @@ public class ScalarSearchPlugin extends ProgramPlugin implements DomainObjectLis
} }
@Override @Override
protected boolean isValidContext(NavigatableActionContext context) { protected boolean isValidNavigationContext(NavigatableActionContext context) {
return !(context instanceof RestrictedAddressSetContext); return !(context instanceof RestrictedAddressSetContext);
} }
}; };

View file

@ -350,7 +350,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
} }
@Override @Override
protected boolean isValidContext(NavigatableActionContext context) { protected boolean isValidNavigationContext(NavigatableActionContext context) {
return !(context instanceof RestrictedAddressSetContext); return !(context instanceof RestrictedAddressSetContext);
} }
}; };
@ -374,7 +374,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
} }
@Override @Override
protected boolean isValidContext(NavigatableActionContext context) { protected boolean isValidNavigationContext(NavigatableActionContext context) {
return !(context instanceof RestrictedAddressSetContext); return !(context instanceof RestrictedAddressSetContext);
} }
}; };

View file

@ -209,11 +209,6 @@ public abstract class AbstractDockingTool implements DockingTool {
winMgr.contextChanged(provider); winMgr.contextChanged(provider);
} }
@Override
public ActionContext getGlobalContext() {
return winMgr.getGlobalContext();
}
@Override @Override
public void addContextListener(DockingContextListener listener) { public void addContextListener(DockingContextListener listener) {
winMgr.addContextListener(listener); winMgr.addContextListener(listener);

View file

@ -117,11 +117,6 @@ public class DockingActionProxy
return dockingAction.isValidContext(context); return dockingAction.isValidContext(context);
} }
@Override
public boolean isValidGlobalContext(ActionContext context) {
return dockingAction.isValidGlobalContext(context);
}
@Override @Override
public void removePropertyChangeListener(PropertyChangeListener listener) { public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyListeners.remove(listener); propertyListeners.remove(listener);

View file

@ -24,12 +24,13 @@ import docking.action.DockingActionIf;
import docking.actions.DockingToolActions; import docking.actions.DockingToolActions;
import docking.actions.PopupActionProvider; import docking.actions.PopupActionProvider;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.ServiceProvider;
/** /**
* Generic tool interface for managing {@link ComponentProvider}s and * Generic tool interface for managing {@link ComponentProvider}s and
* {@link DockingActionIf actions} * {@link DockingActionIf actions}
*/ */
public interface DockingTool { public interface DockingTool extends ServiceProvider {
/** /**
* Returns a combination of the tool name and the instance name of the form * Returns a combination of the tool name and the instance name of the form
@ -247,15 +248,6 @@ public interface DockingTool {
*/ */
public void contextChanged(ComponentProvider provider); public void contextChanged(ComponentProvider provider);
/**
* Returns this tool's notion of the current action context, which is based upon the active
* {@link ComponentProvider}. If there is not active provider, then a generic context will
* be returned.
*
* @return the context
*/
public ActionContext getGlobalContext();
/** /**
* Adds the given context listener to this tool * Adds the given context listener to this tool
* @param listener the listener to add * @param listener the listener to add

View file

@ -353,23 +353,6 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
defaultProvider = provider; defaultProvider = provider;
} }
/**
* Returns this tool's notion of the current action context, which is based upon the active
* {@link ComponentProvider}. If there is not active provider, then a generic context will
* be returned.
*
* @return the context
*/
public ActionContext getGlobalContext() {
if (defaultProvider != null) {
ActionContext actionContext = defaultProvider.getActionContext(null);
if (actionContext != null) {
return actionContext;
}
}
return new ActionContext();
}
/** /**
* Get the window which contains the specified Provider's component. * Get the window which contains the specified Provider's component.
* @param provider component provider * @param provider component provider

View file

@ -47,36 +47,20 @@ public class MenuBarMenuHandler extends MenuHandler {
DockingWindowManager.clearMouseOverHelp(); DockingWindowManager.clearMouseOverHelp();
ComponentProvider provider = windowManager.getActiveComponentProvider(); ComponentProvider provider = windowManager.getActiveComponentProvider();
ActionContext context = provider == null ? null : provider.getActionContext(null); ActionContext providerContext = provider == null ? null : provider.getActionContext(null);
ActionContext localContext = context == null ? new ActionContext() : context; ActionContext context = providerContext == null ? new ActionContext() : providerContext;
ActionContext globalContext = windowManager.getGlobalContext();
ActionContext tempContext = null; context.setSourceObject(event.getSource());
if (action.isValidContext(localContext)) {
tempContext = localContext; // we prefer the local over the global context if valid
}
else if (action.isValidGlobalContext(globalContext)) {
tempContext = globalContext;
}
else {
return; // context is not valid, nothing to do
}
tempContext.setSourceObject(event.getSource());
final ActionContext finalContext = tempContext;
// this gives the UI some time to repaint before executing the action // this gives the UI some time to repaint before executing the action
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(() -> {
@Override windowManager.setStatusText("");
public void run() { if (action.isValidContext(context) && action.isEnabledForContext(context)) {
windowManager.setStatusText(""); if (action instanceof ToggleDockingActionIf) {
if (action.isEnabledForContext(finalContext)) { ToggleDockingActionIf toggleAction = ((ToggleDockingActionIf) action);
if (action instanceof ToggleDockingActionIf) { toggleAction.setSelected(!toggleAction.isSelected());
ToggleDockingActionIf toggleAction = ((ToggleDockingActionIf) action);
toggleAction.setSelected(!toggleAction.isSelected());
}
action.actionPerformed(finalContext);
} }
action.actionPerformed(context);
} }
}); });
} }

View file

@ -121,7 +121,6 @@ public class WindowActionManager {
ComponentProvider provider = placeHolderForScheduledActionUpdate == null ? null ComponentProvider provider = placeHolderForScheduledActionUpdate == null ? null
: placeHolderForScheduledActionUpdate.getProvider(); : placeHolderForScheduledActionUpdate.getProvider();
ActionContext localContext = provider == null ? null : provider.getActionContext(null); ActionContext localContext = provider == null ? null : provider.getActionContext(null);
ActionContext globalContext = winMgr.getGlobalContext();
if (localContext == null) { if (localContext == null) {
localContext = new ActionContext(); localContext = new ActionContext();
} }
@ -132,9 +131,6 @@ public class WindowActionManager {
if (action.isValidContext(localContext)) { if (action.isValidContext(localContext)) {
action.setEnabled(action.isEnabledForContext(localContext)); action.setEnabled(action.isEnabledForContext(localContext));
} }
else if (action.isValidGlobalContext(globalContext)) {
action.setEnabled(action.isEnabledForContext(globalContext));
}
else { else {
action.setEnabled(false); action.setEnabled(false);
} }

View file

@ -76,7 +76,6 @@ public abstract class DockingAction implements DockingActionIf {
private Predicate<ActionContext> enabledPredicate; private Predicate<ActionContext> enabledPredicate;
private Predicate<ActionContext> popupPredicate; private Predicate<ActionContext> popupPredicate;
private Predicate<ActionContext> validContextPredicate; private Predicate<ActionContext> validContextPredicate;
private Predicate<ActionContext> validGlobalContextPredicate;
public DockingAction(String name, String owner) { public DockingAction(String name, String owner) {
this.name = name; this.name = name;
@ -184,14 +183,6 @@ public abstract class DockingAction implements DockingActionIf {
return true; return true;
} }
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
if (validGlobalContextPredicate != null) {
return validGlobalContextPredicate.test(globalContext);
}
return isValidContext(globalContext);
}
/** /**
* Default behavior is to add to main window; * Default behavior is to add to main window;
*/ */
@ -572,17 +563,6 @@ public abstract class DockingAction implements DockingActionIf {
validContextPredicate = predicate; validContextPredicate = predicate;
} }
/**
* Sets a predicate for dynamically determining if this action is valid for the current global
* {@link ActionContext}. See {@link DockingActionIf#isValidGlobalContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given global {@link ActionContext}
*/
public void validGlobalContextWhen(Predicate<ActionContext> predicate) {
validGlobalContextPredicate = predicate;
}
//================================================================================================== //==================================================================================================
// Non-public methods // Non-public methods
//================================================================================================== //==================================================================================================

View file

@ -193,19 +193,6 @@ public interface DockingActionIf extends HelpDescriptor {
*/ */
public boolean isValidContext(ActionContext context); public boolean isValidContext(ActionContext context);
/**
* Method that actions implement to indicate if this action is valid (knows how to work with, is
* appropriate for) for the given global context. This method is just like the isValidContext
* and in fact calls that method by default. Many actions will work with either the active
* provider context or the global (the main listing) context if the local context is not valid.
* If you want a global action to only work on the global context, then override this method
* and return false.
*
* @param globalContext the global {@link ActionContext} from the active provider.
* @return true if this action is appropriate for the given context.
*/
public boolean isValidGlobalContext(ActionContext globalContext);
/** /**
* Method used to determine if this action should be enabled for the given context. * Method used to determine if this action should be enabled for the given context.
* <p> * <p>

View file

@ -121,8 +121,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
ActionContext localContext = getLocalContext(localProvider); ActionContext localContext = getLocalContext(localProvider);
localContext.setSourceObject(event.getSource()); localContext.setSourceObject(event.getSource());
ActionContext globalContext = tool.getGlobalContext(); List<ExecutableKeyActionAdapter> list = getValidContextActions(localContext);
List<ExecutableKeyActionAdapter> list = getValidContextActions(localContext, globalContext);
// If menu active, disable all key bindings // If menu active, disable all key bindings
if (ignoreActionWhileMenuShowing()) { if (ignoreActionWhileMenuShowing()) {
@ -164,8 +163,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
return menuManager.getSelectedPath().length != 0; return menuManager.getSelectedPath().length != 0;
} }
private List<ExecutableKeyActionAdapter> getValidContextActions(ActionContext localContext, private List<ExecutableKeyActionAdapter> getValidContextActions(ActionContext localContext) {
ActionContext globalContext) {
List<ExecutableKeyActionAdapter> list = new ArrayList<>(); List<ExecutableKeyActionAdapter> list = new ArrayList<>();
boolean hasLocalActionsForKeyBinding = false; boolean hasLocalActionsForKeyBinding = false;
@ -222,9 +220,6 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
if (isValidAndEnabled(actionData, localContext)) { if (isValidAndEnabled(actionData, localContext)) {
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext)); list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
} }
else if (isValidAndEnabledGlobally(actionData, globalContext)) {
list.add(new ExecutableKeyActionAdapter(actionData.action, globalContext));
}
} }
} }
return list; return list;
@ -235,11 +230,6 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
return a.isValidContext(localContext) && a.isEnabledForContext(localContext); return a.isValidContext(localContext) && a.isEnabledForContext(localContext);
} }
private boolean isValidAndEnabledGlobally(ActionData actionData, ActionContext globalContext) {
DockingActionIf a = actionData.action;
return a.isValidGlobalContext(globalContext) && a.isEnabledForContext(globalContext);
}
@Override @Override
public boolean isReservedKeybindingPrecedence() { public boolean isReservedKeybindingPrecedence() {
return false; // MultipleKeyActions can never be reserved return false; // MultipleKeyActions can never be reserved
@ -249,9 +239,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
public KeyBindingPrecedence getKeyBindingPrecedence() { public KeyBindingPrecedence getKeyBindingPrecedence() {
ComponentProvider localProvider = tool.getActiveComponentProvider(); ComponentProvider localProvider = tool.getActiveComponentProvider();
ActionContext localContext = getLocalContext(localProvider); ActionContext localContext = getLocalContext(localProvider);
ActionContext globalContext = tool.getGlobalContext(); List<ExecutableKeyActionAdapter> validActions = getValidContextActions(localContext);
List<ExecutableKeyActionAdapter> validActions =
getValidContextActions(localContext, globalContext);
if (validActions.isEmpty()) { if (validActions.isEmpty()) {
return null; // a signal that no actions are valid for the current context return null; // a signal that no actions are valid for the current context

View file

@ -159,12 +159,6 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends
*/ */
private Predicate<ActionContext> validContextPredicate; private Predicate<ActionContext> validContextPredicate;
/**
* Predicate for determining if an action is applicable for a given global context
*/
private Predicate<ActionContext> validGlobalContextPredicate;
/** /**
* Builder constructor * Builder constructor
* @param name the name of the action to be built * @param name the name of the action to be built
@ -551,22 +545,6 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends
return self(); return self();
} }
/**
* Sets a predicate for dynamically determining if this action is valid for the current global
* {@link ActionContext}. See {@link DockingActionIf#isValidGlobalContext(ActionContext)}.
*
* <p>Note: most actions will not use this method, but rely instead on
* {@link #enabledWhen(Predicate)}.
*
* @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given global {@link ActionContext}
* @return this builder (for chaining)
*/
public B validGlobalContextWhen(Predicate<ActionContext> predicate) {
validGlobalContextPredicate = predicate;
return self();
}
protected void validate() { protected void validate() {
if (actionCallback == null) { if (actionCallback == null) {
throw new IllegalStateException( throw new IllegalStateException(
@ -593,9 +571,6 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends
if (validContextPredicate != null) { if (validContextPredicate != null) {
action.validContextWhen(validContextPredicate); action.validContextWhen(validContextPredicate);
} }
if (validGlobalContextPredicate != null) {
action.validGlobalContextWhen(validGlobalContextPredicate);
}
if (popupPredicate != null) { if (popupPredicate != null) {
action.popupWhen(enabledPredicate); action.popupWhen(enabledPredicate);
} }

View file

@ -150,8 +150,7 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
DockingWindowManager manager = DockingWindowManager.getActiveInstance(); DockingWindowManager manager = DockingWindowManager.getActiveInstance();
ComponentProvider provider = manager.getActiveComponentProvider(); ComponentProvider provider = manager.getActiveComponentProvider();
ActionContext localContext = provider == null ? null : provider.getActionContext(null); ActionContext localContext = provider == null ? null : provider.getActionContext(null);
final ActionContext actionContext = ActionContext actionContext = localContext == null ? new ActionContext() : localContext;
localContext == null ? manager.getGlobalContext() : localContext;
return actionContext; return actionContext;
} }

View file

@ -189,33 +189,23 @@ public class ToolBarItemManager implements PropertyChangeListener, ActionListene
@Override @Override
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
DockingWindowManager.clearMouseOverHelp(); DockingWindowManager.clearMouseOverHelp();
ActionContext localContext = getActionContext(); ActionContext context = getActionContext();
ActionContext globalContext = null;
if (windowManager != null) { if (!toolBarAction.isValidContext(context)) {
globalContext = windowManager.getGlobalContext(); return;
} }
ActionContext tempContext = null; context.setSourceObject(event.getSource());
if (toolBarAction.isValidContext(localContext)) {
tempContext = localContext; // we prefer the local over the global context if valid
}
else if (toolBarAction.isValidGlobalContext(globalContext)) {
tempContext = globalContext;
}
else {
return; // context is not valid, nothing to do
}
tempContext.setSourceObject(event.getSource());
final ActionContext finalContext = tempContext;
// this gives the UI some time to repaint before executing the action // this gives the UI some time to repaint before executing the action
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
if (toolBarAction.isEnabledForContext(finalContext)) { if (toolBarAction.isValidContext(context) &&
toolBarAction.isEnabledForContext(context)) {
if (toolBarAction instanceof ToggleDockingActionIf) { if (toolBarAction instanceof ToggleDockingActionIf) {
ToggleDockingActionIf toggleAction = (ToggleDockingActionIf) toolBarAction; ToggleDockingActionIf toggleAction = (ToggleDockingActionIf) toolBarAction;
toggleAction.setSelected(!toggleAction.isSelected()); toggleAction.setSelected(!toggleAction.isSelected());
} }
toolBarAction.actionPerformed(finalContext); toolBarAction.actionPerformed(context);
} }
}); });
} }

View file

@ -23,6 +23,7 @@ import javax.swing.ImageIcon;
import docking.actions.ToolActions; import docking.actions.ToolActions;
import docking.framework.ApplicationInformationDisplayFactory; import docking.framework.ApplicationInformationDisplayFactory;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.util.ServiceListener;
/** /**
* A Test Double of the {@link DockingTool} that provides minimal tool functionality, such * A Test Double of the {@link DockingTool} that provides minimal tool functionality, such
@ -62,4 +63,19 @@ public class FakeDockingTool extends AbstractDockingTool {
public void close() { public void close() {
// stub // stub
} }
@Override
public <T> T getService(Class<T> serviceClass) {
return null;
}
@Override
public void addServiceListener(ServiceListener listener) {
// stub
}
@Override
public void removeServiceListener(ServiceListener listener) {
// stub
}
} }

View file

@ -73,7 +73,7 @@ import ghidra.util.task.*;
* <p>The PluginTool also manages tasks that run in the background, and options used by the plugins. * <p>The PluginTool also manages tasks that run in the background, and options used by the plugins.
* *
*/ */
public abstract class PluginTool extends AbstractDockingTool implements Tool, ServiceProvider { public abstract class PluginTool extends AbstractDockingTool implements Tool {
private static final String DOCKING_WINDOWS_ON_TOP = "Docking Windows On Top"; private static final String DOCKING_WINDOWS_ON_TOP = "Docking Windows On Top";

View file

@ -34,6 +34,7 @@ import docking.util.image.ToolIconURL;
import ghidra.framework.model.*; import ghidra.framework.model.*;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginEvent; import ghidra.framework.plugintool.PluginEvent;
import ghidra.framework.plugintool.util.ServiceListener;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
public class DummyTool implements Tool { public class DummyTool implements Tool {
@ -369,11 +370,6 @@ public class DummyTool implements Tool {
//do nothing //do nothing
} }
@Override
public ActionContext getGlobalContext() {
return null;
}
@Override @Override
public void setStatusInfo(String text) { public void setStatusInfo(String text) {
//do nothing //do nothing
@ -423,4 +419,19 @@ public class DummyTool implements Tool {
public DockingToolActions getToolActions() { public DockingToolActions getToolActions() {
return toolActions; return toolActions;
} }
@Override
public <T> T getService(Class<T> serviceClass) {
return null;
}
@Override
public void addServiceListener(ServiceListener listener) {
//do nothing
}
@Override
public void removeServiceListener(ServiceListener listener) {
//do nothing
}
} }