Updated the Clear Selection action to work in the Decompiler

Fixes #7241
This commit is contained in:
dragonmacher 2025-07-15 15:35:53 -04:00
parent 295f71472a
commit 5345960ac1
6 changed files with 81 additions and 24 deletions

View file

@ -15,7 +15,10 @@
*/ */
package ghidra.app.plugin.core.debug.gui.listing; package ghidra.app.plugin.core.debug.gui.listing;
import org.apache.commons.lang3.StringUtils;
import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingActionContext;
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.app.plugin.core.debug.gui.action.DebuggerProgramLocationActionContext; import ghidra.app.plugin.core.debug.gui.action.DebuggerProgramLocationActionContext;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
@ -41,4 +44,15 @@ public class DebuggerListingActionContext extends ListingActionContext
public TraceProgramView getProgram() { public TraceProgramView getProgram() {
return (TraceProgramView) super.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();
}
} }

View file

@ -17,14 +17,14 @@ package ghidra.app.plugin.core.codebrowser;
import javax.swing.Icon; import javax.swing.Icon;
import org.apache.commons.lang3.StringUtils;
import docking.ComponentProvider; import docking.ComponentProvider;
import docking.action.builder.ActionBuilder; import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import generic.theme.GIcon; import generic.theme.GIcon;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingActionContext;
import ghidra.app.context.NavigatableActionContext;
import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.codebrowser.SelectEndpointsAction.RangeEndpoint; import ghidra.app.plugin.core.codebrowser.SelectEndpointsAction.RangeEndpoint;
import ghidra.app.plugin.core.table.TableComponentProvider; import ghidra.app.plugin.core.table.TableComponentProvider;
@ -95,11 +95,13 @@ public class CodeBrowserSelectionPlugin extends Plugin {
.menuPath(ToolConstants.MENU_SELECTION, "&Clear Selection") .menuPath(ToolConstants.MENU_SELECTION, "&Clear Selection")
.menuGroup(SELECT_GROUP, "b") .menuGroup(SELECT_GROUP, "b")
.helpLocation(new HelpLocation(HelpTopics.SELECTION, "Clear Selection")) .helpLocation(new HelpLocation(HelpTopics.SELECTION, "Clear Selection"))
.withContext(ListingActionContext.class, true) .withContext(NavigatableActionContext.class, true)
.inWindow(ActionBuilder.When.CONTEXT_MATCHES) .inWindow(ActionBuilder.When.CONTEXT_MATCHES)
.enabledWhen(c -> hasSelection(c)) .enabledWhen(NavigatableActionContext::hasSelection)
.onAction(c -> ((CodeViewerProvider) c.getComponentProvider()) .onAction(c -> {
.setSelection(new ProgramSelection())) Navigatable n = c.getNavigatable();
n.setSelection(new ProgramSelection());
})
.buildAndInstall(tool); .buildAndInstall(tool);
new ActionBuilder("Select Complement", getName()) new ActionBuilder("Select Complement", getName())
@ -203,20 +205,6 @@ public class CodeBrowserSelectionPlugin extends Plugin {
return provider instanceof CodeViewerProvider; 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<Address> createTableModel(Program program, private GhidraProgramTableModel<Address> createTableModel(Program program,
CodeUnitIterator iterator, ProgramSelection selection) { CodeUnitIterator iterator, ProgramSelection selection) {

View file

@ -15,6 +15,8 @@
*/ */
package ghidra.app.plugin.core.codebrowser; package ghidra.app.plugin.core.codebrowser;
import org.apache.commons.lang3.StringUtils;
import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingActionContext;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
@ -27,4 +29,15 @@ public class CodeViewerActionContext extends ListingActionContext {
public CodeViewerActionContext(CodeViewerProvider provider, ProgramLocation location) { public CodeViewerActionContext(CodeViewerProvider provider, ProgramLocation location) {
super(provider, provider, 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();
}
} }

View file

@ -15,6 +15,8 @@
*/ */
package ghidra.app.plugin.core.decompile; package ghidra.app.plugin.core.decompile;
import org.apache.commons.lang3.StringUtils;
import ghidra.app.context.NavigatableActionContext; import ghidra.app.context.NavigatableActionContext;
import ghidra.app.context.RestrictedAddressSetContext; import ghidra.app.context.RestrictedAddressSetContext;
import ghidra.app.decompiler.*; import ghidra.app.decompiler.*;
@ -147,6 +149,18 @@ public class DecompilerActionContext extends NavigatableActionContext
getComponentProvider().getController().setStatusMessage(msg); 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 // allows this Decompiler action context to signal the location is on a function
@Override @Override
protected Function getFunctionForLocation() { protected Function getFunctionForLocation() {

View file

@ -33,6 +33,7 @@ import ghidra.GhidraOptions;
import ghidra.app.decompiler.*; import ghidra.app.decompiler.*;
import ghidra.app.decompiler.component.*; import ghidra.app.decompiler.component.*;
import ghidra.app.decompiler.component.margin.DecompilerMarginProvider; import ghidra.app.decompiler.component.margin.DecompilerMarginProvider;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.nav.*; import ghidra.app.nav.*;
import ghidra.app.plugin.core.decompile.actions.*; import ghidra.app.plugin.core.decompile.actions.*;
import ghidra.app.services.*; import ghidra.app.services.*;
@ -435,6 +436,20 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
} }
clipboardProvider.setSelection(selection); 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 @Override

View file

@ -15,13 +15,15 @@
*/ */
package ghidra.app.plugin.core.functiongraph.action; 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.ListingActionContext;
import ghidra.app.context.RestrictedAddressSetContext; import ghidra.app.context.RestrictedAddressSetContext;
import ghidra.app.plugin.core.functiongraph.FGProvider; import ghidra.app.plugin.core.functiongraph.FGProvider;
import ghidra.app.plugin.core.functiongraph.graph.vertex.FGVertex; import ghidra.app.plugin.core.functiongraph.graph.vertex.FGVertex;
import java.util.Set;
public class FunctionGraphEditableVertexLocationActionContext extends ListingActionContext public class FunctionGraphEditableVertexLocationActionContext extends ListingActionContext
implements FunctionGraphVertexLocationContextIf, RestrictedAddressSetContext { implements FunctionGraphVertexLocationContextIf, RestrictedAddressSetContext {
@ -52,4 +54,15 @@ public class FunctionGraphEditableVertexLocationActionContext extends ListingAct
public Set<FGVertex> getSelectedVertices() { public Set<FGVertex> getSelectedVertices() {
return vertexInfo.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();
}
} }