GP-3329 - Search Highlights - Major update and refactor of the way Listing highlights work. Highlights are now more closely coupled with the fields that will paint them.

This commit is contained in:
dragonmacher 2023-04-21 12:43:42 -04:00
parent a21c2c4347
commit 84650030d0
130 changed files with 1096 additions and 919 deletions

View file

@ -21,7 +21,7 @@ import docking.widgets.fieldpanel.field.AttributedString;
import docking.widgets.fieldpanel.field.TextFieldElement; import docking.widgets.fieldpanel.field.TextFieldElement;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -50,14 +50,14 @@ public class TaintFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
protected TaintFieldFactory(FieldFormatModel formatModel, HighlightProvider highlightProvider, protected TaintFieldFactory(FieldFormatModel formatModel, ListingHighlightProvider highlightProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, formatModel, highlightProvider, displayOptions, fieldOptions); super(FIELD_NAME, formatModel, highlightProvider, displayOptions, fieldOptions);
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions displayOptions, ListingHighlightProvider highlightProvider, ToolOptions displayOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new TaintFieldFactory(formatModel, highlightProvider, displayOptions, fieldOptions); return new TaintFieldFactory(formatModel, highlightProvider, displayOptions, fieldOptions);
} }

View file

@ -23,7 +23,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -61,7 +61,7 @@ public class ExternalDisassemblyFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private ExternalDisassemblyFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private ExternalDisassemblyFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -96,7 +96,7 @@ public class ExternalDisassemblyFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) { ListingHighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) {
return new ExternalDisassemblyFieldFactory(formatModel, highlightProvider, options, return new ExternalDisassemblyFieldFactory(formatModel, highlightProvider, options,
fieldOptions); fieldOptions);
} }

View file

@ -21,7 +21,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
@ -52,7 +52,7 @@ public class EntropyFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private EntropyFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private EntropyFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -154,7 +154,7 @@ public class EntropyFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel myModel, HighlightProvider myHlProvider, public FieldFactory newInstance(FieldFormatModel myModel, ListingHighlightProvider myHlProvider,
ToolOptions displayOptions1, ToolOptions fieldOptions) { ToolOptions displayOptions1, ToolOptions fieldOptions) {
return new EntropyFieldFactory(myModel, myHlProvider, displayOptions1, fieldOptions); return new EntropyFieldFactory(myModel, myHlProvider, displayOptions1, fieldOptions);
} }

View file

@ -29,7 +29,7 @@ import ghidra.app.merge.tool.ListingMergePanelPlugin;
import ghidra.app.merge.tree.ProgramTreeMergeManager; import ghidra.app.merge.tree.ProgramTreeMergeManager;
import ghidra.app.nav.*; import ghidra.app.nav.*;
import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin; import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.util.FieldNavigator; import ghidra.app.util.viewer.util.FieldNavigator;
import ghidra.framework.model.UndoableDomainObject; import ghidra.framework.model.UndoableDomainObject;
import ghidra.framework.plugintool.ModalPluginTool; import ghidra.framework.plugintool.ModalPluginTool;
@ -516,12 +516,12 @@ class MergeNavigatable implements Navigatable {
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// currently unsupported // currently unsupported
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, Program program) { public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// currently unsupported // currently unsupported
} }

View file

@ -17,7 +17,7 @@ package ghidra.app.nav;
import javax.swing.Icon; import javax.swing.Icon;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
@ -185,7 +185,7 @@ public interface Navigatable {
* @param highlightProvider the provider * @param highlightProvider the provider
* @param program the program * @param program the program
*/ */
public void setHighlightProvider(HighlightProvider highlightProvider, Program program); public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program);
/** /**
* Removes the given highlight provider for the given program * Removes the given highlight provider for the given program
@ -193,5 +193,5 @@ public interface Navigatable {
* @param highlightProvider the provider * @param highlightProvider the provider
* @param program the program * @param program the program
*/ */
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program); public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program);
} }

View file

@ -38,7 +38,7 @@ import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService; import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.ProgramDropProvider; import ghidra.app.util.ProgramDropProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.*; import ghidra.app.util.viewer.format.*;
@ -322,13 +322,13 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, public void removeHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
connectedProvider.removeHighlightProvider(highlightProvider, highlightProgram); connectedProvider.removeHighlightProvider(highlightProvider, highlightProgram);
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, public void setHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
connectedProvider.setHighlightProvider(highlightProvider, highlightProgram); connectedProvider.setHighlightProvider(highlightProvider, highlightProgram);
} }

View file

