mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Merge branch 'GT-3485_ghidravore_action_context'
Conflicts: Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java
This commit is contained in:
commit
5dc7df71b3
33 changed files with 128 additions and 289 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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()) ||
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue