diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java index ba2e5d8815..84a8be66ea 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java @@ -20,15 +20,46 @@ import docking.action.DockingAction; import docking.action.KeyBindingType; public abstract class NavigatableContextAction extends DockingAction { + // means this action is applicable on navigable providers that restrict the program view such + // as the FunctionGraph or the Decompiler views. + private final boolean supportsRestrictedAddressSetContext; + /** + * Constructor for actions that can work on any Navigatable + * + * @param name the action's name + * @param owner the action's owner + */ public NavigatableContextAction(String name, String owner) { - super(name, owner); - setSupportsDefaultToolContext(true); + this(name, owner, true); } + /** + * Constructor for specifying if that the context works on {@link RestrictedAddressSetContext} + * + * @param name the action's name + * @param owner the action's owner + * @param supportsRestrictedAddressSetContext true if this action can work on + * {@link RestrictedAddressSetContext} + */ + public NavigatableContextAction(String name, String owner, + boolean supportsRestrictedAddressSetContext) { + super(name, owner); + setSupportsDefaultToolContext(true); + this.supportsRestrictedAddressSetContext = supportsRestrictedAddressSetContext; + } + + /** + * Constructor when using a non-standard {@link KeyBindingType} + * + * @param name the action's name + * @param owner the action's owner + * @param type the KeybindingType + */ public NavigatableContextAction(String name, String owner, KeyBindingType type) { super(name, owner, type); setSupportsDefaultToolContext(true); + this.supportsRestrictedAddressSetContext = true; } @Override @@ -48,6 +79,12 @@ public abstract class NavigatableContextAction extends DockingAction { @Override public final boolean isValidContext(ActionContext context) { + // If this method returns false, then when the user is in a restricted view, the action + // will be passed the global context instead of the current local context + if (!supportsRestrictedAddressSetContext && + context instanceof RestrictedAddressSetContext) { + return false; + } return context instanceof NavigatableActionContext; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/context/RestrictedAddressSetContext.java b/Ghidra/Features/Base/src/main/java/ghidra/app/context/RestrictedAddressSetContext.java index 245a453af0..e7f6139ce8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/context/RestrictedAddressSetContext.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/context/RestrictedAddressSetContext.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +15,12 @@ */ package ghidra.app.context; +import ghidra.app.nav.Navigatable; +/** + * Marker interface for {@link Navigatable} contexts that don't support navigating to the entire + * program. Typically, these are used by providers that show only one function at a time such + * as the Decompiler. + */ public interface RestrictedAddressSetContext { } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java index 5e94d95c7f..1b4eeb833f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java @@ -23,7 +23,8 @@ import docking.action.DockingAction; import docking.action.MenuData; import docking.tool.ToolConstants; import ghidra.app.CorePluginPackage; -import ghidra.app.context.*; +import ghidra.app.context.NavigatableActionContext; +import ghidra.app.context.NavigatableContextAction; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.core.instructionsearch.ui.InstructionSearchDialog; @@ -238,17 +239,11 @@ public class InstructionSearchPlugin extends ProgramPlugin { } private void createActions() { - searchAction = new NavigatableContextAction(SEARCH_ACTION_NAME, getName()) { + searchAction = new NavigatableContextAction(SEARCH_ACTION_NAME, getName(), false) { @Override public void actionPerformed(NavigatableActionContext context) { showSearchDialog(context); } - - @Override - protected boolean isEnabledForContext(NavigatableActionContext context) { - return !(context instanceof RestrictedAddressSetContext); - } - }; searchAction.addToWindowWhen(NavigatableActionContext.class); searchAction.setHelpLocation(new HelpLocation("Search", "Instruction_Pattern_Search")); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java index 2c425eda58..376a6f21d3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java @@ -21,7 +21,8 @@ import docking.action.DockingAction; import docking.action.MenuData; import docking.tool.ToolConstants; import ghidra.app.CorePluginPackage; -import ghidra.app.context.*; +import ghidra.app.context.NavigatableActionContext; +import ghidra.app.context.NavigatableContextAction; import ghidra.app.events.ViewChangedPluginEvent; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.ProgramPlugin; @@ -138,16 +139,11 @@ public class ScalarSearchPlugin extends ProgramPlugin implements DomainObjectLis private void createActions() { - searchAction = new NavigatableContextAction(SEARCH_ACTION_NAME, getName()) { + searchAction = new NavigatableContextAction(SEARCH_ACTION_NAME, getName(), false) { @Override public void actionPerformed(NavigatableActionContext context) { openSearchDialog(); } - - @Override - protected boolean isEnabledForContext(NavigatableActionContext context) { - return !(context instanceof RestrictedAddressSetContext); - } }; searchAction.setHelpLocation(new HelpLocation(this.getName(), "Scalar_Search")); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java index a7d4f47ce7..17a9b0a500 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java @@ -30,7 +30,8 @@ import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.table.threaded.*; import ghidra.GhidraOptions; import ghidra.app.CorePluginPackage; -import ghidra.app.context.*; +import ghidra.app.context.NavigatableActionContext; +import ghidra.app.context.NavigatableContextAction; import ghidra.app.events.ProgramSelectionPluginEvent; import ghidra.app.nav.Navigatable; import ghidra.app.nav.NavigatableRemovalListener; @@ -342,17 +343,12 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener, } private void createActions() { - searchAction = new NavigatableContextAction("Search Memory", getName()) { + searchAction = new NavigatableContextAction("Search Memory", getName(), false) { @Override public void actionPerformed(NavigatableActionContext context) { setNavigatable(context.getNavigatable()); invokeSearchDialog(context); } - - @Override - protected boolean isEnabledForContext(NavigatableActionContext context) { - return !(context instanceof RestrictedAddressSetContext); - } }; searchAction.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, searchAction.getName())); String[] menuPath = new String[] { "&Search", "&Memory..." }; @@ -362,17 +358,12 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener, searchAction.addToWindowWhen(NavigatableActionContext.class); tool.addAction(searchAction); - searchAgainAction = new NavigatableContextAction("Repeat Memory Search", getName()) { + searchAgainAction = new NavigatableContextAction("Repeat Memory Search", getName(), false) { @Override public void actionPerformed(NavigatableActionContext context) { setNavigatable(context.getNavigatable()); performSearch(searchInfo); } - - @Override - protected boolean isEnabledForContext(NavigatableActionContext context) { - return !(context instanceof RestrictedAddressSetContext) && searchInfo != null; - } }; searchAgainAction .setHelpLocation(new HelpLocation(HelpTopics.SEARCH, searchAgainAction.getName())); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchtext/SearchTextPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchtext/SearchTextPlugin.java index b51ba51933..5ed124474a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchtext/SearchTextPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchtext/SearchTextPlugin.java @@ -30,8 +30,7 @@ import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.table.threaded.*; import ghidra.GhidraOptions; import ghidra.app.CorePluginPackage; -import ghidra.app.context.ListingActionContext; -import ghidra.app.context.NavigatableActionContext; +import ghidra.app.context.*; import ghidra.app.nav.Navigatable; import ghidra.app.nav.NavigatableRemovalListener; import ghidra.app.plugin.PluginCategoryNames; @@ -380,6 +379,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList .description(DESCRIPTION) .helpLocation(new HelpLocation(HelpTopics.SEARCH, "Search Text")) .withContext(NavigatableActionContext.class) + .validContextWhen(c -> !(c instanceof RestrictedAddressSetContext)) .inWindow(ActionBuilder.When.CONTEXT_MATCHES) .supportsDefaultToolContext(true) .onAction(c -> {