GP-3 - Updated Navigatable to have a notion of selected text; updated

the SearchTextPlugin to use this feature
This commit is contained in:
dragonmacher 2021-05-18 16:30:08 -04:00
parent 3cc2bc5b06
commit 15a78011e3
19 changed files with 162 additions and 40 deletions

View file

@ -418,6 +418,12 @@ class MergeNavigatable implements Navigatable {
@Override @Override
public void addNavigatableListener(NavigatableRemovalListener listener) { public void addNavigatableListener(NavigatableRemovalListener listener) {
// stub
}
@Override
public ProgramSelection getSelection() {
return mergePanel.getFocusedListingPanel().getProgramSelection();
} }
@Override @Override
@ -425,6 +431,11 @@ class MergeNavigatable implements Navigatable {
return mergePanel.getFocusedListingPanel().getProgramHighlight(); return mergePanel.getFocusedListingPanel().getProgramHighlight();
} }
@Override
public String getTextSelection() {
return mergePanel.getFocusedListingPanel().getTextSelection();
}
@Override @Override
public long getInstanceID() { public long getInstanceID() {
return 0; return 0;
@ -450,11 +461,6 @@ class MergeNavigatable implements Navigatable {
return mergePanel.getFocusedProgram(); return mergePanel.getFocusedProgram();
} }
@Override
public ProgramSelection getSelection() {
return mergePanel.getFocusedListingPanel().getProgramSelection();
}
@Override @Override
public boolean goTo(Program program, ProgramLocation location) { public boolean goTo(Program program, ProgramLocation location) {
mergePanel.goTo(location, true); mergePanel.goTo(location, true);

View file

@ -123,6 +123,12 @@ public interface Navigatable {
*/ */
public ProgramSelection getHighlight(); public ProgramSelection getHighlight();
/**
* Returns the current text selection or null
* @return the text selection
*/
public String getTextSelection();
/** /**
* Adds a listener to be notified if this Navigatable is terminated * Adds a listener to be notified if this Navigatable is terminated
* @param listener the listener to be notified when this Navigatable is closed * @param listener the listener to be notified when this Navigatable is closed

View file

@ -109,6 +109,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
private ProgramSelection currentSelection; private ProgramSelection currentSelection;
private ProgramSelection currentHighlight; private ProgramSelection currentHighlight;
private String currentStringSelection;
private FieldNavigator fieldNavigator; private FieldNavigator fieldNavigator;
@ -625,6 +626,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
@Override @Override
public void setStringSelection(String string) { public void setStringSelection(String string) {
this.currentStringSelection = string;
codeViewerClipboardProvider.setStringContent(string); codeViewerClipboardProvider.setStringContent(string);
contextChanged(); contextChanged();
} }
@ -808,6 +810,11 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
return currentHighlight; return currentHighlight;
} }
@Override
public String getTextSelection() {
return currentStringSelection;
}
@Override @Override
public Icon getIcon() { public Icon getIcon() {
if (isConnected()) { if (isConnected()) {

View file

@ -58,6 +58,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
/** /**
* Creates a new instance of the <CODE>GoToServicePlugin</CODE> * Creates a new instance of the <CODE>GoToServicePlugin</CODE>
* @param plugintool the tool
*/ */
public GoToServicePlugin(PluginTool plugintool) { public GoToServicePlugin(PluginTool plugintool) {
super(plugintool, true, true); super(plugintool, true, true);
@ -176,11 +177,13 @@ public final class GoToServicePlugin extends ProgramPlugin {
@Override @Override
public void addNavigatableListener(NavigatableRemovalListener listener) { public void addNavigatableListener(NavigatableRemovalListener listener) {
} // do nothing, default Navigatable never goes away // do nothing, default Navigatable never goes away
}
@Override @Override
public void removeNavigatableListener(NavigatableRemovalListener listener) { public void removeNavigatableListener(NavigatableRemovalListener listener) {
}// do nothing, default Navigatable never goes away // do nothing, default Navigatable never goes away
}
@Override @Override
public void setHighlight(ProgramSelection highlight) { public void setHighlight(ProgramSelection highlight) {
@ -209,6 +212,11 @@ public final class GoToServicePlugin extends ProgramPlugin {
return currentHighlight; return currentHighlight;
} }
@Override
public String getTextSelection() {
return null;
}
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);

View file

@ -476,9 +476,9 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
} }
CodeViewerService codeViewerService = tool.getService(CodeViewerService.class); CodeViewerService codeViewerService = tool.getService(CodeViewerService.class);
String textSelection = codeViewerService.getCurrentFieldTextSelection(); String textSelection = navigatable.getTextSelection();
ProgramLocation textField = codeViewerService.getCurrentLocation(); ProgramLocation location = codeViewerService.getCurrentLocation();
Address address = textField.getAddress(); Address address = location.getAddress();
Listing listing = context.getProgram().getListing(); Listing listing = context.getProgram().getListing();
CodeUnit codeUnit = listing.getCodeUnitAt(address); CodeUnit codeUnit = listing.getCodeUnitAt(address);
boolean isInstruction = false; boolean isInstruction = false;
@ -490,9 +490,9 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
else { else {
isInstruction = false; isInstruction = false;
} }
searchDialog.setValueFieldText(textSelection); searchDialog.setCurrentField(location, isInstruction);
searchDialog.setCurrentField(textField, isInstruction);
} }
searchDialog.setValueFieldText(textSelection);
} }
searchDialog.show(context.getComponentProvider()); searchDialog.show(context.getComponentProvider());
} }

