mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-16 15:40:14 +00:00
Merge branch 'GT-3485-ghidravore_action_context'
This commit is contained in:
commit
16f050f901
@ -17,11 +17,9 @@ package ghidra.app.context;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import docking.*;
|
import docking.ActionContext;
|
||||||
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 {
|
||||||
|
|
||||||
@ -52,7 +50,11 @@ public abstract class NavigatableContextAction extends DockingAction {
|
|||||||
isValidNavigationContext((NavigatableActionContext) context)) {
|
isValidNavigationContext((NavigatableActionContext) context)) {
|
||||||
return (NavigatableActionContext) context;
|
return (NavigatableActionContext) context;
|
||||||
}
|
}
|
||||||
return getGlobalNavigationContext(context);
|
ActionContext globalContext = context.getGlobalContext();
|
||||||
|
if (globalContext instanceof NavigatableActionContext) {
|
||||||
|
return (NavigatableActionContext) globalContext;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,34 +66,6 @@ public abstract class NavigatableContextAction extends DockingAction {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NavigatableActionContext getGlobalNavigationContext(ActionContext context) {
|
|
||||||
Tool tool = getTool(context.getComponentProvider());
|
|
||||||
|
|
||||||
if (tool == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
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 Tool getTool(ComponentProvider provider) {
|
|
||||||
if (provider != null) {
|
|
||||||
return provider.getTool();
|
|
||||||
}
|
|
||||||
DockingWindowManager manager = DockingWindowManager.getActiveInstance();
|
|
||||||
if (manager != null) {
|
|
||||||
return manager.getTool();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
public boolean isAddToPopup(ActionContext context) {
|
||||||
if (!(context instanceof NavigatableActionContext)) {
|
if (!(context instanceof NavigatableActionContext)) {
|
||||||
|
@ -21,12 +21,13 @@ import javax.swing.SwingUtilities;
|
|||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.DockingWindowManager;
|
import docking.DockingWindowManager;
|
||||||
import docking.action.*;
|
import docking.action.DockingAction;
|
||||||
|
import docking.action.MenuData;
|
||||||
|
import docking.action.builder.ActionBuilder;
|
||||||
import docking.widgets.dialogs.MultiLineMessageDialog;
|
import docking.widgets.dialogs.MultiLineMessageDialog;
|
||||||
import ghidra.GhidraOptions;
|
import ghidra.GhidraOptions;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
|
||||||
import ghidra.app.events.*;
|
import ghidra.app.events.*;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
import ghidra.app.services.Analyzer;
|
import ghidra.app.services.Analyzer;
|
||||||
@ -107,53 +108,57 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
|||||||
// use this index to make sure that the following actions are ordered in the way that
|
// use this index to make sure that the following actions are ordered in the way that
|
||||||
// they are inserted
|
// they are inserted
|
||||||
int subGroupIndex = 0;
|
int subGroupIndex = 0;
|
||||||
|
|
||||||
|
autoAnalyzeAction = new ActionBuilder("Auto Analyze", getName())
|
||||||
|
.menuPath("&Analysis", "&Auto Analyze...")
|
||||||
|
.menuGroup(ANALYZE_GROUP_NAME, "" + subGroupIndex++)
|
||||||
|
.keyBinding("A")
|
||||||
|
.onAction(this::analyzeCallback)
|
||||||
|
.enabledWhen(this::canAnalyze)
|
||||||
|
.buildAndInstall(tool);
|
||||||
|
|
||||||
autoAnalyzeAction = new ListingContextAction("Auto Analyze", getName()) {
|
analyzeAllAction = new ActionBuilder("Analyze All Open", getName())
|
||||||
@Override
|
.menuPath("&Analysis", "Analyze All &Open...")
|
||||||
protected void actionPerformed(ListingActionContext programContext) {
|
.menuGroup(ANALYZE_GROUP_NAME, "" + subGroupIndex++)
|
||||||
analyzeCallback(programContext.getProgram(), programContext.getSelection());
|
.onAction(c -> analyzeAllCallback())
|
||||||
}
|
.enabledWhen(c -> getListingContext(c) != null)
|
||||||
|
.buildAndInstall(tool);
|
||||||
@Override
|
|
||||||
public boolean isEnabledForContext(ListingActionContext context) {
|
|
||||||
Program program = context.getProgram();
|
|
||||||
getMenuBarData().setMenuItemName(
|
|
||||||
"&Auto Analyze '" + program.getDomainFile().getName() + "'...");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
String[] menuPath = { "&Analysis", "&Auto Analyze..." };
|
|
||||||
MenuData menuData = new MenuData(menuPath, null, ANALYZE_GROUP_NAME);
|
|
||||||
menuData.setMenuSubGroup("" + subGroupIndex++);
|
|
||||||
autoAnalyzeAction.setMenuBarData(menuData);
|
|
||||||
|
|
||||||
autoAnalyzeAction.setKeyBindingData(new KeyBindingData('A', 0));
|
|
||||||
|
|
||||||
tool.addAction(autoAnalyzeAction);
|
|
||||||
|
|
||||||
analyzeAllAction = new DockingAction("Analyze All Open", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
analyzeAllCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
|
||||||
return context.getContextObject() instanceof ListingActionContext;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
analyzeAllAction.setEnabled(false);
|
|
||||||
menuData =
|
|
||||||
new MenuData(new String[] { "&Analysis", "Analyze All &Open..." }, ANALYZE_GROUP_NAME);
|
|
||||||
menuData.setMenuSubGroup("" + subGroupIndex++);
|
|
||||||
analyzeAllAction.setMenuBarData(menuData);
|
|
||||||
|
|
||||||
tool.addAction(analyzeAllAction);
|
|
||||||
|
|
||||||
tool.setMenuGroup(new String[] { "Analysis", "One Shot" }, ANALYZE_GROUP_NAME);
|
tool.setMenuGroup(new String[] { "Analysis", "One Shot" }, ANALYZE_GROUP_NAME);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canAnalyze(ActionContext context) {
|
||||||
|
ListingActionContext listingContext = getListingContext(context);
|
||||||
|
updateActionName(listingContext);
|
||||||
|
return listingContext != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateActionName(ListingActionContext listingContext) {
|
||||||
|
String programName = "";
|
||||||
|
if (listingContext != null) {
|
||||||
|
programName = listingContext.getProgram().getDomainFile().getName();
|
||||||
|
}
|
||||||
|
MenuData menuBarData = autoAnalyzeAction.getMenuBarData();
|
||||||
|
menuBarData.setMenuItemName("&Auto Analyze '" + programName + "'...");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListingActionContext getListingContext(ActionContext context) {
|
||||||
|
if (context instanceof ListingActionContext) {
|
||||||
|
return (ListingActionContext) context;
|
||||||
|
}
|
||||||
|
ActionContext globalContext = context.getGlobalContext();
|
||||||
|
if (globalContext instanceof ListingActionContext) {
|
||||||
|
return (ListingActionContext) globalContext;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void analyzeCallback(ActionContext context) {
|
||||||
|
ListingActionContext listingContext = getListingContext(context);
|
||||||
|
analyzeCallback(listingContext.getProgram(), listingContext.getSelection());
|
||||||
|
}
|
||||||
|
|
||||||
private void addOneShotActions(Program program) {
|
private void addOneShotActions(Program program) {
|
||||||
removeOneShotActions();
|
removeOneShotActions();
|
||||||
for (Analyzer analyzer : analyzers) {
|
for (Analyzer analyzer : analyzers) {
|
||||||
@ -322,7 +327,7 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OneShotAnalyzerAction extends ListingContextAction {
|
class OneShotAnalyzerAction extends DockingAction {
|
||||||
private Analyzer analyzer;
|
private Analyzer analyzer;
|
||||||
private Program canAnalyzeProgram;
|
private Program canAnalyzeProgram;
|
||||||
private boolean canAnalyze;
|
private boolean canAnalyze;
|
||||||
@ -338,7 +343,8 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ListingActionContext programContext) {
|
public void actionPerformed(ActionContext context) {
|
||||||
|
ListingActionContext programContext = getListingContext(context);
|
||||||
AddressSetView set;
|
AddressSetView set;
|
||||||
if (programContext.hasSelection()) {
|
if (programContext.hasSelection()) {
|
||||||
set = programContext.getSelection();
|
set = programContext.getSelection();
|
||||||
@ -363,7 +369,8 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isEnabledForContext(ListingActionContext programContext) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
ListingActionContext programContext = getListingContext(context);
|
||||||
Program p = programContext.getProgram();
|
Program p = programContext.getProgram();
|
||||||
if (p != canAnalyzeProgram) {
|
if (p != canAnalyzeProgram) {
|
||||||
canAnalyzeProgram = p;
|
canAnalyzeProgram = p;
|
||||||
|
@ -78,6 +78,7 @@ public class ActionContext {
|
|||||||
private MouseEvent mouseEvent;
|
private MouseEvent mouseEvent;
|
||||||
private Object contextObject;
|
private Object contextObject;
|
||||||
private Object sourceObject;
|
private Object sourceObject;
|
||||||
|
private ActionContext globalContext;
|
||||||
|
|
||||||
// Note: the setting of this object is delayed. This allows clients to build-up the state
|
// Note: the setting of this object is delayed. This allows clients to build-up the state
|
||||||
// of this context. This object will be set when getSourceComponent() is called if it
|
// of this context. This object will be set when getSourceComponent() is called if it
|
||||||
@ -243,4 +244,29 @@ public class ActionContext {
|
|||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the global action context for the tool. The global context is the context of
|
||||||
|
* the default focused component, instead of the normal action context which is the current
|
||||||
|
* focused component.
|
||||||
|
* @return the global action context for the tool
|
||||||
|
*/
|
||||||
|
public ActionContext getGlobalContext() {
|
||||||
|
if (globalContext == null) {
|
||||||
|
Tool tool = getTool();
|
||||||
|
globalContext = tool == null ? new ActionContext() : tool.getGlobalActionContext();
|
||||||
|
}
|
||||||
|
return globalContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tool getTool() {
|
||||||
|
if (provider != null) {
|
||||||
|
return provider.getTool();
|
||||||
|
}
|
||||||
|
DockingWindowManager manager = DockingWindowManager.getActiveInstance();
|
||||||
|
if (manager != null) {
|
||||||
|
return manager.getTool();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2140,6 +2140,15 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||||||
contextListeners.remove(listener);
|
contextListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the global action context for the tool
|
||||||
|
* @return the global action context for the tool
|
||||||
|
*/
|
||||||
|
public ActionContext getGlobalActionContext() {
|
||||||
|
return defaultProvider == null ? new ActionContext()
|
||||||
|
: defaultProvider.getActionContext(null);
|
||||||
|
}
|
||||||
|
|
||||||
void notifyContextListeners(ComponentPlaceholder placeHolder, ActionContext actionContext) {
|
void notifyContextListeners(ComponentPlaceholder placeHolder, ActionContext actionContext) {
|
||||||
|
|
||||||
if (placeHolder == focusedPlaceholder) {
|
if (placeHolder == focusedPlaceholder) {
|
||||||
|
@ -304,4 +304,12 @@ public interface Tool extends ServiceProvider {
|
|||||||
*/
|
*/
|
||||||
public void close();
|
public void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the global action context for the tool. The global context is the context of
|
||||||
|
* the default focused component, instead of the normal action context which is the current
|
||||||
|
* focused component.
|
||||||
|
* @return the global action context for the tool
|
||||||
|
*/
|
||||||
|
public ActionContext getGlobalActionContext();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,4 +78,9 @@ public class FakeDockingTool extends AbstractDockingTool {
|
|||||||
public void removeServiceListener(ServiceListener listener) {
|
public void removeServiceListener(ServiceListener listener) {
|
||||||
// stub
|
// stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionContext getGlobalActionContext() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1471,6 +1471,11 @@ public abstract class PluginTool extends AbstractDockingTool {
|
|||||||
winMgr.removePreferenceState(name);
|
winMgr.removePreferenceState(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionContext getGlobalActionContext() {
|
||||||
|
return winMgr.getGlobalActionContext();
|
||||||
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Inner Classes
|
// Inner Classes
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user