mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
Merge remote-tracking branch 'origin/patch'
Conflicts: Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/matchtable/VTMatchTableProvider.java
This commit is contained in:
commit
647bc541e5
@ -34,7 +34,8 @@ public abstract class AbstractTraceRmiLaunchOpinion implements TraceRmiLaunchOpi
|
|||||||
String pluginName = PluginUtils.getPluginNameFromClass(TraceRmiLauncherServicePlugin.class);
|
String pluginName = PluginUtils.getPluginNameFromClass(TraceRmiLauncherServicePlugin.class);
|
||||||
options.registerOption(TraceRmiLauncherServicePlugin.OPTION_NAME_SCRIPT_PATHS,
|
options.registerOption(TraceRmiLauncherServicePlugin.OPTION_NAME_SCRIPT_PATHS,
|
||||||
OptionType.STRING_TYPE, "", new HelpLocation(pluginName, "options"),
|
OptionType.STRING_TYPE, "", new HelpLocation(pluginName, "options"),
|
||||||
"Paths to search for user-created debugger launchers", new ScriptPathsPropertyEditor());
|
"Paths to search for user-created debugger launchers",
|
||||||
|
() -> new ScriptPathsPropertyEditor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,6 +27,7 @@ import ghidra.framework.options.annotation.*;
|
|||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.SystemUtilities;
|
||||||
|
|
||||||
public interface AutoOptions {
|
public interface AutoOptions {
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ public interface AutoOptions {
|
|||||||
String description = annotation.description();
|
String description = annotation.description();
|
||||||
Class<? extends PropertyEditor> editorClass = annotation.editor();
|
Class<? extends PropertyEditor> editorClass = annotation.editor();
|
||||||
final PropertyEditor editor;
|
final PropertyEditor editor;
|
||||||
if (editorClass == PropertyEditor.class) {
|
if (editorClass == PropertyEditor.class || SystemUtilities.isInHeadlessMode()) {
|
||||||
editor = null;
|
editor = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -169,16 +170,16 @@ public interface AutoOptions {
|
|||||||
else if ( is font option ) {
|
else if ( is font option ) {
|
||||||
|
|
||||||
// Note: there is no font value to check against for fonts in the new Theme system.
|
// Note: there is no font value to check against for fonts in the new Theme system.
|
||||||
// If annotation fonts are needed, then they should be bound by String id. Likely,
|
// If annotation fonts are needed, then they should be bound by String id. Likely,
|
||||||
// annotation fonts are not needed now that have themes. We also probably no
|
// annotation fonts are not needed now that have themes. We also probably no
|
||||||
// longer need annotation colors either.
|
// longer need annotation colors either.
|
||||||
|
|
||||||
options.registerThemeFontBinding(description, fontId, help, description);
|
options.registerThemeFontBinding(description, fontId, help, description);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
else {
|
else {
|
||||||
options.registerOption(key.name, type, defaultValue, help, description,
|
options.registerOption(key.name, type, defaultValue, help, description,
|
||||||
editor);
|
() -> editor);
|
||||||
// TODO: Wish Ghidra would do this upon any option registration
|
// TODO: Wish Ghidra would do this upon any option registration
|
||||||
options.putObject(key.name, defaultValue, type);
|
options.putObject(key.name, defaultValue, type);
|
||||||
}
|
}
|
||||||
|
@ -127,13 +127,13 @@ public class ApplyDataArchiveAnalyzer extends AbstractAnalyzer {
|
|||||||
|
|
||||||
options.registerOption(OPTION_NAME_ARCHIVE_CHOOSER, OptionType.STRING_TYPE,
|
options.registerOption(OPTION_NAME_ARCHIVE_CHOOSER, OptionType.STRING_TYPE,
|
||||||
CHOOSER_AUTO_DETECT, null, OPTION_DESCRIPTION_ARCHIVE_CHOOSER,
|
CHOOSER_AUTO_DETECT, null, OPTION_DESCRIPTION_ARCHIVE_CHOOSER,
|
||||||
new StringWithChoicesEditor(chooserList));
|
() -> new StringWithChoicesEditor(chooserList));
|
||||||
|
|
||||||
options.registerOption(OPTION_NAME_GDT_FILEPATH, OptionType.FILE_TYPE, null, null,
|
options.registerOption(OPTION_NAME_GDT_FILEPATH, OptionType.FILE_TYPE, null, null,
|
||||||
OPTION_DESCRIPTION_GDT_FILEPATH,
|
OPTION_DESCRIPTION_GDT_FILEPATH,
|
||||||
new FileChooserEditor(FileDataTypeManager.GDT_FILEFILTER));
|
() -> new FileChooserEditor(FileDataTypeManager.GDT_FILEFILTER));
|
||||||
options.registerOption(OPTION_NAME_PROJECT_PATH, OptionType.STRING_TYPE, null, null,
|
options.registerOption(OPTION_NAME_PROJECT_PATH, OptionType.STRING_TYPE, null, null,
|
||||||
OPTION_DESCRIPTION_PROJECT_PATH, new ProjectPathChooserEditor(
|
OPTION_DESCRIPTION_PROJECT_PATH, () -> new ProjectPathChooserEditor(
|
||||||
"Choose Data Type Archive", DATATYPEARCHIVE_PROJECT_FILTER));
|
"Choose Data Type Archive", DATATYPEARCHIVE_PROJECT_FILTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
|||||||
analysisMgr.addListener(this);
|
analysisMgr.addListener(this);
|
||||||
|
|
||||||
Options options = program.getOptions(Program.ANALYSIS_PROPERTIES);
|
Options options = program.getOptions(Program.ANALYSIS_PROPERTIES);
|
||||||
options.registerOptionsEditor(new AnalysisOptionsEditor(program));
|
options.registerOptionsEditor(() -> new AnalysisOptionsEditor(program));
|
||||||
options.setOptionsHelpLocation(
|
options.setOptionsHelpLocation(
|
||||||
new HelpLocation("AutoAnalysisPlugin", "Auto_Analysis_Option"));
|
new HelpLocation("AutoAnalysisPlugin", "Auto_Analysis_Option"));
|
||||||
}
|
}
|
||||||
@ -264,7 +264,8 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
|||||||
private void programActivated(Program program) {
|
private void programActivated(Program program) {
|
||||||
program.getOptions(StoredAnalyzerTimes.OPTIONS_LIST)
|
program.getOptions(StoredAnalyzerTimes.OPTIONS_LIST)
|
||||||
.registerOption(StoredAnalyzerTimes.OPTION_NAME, OptionType.CUSTOM_TYPE, null, null,
|
.registerOption(StoredAnalyzerTimes.OPTION_NAME, OptionType.CUSTOM_TYPE, null, null,
|
||||||
"Cumulative analysis task times", new StoredAnalyzerTimesPropertyEditor());
|
"Cumulative analysis task times",
|
||||||
|
() -> new StoredAnalyzerTimesPropertyEditor());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.analysis.rust;
|
package ghidra.app.plugin.core.analysis.rust;
|
||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.*;
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import docking.options.editor.BooleanEditor;
|
import docking.options.editor.BooleanEditor;
|
||||||
@ -90,24 +89,14 @@ public class RustDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
|||||||
options.registerOption(OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS, demangleOnlyKnownPatterns,
|
options.registerOption(OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS, demangleOnlyKnownPatterns,
|
||||||
help, OPTION_DESCRIPTION_USE_KNOWN_PATTERNS);
|
help, OPTION_DESCRIPTION_USE_KNOWN_PATTERNS);
|
||||||
|
|
||||||
BooleanEditor deprecatedEditor = null;
|
RustOptionsEditor optionsEditor = new RustOptionsEditor();
|
||||||
FormatEditor formatEditor = null;
|
|
||||||
if (!SystemUtilities.isInHeadlessMode()) {
|
|
||||||
// Only add the custom options editor when not headless. The custom editor allows
|
|
||||||
// the list of choices presented to the user to change depending on the state of the
|
|
||||||
// useDeprecatedDemangler flag.
|
|
||||||
deprecatedEditor = new BooleanEditor();
|
|
||||||
deprecatedEditor.setValue(Boolean.valueOf(useDeprecatedDemangler));
|
|
||||||
formatEditor = new FormatEditor(demanglerFormat, deprecatedEditor);
|
|
||||||
deprecatedEditor.addPropertyChangeListener(formatEditor);
|
|
||||||
}
|
|
||||||
|
|
||||||
options.registerOption(OPTION_NAME_USE_DEPRECATED_DEMANGLER, OptionType.BOOLEAN_TYPE,
|
options.registerOption(OPTION_NAME_USE_DEPRECATED_DEMANGLER, OptionType.BOOLEAN_TYPE,
|
||||||
useDeprecatedDemangler, help, OPTION_DESCRIPTION_DEPRECATED_DEMANGLER,
|
useDeprecatedDemangler, help, OPTION_DESCRIPTION_DEPRECATED_DEMANGLER,
|
||||||
deprecatedEditor);
|
() -> optionsEditor.getDeprecatedNameEditor());
|
||||||
|
|
||||||
options.registerOption(OPTION_NAME_DEMANGLER_FORMAT, OptionType.ENUM_TYPE, demanglerFormat,
|
options.registerOption(OPTION_NAME_DEMANGLER_FORMAT, OptionType.ENUM_TYPE, demanglerFormat,
|
||||||
help, OPTION_DESCRIPTION_DEMANGLER_FORMAT, formatEditor);
|
help, OPTION_DESCRIPTION_DEMANGLER_FORMAT, () -> optionsEditor.getFormatEditor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -162,6 +151,45 @@ public class RustDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
|||||||
super.apply(program, address, demangledVariable, options, log, monitor);
|
super.apply(program, address, demangledVariable, options, log, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Inner Classes
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
// We only use the editor when not headless, since GUI code in headless will throw an exception.
|
||||||
|
// Further, the options below have a relationship, so we need to build them together.
|
||||||
|
// The format editor's list of choices presented to the user will change depending on the state
|
||||||
|
// of the deprecated boolean editor.
|
||||||
|
private class RustOptionsEditor {
|
||||||
|
|
||||||
|
private BooleanEditor deprecatedEditor;
|
||||||
|
private FormatEditor formatEditor;
|
||||||
|
|
||||||
|
private void lazyInit() {
|
||||||
|
if (SystemUtilities.isInHeadlessMode()) {
|
||||||
|
return; // the editor should not be requested in headless mode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deprecatedEditor != null) {
|
||||||
|
return; // already loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecatedEditor = new BooleanEditor();
|
||||||
|
deprecatedEditor.setValue(Boolean.valueOf(useDeprecatedDemangler));
|
||||||
|
formatEditor = new FormatEditor(demanglerFormat, deprecatedEditor);
|
||||||
|
deprecatedEditor.addPropertyChangeListener(formatEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyEditor getDeprecatedNameEditor() {
|
||||||
|
lazyInit();
|
||||||
|
return deprecatedEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyEditor getFormatEditor() {
|
||||||
|
lazyInit();
|
||||||
|
return formatEditor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class FormatEditor extends EnumEditor implements PropertyChangeListener {
|
private static class FormatEditor extends EnumEditor implements PropertyChangeListener {
|
||||||
|
|
||||||
private final FormatSelector selector;
|
private final FormatSelector selector;
|
||||||
|
@ -37,11 +37,11 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
|||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.exception.NotFoundException;
|
import ghidra.util.exception.NotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a service for tracking the selected basic/subroutine block models for a tool.
|
* Provides a service for tracking the selected basic/subroutine block models for a tool.
|
||||||
* Methods are provided for obtaining an instance of the active or arbitrary block model.
|
* Methods are provided for obtaining an instance of the active or arbitrary block model.
|
||||||
* A new model instance is always provided since the internal cache will quickly become
|
* A new model instance is always provided since the internal cache will quickly become
|
||||||
* stale based upon program changes. The current model implementations do not handle
|
* stale based upon program changes. The current model implementations do not handle
|
||||||
* program changes which would invalidate the cached blocks stored within the model.
|
* program changes which would invalidate the cached blocks stored within the model.
|
||||||
*
|
*
|
||||||
* A single basic/sub model list is maintained since it is possible that some uses
|
* A single basic/sub model list is maintained since it is possible that some uses
|
||||||
@ -111,9 +111,12 @@ public class BlockModelServicePlugin extends ProgramPlugin
|
|||||||
|
|
||||||
// Install model selection option in Tool panel
|
// Install model selection option in Tool panel
|
||||||
options = tool.getOptions(ToolConstants.TOOL_OPTIONS);
|
options = tool.getOptions(ToolConstants.TOOL_OPTIONS);
|
||||||
editor = new StringWithChoicesEditor(availableModelNames);
|
|
||||||
options.registerOption(SUB_OPTION, OptionType.STRING_TYPE, selectedSubroutineModelName,
|
options.registerOption(SUB_OPTION, OptionType.STRING_TYPE, selectedSubroutineModelName,
|
||||||
null, "The default subroutine model used when creating call graphs.", editor);
|
null, "The default subroutine model used when creating call graphs.",
|
||||||
|
() -> {
|
||||||
|
editor = new StringWithChoicesEditor(availableModelNames);
|
||||||
|
return editor;
|
||||||
|
});
|
||||||
setPreferedModel(options);
|
setPreferedModel(options);
|
||||||
updateModelOptions();
|
updateModelOptions();
|
||||||
options.addOptionsChangeListener(this);
|
options.addOptionsChangeListener(this);
|
||||||
@ -168,7 +171,9 @@ public class BlockModelServicePlugin extends ProgramPlugin
|
|||||||
|
|
||||||
modelUpdateInProgress = true;
|
modelUpdateInProgress = true;
|
||||||
try {
|
try {
|
||||||
editor.setChoices(availableModelNames);
|
if (editor != null) {
|
||||||
|
editor.setChoices(availableModelNames);
|
||||||
|
}
|
||||||
options.setString(SUB_OPTION, selectedSubroutineModelName);
|
options.setString(SUB_OPTION, selectedSubroutineModelName);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -98,7 +98,7 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
|||||||
|
|
||||||
ToolOptions displayOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
|
ToolOptions displayOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
|
||||||
ToolOptions fieldOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS);
|
ToolOptions fieldOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS);
|
||||||
displayOptions.registerOptionsEditor(new ListingDisplayOptionsEditor(displayOptions));
|
displayOptions.registerOptionsEditor(() -> new ListingDisplayOptionsEditor(displayOptions));
|
||||||
displayOptions.setOptionsHelpLocation(
|
displayOptions.setOptionsHelpLocation(
|
||||||
new HelpLocation(getName(), GhidraOptions.CATEGORY_BROWSER_DISPLAY));
|
new HelpLocation(getName(), GhidraOptions.CATEGORY_BROWSER_DISPLAY));
|
||||||
fieldOptions.setOptionsHelpLocation(
|
fieldOptions.setOptionsHelpLocation(
|
||||||
@ -616,7 +616,7 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
|||||||
options.registerOption(ManualViewerCommandWrappedOption.MANUAL_VIEWER_OPTIONS,
|
options.registerOption(ManualViewerCommandWrappedOption.MANUAL_VIEWER_OPTIONS,
|
||||||
OptionType.CUSTOM_TYPE,
|
OptionType.CUSTOM_TYPE,
|
||||||
ManualViewerCommandWrappedOption.getDefaultBrowserLoaderOptions(), helpLocation,
|
ManualViewerCommandWrappedOption.getDefaultBrowserLoaderOptions(), helpLocation,
|
||||||
"Options for running manual viewer", new ManualViewerCommandEditor());
|
"Options for running manual viewer", () -> new ManualViewerCommandEditor());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager, Opti
|
|||||||
PropertyEditor editor = options.getPropertyEditor(filePropertyName);
|
PropertyEditor editor = options.getPropertyEditor(filePropertyName);
|
||||||
if (editor == null && options.getType(filePropertyName) == OptionType.STRING_TYPE) {
|
if (editor == null && options.getType(filePropertyName) == OptionType.STRING_TYPE) {
|
||||||
options.registerOption(filePropertyName, OptionType.STRING_TYPE, null, null, null,
|
options.registerOption(filePropertyName, OptionType.STRING_TYPE, null, null, null,
|
||||||
new StringBasedFileEditor());
|
() -> new StringBasedFileEditor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.field;
|
package ghidra.app.util.viewer.field;
|
||||||
|
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.field.*;
|
import docking.widgets.fieldpanel.field.*;
|
||||||
@ -47,7 +46,6 @@ public class AddressFieldFactory extends FieldFactory {
|
|||||||
private boolean padZeros;
|
private boolean padZeros;
|
||||||
private int minHexDigits;
|
private int minHexDigits;
|
||||||
private boolean rightJustify;
|
private boolean rightJustify;
|
||||||
private PropertyEditor addressFieldOptionsEditor = new AddressFieldOptionsPropertyEditor();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor
|
* Default Constructor
|
||||||
@ -74,7 +72,7 @@ public class AddressFieldFactory extends FieldFactory {
|
|||||||
|
|
||||||
fieldOptions.registerOption(ADDRESS_DISPLAY_OPTIONS_NAME, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(ADDRESS_DISPLAY_OPTIONS_NAME, OptionType.CUSTOM_TYPE,
|
||||||
new AddressFieldOptionsWrappedOption(), helpLoc, "Adjusts the Address Field display",
|
new AddressFieldOptionsWrappedOption(), helpLoc, "Adjusts the Address Field display",
|
||||||
addressFieldOptionsEditor);
|
() -> new AddressFieldOptionsPropertyEditor());
|
||||||
|
|
||||||
CustomOption customOption =
|
CustomOption customOption =
|
||||||
fieldOptions.getCustomOption(ADDRESS_DISPLAY_OPTIONS_NAME, null);
|
fieldOptions.getCustomOption(ADDRESS_DISPLAY_OPTIONS_NAME, null);
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.field;
|
package ghidra.app.util.viewer.field;
|
||||||
|
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.field.*;
|
import docking.widgets.fieldpanel.field.*;
|
||||||
@ -35,7 +34,6 @@ import ghidra.util.exception.AssertException;
|
|||||||
public class ArrayValuesFieldFactory extends FieldFactory {
|
public class ArrayValuesFieldFactory extends FieldFactory {
|
||||||
public static final String FIELD_NAME = "Array Values";
|
public static final String FIELD_NAME = "Array Values";
|
||||||
private int valuesPerLine;
|
private int valuesPerLine;
|
||||||
private PropertyEditor arrayOptionsEditor = new ArrayElementPropertyEditor();
|
|
||||||
|
|
||||||
public ArrayValuesFieldFactory() {
|
public ArrayValuesFieldFactory() {
|
||||||
super(FIELD_NAME);
|
super(FIELD_NAME);
|
||||||
@ -66,7 +64,7 @@ public class ArrayValuesFieldFactory extends FieldFactory {
|
|||||||
// we need to install a custom editor that allows us to edit a group of related options
|
// we need to install a custom editor that allows us to edit a group of related options
|
||||||
fieldOptions.registerOption(FormatManager.ARRAY_DISPLAY_OPTIONS, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(FormatManager.ARRAY_DISPLAY_OPTIONS, OptionType.CUSTOM_TYPE,
|
||||||
new ArrayElementWrappedOption(), null, FormatManager.ARRAY_DISPLAY_DESCRIPTION,
|
new ArrayElementWrappedOption(), null, FormatManager.ARRAY_DISPLAY_DESCRIPTION,
|
||||||
arrayOptionsEditor);
|
() -> new ArrayElementPropertyEditor());
|
||||||
CustomOption wrappedOption = fieldOptions.getCustomOption(
|
CustomOption wrappedOption = fieldOptions.getCustomOption(
|
||||||
FormatManager.ARRAY_DISPLAY_OPTIONS, new ArrayElementWrappedOption());
|
FormatManager.ARRAY_DISPLAY_OPTIONS, new ArrayElementWrappedOption());
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
|||||||
GhidraOptions.OPERAND_GROUP_TITLE + Options.DELIMITER + "Always Show Primary Reference";
|
GhidraOptions.OPERAND_GROUP_TITLE + Options.DELIMITER + "Always Show Primary Reference";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option for whether to follow referenced pointers, for read or indirect reference types,
|
* Option for whether to follow referenced pointers, for read or indirect reference types,
|
||||||
* to show pointer's referenced symbol instead of symbol at pointer. When applied the
|
* to show pointer's referenced symbol instead of symbol at pointer. When applied the
|
||||||
* resulting label will be preceded by ->.
|
* resulting label will be preceded by ->.
|
||||||
*/
|
*/
|
||||||
private final static String FOLLOW_POINTER_REFERENCE_MARKUP_OPTION =
|
private final static String FOLLOW_POINTER_REFERENCE_MARKUP_OPTION =
|
||||||
@ -98,7 +98,7 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
|||||||
* This constructor must be used by the field factory since an OptionsService may
|
* This constructor must be used by the field factory since an OptionsService may
|
||||||
* not obtainable at the time they are constructed.
|
* not obtainable at the time they are constructed.
|
||||||
* @param fieldOptions field options
|
* @param fieldOptions field options
|
||||||
* @param autoUpdate if true format will auto update if associated options are changed, in
|
* @param autoUpdate if true format will auto update if associated options are changed, in
|
||||||
* addition any listeners will be notified when this format is updated.
|
* addition any listeners will be notified when this format is updated.
|
||||||
*/
|
*/
|
||||||
BrowserCodeUnitFormatOptions(ToolOptions fieldOptions, boolean autoUpdate) {
|
BrowserCodeUnitFormatOptions(ToolOptions fieldOptions, boolean autoUpdate) {
|
||||||
@ -110,7 +110,7 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
|||||||
if (!exists) {
|
if (!exists) {
|
||||||
fieldOptions.registerOption(NAMESPACE_OPTIONS, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(NAMESPACE_OPTIONS, OptionType.CUSTOM_TYPE,
|
||||||
new NamespaceWrappedOption(), null, NAMESPACE_OPTIONS_DESCRIPTIONS,
|
new NamespaceWrappedOption(), null, NAMESPACE_OPTIONS_DESCRIPTIONS,
|
||||||
new NamespacePropertyEditor());
|
() -> new NamespacePropertyEditor());
|
||||||
|
|
||||||
HelpLocation hl = new HelpLocation("CodeBrowserPlugin", "Operands_Field");
|
HelpLocation hl = new HelpLocation("CodeBrowserPlugin", "Operands_Field");
|
||||||
fieldOptions.getOptions(GhidraOptions.OPERAND_GROUP_TITLE).setOptionsHelpLocation(hl);
|
fieldOptions.getOptions(GhidraOptions.OPERAND_GROUP_TITLE).setOptionsHelpLocation(hl);
|
||||||
@ -165,7 +165,7 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
|||||||
private void updateFormat() {
|
private void updateFormat() {
|
||||||
fieldOptions.registerOption(NAMESPACE_OPTIONS, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(NAMESPACE_OPTIONS, OptionType.CUSTOM_TYPE,
|
||||||
new NamespaceWrappedOption(), null, NAMESPACE_OPTIONS_DESCRIPTIONS,
|
new NamespaceWrappedOption(), null, NAMESPACE_OPTIONS_DESCRIPTIONS,
|
||||||
new NamespacePropertyEditor());
|
() -> new NamespacePropertyEditor());
|
||||||
CustomOption customOption =
|
CustomOption customOption =
|
||||||
fieldOptions.getCustomOption(NAMESPACE_OPTIONS, new NamespaceWrappedOption());
|
fieldOptions.getCustomOption(NAMESPACE_OPTIONS, new NamespaceWrappedOption());
|
||||||
if (!(customOption instanceof NamespaceWrappedOption)) {
|
if (!(customOption instanceof NamespaceWrappedOption)) {
|
||||||
@ -240,9 +240,9 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current state of the Follow Referenced Pointers option.
|
* Get current state of the Follow Referenced Pointers option.
|
||||||
* @return true if operand pointer read of indirect references will be followed and
|
* @return true if operand pointer read of indirect references will be followed and
|
||||||
* non-dynamic pointer referenced symbol will be rendered in place of pointer label.
|
* non-dynamic pointer referenced symbol will be rendered in place of pointer label.
|
||||||
*/
|
*/
|
||||||
public boolean followReferencedPointers() {
|
public boolean followReferencedPointers() {
|
||||||
return followReferencedPointers;
|
return followReferencedPointers;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package ghidra.app.util.viewer.field;
|
package ghidra.app.util.viewer.field;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -67,7 +66,6 @@ public class EolCommentFieldFactory extends FieldFactory {
|
|||||||
private int refRepeatableCommentStyle;
|
private int refRepeatableCommentStyle;
|
||||||
|
|
||||||
private EolExtraCommentsOption extraCommentsOption = new EolExtraCommentsOption();
|
private EolExtraCommentsOption extraCommentsOption = new EolExtraCommentsOption();
|
||||||
private PropertyEditor extraCommmentsEditor = new EolExtraCommentsPropertyEditor();
|
|
||||||
|
|
||||||
// The codeUnitFormatOptions is used to monitor "follow pointer..." option to avoid duplication
|
// The codeUnitFormatOptions is used to monitor "follow pointer..." option to avoid duplication
|
||||||
// of data within auto-comment. We don't bother adding a listener to kick the model since this
|
// of data within auto-comment. We don't bother adding a listener to kick the model since this
|
||||||
@ -126,7 +124,7 @@ public class EolCommentFieldFactory extends FieldFactory {
|
|||||||
private void setupAutoCommentOptions(Options fieldOptions, HelpLocation hl) {
|
private void setupAutoCommentOptions(Options fieldOptions, HelpLocation hl) {
|
||||||
fieldOptions.registerOption(EXTRA_COMMENT_KEY, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(EXTRA_COMMENT_KEY, OptionType.CUSTOM_TYPE,
|
||||||
new EolExtraCommentsOption(), hl, "The group of auto comment options",
|
new EolExtraCommentsOption(), hl, "The group of auto comment options",
|
||||||
extraCommmentsEditor);
|
() -> new EolExtraCommentsPropertyEditor());
|
||||||
CustomOption customOption = fieldOptions.getCustomOption(EXTRA_COMMENT_KEY, null);
|
CustomOption customOption = fieldOptions.getCustomOption(EXTRA_COMMENT_KEY, null);
|
||||||
|
|
||||||
if (!(customOption instanceof EolExtraCommentsOption)) {
|
if (!(customOption instanceof EolExtraCommentsOption)) {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.field;
|
package ghidra.app.util.viewer.field;
|
||||||
|
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.field.*;
|
import docking.widgets.fieldpanel.field.*;
|
||||||
@ -49,8 +48,6 @@ public class FileOffsetFieldFactory extends FieldFactory {
|
|||||||
|
|
||||||
private boolean showFilename;
|
private boolean showFilename;
|
||||||
private boolean useHex;
|
private boolean useHex;
|
||||||
private PropertyEditor fileOffsetFieldOptionsEditor =
|
|
||||||
new FileOffsetFieldOptionsPropertyEditor();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor
|
* Default Constructor
|
||||||
@ -77,7 +74,8 @@ public class FileOffsetFieldFactory extends FieldFactory {
|
|||||||
|
|
||||||
fieldOptions.registerOption(FILE_OFFSET_DISPLAY_OPTIONS_NAME, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(FILE_OFFSET_DISPLAY_OPTIONS_NAME, OptionType.CUSTOM_TYPE,
|
||||||
new FileOffsetFieldOptionsWrappedOption(), helpLoc,
|
new FileOffsetFieldOptionsWrappedOption(), helpLoc,
|
||||||
"Adjusts the File Offset Field display", fileOffsetFieldOptionsEditor);
|
"Adjusts the File Offset Field display",
|
||||||
|
() -> new FileOffsetFieldOptionsPropertyEditor());
|
||||||
|
|
||||||
CustomOption customOption =
|
CustomOption customOption =
|
||||||
fieldOptions.getCustomOption(FILE_OFFSET_DISPLAY_OPTIONS_NAME, null);
|
fieldOptions.getCustomOption(FILE_OFFSET_DISPLAY_OPTIONS_NAME, null);
|
||||||
@ -97,7 +95,8 @@ public class FileOffsetFieldFactory extends FieldFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel formatModel,
|
public FieldFactory newInstance(FieldFormatModel formatModel,
|
||||||
ListingHighlightProvider 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.field;
|
package ghidra.app.util.viewer.field;
|
||||||
|
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -60,8 +59,6 @@ public class LabelFieldFactory extends FieldFactory {
|
|||||||
private Icon ANCHOR_ICON =
|
private Icon ANCHOR_ICON =
|
||||||
new MultiIcon(EMPTY_ICON, new GIcon("icon.base.util.viewer.fieldfactory.label"));
|
new MultiIcon(EMPTY_ICON, new GIcon("icon.base.util.viewer.fieldfactory.label"));
|
||||||
|
|
||||||
private PropertyEditor namespaceOptionsEditor = new NamespacePropertyEditor();
|
|
||||||
|
|
||||||
private boolean displayFunctionLabel;
|
private boolean displayFunctionLabel;
|
||||||
private boolean displayLocalNamespace;
|
private boolean displayLocalNamespace;
|
||||||
private boolean displayNonLocalNamespace;
|
private boolean displayNonLocalNamespace;
|
||||||
@ -107,7 +104,7 @@ public class LabelFieldFactory extends FieldFactory {
|
|||||||
// we need to install a custom editor that allows us to edit a group of related options
|
// we need to install a custom editor that allows us to edit a group of related options
|
||||||
fieldOptions.registerOption(NAMESPACE_OPTIONS, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(NAMESPACE_OPTIONS, OptionType.CUSTOM_TYPE,
|
||||||
new NamespaceWrappedOption(), null, "Adjusts the Label Field namespace display",
|
new NamespaceWrappedOption(), null, "Adjusts the Label Field namespace display",
|
||||||
namespaceOptionsEditor);
|
() -> new NamespacePropertyEditor());
|
||||||
CustomOption wrappedOption =
|
CustomOption wrappedOption =
|
||||||
fieldOptions.getCustomOption(NAMESPACE_OPTIONS, new NamespaceWrappedOption());
|
fieldOptions.getCustomOption(NAMESPACE_OPTIONS, new NamespaceWrappedOption());
|
||||||
if (!(wrappedOption instanceof NamespaceWrappedOption)) {
|
if (!(wrappedOption instanceof NamespaceWrappedOption)) {
|
||||||
|
@ -17,7 +17,6 @@ package ghidra.app.util.viewer.field;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@ -75,8 +74,6 @@ public class XRefFieldFactory extends FieldFactory {
|
|||||||
static final String GROUP_BY_FUNCTION_KEY =
|
static final String GROUP_BY_FUNCTION_KEY =
|
||||||
GROUP_TITLE + Options.DELIMITER + "Group by Function";
|
GROUP_TITLE + Options.DELIMITER + "Group by Function";
|
||||||
|
|
||||||
private PropertyEditor namespaceOptionsEditor = new NamespacePropertyEditor();
|
|
||||||
|
|
||||||
protected String delim = DELIMITER;
|
protected String delim = DELIMITER;
|
||||||
protected boolean displayBlockName;
|
protected boolean displayBlockName;
|
||||||
protected boolean groupByFunction;
|
protected boolean groupByFunction;
|
||||||
@ -168,7 +165,7 @@ public class XRefFieldFactory extends FieldFactory {
|
|||||||
// we need to install a custom editor that allows us to edit a group of related options
|
// we need to install a custom editor that allows us to edit a group of related options
|
||||||
fieldOptions.registerOption(NAMESPACE_OPTIONS_KEY, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(NAMESPACE_OPTIONS_KEY, OptionType.CUSTOM_TYPE,
|
||||||
new NamespaceWrappedOption(), new HelpLocation("CodeBrowserPlugin", "XREFs_Field"),
|
new NamespaceWrappedOption(), new HelpLocation("CodeBrowserPlugin", "XREFs_Field"),
|
||||||
"Adjusts the XREFs Field namespace display", namespaceOptionsEditor);
|
"Adjusts the XREFs Field namespace display", () -> new NamespacePropertyEditor());
|
||||||
CustomOption customOption = fieldOptions.getCustomOption(NAMESPACE_OPTIONS_KEY, null);
|
CustomOption customOption = fieldOptions.getCustomOption(NAMESPACE_OPTIONS_KEY, null);
|
||||||
|
|
||||||
if (!(customOption instanceof NamespaceWrappedOption)) {
|
if (!(customOption instanceof NamespaceWrappedOption)) {
|
||||||
|
@ -71,7 +71,7 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
TemplateSimplifier templateSimplifier;
|
TemplateSimplifier templateSimplifier;
|
||||||
|
|
||||||
// NOTE: Unused custom format code was removed. The custom format code last existed in
|
// NOTE: Unused custom format code was removed. The custom format code last existed in
|
||||||
// commit #204e7892bf2f110ebb05ca4beee3fe5b397f88c9.
|
// commit #204e7892bf2f110ebb05ca4beee3fe5b397f88c9.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new FormatManager.
|
* Constructs a new FormatManager.
|
||||||
@ -100,7 +100,7 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
private void getArrayDisplayOptions(Options options) {
|
private void getArrayDisplayOptions(Options options) {
|
||||||
options.registerOption(ARRAY_DISPLAY_OPTIONS, OptionType.CUSTOM_TYPE,
|
options.registerOption(ARRAY_DISPLAY_OPTIONS, OptionType.CUSTOM_TYPE,
|
||||||
new ArrayElementWrappedOption(), null, ARRAY_DISPLAY_DESCRIPTION,
|
new ArrayElementWrappedOption(), null, ARRAY_DISPLAY_DESCRIPTION,
|
||||||
new ArrayElementPropertyEditor());
|
() -> new ArrayElementPropertyEditor());
|
||||||
CustomOption option = options.getCustomOption(ARRAY_DISPLAY_OPTIONS, null);
|
CustomOption option = options.getCustomOption(ARRAY_DISPLAY_OPTIONS, null);
|
||||||
if (option instanceof ArrayElementWrappedOption) {
|
if (option instanceof ArrayElementWrappedOption) {
|
||||||
ArrayElementWrappedOption arrayOption = (ArrayElementWrappedOption) option;
|
ArrayElementWrappedOption arrayOption = (ArrayElementWrappedOption) option;
|
||||||
@ -174,7 +174,7 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the total number of model in the format manager.
|
* Returns the total number of model in the format manager.
|
||||||
* @return the total number of model in the format manager
|
* @return the total number of model in the format manager
|
||||||
*/
|
*/
|
||||||
public int getNumModels() {
|
public int getNumModels() {
|
||||||
return NUM_MODELS;
|
return NUM_MODELS;
|
||||||
@ -200,7 +200,7 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the format model for the plate field.
|
* Returns the format model for the plate field.
|
||||||
* @return the format model for the plate field
|
* @return the format model for the plate field
|
||||||
*/
|
*/
|
||||||
public FieldFormatModel getPlateFormat() {
|
public FieldFormatModel getPlateFormat() {
|
||||||
return models[FieldFormatModel.PLATE];
|
return models[FieldFormatModel.PLATE];
|
||||||
@ -279,7 +279,7 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Options used for field specific properties.
|
* Returns the Options used for field specific properties.
|
||||||
* @return the Options used for field specific properties
|
* @return the Options used for field specific properties
|
||||||
*/
|
*/
|
||||||
public ToolOptions getFieldOptions() {
|
public ToolOptions getFieldOptions() {
|
||||||
return fieldOptions;
|
return fieldOptions;
|
||||||
@ -847,7 +847,7 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all {@link ListingHighlightProvider}s installed on this FormatManager via the
|
* Gets all {@link ListingHighlightProvider}s installed on this FormatManager via the
|
||||||
* {@link #addHighlightProvider(ListingHighlightProvider)}.
|
* {@link #addHighlightProvider(ListingHighlightProvider)}.
|
||||||
*
|
*
|
||||||
* @return all {@link ListingHighlightProvider}s installed on this FormatManager.
|
* @return all {@link ListingHighlightProvider}s installed on this FormatManager.
|
||||||
@ -930,12 +930,12 @@ public class FormatManager implements OptionsChangeListener {
|
|||||||
public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
|
public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Gather and use all other registered providers.
|
// Gather and use all other registered providers.
|
||||||
//
|
//
|
||||||
// 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--) {
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.misc;
|
package ghidra.app.plugin.core.misc;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
@ -53,7 +52,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
runSwing(() -> DockingDialog.createDialog(null, dialogComponent, null));
|
runSwing(() -> DockingDialog.createDialog(null, dialogComponent, null));
|
||||||
SwingUtilities.invokeLater(() -> editorDialog.setVisible(true));
|
SwingUtilities.invokeLater(() -> editorDialog.setVisible(true));
|
||||||
|
|
||||||
waitForJDialog(null, "Test Properties", 500);
|
waitForJDialog("Test Properties");
|
||||||
assertNotNull("Dialog failed to launch", editorDialog);
|
assertNotNull("Dialog failed to launch", editorDialog);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
waitForOptionsTree(dialogComponent);
|
waitForOptionsTree(dialogComponent);
|
||||||
@ -219,7 +218,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
Options options = new ToolOptions("Test");
|
Options options = new ToolOptions("Test");
|
||||||
String[] choices = new String[] { "abc", "def", "ghi", "jkl" };
|
String[] choices = new String[] { "abc", "def", "ghi", "jkl" };
|
||||||
options.registerOption("TestStringWithChoices", OptionType.STRING_TYPE, choices[0], null,
|
options.registerOption("TestStringWithChoices", OptionType.STRING_TYPE, choices[0], null,
|
||||||
"String Choices", new StringWithChoicesEditor(choices));
|
"String Choices", () -> new StringWithChoicesEditor(choices));
|
||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ public class OptionsDBTest extends AbstractDockingTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRegisterPropertyEditor() {
|
public void testRegisterPropertyEditor() {
|
||||||
MyPropertyEditor editor = new MyPropertyEditor();
|
MyPropertyEditor editor = new MyPropertyEditor();
|
||||||
options.registerOption("foo", OptionType.INT_TYPE, 5, null, "description", editor);
|
options.registerOption("foo", OptionType.INT_TYPE, 5, null, "description", () -> editor);
|
||||||
assertEquals(editor, options.getRegisteredPropertyEditor("foo"));
|
assertEquals(editor, options.getRegisteredPropertyEditor("foo"));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -561,12 +561,11 @@ public class OptionsDBTest extends AbstractDockingTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRegisteringOptionsEditor() {
|
public void testRegisteringOptionsEditor() {
|
||||||
MyOptionsEditor myOptionsEditor = new MyOptionsEditor();
|
MyOptionsEditor myOptionsEditor = new MyOptionsEditor();
|
||||||
options.registerOptionsEditor(myOptionsEditor);
|
options.registerOptionsEditor(() -> myOptionsEditor);
|
||||||
assertEquals(myOptionsEditor, options.getOptionsEditor());
|
assertEquals(myOptionsEditor, options.getOptionsEditor());
|
||||||
Options subOptions = options.getOptions("SUB");
|
Options subOptions = options.getOptions("SUB");
|
||||||
subOptions.registerOptionsEditor(myOptionsEditor);
|
subOptions.registerOptionsEditor(() -> myOptionsEditor);
|
||||||
assertEquals(myOptionsEditor, subOptions.getOptionsEditor());
|
assertEquals(myOptionsEditor, subOptions.getOptionsEditor());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -296,7 +296,8 @@ public class OptionsTest extends AbstractGuiTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRegisterPropertyEditor() {
|
public void testRegisterPropertyEditor() {
|
||||||
MyPropertyEditor editor = new MyPropertyEditor();
|
MyPropertyEditor editor = new MyPropertyEditor();
|
||||||
options.registerOption("color", OptionType.COLOR_TYPE, Color.RED, null, "foo", editor);
|
options.registerOption("color", OptionType.COLOR_TYPE, Color.RED, null, "foo",
|
||||||
|
() -> editor);
|
||||||
assertEquals(editor, options.getRegisteredPropertyEditor("color"));
|
assertEquals(editor, options.getRegisteredPropertyEditor("color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,10 +571,10 @@ public class OptionsTest extends AbstractGuiTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRegisteringOptionsEditor() {
|
public void testRegisteringOptionsEditor() {
|
||||||
MyOptionsEditor myOptionsEditor = new MyOptionsEditor();
|
MyOptionsEditor myOptionsEditor = new MyOptionsEditor();
|
||||||
options.registerOptionsEditor(myOptionsEditor);
|
options.registerOptionsEditor(() -> myOptionsEditor);
|
||||||
assertEquals(myOptionsEditor, options.getOptionsEditor());
|
assertEquals(myOptionsEditor, options.getOptionsEditor());
|
||||||
Options subOptions = options.getOptions("SUB");
|
Options subOptions = options.getOptions("SUB");
|
||||||
subOptions.registerOptionsEditor(myOptionsEditor);
|
subOptions.registerOptionsEditor(() -> myOptionsEditor);
|
||||||
assertEquals(myOptionsEditor, subOptions.getOptionsEditor());
|
assertEquals(myOptionsEditor, subOptions.getOptionsEditor());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.analysis;
|
package ghidra.app.plugin.core.analysis;
|
||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.*;
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import docking.options.editor.BooleanEditor;
|
import docking.options.editor.BooleanEditor;
|
||||||
@ -93,24 +92,16 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
|||||||
options.registerOption(OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS, demangleOnlyKnownPatterns,
|
options.registerOption(OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS, demangleOnlyKnownPatterns,
|
||||||
help, OPTION_DESCRIPTION_USE_KNOWN_PATTERNS);
|
help, OPTION_DESCRIPTION_USE_KNOWN_PATTERNS);
|
||||||
|
|
||||||
BooleanEditor deprecatedEditor = null;
|
GnuOptionsEditor optionsEditor = new GnuOptionsEditor();
|
||||||
FormatEditor formatEditor = null;
|
|
||||||
if (!SystemUtilities.isInHeadlessMode()) {
|
|
||||||
// Only add the custom options editor when not headless. The custom editor allows
|
|
||||||
// the list of choices presented to the user to change depending on the state of the
|
|
||||||
// useDeprecatedDemangler flag.
|
|
||||||
deprecatedEditor = new BooleanEditor();
|
|
||||||
deprecatedEditor.setValue(Boolean.valueOf(useDeprecatedDemangler));
|
|
||||||
formatEditor = new FormatEditor(demanglerFormat, deprecatedEditor);
|
|
||||||
deprecatedEditor.addPropertyChangeListener(formatEditor);
|
|
||||||
}
|
|
||||||
|
|
||||||
options.registerOption(OPTION_NAME_USE_DEPRECATED_DEMANGLER, OptionType.BOOLEAN_TYPE,
|
options.registerOption(OPTION_NAME_USE_DEPRECATED_DEMANGLER, OptionType.BOOLEAN_TYPE,
|
||||||
useDeprecatedDemangler, help, OPTION_DESCRIPTION_DEPRECATED_DEMANGLER,
|
useDeprecatedDemangler, help, OPTION_DESCRIPTION_DEPRECATED_DEMANGLER,
|
||||||
deprecatedEditor);
|
() -> optionsEditor.getDeprecatedNameEditor());
|
||||||
|
|
||||||
options.registerOption(OPTION_NAME_DEMANGLER_FORMAT, OptionType.ENUM_TYPE,
|
options.registerOption(OPTION_NAME_DEMANGLER_FORMAT, OptionType.ENUM_TYPE,
|
||||||
demanglerFormat, help, OPTION_DESCRIPTION_DEMANGLER_FORMAT, formatEditor);
|
demanglerFormat, help, OPTION_DESCRIPTION_DEMANGLER_FORMAT,
|
||||||
|
() -> optionsEditor.getFormatEditor());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -143,6 +134,45 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
|||||||
return demangler.demangle(mangled, demanglerOtions);
|
return demangler.demangle(mangled, demanglerOtions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Inner Classes
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
// We only use the editor when not headless, since GUI code in headless will throw an exception.
|
||||||
|
// Further, the options below have a relationship, so we need to build them together.
|
||||||
|
// The format editor's list of choices presented to the user will change depending on the state
|
||||||
|
// of the deprecated boolean editor.
|
||||||
|
private class GnuOptionsEditor {
|
||||||
|
|
||||||
|
private BooleanEditor deprecatedEditor;
|
||||||
|
private FormatEditor formatEditor;
|
||||||
|
|
||||||
|
private void lazyInit() {
|
||||||
|
if (SystemUtilities.isInHeadlessMode()) {
|
||||||
|
return; // the editor should not be requested in headless mode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deprecatedEditor != null) {
|
||||||
|
return; // already loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecatedEditor = new BooleanEditor();
|
||||||
|
deprecatedEditor.setValue(Boolean.valueOf(useDeprecatedDemangler));
|
||||||
|
formatEditor = new FormatEditor(demanglerFormat, deprecatedEditor);
|
||||||
|
deprecatedEditor.addPropertyChangeListener(formatEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyEditor getDeprecatedNameEditor() {
|
||||||
|
lazyInit();
|
||||||
|
return deprecatedEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyEditor getFormatEditor() {
|
||||||
|
lazyInit();
|
||||||
|
return formatEditor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class FormatEditor extends EnumEditor implements PropertyChangeListener {
|
private static class FormatEditor extends EnumEditor implements PropertyChangeListener {
|
||||||
|
|
||||||
private final FormatSelector selector;
|
private final FormatSelector selector;
|
||||||
@ -221,6 +251,5 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
|||||||
void setFormat(GnuDemanglerFormat format) {
|
void setFormat(GnuDemanglerFormat format) {
|
||||||
setSelectedItem(format.name());
|
setSelectedItem(format.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ public class VTPlugin extends Plugin {
|
|||||||
|
|
||||||
private void initializeOptions() {
|
private void initializeOptions() {
|
||||||
Options options = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
|
Options options = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
|
||||||
options.registerOptionsEditor(new ListingDisplayOptionsEditor(options));
|
options.registerOptionsEditor(() -> new ListingDisplayOptionsEditor(options));
|
||||||
options.setOptionsHelpLocation(new HelpLocation(CodeBrowserPlugin.class.getSimpleName(),
|
options.setOptionsHelpLocation(new HelpLocation(CodeBrowserPlugin.class.getSimpleName(),
|
||||||
GhidraOptions.CATEGORY_BROWSER_DISPLAY));
|
GhidraOptions.CATEGORY_BROWSER_DISPLAY));
|
||||||
|
|
||||||
|
@ -703,7 +703,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
"should become ignored by applying a match.");
|
"should become ignored by applying a match.");
|
||||||
|
|
||||||
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
||||||
.registerOptionsEditor(new ApplyMarkupPropertyEditor(controller));
|
.registerOptionsEditor(() -> new ApplyMarkupPropertyEditor(controller));
|
||||||
vtOptions.getOptions(DISPLAY_APPLY_MARKUP_OPTIONS)
|
vtOptions.getOptions(DISPLAY_APPLY_MARKUP_OPTIONS)
|
||||||
.setOptionsHelpLocation(
|
.setOptionsHelpLocation(
|
||||||
new HelpLocation("VersionTracking", "Apply Markup Options"));
|
new HelpLocation("VersionTracking", "Apply Markup Options"));
|
||||||
|
@ -111,6 +111,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
* {@link GraphType}s that have options registered in the tool.
|
* {@link GraphType}s that have options registered in the tool.
|
||||||
* @param graphType The {@link GraphType} for which to define display options
|
* @param graphType The {@link GraphType} for which to define display options
|
||||||
* @param tool the tool from which to initialize from {@link ToolOptions}
|
* @param tool the tool from which to initialize from {@link ToolOptions}
|
||||||
|
* @param help the help location
|
||||||
*/
|
*/
|
||||||
protected GraphDisplayOptions(GraphType graphType, Tool tool, HelpLocation help) {
|
protected GraphDisplayOptions(GraphType graphType, Tool tool, HelpLocation help) {
|
||||||
this(graphType);
|
this(graphType);
|
||||||
@ -380,7 +381,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the color for vertices with the given vertex type. Note that this method does not
|
* Sets the color for vertices with the given vertex type. Note that this method does not
|
||||||
* allow the vertex color to be registered in tool options.
|
* allow the vertex color to be registered in tool options.
|
||||||
* See {@link #setVertexColor(String, String)}.
|
* See {@link #setVertexColor(String, String)}.
|
||||||
* @param vertexType the vertex type for which to set its color
|
* @param vertexType the vertex type for which to set its color
|
||||||
* @param color the color to use for vertices with the given vertex type
|
* @param color the color to use for vertices with the given vertex type
|
||||||
@ -392,7 +393,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the vertex color using a theme color id. By using a theme color id, this property
|
* Sets the vertex color using a theme color id. By using a theme color id, this property
|
||||||
* is eligible to be registered as a tool option.
|
* is eligible to be registered as a tool option.
|
||||||
* @param vertexType the vertex type for which to set its color
|
* @param vertexType the vertex type for which to set its color
|
||||||
* @param themeColorId the theme color id of the color for this vertex type
|
* @param themeColorId the theme color id of the color for this vertex type
|
||||||
*/
|
*/
|
||||||
@ -428,7 +429,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the edge color using a theme color id. By using a theme color id, this property
|
* Sets the edge color using a theme color id. By using a theme color id, this property
|
||||||
* is eligible to be registered as a tool option.
|
* is eligible to be registered as a tool option.
|
||||||
* @param edgeType the edge type for which to set its color
|
* @param edgeType the edge type for which to set its color
|
||||||
* @param themeColorId the theme color id of the color for this edge type
|
* @param themeColorId the theme color id of the color for this edge type
|
||||||
*/
|
*/
|
||||||
@ -574,7 +575,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the rendering mode is to use icons for the vertices. If using
|
* Returns true if the rendering mode is to use icons for the vertices. If using
|
||||||
* icons, the label is drawn inside the shape.
|
* icons, the label is drawn inside the shape.
|
||||||
* @return true if the rendering mode is to use icons.
|
* @return true if the rendering mode is to use icons.
|
||||||
*/
|
*/
|
||||||
public boolean usesIcons() {
|
public boolean usesIcons() {
|
||||||
@ -592,7 +593,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the label position relative to the vertex. Note this is only relevant
|
* Returns the label position relative to the vertex. Note this is only relevant
|
||||||
* if {@link #usesIcons()} is false
|
* if {@link #usesIcons()} is false
|
||||||
* @return the label position relative to the vertex
|
* @return the label position relative to the vertex
|
||||||
*/
|
*/
|
||||||
@ -659,8 +660,8 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum number of nodes a graph can have and still be displayed. Be careful,
|
* Sets the maximum number of nodes a graph can have and still be displayed. Be careful,
|
||||||
* setting this value too high can result in Ghidra running out of memory and/or
|
* setting this value too high can result in Ghidra running out of memory and/or
|
||||||
* making the system very sluggish.
|
* making the system very sluggish.
|
||||||
* @param maxNodeCount the maximum number of nodes a graph can have and still be displayed.
|
* @param maxNodeCount the maximum number of nodes a graph can have and still be displayed.
|
||||||
*/
|
*/
|
||||||
@ -705,7 +706,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
* are registered with tool options, show the tool options with the appropriate
|
* are registered with tool options, show the tool options with the appropriate
|
||||||
* graph options selected. Otherwise, show an editor for locally editing these
|
* graph options selected. Otherwise, show an editor for locally editing these
|
||||||
* options.
|
* options.
|
||||||
* @param tool the tool
|
* @param tool the tool
|
||||||
* @param help the help location to use if the options are edited locally
|
* @param help the help location to use if the options are edited locally
|
||||||
*/
|
*/
|
||||||
public void displayEditor(Tool tool, HelpLocation help) {
|
public void displayEditor(Tool tool, HelpLocation help) {
|
||||||
@ -723,7 +724,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, create a new empty options, register the graph options into the
|
// Otherwise, create a new empty options, register the graph options into the
|
||||||
// those options and use our options editor on those options to allow the
|
// those options and use our options editor on those options to allow the
|
||||||
// user to change these graph display options.
|
// user to change these graph display options.
|
||||||
|
|
||||||
ToolOptions transientOptions = new ToolOptions("Graph");
|
ToolOptions transientOptions = new ToolOptions("Graph");
|
||||||
@ -740,7 +741,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets default values for vertex types. This method does not allow the vertexType color to
|
* Sets default values for vertex types. This method does not allow the vertexType color to
|
||||||
* be eligible to be registered as a tool option.
|
* be eligible to be registered as a tool option.
|
||||||
* @param vertexType the vertex type whose default color and shape are being defined
|
* @param vertexType the vertex type whose default color and shape are being defined
|
||||||
* @param vertexShape the default vertex shape for the given vertex type
|
* @param vertexShape the default vertex shape for the given vertex type
|
||||||
@ -765,7 +766,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets default values for edge types. This method does not allow the vertexType color to
|
* Sets default values for edge types. This method does not allow the vertexType color to
|
||||||
* be eligible to be registered as a tool option.
|
* be eligible to be registered as a tool option.
|
||||||
* @param edgeType the edge type whose default color and shape are being defined
|
* @param edgeType the edge type whose default color and shape are being defined
|
||||||
* @param color the default color for the given edge type
|
* @param color the default color for the given edge type
|
||||||
@ -879,8 +880,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<String> list = new ArrayList<>(graphType.getVertexTypes());
|
List<String> list = new ArrayList<>(graphType.getVertexTypes());
|
||||||
OptionsEditor editor = new ScrollableOptionsEditor(VERTEX_COLORS, list);
|
options.registerOptionsEditor(() -> new ScrollableOptionsEditor(VERTEX_COLORS, list));
|
||||||
options.registerOptionsEditor(editor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerVertexShapeOptions(Options rootOptions, HelpLocation help) {
|
private void registerVertexShapeOptions(Options rootOptions, HelpLocation help) {
|
||||||
@ -889,14 +889,12 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
List<String> shapeNames = VertexShape.getShapeNames();
|
List<String> shapeNames = VertexShape.getShapeNames();
|
||||||
|
|
||||||
for (String vertexType : graphType.getVertexTypes()) {
|
for (String vertexType : graphType.getVertexTypes()) {
|
||||||
StringWithChoicesEditor editor = new StringWithChoicesEditor(shapeNames);
|
|
||||||
options.registerOption(vertexType, OptionType.STRING_TYPE,
|
options.registerOption(vertexType, OptionType.STRING_TYPE,
|
||||||
getVertexShapeName(vertexType), help, "Choose the shape for this vertex type",
|
getVertexShapeName(vertexType), help, "Choose the shape for this vertex type",
|
||||||
editor);
|
() -> new StringWithChoicesEditor(shapeNames));
|
||||||
}
|
}
|
||||||
List<String> list = new ArrayList<>(graphType.getVertexTypes());
|
List<String> list = new ArrayList<>(graphType.getVertexTypes());
|
||||||
OptionsEditor editor = new ScrollableOptionsEditor(VERTEX_SHAPES, list);
|
options.registerOptionsEditor(() -> new ScrollableOptionsEditor(VERTEX_SHAPES, list));
|
||||||
options.registerOptionsEditor(editor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerEdgeColorOptions(Options rootOptions, HelpLocation help) {
|
private void registerEdgeColorOptions(Options rootOptions, HelpLocation help) {
|
||||||
@ -909,8 +907,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<String> list = new ArrayList<>(graphType.getEdgeTypes());
|
List<String> list = new ArrayList<>(graphType.getEdgeTypes());
|
||||||
OptionsEditor editor = new ScrollableOptionsEditor(EDGE_COLORS, list);
|
options.registerOptionsEditor(() -> new ScrollableOptionsEditor(EDGE_COLORS, list));
|
||||||
options.registerOptionsEditor(editor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerMiscellaneousOptions(Options rootOptions, HelpLocation help) {
|
private void registerMiscellaneousOptions(Options rootOptions, HelpLocation help) {
|
||||||
@ -921,7 +918,6 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
optionNamesInDisplayOrder.add(MAX_NODES_SIZE);
|
optionNamesInDisplayOrder.add(MAX_NODES_SIZE);
|
||||||
options.registerOption(MAX_NODES_SIZE, OptionType.INT_TYPE, maxNodeCount, help,
|
options.registerOption(MAX_NODES_SIZE, OptionType.INT_TYPE, maxNodeCount, help,
|
||||||
"Graphs with more than this number of nodes will not be displayed. (Large graphs can cause Ghidra to become unstable/sluggish)");
|
"Graphs with more than this number of nodes will not be displayed. (Large graphs can cause Ghidra to become unstable/sluggish)");
|
||||||
StringWithChoicesEditor editor = new StringWithChoicesEditor(VertexShape.getShapeNames());
|
|
||||||
|
|
||||||
if (defaultRegistrations.containsKey(VERTEX_SELECTION_COLOR)) {
|
if (defaultRegistrations.containsKey(VERTEX_SELECTION_COLOR)) {
|
||||||
optionNamesInDisplayOrder.add(VERTEX_SELECTION_COLOR);
|
optionNamesInDisplayOrder.add(VERTEX_SELECTION_COLOR);
|
||||||
@ -954,20 +950,21 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
optionNamesInDisplayOrder.add(DEFAULT_VERTEX_SHAPE);
|
optionNamesInDisplayOrder.add(DEFAULT_VERTEX_SHAPE);
|
||||||
options.registerOption(DEFAULT_VERTEX_SHAPE, OptionType.STRING_TYPE,
|
options.registerOption(DEFAULT_VERTEX_SHAPE, OptionType.STRING_TYPE,
|
||||||
defaultVertexShape.getName(), help,
|
defaultVertexShape.getName(), help,
|
||||||
"Shape for vertices that have no vertex type defined", editor);
|
"Shape for vertices that have no vertex type defined",
|
||||||
|
() -> new StringWithChoicesEditor(VertexShape.getShapeNames()));
|
||||||
|
|
||||||
optionNamesInDisplayOrder.add(FAVORED_EDGE_TYPE);
|
optionNamesInDisplayOrder.add(FAVORED_EDGE_TYPE);
|
||||||
List<String> edgeTypes = graphType.getEdgeTypes();
|
List<String> edgeTypes = graphType.getEdgeTypes();
|
||||||
if (!edgeTypes.isEmpty()) {
|
if (!edgeTypes.isEmpty()) {
|
||||||
editor = new StringWithChoicesEditor(edgeTypes);
|
|
||||||
options.registerOption(FAVORED_EDGE_TYPE, OptionType.STRING_TYPE, favoredEdgeType, help,
|
options.registerOption(FAVORED_EDGE_TYPE, OptionType.STRING_TYPE, favoredEdgeType, help,
|
||||||
"Favored edge is used to influence layout algorithms", editor);
|
"Favored edge is used to influence layout algorithms",
|
||||||
|
() -> new StringWithChoicesEditor(edgeTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
optionNamesInDisplayOrder.add(DEFAULT_LAYOUT_ALGORITHM);
|
optionNamesInDisplayOrder.add(DEFAULT_LAYOUT_ALGORITHM);
|
||||||
editor = new StringWithChoicesEditor(LayoutAlgorithmNames.getLayoutAlgorithmNames());
|
|
||||||
options.registerOption(DEFAULT_LAYOUT_ALGORITHM, OptionType.STRING_TYPE,
|
options.registerOption(DEFAULT_LAYOUT_ALGORITHM, OptionType.STRING_TYPE,
|
||||||
defaultLayoutAlgorithmName, help, "Initial layout algorithm", editor);
|
defaultLayoutAlgorithmName, help, "Initial layout algorithm",
|
||||||
|
() -> new StringWithChoicesEditor(LayoutAlgorithmNames.getLayoutAlgorithmNames()));
|
||||||
|
|
||||||
optionNamesInDisplayOrder.add(LABEL_POSITION);
|
optionNamesInDisplayOrder.add(LABEL_POSITION);
|
||||||
options.registerOption(LABEL_POSITION, OptionType.ENUM_TYPE, labelPosition, help,
|
options.registerOption(LABEL_POSITION, OptionType.ENUM_TYPE, labelPosition, help,
|
||||||
@ -982,11 +979,8 @@ public class GraphDisplayOptions implements OptionsChangeListener {
|
|||||||
optionNamesInDisplayOrder.add(USE_ICONS);
|
optionNamesInDisplayOrder.add(USE_ICONS);
|
||||||
options.registerOption(USE_ICONS, OptionType.BOOLEAN_TYPE, useIcons, help,
|
options.registerOption(USE_ICONS, OptionType.BOOLEAN_TYPE, useIcons, help,
|
||||||
"If true, vertices are drawn using pre-rendered images versus compact shapes");
|
"If true, vertices are drawn using pre-rendered images versus compact shapes");
|
||||||
|
options.registerOptionsEditor(
|
||||||
OptionsEditor optionsEditor =
|
() -> new ScrollableOptionsEditor(MISCELLANEOUS_OPTIONS, optionNamesInDisplayOrder));
|
||||||
new ScrollableOptionsEditor(MISCELLANEOUS_OPTIONS, optionNamesInDisplayOrder);
|
|
||||||
options.registerOptionsEditor(optionsEditor);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVertexType(String vertexType) {
|
private void checkVertexType(String vertexType) {
|
||||||
|
@ -21,17 +21,17 @@ import java.beans.PropertyEditor;
|
|||||||
import java.beans.PropertyEditorManager;
|
import java.beans.PropertyEditorManager;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
|
|
||||||
import generic.theme.*;
|
import generic.theme.*;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.*;
|
||||||
import ghidra.util.Msg;
|
|
||||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import utilities.util.reflection.ReflectionUtilities;
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
|
import utility.function.Dummy;
|
||||||
|
|
||||||
public abstract class AbstractOptions implements Options {
|
public abstract class AbstractOptions implements Options {
|
||||||
public static final Set<Class<?>> SUPPORTED_CLASSES = buildSupportedClassSet();
|
public static final Set<Class<?>> SUPPORTED_CLASSES = buildSupportedClassSet();
|
||||||
@ -83,7 +83,14 @@ public abstract class AbstractOptions implements Options {
|
|||||||
protected abstract boolean notifyOptionChanged(String optionName, Object oldValue,
|
protected abstract boolean notifyOptionChanged(String optionName, Object oldValue,
|
||||||
Object newValue);
|
Object newValue);
|
||||||
|
|
||||||
public synchronized void registerOptionsEditor(String categoryPath, OptionsEditor editor) {
|
public synchronized void registerOptionsEditor(String categoryPath,
|
||||||
|
Supplier<OptionsEditor> editorSupplier) {
|
||||||
|
|
||||||
|
OptionsEditor editor = null;
|
||||||
|
if (!SystemUtilities.isInHeadlessMode()) {
|
||||||
|
editor = editorSupplier.get();
|
||||||
|
}
|
||||||
|
|
||||||
optionsEditorMap.put(categoryPath, editor);
|
optionsEditorMap.put(categoryPath, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,12 +135,13 @@ public abstract class AbstractOptions implements Options {
|
|||||||
@Override
|
@Override
|
||||||
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||||
HelpLocation help, String description) {
|
HelpLocation help, String description) {
|
||||||
registerOption(optionName, type, defaultValue, help, description, null);
|
registerOption(optionName, type, defaultValue, help, description,
|
||||||
|
(Supplier<PropertyEditor>) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void registerOption(String optionName, OptionType type, Object defaultValue,
|
public synchronized void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||||
HelpLocation help, String description, PropertyEditor editor) {
|
HelpLocation help, String description, Supplier<PropertyEditor> editorSupplier) {
|
||||||
|
|
||||||
if (type == OptionType.NO_TYPE) {
|
if (type == OptionType.NO_TYPE) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@ -153,10 +161,20 @@ public abstract class AbstractOptions implements Options {
|
|||||||
", defaultValue = " + defaultValue);
|
", defaultValue = " + defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == OptionType.CUSTOM_TYPE && editor == null) {
|
editorSupplier = Dummy.ifNull(editorSupplier);
|
||||||
throw new IllegalStateException(
|
PropertyEditor editor = null;
|
||||||
"Can't register a custom option without a property editor");
|
boolean isHeadless = SystemUtilities.isInHeadlessMode();
|
||||||
|
if (!isHeadless) {
|
||||||
|
editor = editorSupplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == OptionType.CUSTOM_TYPE) {
|
||||||
|
if (!isHeadless && editor == null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Can't register a custom option without a property editor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (description == null) {
|
if (description == null) {
|
||||||
Msg.error(this, "Registered an option without a description: " + optionName,
|
Msg.error(this, "Registered an option without a description: " + optionName,
|
||||||
ReflectionUtilities.createJavaFilteredThrowable());
|
ReflectionUtilities.createJavaFilteredThrowable());
|
||||||
@ -169,7 +187,8 @@ public abstract class AbstractOptions implements Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Option option =
|
Option option =
|
||||||
createRegisteredOption(optionName, type, description, help, defaultValue, editor);
|
createRegisteredOption(optionName, type, description, help, defaultValue,
|
||||||
|
editor);
|
||||||
|
|
||||||
valueMap.put(optionName, option);
|
valueMap.put(optionName, option);
|
||||||
}
|
}
|
||||||
@ -594,8 +613,8 @@ public abstract class AbstractOptions implements Options {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyEditor getPropertyEditor(String optionName) {
|
public PropertyEditor getPropertyEditor(String optionName) {
|
||||||
if (!SwingUtilities.isEventDispatchThread()) {
|
if (!Swing.isSwingThread()) {
|
||||||
throw new IllegalStateException("This method must be called from the swing thread.");
|
throw new IllegalStateException("This method must be called from the Swing thread");
|
||||||
}
|
}
|
||||||
Option option = getOption(optionName, OptionType.NO_TYPE, null);
|
Option option = getOption(optionName, OptionType.NO_TYPE, null);
|
||||||
PropertyEditor editor = option.getPropertyEditor();
|
PropertyEditor editor = option.getPropertyEditor();
|
||||||
@ -688,8 +707,8 @@ public abstract class AbstractOptions implements Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void registerOptionsEditor(OptionsEditor editor) {
|
public synchronized void registerOptionsEditor(Supplier<OptionsEditor> editor) {
|
||||||
optionsEditorMap.put("", editor);
|
registerOptionsEditor("", editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,10 +20,13 @@ import java.awt.Font;
|
|||||||
import java.beans.PropertyEditor;
|
import java.beans.PropertyEditor;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
|
|
||||||
public interface Options {
|
public interface Options {
|
||||||
public static final char DELIMITER = '.';
|
public static final char DELIMITER = '.';
|
||||||
@ -108,11 +111,11 @@ public interface Options {
|
|||||||
/**
|
/**
|
||||||
* Registers an option with a description, help location, and a default value without specifying
|
* Registers an option with a description, help location, and a default value without specifying
|
||||||
* the option type. This form requires that the default value not be null so that the option
|
* the option type. This form requires that the default value not be null so that the option
|
||||||
* type can be inferred from the default value.
|
* type can be inferred from the default value.
|
||||||
* <P>
|
* <P>
|
||||||
* Note, this method should not be used for
|
* Note, this method should not be used for
|
||||||
* colors and font as doing so will result in those colors and fonts becoming disconnected
|
* colors and font as doing so will result in those colors and fonts becoming disconnected
|
||||||
* to the current theme. Instead use
|
* to the current theme. Instead use
|
||||||
*
|
*
|
||||||
* {@link #registerThemeColorBinding(String, String, HelpLocation, String)} or
|
* {@link #registerThemeColorBinding(String, String, HelpLocation, String)} or
|
||||||
* {@link #registerThemeFontBinding(String, String, HelpLocation, String)}.
|
* {@link #registerThemeFontBinding(String, String, HelpLocation, String)}.
|
||||||
@ -133,7 +136,7 @@ public interface Options {
|
|||||||
* <P>
|
* <P>
|
||||||
* Note, this method should not be used for
|
* Note, this method should not be used for
|
||||||
* colors and font as doing so will result in those colors and fonts becoming disconnected
|
* colors and font as doing so will result in those colors and fonts becoming disconnected
|
||||||
* to the current theme. Instead use
|
* to the current theme. Instead use
|
||||||
* {@link #registerThemeColorBinding(String, String, HelpLocation, String)} or
|
* {@link #registerThemeColorBinding(String, String, HelpLocation, String)} or
|
||||||
* {@link #registerThemeFontBinding(String, String, HelpLocation, String)}.
|
* {@link #registerThemeFontBinding(String, String, HelpLocation, String)}.
|
||||||
*
|
*
|
||||||
@ -153,9 +156,16 @@ public interface Options {
|
|||||||
* <P>
|
* <P>
|
||||||
* Note, this method should not be used for
|
* Note, this method should not be used for
|
||||||
* colors and font as doing so will result in those colors and fonts becoming disconnected
|
* colors and font as doing so will result in those colors and fonts becoming disconnected
|
||||||
* to the current theme. Instead use
|
* to the current theme. Instead use
|
||||||
* {@link #registerThemeColorBinding(String, String, HelpLocation, String)} or
|
* {@link #registerThemeColorBinding(String, String, HelpLocation, String)} or
|
||||||
* {@link #registerThemeFontBinding(String, String, HelpLocation, String)}.
|
* {@link #registerThemeFontBinding(String, String, HelpLocation, String)}.
|
||||||
|
* <P>
|
||||||
|
* Note: we use a <i>supplier</i> of a custom editor, instead of a custom editor, to avoid
|
||||||
|
* creating {@link PropertyEditor}s until needed. This allows us to use the same API in both
|
||||||
|
* GUI mode and headless mode. If GUI property editors are created in headless mode, exceptions
|
||||||
|
* may be thrown. This API will not use the supplier when in headless mode, this avoiding the
|
||||||
|
* creation of GUI components. For this to work correctly, clients using custom property
|
||||||
|
* editors must defer construction of the editor until the supplier is called.
|
||||||
*
|
*
|
||||||
* @param optionName the name of the option being registered.
|
* @param optionName the name of the option being registered.
|
||||||
* @param type the OptionType for this options.
|
* @param type the OptionType for this options.
|
||||||
@ -163,12 +173,37 @@ public interface Options {
|
|||||||
* value may be null.
|
* value may be null.
|
||||||
* @param help the HelpLocation for this option.
|
* @param help the HelpLocation for this option.
|
||||||
* @param description a description of the option.
|
* @param description a description of the option.
|
||||||
* @param editor an optional custom editor for this property. Note if the option is a custom option,
|
* @param editor an optional supplier of a custom editor for this property. Note if the option
|
||||||
* then the property editor can't be null;
|
* is a custom option, then the property editor can't be null;
|
||||||
* @throws IllegalStateException if the options is a custom option and the editor is null.
|
* @throws IllegalStateException if the options is a custom option and the editor is null.
|
||||||
*/
|
*/
|
||||||
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||||
HelpLocation help, String description, PropertyEditor editor);
|
HelpLocation help, String description, Supplier<PropertyEditor> editor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use instead
|
||||||
|
* {@link #registerOption(String, OptionType, Object, HelpLocation, String, Supplier)}
|
||||||
|
* @param optionName the name of the option being registered.
|
||||||
|
* @param type the OptionType for this options.
|
||||||
|
* @param defaultValue the defaultValue for the option. In this version of the method, the default
|
||||||
|
* value may be null.
|
||||||
|
* @param help the HelpLocation for this option.
|
||||||
|
* @param description a description of the option.
|
||||||
|
* @param editor an optional supplier of a custom editor for this property. Note if the option
|
||||||
|
* is a custom option, then the property editor can't be null;
|
||||||
|
* @deprecated Use instead
|
||||||
|
* {@link #registerOption(String, OptionType, Object, HelpLocation, String, Supplier)}
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "11.0.2", forRemoval = true)
|
||||||
|
default public void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||||
|
HelpLocation help, String description, PropertyEditor editor) {
|
||||||
|
String caller = ReflectionUtilities.getClassNameOlderThan(Options.class);
|
||||||
|
String message = """
|
||||||
|
Using deprecated call to registerOption(PropertyEditor) from % for option %s
|
||||||
|
""".formatted(caller, optionName);
|
||||||
|
Msg.debug(this, message);
|
||||||
|
registerOption(optionName, type, defaultValue, help, description, () -> editor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register/binds the option to a theme color id. Changing the option's color via the options
|
* Register/binds the option to a theme color id. Changing the option's color via the options
|
||||||
@ -185,7 +220,7 @@ public interface Options {
|
|||||||
* Register/binds the option to a theme font id. Changing the option's font via the options
|
* Register/binds the option to a theme font id. Changing the option's font via the options
|
||||||
* Gui will result in directly changing the theme color of the given font id.
|
* Gui will result in directly changing the theme color of the given font id.
|
||||||
* @param optionName the name of the font option
|
* @param optionName the name of the font option
|
||||||
* @param fontId the theme color id whose color value is changed when the option's color
|
* @param fontId the theme color id whose color value is changed when the option's color
|
||||||
* is changed
|
* is changed
|
||||||
* @param help the HelpLocation for this option
|
* @param help the HelpLocation for this option
|
||||||
* @param description a description of the option
|
* @param description a description of the option
|
||||||
@ -194,10 +229,34 @@ public interface Options {
|
|||||||
String description);
|
String description);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the options editor that will handle the editing for all the options or a sub group of options.
|
* Register the options editor that will handle the editing for all the options or a sub-group
|
||||||
* @param editor the custom editor panel to be used to edit the options or sub group of options.
|
* of options.
|
||||||
|
* <P>
|
||||||
|
* Note: we use a <i>supplier</i> of a custom editor, instead of a custom editor, to avoid
|
||||||
|
* creating {@link PropertyEditor}s until needed. This allows us to use the same API in both
|
||||||
|
* GUI mode and headless mode. If GUI property editors are created in headless mode, exceptions
|
||||||
|
* may be thrown. This API will not use the supplier when in headless mode, this avoiding the
|
||||||
|
* creation of GUI components. For this to work correctly, clients using custom property
|
||||||
|
* editors must defer construction of the editor until the supplier is called.
|
||||||
|
* @param editor a supplier for the custom editor panel to be used to edit the options or
|
||||||
|
* sub-group of options.
|
||||||
*/
|
*/
|
||||||
public void registerOptionsEditor(OptionsEditor editor);
|
public void registerOptionsEditor(Supplier<OptionsEditor> editor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use instead {@link #registerOptionsEditor(Supplier)}
|
||||||
|
* @param editor the editor
|
||||||
|
* @deprecated Use instead {@link #registerOptionsEditor(Supplier)}
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "11.0.2", forRemoval = true)
|
||||||
|
default public void registerOptionsEditor(OptionsEditor editor) {
|
||||||
|
String caller = ReflectionUtilities.getClassNameOlderThan(Options.class);
|
||||||
|
String message = """
|
||||||
|
Using deprecated call to registerOption(OptionsEditor) from % for options %s
|
||||||
|
""".formatted(caller, getName());
|
||||||
|
Msg.debug(this, message);
|
||||||
|
registerOptionsEditor(() -> editor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the editor that will handle editing all the values in this options or sub group of options.
|
* Get the editor that will handle editing all the values in this options or sub group of options.
|
||||||
|
@ -20,6 +20,7 @@ import java.awt.Font;
|
|||||||
import java.beans.PropertyEditor;
|
import java.beans.PropertyEditor;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ public class SubOptions implements Options {
|
|||||||
public List<Options> getChildOptions() {
|
public List<Options> getChildOptions() {
|
||||||
List<String> optionPaths = getOptionNames();
|
List<String> optionPaths = getOptionNames();
|
||||||
Set<String> childCategories = AbstractOptions.getChildCategories(optionPaths);
|
Set<String> childCategories = AbstractOptions.getChildCategories(optionPaths);
|
||||||
List<Options> childOptions = new ArrayList<Options>(childCategories.size());
|
List<Options> childOptions = new ArrayList<>(childCategories.size());
|
||||||
for (String categoryName : childCategories) {
|
for (String categoryName : childCategories) {
|
||||||
childOptions.add(new SubOptions(options, categoryName, prefix + categoryName +
|
childOptions.add(new SubOptions(options, categoryName, prefix + categoryName +
|
||||||
DELIMITER));
|
DELIMITER));
|
||||||
@ -88,7 +89,7 @@ public class SubOptions implements Options {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||||
HelpLocation help, String description, PropertyEditor editor) {
|
HelpLocation help, String description, Supplier<PropertyEditor> editor) {
|
||||||
options.registerOption(prefix + optionName, type, defaultValue, help, description, editor);
|
options.registerOption(prefix + optionName, type, defaultValue, help, description, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +253,7 @@ public class SubOptions implements Options {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getOptionNames() {
|
public List<String> getOptionNames() {
|
||||||
List<String> allOptionPaths = options.getOptionNames();
|
List<String> allOptionPaths = options.getOptionNames();
|
||||||
List<String> names = new ArrayList<String>();
|
List<String> names = new ArrayList<>();
|
||||||
for (String path : allOptionPaths) {
|
for (String path : allOptionPaths) {
|
||||||
if (path.startsWith(prefix)) {
|
if (path.startsWith(prefix)) {
|
||||||
names.add(path.substring(prefix.length()));
|
names.add(path.substring(prefix.length()));
|
||||||
@ -317,7 +318,7 @@ public class SubOptions implements Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerOptionsEditor(OptionsEditor editor) {
|
public void registerOptionsEditor(Supplier<OptionsEditor> editor) {
|
||||||
options.registerOptionsEditor(prefix, editor);
|
options.registerOptionsEditor(prefix, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +379,7 @@ public class SubOptions implements Options {
|
|||||||
public List<String> getLeafOptionNames() {
|
public List<String> getLeafOptionNames() {
|
||||||
List<String> optionPaths = getOptionNames();
|
List<String> optionPaths = getOptionNames();
|
||||||
Set<String> leaves = AbstractOptions.getLeaves(optionPaths);
|
Set<String> leaves = AbstractOptions.getLeaves(optionPaths);
|
||||||
return new ArrayList<String>(leaves);
|
return new ArrayList<>(leaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -238,7 +238,7 @@ public class OptionsManager implements OptionsService, OptionsChangeListener {
|
|||||||
oldEditor.dispose();
|
oldEditor.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
keyBindingOptions.registerOptionsEditor(new KeyBindingOptionsEditor());
|
keyBindingOptions.registerOptionsEditor(() -> new KeyBindingOptionsEditor());
|
||||||
OptionsDialog dialog =
|
OptionsDialog dialog =
|
||||||
new OptionsDialog("Options for " + tool.getName(), "Options", getEditableOptions(),
|
new OptionsDialog("Options for " + tool.getName(), "Options", getEditableOptions(),
|
||||||
null, true);
|
null, true);
|
||||||
|
@ -363,7 +363,7 @@ public class ProgramCompilerSpec extends BasicCompilerSpec {
|
|||||||
OptionType.STRING_TYPE, evalChoices[0],
|
OptionType.STRING_TYPE, evalChoices[0],
|
||||||
new HelpLocation("DecompilePlugin", "OptionProtoEval"),
|
new HelpLocation("DecompilePlugin", "OptionProtoEval"),
|
||||||
"Select the default function prototype/evaluation model to be used during Decompiler analysis",
|
"Select the default function prototype/evaluation model to be used during Decompiler analysis",
|
||||||
new StringWithChoicesEditor(evalChoices));
|
() -> new StringWithChoicesEditor(evalChoices));
|
||||||
|
|
||||||
// TODO: registration of DECOMPILER_OUTPUT_LANGUAGE option should be tied to Processor
|
// TODO: registration of DECOMPILER_OUTPUT_LANGUAGE option should be tied to Processor
|
||||||
// and not presence of stored option.
|
// and not presence of stored option.
|
||||||
|
@ -36,7 +36,7 @@ import ghidra.xml.*;
|
|||||||
* Utility class for installing/removing "specification extensions" to a Program.
|
* Utility class for installing/removing "specification extensions" to a Program.
|
||||||
* A specification extension is a program specific version of either a:
|
* A specification extension is a program specific version of either a:
|
||||||
* - Prototype Model
|
* - Prototype Model
|
||||||
* - Call Fixup or
|
* - Call Fixup or
|
||||||
* - Callother Fixup
|
* - Callother Fixup
|
||||||
* Normally these objects are provided by the language specific configuration files (.cspec or .pspec),
|
* Normally these objects are provided by the language specific configuration files (.cspec or .pspec),
|
||||||
* but this class allows additional objects to be added that are specific to the program.
|
* but this class allows additional objects to be added that are specific to the program.
|
||||||
@ -48,7 +48,7 @@ import ghidra.xml.*;
|
|||||||
* - \<callotherfixup> - describing a Callother Fixup
|
* - \<callotherfixup> - describing a Callother Fixup
|
||||||
* - \<prototype> - describing a typical Prototype Model
|
* - \<prototype> - describing a typical Prototype Model
|
||||||
* - \<resolveprototype> - describing a Prototype Model merged from other models
|
* - \<resolveprototype> - describing a Prototype Model merged from other models
|
||||||
*
|
*
|
||||||
* Each type of object has a unique name or target, which must be specified as part of the XML tag,
|
* Each type of object has a unique name or target, which must be specified as part of the XML tag,
|
||||||
* which is referred to in this class as the extension's "formal name". In the \<callotherfixup> tag,
|
* which is referred to in this class as the extension's "formal name". In the \<callotherfixup> tag,
|
||||||
* the formal name is given by the "targetop" attribute; for all the other tags, the formal name is
|
* the formal name is given by the "targetop" attribute; for all the other tags, the formal name is
|
||||||
@ -332,7 +332,7 @@ public class SpecExtension {
|
|||||||
if (!SystemUtilities.isInHeadlessMode()) {
|
if (!SystemUtilities.isInHeadlessMode()) {
|
||||||
Options options = program.getOptions(SPEC_EXTENSION);
|
Options options = program.getOptions(SPEC_EXTENSION);
|
||||||
options.setOptionsHelpLocation(new HelpLocation("DecompilePlugin", "ExtensionOptions"));
|
options.setOptionsHelpLocation(new HelpLocation("DecompilePlugin", "ExtensionOptions"));
|
||||||
options.registerOptionsEditor(new SpecExtensionEditor((ProgramDB) program));
|
options.registerOptionsEditor(() -> new SpecExtensionEditor((ProgramDB) program));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user