View file

@ -15,6 +15,11 @@
*/ */
package ghidra.app.util.viewer.listingpanel; package ghidra.app.util.viewer.listingpanel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import ghidra.app.nav.*; import ghidra.app.nav.*;
import ghidra.app.services.GoToService; import ghidra.app.services.GoToService;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.HighlightProvider;
@ -23,11 +28,6 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.UniversalIdGenerator; import ghidra.util.UniversalIdGenerator;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
/** /**
* Navigator for the listings contained in a ListingCodeComparisonPanel. * Navigator for the listings contained in a ListingCodeComparisonPanel.
*/ */
@ -35,7 +35,7 @@ class DualListingNavigator implements Navigatable {
private final ListingPanel listingPanel; private final ListingPanel listingPanel;
private List<NavigatableRemovalListener> listeners = private List<NavigatableRemovalListener> listeners =
new ArrayList<NavigatableRemovalListener>(); new ArrayList<>();
private long id; private long id;
private GoToService goToService; private GoToService goToService;
@ -58,11 +58,21 @@ class DualListingNavigator implements Navigatable {
listeners.add(listener); listeners.add(listener);
} }
@Override
public ProgramSelection getSelection() {
return listingPanel.getProgramSelection();
}
@Override @Override
public ProgramSelection getHighlight() { public ProgramSelection getHighlight() {
return listingPanel.getProgramHighlight(); return listingPanel.getProgramHighlight();
} }
@Override
public String getTextSelection() {
return listingPanel.getTextSelection();
}
@Override @Override
public long getInstanceID() { public long getInstanceID() {
return id; return id;
@ -88,11 +98,6 @@ class DualListingNavigator implements Navigatable {
return listingPanel.getProgram(); return listingPanel.getProgram();
} }
@Override
public ProgramSelection getSelection() {
return listingPanel.getProgramSelection();
}
@Override @Override
public boolean goTo(Program program, ProgramLocation location) { public boolean goTo(Program program, ProgramLocation location) {
if (program != listingPanel.getProgram()) { if (program != listingPanel.getProgram()) {

View file

@ -91,6 +91,8 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
}; };
private List<ListingDisplayListener> displayListeners = new ArrayList<>(); private List<ListingDisplayListener> displayListeners = new ArrayList<>();
private String currentTextSelection;
/** /**
* Constructs a new ListingPanel using the given FormatManager and ServiceProvider. * Constructs a new ListingPanel using the given FormatManager and ServiceProvider.
* *
@ -1098,9 +1100,12 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
if (stringSelectionListener != null) { if (stringSelectionListener != null) {
stringSelectionListener.setStringSelection(text); stringSelectionListener.setStringSelection(text);
} }
currentTextSelection = text;
if (text != null) { if (text != null) {
return; return;
} }
if (trigger != EventTrigger.API_CALL) { if (trigger != EventTrigger.API_CALL) {
if (listingModel.getProgram() == null || programSelectionListener == null) { if (listingModel.getProgram() == null || programSelectionListener == null) {
return; return;
@ -1112,6 +1117,15 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
} }
} }
/**
* Returns the currently selected text. The value will only be non-null for selections within
* a single field.
* @return the selected text or null
*/
public String getTextSelection() {
return currentTextSelection;
}
public void enablePropertyBasedColorModel(boolean b) { public void enablePropertyBasedColorModel(boolean b) {
propertyBasedColorModel.setEnabled(b); propertyBasedColorModel.setEnabled(b);
} }

View file

@ -114,6 +114,12 @@ public class TestDummyNavigatable implements Navigatable {
return null; return null;
} }
@Override
public String getTextSelection() {
// stub
return null;
}
@Override @Override
public void addNavigatableListener(NavigatableRemovalListener listener) { public void addNavigatableListener(NavigatableRemovalListener listener) {
// stub // stub

View file

@ -160,6 +160,11 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
return currentHighlight; return currentHighlight;
} }
@Override
public String getTextSelection() {
return getTextSelection();
}
private void setSelection(ProgramSelection selection, boolean notify) { private void setSelection(ProgramSelection selection, boolean notify) {
currentSelection = selection; currentSelection = selection;
if (selection == null) { if (selection == null) {

View file

@ -889,6 +889,15 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
return null; return null;
} }
public String getTextSelection() {
FieldSelection selection = fieldPanel.getSelection();
if (selection.isEmpty()) {
return null;
}
return FieldSelectionHelper.getFieldSelectionText(selection, fieldPanel);
}
public ClangToken getTokenAtCursor() { public ClangToken getTokenAtCursor() {
FieldLocation cursorPosition = fieldPanel.getCursorLocation(); FieldLocation cursorPosition = fieldPanel.getCursorLocation();
Field field = fieldPanel.getCurrentField(); Field field = fieldPanel.getCurrentField();

View file

@ -480,6 +480,12 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
return null; return null;
} }
@Override
public String getTextSelection() {
DecompilerPanel decompilerPanel = controller.getDecompilerPanel();
return decompilerPanel.getTextSelection();
}
boolean isBusy() { boolean isBusy() {
return redecompileUpdater.isBusy() || controller.isDecompiling(); return redecompileUpdater.isBusy() || controller.isDecompiling();
} }

View file

@ -1193,6 +1193,22 @@ public class FGProvider extends VisualGraphComponentProvider<FGVertex, FGEdge, F
return new ProgramSelection(intersection); return new ProgramSelection(intersection);
} }
@Override
public String getTextSelection() {
FGData currentData = controller.getFunctionGraphData();
if (!currentData.hasResults()) {
return null;
}
FGVertex focusedVertex = controller.getFocusedVertex();
if (focusedVertex == null) {
return null;
}
return focusedVertex.getTextSelection();
}
@Override @Override
public boolean supportsHighlight() { public boolean supportsHighlight() {
return true; return true;

View file

@ -390,6 +390,11 @@ public abstract class AbstractFunctionGraphVertex implements FGVertex {
return doGetComponent().getProgramSelection(); return doGetComponent().getProgramSelection();
} }
@Override
public String getTextSelection() {
return doGetComponent().getTextSelection();
}
@Override @Override
public void setProgramHighlight(ProgramSelection highlight) { public void setProgramHighlight(ProgramSelection highlight) {
doGetComponent().setProgramHighlight(highlight); doGetComponent().setProgramHighlight(highlight);

View file

@ -121,6 +121,8 @@ public abstract class AbstractGraphComponentPanel extends JPanel {
abstract ProgramSelection getProgramSelection(); abstract ProgramSelection getProgramSelection();
abstract String getTextSelection();
abstract void setProgramHighlight(ProgramSelection highlight); abstract void setProgramHighlight(ProgramSelection highlight);
void setProgramLocation(ProgramLocation location) { void setProgramLocation(ProgramLocation location) {

View file

@ -134,6 +134,12 @@ public interface FGVertex extends VisualVertex {
public ProgramSelection getProgramSelection(); public ProgramSelection getProgramSelection();
/**
* Returns any selected text within the vertex that does not span multiple fields
* @return the text
*/
public String getTextSelection();
public void setProgramHighlight(ProgramSelection highlight); public void setProgramHighlight(ProgramSelection highlight);
public ProgramLocation getProgramLocation(); public ProgramLocation getProgramLocation();

View file

@ -539,6 +539,11 @@ public class GroupedFunctionGraphComponentPanel extends AbstractGraphComponentPa
return new ProgramSelection(addresses); return new ProgramSelection(addresses);
} }
@Override
String getTextSelection() {
return null; // can't select text in a group vertex
}
@Override @Override
void setProgramHighlight(ProgramSelection highlight) { void setProgramHighlight(ProgramSelection highlight) {
Set<FGVertex> vertices = groupVertex.getVertices(); Set<FGVertex> vertices = groupVertex.getVertices();

View file

@ -404,6 +404,11 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
return listingPanel.getProgramSelection(); return listingPanel.getProgramSelection();
} }
@Override
String getTextSelection() {
return listingPanel.getTextSelection();
}
@Override @Override
ProgramLocation getProgramLocation() { ProgramLocation getProgramLocation() {
return listingPanel.getProgramLocation(); return listingPanel.getProgramLocation();

View file

@ -15,6 +15,8 @@
*/ */
package ghidra.app.plugin.core.diff; package ghidra.app.plugin.core.diff;
import javax.swing.Icon;
import ghidra.app.nav.*; import ghidra.app.nav.*;
import ghidra.app.plugin.core.codebrowser.CodeViewerLocationMemento; import ghidra.app.plugin.core.codebrowser.CodeViewerLocationMemento;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.HighlightProvider;
@ -24,8 +26,6 @@ import ghidra.program.util.ProgramSelection;
import ghidra.util.datastruct.WeakDataStructureFactory; import ghidra.util.datastruct.WeakDataStructureFactory;
import ghidra.util.datastruct.WeakSet; import ghidra.util.datastruct.WeakSet;
import javax.swing.Icon;
/** /**
* This is a navigatable for use by the right-hand listing of the Diff. * This is a navigatable for use by the right-hand listing of the Diff.
* It should navigate within the Diff's listing, which would then reposition * It should navigate within the Diff's listing, which would then reposition
@ -140,6 +140,11 @@ class DiffNavigatable implements Navigatable {
return navigatable.getHighlight(); return navigatable.getHighlight();
} }
@Override
public String getTextSelection() {
return navigatable.getTextSelection();
}
@Override @Override
public void addNavigatableListener(NavigatableRemovalListener listener) { public void addNavigatableListener(NavigatableRemovalListener listener) {
navigationListeners.add(listener); navigationListeners.add(listener);

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +15,11 @@
*/ */
package ghidra.feature.vt.gui.duallisting; package ghidra.feature.vt.gui.duallisting;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import ghidra.app.nav.*; import ghidra.app.nav.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.HighlightProvider;
import ghidra.app.util.viewer.listingpanel.ListingCodeComparisonPanel; import ghidra.app.util.viewer.listingpanel.ListingCodeComparisonPanel;
@ -25,20 +29,16 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.UniversalIdGenerator; import ghidra.util.UniversalIdGenerator;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
public class VTListingNavigator implements Navigatable { public class VTListingNavigator implements Navigatable {
private final ListingCodeComparisonPanel dualListingPanel; private final ListingCodeComparisonPanel dualListingPanel;
private final ListingPanel listingPanel; private final ListingPanel listingPanel;
private List<NavigatableRemovalListener> listeners = private List<NavigatableRemovalListener> listeners =
new ArrayList<NavigatableRemovalListener>(); new ArrayList<>();
private long id; private long id;
public VTListingNavigator(ListingCodeComparisonPanel dualListingPanel, ListingPanel listingPanel) { public VTListingNavigator(ListingCodeComparisonPanel dualListingPanel,
ListingPanel listingPanel) {
this.dualListingPanel = dualListingPanel; this.dualListingPanel = dualListingPanel;
this.listingPanel = listingPanel; this.listingPanel = listingPanel;
@ -50,11 +50,21 @@ public class VTListingNavigator implements Navigatable {
listeners.add(listener); listeners.add(listener);
} }
@Override
public ProgramSelection getSelection() {
return listingPanel.getProgramSelection();
}
@Override @Override
public ProgramSelection getHighlight() { public ProgramSelection getHighlight() {
return listingPanel.getProgramHighlight(); return listingPanel.getProgramHighlight();
} }
@Override
public String getTextSelection() {
return listingPanel.getTextSelection();
}
@Override @Override
public long getInstanceID() { public long getInstanceID() {
return id; return id;
@ -80,11 +90,6 @@ public class VTListingNavigator implements Navigatable {
return listingPanel.getProgram(); return listingPanel.getProgram();
} }
@Override
public ProgramSelection getSelection() {
return listingPanel.getProgramSelection();
}
@Override @Override
public boolean goTo(Program program, ProgramLocation location) { public boolean goTo(Program program, ProgramLocation location) {
boolean went = listingPanel.goTo(location); boolean went = listingPanel.goTo(location);
@ -133,6 +138,7 @@ public class VTListingNavigator implements Navigatable {
@Override @Override
public void setMemento(LocationMemento memento) { public void setMemento(LocationMemento memento) {
// unsupported
} }
@Override @Override