@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -44,7 +44,7 @@ import ghidra.app.plugin.core.codebrowser.actions.*;
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService; import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.format.*; import ghidra.app.util.viewer.format.*;
import ghidra.app.util.viewer.listingpanel.*; import ghidra.app.util.viewer.listingpanel.*;
import ghidra.app.util.viewer.multilisting.MultiListingLayoutModel; import ghidra.app.util.viewer.multilisting.MultiListingLayoutModel;
@ -79,7 +79,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
private static final String DIVIDER_LOCATION = "DividerLocation"; private static final String DIVIDER_LOCATION = "DividerLocation";
private ImageIcon navigatableIcon; private ImageIcon navigatableIcon;
private Map<Program, HighlightProvider> programHighlighterMap = new HashMap<>(); private Map<Program, ListingHighlightProvider> programHighlighterMap = new HashMap<>();
private ProgramHighlighterProvider highlighterAdapter; private ProgramHighlighterProvider highlighterAdapter;
private ListingPanel listingPanel; private ListingPanel listingPanel;
@ -144,7 +144,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
listingPanel = new ListingPanel(formatMgr); listingPanel = new ListingPanel(formatMgr);
listingPanel.enablePropertyBasedColorModel(true); listingPanel.enablePropertyBasedColorModel(true);
decorationPanel = new ListingPanelContainer(listingPanel, isConnected); decorationPanel = new ListingPanelContainer(listingPanel, isConnected);
ListingHighlightProvider listingHighlighter = ListingMiddleMouseHighlightProvider listingHighlighter =
createListingHighlighter(listingPanel, tool, decorationPanel); createListingHighlighter(listingPanel, tool, decorationPanel);
highlighterAdapter = new ProgramHighlighterProvider(listingHighlighter); highlighterAdapter = new ProgramHighlighterProvider(listingHighlighter);
listingPanel.addHighlightProvider(highlighterAdapter); listingPanel.addHighlightProvider(highlighterAdapter);
@ -194,10 +194,10 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
return false; return false;
} }
private ListingHighlightProvider createListingHighlighter(ListingPanel panel, private ListingMiddleMouseHighlightProvider createListingHighlighter(ListingPanel panel,
PluginTool pluginTool, Component repaintComponent) { PluginTool pluginTool, Component repaintComponent) {
ListingHighlightProvider listingHighlighter = ListingMiddleMouseHighlightProvider listingHighlighter =
new ListingHighlightProvider(pluginTool, repaintComponent); new ListingMiddleMouseHighlightProvider(pluginTool, repaintComponent);
panel.addButtonPressedListener(listingHighlighter); panel.addButtonPressedListener(listingHighlighter);
return listingHighlighter; return listingHighlighter;
} }
@ -398,14 +398,14 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, public void removeHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
programHighlighterMap.remove(highlightProgram); programHighlighterMap.remove(highlightProgram);
updateHighlightProvider(); updateHighlightProvider();
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, public void setHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
programHighlighterMap.put(highlightProgram, highlightProvider); programHighlighterMap.put(highlightProgram, highlightProvider);
updateHighlightProvider(); updateHighlightProvider();
@ -1105,23 +1105,23 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
* A class that allows clients to install transient highlighters while keeping the middle-mouse * A class that allows clients to install transient highlighters while keeping the middle-mouse
* highlighting on at the same time. * highlighting on at the same time.
*/ */
private class ProgramHighlighterProvider implements HighlightProvider { private class ProgramHighlighterProvider implements ListingHighlightProvider {
private final ListingHighlightProvider listingHighlighter; private final ListingMiddleMouseHighlightProvider listingHighlighter;
ProgramHighlighterProvider(ListingHighlightProvider listingHighlighter) { ProgramHighlighterProvider(ListingMiddleMouseHighlightProvider listingHighlighter) {
this.listingHighlighter = listingHighlighter; this.listingHighlighter = listingHighlighter;
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
List<Highlight> list = new ArrayList<>(); List<Highlight> list = new ArrayList<>();
HighlightProvider currentExternalHighligter = programHighlighterMap.get(program); ListingHighlightProvider currentExternalHighligter =
programHighlighterMap.get(program);
if (currentExternalHighligter != null) { if (currentExternalHighligter != null) {
Highlight[] highlights = currentExternalHighligter.getHighlights(text, obj, Highlight[] highlights = currentExternalHighligter.createHighlights(text, field,
fieldFactoryClass, cursorTextOffset); cursorTextOffset);
for (Highlight highlight : highlights) { for (Highlight highlight : highlights) {
list.add(highlight); list.add(highlight);
} }
@ -1130,7 +1130,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
// always call the listing highlighter last so the middle-mouse highlight will always // always call the listing highlighter last so the middle-mouse highlight will always
// be on top of other highlights // be on top of other highlights
Highlight[] highlights = Highlight[] highlights =
listingHighlighter.getHighlights(text, obj, fieldFactoryClass, cursorTextOffset); listingHighlighter.createHighlights(text, field, cursorTextOffset);
for (Highlight highlight : highlights) { for (Highlight highlight : highlights) {
list.add(highlight); list.add(highlight);
} }

View file

@ -34,8 +34,9 @@ import ghidra.GhidraOptions;
import ghidra.GhidraOptions.CURSOR_MOUSE_BUTTON_NAMES; import ghidra.GhidraOptions.CURSOR_MOUSE_BUTTON_NAMES;
import ghidra.app.plugin.processors.generic.PcodeFieldFactory; import ghidra.app.plugin.processors.generic.PcodeFieldFactory;
import ghidra.app.services.ButtonPressedListener; import ghidra.app.services.ButtonPressedListener;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@ -50,8 +51,8 @@ import ghidra.program.util.*;
import ghidra.util.*; import ghidra.util.*;
import ghidra.util.datastruct.Stack; import ghidra.util.datastruct.Stack;
public class ListingHighlightProvider public class ListingMiddleMouseHighlightProvider
implements ButtonPressedListener, OptionsChangeListener, HighlightProvider { implements ButtonPressedListener, OptionsChangeListener, ListingHighlightProvider {
//@formatter:off //@formatter:off
private static final GColor DEFAULT_HIGHLIGHT_COLOR = new GColor("color.bg.listing.highlighter.default"); private static final GColor DEFAULT_HIGHLIGHT_COLOR = new GColor("color.bg.listing.highlighter.default");
private static final GColor DEFAULT_SCOPED_READ_COLOR = new GColor("color.bg.listing.highlighter.scoped.read"); private static final GColor DEFAULT_SCOPED_READ_COLOR = new GColor("color.bg.listing.highlighter.scoped.read");
@ -87,7 +88,7 @@ public class ListingHighlightProvider
private final Component repaintComponent; private final Component repaintComponent;
private final PluginTool tool; private final PluginTool tool;
public ListingHighlightProvider(PluginTool tool, Component repaintComponent) { public ListingMiddleMouseHighlightProvider(PluginTool tool, Component repaintComponent) {
this.tool = tool; this.tool = tool;
this.repaintComponent = repaintComponent; this.repaintComponent = repaintComponent;
@ -102,8 +103,11 @@ public class ListingHighlightProvider
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
if (scopeRegisterHighlight && scope != null) { if (scopeRegisterHighlight && scope != null) {
if (fieldFactoryClass == VariableNameFieldFactory.class || if (fieldFactoryClass == VariableNameFieldFactory.class ||
fieldFactoryClass == VariableLocFieldFactory.class) { fieldFactoryClass == VariableLocFieldFactory.class) {

View file

@ -22,7 +22,7 @@ import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.cmd.function.CallDepthChangeInfo; import ghidra.app.cmd.function.CallDepthChangeInfo;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -44,13 +44,13 @@ public class StackDepthFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private StackDepthFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private StackDepthFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel newModel, HighlightProvider highlightProvider, public FieldFactory newInstance(FieldFormatModel newModel, ListingHighlightProvider highlightProvider,
ToolOptions toolDisplayOptions, ToolOptions fieldOptions) { ToolOptions toolDisplayOptions, ToolOptions fieldOptions) {
return new StackDepthFieldFactory(newModel, highlightProvider, toolDisplayOptions, return new StackDepthFieldFactory(newModel, highlightProvider, toolDisplayOptions,
fieldOptions); fieldOptions);

View file

@ -24,7 +24,7 @@ import ghidra.app.nav.*;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.PluginConstants; import ghidra.app.util.PluginConstants;
import ghidra.app.util.navigation.GoToServiceImpl; import ghidra.app.util.navigation.GoToServiceImpl;
import ghidra.app.util.query.TableService; import ghidra.app.util.query.TableService;
@ -225,7 +225,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
if (service != null) { if (service != null) {
service.removeHighlightProvider(highlightProvider, program); service.removeHighlightProvider(highlightProvider, program);
@ -233,7 +233,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, Program program) { public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
if (service != null) { if (service != null) {
service.setHighlightProvider(highlightProvider, program); service.setHighlightProvider(highlightProvider, program);

View file

@ -22,8 +22,9 @@ import generic.theme.GColor;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@ -51,7 +52,7 @@ class LocationReferencesHighlighter {
private LocationReferencesProvider provider; private LocationReferencesProvider provider;
private LocationReferencesPlugin locationReferencesPlugin; private LocationReferencesPlugin locationReferencesPlugin;
private HighlightProvider highlightProvider; private ListingHighlightProvider highlightProvider;
private MarkerRemover markerRemover; private MarkerRemover markerRemover;
private Color highlightColor; private Color highlightColor;
private OptionsChangeListener optionsListener = (options, name, oldValue, newValue) -> { private OptionsChangeListener optionsListener = (options, name, oldValue, newValue) -> {
@ -211,19 +212,20 @@ class LocationReferencesHighlighter {
// Inner Classes // Inner Classes
//================================================================================================== //==================================================================================================
private class LocationReferencesHighlightProvider implements HighlightProvider { private class LocationReferencesHighlightProvider implements ListingHighlightProvider {
private final Highlight[] NO_HIGHLIGHTS = new Highlight[0]; private final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
// for the Class parameter
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
if (text == null) { if (text == null) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
LocationDescriptor locationDescriptor = provider.getLocationDescriptor(); LocationDescriptor locationDescriptor = provider.getLocationDescriptor();
return locationDescriptor.getHighlights(text, obj, fieldFactoryClass, highlightColor); ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
return locationDescriptor.getHighlights(text, obj, field.getFieldFactory().getClass(),
highlightColor);
} }
} }

View file

@ -40,8 +40,8 @@ import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.query.TableService; import ghidra.app.util.query.TableService;
import ghidra.app.util.viewer.field.BytesFieldFactory; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.options.*; import ghidra.framework.options.*;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
@ -83,8 +83,6 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
/** Constant for read/writeConfig() for dialog options */ /** Constant for read/writeConfig() for dialog options */
private static final String SHOW_ADVANCED_OPTIONS = "Show Advanced Options"; private static final String SHOW_ADVANCED_OPTIONS = "Show Advanced Options";
final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
private static final int MAX_PRE_POPULTATE_BYTE_COUNT = 20; private static final int MAX_PRE_POPULTATE_BYTE_COUNT = 20;
private DockingAction searchAction; private DockingAction searchAction;
@ -334,7 +332,6 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
@Override @Override
public void setSearchText(String maskedString) { public void setSearchText(String maskedString) {
//sets the search value to a bit string provided by the MnemonicSearchPlugin
searchDialog.setSearchText(maskedString); searchDialog.setSearchText(maskedString);
} }
@ -613,7 +610,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
} }
private abstract class SearchResultsHighlighter private abstract class SearchResultsHighlighter
implements HighlightProvider, ComponentProviderActivationListener { implements ListingHighlightProvider, ComponentProviderActivationListener {
private TableComponentProvider<MemSearchResult> provider; private TableComponentProvider<MemSearchResult> provider;
private Program highlightProgram; private Program highlightProgram;
@ -688,16 +685,20 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Program program = navigatable != null ? navigatable.getProgram() : null; Program program = navigatable != null ? navigatable.getProgram() : null;
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
if (fieldFactoryClass != BytesFieldFactory.class) { if (fieldFactoryClass != BytesFieldFactory.class) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (checkRemoveHighlights()) { if (checkRemoveHighlights()) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (!(obj instanceof CodeUnit)) {
ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
if (!(obj instanceof CodeUnit cu)) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (!doHighlight) { if (!doHighlight) {
@ -708,7 +709,6 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
CodeUnit cu = (CodeUnit) obj;
Address minAddr = cu.getMinAddress(); Address minAddr = cu.getMinAddress();
Address maxAddr = cu.getMaxAddress(); Address maxAddr = cu.getMaxAddress();
List<MemSearchResult> results = getAddressesFoundInRange(minAddr, maxAddr); List<MemSearchResult> results = getAddressesFoundInRange(minAddr, maxAddr);

View file

@ -16,6 +16,7 @@
package ghidra.app.plugin.core.searchtext; package ghidra.app.plugin.core.searchtext;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.app.util.PluginConstants; import ghidra.app.util.PluginConstants;
import ghidra.app.util.query.ProgramLocationPreviewTableModel; import ghidra.app.util.query.ProgramLocationPreviewTableModel;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -58,11 +59,11 @@ public abstract class AbstractSearchTableModel extends ProgramLocationPreviewTab
throws CancelledException { throws CancelledException {
Searcher searcher = getSearcher(tool, monitor); Searcher searcher = getSearcher(tool, monitor);
monitor.checkCanceled(); monitor.checkCanceled();
ProgramLocation loc = searcher.search(); TextSearchResult result = searcher.search();
while (loc != null && accumulator.size() < searchLimit) { while (result != null && accumulator.size() < searchLimit) {
accumulator.add(loc); accumulator.add(result.programLocation());
monitor.checkCanceled(); monitor.checkCanceled();
loc = searcher.search(); result = searcher.search();
} }
} }

View file

@ -63,8 +63,8 @@ class ListingDisplaySearcher implements Searcher {
private AddressSetView searchAddresses; private AddressSetView searchAddresses;
private TaskMonitor monitor; private TaskMonitor monitor;
private List<ProgramLocation> locationList; private List<TextSearchResult> results;
private ListIterator<ProgramLocation> locationIterator; private ListIterator<TextSearchResult> locationIterator;
private ProgramLocation startLocation; private ProgramLocation startLocation;
private int startIndex; private int startIndex;
@ -103,8 +103,8 @@ class ListingDisplaySearcher implements Searcher {
searchPattern = searchPattern =
UserSearchUtils.createSearchPattern(options.getText(), options.isCaseSensitive()); UserSearchUtils.createSearchPattern(options.getText(), options.isCaseSensitive());
locationList = new ArrayList<>(); results = new ArrayList<>();
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
listingModel = service.getListingModel(); listingModel = service.getListingModel();
@ -175,34 +175,34 @@ class ListingDisplaySearcher implements Searcher {
return iterators.toArray(new AddressIterator[iterators.size()]); return iterators.toArray(new AddressIterator[iterators.size()]);
} }
ProgramLocation next() { TextSearchResult next() {
if (locationList.size() == 0) { if (results.size() == 0) {
findNext(); findNext();
} }
boolean isForward = options.isForward(); boolean isForward = options.isForward();
if (isForward && locationIterator.hasNext()) { if (isForward && locationIterator.hasNext()) {
ProgramLocation loc = locationIterator.next(); TextSearchResult result = locationIterator.next();
if (!locationIterator.hasNext()) { if (!locationIterator.hasNext()) {
locationList.clear(); results.clear();
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
} }
return loc; return result;
} }
if (!isForward && locationIterator.hasPrevious()) { if (!isForward && locationIterator.hasPrevious()) {
ProgramLocation loc = locationIterator.previous(); TextSearchResult result = locationIterator.previous();
if (!locationIterator.hasPrevious()) { if (!locationIterator.hasPrevious()) {
locationList.clear(); results.clear();
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
} }
return loc; return result;
} }
return null; return null;
} }
boolean hasNext() { boolean hasNext() {
if (locationList.size() == 0) { if (results.size() == 0) {
findNext(); findNext();
} }
return options.isForward() ? locationIterator.hasNext() : locationIterator.hasPrevious(); return options.isForward() ? locationIterator.hasNext() : locationIterator.hasPrevious();
@ -214,7 +214,7 @@ class ListingDisplaySearcher implements Searcher {
} }
@Override @Override
public ProgramLocation search() { public TextSearchResult search() {
try { try {
if (hasNext()) { if (hasNext()) {
return next(); return next();
@ -245,7 +245,7 @@ class ListingDisplaySearcher implements Searcher {
private void findNext() { private void findNext() {
if (currentLayout != null) { if (currentLayout != null) {
findNextMatch(); findNextMatch();
if (locationList.size() > 0) { if (results.size() > 0) {
return; return;
} }
} }
@ -256,7 +256,7 @@ class ListingDisplaySearcher implements Searcher {
currentCodeUnit = null; currentCodeUnit = null;
Listing listing = program.getListing(); Listing listing = program.getListing();
while (!monitor.isCancelled() && currentLayout == null && addressIterator.hasNext() && while (!monitor.isCancelled() && currentLayout == null && addressIterator.hasNext() &&
locationList.size() == 0) { results.size() == 0) {
currentAddress = addressIterator.next(); currentAddress = addressIterator.next();
monitor.setMessage("Checking address " + currentAddress); monitor.setMessage("Checking address " + currentAddress);
@ -287,14 +287,14 @@ class ListingDisplaySearcher implements Searcher {
} }
if (options.isForward()) { if (options.isForward()) {
while (!monitor.isCancelled() && locationList.size() == 0 && while (!monitor.isCancelled() && results.size() == 0 &&
currentLayout != null && currentFieldIndex < currentLayout.getNumFields()) { currentLayout != null && currentFieldIndex < currentLayout.getNumFields()) {
findNextMatch(); findNextMatch();
} }
} }
else { else {
currentFieldIndex = currentLayout.getNumFields() - 1; currentFieldIndex = currentLayout.getNumFields() - 1;
while (!monitor.isCancelled() && locationList.size() == 0 && while (!monitor.isCancelled() && results.size() == 0 &&
currentLayout != null && currentFieldIndex >= 0) { currentLayout != null && currentFieldIndex >= 0) {
findNextMatch(); findNextMatch();
} }
@ -372,7 +372,7 @@ class ListingDisplaySearcher implements Searcher {
findLocations(field); findLocations(field);
} }
if (locationList.size() > 0) { if (results.size() > 0) {
// we found a match! // we found a match!
return fieldCount; return fieldCount;
} }
@ -529,7 +529,9 @@ class ListingDisplaySearcher implements Searcher {
if (index == mnemonicLength) { if (index == mnemonicLength) {
col++; col++;
} }
locationList.add(fieldFactory.getProgramLocation(rc.row(), col, mnemonicField));
ProgramLocation loc = fieldFactory.getProgramLocation(rc.row(), col, mnemonicField);
results.add(new TextSearchResult(loc, index));
} }
adjustIterator(); adjustIterator();
@ -559,8 +561,8 @@ class ListingDisplaySearcher implements Searcher {
RowColLocation rc = field.textOffsetToScreenLocation(index); RowColLocation rc = field.textOffsetToScreenLocation(index);
FieldFactory fieldFactory = field.getFieldFactory(); FieldFactory fieldFactory = field.getFieldFactory();
ProgramLocation loc = fieldFactory.getProgramLocation(rc.row(), rc.col(), field); ProgramLocation loc = fieldFactory.getProgramLocation(rc.row(), rc.col(), field);
if ((loc != null) && !isSameLocation(loc)) { // loc will be null if field is clipped. if ((loc != null) && !isSameLocation(loc)) { // loc will be null if field is clipped.
locationList.add(loc); results.add(new TextSearchResult(loc, index));
} }
} }
@ -570,7 +572,7 @@ class ListingDisplaySearcher implements Searcher {
} }
private void adjustIterator() { private void adjustIterator() {
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
if (!options.isForward()) { if (!options.isForward()) {
// position iterator to end so that previous() will work // position iterator to end so that previous() will work
while (locationIterator.hasNext()) { while (locationIterator.hasNext()) {

View file

@ -16,9 +16,9 @@
package ghidra.app.plugin.core.searchtext; package ghidra.app.plugin.core.searchtext;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.framework.model.DomainObjectException; import ghidra.framework.model.DomainObjectException;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.task.Task; import ghidra.util.task.Task;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@ -30,7 +30,7 @@ class SearchTask extends Task {
private Searcher textSearcher; private Searcher textSearcher;
private Navigatable navigatable; private Navigatable navigatable;
private ProgramLocation loc; private TextSearchResult result;
private boolean isCanceled; private boolean isCanceled;
private Program program; private Program program;
@ -59,7 +59,7 @@ class SearchTask extends Task {
monitor.setMessage("Searching..."); monitor.setMessage("Searching...");
textSearcher.setMonitor(monitor); textSearcher.setMonitor(monitor);
try { try {
loc = textSearcher.search(); result = textSearcher.search();
} }
catch (Exception e) { catch (Exception e) {
if (!(e instanceof DomainObjectException)) { if (!(e instanceof DomainObjectException)) {
@ -76,8 +76,8 @@ class SearchTask extends Task {
return navigatable; return navigatable;
} }
ProgramLocation getSearchLocation() { TextSearchResult getSearchLocation() {
return loc; return result;
} }
/** /**

View file

@ -15,8 +15,7 @@
*/ */
package ghidra.app.plugin.core.searchtext; package ghidra.app.plugin.core.searchtext;
import java.awt.Component; import java.awt.*;
import java.awt.KeyboardFocusManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -24,6 +23,8 @@ import java.util.regex.Pattern;
import javax.swing.Icon; import javax.swing.Icon;
import org.apache.commons.lang3.StringUtils;
import docking.*; import docking.*;
import docking.action.builder.ActionBuilder; import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
@ -37,13 +38,16 @@ import ghidra.app.nav.Navigatable;
import ghidra.app.nav.NavigatableRemovalListener; import ghidra.app.nav.NavigatableRemovalListener;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearchTableModel; import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearchTableModel;
import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearcher; import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearcher;
import ghidra.app.plugin.core.table.TableComponentProvider; import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.services.*; import ghidra.app.services.GoToService;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.query.TableService; import ghidra.app.util.query.TableService;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
@ -83,7 +87,7 @@ import ghidra.util.task.*;
"on the entire program. Multiple matches are displayed " + "on the entire program. Multiple matches are displayed " +
"in a query results table. An option allows the search results " + "in a query results table. An option allows the search results " +
"to be highlighted in the Code Browser.", "to be highlighted in the Code Browser.",
servicesRequired = { ProgramManager.class, GoToService.class, CodeViewerService.class /*, TableService.class */ } servicesRequired = { ProgramManager.class, GoToService.class }
) )
//@formatter:on //@formatter:on
public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeListener, TaskListener, public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeListener, TaskListener,
@ -92,7 +96,6 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
private static final Icon SEARCH_MARKER_ICON = new GIcon("icon.base.search.marker"); private static final Icon SEARCH_MARKER_ICON = new GIcon("icon.base.search.marker");
private static final String DESCRIPTION = "Search program text for string"; private static final String DESCRIPTION = "Search program text for string";
private final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
private boolean waitingForSearchAll; private boolean waitingForSearchAll;
private SearchTextDialog searchDialog; private SearchTextDialog searchDialog;
@ -142,20 +145,22 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
return; return;
} }
ProgramLocation loc = searchTask.getSearchLocation(); TextSearchResult result = searchTask.getSearchLocation();
Searcher textSearcher = searchTask.getTextSearcher(); Searcher textSearcher = searchTask.getTextSearcher();
SearchOptions searchOptions = textSearcher.getSearchOptions(); SearchOptions searchOptions = textSearcher.getSearchOptions();
if (loc != null && loc.equals(currentLocation)) { if (result == null) {
searchDialog.setStatusText("Not found");
}
else if (result.programLocation().equals(currentLocation)) {
searchNext(searchTask.getProgram(), searchNavigatable, textSearcher); searchNext(searchTask.getProgram(), searchNavigatable, textSearcher);
} }
else if (loc != null) {
searchDialog.setStatusText("");
if (goToService.goTo(searchNavigatable, loc, program)) {
new HighlightHandler(searchNavigatable, searchOptions, null, program, loc);
}
}
else { else {
searchDialog.setStatusText("Not found"); searchDialog.setStatusText("");
ProgramLocation loc = result.programLocation();
if (goToService.goTo(searchNavigatable, loc, program)) {
new SearchTextHighlightProvider(searchNavigatable, searchOptions, null, program,
result);
}
} }
lastSearchedText = searchOptions.getText(); lastSearchedText = searchOptions.getText();
@ -324,7 +329,8 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
searchAllTaskMonitor = tablePanel.getTaskMonitor(); searchAllTaskMonitor = tablePanel.getTaskMonitor();
tableProvider.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "SearchAllResults")); tableProvider.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "SearchAllResults"));
new HighlightHandler(searchNavigatable, searchOptions, tableProvider, searchProgram, null); new SearchTextHighlightProvider(searchNavigatable, searchOptions, tableProvider,
searchProgram, null);
} }
private TableComponentProvider<ProgramLocation> getTableResultsProvider( private TableComponentProvider<ProgramLocation> getTableResultsProvider(
@ -593,20 +599,26 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
} }
} }
class HighlightHandler implements HighlightProvider, ComponentProviderActivationListener { private class SearchTextHighlightProvider
implements ListingHighlightProvider, ComponentProviderActivationListener {
private SearchOptions searchOptions; private SearchOptions searchOptions;
private TableComponentProvider<?> provider; private TableComponentProvider<?> provider;
private Program highlightProgram; private Program highlightProgram;
private final Navigatable highlightNavigatable; private final Navigatable highlightNavigatable;
private ProgramLocation loc; private boolean showAllResults;
HighlightHandler(Navigatable navigatable, SearchOptions searchOptions, // this is non-null for a single search
TableComponentProvider<?> provider, Program program, ProgramLocation loc) { private TextSearchResult searchResult;
SearchTextHighlightProvider(Navigatable navigatable, SearchOptions searchOptions,
TableComponentProvider<?> provider, Program program,
TextSearchResult searchResult) {
highlightNavigatable = navigatable; highlightNavigatable = navigatable;
this.searchOptions = searchOptions; this.searchOptions = searchOptions;
this.provider = provider; this.provider = provider;
this.highlightProgram = program; this.highlightProgram = program;
this.loc = loc; this.searchResult = searchResult;
this.showAllResults = searchResult == null;
if (provider != null) { if (provider != null) {
provider.addActivationListener(this); provider.addActivationListener(this);
@ -615,8 +627,10 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
if (!doHighlight) { if (!doHighlight) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
@ -625,7 +639,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (!shouldHighlight(fieldFactoryClass, obj)) { if (!shouldHighlight(field)) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
@ -634,50 +648,93 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
return getHighlights(text, cursorTextOffset); if (showAllResults) {
return getAllHighlights(text, cursorTextOffset);
}
Address address = searchResult.programLocation().getAddress();
ProxyObj<?> proxy = field.getProxy();
if (proxy.contains(address)) {
return getSingleSearchHighlight(text, field, cursorTextOffset);
}
return NO_HIGHLIGHTS;
} }
private Highlight[] getHighlights(String text, int cursorTextOffset) { private Highlight[] getAllHighlights(String text, int cursorTextOffset) {
String matchStr = searchOptions.getText().trim(); String searchText = searchOptions.getText();
if (matchStr == null || text == null) { if (StringUtils.isBlank(searchText) || StringUtils.isBlank(text)) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
List<Highlight> list = new ArrayList<>(); List<Highlight> list = new ArrayList<>();
Pattern regexp = Pattern regexp =
UserSearchUtils.createSearchPattern(matchStr, searchOptions.isCaseSensitive()); UserSearchUtils.createSearchPattern(searchText, searchOptions.isCaseSensitive());
Matcher matcher = regexp.matcher(text); Matcher matcher = regexp.matcher(text);
while (matcher.find()) { while (matcher.find()) {
int start = matcher.start(); int start = matcher.start();
int end = matcher.end() - 1; int end = matcher.end() - 1;
Color hlColor = PluginConstants.SEARCH_HIGHLIGHT_COLOR;
if (start <= cursorTextOffset && end >= cursorTextOffset) { if (start <= cursorTextOffset && end >= cursorTextOffset) {
list.add(new Highlight(start, end, // change the highlight color when in the field so it stands out
PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR)); hlColor = PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR;
}
else if (loc == null) { // only add in matches around current match if loc is null
// meaning that this is a one at a time search and not a table
// of results.
list.add(new Highlight(start, end,
PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR));
} }
list.add(new Highlight(start, end, hlColor));
} }
if (list.size() == 0) { if (list.isEmpty()) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
Highlight[] h = new Highlight[list.size()]; return list.toArray(Highlight[]::new);
return list.toArray(h);
} }
/** private Highlight[] getSingleSearchHighlight(String text, ListingField field,
* Return whether the field for the given factory class should be highlighted; compare int cursorTextOffset) {
* against the search options
* String searchText = searchOptions.getText();
* @param factoryClass field factory class if (StringUtils.isBlank(searchText) || StringUtils.isBlank(text)) {
* @param obj object associated with the field, e.g. CodeUnit return NO_HIGHLIGHTS;
*/ }
private boolean shouldHighlight(Class<?> factoryClass, Object obj) {
FieldFactory fieldFactory = field.getFieldFactory();
ProgramLocation loc = searchResult.programLocation();
if (!fieldFactory.supportsLocation(field, loc)) {
return NO_HIGHLIGHTS;
}
int charOffset = searchResult.offset();
int searchStart = charOffset;
int searchEnd = searchStart + searchText.length();
Pattern regexp =
UserSearchUtils.createSearchPattern(searchText, searchOptions.isCaseSensitive());
Matcher matcher = regexp.matcher(text);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
// ensure the particular regex match is the actual search result
if (start == searchStart && end == searchEnd) {
Color hlColor = PluginConstants.SEARCH_HIGHLIGHT_COLOR;
if (start <= cursorTextOffset && end >= cursorTextOffset) {
// change the highlight color when in the field so it stands out
hlColor = PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR;
}
// this is the matching search hit for a single search
int endEx = end - 1;
return new Highlight[] { new Highlight(start, endEx, hlColor) };
}
}
return NO_HIGHLIGHTS;
}
private boolean shouldHighlight(ListingField field) {
ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
Program navigatableProgram = navigatable == null ? null : navigatable.getProgram(); Program navigatableProgram = navigatable == null ? null : navigatable.getProgram();
if (navigatableProgram != highlightProgram) { if (navigatableProgram != highlightProgram) {
return false; return false;
@ -686,6 +743,8 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
if (searchOptions.searchAllFields()) { if (searchOptions.searchAllFields()) {
return true; return true;
} }
Class<? extends FieldFactory> factoryClass = field.getFieldFactory().getClass();
if (searchOptions.searchComments()) { if (searchOptions.searchComments()) {
if (factoryClass == PreCommentFieldFactory.class || if (factoryClass == PreCommentFieldFactory.class ||
factoryClass == PlateFieldFactory.class || factoryClass == PlateFieldFactory.class ||

View file

@ -27,7 +27,7 @@ public interface Searcher {
* Get the next program location. * Get the next program location.
* @return null if there is no next program location. * @return null if there is no next program location.
*/ */
public ProgramLocation search(); public TextSearchResult search();
/** /**
* Set the task monitor. * Set the task monitor.
@ -40,4 +40,15 @@ public interface Searcher {
* @return the search option * @return the search option
*/ */
public SearchOptions getSearchOptions(); public SearchOptions getSearchOptions();
/**
* A record object that represents a single search result
*
* @param programLocation the program location of the search result.
* @param offset the offset in the *model*'s text of the search result; this value will be from
* 0 to text.length(), where text is a single string for all text in the given field.
*/
public record TextSearchResult(ProgramLocation programLocation, int offset) {
// stub
}
} }

View file

@ -19,6 +19,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.util.*; import ghidra.program.util.*;
@ -52,7 +53,7 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Address nextAddress = iterator.next(); Address nextAddress = iterator.next();
if (nextAddress != null) { if (nextAddress != null) {
findMatchesForCurrentAddress(nextAddress, currentMatches); findMatchesForCurrentAddress(nextAddress, currentMatches);
@ -61,7 +62,7 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
private void findMatchesForCurrentAddress(Address address, private void findMatchesForCurrentAddress(Address address,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
String comment = program.getListing().getComment(commentType, address); String comment = program.getListing().getComment(commentType, address);
if (comment == null) { if (comment == null) {
return; return;
@ -70,14 +71,15 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
Matcher matcher = pattern.matcher(cleanedUpComment); Matcher matcher = pattern.matcher(cleanedUpComment);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(getCommentLocation(comment, index, address)); currentMatches
.add(new TextSearchResult(getCommentLocation(comment, index, address), index));
} }
} }
private ProgramLocation getCommentLocation(String commentStr, int index, Address address) { private ProgramLocation getCommentLocation(String commentStr, int index, Address address) {
String[] comments = StringUtilities.toLines(commentStr); String[] comments = StringUtilities.toLines(commentStr);
int rowIndex = findRowIndex(comments, index); int rowIndex = findRowIndex(comments, index);
int charOffset = findCharOffset(index, rowIndex, comments); int charOffset = getRelativeCharOffset(index, rowIndex, comments);
int[] dataPath = getDataComponentPath(address); int[] dataPath = getDataComponentPath(address);
switch (commentType) { switch (commentType) {
case CodeUnit.EOL_COMMENT: case CodeUnit.EOL_COMMENT:
@ -114,12 +116,12 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
return null; return null;
} }
private int findCharOffset(int index, int rowIndex, String[] opStrings) { private int getRelativeCharOffset(int index, int rowIndex, String[] comments) {
int totalBeforeOpIndex = 0; int preceding = 0;
for (int i = 0; i < rowIndex; i++) { for (int i = 0; i < rowIndex; i++) {
totalBeforeOpIndex += opStrings[i].length(); preceding += comments[i].length();
} }
return index - totalBeforeOpIndex; return index - preceding;
} }
private int findRowIndex(String[] commentStrings, int index) { private int findRowIndex(String[] commentStrings, int index) {

View file

@ -15,15 +15,16 @@
*/ */
package ghidra.app.plugin.core.searchtext.databasesearcher; package ghidra.app.plugin.core.searchtext.databasesearcher;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.util.*; import ghidra.program.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearcher { public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearcher {
private DataIterator iterator; private DataIterator iterator;
private CodeUnitFormat format; private CodeUnitFormat format;
@ -75,7 +76,7 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Data data = iterator.next(); Data data = iterator.next();
Address nextAddress = null; Address nextAddress = null;
if (data != null) { if (data != null) {
@ -85,7 +86,7 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
return nextAddress; return nextAddress;
} }
private void findMatchesForCurrentAddress(Data data, List<ProgramLocation> currentMatches) { private void findMatchesForCurrentAddress(Data data, List<TextSearchResult> currentMatches) {
StringBuffer searchStrBuf = new StringBuffer(); StringBuffer searchStrBuf = new StringBuffer();
String mnemonicString = ""; String mnemonicString = "";
String operandString = ""; String operandString = "";
@ -122,16 +123,17 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
} }
} }
private void addOperandMatch(Data data, List<ProgramLocation> currentMatches, private void addOperandMatch(Data data, List<TextSearchResult> currentMatches,
String mnemonicString, String operandString, Address address, int index) { String mnemonicString, String operandString, Address address, int index) {
if (!doOperands) { if (!doOperands) {
return; return;
} }
currentMatches.add(new OperandFieldLocation(program, address, data.getComponentPath(), currentMatches.add(
null, operandString, 0, index - mnemonicString.length() - 1)); new TextSearchResult(new OperandFieldLocation(program, address, data.getComponentPath(),
null, operandString, 0, index - mnemonicString.length() - 1), index));
} }
private void addMnemonicMatch(List<ProgramLocation> currentMatches, String mnemonicString, private void addMnemonicMatch(List<TextSearchResult> currentMatches, String mnemonicString,
Address address, int index, int endIndex) { Address address, int index, int endIndex) {
if (!doMnemonics) { if (!doMnemonics) {
return; return;
@ -140,7 +142,7 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
if (endIndex > mnemonicString.length()) { if (endIndex > mnemonicString.length()) {
return; return;
} }
currentMatches.add(new MnemonicFieldLocation(program, address, null, null, mnemonicString, currentMatches.add(new TextSearchResult(
index)); new MnemonicFieldLocation(program, address, null, null, mnemonicString, index), index));
} }
} }

View file

@ -20,6 +20,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.navigation.FunctionUtils; import ghidra.app.plugin.core.navigation.FunctionUtils;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
@ -46,7 +47,7 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
if (iterator.hasNext()) { if (iterator.hasNext()) {
Function function = iterator.next(); Function function = iterator.next();
Address nextAddress = null; Address nextAddress = null;
@ -62,34 +63,34 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
private void findMatchesForCurrentFunction(Function function, private void findMatchesForCurrentFunction(Function function,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
findCommentMatches(function, currentMatches); findCommentMatches(function, currentMatches);
findSignatureMatches(function, currentMatches); findSignatureMatches(function, currentMatches);
findVariableMatches(function, currentMatches); findVariableMatches(function, currentMatches);
} }
private void findVariableMatches(Function function, List<ProgramLocation> currentMatches) { private void findVariableMatches(Function function, List<TextSearchResult> currentMatches) {
Parameter[] parameters = function.getParameters(); Parameter[] parameters = function.getParameters();
for (int i = 0; i < parameters.length; i++) { for (Parameter parameter : parameters) {
checkTypeString(parameters[i], currentMatches); checkTypeString(parameter, currentMatches);
checkName(parameters[i], currentMatches); checkName(parameter, currentMatches);
checkStorage(parameters[i], currentMatches); checkStorage(parameter, currentMatches);
checkComment(parameters[i], currentMatches); checkComment(parameter, currentMatches);
} }
Variable[] localVariables = function.getLocalVariables(); Variable[] localVariables = function.getLocalVariables();
for (int i = 0; i < localVariables.length; i++) { for (Variable localVariable : localVariables) {
checkTypeString(localVariables[i], currentMatches); checkTypeString(localVariable, currentMatches);
checkName(localVariables[i], currentMatches); checkName(localVariable, currentMatches);
checkStorage(localVariables[i], currentMatches); checkStorage(localVariable, currentMatches);
checkComment(localVariables[i], currentMatches); checkComment(localVariable, currentMatches);
} }
} }
private void checkTypeString(Variable variable, List<ProgramLocation> currentMatches) { private void checkTypeString(Variable variable, List<TextSearchResult> currentMatches) {
DataType dt; DataType dt;
if (variable instanceof Parameter) { if (variable instanceof Parameter) {
dt = ((Parameter)variable).getFormalDataType(); dt = ((Parameter) variable).getFormalDataType();
} }
else { else {
dt = variable.getDataType(); dt = variable.getDataType();
@ -102,29 +103,32 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableTypeFieldLocation(program, variable, index)); currentMatches.add(new TextSearchResult(
new VariableTypeFieldLocation(program, variable, index), index));
} }
} }
private void checkName(Variable variable, List<ProgramLocation> currentMatches) { private void checkName(Variable variable, List<TextSearchResult> currentMatches) {
String searchString = variable.getName(); String searchString = variable.getName();
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableNameFieldLocation(program, variable, index)); currentMatches.add(new TextSearchResult(
new VariableNameFieldLocation(program, variable, index), index));
} }
} }
private void checkStorage(Variable var, List<ProgramLocation> currentMatches) { private void checkStorage(Variable var, List<TextSearchResult> currentMatches) {
String searchString = var.getVariableStorage().toString(); String searchString = var.getVariableStorage().toString();
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableLocFieldLocation(program, var, index)); currentMatches.add(
new TextSearchResult(new VariableLocFieldLocation(program, var, index), index));
} }
} }
private void checkComment(Variable variable, List<ProgramLocation> currentMatches) { private void checkComment(Variable variable, List<TextSearchResult> currentMatches) {
String searchString = variable.getComment(); String searchString = variable.getComment();
if (searchString == null) { if (searchString == null) {
return; return;
@ -132,23 +136,27 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableCommentFieldLocation(program, variable, index)); currentMatches.add(
new TextSearchResult(new VariableCommentFieldLocation(program, variable, index),
index));
} }
} }
private void findSignatureMatches(Function function, List<ProgramLocation> currentMatches) { private void findSignatureMatches(Function function, List<TextSearchResult> currentMatches) {
String signature = function.getPrototypeString(false, false); String signature = function.getPrototypeString(false, false);
Matcher matcher = pattern.matcher(signature); Matcher matcher = pattern.matcher(signature);
Address address = function.getEntryPoint(); Address address = function.getEntryPoint();
int callingConventionOffset = FunctionUtils.getCallingConventionSignatureOffset(function); int callingConventionOffset = FunctionUtils.getCallingConventionSignatureOffset(function);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new FunctionSignatureFieldLocation(program, address, null, index + currentMatches.add(new TextSearchResult(
callingConventionOffset, signature)); new FunctionSignatureFieldLocation(program, address, null, index +
callingConventionOffset, signature),
index));
} }
} }
private void findCommentMatches(Function function, List<ProgramLocation> currentMatches) { private void findCommentMatches(Function function, List<TextSearchResult> currentMatches) {
String functionComment = function.getRepeatableComment(); String functionComment = function.getRepeatableComment();
if (functionComment == null) { if (functionComment == null) {
@ -159,7 +167,8 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
Address address = function.getEntryPoint(); Address address = function.getEntryPoint();
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(getFunctionCommentLocation(functionComment, index, address)); currentMatches.add(new TextSearchResult(
getFunctionCommentLocation(functionComment, index, address), index));
} }
} }

View file

@ -19,6 +19,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -74,7 +75,7 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Instruction instruction = iterator.hasNext() ? iterator.next() : null; Instruction instruction = iterator.hasNext() ? iterator.next() : null;
Address nextAddress = null; Address nextAddress = null;
if (instruction != null) { if (instruction != null) {
@ -85,7 +86,7 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
} }
private void findMatchesForCurrentAddress(Instruction instruction, private void findMatchesForCurrentAddress(Instruction instruction,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
String mnemonicString = instruction.getMnemonicString(); String mnemonicString = instruction.getMnemonicString();
String[] opStrings = getOperandStrings(instruction); String[] opStrings = getOperandStrings(instruction);
Matcher matcher = pattern.matcher(combineStrings(mnemonicString, opStrings)); Matcher matcher = pattern.matcher(combineStrings(mnemonicString, opStrings));
@ -103,18 +104,18 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
} }
} }
private void addOperandMatch(Instruction instruction, List<ProgramLocation> currentMatches, private void addOperandMatch(Instruction instruction, List<TextSearchResult> currentMatches,
String[] opStrings, Address address, int index) { String[] opStrings, Address address, int index) {
if (!doOperands) { if (!doOperands) {
return; return;
} }
int opIndex = findOpIndex(opStrings, index); int opIndex = findOpIndex(opStrings, index);
int charOffset = findCharOffset(index, opIndex, opStrings); int charOffset = findCharOffset(index, opIndex, opStrings);
currentMatches.add(new OperandFieldLocation(program, address, null, currentMatches.add(new TextSearchResult(new OperandFieldLocation(program, address, null,
instruction.getAddress(opIndex), opStrings[opIndex], opIndex, charOffset)); instruction.getAddress(opIndex), opStrings[opIndex], opIndex, charOffset), index));
} }
private void addMnemonicMatch(List<ProgramLocation> currentMatches, Address address, private void addMnemonicMatch(List<TextSearchResult> currentMatches, Address address,
String mnemonicString, int startIndex, int endIndex) { String mnemonicString, int startIndex, int endIndex) {
if (!doMnemonics) { if (!doMnemonics) {
return; return;
@ -124,7 +125,9 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
return; return;
} }
currentMatches.add(new MnemonicFieldLocation(program, address, null, null, mnemonicString, currentMatches.add(new TextSearchResult(
new MnemonicFieldLocation(program, address, null, null, mnemonicString,
startIndex),
startIndex)); startIndex));
} }

View file

@ -20,6 +20,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -29,13 +30,11 @@ import ghidra.program.util.ProgramLocation;
public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher { public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
private AddressIterator iterator; private AddressIterator iterator;
private SymbolTable symbolTable; private SymbolTable symbolTable;
private Program program;
public LabelFieldSearcher(Program program, ProgramLocation startLoc, AddressSetView set, public LabelFieldSearcher(Program program, ProgramLocation startLoc, AddressSetView set,
boolean forward, Pattern pattern) { boolean forward, Pattern pattern) {
super(pattern, forward, startLoc, set); super(pattern, forward, startLoc, set);
this.program = program;
this.symbolTable = program.getSymbolTable(); this.symbolTable = program.getSymbolTable();
SymbolIterator symbolIterator; SymbolIterator symbolIterator;
@ -48,15 +47,15 @@ public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
else { else {
symbolIterator = symbolIterator =
program.getSymbolTable().getPrimarySymbolIterator(startLoc.getAddress(), forward); program.getSymbolTable().getPrimarySymbolIterator(startLoc.getAddress(), forward);
refIterator = program.getReferenceManager().getReferenceDestinationIterator( refIterator = program.getReferenceManager()
startLoc.getAddress(), forward); .getReferenceDestinationIterator(
startLoc.getAddress(), forward);
} }
iterator = new SymbolAddressIterator(symbolIterator, refIterator, forward); iterator = new SymbolAddressIterator(symbolIterator, refIterator, forward);
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Address nextAddress = iterator.next(); Address nextAddress = iterator.next();
if (nextAddress == null) { if (nextAddress == null) {
return null; return null;
@ -66,14 +65,15 @@ public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
private void findMatchesForCurrentAddress(Address address, private void findMatchesForCurrentAddress(Address address,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
Symbol[] symbols = symbolTable.getSymbols(address); Symbol[] symbols = symbolTable.getSymbols(address);
makePrimaryLastItem(symbols); makePrimaryLastItem(symbols);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
Matcher matcher = pattern.matcher(symbol.getName()); Matcher matcher = pattern.matcher(symbol.getName());
while (matcher.find()) { while (matcher.find()) {
int charOffset = matcher.start(); int charOffset = matcher.start();
currentMatches.add(new LabelFieldLocation(symbol, 0, charOffset)); currentMatches.add(new TextSearchResult(
new LabelFieldLocation(symbol, 0, charOffset), charOffset));
} }
} }
} }
@ -110,9 +110,6 @@ public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
nextRefAddress = getNextRefAddress(); nextRefAddress = getNextRefAddress();
} }
/**
* @see java.util.Iterator#remove()
*/
@Override @Override
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View file

@ -15,49 +15,54 @@
*/ */
package ghidra.app.plugin.core.searchtext.databasesearcher; package ghidra.app.plugin.core.searchtext.databasesearcher;
import java.util.*;
import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import java.util.*;
import java.util.regex.Pattern;
public abstract class ProgramDatabaseFieldSearcher { public abstract class ProgramDatabaseFieldSearcher {
protected final Pattern pattern; protected final Pattern pattern;
protected final boolean forward; protected final boolean forward;
private Address currentAddress; private Address currentAddress;
private ProgramLocation startLocation; private ProgramLocation startLocation;
private List<ProgramLocation> matchesForCurrentAddress = new LinkedList<ProgramLocation>(); private List<TextSearchResult> matchesForCurrentAddress = new LinkedList<>();
protected ProgramDatabaseFieldSearcher(Pattern pattern, boolean forward, ProgramLocation startLoc, AddressSetView set) { protected ProgramDatabaseFieldSearcher(Pattern pattern, boolean forward,
ProgramLocation startLoc, AddressSetView set) {
this.pattern = pattern; this.pattern = pattern;
this.forward = forward; this.forward = forward;
this.startLocation = startLoc; this.startLocation = startLoc;
if (forward && set != null && !set.isEmpty() && startLoc != null && if (forward && set != null && !set.isEmpty() && startLoc != null &&
!set.getMinAddress().equals(startLoc.getAddress())) { !set.getMinAddress().equals(startLoc.getAddress())) {
throw new IllegalArgumentException("Start location and addressSet are inconsistent!"); throw new IllegalArgumentException("Start location and addressSet are inconsistent!");
} }
if (!forward && set != null && !set.isEmpty() && startLoc != null && if (!forward && set != null && !set.isEmpty() && startLoc != null &&
!set.getMaxAddress().equals(startLoc.getAddress())) { !set.getMaxAddress().equals(startLoc.getAddress())) {
throw new IllegalArgumentException("Start location and addressSet are inconsistent!"); throw new IllegalArgumentException("Start location and addressSet are inconsistent!");
} }
} }
private void initialize() { private void initialize() {
currentAddress = doAdvance(matchesForCurrentAddress); currentAddress = doAdvance(matchesForCurrentAddress);
trimMatchesForStartLocation( ); trimMatchesForStartLocation();
} }
private Address doAdvance(List<ProgramLocation> currentMatches) {
private Address doAdvance(List<TextSearchResult> currentMatches) {
Address address = advance(matchesForCurrentAddress); Address address = advance(matchesForCurrentAddress);
if (!forward) { if (!forward) {
Collections.reverse( matchesForCurrentAddress ); Collections.reverse(matchesForCurrentAddress);
} }
return address; return address;
} }
protected abstract Address advance(List<ProgramLocation> currentMatches);
protected abstract Address advance(List<TextSearchResult> currentMatches);
public Address getNextSignificantAddress( Address address ) {
public Address getNextSignificantAddress(Address address) {
if (address == null) { if (address == null) {
initialize(); initialize();
return currentAddress; return currentAddress;
@ -65,37 +70,37 @@ public abstract class ProgramDatabaseFieldSearcher {
if (currentAddress == null) { // we have no more records in our iterator. if (currentAddress == null) { // we have no more records in our iterator.
return null; return null;
} }
if (currentAddress.equals( address )) { // we need to move to the next record if (currentAddress.equals(address)) { // we need to move to the next record
currentAddress = doAdvance(matchesForCurrentAddress); currentAddress = doAdvance(matchesForCurrentAddress);
} }
return currentAddress; return currentAddress;
} }
public ProgramLocation getMatch() { public TextSearchResult getMatch() {
return matchesForCurrentAddress.remove( 0 ); return matchesForCurrentAddress.remove(0);
} }
public boolean hasMatch( Address address ) { public boolean hasMatch(Address address) {
if (!address.equals(currentAddress)) { if (!address.equals(currentAddress)) {
return false; return false;
} }
return !matchesForCurrentAddress.isEmpty(); return !matchesForCurrentAddress.isEmpty();
} }
private void trimMatchesForStartLocation( ) { private void trimMatchesForStartLocation() {
if (startLocation == null) { if (startLocation == null) {
return; return;
} }
if (!startLocation.getAddress().equals( currentAddress )) { if (!startLocation.getAddress().equals(currentAddress)) {
return; return;
} }
Iterator<ProgramLocation> it = matchesForCurrentAddress.iterator(); Iterator<TextSearchResult> it = matchesForCurrentAddress.iterator();
while(it.hasNext()) { while (it.hasNext()) {
ProgramLocation programLoc = it.next(); ProgramLocation programLoc = it.next().programLocation();
int compareVal = startLocation.compareTo( programLoc ); int compareVal = startLocation.compareTo(programLoc);
if ((forward && compareVal >=0) || if ((forward && compareVal >= 0) ||
(!forward && compareVal <=0 )) { (!forward && compareVal <= 0)) {
it.remove(); it.remove();
} }
} }
} }

View file

@ -82,7 +82,7 @@ public class ProgramDatabaseSearcher implements Searcher {
} }
@Override @Override
public ProgramLocation search() { public TextSearchResult search() {
List<ProgramDatabaseFieldSearcher> orderedSearchers = searchers; List<ProgramDatabaseFieldSearcher> orderedSearchers = searchers;
if (!searchOptions.isForward()) { if (!searchOptions.isForward()) {
orderedSearchers = new ArrayList<>(searchers); orderedSearchers = new ArrayList<>(searchers);
@ -210,8 +210,9 @@ public class ProgramDatabaseSearcher implements Searcher {
} }
if (options.searchBothInstructionMnemonicAndOperands()) { if (options.searchBothInstructionMnemonicAndOperands()) {
searchers.add( searchers.add(
InstructionMnemonicOperandFieldSearcher.createInstructionMnemonicAndOperandFieldSearcher( InstructionMnemonicOperandFieldSearcher
program, adjustedStart, trimmedSet, forward, pattern, format)); .createInstructionMnemonicAndOperandFieldSearcher(
program, adjustedStart, trimmedSet, forward, pattern, format));
} }
if (options.searchOnlyInstructionMnemonics()) { if (options.searchOnlyInstructionMnemonics()) {
searchers.add( searchers.add(

View file

@ -21,7 +21,7 @@ import java.util.*;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.pcode.AttributedStringPcodeFormatter; import ghidra.app.util.pcode.AttributedStringPcodeFormatter;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
@ -55,7 +55,7 @@ public class PcodeFieldFactory extends FieldFactory {
} }
public PcodeFieldFactory(String name, FieldFormatModel model, public PcodeFieldFactory(String name, FieldFormatModel model,
HighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) {
super(name, model, highlightProvider, displayOptions, fieldOptions); super(name, model, highlightProvider, displayOptions, fieldOptions);
setWidth(300); setWidth(300);
@ -67,7 +67,7 @@ public class PcodeFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel myModel, HighlightProvider highlightProvider, public FieldFactory newInstance(FieldFormatModel myModel, ListingHighlightProvider highlightProvider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new PcodeFieldFactory(FIELD_NAME, myModel, highlightProvider, options, fieldOptions); return new PcodeFieldFactory(FIELD_NAME, myModel, highlightProvider, options, fieldOptions);
} }

View file

@ -22,7 +22,7 @@ import docking.widgets.fieldpanel.FieldPanel;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.ProgramDropProvider; import ghidra.app.util.ProgramDropProvider;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.listingpanel.*; import ghidra.app.util.viewer.listingpanel.*;
@ -105,14 +105,14 @@ public interface CodeViewerService {
* @param provider The provider to set. * @param provider The provider to set.
* @param program The program with which to associate the given provider. * @param program The program with which to associate the given provider.
*/ */
public void setHighlightProvider(HighlightProvider provider, Program program); public void setHighlightProvider(ListingHighlightProvider provider, Program program);
/** /**
* Remove the highlight provider. * Remove the highlight provider.
* @param provider the provider to remove. * @param provider the provider to remove.
* @param program the program associated with the given provider. * @param program the program associated with the given provider.
*/ */
public void removeHighlightProvider(HighlightProvider provider, Program program); public void removeHighlightProvider(ListingHighlightProvider provider, Program program);
/** /**
* Set a listing panel on the code viewer. * Set a listing panel on the code viewer.

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,28 +15,27 @@
*/ */
package ghidra.app.util; package ghidra.app.util;
import ghidra.app.util.viewer.field.FieldFactory;
import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.util.viewer.field.ListingField;
import ghidra.program.model.listing.CodeUnit;
/** /**
* Provider of Highlight objects appropriate for the text, object, and FieldFactory class. * Provider of Highlight objects appropriate {@link ListingField}s.
*
*/ */
public interface HighlightProvider { public interface ListingHighlightProvider {
public static final Highlight[] EMPTY_HIGHLIGHT = new Highlight[0]; public static final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
/** /**
* Get the highlights appropriate for the given text, object, and FieldFactory class. * Get the highlights appropriate for the given text
*
* @param text the entire text contained in the field, regardless of layout. * @param text the entire text contained in the field, regardless of layout.
* @param obj object that provides the information to be rendered (usually a code unit) * @param field the field being rendered. From this field you can get the field factory and
* @param fieldFactoryClass the class that indicates what type of field is being rendered. * the proxy object, which is usually a {@link CodeUnit}.
* For Example, address fields would have the AddressFieldFactory class. * @param cursorTextOffset the cursor position within the given text or -1 if no cursor in this
* @param cursorTextOffset the cursor position within the given text or -1 if no cursor in this field. * field.
* @return an array of highlight objects that indicate the location within the text string to * @return an array of highlight objects that indicate the location within the text string to
* be highlighted. * be highlighted.
*/ */
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset);
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset);
} }

View file

@ -17,7 +17,7 @@ package ghidra.app.util.viewer.field;
import java.awt.*; import java.awt.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.options.OptionsGui; import ghidra.app.util.viewer.options.OptionsGui;
@ -65,7 +65,7 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected AbstractVariableFieldFactory(String name, FieldFormatModel model, protected AbstractVariableFieldFactory(String name, FieldFormatModel model,
HighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) {
super(name, model, highlightProvider, displayOptions, fieldOptions); super(name, model, highlightProvider, displayOptions, fieldOptions);
} }

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.*; import ghidra.framework.options.*;
@ -63,7 +63,7 @@ public class AddressFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private AddressFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private AddressFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
initOptions(fieldOptions); initOptions(fieldOptions);
@ -198,7 +198,7 @@ public class AddressFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel newModel, public FieldFactory newInstance(FieldFormatModel newModel,
HighlightProvider highlightStringProvider, ToolOptions toolOptions, ListingHighlightProvider highlightStringProvider, ToolOptions toolOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new AddressFieldFactory(newModel, highlightStringProvider, toolOptions, return new AddressFieldFactory(newModel, highlightStringProvider, toolOptions,
fieldOptions); fieldOptions);

View file

@ -21,7 +21,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -43,7 +43,7 @@ public class ArrayValuesFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions toolOptions, ListingHighlightProvider highlightProvider, ToolOptions toolOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new ArrayValuesFieldFactory(formatModel, highlightProvider, toolOptions, return new ArrayValuesFieldFactory(formatModel, highlightProvider, toolOptions,
fieldOptions); fieldOptions);
@ -56,7 +56,7 @@ public class ArrayValuesFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private ArrayValuesFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private ArrayValuesFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
setupOptions(fieldOptions); setupOptions(fieldOptions);

View file

@ -20,7 +20,7 @@ import java.util.ArrayList;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -50,7 +50,7 @@ public class AssignedVariableFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private AssignedVariableFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private AssignedVariableFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@ -134,7 +134,7 @@ public class AssignedVariableFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new AssignedVariableFieldFactory(formatModel, hsProvider, displayOptions, return new AssignedVariableFieldFactory(formatModel, hsProvider, displayOptions,
fieldOptions); fieldOptions);

View file

@ -27,7 +27,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -35,10 +35,12 @@ import ghidra.framework.options.ToolOptions;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Structure; import ghidra.program.model.data.Structure;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.util.BytesFieldLocation; import ghidra.program.util.BytesFieldLocation;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.Msg;
/** /**
* Generates Bytes Fields. * Generates Bytes Fields.
@ -81,7 +83,7 @@ public class BytesFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private BytesFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private BytesFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -171,22 +173,23 @@ public class BytesFieldFactory extends FieldFactory {
if (!enabled || !(obj instanceof CodeUnit)) { if (!enabled || !(obj instanceof CodeUnit)) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj;
CodeUnit cu = (CodeUnit) obj;
int length = Math.min(cu.getLength(), 100); int length = Math.min(cu.getLength(), 100);
byte[] bytes = new byte[length]; byte[] bytes = new byte[length];
Memory memory = cu.getProgram().getMemory();
try { try {
length = cu.getProgram().getMemory().getBytes(cu.getAddress(), bytes); length = memory.getBytes(cu.getAddress(), bytes);
} }
catch (MemoryAccessException e) { catch (MemoryAccessException e) {
return null; return null;
} }
if (length == 0) { if (length == 0) {
return null; return null;
} }
if ((cu instanceof Instruction) && reverseInstByteOrdering && if ((cu instanceof Instruction) && reverseInstByteOrdering && !memory.isBigEndian()) {
!cu.getProgram().getMemory().isBigEndian()) {
int i = 0; int i = 0;
int j = length - 1; int j = length - 1;
while (j > i) { while (j > i) {
@ -196,26 +199,24 @@ public class BytesFieldFactory extends FieldFactory {
} }
} }
int fieldElementLength = length / byteGroupSize; int groupLength = length / byteGroupSize;
int residual = length % byteGroupSize; int residual = length % byteGroupSize;
if (residual != 0) { if (residual != 0) {
fieldElementLength++; groupLength++;
} }
boolean wasTruncated = length != cu.getLength(); boolean wasTruncated = length != cu.getLength();
byte[] alignmentBytes = getAlignmentBytes(cu, wasTruncated); byte[] alignmentBytes = getAlignmentBytes(cu, wasTruncated);
int extraLen = getLengthForAlignmentBytes(alignmentBytes, residual); int extraLength = getLengthForAlignmentBytes(alignmentBytes, residual);
FieldElement[] elements = new FieldElement[groupLength + extraLength];
FieldElement[] aStrings = new FieldElement[fieldElementLength + extraLen]; boolean addDelimiter = extraLength != 0;
buildAttributedByteValues(elements, 0, bytes, length, 0, ListingColors.BYTES, addDelimiter);
buildAttributedByteValues(aStrings, 0, bytes, length, 0, ListingColors.BYTES, if (addDelimiter) {
extraLen != 0); buildAttributedByteValues(elements, groupLength, alignmentBytes,
if (extraLen != 0) {
buildAttributedByteValues(aStrings, fieldElementLength, alignmentBytes,
alignmentBytes.length, residual, ListingColors.BYTES_ALIGNMENT, false); alignmentBytes.length, residual, ListingColors.BYTES_ALIGNMENT, false);
} }
return ListingTextField.createPackedTextField(this, proxy, aStrings, startX + varWidth, return ListingTextField.createPackedTextField(this, proxy, elements, startX + varWidth,
width, maxDisplayLines, hlProvider); width, maxDisplayLines, hlProvider);
} }
@ -242,9 +243,9 @@ public class BytesFieldFactory extends FieldFactory {
return null; return null;
} }
private int buildAttributedByteValues(FieldElement[] aStrings, int pos, byte[] bytes, int size, private int buildAttributedByteValues(FieldElement[] elements, int pos, byte[] bytes, int size,
int residual, Color c, boolean addDelimToLastGroup) { int residual, Color color, boolean addDelimiter) {
StringBuffer buffer = new StringBuffer(); StringBuilder buffer = new StringBuilder();
int groupSize = byteGroupSize - residual; int groupSize = byteGroupSize - residual;
int tempGroupSize = 0; int tempGroupSize = 0;
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
@ -263,19 +264,20 @@ public class BytesFieldFactory extends FieldFactory {
if (tempGroupSize == groupSize) { if (tempGroupSize == groupSize) {
tempGroupSize = 0; tempGroupSize = 0;
groupSize = byteGroupSize; groupSize = byteGroupSize;
if (i < size - 1 || addDelimToLastGroup) { if (i < size - 1 || addDelimiter) {
buffer.append(delim); buffer.append(delim);
} }
AttributedString as = new AttributedString(buffer.toString(), c, getMetrics()); AttributedString as = new AttributedString(buffer.toString(), color, getMetrics());
aStrings[pos] = new TextFieldElement(as, pos, 0); elements[pos] = new TextFieldElement(as, pos, 0);
pos++; pos++;
buffer = new StringBuffer(); buffer = new StringBuilder();
} }
} }
// append incomplete byte group... // append incomplete byte group...
if (tempGroupSize > 0) { if (tempGroupSize > 0) {
AttributedString as = new AttributedString(buffer.toString(), c, getMetrics()); AttributedString as = new AttributedString(buffer.toString(), color, getMetrics());
aStrings[pos] = new TextFieldElement(as, pos, 0); elements[pos] = new TextFieldElement(as, pos, 0);
} }
return tempGroupSize; return tempGroupSize;
} }
@ -310,8 +312,8 @@ public class BytesFieldFactory extends FieldFactory {
if (alignSize <= 0) { if (alignSize <= 0) {
return null; return null;
} }
int alignmentOffset = data.getParentOffset() + data.getLength();
int alignmentOffset = data.getParentOffset() + data.getLength();
byte[] bytes = new byte[alignSize]; byte[] bytes = new byte[alignSize];
parent.getBytes(bytes, alignmentOffset); parent.getBytes(bytes, alignmentOffset);
return bytes; return bytes;
@ -319,13 +321,15 @@ public class BytesFieldFactory extends FieldFactory {
@Override @Override
public ProgramLocation getProgramLocation(int row, int col, ListingField bf) { public ProgramLocation getProgramLocation(int row, int col, ListingField bf) {
Msg.debug(this, "Bytes - getProgLoc() - row / col: " + row + " / " + col);
Object obj = bf.getProxy().getObject(); Object obj = bf.getProxy().getObject();
if (!(obj instanceof CodeUnit) || row < 0 || col < 0) { if (!(obj instanceof CodeUnit) || row < 0 || col < 0) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj; CodeUnit cu = (CodeUnit) obj;
int[] cpath = null; int[] cpath = null;
if (cu instanceof Data) { if (cu instanceof Data) {
cpath = ((Data) cu).getComponentPath(); cpath = ((Data) cu).getComponentPath();
@ -354,16 +358,15 @@ public class BytesFieldFactory extends FieldFactory {
int byteIndex = tokenIndex * byteGroupSize + getByteIndexInToken(tokenCharPos); int byteIndex = tokenIndex * byteGroupSize + getByteIndexInToken(tokenCharPos);
int charOffset = computeCharOffset(tokenCharPos); int charOffset = computeCharOffset(tokenCharPos);
return new BytesFieldLocation(cu.getProgram(), cu.getMinAddress(), return new BytesFieldLocation(cu.getProgram(), cu.getMinAddress(),
cu.getMinAddress().add(byteIndex), cpath, charOffset); cu.getMinAddress().add(byteIndex), cpath, charOffset);
} }
/** /**
* Computes how many bytes the the given column position represents. Normally * Computes how many bytes the the given column position represents. Normally this is just the
* this is just the column position / 2 (since each byte consists of two chars). There * column position / 2 (since each byte consists of two chars). There is a special case when
* is a special case when the col position is just past the last char of the token. In * the col position is just past the last char of the token. In this case, we want to return
* this case, we want to return the number of bytes in a token - 1; * the number of bytes in a token - 1;
*/ */
private int getByteIndexInToken(int col) { private int getByteIndexInToken(int col) {
if (col >= byteGroupSize * CHARS_IN_BYTE) { if (col >= byteGroupSize * CHARS_IN_BYTE) {
@ -374,11 +377,10 @@ public class BytesFieldFactory extends FieldFactory {
/** /**
* Computes the character offset for a BytesFieldLocation based on the character column the * Computes the character offset for a BytesFieldLocation based on the character column the
* cursor is at in the token. BytesFieldLocation character offsets are always as if the group size is 1. * cursor is at in the token. BytesFieldLocation character offsets are always as if the group
* So for all positions except the last byte, it is just the column modulo 2. For the last byte, we have * size is 1. So for all positions except the last byte, it is just the column modulo 2. For
* to account for any columns past the last char. In this case, we have to subtract off * the last byte, we have to account for any columns past the last char. In this case, we have
* 2 for every byte before the last byte. * to subtract off 2 for every byte before the last byte.
*
*/ */
private int computeCharOffset(int col) { private int computeCharOffset(int col) {
if (col >= byteGroupSize * CHARS_IN_BYTE) { if (col >= byteGroupSize * CHARS_IN_BYTE) {
@ -390,17 +392,16 @@ public class BytesFieldFactory extends FieldFactory {
@Override @Override
public FieldLocation getFieldLocation(ListingField bf, BigInteger index, int fieldNum, public FieldLocation getFieldLocation(ListingField bf, BigInteger index, int fieldNum,
ProgramLocation loc) { ProgramLocation loc) {
if (!(loc instanceof BytesFieldLocation)) { if (!(loc instanceof BytesFieldLocation)) {
return null; return null;
} }
Object obj = bf.getProxy().getObject(); Object obj = bf.getProxy().getObject();
if (!(obj instanceof CodeUnit)) { if (!(obj instanceof CodeUnit)) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj; CodeUnit cu = (CodeUnit) obj;
BytesFieldLocation bytesLoc = (BytesFieldLocation) loc; BytesFieldLocation bytesLoc = (BytesFieldLocation) loc;
int byteIndex = bytesLoc.getByteIndex(); int byteIndex = bytesLoc.getByteIndex();
int columnInByte = bytesLoc.getColumnInByte(); int columnInByte = bytesLoc.getColumnInByte();
@ -442,7 +443,8 @@ public class BytesFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel,
ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new BytesFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new BytesFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -79,7 +79,7 @@ public class DummyFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hlProvdier, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hlProvdier,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return this; return this;
} }

View file

@ -98,7 +98,7 @@ public class EolCommentFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private EolCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private EolCommentFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
HelpLocation hl = new HelpLocation("CodeBrowserPlugin", "EOL_Comments_Field"); HelpLocation hl = new HelpLocation("CodeBrowserPlugin", "EOL_Comments_Field");
@ -522,13 +522,13 @@ public class EolCommentFieldFactory extends FieldFactory {
if (!(obj instanceof CodeUnit)) { if (!(obj instanceof CodeUnit)) {
return null; return null;
} }
DisplayableEol displayableEol = DisplayableEol displayableEol =
new DisplayableEol((CodeUnit) obj, alwaysShowRepeatable, alwaysShowRefRepeatables, new DisplayableEol((CodeUnit) obj, alwaysShowRepeatable, alwaysShowRefRepeatables,
alwaysShowAutomatic, codeUnitFormatOptions.followReferencedPointers(), alwaysShowAutomatic, codeUnitFormatOptions.followReferencedPointers(),
maxDisplayLines, useAbbreviatedAutomatic, showAutomaticFunctions); maxDisplayLines, useAbbreviatedAutomatic, showAutomaticFunctions);
ListingTextField btf = (ListingTextField) bf; ListingTextField btf = (ListingTextField) bf;
RowColLocation eolRowCol = displayableEol.getRowCol((CommentFieldLocation) loc); RowColLocation eolRowCol = displayableEol.getRowCol((CommentFieldLocation) loc);
RowColLocation rcl = btf.dataToScreenLocation(eolRowCol.row(), eolRowCol.col()); RowColLocation rcl = btf.dataToScreenLocation(eolRowCol.row(), eolRowCol.col());
if (!hasSamePath(bf, loc)) { if (!hasSamePath(bf, loc)) {
@ -548,7 +548,7 @@ public class EolCommentFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel fieldFormatModel, public FieldFactory newInstance(FieldFormatModel fieldFormatModel,
HighlightProvider highlightProvider, ToolOptions newDisplayOptions, ListingHighlightProvider highlightProvider, ToolOptions newDisplayOptions,
ToolOptions newFieldOptions) { ToolOptions newFieldOptions) {
return new EolCommentFieldFactory(fieldFormatModel, highlightProvider, newDisplayOptions, return new EolCommentFieldFactory(fieldFormatModel, highlightProvider, newDisplayOptions,
newFieldOptions); newFieldOptions);

View file

@ -16,7 +16,6 @@
package ghidra.app.util.viewer.field; package ghidra.app.util.viewer.field;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.util.viewer.format.ErrorListingField;
import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg; import ghidra.util.Msg;

View file

@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package ghidra.app.util.viewer.format; package ghidra.app.util.viewer.field;
import java.awt.Color; import java.awt.Color;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.Highlight;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
public class ErrorListingField extends ListingTextField { public class ErrorListingField extends ListingTextField {
@ -31,21 +31,25 @@ public class ErrorListingField extends ListingTextField {
private Throwable t; private Throwable t;
private static HighlightProvider myProvider = private static ListingHighlightProvider myProvider =
(text, obj, fieldFactoryClass, cursorTextOffset) -> new Highlight[] { (text, field, cursorTextOffset) -> new Highlight[] {
new Highlight(0, text.length() - 1, BG_ERROR_COLOR) }; new Highlight(0, text.length() - 1, BG_ERROR_COLOR) };
public ErrorListingField(FieldFactory ff, ProxyObj<?> proxy, int varWidth, Throwable t) { public ErrorListingField(FieldFactory ff, ProxyObj<?> proxy, int varWidth, Throwable t) {
super(ff, proxy, createField(ff, proxy, varWidth, t)); super(ff, proxy, null, createHighlightFactory());
this.field = createField(ff, proxy, varWidth);
this.t = t; this.t = t;
} }
private static TextField createField(FieldFactory ff, ProxyObj<?> proxy, int varWidth, private static ListingFieldHighlightFactoryAdapter createHighlightFactory() {
Throwable t) { return new ListingFieldHighlightFactoryAdapter(myProvider);
HighlightFactory hlFactory = }
new FieldHighlightFactory(myProvider, ff.getClass(), proxy.getObject());
return new ClippingTextField(ff.getStartX() + varWidth, ff.getWidth(), private ClippingTextField createField(FieldFactory ff, ProxyObj<?> proxy, int varWidth) {
createElement(ff, t), hlFactory); ClippingTextField textField =
new ClippingTextField(ff.getStartX() + varWidth, ff.getWidth(),
createElement(ff, t), hlFactory);
return textField;
} }
private static FieldElement createElement(FieldFactory ff, Throwable t) { private static FieldElement createElement(FieldFactory ff, Throwable t) {

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.Gui; import generic.theme.Gui;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.template.TemplateSimplifier; import ghidra.app.util.template.TemplateSimplifier;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -51,7 +51,7 @@ public abstract class FieldFactory implements ExtensionPoint {
protected Font baseFont; protected Font baseFont;
protected int style = -1; protected int style = -1;
protected boolean enabled = true; protected boolean enabled = true;
protected HighlightProvider hlProvider; protected ListingHighlightProvider hlProvider;
protected String colorOptionName; protected String colorOptionName;
protected String styleOptionName; protected String styleOptionName;
@ -65,7 +65,8 @@ public abstract class FieldFactory implements ExtensionPoint {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected FieldFactory(String name, FieldFormatModel model, HighlightProvider highlightProvider, protected FieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider highlightProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
this.name = name; this.name = name;
this.model = model; this.model = model;
@ -81,7 +82,7 @@ public abstract class FieldFactory implements ExtensionPoint {
protected void initFieldOptions(Options fieldOptions) { protected void initFieldOptions(Options fieldOptions) {
fieldOptions.getOptions(name) fieldOptions.getOptions(name)
.setOptionsHelpLocation(new HelpLocation("CodeBrowserPlugin", name)); .setOptionsHelpLocation(new HelpLocation("CodeBrowserPlugin", name));
} }
protected void initDisplayOptions(Options displayOptions) { protected void initDisplayOptions(Options displayOptions) {
@ -121,7 +122,8 @@ public abstract class FieldFactory implements ExtensionPoint {
* @return the factory * @return the factory
*/ */
public abstract FieldFactory newInstance(FieldFormatModel formatModel, public abstract FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions); ListingHighlightProvider highlightProvider, ToolOptions options,
ToolOptions fieldOptions);
/** /**
* Notifications that the display options changed. * Notifications that the display options changed.
@ -220,6 +222,19 @@ public abstract class FieldFactory implements ExtensionPoint {
model.modelChanged(); model.modelChanged();
} }
/**
* Returns true if this given field represents the given location
* @param listingField the field
* @param location the location
* @return true if this given field represents the given location
*/
public boolean supportsLocation(ListingField listingField, ProgramLocation location) {
BigInteger dummyIndex = BigInteger.ZERO;
int dummyFieldNumber = 0;
FieldLocation f = getFieldLocation(listingField, dummyIndex, dummyFieldNumber, location);
return f != null;
}
/** /**
* Generates a Field based on the given information. * Generates a Field based on the given information.
* @param obj The object that the generated field will report some information about. * @param obj The object that the generated field will report some information about.

View file

@ -1,51 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.viewer.field;
import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.Highlight;
import docking.widgets.fieldpanel.support.HighlightFactory;
import ghidra.app.util.HighlightProvider;
/**
* Wrapper class to hold field factory information in the text field to be provided to the
* highlightProvider to get highlights just before the field is painted.
*
*/
public class FieldHighlightFactory implements HighlightFactory {
private HighlightProvider provider;
private Class<? extends FieldFactory> fieldFactoryClass;
private Object obj;
/**
* Constructs a new FieldHighlightFactory.
* @param provider the HighlightProvider that will actually compute the highlights.
* @param fieldFactoryClass the class of the field factory that generated the field to be rendered.
* @param obj the object that holds the information that will be rendered (usually a code unit)
*/
public FieldHighlightFactory(HighlightProvider provider,
Class<? extends FieldFactory> fieldFactoryClass, Object obj) {
this.provider = provider;
this.fieldFactoryClass = fieldFactoryClass;
this.obj = obj;
}
@Override
public Highlight[] getHighlights(Field field, String text, int cursorTextOffset) {
return provider.getHighlights(text, obj, fieldFactoryClass, cursorTextOffset);
}
}

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -70,7 +70,7 @@ public class FieldNameFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private FieldNameFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FieldNameFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
fieldOptions.registerOption(ARRAY_INDEX_FORMAT_NAME, IndexFormat.decimal, null, fieldOptions.registerOption(ARRAY_INDEX_FORMAT_NAME, IndexFormat.decimal, null,
@ -155,7 +155,7 @@ public class FieldNameFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FieldNameFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new FieldNameFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }

View file

@ -21,7 +21,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.*; import ghidra.framework.options.*;
@ -66,7 +66,7 @@ public class FileOffsetFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private FileOffsetFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FileOffsetFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
initOptions(fieldOptions); initOptions(fieldOptions);
@ -97,7 +97,7 @@ public class FileOffsetFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) { ListingHighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) {
return new FileOffsetFieldFactory(formatModel, highlightProvider, options, fieldOptions); return new FileOffsetFieldFactory(formatModel, highlightProvider, options, fieldOptions);
} }

View file

@ -20,7 +20,7 @@ import java.util.ArrayList;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@ -52,7 +52,7 @@ public class FunctionCallFixupFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionCallFixupFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public FunctionCallFixupFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -118,7 +118,7 @@ public class FunctionCallFixupFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new FunctionCallFixupFieldFactory(formatModel, provider, displayOptions, return new FunctionCallFixupFieldFactory(formatModel, provider, displayOptions,
fieldOptions); fieldOptions);

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -37,14 +37,14 @@ public class FunctionPurgeFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private FunctionPurgeFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FunctionPurgeFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel newModel, HighlightProvider newHlProvider, public FieldFactory newInstance(FieldFormatModel newModel, ListingHighlightProvider newHlProvider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionPurgeFieldFactory(newModel, newHlProvider, toolOptions, fieldOptions); return new FunctionPurgeFieldFactory(newModel, newHlProvider, toolOptions, fieldOptions);
} }

View file

@ -21,7 +21,7 @@ import docking.widgets.fieldpanel.field.AttributedString;
import docking.widgets.fieldpanel.field.FieldElement; import docking.widgets.fieldpanel.field.FieldElement;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.CommentColors; import ghidra.app.util.viewer.field.ListingColors.CommentColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@ -55,7 +55,7 @@ public class FunctionRepeatableCommentFieldFactory extends FieldFactory {
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionRepeatableCommentFieldFactory(FieldFormatModel model, public FunctionRepeatableCommentFieldFactory(FieldFormatModel model,
HighlightProvider hlProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider hlProvider, Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -121,7 +121,7 @@ public class FunctionRepeatableCommentFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new FunctionRepeatableCommentFieldFactory(formatModel, provider, options, return new FunctionRepeatableCommentFieldFactory(formatModel, provider, options,

View file

@ -24,7 +24,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@ -58,7 +58,7 @@ public class FunctionSignatureFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionSignatureFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public FunctionSignatureFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -375,7 +375,7 @@ public class FunctionSignatureFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionSignatureFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new FunctionSignatureFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.AttributedString; import docking.widgets.fieldpanel.field.AttributedString;
import docking.widgets.fieldpanel.field.TextFieldElement; import docking.widgets.fieldpanel.field.TextFieldElement;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@ -55,7 +55,7 @@ public class FunctionSignatureSourceFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionSignatureSourceFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public FunctionSignatureSourceFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -112,7 +112,7 @@ public class FunctionSignatureSourceFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionSignatureSourceFieldFactory(formatModel, provider, toolOptions, return new FunctionSignatureSourceFieldFactory(formatModel, provider, toolOptions,
fieldOptions); fieldOptions);

View file

@ -23,7 +23,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@ -59,7 +59,7 @@ public class FunctionTagFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private FunctionTagFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FunctionTagFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -125,7 +125,7 @@ public class FunctionTagFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionTagFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new FunctionTagFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }

View file

@ -21,7 +21,6 @@ import javax.swing.Icon;
import docking.widgets.fieldpanel.field.SimpleImageField; import docking.widgets.fieldpanel.field.SimpleImageField;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.EmptyProxy; import ghidra.app.util.viewer.proxy.EmptyProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -79,11 +78,6 @@ public class ImageFactoryField extends SimpleImageField implements ListingField
return factory; return factory;
} }
@Override
public FieldFormatModel getFieldModel() {
return factory.getFieldModel();
}
@Override @Override
public ProxyObj<?> getProxy() { public ProxyObj<?> getProxy() {
if (proxy == null) { if (proxy == null) {

View file

@ -23,7 +23,6 @@ import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager;
import docking.widgets.fieldpanel.internal.PaintContext; import docking.widgets.fieldpanel.internal.PaintContext;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.*;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.EmptyProxy; import ghidra.app.util.viewer.proxy.EmptyProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -80,15 +79,6 @@ public class IndentField implements ListingField {
return factory; return factory;
} }
/**
* Returns the FieldModel that contains the FieldFactory that generated this
* field.
*/
@Override
public FieldFormatModel getFieldModel() {
return factory.getFieldModel();
}
/** /**
* Returns the object associated with this field instance. * Returns the object associated with this field instance.
*/ */

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.MaskColors; import ghidra.app.util.viewer.field.ListingColors.MaskColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -52,7 +52,7 @@ public class InstructionMaskValueFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private InstructionMaskValueFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private InstructionMaskValueFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@ -165,7 +165,7 @@ public class InstructionMaskValueFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new InstructionMaskValueFieldFactory(formatModel, hsProvider, toolOptions, return new InstructionMaskValueFieldFactory(formatModel, hsProvider, toolOptions,
fieldOptions); fieldOptions);

View file

@ -83,7 +83,7 @@ public class LabelFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private LabelFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private LabelFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -449,7 +449,7 @@ public class LabelFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions pDisplayOptions, ToolOptions fieldOptions) { ToolOptions pDisplayOptions, ToolOptions fieldOptions) {
return new LabelFieldFactory(formatModel, provider, pDisplayOptions, fieldOptions); return new LabelFieldFactory(formatModel, provider, pDisplayOptions, fieldOptions);
} }

View file

@ -17,7 +17,6 @@ package ghidra.app.util.viewer.field;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
/** /**
@ -31,24 +30,6 @@ public interface ListingField extends Field {
*/ */
public FieldFactory getFieldFactory(); public FieldFactory getFieldFactory();
/**
* Returns the height above the imaginary base line used for alignment of fields.
*/
@Override
public int getHeightAbove();
/**
* Returns the height below the imaginary base line used for alignment of fields.
*/
@Override
public int getHeightBelow();
/**
* Returns the fieldModel that has the FieldFactory that generated this field.
* @return the fieldModel that has the FieldFactory that generated this field.
*/
public FieldFormatModel getFieldModel();
/** /**
* Returns the object that the fieldFactory used to generate the information in this field. * Returns the object that the fieldFactory used to generate the information in this field.
* @return the object that the fieldFactory used to generate the information in this field. * @return the object that the fieldFactory used to generate the information in this field.

View file

@ -0,0 +1,61 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.viewer.field;
import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.FieldHighlightFactory;
import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.listingpanel.ListingPanel;
import ghidra.util.Msg;
import utilities.util.reflection.ReflectionUtilities;
/**
* Wrapper class to translate calls to {@link FieldHighlightFactory} into a call needed by the
* {@link ListingHighlightProvider}. This class holds field factory information in the text
* field to be provided to the highlightProvider to get highlights just before the field is painted.
* <p>
* This class is needed to allow the basic {@link Field} API to be used with more richness at the
* {@link ListingPanel} level.
*/
public class ListingFieldHighlightFactoryAdapter implements FieldHighlightFactory {
private ListingHighlightProvider provider;
private ListingField listingField;
/**
* Constructor
* @param provider the HighlightProvider that will actually compute the highlights.
*/
public ListingFieldHighlightFactoryAdapter(ListingHighlightProvider provider) {
this.provider = provider;
}
void setListingField(ListingField listingField) {
this.listingField = listingField;
}
@Override
public Highlight[] createHighlights(Field field, String text, int cursorTextOffset) {
if (listingField == null) {
Msg.error(this,
"Listing highlight factory not correctly setup; ListingField must be set",
ReflectionUtilities.createJavaFilteredThrowable());
return NO_HIGHLIGHTS;
}
return provider.createHighlights(text, listingField, cursorTextOffset);
}
}

View file

@ -25,9 +25,9 @@ import javax.swing.JComponent;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager; import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager;
import docking.widgets.fieldpanel.internal.PaintContext; import docking.widgets.fieldpanel.internal.PaintContext;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.proxy.EmptyProxy; import ghidra.app.util.viewer.proxy.EmptyProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -39,6 +39,7 @@ public class ListingTextField implements ListingField, TextField {
private ProxyObj<?> proxy; private ProxyObj<?> proxy;
private FieldFactory factory; private FieldFactory factory;
protected TextField field; protected TextField field;
protected ListingFieldHighlightFactoryAdapter hlFactory;
/** /**
* Creates a new ListingTextField that displays the text on a single line, clipping as needed. * Creates a new ListingTextField that displays the text on a single line, clipping as needed.
@ -53,21 +54,24 @@ public class ListingTextField implements ListingField, TextField {
*/ */
public static ListingTextField createSingleLineTextField(FieldFactory factory, public static ListingTextField createSingleLineTextField(FieldFactory factory,
ProxyObj<?> proxy, FieldElement fieldElement, int startX, int width, ProxyObj<?> proxy, FieldElement fieldElement, int startX, int width,
HighlightProvider provider) { ListingHighlightProvider provider) {
HighlightFactory hlFactory = ListingFieldHighlightFactoryAdapter hlFactory =
new FieldHighlightFactory(provider, factory.getClass(), proxy.getObject()); new ListingFieldHighlightFactoryAdapter(provider);
TextField field = new ClippingTextField(startX, width, fieldElement, hlFactory); TextField field = new ClippingTextField(startX, width, fieldElement, hlFactory);
return new ListingTextField(factory, proxy, field); ListingTextField listingField = new ListingTextField(factory, proxy, field, hlFactory);
return listingField;
} }
public static ListingTextField createSingleLineTextFieldWithReverseClipping( public static ListingTextField createSingleLineTextFieldWithReverseClipping(
AddressFieldFactory factory, ProxyObj<?> proxy, FieldElement fieldElement, int startX, AddressFieldFactory factory, ProxyObj<?> proxy, FieldElement fieldElement, int startX,
int width, HighlightProvider provider) { int width, ListingHighlightProvider provider) {
HighlightFactory hlFactory =
new FieldHighlightFactory(provider, factory.getClass(), proxy.getObject()); ListingFieldHighlightFactoryAdapter hlFactory =
new ListingFieldHighlightFactoryAdapter(provider);
TextField field = new ReverseClippingTextField(startX, width, fieldElement, hlFactory); TextField field = new ReverseClippingTextField(startX, width, fieldElement, hlFactory);
return new ListingTextField(factory, proxy, field); ListingTextField listingField = new ListingTextField(factory, proxy, field, hlFactory);
return listingField;
} }
/** /**
@ -85,13 +89,14 @@ public class ListingTextField implements ListingField, TextField {
*/ */
public static ListingTextField createWordWrappedTextField(FieldFactory factory, public static ListingTextField createWordWrappedTextField(FieldFactory factory,
ProxyObj<?> proxy, FieldElement fieldElement, int startX, int width, int maxLines, ProxyObj<?> proxy, FieldElement fieldElement, int startX, int width, int maxLines,
HighlightProvider provider) { ListingHighlightProvider provider) {
HighlightFactory hlFactory = ListingFieldHighlightFactoryAdapter hlFactory =
new FieldHighlightFactory(provider, factory.getClass(), proxy.getObject()); new ListingFieldHighlightFactoryAdapter(provider);
TextField field = TextField field =
new WrappingVerticalLayoutTextField(fieldElement, startX, width, maxLines, hlFactory); new WrappingVerticalLayoutTextField(fieldElement, startX, width, maxLines, hlFactory);
return new ListingTextField(factory, proxy, field); ListingTextField listingField = new ListingTextField(factory, proxy, field, hlFactory);
return listingField;
} }
/** /**
@ -109,13 +114,14 @@ public class ListingTextField implements ListingField, TextField {
*/ */
public static ListingTextField createPackedTextField(FieldFactory factory, ProxyObj<?> proxy, public static ListingTextField createPackedTextField(FieldFactory factory, ProxyObj<?> proxy,
FieldElement[] textElements, int startX, int width, int maxLines, FieldElement[] textElements, int startX, int width, int maxLines,
HighlightProvider provider) { ListingHighlightProvider provider) {
HighlightFactory hlFactory = ListingFieldHighlightFactoryAdapter hlFactory =
new FieldHighlightFactory(provider, factory.getClass(), proxy.getObject()); new ListingFieldHighlightFactoryAdapter(provider);
List<FieldElement> list = Arrays.asList(textElements); List<FieldElement> list = Arrays.asList(textElements);
TextField field = new FlowLayoutTextField(list, startX, width, maxLines, hlFactory); TextField field = new FlowLayoutTextField(list, startX, width, maxLines, hlFactory);
return new ListingTextField(factory, proxy, field); ListingTextField listingField = new ListingTextField(factory, proxy, field, hlFactory);
return listingField;
} }
/** /**
@ -132,20 +138,24 @@ public class ListingTextField implements ListingField, TextField {
*/ */
public static ListingTextField createMultilineTextField(FieldFactory factory, ProxyObj<?> proxy, public static ListingTextField createMultilineTextField(FieldFactory factory, ProxyObj<?> proxy,
FieldElement[] textElements, int startX, int width, int maxLines, FieldElement[] textElements, int startX, int width, int maxLines,
HighlightProvider provider) { ListingHighlightProvider provider) {
HighlightFactory hlFactory = ListingFieldHighlightFactoryAdapter hlFactory =
new FieldHighlightFactory(provider, factory.getClass(), proxy.getObject()); new ListingFieldHighlightFactoryAdapter(provider);
List<FieldElement> list = Arrays.asList(textElements); List<FieldElement> list = Arrays.asList(textElements);
TextField field = TextField field =
new VerticalLayoutTextField(list, startX, width, maxLines, hlFactory); new VerticalLayoutTextField(list, startX, width, maxLines, hlFactory);
return new ListingTextField(factory, proxy, field); ListingTextField listingField = new ListingTextField(factory, proxy, field, hlFactory);
return listingField;
} }
protected ListingTextField(FieldFactory factory, ProxyObj<?> proxy, TextField field) { protected ListingTextField(FieldFactory factory, ProxyObj<?> proxy, TextField field,
ListingFieldHighlightFactoryAdapter hlFactory) {
this.factory = factory; this.factory = factory;
this.proxy = proxy; this.proxy = proxy;
this.field = field; this.field = field;
this.hlFactory = hlFactory;
hlFactory.setListingField(this);
} }
@Override @Override
@ -303,11 +313,6 @@ public class ListingTextField implements ListingField, TextField {
return proxy; return proxy;
} }
@Override
public FieldFormatModel getFieldModel() {
return factory.getFieldModel();
}
@Override @Override
public boolean isClipped() { public boolean isClipped() {
return field.isClipped(); return field.isClipped();

View file

@ -23,7 +23,7 @@ import java.util.List;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -56,7 +56,7 @@ public class MemoryBlockStartFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private MemoryBlockStartFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private MemoryBlockStartFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -177,7 +177,7 @@ public class MemoryBlockStartFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new MemoryBlockStartFieldFactory(formatModel, provider, displayOptions, return new MemoryBlockStartFieldFactory(formatModel, provider, displayOptions,
fieldOptions); fieldOptions);

View file

@ -24,7 +24,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.MnemonicColors; import ghidra.app.util.viewer.field.ListingColors.MnemonicColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -68,7 +68,7 @@ public class MnemonicFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private MnemonicFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private MnemonicFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
@ -202,7 +202,7 @@ public class MnemonicFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new MnemonicFieldFactory(formatModel, hsProvider, displayOptions, fieldOptions); return new MnemonicFieldFactory(formatModel, hsProvider, displayOptions, fieldOptions);
} }

View file

@ -24,7 +24,6 @@ import docking.widgets.fieldpanel.internal.PaintContext;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.*;
import generic.theme.GIcon; import generic.theme.GIcon;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.EmptyProxy; import ghidra.app.util.viewer.proxy.EmptyProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
@ -82,11 +81,6 @@ public class OpenCloseField implements ListingField {
return factory; return factory;
} }
@Override
public FieldFormatModel getFieldModel() {
return factory.getFieldModel();
}
@Override @Override
public ProxyObj<?> getProxy() { public ProxyObj<?> getProxy() {
if (proxy == null) { if (proxy == null) {

View file

@ -18,7 +18,7 @@ package ghidra.app.util.viewer.field;
import java.math.BigInteger; import java.math.BigInteger;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -46,7 +46,7 @@ public class OpenCloseFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private OpenCloseFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private OpenCloseFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
servicesChanged(); servicesChanged();
@ -154,7 +154,7 @@ public class OpenCloseFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel fieldModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel fieldModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new OpenCloseFieldFactory(fieldModel, provider, displayOptions, fieldOptions); return new OpenCloseFieldFactory(fieldModel, provider, displayOptions, fieldOptions);
} }

View file

@ -18,7 +18,7 @@ package ghidra.app.util.viewer.field;
import java.math.BigInteger; import java.math.BigInteger;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
@ -43,7 +43,7 @@ public class OperandFieldFactory extends OperandFieldHelper {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected OperandFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, protected OperandFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -89,7 +89,7 @@ public class OperandFieldFactory extends OperandFieldHelper {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new OperandFieldFactory(formatModel, hsProvider, displayOptions, fieldOptions); return new OperandFieldFactory(formatModel, hsProvider, displayOptions, fieldOptions);
} }

View file

@ -96,7 +96,7 @@ abstract class OperandFieldHelper extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
OperandFieldHelper(String name, FieldFormatModel model, HighlightProvider hlProvider, OperandFieldHelper(String name, FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(name, model, hlProvider, displayOptions, fieldOptions); super(name, model, hlProvider, displayOptions, fieldOptions);

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -52,7 +52,7 @@ public class ParallelInstructionFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private ParallelInstructionFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private ParallelInstructionFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@ -117,7 +117,7 @@ public class ParallelInstructionFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions toolOptinos, ToolOptions fieldOptions) { ToolOptions toolOptinos, ToolOptions fieldOptions) {
return new ParallelInstructionFieldFactory(formatModel, hsProvider, toolOptinos, return new ParallelInstructionFieldFactory(formatModel, hsProvider, toolOptinos,
fieldOptions); fieldOptions);

View file

@ -26,7 +26,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.*;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.util.HelpTopics; import ghidra.app.util.HelpTopics;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.CommentColors; import ghidra.app.util.viewer.field.ListingColors.CommentColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
@ -112,7 +112,7 @@ public class PlateFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private PlateFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private PlateFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
init(fieldOptions); init(fieldOptions);
@ -161,9 +161,13 @@ public class PlateFieldFactory extends FieldFactory {
return null; return null;
} }
ListingFieldHighlightFactoryAdapter hlFactory =
new ListingFieldHighlightFactoryAdapter(hlProvider);
PlateFieldTextField textField = PlateFieldTextField textField =
new PlateFieldTextField(elements, this, proxy, startX, width, commentText, isClipped); new PlateFieldTextField(elements, this, proxy, startX, width, commentText, isClipped,
return new PlateListingTextField(proxy, textField); hlFactory);
PlateListingTextField listingField = new PlateListingTextField(proxy, textField, hlFactory);
return listingField;
} }
private boolean getFormattedFieldElements(CodeUnit cu, List<FieldElement> elements) { private boolean getFormattedFieldElements(CodeUnit cu, List<FieldElement> elements) {
@ -567,7 +571,8 @@ public class PlateFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel,
ListingHighlightProvider hsProvider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new PlateFieldFactory(formatModel, hsProvider, toolOptions, fieldOptions); return new PlateFieldFactory(formatModel, hsProvider, toolOptions, fieldOptions);
} }
@ -718,8 +723,9 @@ public class PlateFieldFactory extends FieldFactory {
class PlateListingTextField extends ListingTextField { class PlateListingTextField extends ListingTextField {
PlateListingTextField(ProxyObj<?> proxy, PlateFieldTextField field) { PlateListingTextField(ProxyObj<?> proxy, PlateFieldTextField field,
super(PlateFieldFactory.this, proxy, field); ListingFieldHighlightFactoryAdapter hlFactory) {
super(PlateFieldFactory.this, proxy, field, hlFactory);
} }
PlateFieldTextField getPlateTextField() { PlateFieldTextField getPlateTextField() {
@ -734,9 +740,8 @@ public class PlateFieldFactory extends FieldFactory {
PlateFieldTextField(List<FieldElement> textElements, PlateFieldFactory factory, PlateFieldTextField(List<FieldElement> textElements, PlateFieldFactory factory,
ProxyObj<?> proxy, int startX, int width, String commentText, ProxyObj<?> proxy, int startX, int width, String commentText,
boolean isCommentClipped) { boolean isCommentClipped, FieldHighlightFactory hlFactory) {
super(textElements, startX, width, Integer.MAX_VALUE, super(textElements, startX, width, Integer.MAX_VALUE, hlFactory);
new FieldHighlightFactory(hlProvider, factory.getClass(), proxy.getObject()));
this.commentText = commentText; this.commentText = commentText;
this.isCommentClipped = isCommentClipped; this.isCommentClipped = isCommentClipped;
} }

View file

@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.FieldUtils; import docking.widgets.fieldpanel.support.FieldUtils;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.CommentColors; import ghidra.app.util.viewer.field.ListingColors.CommentColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.options.OptionsGui; import ghidra.app.util.viewer.options.OptionsGui;
@ -89,7 +89,7 @@ public class PostCommentFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private PostCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private PostCommentFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -323,7 +323,7 @@ public class PostCommentFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new PostCommentFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new PostCommentFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }

View file

@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.FieldUtils; import docking.widgets.fieldpanel.support.FieldUtils;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.CommentColors; import ghidra.app.util.viewer.field.ListingColors.CommentColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.options.OptionsGui; import ghidra.app.util.viewer.options.OptionsGui;
@ -82,7 +82,7 @@ public class PreCommentFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private PreCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private PreCommentFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -179,7 +179,7 @@ public class PreCommentFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new PreCommentFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new PreCommentFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }

View file

@ -20,7 +20,7 @@ import java.util.*;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -52,7 +52,7 @@ public class RegisterFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private RegisterFieldFactory(FieldFormatModel model, HighlightProvider highlightProvider, private RegisterFieldFactory(FieldFormatModel model, ListingHighlightProvider highlightProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, highlightProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, highlightProvider, displayOptions, fieldOptions);
regComp = new RegComparator(); regComp = new RegComparator();
@ -73,7 +73,7 @@ public class RegisterFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions toolOptions, ListingHighlightProvider highlightProvider, ToolOptions toolOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new RegisterFieldFactory(formatModel, highlightProvider, toolOptions, fieldOptions); return new RegisterFieldFactory(formatModel, highlightProvider, toolOptions, fieldOptions);
} }

View file

@ -22,7 +22,7 @@ import java.util.List;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.cmd.function.CallDepthChangeInfo; import ghidra.app.cmd.function.CallDepthChangeInfo;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -55,7 +55,7 @@ public class RegisterTransitionFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private RegisterTransitionFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private RegisterTransitionFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
initOptions(displayOptions, fieldOptions); initOptions(displayOptions, fieldOptions);
@ -242,7 +242,7 @@ public class RegisterTransitionFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel fieldFormatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel fieldFormatModel, ListingHighlightProvider hsProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new RegisterTransitionFieldFactory(fieldFormatModel, hsProvider, displayOptions, return new RegisterTransitionFieldFactory(fieldFormatModel, hsProvider, displayOptions,
fieldOptions); fieldOptions);

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -52,7 +52,7 @@ public class SeparatorFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private SeparatorFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private SeparatorFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -115,7 +115,7 @@ public class SeparatorFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new SeparatorFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new SeparatorFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -51,7 +51,7 @@ public class SpaceFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private SpaceFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private SpaceFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -146,10 +146,10 @@ public class SpaceFieldFactory extends FieldFactory {
} }
/** /**
* @see ghidra.app.util.viewer.field.FieldFactory#newInstance(ghidra.app.util.viewer.format.FieldFormatModel, ghidra.app.util.HighlightProvider, ghidra.framework.options.ToolOptions, ghidra.framework.options.ToolOptions) * @see ghidra.app.util.viewer.field.FieldFactory#newInstance(ghidra.app.util.viewer.format.FieldFormatModel, ghidra.app.util.ListingHighlightProvider, ghidra.framework.options.ToolOptions, ghidra.framework.options.ToolOptions)
*/ */
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new SpaceFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new SpaceFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }

View file

@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -52,7 +52,7 @@ public class SpacerFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private SpacerFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private SpacerFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@ -65,7 +65,7 @@ public class SpacerFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public SpacerFieldFactory(String text, FieldFormatModel model, HighlightProvider hsProvider, public SpacerFieldFactory(String text, FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
@ -179,7 +179,7 @@ public class SpacerFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new SpacerFieldFactory(formatModel, provider, options, fieldOptions); return new SpacerFieldFactory(formatModel, provider, options, fieldOptions);
} }

View file

@ -18,7 +18,7 @@ package ghidra.app.util.viewer.field;
import java.math.BigInteger; import java.math.BigInteger;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
@ -48,7 +48,7 @@ public class SubDataFieldFactory extends OperandFieldFactory {
} }
private SubDataFieldFactory(String name, int[] componentPath, FieldFormatModel model, private SubDataFieldFactory(String name, int[] componentPath, FieldFormatModel model,
HighlightProvider hlProvider, ToolOptions displayOptions, ToolOptions fieldOptions) { ListingHighlightProvider hlProvider, ToolOptions displayOptions, ToolOptions fieldOptions) {
super(model, hlProvider, displayOptions, fieldOptions); super(model, hlProvider, displayOptions, fieldOptions);
this.name = name; this.name = name;
this.componentPath = componentPath; this.componentPath = componentPath;
@ -125,7 +125,7 @@ public class SubDataFieldFactory extends OperandFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new SubDataFieldFactory(name, componentPath, formatModel, provider, options, return new SubDataFieldFactory(name, componentPath, formatModel, provider, options,
fieldOptions); fieldOptions);

View file

@ -21,7 +21,7 @@ import java.util.ArrayList;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -54,7 +54,7 @@ public class ThunkedFunctionFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public ThunkedFunctionFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public ThunkedFunctionFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -139,7 +139,7 @@ public class ThunkedFunctionFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions pDisplayOptions, ToolOptions fieldOptions) { ToolOptions pDisplayOptions, ToolOptions fieldOptions) {
return new ThunkedFunctionFieldFactory(formatModel, provider, pDisplayOptions, return new ThunkedFunctionFieldFactory(formatModel, provider, pDisplayOptions,
fieldOptions); fieldOptions);

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.app.util.viewer.proxy.VariableProxy; import ghidra.app.util.viewer.proxy.VariableProxy;
@ -50,7 +50,7 @@ public class VariableCommentFieldFactory extends AbstractVariableFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private VariableCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private VariableCommentFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -175,7 +175,7 @@ public class VariableCommentFieldFactory extends AbstractVariableFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new VariableCommentFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new VariableCommentFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }

View file

@ -24,7 +24,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GIcon; import generic.theme.GIcon;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.app.util.viewer.proxy.VariableProxy; import ghidra.app.util.viewer.proxy.VariableProxy;
@ -59,7 +59,7 @@ public class VariableLocFieldFactory extends AbstractVariableFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private VariableLocFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private VariableLocFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -145,7 +145,7 @@ public class VariableLocFieldFactory extends AbstractVariableFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new VariableLocFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new VariableLocFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.app.util.viewer.proxy.VariableProxy; import ghidra.app.util.viewer.proxy.VariableProxy;
@ -49,7 +49,7 @@ public class VariableNameFieldFactory extends AbstractVariableFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private VariableNameFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private VariableNameFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -123,7 +123,7 @@ public class VariableNameFieldFactory extends AbstractVariableFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new VariableNameFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new VariableNameFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.app.util.viewer.proxy.VariableProxy; import ghidra.app.util.viewer.proxy.VariableProxy;
@ -50,7 +50,7 @@ public class VariableTypeFieldFactory extends AbstractVariableFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private VariableTypeFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private VariableTypeFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -139,7 +139,7 @@ public class VariableTypeFieldFactory extends AbstractVariableFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new VariableTypeFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new VariableTypeFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }

View file

@ -22,7 +22,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.XReferenceUtils; import ghidra.app.util.XReferenceUtils;
import ghidra.app.util.viewer.field.ListingColors.XrefColors; import ghidra.app.util.viewer.field.ListingColors.XrefColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
@ -62,13 +62,13 @@ public class VariableXRefFieldFactory extends XRefFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public VariableXRefFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public VariableXRefFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
this(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); this(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
protected VariableXRefFieldFactory(String name, FieldFormatModel model, protected VariableXRefFieldFactory(String name, FieldFormatModel model,
HighlightProvider hlProvider, Options displayOptions, ToolOptions fieldOptions) { ListingHighlightProvider hlProvider, Options displayOptions, ToolOptions fieldOptions) {
super(name, model, hlProvider, displayOptions, fieldOptions); super(name, model, hlProvider, displayOptions, fieldOptions);
} }
@ -229,7 +229,7 @@ public class VariableXRefFieldFactory extends XRefFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new VariableXRefFieldFactory(formatModel, provider, options, fieldOptions); return new VariableXRefFieldFactory(formatModel, provider, options, fieldOptions);
} }

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.XrefColors; import ghidra.app.util.viewer.field.ListingColors.XrefColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@ -55,7 +55,7 @@ public class VariableXRefHeaderFieldFactory extends VariableXRefFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public VariableXRefHeaderFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public VariableXRefHeaderFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
colorOptionName = "XRef Color"; colorOptionName = "XRef Color";
@ -176,7 +176,7 @@ public class VariableXRefHeaderFieldFactory extends VariableXRefFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new VariableXRefHeaderFieldFactory(formatModel, provider, displayOptions, return new VariableXRefHeaderFieldFactory(formatModel, provider, displayOptions,
fieldOptions); fieldOptions);

View file

@ -28,7 +28,7 @@ import javax.swing.event.ChangeListener;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.*;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.XReferenceUtils; import ghidra.app.util.XReferenceUtils;
import ghidra.app.util.viewer.field.ListingColors.XrefColors; import ghidra.app.util.viewer.field.ListingColors.XrefColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
@ -106,7 +106,7 @@ public class XRefFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public XRefFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public XRefFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
this(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); this(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@ -121,7 +121,8 @@ public class XRefFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected XRefFieldFactory(String name, FieldFormatModel model, HighlightProvider hlProvider, protected XRefFieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
super(name, model, hlProvider, displayOptions, fieldOptions); super(name, model, hlProvider, displayOptions, fieldOptions);
@ -322,8 +323,8 @@ public class XRefFieldFactory extends FieldFactory {
// //
Set<Reference> offcutSet = new HashSet<>(offcuts); Set<Reference> offcutSet = new HashSet<>(offcuts);
Predicate<Reference> isOffcut = r -> offcutSet.contains(r); Predicate<Reference> isOffcut = r -> offcutSet.contains(r);
HighlightFactory hlFactory = ListingFieldHighlightFactoryAdapter hlFactory =
new FieldHighlightFactory(hlProvider, getClass(), proxy.getObject()); new ListingFieldHighlightFactoryAdapter(hlProvider);
Function currentFunction = functionManager.getFunctionContaining(cu.getMinAddress()); Function currentFunction = functionManager.getFunctionContaining(cu.getMinAddress());
List<TextField> functionRows = createXrefRowsByFunction(program, currentFunction, List<TextField> functionRows = createXrefRowsByFunction(program, currentFunction,
xrefsByFunction, isOffcut, varWidth, hlFactory); xrefsByFunction, isOffcut, varWidth, hlFactory);
@ -372,12 +373,14 @@ public class XRefFieldFactory extends FieldFactory {
CompositeVerticalLayoutTextField compositefield = CompositeVerticalLayoutTextField compositefield =
new CompositeVerticalLayoutTextField(allFields, newStartX, width, maxXRefs, hlFactory); new CompositeVerticalLayoutTextField(allFields, newStartX, width, maxXRefs, hlFactory);
return new XrefListingField(this, proxy, compositefield); XrefListingField listingField =
new XrefListingField(this, proxy, compositefield, hlFactory);
return listingField;
} }
private List<TextField> createXrefRowsByFunction(Program program, Function currentFunction, private List<TextField> createXrefRowsByFunction(Program program, Function currentFunction,
TreeMap<Function, List<Reference>> xrefsByFunction, Predicate<Reference> isOffcut, TreeMap<Function, List<Reference>> xrefsByFunction, Predicate<Reference> isOffcut,
int varWidth, HighlightFactory hlFactory) { int varWidth, FieldHighlightFactory hlFactory) {
FontMetrics metrics = getMetrics(); FontMetrics metrics = getMetrics();
AttributedString delimiter = new AttributedString(delim, Colors.FOREGROUND, metrics); AttributedString delimiter = new AttributedString(delim, Colors.FOREGROUND, metrics);
@ -436,7 +439,7 @@ public class XRefFieldFactory extends FieldFactory {
private TextField createWrappingXrefRow(Program program, int startRow, List<Reference> xrefs, private TextField createWrappingXrefRow(Program program, int startRow, List<Reference> xrefs,
Function currentFunction, Predicate<Reference> isOffcut, int availableLines, Function currentFunction, Predicate<Reference> isOffcut, int availableLines,
HighlightFactory hlFactory) { FieldHighlightFactory hlFactory) {
FontMetrics metrics = getMetrics(); FontMetrics metrics = getMetrics();
AttributedString delimiter = new AttributedString(delim, Colors.FOREGROUND, metrics); AttributedString delimiter = new AttributedString(delim, Colors.FOREGROUND, metrics);
@ -531,10 +534,11 @@ public class XRefFieldFactory extends FieldFactory {
// assumption: the given array has been limited to the maxXref size already // assumption: the given array has been limited to the maxXref size already
int n = list.size(); int n = list.size();
HighlightFactory hlFactory = ListingFieldHighlightFactoryAdapter hlFactory =
new FieldHighlightFactory(hlProvider, getClass(), proxy.getObject()); new ListingFieldHighlightFactoryAdapter(hlProvider);
TextField field = new FlowLayoutTextField(list, startX + varWidth, width, n, hlFactory); TextField field = new FlowLayoutTextField(list, startX + varWidth, width, n, hlFactory);
return new XrefListingField(this, proxy, field); XrefListingField listingField = new XrefListingField(this, proxy, field, hlFactory);
return listingField;
} }
private List<FieldElement> toFieldElements(List<XrefFieldElement> list, boolean showEllipses) { private List<FieldElement> toFieldElements(List<XrefFieldElement> list, boolean showEllipses) {
@ -816,7 +820,8 @@ public class XRefFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel,
ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new XRefFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new XRefFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }
@ -887,8 +892,9 @@ public class XRefFieldFactory extends FieldFactory {
private class XrefListingField extends ListingTextField { private class XrefListingField extends ListingTextField {
XrefListingField(XRefFieldFactory factory, ProxyObj<?> proxy, TextField field) { XrefListingField(XRefFieldFactory factory, ProxyObj<?> proxy, TextField field,
super(factory, proxy, field); ListingFieldHighlightFactoryAdapter hlFactory) {
super(factory, proxy, field, hlFactory);
} }
} }

View file

@ -20,7 +20,7 @@ import java.util.List;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.XReferenceUtils; import ghidra.app.util.XReferenceUtils;
import ghidra.app.util.viewer.field.ListingColors.XrefColors; import ghidra.app.util.viewer.field.ListingColors.XrefColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
@ -50,7 +50,7 @@ public class XRefHeaderFieldFactory extends XRefFieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public XRefHeaderFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public XRefHeaderFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
super(XREF_FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(XREF_FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@ -116,7 +116,7 @@ public class XRefHeaderFieldFactory extends XRefFieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new XRefHeaderFieldFactory(formatModel, provider, options, fieldOptions); return new XRefHeaderFieldFactory(formatModel, provider, options, fieldOptions);
} }

View file

@ -21,7 +21,7 @@ import org.jdom.Element;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.RowLayout; import docking.widgets.fieldpanel.support.RowLayout;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@ -151,7 +151,7 @@ public class FieldFormatModel {
* @param colIndex the position in the row for the new field. * @param colIndex the position in the row for the new field.
*/ */
public void addFactory(FieldFactory factory, int rowIndex, int colIndex) { public void addFactory(FieldFactory factory, int rowIndex, int colIndex) {
HighlightProvider hsProvider = formatMgr.getFormatHighlightProvider(); ListingHighlightProvider hsProvider = formatMgr.getFormatHighlightProvider();
ToolOptions displayOptions = formatMgr.getDisplayOptions(); ToolOptions displayOptions = formatMgr.getDisplayOptions();
ToolOptions fieldOptions = formatMgr.getFieldOptions(); ToolOptions fieldOptions = formatMgr.getFieldOptions();
FieldFactory ff = factory.newInstance(this, hsProvider, displayOptions, fieldOptions); FieldFactory ff = factory.newInstance(this, hsProvider, displayOptions, fieldOptions);

View file

@ -22,7 +22,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.jdom.Element; import org.jdom.Element;
import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.template.TemplateSimplifier; import ghidra.app.util.template.TemplateSimplifier;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.framework.options.*; import ghidra.framework.options.*;
@ -824,10 +824,10 @@ public class FormatManager implements OptionsChangeListener {
* *
* @param provider * @param provider
* the provider to use. * the provider to use.
* @see #removeHighlightProvider(HighlightProvider) * @see #removeHighlightProvider(ListingHighlightProvider)
* @see #getHighlightProviders() * @see #getHighlightProviders()
*/ */
public void addHighlightProvider(HighlightProvider provider) { public void addHighlightProvider(ListingHighlightProvider provider) {
if (provider instanceof MultipleHighlighterProvider) { if (provider instanceof MultipleHighlighterProvider) {
throw new AssertException("Cannot set FormatManager's internal highlight provider " + throw new AssertException("Cannot set FormatManager's internal highlight provider " +
"on another FormatManager!"); "on another FormatManager!");
@ -840,27 +840,27 @@ public class FormatManager implements OptionsChangeListener {
* *
* @param provider * @param provider
* the provider to remove. * the provider to remove.
* @see #addHighlightProvider(HighlightProvider) * @see #addHighlightProvider(ListingHighlightProvider)
*/ */
public void removeHighlightProvider(HighlightProvider provider) { public void removeHighlightProvider(ListingHighlightProvider provider) {
highlightProvider.removeHighlightProvider(provider); highlightProvider.removeHighlightProvider(provider);
} }
/** /**
* Gets all {@link HighlightProvider}s installed on this FormatManager via the * Gets all {@link ListingHighlightProvider}s installed on this FormatManager via the
* {@link #addHighlightProvider(HighlightProvider)}. * {@link #addHighlightProvider(ListingHighlightProvider)}.
* *
* @return all {@link HighlightProvider}s installed on this FormatManager. * @return all {@link ListingHighlightProvider}s installed on this FormatManager.
*/ */
public List<HighlightProvider> getHighlightProviders() { public List<ListingHighlightProvider> getHighlightProviders() {
return highlightProvider.getHighlightProviders(); return highlightProvider.getHighlightProviders();
} }
/** /**
* Returns the {@link HighlightProvider} that should be used when creating {@link FieldFactory} * Returns the {@link ListingHighlightProvider} that should be used when creating {@link FieldFactory}
* objects. * objects.
*/ */
public HighlightProvider getFormatHighlightProvider() { public ListingHighlightProvider getFormatHighlightProvider() {
return highlightProvider; return highlightProvider;
} }
@ -921,13 +921,13 @@ public class FormatManager implements OptionsChangeListener {
// Inner Classes // Inner Classes
//================================================================================================== //==================================================================================================
private class MultipleHighlighterProvider implements HighlightProvider { private class MultipleHighlighterProvider implements ListingHighlightProvider {
private List<HighlightProvider> highlightProviders = new CopyOnWriteArrayList<>(); private List<ListingHighlightProvider> highlightProviders =
new CopyOnWriteArrayList<>();
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
// //
// Gather and use all other registered providers. // Gather and use all other registered providers.
@ -935,13 +935,13 @@ public class FormatManager implements OptionsChangeListener {
// Note: we loop backwards here as a hacky method to make sure that the middle-mouse // Note: we loop backwards here as a hacky method to make sure that the middle-mouse
// highlighter runs last and is thus painted above other highlights. This // highlighter runs last and is thus painted above other highlights. This
// works because the middle-mouse highlighter is installed before any other // works because the middle-mouse highlighter is installed before any other
// highlighters. // highlighters.
List<Highlight> list = new ArrayList<>(); List<Highlight> list = new ArrayList<>();
int size = highlightProviders.size(); int size = highlightProviders.size();
for (int i = size - 1; i >= 0; i--) { for (int i = size - 1; i >= 0; i--) {
HighlightProvider provider = highlightProviders.get(i); ListingHighlightProvider provider = highlightProviders.get(i);
Highlight[] highlights = Highlight[] highlights =
provider.getHighlights(text, obj, fieldFactoryClass, cursorTextOffset); provider.createHighlights(text, field, cursorTextOffset);
for (Highlight highlight : highlights) { for (Highlight highlight : highlights) {
list.add(highlight); list.add(highlight);
} }
@ -950,17 +950,17 @@ public class FormatManager implements OptionsChangeListener {
return list.toArray(new Highlight[list.size()]); return list.toArray(new Highlight[list.size()]);
} }
List<HighlightProvider> getHighlightProviders() { List<ListingHighlightProvider> getHighlightProviders() {
return new ArrayList<>(highlightProviders); return new ArrayList<>(highlightProviders);
} }
void addHighlightProvider(HighlightProvider provider) { void addHighlightProvider(ListingHighlightProvider provider) {
if (!highlightProviders.contains(provider)) { if (!highlightProviders.contains(provider)) {
highlightProviders.add(provider); highlightProviders.add(provider);
} }
} }
void removeHighlightProvider(HighlightProvider provider) { void removeHighlightProvider(ListingHighlightProvider provider) {
highlightProviders.remove(provider); highlightProviders.remove(provider);
} }
} }

View file

@ -19,7 +19,7 @@ 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.ListingHighlightProvider;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
@ -152,12 +152,12 @@ class DualListingNavigator implements Navigatable {
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// currently unsupported // currently unsupported
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, Program program) { public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// currently unsupported // currently unsupported
} }
} }

View file

@ -43,7 +43,7 @@ import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel;
import ghidra.app.plugin.core.codebrowser.hover.*; import ghidra.app.plugin.core.codebrowser.hover.*;
import ghidra.app.plugin.core.marker.MarkerManager; import ghidra.app.plugin.core.marker.MarkerManager;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.SymbolPath; import ghidra.app.util.SymbolPath;
import ghidra.app.util.viewer.format.*; import ghidra.app.util.viewer.format.*;
import ghidra.app.util.viewer.util.*; import ghidra.app.util.viewer.util.*;
@ -308,17 +308,17 @@ public class ListingCodeComparisonPanel
* @param leftHighlightProvider the highlight provider for the left side's listing. * @param leftHighlightProvider the highlight provider for the left side's listing.
* @param rightHighlightProvider the highlight provider for the right side's listing. * @param rightHighlightProvider the highlight provider for the right side's listing.
*/ */
public void addHighlightProviders(HighlightProvider leftHighlightProvider, public void addHighlightProviders(ListingHighlightProvider leftHighlightProvider,
HighlightProvider rightHighlightProvider) { ListingHighlightProvider rightHighlightProvider) {
addLeftHighlightProvider(leftHighlightProvider); addLeftHighlightProvider(leftHighlightProvider);
addRightHighlightProvider(rightHighlightProvider); addRightHighlightProvider(rightHighlightProvider);
} }
private void addLeftHighlightProvider(HighlightProvider leftHighlightProvider) { private void addLeftHighlightProvider(ListingHighlightProvider leftHighlightProvider) {
listingPanels[LEFT].getFormatManager().addHighlightProvider(leftHighlightProvider); listingPanels[LEFT].getFormatManager().addHighlightProvider(leftHighlightProvider);
} }
private void addRightHighlightProvider(HighlightProvider rightHighlightProvider) { private void addRightHighlightProvider(ListingHighlightProvider rightHighlightProvider) {
listingPanels[RIGHT].getFormatManager().addHighlightProvider(rightHighlightProvider); listingPanels[RIGHT].getFormatManager().addHighlightProvider(rightHighlightProvider);
} }
@ -328,17 +328,17 @@ public class ListingCodeComparisonPanel
* @param leftHighlightProvider the highlight provider for the left side's listing. * @param leftHighlightProvider the highlight provider for the left side's listing.
* @param rightHighlightProvider the highlight provider for the right side's listing. * @param rightHighlightProvider the highlight provider for the right side's listing.
*/ */
public void removeHighlightProviders(HighlightProvider leftHighlightProvider, public void removeHighlightProviders(ListingHighlightProvider leftHighlightProvider,
HighlightProvider rightHighlightProvider) { ListingHighlightProvider rightHighlightProvider) {
removeLeftHighlightProvider(leftHighlightProvider); removeLeftHighlightProvider(leftHighlightProvider);
removeRightHighlightProvider(rightHighlightProvider); removeRightHighlightProvider(rightHighlightProvider);
} }
private void removeLeftHighlightProvider(HighlightProvider leftHighlightProvider) { private void removeLeftHighlightProvider(ListingHighlightProvider leftHighlightProvider) {
listingPanels[LEFT].getFormatManager().removeHighlightProvider(leftHighlightProvider); listingPanels[LEFT].getFormatManager().removeHighlightProvider(leftHighlightProvider);
} }
private void removeRightHighlightProvider(HighlightProvider rightHighlightProvider) { private void removeRightHighlightProvider(ListingHighlightProvider rightHighlightProvider) {
listingPanels[RIGHT].getFormatManager().removeHighlightProvider(rightHighlightProvider); listingPanels[RIGHT].getFormatManager().removeHighlightProvider(rightHighlightProvider);
} }

View file

@ -19,14 +19,15 @@ import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.CodeUnit; import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.Instruction; import ghidra.program.model.listing.Instruction;
import ghidra.program.util.ListingDiff; import ghidra.program.util.ListingDiff;
public class ListingDiffHighlightProvider implements HighlightProvider { public class ListingDiffHighlightProvider implements ListingHighlightProvider {
private static final int NUM_CHARACTERS_PER_BYTE = 3; // 2 hex digits and a space; private static final int NUM_CHARACTERS_PER_BYTE = 3; // 2 hex digits and a space;
private static final String DEFAULT_OPERAND_SEPARATOR = ","; private static final String DEFAULT_OPERAND_SEPARATOR = ",";
@ -52,13 +53,14 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Highlight[] highlights = EMPTY_HIGHLIGHT; Highlight[] highlights = NO_HIGHLIGHTS;
if (obj instanceof CodeUnit) { ProxyObj<?> proxy = field.getProxy();
CodeUnit codeUnit = (CodeUnit) obj; Object obj = proxy.getObject();
if (obj instanceof CodeUnit codeUnit) {
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
if (fieldFactoryClass == BytesFieldFactory.class) { if (fieldFactoryClass == BytesFieldFactory.class) {
highlights = getByteDiffHighlights(text, codeUnit, cursorTextOffset); highlights = getByteDiffHighlights(text, codeUnit, cursorTextOffset);
} }
@ -78,7 +80,7 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
AddressSetView unmatchedDiffs = (isListing1) ? listingDiff.getListing1UnmatchedCode() AddressSetView unmatchedDiffs = (isListing1) ? listingDiff.getListing1UnmatchedCode()
: listingDiff.getListing2UnmatchedCode(); : listingDiff.getListing2UnmatchedCode();
if (unmatchedDiffs.contains(minAddress)) { if (unmatchedDiffs.contains(minAddress)) {
return EMPTY_HIGHLIGHT; return NO_HIGHLIGHTS;
} }
Color byteDiffsBackgroundColor = comparisonOptions.getByteDiffsBackgroundColor(); Color byteDiffsBackgroundColor = comparisonOptions.getByteDiffsBackgroundColor();
AddressSetView byteDiffs = AddressSetView byteDiffs =
@ -100,7 +102,7 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
} }
return highlights.toArray(new Highlight[highlights.size()]); return highlights.toArray(new Highlight[highlights.size()]);
} }
return EMPTY_HIGHLIGHT; return NO_HIGHLIGHTS;
} }
private Highlight[] getMnemonicDiffHighlights(String text, CodeUnit codeUnit, private Highlight[] getMnemonicDiffHighlights(String text, CodeUnit codeUnit,
@ -109,7 +111,7 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
AddressSetView unmatchedDiffs = (isListing1) ? listingDiff.getListing1UnmatchedCode() AddressSetView unmatchedDiffs = (isListing1) ? listingDiff.getListing1UnmatchedCode()
: listingDiff.getListing2UnmatchedCode(); : listingDiff.getListing2UnmatchedCode();
if (unmatchedDiffs.contains(minAddress)) { if (unmatchedDiffs.contains(minAddress)) {
return EMPTY_HIGHLIGHT; return NO_HIGHLIGHTS;
} }
Color mnemonicDiffsBackgroundColor = comparisonOptions.getMnemonicDiffsBackgroundColor(); Color mnemonicDiffsBackgroundColor = comparisonOptions.getMnemonicDiffsBackgroundColor();
AddressSetView codeUnitDiffs = (isListing1) ? listingDiff.getListing1CodeUnitDiffs() AddressSetView codeUnitDiffs = (isListing1) ? listingDiff.getListing1CodeUnitDiffs()
@ -129,7 +131,7 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
return entireTextHighlight(text, cursorTextOffset, mnemonicDiffsBackgroundColor); return entireTextHighlight(text, cursorTextOffset, mnemonicDiffsBackgroundColor);
} }
} }
return EMPTY_HIGHLIGHT; return NO_HIGHLIGHTS;
} }
private Highlight[] getOperandDiffHighlights(String text, CodeUnit codeUnit, private Highlight[] getOperandDiffHighlights(String text, CodeUnit codeUnit,
@ -138,7 +140,7 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
AddressSetView unmatchedDiffs = (isListing1) ? listingDiff.getListing1UnmatchedCode() AddressSetView unmatchedDiffs = (isListing1) ? listingDiff.getListing1UnmatchedCode()
: listingDiff.getListing2UnmatchedCode(); : listingDiff.getListing2UnmatchedCode();
if (unmatchedDiffs.contains(minAddress)) { if (unmatchedDiffs.contains(minAddress)) {
return EMPTY_HIGHLIGHT; return NO_HIGHLIGHTS;
} }
Color operandDiffsBackgroundColor = comparisonOptions.getOperandDiffsBackgroundColor(); Color operandDiffsBackgroundColor = comparisonOptions.getOperandDiffsBackgroundColor();
AddressSetView codeUnitDiffs = (isListing1) ? listingDiff.getListing1CodeUnitDiffs() AddressSetView codeUnitDiffs = (isListing1) ? listingDiff.getListing1CodeUnitDiffs()
@ -165,7 +167,7 @@ public class ListingDiffHighlightProvider implements HighlightProvider {
} }
return highlights.toArray(new Highlight[highlights.size()]); return highlights.toArray(new Highlight[highlights.size()]);
} }
return EMPTY_HIGHLIGHT; return NO_HIGHLIGHTS;
} }
/** /**

View file

@ -36,7 +36,7 @@ import generic.theme.GThemeDefaults.Colors;
import ghidra.app.plugin.core.codebrowser.LayeredColorModel; import ghidra.app.plugin.core.codebrowser.LayeredColorModel;
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService; import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
import ghidra.app.services.ButtonPressedListener; import ghidra.app.services.ButtonPressedListener;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.FieldFactory;
import ghidra.app.util.viewer.field.ListingField; import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.format.FieldHeader; import ghidra.app.util.viewer.format.FieldHeader;
@ -449,22 +449,22 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
} }
/** /**
* Removes the given {@link HighlightProvider} from this listing. * Removes the given {@link ListingHighlightProvider} from this listing.
* *
* @param highlightProvider The provider to remove. * @param highlightProvider The provider to remove.
* @see #addHighlightProvider(HighlightProvider) * @see #addHighlightProvider(ListingHighlightProvider)
*/ */
public void removeHighlightProvider(HighlightProvider highlightProvider) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider) {
formatManager.removeHighlightProvider(highlightProvider); formatManager.removeHighlightProvider(highlightProvider);
} }
/** /**
* Adds a {@link HighlightProvider} to this listing. This highlight provider will be used with * Adds a {@link ListingHighlightProvider} to this listing. This highlight provider will be used with
* any other registered providers to paint all the highlights for this listing. * any other registered providers to paint all the highlights for this listing.
* *
* @param highlightProvider The provider to add * @param highlightProvider The provider to add
*/ */
public void addHighlightProvider(HighlightProvider highlightProvider) { public void addHighlightProvider(ListingHighlightProvider highlightProvider) {
formatManager.addHighlightProvider(highlightProvider); formatManager.addHighlightProvider(highlightProvider);
} }
@ -1157,11 +1157,11 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
} }
public void setFormatManager(FormatManager formatManager) { public void setFormatManager(FormatManager formatManager) {
List<HighlightProvider> highlightProviders = this.formatManager.getHighlightProviders(); List<ListingHighlightProvider> highlightProviders = this.formatManager.getHighlightProviders();
this.formatManager = formatManager; this.formatManager = formatManager;
for (HighlightProvider provider : highlightProviders) { for (ListingHighlightProvider provider : highlightProviders) {
this.formatManager.addHighlightProvider(provider); this.formatManager.addHighlightProvider(provider);
} }

View file

@ -47,7 +47,7 @@ import ghidra.util.SystemUtilities;
*/ */
public class OptionsGui extends JPanel { public class OptionsGui extends JPanel {
private static final Highlight[] NO_HIGHLIGHTS = new Highlight[0]; private static final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
private static final HighlightFactory hlFactory = private static final FieldHighlightFactory hlFactory =
(field, text, cursorTextOffset) -> NO_HIGHLIGHTS; (field, text, cursorTextOffset) -> NO_HIGHLIGHTS;
// @formatter:off // @formatter:off
@ -895,7 +895,7 @@ public class OptionsGui extends JPanel {
private ScreenElement screenElement; private ScreenElement screenElement;
ScreenElementTextField(ScreenElement screenElement, int startX, int length, ScreenElementTextField(ScreenElement screenElement, int startX, int length,
FieldElement field, HighlightFactory factory) { FieldElement field, FieldHighlightFactory factory) {
super(startX, length, field, factory); super(startX, length, field, factory);
this.screenElement = screenElement; this.screenElement = screenElement;
} }

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.
@ -20,14 +19,15 @@ import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
/** /**
* Stores information about a address in a program such that the address can * Stores information about an address in a program.
* be retrieved when needed.
*/ */
public class AddressProxy extends ProxyObj<Address> { public class AddressProxy extends ProxyObj<Address> {
Address addr;
private Address addr;
/** /**
* Construct a address proxy * Construct a address proxy
* @param model the model
* @param addr the address to proxy * @param addr the address to proxy
*/ */
public AddressProxy(ListingModel model, Address addr) { public AddressProxy(ListingModel model, Address addr) {
@ -35,12 +35,13 @@ public class AddressProxy extends ProxyObj<Address> {
this.addr = addr; this.addr = addr;
} }
/**
* @see ghidra.app.util.viewer.proxy.ProxyObj#getObject()
*/
@Override @Override
public Address getObject() { public Address getObject() {
return addr; return addr;
} }
@Override
public boolean contains(Address a) {
return addr.equals(a);
}
} }

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.
@ -22,24 +21,24 @@
*/ */
package ghidra.app.util.viewer.proxy; package ghidra.app.util.viewer.proxy;
import java.util.ConcurrentModificationException;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CodeUnit; import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import java.util.ConcurrentModificationException;
/** /**
* Stores information about a code unti in a program such that the code unit can * Stores information about a code unit in a program.
* be retrieved when needed.
*/ */
public class CodeUnitProxy extends ProxyObj<CodeUnit> { public class CodeUnitProxy extends ProxyObj<CodeUnit> {
Program program; private Program program;
CodeUnit cu; private CodeUnit cu;
Address addr; private Address addr;
/** /**
* Construct a proxy for a code unit * Construct a proxy for a code unit
* @param model the model
* @param program the program containing the code unit * @param program the program containing the code unit
* @param cu the code unit to proxy. * @param cu the code unit to proxy.
*/ */
@ -50,9 +49,6 @@ public class CodeUnitProxy extends ProxyObj<CodeUnit> {
this.addr = cu.getMinAddress(); this.addr = cu.getMinAddress();
} }
/**
* @see ghidra.app.util.viewer.proxy.ProxyObj#getObject()
*/
@Override @Override
public CodeUnit getObject() { public CodeUnit getObject() {
if (cu != null) { if (cu != null) {
@ -67,4 +63,12 @@ public class CodeUnitProxy extends ProxyObj<CodeUnit> {
return cu; return cu;
} }
@Override
public boolean contains(Address a) {
CodeUnit c = getObject();
if (c == null) {
return false;
}
return c.contains(a);
}
} }

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,13 +15,13 @@
*/ */
package ghidra.app.util.viewer.proxy; package ghidra.app.util.viewer.proxy;
import java.util.ConcurrentModificationException;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import java.util.ConcurrentModificationException;
/** /**
* Stores information about a data item in a program such that the data item can * Stores information about a data item in a program such that the data item can
* be retrieved when needed. * be retrieved when needed.
@ -35,6 +34,7 @@ public class DataProxy extends ProxyObj<Data> {
/** /**
* Construct a proxy for the given Data object. * Construct a proxy for the given Data object.
* @param model the model
* @param program the program containing the data object. * @param program the program containing the data object.
* @param data the Data object to proxy. * @param data the Data object to proxy.
*/ */
@ -46,9 +46,6 @@ public class DataProxy extends ProxyObj<Data> {
this.path = data.getComponentPath(); this.path = data.getComponentPath();
} }
/**
* @see ghidra.app.util.viewer.proxy.ProxyObj#getObject()
*/
@Override @Override
public Data getObject() { public Data getObject() {
if (data != null) { if (data != null) {
@ -66,4 +63,12 @@ public class DataProxy extends ProxyObj<Data> {
return data; return data;
} }
@Override
public boolean contains(Address a) {
Data d = getObject();
if (d == null) {
return false;
}
return d.contains(a);
}
} }

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,8 +15,10 @@
*/ */
package ghidra.app.util.viewer.proxy; package ghidra.app.util.viewer.proxy;
import ghidra.program.model.address.Address;
/** /**
* Used proxy a null value * Used as proxy for a null value.
*/ */
public class EmptyProxy extends ProxyObj<Object> { public class EmptyProxy extends ProxyObj<Object> {
public static final EmptyProxy EMPTY_PROXY = new EmptyProxy(); public static final EmptyProxy EMPTY_PROXY = new EmptyProxy();
@ -29,12 +30,13 @@ public class EmptyProxy extends ProxyObj<Object> {
super(null); super(null);
} }
/**
* @see ghidra.app.util.viewer.proxy.ProxyObj#getObject()
*/
@Override @Override
public Object getObject() { public Object getObject() {
return null; return null;
} }
@Override
public boolean contains(Address a) {
return false;
}
} }

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.
@ -22,24 +21,24 @@
*/ */
package ghidra.app.util.viewer.proxy; package ghidra.app.util.viewer.proxy;
import java.util.ConcurrentModificationException;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.Pointer; import ghidra.program.model.data.Pointer;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Reference; import ghidra.program.model.symbol.Reference;
import java.util.ConcurrentModificationException;
/** /**
* Stores information about a function in a program such that the function can * Stores information about a function in a program such that the function can
* be retrieved when needed. The locationAddr and functionAddr may differ when the * be retrieved when needed. The locationAddr and functionAddr may differ when the
* function object has been inferred via a reference at the locationAddr. * function object has been inferred via a reference at the locationAddr.
*/ */
public class FunctionProxy extends ProxyObj<Function> { public class FunctionProxy extends ProxyObj<Function> {
Program program; private Program program;
Function function; private Function function;
Address functionAddr; private Address functionAddr;
Address locationAddr; private Address locationAddr;
/** /**
* Construct a proxy for a function * Construct a proxy for a function
@ -65,9 +64,6 @@ public class FunctionProxy extends ProxyObj<Function> {
return functionAddr; return functionAddr;
} }
/**
* @see ghidra.app.util.viewer.proxy.ProxyObj#getObject()
*/
@Override @Override
public Function getObject() { public Function getObject() {
if (function != null) { if (function != null) {
@ -105,4 +101,12 @@ public class FunctionProxy extends ProxyObj<Function> {
return function; return function;
} }
@Override
public boolean contains(Address a) {
Function f = getObject();
if (f == null) {
return false;
}
return f.getBody().contains(a);
}
} }

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.
@ -17,13 +16,15 @@
package ghidra.app.util.viewer.proxy; package ghidra.app.util.viewer.proxy;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.program.model.address.Address;
/** /**
* Implementing objects of this interface hold an object from a program (e.g. CodeUnit, Funtion etc.) * Implementing objects of this interface hold an object from a program (e.g., CodeUnit, Function,
* in such a way as to be robust against changes to the program. In other words, it protects * etc.) in such a way as to be robust against changes to the program. In other words, it protects
* against holding on to` "stale" objects. The getObject() method will return the represented object * against holding on to "stale" objects. The getObject() method will return the represented object
* (refreshed if it was stale) or null if it no longer exists. * (refreshed if it was stale) or null if it no longer exists.
* *
* @param <T> the proxy object type
*/ */
public abstract class ProxyObj<T> { public abstract class ProxyObj<T> {
@ -35,17 +36,22 @@ public abstract class ProxyObj<T> {
/** /**
* Returns the layout model which corresponds to this field proxy. * Returns the layout model which corresponds to this field proxy.
* @return the model
*/ */
public ListingModel getListingLayoutModel() { public ListingModel getListingLayoutModel() {
return model; return model;
} }
/** /**
* Returns the object that this proxy represents or null if the represented object no longer * Returns the object that this proxy represents or null if the object no longer exists.
* exists. * @return the object that this proxy represents or null if the object no longer exists.
* @return the object that this proxy represents or null if the represented object no longer
* exists.
*/ */
public abstract T getObject(); public abstract T getObject();
/**
* Returns true if the proxy object of this class contains the given address.
* @param a the address
* @return true if the proxy object of this class contains the given address.
*/
public abstract boolean contains(Address a);
} }

View file

@ -59,9 +59,6 @@ public class VariableProxy extends ProxyObj<Variable> {
firstUseOffset = var.getFirstUseOffset(); firstUseOffset = var.getFirstUseOffset();
} }
/**
* @see ghidra.app.util.viewer.proxy.ProxyObj#getObject()
*/
@Override @Override
public Variable getObject() { public Variable getObject() {
@ -107,12 +104,12 @@ public class VariableProxy extends ProxyObj<Variable> {
} }
Variable[] vars = function.getLocalVariables(); Variable[] vars = function.getLocalVariables();
for (int i = 0; i < vars.length; i++) { for (Variable var2 : vars) {
if (firstUseOffset != vars[i].getFirstUseOffset()) { if (firstUseOffset != var2.getFirstUseOffset()) {
continue; continue;
} }
if (storageAddr.equals(vars[i].getMinAddress())) { if (storageAddr.equals(var2.getMinAddress())) {
var = vars[i]; var = var2;
return var; return var;
} }
} }
@ -127,4 +124,12 @@ public class VariableProxy extends ProxyObj<Variable> {
return functionAddr; return functionAddr;
} }
@Override
public boolean contains(Address a) {
Variable v = getObject();
if (v == null) {
return false;
}
return v.getMinAddress().equals(a);
}
} }

View file

@ -17,12 +17,16 @@ package ghidra.test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.junit.After; import org.junit.After;
import docking.widgets.fieldpanel.*;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.listingpanel.ListingPanel;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -206,4 +210,50 @@ public abstract class AbstractProgramBasedTest extends AbstractGhidraHeadedInteg
} }
return result; return result;
} }
/**
* Returns a field by the given name at the given address. Clients can use the convention
* that field factory classes specify a public static field named 'FIELD_NAME' to choose the
* desired field name.
* <p>
* Note: you will have to perform a {@code goTo()} to trigger the view to load the given field.
*
* @param a the address
* @param fieldName the field name
* @return the field
*/
protected ListingField getField(Address a, String fieldName) {
ListingPanel panel = codeBrowser.getListingPanel();
BigInteger index = panel.getAddressIndexMap().getIndex(a);
FieldPanel fieldPanel = panel.getFieldPanel();
ListingField field = getField(fieldName, 1, index, fieldPanel);
return field;
}
protected ListingField getField(String fieldName, int occurrence, final BigInteger index,
FieldPanel fieldPanel) {
if (fieldName == null) {
return null;
}
LayoutModel model = fieldPanel.getLayoutModel();
Layout layout = model.getLayout(index);
if (layout == null) {
return null;
}
int instanceNum = 1;
for (int i = 0; i < layout.getNumFields(); i++) {
ListingField bf = (ListingField) layout.getField(i);
if (bf.getFieldFactory().getFieldName().equals(fieldName)) {
if (instanceNum++ == occurrence) {
return bf;
}
}
}
return null;
}
} }

View file

@ -27,7 +27,6 @@ import java.util.stream.Collectors;
import javax.swing.*; import javax.swing.*;
import org.apache.commons.collections4.IteratorUtils; import org.apache.commons.collections4.IteratorUtils;
import org.junit.After;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.test.AbstractDockingTest; import docking.test.AbstractDockingTest;
@ -37,8 +36,9 @@ import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.app.plugin.core.table.TableComponentProvider; import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.plugin.core.table.TableServicePlugin; import ghidra.app.plugin.core.table.TableServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.BytesFieldFactory; import ghidra.app.util.viewer.field.BytesFieldFactory;
import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -98,12 +98,6 @@ public abstract class AbstractMemSearchTest extends AbstractProgramBasedTest {
selectRadioButton("Binary"); selectRadioButton("Binary");
} }
@Override
@After
public void tearDown() throws Exception {
env.dispose();
}
@Override @Override
protected Program getProgram() throws Exception { protected Program getProgram() throws Exception {
return buildProgram(); return buildProgram();
@ -163,10 +157,10 @@ public abstract class AbstractMemSearchTest extends AbstractProgramBasedTest {
private List<Address> getHighlightAddresses() { private List<Address> getHighlightAddresses() {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
Object codeViewerProvider = getInstanceField("connectedProvider", service); Object codeViewerProvider = getInstanceField("connectedProvider", service);
Map<Program, HighlightProvider> highlighterMap = Map<Program, ListingHighlightProvider> highlighterMap =
(Map<Program, HighlightProvider>) getInstanceField("programHighlighterMap", (Map<Program, ListingHighlightProvider>) getInstanceField("programHighlighterMap",
codeViewerProvider); codeViewerProvider);
HighlightProvider highlightProvider = highlighterMap.get(program); ListingHighlightProvider highlightProvider = highlighterMap.get(program);
assertEquals("The inner-class has been renamed", "SearchTableHighlightHandler", assertEquals("The inner-class has been renamed", "SearchTableHighlightHandler",
highlightProvider.getClass().getSimpleName()); highlightProvider.getClass().getSimpleName());
@ -237,10 +231,10 @@ public abstract class AbstractMemSearchTest extends AbstractProgramBasedTest {
triggerText(valueField, text); triggerText(valueField, text);
} }
protected HighlightProvider getHighlightProvider() { protected ListingHighlightProvider getHighlightProvider() {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
FormatManager fm = (FormatManager) getInstanceField("formatMgr", service); FormatManager fm = (FormatManager) getInstanceField("formatMgr", service);
return (HighlightProvider) getInstanceField("highlightProvider", fm); return (ListingHighlightProvider) getInstanceField("highlightProvider", fm);
} }
protected void repeatSearch() { protected void repeatSearch() {
@ -296,10 +290,11 @@ public abstract class AbstractMemSearchTest extends AbstractProgramBasedTest {
} }
protected Highlight[] getByteHighlights(Address address, String bytes) { protected Highlight[] getByteHighlights(Address address, String bytes) {
goTo(address);
CodeUnit cu = codeUnitContaining(address); CodeUnit cu = codeUnitContaining(address);
HighlightProvider provider1 = getHighlightProvider(); ListingHighlightProvider hlProvider = getHighlightProvider();
Highlight[] h = provider1.getHighlights(bytes, cu, BytesFieldFactory.class, -1); ListingField field = getField(address, BytesFieldFactory.FIELD_NAME);
return h; return hlProvider.createHighlights(bytes, field, -1);
} }
protected void setEndianess(String text) { protected void setEndianess(String text) {

View file

@ -15,8 +15,7 @@
*/ */
package ghidra.app.plugin.core.searchmem; package ghidra.app.plugin.core.searchmem;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
@ -35,10 +34,6 @@ import ghidra.program.model.listing.*;
*/ */
public class MemSearchRegExTest extends AbstractMemSearchTest { public class MemSearchRegExTest extends AbstractMemSearchTest {
public MemSearchRegExTest() {
super();
}
@Override @Override
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@ -313,7 +308,7 @@ public class MemSearchRegExTest extends AbstractMemSearchTest {
waitForSearch("Search Memory - ", 3); waitForSearch("Search Memory - ", 3);
Highlight[] h = getByteHighlights(addr(0x1002827), "6a 01"); Highlight[] h = getByteHighlights(addr(0x1002826), "6a 01");
assertEquals(1, h.length); assertEquals(1, h.length);
} }
} }

View file

@ -149,7 +149,7 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
assertTrue(searcher.hasNext()); assertTrue(searcher.hasNext());
while (searcher.hasNext()) { while (searcher.hasNext()) {
ProgramLocation location = searcher.next(); ProgramLocation location = searcher.next().programLocation();
testForMatchingText(searchText, location); testForMatchingText(searchText, location);
} }
} }
@ -171,7 +171,7 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
assertTrue(searcher.hasNext()); assertTrue(searcher.hasNext());
while (searcher.hasNext()) { while (searcher.hasNext()) {
ProgramLocation location = searcher.next(); ProgramLocation location = searcher.next().programLocation();
testForMatchingText(searchText, location); testForMatchingText(searchText, location);
} }
} }
@ -267,10 +267,12 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
int transactionID = program.startTransaction("test"); int transactionID = program.startTransaction("test");
try { try {
DataType dt = program.getDataTypeManager().addDataType(struct, DataType dt = program.getDataTypeManager()
DataTypeConflictHandler.DEFAULT_HANDLER); .addDataType(struct,
floatDt = program.getDataTypeManager().addDataType(new FloatDataType(), DataTypeConflictHandler.DEFAULT_HANDLER);
DataTypeConflictHandler.DEFAULT_HANDLER); floatDt = program.getDataTypeManager()
.addDataType(new FloatDataType(),
DataTypeConflictHandler.DEFAULT_HANDLER);
listing.createData(addr(0x0100689b), dt); listing.createData(addr(0x0100689b), dt);
listing.createData(addr(0x0100688c), floatDt); listing.createData(addr(0x0100688c), floatDt);
listing.createData(addr(0x01006890), floatDt); listing.createData(addr(0x01006890), floatDt);
@ -344,10 +346,12 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
int transactionID = program.startTransaction("test"); int transactionID = program.startTransaction("test");
try { try {
DataType dt = program.getDataTypeManager().addDataType(struct, DataType dt = program.getDataTypeManager()
DataTypeConflictHandler.DEFAULT_HANDLER); .addDataType(struct,
floatDt = program.getDataTypeManager().addDataType(new FloatDataType(), DataTypeConflictHandler.DEFAULT_HANDLER);
DataTypeConflictHandler.DEFAULT_HANDLER); floatDt = program.getDataTypeManager()
.addDataType(new FloatDataType(),
DataTypeConflictHandler.DEFAULT_HANDLER);
listing.createData(addr(0x0100689b), dt); listing.createData(addr(0x0100689b), dt);
listing.createData(addr(0x0100688c), floatDt); listing.createData(addr(0x0100688c), floatDt);
listing.createData(addr(0x01006890), floatDt); listing.createData(addr(0x01006890), floatDt);
@ -378,38 +382,38 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
searcher = searcher =
new ListingDisplaySearcher(tool, program, startLoc, sel, options, TaskMonitor.DUMMY); new ListingDisplaySearcher(tool, program, startLoc, sel, options, TaskMonitor.DUMMY);
ProgramLocation loc = searcher.next(); ProgramLocation loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100688c), loc.getByteAddress()); assertEquals(addr(0x0100688c), loc.getByteAddress());
assertTrue(loc instanceof CommentFieldLocation); assertTrue(loc instanceof CommentFieldLocation);
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x01006890), loc.getByteAddress()); assertEquals(addr(0x01006890), loc.getByteAddress());
assertTrue(loc instanceof MnemonicFieldLocation); assertTrue(loc instanceof MnemonicFieldLocation);
MnemonicFieldLocation mloc = (MnemonicFieldLocation) loc; MnemonicFieldLocation mloc = (MnemonicFieldLocation) loc;
assertEquals("float", mloc.getMnemonic()); assertEquals("float", mloc.getMnemonic());
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x01006890), loc.getByteAddress()); assertEquals(addr(0x01006890), loc.getByteAddress());
assertTrue(loc instanceof CommentFieldLocation); assertTrue(loc instanceof CommentFieldLocation);
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100689b), loc.getByteAddress()); assertEquals(addr(0x0100689b), loc.getByteAddress());
assertTrue(loc instanceof MnemonicFieldLocation); assertTrue(loc instanceof MnemonicFieldLocation);
mloc = (MnemonicFieldLocation) loc; mloc = (MnemonicFieldLocation) loc;
assertEquals("float", mloc.getMnemonic()); assertEquals("float", mloc.getMnemonic());
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100689f), loc.getByteAddress()); assertEquals(addr(0x0100689f), loc.getByteAddress());
assertTrue(loc instanceof MnemonicFieldLocation); assertTrue(loc instanceof MnemonicFieldLocation);
mloc = (MnemonicFieldLocation) loc; mloc = (MnemonicFieldLocation) loc;
assertEquals("float", mloc.getMnemonic()); assertEquals("float", mloc.getMnemonic());
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100689f), loc.getByteAddress()); assertEquals(addr(0x0100689f), loc.getByteAddress());
assertTrue(loc instanceof CommentFieldLocation); assertTrue(loc instanceof CommentFieldLocation);
@ -432,10 +436,12 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
int transactionID = program.startTransaction("test"); int transactionID = program.startTransaction("test");
try { try {
DataType dt = program.getDataTypeManager().addDataType(struct, DataType dt = program.getDataTypeManager()
DataTypeConflictHandler.DEFAULT_HANDLER); .addDataType(struct,
floatDt = program.getDataTypeManager().addDataType(new FloatDataType(), DataTypeConflictHandler.DEFAULT_HANDLER);
DataTypeConflictHandler.DEFAULT_HANDLER); floatDt = program.getDataTypeManager()
.addDataType(new FloatDataType(),
DataTypeConflictHandler.DEFAULT_HANDLER);
listing.createData(addr(0x0100689b), dt); listing.createData(addr(0x0100689b), dt);
listing.createData(addr(0x0100688c), floatDt); listing.createData(addr(0x0100688c), floatDt);
listing.createData(addr(0x01006890), floatDt); listing.createData(addr(0x01006890), floatDt);
@ -469,26 +475,26 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
searcher = searcher =
new ListingDisplaySearcher(tool, program, startLoc, sel, options, TaskMonitor.DUMMY); new ListingDisplaySearcher(tool, program, startLoc, sel, options, TaskMonitor.DUMMY);
ProgramLocation loc = searcher.next(); ProgramLocation loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100688c), loc.getByteAddress()); assertEquals(addr(0x0100688c), loc.getByteAddress());
assertTrue(loc instanceof CommentFieldLocation); assertTrue(loc instanceof CommentFieldLocation);
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100689b), loc.getByteAddress()); assertEquals(addr(0x0100689b), loc.getByteAddress());
assertTrue(loc instanceof MnemonicFieldLocation); assertTrue(loc instanceof MnemonicFieldLocation);
MnemonicFieldLocation mloc = (MnemonicFieldLocation) loc; MnemonicFieldLocation mloc = (MnemonicFieldLocation) loc;
assertEquals("float", mloc.getMnemonic()); assertEquals("float", mloc.getMnemonic());
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100689f), loc.getByteAddress()); assertEquals(addr(0x0100689f), loc.getByteAddress());
assertTrue(loc instanceof MnemonicFieldLocation); assertTrue(loc instanceof MnemonicFieldLocation);
mloc = (MnemonicFieldLocation) loc; mloc = (MnemonicFieldLocation) loc;
assertEquals("float", mloc.getMnemonic()); assertEquals("float", mloc.getMnemonic());
// //
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x0100689f), loc.getByteAddress()); assertEquals(addr(0x0100689f), loc.getByteAddress());
assertTrue(loc instanceof CommentFieldLocation); assertTrue(loc instanceof CommentFieldLocation);
@ -677,16 +683,15 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
assertTrue(searcher.hasNext()); assertTrue(searcher.hasNext());
ProgramLocation loc = searcher.next(); ProgramLocation loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x01001068), loc.getByteAddress()); assertEquals(addr(0x01001068), loc.getByteAddress());
assertTrue(loc instanceof LabelFieldLocation); assertTrue(loc instanceof LabelFieldLocation);
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertEquals(addr(0x01001068), loc.getByteAddress()); assertEquals(addr(0x01001068), loc.getByteAddress());
assertTrue(loc instanceof EolCommentFieldLocation); assertTrue(loc instanceof EolCommentFieldLocation);
loc = searcher.next(); assertNull(searcher.next());
assertNull(loc);
} }
@ -759,7 +764,6 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
checkTextFound(addr(0x0100419f), OperandFieldLocation.class); checkTextFound(addr(0x0100419f), OperandFieldLocation.class);
checkTextFound(addr(0x010041a1), LabelFieldLocation.class); checkTextFound(addr(0x010041a1), LabelFieldLocation.class);
checkTextFound(addr(0x010041a4), LabelFieldLocation.class); checkTextFound(addr(0x010041a4), LabelFieldLocation.class);
} }
//================================================================================================== //==================================================================================================
@ -816,11 +820,9 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
private void checkTextFound(ArrayList<Address> startList, Class<?> fieldClass) { private void checkTextFound(ArrayList<Address> startList, Class<?> fieldClass) {
for (int i = 0; i < startList.size(); i++) { for (Address start : startList) {
ProgramLocation loc = searcher.next(); ProgramLocation loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
Address start = startList.get(i);
assertTrue(fieldClass.isAssignableFrom(loc.getClass())); assertTrue(fieldClass.isAssignableFrom(loc.getClass()));
assertEquals(start, loc.getAddress()); assertEquals(start, loc.getAddress());
} }
@ -831,7 +833,7 @@ public class ListingDisplaySearcherTest extends AbstractGhidraHeadedIntegrationT
private void checkTextFound(Address addr, Class<?> fieldClass) { private void checkTextFound(Address addr, Class<?> fieldClass) {
ProgramLocation loc; ProgramLocation loc;
loc = searcher.next(); loc = searcher.next().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertTrue(fieldClass.isAssignableFrom(loc.getClass())); assertTrue(fieldClass.isAssignableFrom(loc.getClass()));

View file

@ -27,6 +27,7 @@ import javax.swing.*;
import org.junit.*; import org.junit.*;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.widgets.fieldpanel.FieldPanel;
import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider; import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
@ -34,7 +35,7 @@ import ghidra.app.plugin.core.marker.MarkerManagerPlugin;
import ghidra.app.plugin.core.programtree.ProgramTreePlugin; import ghidra.app.plugin.core.programtree.ProgramTreePlugin;
import ghidra.app.services.GoToService; import ghidra.app.services.GoToService;
import ghidra.app.services.ProgramManager; import ghidra.app.services.ProgramManager;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.*; import ghidra.app.util.viewer.format.*;
import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.app.util.viewer.listingpanel.ListingPanel;
@ -64,10 +65,6 @@ public class SearchTextPlugin3Test extends AbstractGhidraHeadedIntegrationTest {
private CodeViewerProvider provider; private CodeViewerProvider provider;
private GoToService goToService; private GoToService goToService;
public SearchTextPlugin3Test() {
super();
}
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
env = new TestEnv(); env = new TestEnv();
@ -509,18 +506,20 @@ public class SearchTextPlugin3Test extends AbstractGhidraHeadedIntegrationTest {
String signature = ((FunctionSignatureFieldLocation) loc).getSignature(); String signature = ((FunctionSignatureFieldLocation) loc).getSignature();
Function function = listing.getFunctionAt(loc.getAddress()); ListingHighlightProvider highlightProvider =
HighlightProvider highlightProvider =
cbPlugin.getFormatManager().getFormatHighlightProvider(); cbPlugin.getFormatManager().getFormatHighlightProvider();
Highlight[] h = highlightProvider.getHighlights(signature, function,
FunctionSignatureFieldFactory.class, signature.indexOf(searchText)); FieldPanel fieldPanel = cbPlugin.getFieldPanel();
ListingField field = (ListingField) fieldPanel.getCurrentField();
int offset = signature.indexOf(searchText);
Highlight[] h = highlightProvider.createHighlights(signature, field, offset);
assertEquals(1, h.length); assertEquals(1, h.length);
runSwing(() -> dialog.close()); runSwing(() -> dialog.close());
// highlights should be gone // highlights should be gone
h = highlightProvider.getHighlights(signature, function, h = highlightProvider.createHighlights(signature, field, offset);
FunctionSignatureFieldFactory.class, -1);
assertEquals(0, h.length); assertEquals(0, h.length);
} }
@ -564,10 +563,14 @@ public class SearchTextPlugin3Test extends AbstractGhidraHeadedIntegrationTest {
String signature = ((FunctionSignatureFieldLocation) loc).getSignature(); String signature = ((FunctionSignatureFieldLocation) loc).getSignature();
Function function = listing.getFunctionAt(loc.getAddress()); Function function = listing.getFunctionAt(loc.getAddress());
HighlightProvider highlightProvider = ListingHighlightProvider highlightProvider =
cbPlugin.getFormatManager().getFormatHighlightProvider(); cbPlugin.getFormatManager().getFormatHighlightProvider();
Highlight[] h = highlightProvider.getHighlights(signature, function,
FunctionSignatureFieldFactory.class, -1); FieldPanel fieldPanel = cbPlugin.getFieldPanel();
ListingField field = (ListingField) fieldPanel.getCurrentField();
FieldFactory factory = field.getFieldFactory();
Highlight[] h = highlightProvider.createHighlights(signature, field, -1);
int numberOfHighlights = h.length; int numberOfHighlights = h.length;
assertTrue("Did not find highlights at expected field.", (numberOfHighlights > 0)); assertTrue("Did not find highlights at expected field.", (numberOfHighlights > 0));
@ -590,13 +593,12 @@ public class SearchTextPlugin3Test extends AbstractGhidraHeadedIntegrationTest {
cbPlugin.goToField(addr, "Operands", 0, 2); cbPlugin.goToField(addr, "Operands", 0, 2);
waitForSwing(); waitForSwing();
loc = plugin.getNavigatable().getLocation(); loc = plugin.getNavigatable().getLocation();
assertTrue(loc instanceof OperandFieldLocation); assertTrue(loc instanceof OperandFieldLocation);
OperandFieldLocation operandLocation = (OperandFieldLocation) loc;
Instruction instruction = listing.getInstructionAt(addr);
h = highlightProvider.getHighlights(operandLocation.getOperandRepresentation(), instruction, field = (ListingField) fieldPanel.getCurrentField();
OperandFieldFactory.class, 0); factory = field.getFieldFactory();
h = highlightProvider.createHighlights(signature, field, -1);
assertTrue("Did not update highlights for new search.", (numberOfHighlights != h.length)); assertTrue("Did not update highlights for new search.", (numberOfHighlights != h.length));
} }

View file

@ -29,6 +29,7 @@ import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin;
import ghidra.app.plugin.core.navigation.NextPrevAddressPlugin; import ghidra.app.plugin.core.navigation.NextPrevAddressPlugin;
import ghidra.app.plugin.core.searchtext.SearchOptions; import ghidra.app.plugin.core.searchtext.SearchOptions;
import ghidra.app.plugin.core.searchtext.Searcher; import ghidra.app.plugin.core.searchtext.Searcher;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.app.plugin.core.searchtext.databasesearcher.*; import ghidra.app.plugin.core.searchtext.databasesearcher.*;
import ghidra.app.services.ProgramManager; import ghidra.app.services.ProgramManager;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@ -115,7 +116,7 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
while (currentAddress != null) { while (currentAddress != null) {
if (searcher.hasMatch(currentAddress)) { if (searcher.hasMatch(currentAddress)) {
return searcher.getMatch(); return searcher.getMatch().programLocation();
} }
currentAddress = searcher.getNextSignificantAddress(currentAddress); currentAddress = searcher.getNextSignificantAddress(currentAddress);
} }
@ -413,7 +414,7 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
ProgramLocation startLoc = new ProgramLocation(program, getAddr(0x1001950)); ProgramLocation startLoc = new ProgramLocation(program, getAddr(0x1001950));
Searcher ts = new ProgramDatabaseSearcher(tool, program, startLoc, null, options, monitor); Searcher ts = new ProgramDatabaseSearcher(tool, program, startLoc, null, options, monitor);
ProgramLocation loc = ts.search(); ProgramLocation loc = ts.search().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!", assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!",
@ -422,7 +423,7 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
assertEquals(cloc.getCharOffset(), 5); assertEquals(cloc.getCharOffset(), 5);
// should be 3 hits at address 0x1001960 // should be 3 hits at address 0x1001960
loc = ts.search(); loc = ts.search().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!", assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!",
(loc instanceof CommentFieldLocation)); (loc instanceof CommentFieldLocation));
@ -431,7 +432,7 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
cloc = (CommentFieldLocation) loc; cloc = (CommentFieldLocation) loc;
assertEquals(cloc.getCharOffset(), 12); assertEquals(cloc.getCharOffset(), 12);
loc = ts.search(); loc = ts.search().programLocation();
assertNotNull(loc); assertNotNull(loc);
assertTrue("Expected LabelFieldLocation, got " + loc.getClass() + " instead!", assertTrue("Expected LabelFieldLocation, got " + loc.getClass() + " instead!",
(loc instanceof LabelFieldLocation)); (loc instanceof LabelFieldLocation));
@ -439,7 +440,7 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
assertEquals(floc.getCharOffset(), 3); assertEquals(floc.getCharOffset(), 3);
assertEquals(getAddr(0x1001960L), floc.getAddress()); assertEquals(getAddr(0x1001960L), floc.getAddress());
loc = ts.search(); loc = ts.search().programLocation();
assertEquals(getAddr(0x1001960), loc.getAddress()); assertEquals(getAddr(0x1001960), loc.getAddress());
assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!", assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!",
(loc instanceof CommentFieldLocation)); (loc instanceof CommentFieldLocation));
@ -470,12 +471,12 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
ProgramLocation startLoc = ProgramLocation startLoc =
new ProgramLocation(program, program.getMinAddress().getNewAddress(0x1001950L)); new ProgramLocation(program, program.getMinAddress().getNewAddress(0x1001950L));
Searcher ts = new ProgramDatabaseSearcher(tool, program, startLoc, null, options, monitor); Searcher ts = new ProgramDatabaseSearcher(tool, program, startLoc, null, options, monitor);
ProgramLocation loc = ts.search(); ProgramLocation loc = ts.search().programLocation();
assertEquals(getAddr(0x1001955L), loc.getAddress()); assertEquals(getAddr(0x1001955L), loc.getAddress());
assertTrue("Expected MnemonicFieldLocation, got " + loc.getClass() + " instead!", assertTrue("Expected MnemonicFieldLocation, got " + loc.getClass() + " instead!",
(loc instanceof MnemonicFieldLocation)); (loc instanceof MnemonicFieldLocation));
loc = ts.search(); loc = ts.search().programLocation();
assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!", assertTrue("Expected CommentFieldLocation, got " + loc.getClass() + " instead!",
(loc instanceof CommentFieldLocation)); (loc instanceof CommentFieldLocation));
assertEquals(CodeUnit.POST_COMMENT, ((CommentFieldLocation) loc).getCommentType()); assertEquals(CodeUnit.POST_COMMENT, ((CommentFieldLocation) loc).getCommentType());
@ -534,8 +535,10 @@ public class ProgramDatabaseSearchIteratorTest extends AbstractGhidraHeadedInteg
return new ProgramDatabaseSearcher(pluginTool, searchProgram, startLoc, set, options, return new ProgramDatabaseSearcher(pluginTool, searchProgram, startLoc, set, options,
taskMonitor); taskMonitor);
}); });
ProgramLocation loc = null;
while ((loc = ts.search()) != null) { TextSearchResult searchResult = null;
while ((searchResult = ts.search()) != null) {
ProgramLocation loc = searchResult.programLocation();
list.add(loc); list.add(loc);
++count; ++count;
if (searchLimit > 0 && count >= searchLimit) { if (searchLimit > 0 && count >= searchLimit) {

View file

@ -17,7 +17,7 @@ package ghidra.app.nav;
import javax.swing.Icon; import javax.swing.Icon;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
@ -143,12 +143,12 @@ public class TestDummyNavigatable implements Navigatable {
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, Program program) { public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// stub // stub
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// stub // stub
} }
} }

View file

@ -24,7 +24,7 @@ import docking.util.GraphicsUtils;
import docking.widgets.fieldpanel.field.SimpleTextField; import docking.widgets.fieldpanel.field.SimpleTextField;
import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager; import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager;
import docking.widgets.fieldpanel.internal.PaintContext; import docking.widgets.fieldpanel.internal.PaintContext;
import docking.widgets.fieldpanel.support.HighlightFactory; import docking.widgets.fieldpanel.support.FieldHighlightFactory;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.util.ColorUtils; import ghidra.util.ColorUtils;
@ -52,7 +52,7 @@ public class ByteField extends SimpleTextField {
*/ */
public ByteField(String text, FontMetrics fontMetrics, int startX, int width, public ByteField(String text, FontMetrics fontMetrics, int startX, int width,
boolean allowCursorAtEnd, int fieldOffset, BigInteger index, boolean allowCursorAtEnd, int fieldOffset, BigInteger index,
HighlightFactory hlFactory) { FieldHighlightFactory hlFactory) {
super(text, fontMetrics, startX, width, allowCursorAtEnd, hlFactory); super(text, fontMetrics, startX, width, allowCursorAtEnd, hlFactory);
this.fieldOffset = fieldOffset; this.fieldOffset = fieldOffset;
@ -64,7 +64,7 @@ public class ByteField extends SimpleTextField {
public void paint(JComponent c, Graphics g, PaintContext context, public void paint(JComponent c, Graphics g, PaintContext context,
Rectangle clip, FieldBackgroundColorManager colorManager, RowColLocation cursorLoc, int rowHeight) { Rectangle clip, FieldBackgroundColorManager colorManager, RowColLocation cursorLoc, int rowHeight) {
paintSelection(g, colorManager, 0); paintSelection(g, colorManager, 0);
paintHighlights(g, hlFactory.getHighlights(this, text, -1)); paintHighlights(g, hlFactory.createHighlights(this, text, -1));
g.setFont(metrics.getFont()); g.setFont(metrics.getFont());
if (foregroundColor == null) { if (foregroundColor == null) {
foregroundColor = context.getForeground(); foregroundColor = context.getForeground();

Some files were not shown because too many files have changed in this diff Show more