diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingActionContext.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingActionContext.java index 6204f0c210..7808243c86 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingActionContext.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingActionContext.java @@ -15,7 +15,10 @@ */ package ghidra.app.plugin.core.debug.gui.listing; +import org.apache.commons.lang3.StringUtils; + import ghidra.app.context.ListingActionContext; +import ghidra.app.plugin.core.codebrowser.CodeViewerProvider; import ghidra.app.plugin.core.debug.gui.action.DebuggerProgramLocationActionContext; import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramSelection; @@ -41,4 +44,15 @@ public class DebuggerListingActionContext extends ListingActionContext public TraceProgramView getProgram() { return (TraceProgramView) super.getProgram(); } + + @Override + public boolean hasSelection() { + CodeViewerProvider provider = (CodeViewerProvider) getComponentProvider(); + String textSelection = provider.getTextSelection(); + if (!StringUtils.isBlank(textSelection)) { + return true; + } + + return super.hasSelection(); + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserSelectionPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserSelectionPlugin.java index d1fc4fe923..2969d7c541 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserSelectionPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserSelectionPlugin.java @@ -17,14 +17,14 @@ package ghidra.app.plugin.core.codebrowser; import javax.swing.Icon; -import org.apache.commons.lang3.StringUtils; - import docking.ComponentProvider; import docking.action.builder.ActionBuilder; import docking.tool.ToolConstants; import generic.theme.GIcon; import ghidra.app.CorePluginPackage; import ghidra.app.context.ListingActionContext; +import ghidra.app.context.NavigatableActionContext; +import ghidra.app.nav.Navigatable; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.codebrowser.SelectEndpointsAction.RangeEndpoint; import ghidra.app.plugin.core.table.TableComponentProvider; @@ -95,11 +95,13 @@ public class CodeBrowserSelectionPlugin extends Plugin { .menuPath(ToolConstants.MENU_SELECTION, "&Clear Selection") .menuGroup(SELECT_GROUP, "b") .helpLocation(new HelpLocation(HelpTopics.SELECTION, "Clear Selection")) - .withContext(ListingActionContext.class, true) + .withContext(NavigatableActionContext.class, true) .inWindow(ActionBuilder.When.CONTEXT_MATCHES) - .enabledWhen(c -> hasSelection(c)) - .onAction(c -> ((CodeViewerProvider) c.getComponentProvider()) - .setSelection(new ProgramSelection())) + .enabledWhen(NavigatableActionContext::hasSelection) + .onAction(c -> { + Navigatable n = c.getNavigatable(); + n.setSelection(new ProgramSelection()); + }) .buildAndInstall(tool); new ActionBuilder("Select Complement", getName()) @@ -203,20 +205,6 @@ public class CodeBrowserSelectionPlugin extends Plugin { return provider instanceof CodeViewerProvider; } - private boolean hasSelection(ListingActionContext c) { - if (!hasCodeViewer(c)) { - return false; - } - - if (c.hasSelection()) { - return true; - } - - CodeViewerProvider provider = (CodeViewerProvider) c.getComponentProvider(); - String textSelection = provider.getTextSelection(); - return !StringUtils.isBlank(textSelection); - } - private GhidraProgramTableModel
createTableModel(Program program, CodeUnitIterator iterator, ProgramSelection selection) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerActionContext.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerActionContext.java index d0e889b166..8e9520410e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerActionContext.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerActionContext.java @@ -15,6 +15,8 @@ */ package ghidra.app.plugin.core.codebrowser; +import org.apache.commons.lang3.StringUtils; + import ghidra.app.context.ListingActionContext; import ghidra.program.util.ProgramLocation; @@ -27,4 +29,15 @@ public class CodeViewerActionContext extends ListingActionContext { public CodeViewerActionContext(CodeViewerProvider provider, ProgramLocation location) { super(provider, provider, location); } + + @Override + public boolean hasSelection() { + CodeViewerProvider provider = (CodeViewerProvider) getComponentProvider(); + String textSelection = provider.getTextSelection(); + if (!StringUtils.isBlank(textSelection)) { + return true; + } + + return super.hasSelection(); + } } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerActionContext.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerActionContext.java index 57f0cf48fd..cd18f5865c 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerActionContext.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerActionContext.java @@ -15,6 +15,8 @@ */ package ghidra.app.plugin.core.decompile; +import org.apache.commons.lang3.StringUtils; + import ghidra.app.context.NavigatableActionContext; import ghidra.app.context.RestrictedAddressSetContext; import ghidra.app.decompiler.*; @@ -147,6 +149,18 @@ public class DecompilerActionContext extends NavigatableActionContext getComponentProvider().getController().setStatusMessage(msg); } + @Override + public boolean hasSelection() { + + DecompilerProvider provider = getComponentProvider(); + String textSelection = provider.getTextSelection(); + if (!StringUtils.isBlank(textSelection)) { + return true; + } + + return super.hasSelection(); + } + // allows this Decompiler action context to signal the location is on a function @Override protected Function getFunctionForLocation() { diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java index 2438e67e32..fef5e719e0 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java @@ -33,6 +33,7 @@ import ghidra.GhidraOptions; import ghidra.app.decompiler.*; import ghidra.app.decompiler.component.*; import ghidra.app.decompiler.component.margin.DecompilerMarginProvider; +import ghidra.app.events.ProgramSelectionPluginEvent; import ghidra.app.nav.*; import ghidra.app.plugin.core.decompile.actions.*; import ghidra.app.services.*; @@ -435,6 +436,20 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter } clipboardProvider.setSelection(selection); + notifySelectionChanged(selection); + } + + private void notifySelectionChanged(ProgramSelection selection) { + if (!isConnected()) { + return; + } + + if (selection == null) { + return; + } + + plugin.firePluginEvent( + new ProgramSelectionPluginEvent(plugin.getName(), selection, getProgram())); } @Override diff --git a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/action/FunctionGraphEditableVertexLocationActionContext.java b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/action/FunctionGraphEditableVertexLocationActionContext.java index 804f777ea0..4413f06b8e 100644 --- a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/action/FunctionGraphEditableVertexLocationActionContext.java +++ b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/action/FunctionGraphEditableVertexLocationActionContext.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,13 +15,15 @@ */ package ghidra.app.plugin.core.functiongraph.action; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; + import ghidra.app.context.ListingActionContext; import ghidra.app.context.RestrictedAddressSetContext; import ghidra.app.plugin.core.functiongraph.FGProvider; import ghidra.app.plugin.core.functiongraph.graph.vertex.FGVertex; -import java.util.Set; - public class FunctionGraphEditableVertexLocationActionContext extends ListingActionContext implements FunctionGraphVertexLocationContextIf, RestrictedAddressSetContext { @@ -52,4 +54,15 @@ public class FunctionGraphEditableVertexLocationActionContext extends ListingAct public Set getSelectedVertices() { return vertexInfo.getSelectedVertices(); } + + @Override + public boolean hasSelection() { + FGProvider provider = (FGProvider) getComponentProvider(); + String textSelection = provider.getTextSelection(); + if (!StringUtils.isBlank(textSelection)) { + return true; + } + + return super.hasSelection(); + } }