GT-3485 Removed Secondary "default" action context to prevent actions

from triggering unexpectedly
This commit is contained in:
ghidravore 2020-01-23 11:49:58 -05:00
parent db7803144a
commit 26d7d0da5f
33 changed files with 128 additions and 288 deletions

View file

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

View file

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

View file

@ -24,12 +24,13 @@ import docking.action.DockingActionIf;
import docking.actions.DockingToolActions;
import docking.actions.PopupActionProvider;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.ServiceProvider;
/**
* Generic tool interface for managing {@link ComponentProvider}s and
* {@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
@ -247,15 +248,6 @@ public interface DockingTool {
*/
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
* @param listener the listener to add

View file

@ -353,23 +353,6 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
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.
* @param provider component provider

View file

@ -47,36 +47,20 @@ public class MenuBarMenuHandler extends MenuHandler {
DockingWindowManager.clearMouseOverHelp();
ComponentProvider provider = windowManager.getActiveComponentProvider();
ActionContext context = provider == null ? null : provider.getActionContext(null);
ActionContext localContext = context == null ? new ActionContext() : context;
ActionContext globalContext = windowManager.getGlobalContext();
ActionContext providerContext = provider == null ? null : provider.getActionContext(null);
ActionContext context = providerContext == null ? new ActionContext() : providerContext;
ActionContext tempContext = null;
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;
context.setSourceObject(event.getSource());
// this gives the UI some time to repaint before executing the action
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
windowManager.setStatusText("");
if (action.isEnabledForContext(finalContext)) {
if (action instanceof ToggleDockingActionIf) {
ToggleDockingActionIf toggleAction = ((ToggleDockingActionIf) action);
toggleAction.setSelected(!toggleAction.isSelected());
}
action.actionPerformed(finalContext);
SwingUtilities.invokeLater(() -> {
windowManager.setStatusText("");
if (action.isValidContext(context) && action.isEnabledForContext(context)) {
if (action instanceof ToggleDockingActionIf) {
ToggleDockingActionIf toggleAction = ((ToggleDockingActionIf) action);
toggleAction.setSelected(!toggleAction.isSelected());
}
action.actionPerformed(context);
}
});
}

View file

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

View file

@ -76,7 +76,6 @@ public abstract class DockingAction implements DockingActionIf {
private Predicate<ActionContext> enabledPredicate;
private Predicate<ActionContext> popupPredicate;
private Predicate<ActionContext> validContextPredicate;
private Predicate<ActionContext> validGlobalContextPredicate;
public DockingAction(String name, String owner) {
this.name = name;
@ -184,14 +183,6 @@ public abstract class DockingAction implements DockingActionIf {
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;
*/
@ -572,17 +563,6 @@ public abstract class DockingAction implements DockingActionIf {
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
//==================================================================================================

View file

@ -193,19 +193,6 @@ public interface DockingActionIf extends HelpDescriptor {
*/
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.
* <p>

View file

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

View file

@ -152,11 +152,6 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends
*/
private Predicate<ActionContext> validContextPredicate;
/**
* Predicate for determining if an action is applicable for a given global context
*/
private Predicate<ActionContext> validGlobalContextPredicate;
/**
* Builder constructor
* @param name the name of the action to be built
@ -517,22 +512,6 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends
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() {
if (actionCallback == null) {
throw new IllegalStateException(
@ -558,9 +537,6 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends
if (validContextPredicate != null) {
action.validContextWhen(validContextPredicate);
}
if (validGlobalContextPredicate != null) {
action.validGlobalContextWhen(validGlobalContextPredicate);
}
if (popupPredicate != null) {
action.popupWhen(enabledPredicate);
}

View file

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

View file

@ -189,33 +189,23 @@ public class ToolBarItemManager implements PropertyChangeListener, ActionListene
@Override
public void actionPerformed(ActionEvent event) {
DockingWindowManager.clearMouseOverHelp();
ActionContext localContext = getActionContext();
ActionContext globalContext = null;
if (windowManager != null) {
globalContext = windowManager.getGlobalContext();
ActionContext context = getActionContext();
if (!toolBarAction.isValidContext(context)) {
return;
}
ActionContext tempContext = null;
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;
context.setSourceObject(event.getSource());
// this gives the UI some time to repaint before executing the action
SwingUtilities.invokeLater(() -> {
if (toolBarAction.isEnabledForContext(finalContext)) {
if (toolBarAction.isValidContext(context) &&
toolBarAction.isEnabledForContext(context)) {
if (toolBarAction instanceof ToggleDockingActionIf) {
ToggleDockingActionIf toggleAction = (ToggleDockingActionIf) toolBarAction;
toggleAction.setSelected(!toggleAction.isSelected());
}
toolBarAction.actionPerformed(finalContext);
toolBarAction.actionPerformed(context);
}
});
}