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;
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();
}
}

View file

@ -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<Address> createTableModel(Program program,
CodeUnitIterator iterator, ProgramSelection selection) {

View file

@ -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();
}
}

View file

@ -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() {

View file

@ -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

View file

@ -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<FGVertex> 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();
}
}