mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GT-3179 - Help - addressed missing help for tool options; fixed bug that
caused help find dialog to be stuck behind Tool Options dialog; fixed bug that caused the Help Find Dialog keybinding to trigger an exception
This commit is contained in:
parent
ea953ce924
commit
66198876e5
28 changed files with 296 additions and 151 deletions
|
@ -16,6 +16,7 @@
|
||||||
<P>Often, users need to navigate to specific locations in a program. Ghidra provides
|
<P>Often, users need to navigate to specific locations in a program. Ghidra provides
|
||||||
several different ways to do this: </P>
|
several different ways to do this: </P>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
<UL>
|
<UL>
|
||||||
<LI> Enter a particular address or label (<A href="#Go_To_Address_Label">Go
|
<LI> Enter a particular address or label (<A href="#Go_To_Address_Label">Go
|
||||||
To</A>)</LI>
|
To</A>)</LI>
|
||||||
|
@ -29,11 +30,12 @@
|
||||||
<LI> Use the <A href="#Navigation_History">Navigation History</A> to return to a
|
<LI> Use the <A href="#Navigation_History">Navigation History</A> to return to a
|
||||||
previously visited location</LI>
|
previously visited location</LI>
|
||||||
</UL>
|
</UL>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H2><A name="Go_To_Address_Label"></A>Go To Address, Label, or Expression</H2>
|
<H2><A name="Go_To_Address_Label"></A>Go To Address, Label, or Expression</H2>
|
||||||
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<H3>To perform a Go To: </H3>
|
<H3>To Perform a Go To: </H3>
|
||||||
|
|
||||||
<OL>
|
<OL>
|
||||||
<LI>In the menu-bar of a tool, select <B>Navigation <IMG src="../../shared/arrow.gif"
|
<LI>In the menu-bar of a tool, select <B>Navigation <IMG src="../../shared/arrow.gif"
|
||||||
|
@ -228,25 +230,40 @@
|
||||||
expresion evaluation.<BR>
|
expresion evaluation.<BR>
|
||||||
For example:<BR>
|
For example:<BR>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<TABLE BORDER="1">
|
||||||
|
<TR>
|
||||||
|
<TD WIDTH="35%">
|
||||||
|
<B>ENTRY+10</B>
|
||||||
|
</TD>
|
||||||
|
<TD>Positions
|
||||||
|
the cursor at the address 0x10 addresses past the symbol ENTRY
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
<TR>
|
||||||
|
<TD><B>0x100000+30</B>
|
||||||
|
</TD>
|
||||||
|
<TD>Positions the cursor at address 0x100030
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
<TR>
|
||||||
|
<TD><B>0x100000+(2*10)</B>
|
||||||
|
</TD>
|
||||||
|
<TD>Posiitons the cursor at address 0x100020
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
<TR>
|
||||||
|
<TD><B>+20</B>
|
||||||
|
</TD>
|
||||||
|
<TD>Positions the cursor at an address that is 0x20 past the current location
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
</TABLE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<DIV style="margin-left: 4em">
|
|
||||||
<UL>
|
|
||||||
<LI>ENTRY+10 Positions
|
|
||||||
the cursor at the address 0x10 addresses past the symbol ENTRY.</LI>
|
|
||||||
|
|
||||||
<LI>0x100000+30 Positions the cursor
|
|
||||||
at address 0x100030.</LI>
|
|
||||||
|
|
||||||
<LI>0x100000+(2*10) Posiitons the cursor at address 0x100020.</LI>
|
|
||||||
|
|
||||||
<LI>
|
|
||||||
+20
|
|
||||||
Positions the cursor at an address that is 0x20 past the current location.<BR>
|
|
||||||
</LI>
|
|
||||||
</UL>
|
|
||||||
</DIV>
|
|
||||||
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<H3>Executing a Query</H3>
|
<H3>Executing a Query</H3>
|
||||||
|
@ -626,6 +643,79 @@
|
||||||
<BR>
|
<BR>
|
||||||
|
|
||||||
|
|
||||||
|
<HR WIDTH="80%">
|
||||||
|
|
||||||
|
<H2><A NAME="Navigation_Options"></A>Navigation Options</H2>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<B>'Go To' in Current Program Only</B> -
|
||||||
|
'Go To' service will only search for and navigate to labels in the current program.
|
||||||
|
If this option is off and the search label is not found in the current program, the
|
||||||
|
'Go To' action will search other open programs,
|
||||||
|
possibly resulting in the listing view switching to a different open program tab.
|
||||||
|
By default, this option is on, thereby guaranteeing that the listing view will not
|
||||||
|
change to a different program when performing a <A HREF="#Go_To_Address_Label">
|
||||||
|
'Go To' action</A>.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<B>External Navigation</B> -
|
||||||
|
Determines the behavior for navigation to external symbols and references.
|
||||||
|
By default, navigating to an external will attempt to navigate within the
|
||||||
|
current program to the first linkage reference (pointer or thunk).
|
||||||
|
Alternatively, if an external program has been associated with an
|
||||||
|
import Library, then that program will be opened and positioned to the selected
|
||||||
|
external location if found.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<B>Follow Indirection</B> -
|
||||||
|
Determines the behavior for navigation on indirect flow references.
|
||||||
|
By default, this option is disabled providing navigation to the
|
||||||
|
referenced pointer data. If enabled, the pointer will be followed
|
||||||
|
to its referenced destination if contained within the program's memory.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<B>Prefer Current Address Space</B> -
|
||||||
|
Determines if the 'Go To' action prefers the current address space when entering address offsets.
|
||||||
|
For example, if your program has multiple address spaces such as 'RAM' or 'DATA' and you
|
||||||
|
enter 1000 into the 'Go To' field, you could mean RAM:1000 or DATA:1000. If this option
|
||||||
|
is on, then it will go to the address with the address space that matches the current
|
||||||
|
cursor location. Otherwise, it will show a list of possible addresses for the given offset.
|
||||||
|
The default is on for this option.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<B>Range Navigation</B> -
|
||||||
|
Determines how <A HREF="help/topics/Selection/Selecting.htm#NavigateOverSelection">
|
||||||
|
navigation of ranges</A>
|
||||||
|
(i.e., selection ranges and highlight ranges) takes place. By default, navigating
|
||||||
|
to ranges will place the cursor at the top of the
|
||||||
|
next range. You may use this option to navigate to both the top and the bottom of each
|
||||||
|
range being navigated.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is different than most, since it has multiple plugins contributing to the
|
||||||
|
content. Add some space at the bottom of the file to separate this contribution.
|
||||||
|
-->
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
|
|
||||||
<P class="relatedtopic">Related Topics:</P>
|
<P class="relatedtopic">Related Topics:</P>
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,10 @@
|
||||||
types of selections that are available from the tool <B>Select</B> menu. Each predefined type
|
types of selections that are available from the tool <B>Select</B> menu. Each predefined type
|
||||||
of selection exposes different characteristics of the program.</P>
|
of selection exposes different characteristics of the program.</P>
|
||||||
|
|
||||||
<P>To create a selection using one of the predefined methods:</P>
|
<P>To create a selection using one of the predefined methods via the menu item
|
||||||
|
<B>Select</B><I><B><IMG src=
|
||||||
<UL type="disc">
|
"../../shared/arrow.gif">SelectionType</B>.</I>
|
||||||
<LI>From the Code Browser, select the menu option <B>Select</B><I><B><IMG src=
|
</P>
|
||||||
"../../shared/arrow.gif">SelectionType</B>.</I></LI>
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<P>The <I><B>SelectionTypes</B></I> and their descriptions are as follows:</P>
|
<P>The <I><B>SelectionTypes</B></I> and their descriptions are as follows:</P>
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class CodeBrowserPlugin extends Plugin
|
||||||
GhidraOptions.CATEGORY_BROWSER_POPUPS);
|
GhidraOptions.CATEGORY_BROWSER_POPUPS);
|
||||||
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(this, 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(
|
||||||
|
|
|
@ -267,12 +267,12 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
return address.compareTo(screenBottom) > 0;
|
return address.compareTo(screenBottom) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The y value of the start of the layout at the given address. */
|
/* The y value of the start of the layout at the given address. */
|
||||||
Integer getStartPos(Address addr) {
|
Integer getStartPos(Address addr) {
|
||||||
return startAddressToPixel.get(addr);
|
return startAddressToPixel.get(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The y value of the end of the layout at the given address. */
|
/* The y value of the end of the layout at the given address. */
|
||||||
Integer getEndPos(Address addr) {
|
Integer getEndPos(Address addr) {
|
||||||
return endAddressToPixel.get(addr);
|
return endAddressToPixel.get(addr);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
return flowArrows.iterator();
|
return flowArrows.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Those arrows starting at the current address */
|
/* Those arrows starting at the current address */
|
||||||
Iterator<FlowArrow> getActiveArrows() {
|
Iterator<FlowArrow> getActiveArrows() {
|
||||||
return activeArrows.iterator();
|
return activeArrows.iterator();
|
||||||
}
|
}
|
||||||
|
@ -584,8 +584,8 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
for (int layout = 0; layout < n; layout++) {
|
for (int layout = 0; layout < n; layout++) {
|
||||||
Address addr = layoutToPixel.getLayoutAddress(layout);
|
Address addr = layoutToPixel.getLayoutAddress(layout);
|
||||||
if (addr != null) {
|
if (addr != null) {
|
||||||
startAddressToPixel.put(addr, new Integer(layoutToPixel.getBeginPosition(layout)));
|
startAddressToPixel.put(addr, layoutToPixel.getBeginPosition(layout));
|
||||||
endAddressToPixel.put(addr, new Integer(layoutToPixel.getEndPosition(layout)));
|
endAddressToPixel.put(addr, layoutToPixel.getEndPosition(layout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,11 +640,14 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
ToolOptions opt = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
|
ToolOptions opt = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_DISPLAY);
|
||||||
|
|
||||||
opt.registerOption(OptionsGui.FLOW_ARROW_NON_ACTIVE.getColorOptionName(),
|
opt.registerOption(OptionsGui.FLOW_ARROW_NON_ACTIVE.getColorOptionName(),
|
||||||
OptionsGui.FLOW_ARROW_NON_ACTIVE.getDefaultColor(), null, null);
|
OptionsGui.FLOW_ARROW_NON_ACTIVE.getDefaultColor(), null,
|
||||||
|
"The color for an arrow with no endpoint at the current address");
|
||||||
opt.registerOption(OptionsGui.FLOW_ARROW_ACTIVE.getColorOptionName(),
|
opt.registerOption(OptionsGui.FLOW_ARROW_ACTIVE.getColorOptionName(),
|
||||||
OptionsGui.FLOW_ARROW_ACTIVE.getDefaultColor(), null, null);
|
OptionsGui.FLOW_ARROW_ACTIVE.getDefaultColor(), null,
|
||||||
|
"The color for an arrow with an endpoint at the current address");
|
||||||
opt.registerOption(OptionsGui.FLOW_ARROW_SELECTED.getColorOptionName(),
|
opt.registerOption(OptionsGui.FLOW_ARROW_SELECTED.getColorOptionName(),
|
||||||
OptionsGui.FLOW_ARROW_SELECTED.getDefaultColor(), null, null);
|
OptionsGui.FLOW_ARROW_SELECTED.getDefaultColor(), null,
|
||||||
|
"The color for an arrow that has been selected by the user");
|
||||||
|
|
||||||
Color c = opt.getColor(OptionsGui.BACKGROUND.getColorOptionName(),
|
Color c = opt.getColor(OptionsGui.BACKGROUND.getColorOptionName(),
|
||||||
OptionsGui.BACKGROUND.getDefaultColor());
|
OptionsGui.BACKGROUND.getDefaultColor());
|
||||||
|
|
|
@ -20,9 +20,12 @@ 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;
|
||||||
import ghidra.framework.plugintool.util.OptionsService;
|
import ghidra.framework.plugintool.util.OptionsService;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
public class NavigationOptions implements OptionsChangeListener {
|
public class NavigationOptions implements OptionsChangeListener {
|
||||||
|
|
||||||
|
static final String NAVIGATION_TOPIC = "Navigation";
|
||||||
|
|
||||||
static final String NAVIGATION_OPTIONS = GhidraOptions.NAVIGATION_OPTIONS;
|
static final String NAVIGATION_OPTIONS = GhidraOptions.NAVIGATION_OPTIONS;
|
||||||
|
|
||||||
static final String NAVIGATION_RANGE_OPTION = GhidraOptions.NAVIGATION_RANGE_OPTION;
|
static final String NAVIGATION_RANGE_OPTION = GhidraOptions.NAVIGATION_RANGE_OPTION;
|
||||||
|
@ -51,7 +54,7 @@ public class NavigationOptions implements OptionsChangeListener {
|
||||||
static final String EXTERNAL_NAVIGATION_OPTION = GhidraOptions.EXTERNAL_NAVIGATION_OPTION;
|
static final String EXTERNAL_NAVIGATION_OPTION = GhidraOptions.EXTERNAL_NAVIGATION_OPTION;
|
||||||
|
|
||||||
static final String EXTERNAL_NAVIGATION_DESCRIPTION =
|
static final String EXTERNAL_NAVIGATION_DESCRIPTION =
|
||||||
"Determines the bahavior for navigation to external symbols and references. " +
|
"Determines the behavior for navigation to external symbols and references. " +
|
||||||
"By default, navigating to an external will attempt to navigate within the " +
|
"By default, navigating to an external will attempt to navigate within the " +
|
||||||
"current program to the first linkage reference (pointer or thunk). " +
|
"current program to the first linkage reference (pointer or thunk). " +
|
||||||
"Alternatively, if an external program has been associated with an " +
|
"Alternatively, if an external program has been associated with an " +
|
||||||
|
@ -78,12 +81,12 @@ public class NavigationOptions implements OptionsChangeListener {
|
||||||
GhidraOptions.FOLLOW_INDIRECTION_NAVIGATION_OPTION;
|
GhidraOptions.FOLLOW_INDIRECTION_NAVIGATION_OPTION;
|
||||||
|
|
||||||
static final String FOLLOW_INDIRECTION_NAVIGATION_DESCRIPTION =
|
static final String FOLLOW_INDIRECTION_NAVIGATION_DESCRIPTION =
|
||||||
"Determines the bahavior for navigation on indirect flow references. " +
|
"Determines the behavior for navigation on indirect flow references. " +
|
||||||
"By default, this option is disabled providing navigation to the " +
|
"By default, this option is disabled providing navigation to the " +
|
||||||
"referenced pointer data. If enabled, the pointer will be followed " +
|
"referenced pointer data. If enabled, the pointer will be followed " +
|
||||||
"to its referenced destination if contained within the program's memory.";
|
"to its referenced destination if contained within the program's memory.";
|
||||||
|
|
||||||
static final String ASSUME_CURRENT_ADDRESS_SPACE = "Prefer current Address Space";
|
static final String ASSUME_CURRENT_ADDRESS_SPACE = "Prefer Current Address Space";
|
||||||
private static final String ASSUME_CURRENT_ADDRESS_SPACE_DESCRIPTION =
|
private static final String ASSUME_CURRENT_ADDRESS_SPACE_DESCRIPTION =
|
||||||
"Determines if the 'Go To' action prefers the current address space when entering address offsets. " +
|
"Determines if the 'Go To' action prefers the current address space when entering address offsets. " +
|
||||||
"For example, if your program has multiple address spaces such as 'RAM' or 'DATA' and you " +
|
"For example, if your program has multiple address spaces such as 'RAM' or 'DATA' and you " +
|
||||||
|
@ -92,7 +95,7 @@ public class NavigationOptions implements OptionsChangeListener {
|
||||||
"cursor location. Otherwise, it will show a list of possible addresses for the given offset. " +
|
"cursor location. Otherwise, it will show a list of possible addresses for the given offset. " +
|
||||||
"The default is on for this option.";
|
"The default is on for this option.";
|
||||||
|
|
||||||
private final String RESTRICT_GOTO_CURRENT_TAB = "'Go To' in current program only";
|
private final String RESTRICT_GOTO_CURRENT_TAB = "'Go To' in Current Program Only";
|
||||||
private static final String RESTRICT_GOTO_CURRENT_TAB_DESCRIPTION = "Determines if the " +
|
private static final String RESTRICT_GOTO_CURRENT_TAB_DESCRIPTION = "Determines if the " +
|
||||||
"'Go To' service will only search for and navigate to labels in the current program. " +
|
"'Go To' service will only search for and navigate to labels in the current program. " +
|
||||||
"If this option is off and the search label is not found in the current program, the " +
|
"If this option is off and the search label is not found in the current program, the " +
|
||||||
|
@ -120,32 +123,33 @@ public class NavigationOptions implements OptionsChangeListener {
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
|
HelpLocation help = new HelpLocation(NAVIGATION_TOPIC, "Navigation_Options");
|
||||||
options.registerOption(NavigationOptions.NAVIGATION_RANGE_OPTION,
|
options.registerOption(NavigationOptions.NAVIGATION_RANGE_OPTION,
|
||||||
RangeNavigationEnum.TopOfRangeOnly, null,
|
RangeNavigationEnum.TopOfRangeOnly, help,
|
||||||
NavigationOptions.NAVIGATION_RANGE_DESCRIPTION);
|
NavigationOptions.NAVIGATION_RANGE_DESCRIPTION);
|
||||||
RangeNavigationEnum rangeNavigationOption = options.getEnum(
|
RangeNavigationEnum rangeNavigationOption = options.getEnum(
|
||||||
NavigationOptions.NAVIGATION_RANGE_OPTION, RangeNavigationEnum.TopOfRangeOnly);
|
NavigationOptions.NAVIGATION_RANGE_OPTION, RangeNavigationEnum.TopOfRangeOnly);
|
||||||
gotoTopAndBottom = (rangeNavigationOption == RangeNavigationEnum.TopAndBottomOfRange);
|
gotoTopAndBottom = (rangeNavigationOption == RangeNavigationEnum.TopAndBottomOfRange);
|
||||||
|
|
||||||
options.registerOption(NavigationOptions.EXTERNAL_NAVIGATION_OPTION,
|
options.registerOption(NavigationOptions.EXTERNAL_NAVIGATION_OPTION,
|
||||||
ExternalNavigationEnum.NavigateToLinkage, null,
|
ExternalNavigationEnum.NavigateToLinkage, help,
|
||||||
NavigationOptions.EXTERNAL_NAVIGATION_DESCRIPTION);
|
NavigationOptions.EXTERNAL_NAVIGATION_DESCRIPTION);
|
||||||
ExternalNavigationEnum externalNavigationOption = options.getEnum(
|
ExternalNavigationEnum externalNavigationOption = options.getEnum(
|
||||||
NavigationOptions.EXTERNAL_NAVIGATION_OPTION, ExternalNavigationEnum.NavigateToLinkage);
|
NavigationOptions.EXTERNAL_NAVIGATION_OPTION, ExternalNavigationEnum.NavigateToLinkage);
|
||||||
gotoExternalProgram =
|
gotoExternalProgram =
|
||||||
(externalNavigationOption == ExternalNavigationEnum.NavigateToExternalProgram);
|
(externalNavigationOption == ExternalNavigationEnum.NavigateToExternalProgram);
|
||||||
|
|
||||||
options.registerOption(NavigationOptions.FOLLOW_INDIRECTION_NAVIGATION_OPTION, false, null,
|
options.registerOption(NavigationOptions.FOLLOW_INDIRECTION_NAVIGATION_OPTION, false, help,
|
||||||
NavigationOptions.FOLLOW_INDIRECTION_NAVIGATION_DESCRIPTION);
|
NavigationOptions.FOLLOW_INDIRECTION_NAVIGATION_DESCRIPTION);
|
||||||
followIndirectReferences =
|
followIndirectReferences =
|
||||||
options.getBoolean(NavigationOptions.FOLLOW_INDIRECTION_NAVIGATION_OPTION, false);
|
options.getBoolean(NavigationOptions.FOLLOW_INDIRECTION_NAVIGATION_OPTION, false);
|
||||||
|
|
||||||
options.registerOption(ASSUME_CURRENT_ADDRESS_SPACE, true, null,
|
options.registerOption(ASSUME_CURRENT_ADDRESS_SPACE, true, help,
|
||||||
ASSUME_CURRENT_ADDRESS_SPACE_DESCRIPTION);
|
ASSUME_CURRENT_ADDRESS_SPACE_DESCRIPTION);
|
||||||
|
|
||||||
preferCurrentAddressSpace = options.getBoolean(ASSUME_CURRENT_ADDRESS_SPACE, true);
|
preferCurrentAddressSpace = options.getBoolean(ASSUME_CURRENT_ADDRESS_SPACE, true);
|
||||||
|
|
||||||
options.registerOption(RESTRICT_GOTO_CURRENT_TAB, true, null,
|
options.registerOption(RESTRICT_GOTO_CURRENT_TAB, true, help,
|
||||||
RESTRICT_GOTO_CURRENT_TAB_DESCRIPTION);
|
RESTRICT_GOTO_CURRENT_TAB_DESCRIPTION);
|
||||||
|
|
||||||
restrictGotoToCurrentProgram = options.getBoolean(RESTRICT_GOTO_CURRENT_TAB, true);
|
restrictGotoToCurrentProgram = options.getBoolean(RESTRICT_GOTO_CURRENT_TAB, true);
|
||||||
|
@ -158,7 +162,7 @@ public class NavigationOptions implements OptionsChangeListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
|
public void optionsChanged(ToolOptions toolOptions, String optionName, Object oldValue,
|
||||||
Object newValue) {
|
Object newValue) {
|
||||||
if (NavigationOptions.NAVIGATION_RANGE_OPTION.equals(optionName)) {
|
if (NavigationOptions.NAVIGATION_RANGE_OPTION.equals(optionName)) {
|
||||||
RangeNavigationEnum rangeNavigationOption = (RangeNavigationEnum) newValue;
|
RangeNavigationEnum rangeNavigationOption = (RangeNavigationEnum) newValue;
|
||||||
|
|
|
@ -401,9 +401,10 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
|
||||||
"Toggles highlight search results");
|
"Toggles highlight search results");
|
||||||
|
|
||||||
opt.registerOption(PluginConstants.SEARCH_HIGHLIGHT_COLOR_NAME,
|
opt.registerOption(PluginConstants.SEARCH_HIGHLIGHT_COLOR_NAME,
|
||||||
PluginConstants.SEARCH_HIGHLIGHT_COLOR, null, null);
|
PluginConstants.SEARCH_HIGHLIGHT_COLOR, null, "The search result highlight color");
|
||||||
opt.registerOption(PluginConstants.SEARCH_HIGHLIGHT_CURRENT_COLOR_NAME,
|
opt.registerOption(PluginConstants.SEARCH_HIGHLIGHT_CURRENT_COLOR_NAME,
|
||||||
PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR, null, null);
|
PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR, null,
|
||||||
|
"The search result highlight color for the currently selected match");
|
||||||
|
|
||||||
opt.addOptionsChangeListener(this);
|
opt.addOptionsChangeListener(this);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class AddressFieldFactory extends FieldFactory {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param model the model that the field belongs to.
|
* @param model the model that the field belongs to.
|
||||||
* @param hsProvider the HightLightStringProvider.
|
* @param hlProvider the HightLightStringProvider.
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
|
@ -75,7 +75,8 @@ public class AddressFieldFactory extends FieldFactory {
|
||||||
HelpLocation helpLoc = new HelpLocation("CodeBrowserPlugin", "Address_Field");
|
HelpLocation helpLoc = new HelpLocation("CodeBrowserPlugin", "Address_Field");
|
||||||
|
|
||||||
fieldOptions.registerOption(ADDRESS_DISPLAY_OPTIONS_NAME, OptionType.CUSTOM_TYPE,
|
fieldOptions.registerOption(ADDRESS_DISPLAY_OPTIONS_NAME, OptionType.CUSTOM_TYPE,
|
||||||
new AddressFieldOptionsWrappedOption(), helpLoc, null, addressFieldOptionsEditor);
|
new AddressFieldOptionsWrappedOption(), helpLoc, "Adjusts the Address Field display",
|
||||||
|
addressFieldOptionsEditor);
|
||||||
|
|
||||||
CustomOption customOption =
|
CustomOption customOption =
|
||||||
fieldOptions.getCustomOption(ADDRESS_DISPLAY_OPTIONS_NAME, null);
|
fieldOptions.getCustomOption(ADDRESS_DISPLAY_OPTIONS_NAME, null);
|
||||||
|
@ -204,9 +205,9 @@ public class AddressFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel newModel,
|
public FieldFactory newInstance(FieldFormatModel newModel,
|
||||||
HighlightProvider highlightStringProvider, ToolOptions displayOptions,
|
HighlightProvider highlightStringProvider, ToolOptions toolOptions,
|
||||||
ToolOptions fieldOptions) {
|
ToolOptions fieldOptions) {
|
||||||
return new AddressFieldFactory(newModel, highlightStringProvider, displayOptions,
|
return new AddressFieldFactory(newModel, highlightStringProvider, toolOptions,
|
||||||
fieldOptions);
|
fieldOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,16 +43,16 @@ public class ArrayValuesFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel formatModel,
|
public FieldFactory newInstance(FieldFormatModel formatModel,
|
||||||
HighlightProvider highlightProvider, ToolOptions displayOptions,
|
HighlightProvider highlightProvider, ToolOptions toolOptions,
|
||||||
ToolOptions fieldOptions) {
|
ToolOptions fieldOptions) {
|
||||||
return new ArrayValuesFieldFactory(formatModel, highlightProvider, displayOptions,
|
return new ArrayValuesFieldFactory(formatModel, highlightProvider, toolOptions,
|
||||||
fieldOptions);
|
fieldOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param model the model that the field belongs to.
|
* @param model the model that the field belongs to.
|
||||||
* @param hsProvider the HightLightStringProvider.
|
* @param hlProvider the HightLightStringProvider.
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +65,8 @@ public class ArrayValuesFieldFactory extends FieldFactory {
|
||||||
private void setupOptions(Options fieldOptions) {
|
private void setupOptions(Options fieldOptions) {
|
||||||
// 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, null, arrayOptionsEditor);
|
new ArrayElementWrappedOption(), null, FormatManager.ARRAY_DISPLAY_DESCRIPTION,
|
||||||
|
arrayOptionsEditor);
|
||||||
CustomOption wrappedOption = fieldOptions.getCustomOption(
|
CustomOption wrappedOption = fieldOptions.getCustomOption(
|
||||||
FormatManager.ARRAY_DISPLAY_OPTIONS, new ArrayElementWrappedOption());
|
FormatManager.ARRAY_DISPLAY_OPTIONS, new ArrayElementWrappedOption());
|
||||||
|
|
||||||
|
@ -162,9 +163,6 @@ public class ArrayValuesFieldFactory extends FieldFactory {
|
||||||
return (category == FieldFormatModel.ARRAY);
|
return (category == FieldFormatModel.ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.viewer.field.FieldFactory#fieldOptionsChanged(ghidra.framework.options.ToolOptions, java.lang.String, java.lang.Object, java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldOptionsChanged(Options options, String optionName, Object oldValue,
|
public void fieldOptionsChanged(Options options, String optionName, Object oldValue,
|
||||||
Object newValue) {
|
Object newValue) {
|
||||||
|
|
|
@ -76,6 +76,8 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
||||||
*/
|
*/
|
||||||
private final static String NAMESPACE_OPTIONS =
|
private final static String NAMESPACE_OPTIONS =
|
||||||
GhidraOptions.OPERAND_GROUP_TITLE + Options.DELIMITER + "Display Namespace";
|
GhidraOptions.OPERAND_GROUP_TITLE + Options.DELIMITER + "Display Namespace";
|
||||||
|
private static final String NAMESPACE_OPTIONS_DESCRIPTIONS =
|
||||||
|
"Adjusts the Operands Field namespace display";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option which controls the display of data mutability in the mnemonic representation
|
* Option which controls the display of data mutability in the mnemonic representation
|
||||||
|
@ -106,7 +108,8 @@ 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, null, new NamespacePropertyEditor());
|
new NamespaceWrappedOption(), null, NAMESPACE_OPTIONS_DESCRIPTIONS,
|
||||||
|
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);
|
||||||
|
@ -157,7 +160,8 @@ 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, null, new NamespacePropertyEditor());
|
new NamespaceWrappedOption(), null, NAMESPACE_OPTIONS_DESCRIPTIONS,
|
||||||
|
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)) {
|
||||||
|
@ -208,7 +212,7 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
||||||
/**
|
/**
|
||||||
* Add format change listener.
|
* Add format change listener.
|
||||||
* Listeners will only be notified if autoUpdate was true when instantiated.
|
* Listeners will only be notified if autoUpdate was true when instantiated.
|
||||||
* @param listener
|
* @param listener the listener
|
||||||
*/
|
*/
|
||||||
public void addChangeListener(ChangeListener listener) {
|
public void addChangeListener(ChangeListener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
|
@ -216,7 +220,7 @@ public class BrowserCodeUnitFormatOptions extends CodeUnitFormatOptions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove format change listener
|
* Remove format change listener
|
||||||
* @param listener
|
* @param listener the listener
|
||||||
*/
|
*/
|
||||||
public void removeChangeListener(ChangeListener listener) {
|
public void removeChangeListener(ChangeListener listener) {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
|
|
|
@ -89,8 +89,9 @@ public abstract class FieldFactory implements ExtensionPoint {
|
||||||
// For most fields (defined in optionsGui) these will be set. But "ad hoc" fields won't,
|
// For most fields (defined in optionsGui) these will be set. But "ad hoc" fields won't,
|
||||||
// so register something. A second registration won't change the original
|
// so register something. A second registration won't change the original
|
||||||
|
|
||||||
displayOptions.registerOption(colorOptionName, Color.BLACK, null, null);
|
displayOptions.registerOption(colorOptionName, Color.BLACK, null,
|
||||||
displayOptions.registerOption(styleOptionName, -1, null, null);
|
"Sets the " + colorOptionName);
|
||||||
|
displayOptions.registerOption(styleOptionName, -1, null, "Sets the " + style);
|
||||||
|
|
||||||
color = displayOptions.getColor(colorOptionName, getDefaultColor());
|
color = displayOptions.getColor(colorOptionName, getDefaultColor());
|
||||||
style = displayOptions.getInt(styleOptionName, -1);
|
style = displayOptions.getInt(styleOptionName, -1);
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class LabelFieldFactory extends FieldFactory {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param model the model that the field belongs to.
|
* @param model the model that the field belongs to.
|
||||||
* @param hsProvider the HightLightStringProvider.
|
* @param hlProvider the HightLightStringProvider.
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
|
@ -116,7 +116,8 @@ public class LabelFieldFactory extends FieldFactory {
|
||||||
private void setupNamespaceOptions(Options fieldOptions) {
|
private void setupNamespaceOptions(Options fieldOptions) {
|
||||||
// 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, null, namespaceOptionsEditor);
|
new NamespaceWrappedOption(), null, "Adjusts the Label Field namespace display",
|
||||||
|
namespaceOptionsEditor);
|
||||||
CustomOption wrappedOption =
|
CustomOption wrappedOption =
|
||||||
fieldOptions.getCustomOption(NAMESPACE_OPTIONS, new NamespaceWrappedOption());
|
fieldOptions.getCustomOption(NAMESPACE_OPTIONS, new NamespaceWrappedOption());
|
||||||
if (!(wrappedOption instanceof NamespaceWrappedOption)) {
|
if (!(wrappedOption instanceof NamespaceWrappedOption)) {
|
||||||
|
@ -406,8 +407,7 @@ public class LabelFieldFactory extends FieldFactory {
|
||||||
text = SymbolUtilities.getDynamicOffcutName(addr);
|
text = SymbolUtilities.getDynamicOffcutName(addr);
|
||||||
}
|
}
|
||||||
// since these labels are fictitious, they don't have a namespace.
|
// since these labels are fictitious, they don't have a namespace.
|
||||||
return new LabelFieldLocation(cu.getProgram(), addr, cpath, text, null, row,
|
return new LabelFieldLocation(cu.getProgram(), addr, cpath, text, null, row, col);
|
||||||
col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -654,11 +654,11 @@ public class PlateFieldFactory extends FieldFactory {
|
||||||
"Number of lines to displayed before a plate comment." +
|
"Number of lines to displayed before a plate comment." +
|
||||||
" This setting has precedence over Lines Before Labels.");
|
" This setting has precedence over Lines Before Labels.");
|
||||||
|
|
||||||
|
help = new HelpLocation(HelpTopics.CODE_BROWSER, "Function_Pointers");
|
||||||
options.registerOption(ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true,
|
options.registerOption(ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true,
|
||||||
help, null);
|
help, "Shows/hides function header format for pointers to external functions");
|
||||||
options.registerOption(ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false,
|
options.registerOption(ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false,
|
||||||
help, null);
|
help, "Shows/hides function header format for pointers to non-external functions");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class PostCommentFieldFactory extends FieldFactory {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param model the model that the field belongs to.
|
* @param model the model that the field belongs to.
|
||||||
* @param hsProvider the HightLightStringProvider.
|
* @param hlProvider the HightLightStringProvider.
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
|
@ -93,9 +93,12 @@ public class PostCommentFieldFactory extends FieldFactory {
|
||||||
Options displayOptions, Options fieldOptions) {
|
Options displayOptions, Options fieldOptions) {
|
||||||
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
|
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
|
||||||
|
|
||||||
fieldOptions.registerOption(FLAG_FUNCTION_EXIT_OPTION, false, null, null);
|
fieldOptions.registerOption(FLAG_FUNCTION_EXIT_OPTION, false, null,
|
||||||
fieldOptions.registerOption(FLAG_TERMINATOR_OPTION, false, null, null);
|
"Toggles the display of a post-comment for a function exit");
|
||||||
fieldOptions.registerOption(LINES_AFTER_BLOCKS_OPTION, 0, null, null);
|
fieldOptions.registerOption(FLAG_TERMINATOR_OPTION, false, null,
|
||||||
|
"Toggles the display of a jump/return post-comments");
|
||||||
|
fieldOptions.registerOption(LINES_AFTER_BLOCKS_OPTION, 0, null,
|
||||||
|
"The number of lines to display after basic blocks");
|
||||||
|
|
||||||
flagFunctionExits = fieldOptions.getBoolean(FLAG_FUNCTION_EXIT_OPTION, false);
|
flagFunctionExits = fieldOptions.getBoolean(FLAG_FUNCTION_EXIT_OPTION, false);
|
||||||
flagJMPsRETs = fieldOptions.getBoolean(FLAG_TERMINATOR_OPTION, false);
|
flagJMPsRETs = fieldOptions.getBoolean(FLAG_TERMINATOR_OPTION, false);
|
||||||
|
@ -226,9 +229,8 @@ public class PostCommentFieldFactory extends FieldFactory {
|
||||||
comments.addFirst(callOtherCallOverrideComment);
|
comments.addFirst(callOtherCallOverrideComment);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
overrideData =
|
overrideData = getOverrideCommentData(instr, RefType.CALLOTHER_OVERRIDE_JUMP,
|
||||||
getOverrideCommentData(instr, RefType.CALLOTHER_OVERRIDE_JUMP, pcodeOps,
|
pcodeOps, pCodeOverride);
|
||||||
pCodeOverride);
|
|
||||||
if (overrideData != null) {
|
if (overrideData != null) {
|
||||||
String callOtherJumpOverrideComment =
|
String callOtherJumpOverrideComment =
|
||||||
"-- CALLOTHER(" + overrideData.getOverriddenCallOther() +
|
"-- CALLOTHER(" + overrideData.getOverriddenCallOther() +
|
||||||
|
@ -313,8 +315,8 @@ public class PostCommentFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider,
|
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider,
|
||||||
ToolOptions displayOptions, ToolOptions fieldOptions) {
|
ToolOptions toolOptions, ToolOptions fieldOptions) {
|
||||||
return new PostCommentFieldFactory(formatModel, provider, displayOptions, fieldOptions);
|
return new PostCommentFieldFactory(formatModel, provider, toolOptions, fieldOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -525,7 +527,8 @@ public class PostCommentFieldFactory extends FieldFactory {
|
||||||
"at a jump or a return instruction.");
|
"at a jump or a return instruction.");
|
||||||
options.registerOption(LINES_AFTER_BLOCKS_OPTION, 0, null,
|
options.registerOption(LINES_AFTER_BLOCKS_OPTION, 0, null,
|
||||||
"Number of lines to display in the post comment after a code block.");
|
"Number of lines to display in the post comment after a code block.");
|
||||||
options.registerOption(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true, null, null);
|
options.registerOption(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true, null,
|
||||||
|
"Toggles the display of the automatic post-comment");
|
||||||
|
|
||||||
isWordWrap = options.getBoolean(ENABLE_WORD_WRAP_MSG, false);
|
isWordWrap = options.getBoolean(ENABLE_WORD_WRAP_MSG, false);
|
||||||
alwaysShowAutomatic = options.getBoolean(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true);
|
alwaysShowAutomatic = options.getBoolean(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true);
|
||||||
|
@ -557,6 +560,7 @@ public class PostCommentFieldFactory extends FieldFactory {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
|
// don't care
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,17 +77,18 @@ public class PreCommentFieldFactory extends FieldFactory {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param model the model that the field belongs to.
|
* @param model the model that the field belongs to.
|
||||||
* @param hsProvider the HightLightStringProvider.
|
* @param hlProvider the HightLightStringProvider.
|
||||||
* @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.
|
||||||
* @param serviceProvider the provider for services.
|
|
||||||
*/
|
*/
|
||||||
private PreCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider,
|
private PreCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider,
|
||||||
Options displayOptions, Options fieldOptions) {
|
Options displayOptions, Options fieldOptions) {
|
||||||
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
|
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
|
||||||
|
|
||||||
fieldOptions.registerOption(FLAG_FUNCTION_ENTRY_OPTION, false, null, null);
|
fieldOptions.registerOption(FLAG_FUNCTION_ENTRY_OPTION, false, null,
|
||||||
fieldOptions.registerOption(FLAG_SUBROUTINE_ENTRY_OPTION, false, null, null);
|
"Toggles the display of a pre-comment for a function entry");
|
||||||
|
fieldOptions.registerOption(FLAG_SUBROUTINE_ENTRY_OPTION, false, null,
|
||||||
|
"Toggles the display of a pre-comment for a sub-routine entry");
|
||||||
|
|
||||||
flagFunctionEntry = fieldOptions.getBoolean(FLAG_FUNCTION_ENTRY_OPTION, false);
|
flagFunctionEntry = fieldOptions.getBoolean(FLAG_FUNCTION_ENTRY_OPTION, false);
|
||||||
flagSubroutineEntry = fieldOptions.getBoolean(FLAG_SUBROUTINE_ENTRY_OPTION, false);
|
flagSubroutineEntry = fieldOptions.getBoolean(FLAG_SUBROUTINE_ENTRY_OPTION, false);
|
||||||
|
@ -183,8 +184,8 @@ public class PreCommentFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider,
|
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider,
|
||||||
ToolOptions displayOptions, ToolOptions fieldOptions) {
|
ToolOptions toolOptions, ToolOptions fieldOptions) {
|
||||||
return new PreCommentFieldFactory(formatModel, provider, displayOptions, fieldOptions);
|
return new PreCommentFieldFactory(formatModel, provider, toolOptions, fieldOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -379,7 +380,8 @@ public class PreCommentFieldFactory extends FieldFactory {
|
||||||
"wrapping is off, comments are displayed in line format " +
|
"wrapping is off, comments are displayed in line format " +
|
||||||
"however the user entered them. Lines that are too long " +
|
"however the user entered them. Lines that are too long " +
|
||||||
"for the field, are truncated.");
|
"for the field, are truncated.");
|
||||||
options.registerOption(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true, null, null);
|
options.registerOption(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true, null,
|
||||||
|
"Toggles the display of the automatic pre-comment");
|
||||||
|
|
||||||
isWordWrap = options.getBoolean(ENABLE_WORD_WRAP_MSG, false);
|
isWordWrap = options.getBoolean(ENABLE_WORD_WRAP_MSG, false);
|
||||||
alwaysShowAutomatic = options.getBoolean(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true);
|
alwaysShowAutomatic = options.getBoolean(ENABLE_ALWAYS_SHOW_AUTOMATIC_MSG, true);
|
||||||
|
|
|
@ -63,7 +63,8 @@ public class RegisterFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
fieldOptions.registerOption(DISPLAY_HIDDEN_REGISTERS_OPTION_NAME, false, null,
|
fieldOptions.registerOption(DISPLAY_HIDDEN_REGISTERS_OPTION_NAME, false, null,
|
||||||
"Shows/hides context registers");
|
"Shows/hides context registers");
|
||||||
fieldOptions.registerOption(DISPLAY_DEFAULT_REGISTER_VALUES_OPTION_NAME, false, null, null);
|
fieldOptions.registerOption(DISPLAY_DEFAULT_REGISTER_VALUES_OPTION_NAME, false, null,
|
||||||
|
"Shows/hides default register values");
|
||||||
regColor =
|
regColor =
|
||||||
displayOptions.getColor(OptionsGui.REGISTERS.getColorOptionName(), getDefaultColor());
|
displayOptions.getColor(OptionsGui.REGISTERS.getColorOptionName(), getDefaultColor());
|
||||||
|
|
||||||
|
@ -74,10 +75,9 @@ public class RegisterFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel formatModel,
|
public FieldFactory newInstance(FieldFormatModel formatModel,
|
||||||
HighlightProvider highlightProvider, ToolOptions displayOptions,
|
HighlightProvider highlightProvider, ToolOptions toolOptions,
|
||||||
ToolOptions fieldOptions) {
|
ToolOptions fieldOptions) {
|
||||||
return new RegisterFieldFactory(formatModel, highlightProvider, displayOptions,
|
return new RegisterFieldFactory(formatModel, highlightProvider, toolOptions, fieldOptions);
|
||||||
fieldOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -173,7 +173,8 @@ public class XRefFieldFactory extends FieldFactory {
|
||||||
private void setupNamespaceOptions(Options fieldOptions) {
|
private void setupNamespaceOptions(Options fieldOptions) {
|
||||||
// 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, null, namespaceOptionsEditor);
|
new NamespaceWrappedOption(), null, "Adjusts the XREFs Field namespace display",
|
||||||
|
namespaceOptionsEditor);
|
||||||
CustomOption customOption = fieldOptions.getCustomOption(NAMESPACE_OPTIONS, null);
|
CustomOption customOption = fieldOptions.getCustomOption(NAMESPACE_OPTIONS, null);
|
||||||
fieldOptions.getOptions(NAMESPACE_OPTIONS).setOptionsHelpLocation(
|
fieldOptions.getOptions(NAMESPACE_OPTIONS).setOptionsHelpLocation(
|
||||||
new HelpLocation("CodeBrowserPlugin", "XREFs_Field"));
|
new HelpLocation("CodeBrowserPlugin", "XREFs_Field"));
|
||||||
|
@ -529,6 +530,7 @@ public class XRefFieldFactory extends FieldFactory {
|
||||||
* Get an address location for this object.
|
* Get an address location for this object.
|
||||||
*
|
*
|
||||||
* @param obj object to get location from
|
* @param obj object to get location from
|
||||||
|
* @return the address
|
||||||
*/
|
*/
|
||||||
protected Address getXRefLocation(Object obj) {
|
protected Address getXRefLocation(Object obj) {
|
||||||
if (obj == null || !(obj instanceof CodeUnit)) {
|
if (obj == null || !(obj instanceof CodeUnit)) {
|
||||||
|
@ -556,7 +558,7 @@ public class XRefFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider,
|
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider,
|
||||||
ToolOptions displayOptions, ToolOptions fieldOptions) {
|
ToolOptions toolOptions, ToolOptions fieldOptions) {
|
||||||
return new XRefFieldFactory(formatModel, provider, displayOptions, fieldOptions);
|
return new XRefFieldFactory(formatModel, provider, toolOptions, fieldOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class FormatManager implements OptionsChangeListener {
|
||||||
HIGHLIGHT_GROUP + Options.DELIMITER + "Alternate Highlight Color";
|
HIGHLIGHT_GROUP + Options.DELIMITER + "Alternate Highlight Color";
|
||||||
public final static String ARRAY_DISPLAY_OPTIONS =
|
public final static String ARRAY_DISPLAY_OPTIONS =
|
||||||
OPTIONS_GROUP + Options.DELIMITER + "Array Display Options";
|
OPTIONS_GROUP + Options.DELIMITER + "Array Display Options";
|
||||||
|
public final static String ARRAY_DISPLAY_DESCRIPTION = "Adjusts the Array Field display";
|
||||||
|
|
||||||
private static final int NUM_MODELS = 7;
|
private static final int NUM_MODELS = 7;
|
||||||
|
|
||||||
|
@ -94,7 +95,8 @@ 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, null, new ArrayElementPropertyEditor());
|
new ArrayElementWrappedOption(), null, ARRAY_DISPLAY_DESCRIPTION,
|
||||||
|
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;
|
||||||
|
|
|
@ -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.listingpanel;
|
package ghidra.app.util.viewer.listingpanel;
|
||||||
|
|
||||||
|
import docking.widgets.fieldpanel.Layout;
|
||||||
import ghidra.app.util.viewer.format.FormatManager;
|
import ghidra.app.util.viewer.format.FormatManager;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.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 ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import docking.widgets.fieldpanel.Layout;
|
|
||||||
|
|
||||||
public interface ListingModel {
|
public interface ListingModel {
|
||||||
|
|
||||||
|
@ -30,10 +29,10 @@ public interface ListingModel {
|
||||||
|
|
||||||
public static final String DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME =
|
public static final String DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME =
|
||||||
FUNCTION_POINTER_OPTION_GROUP_NAME + Options.DELIMITER +
|
FUNCTION_POINTER_OPTION_GROUP_NAME + Options.DELIMITER +
|
||||||
"Display Function Header for External Function Pointers";
|
"Display External Function Pointer Header";
|
||||||
public static final String DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME =
|
public static final String DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME =
|
||||||
FUNCTION_POINTER_OPTION_GROUP_NAME + Options.DELIMITER +
|
FUNCTION_POINTER_OPTION_GROUP_NAME + Options.DELIMITER +
|
||||||
"Display Function Header for Non-External Function Pointers";
|
"Display Non-External Function Pointer Header";
|
||||||
|
|
||||||
public AddressSetView getAddressSet();
|
public AddressSetView getAddressSet();
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,6 @@ public class ProgramBigListingModel implements ListingModel, FormatModelListener
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initOptions() {
|
private void initOptions() {
|
||||||
fieldOptions.registerOption(DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true, null,
|
|
||||||
"Shows/hides function header format for pointers to external functions");
|
|
||||||
fieldOptions.registerOption(DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false, null,
|
|
||||||
"Shows/hides function header format for pointers to non-external functions");
|
|
||||||
|
|
||||||
showExternalFunctionPointerFormat =
|
showExternalFunctionPointerFormat =
|
||||||
fieldOptions.getBoolean(DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
|
fieldOptions.getBoolean(DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
|
||||||
showNonExternalFunctionPointerFormat =
|
showNonExternalFunctionPointerFormat =
|
||||||
|
|
|
@ -23,7 +23,6 @@ import javax.swing.JComponent;
|
||||||
|
|
||||||
import ghidra.GhidraOptions;
|
import ghidra.GhidraOptions;
|
||||||
import ghidra.framework.options.*;
|
import ghidra.framework.options.*;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for editing Listing display properties.
|
* Class for editing Listing display properties.
|
||||||
|
@ -35,14 +34,11 @@ public class ListingDisplayOptionsEditor implements OptionsEditor {
|
||||||
private Options options;
|
private Options options;
|
||||||
private PropertyChangeListener propertyChangeListener;
|
private PropertyChangeListener propertyChangeListener;
|
||||||
|
|
||||||
private final Plugin ownerPlugin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ListingDisplayOptionsEditor.
|
* Constructs a new ListingDisplayOptionsEditor.
|
||||||
* @param options the options object to edit
|
* @param options the options object to edit
|
||||||
*/
|
*/
|
||||||
public ListingDisplayOptionsEditor(Plugin ownerPlugin, Options options) {
|
public ListingDisplayOptionsEditor(Options options) {
|
||||||
this.ownerPlugin = ownerPlugin;
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
registerOptions();
|
registerOptions();
|
||||||
}
|
}
|
||||||
|
@ -56,17 +52,18 @@ public class ListingDisplayOptionsEditor implements OptionsEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerOptions() {
|
private void registerOptions() {
|
||||||
options.registerOption(GhidraOptions.OPTION_BASE_FONT, DEFAULT_FONT, null, null);
|
String prefix = "Sets the ";
|
||||||
|
options.registerOption(GhidraOptions.OPTION_BASE_FONT, DEFAULT_FONT, null,
|
||||||
|
prefix + GhidraOptions.OPTION_BASE_FONT);
|
||||||
for (ScreenElement element : OptionsGui.elements) {
|
for (ScreenElement element : OptionsGui.elements) {
|
||||||
options.registerOption(element.getColorOptionName(), element.getDefaultColor(), null,
|
String colorOptionName = element.getColorOptionName();
|
||||||
null);
|
options.registerOption(colorOptionName, element.getDefaultColor(), null,
|
||||||
options.registerOption(element.getStyleOptionName(), -1, null, null);
|
prefix + colorOptionName);
|
||||||
|
String styleOptionName = element.getStyleOptionName();
|
||||||
|
options.registerOption(styleOptionName, -1, null, prefix + styleOptionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the changes.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void apply() {
|
public void apply() {
|
||||||
if (optionsGui != null) {
|
if (optionsGui != null) {
|
||||||
|
@ -105,9 +102,6 @@ public class ListingDisplayOptionsEditor implements OptionsEditor {
|
||||||
// nothing to do, as this component is reloaded when options are changed
|
// nothing to do, as this component is reloaded when options are changed
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.framework.options.OptionsEditor#setOptionsPropertyChangeListener(java.beans.PropertyChangeListener)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setOptionsPropertyChangeListener(PropertyChangeListener listener) {
|
public void setOptionsPropertyChangeListener(PropertyChangeListener listener) {
|
||||||
this.propertyChangeListener = listener;
|
this.propertyChangeListener = listener;
|
||||||
|
@ -120,14 +114,12 @@ public class ListingDisplayOptionsEditor implements OptionsEditor {
|
||||||
/**
|
/**
|
||||||
* Returns true if this component has "good" resizing behavior. Components
|
* Returns true if this component has "good" resizing behavior. Components
|
||||||
* that do not have this property will be placed in a scrolled pane.
|
* that do not have this property will be placed in a scrolled pane.
|
||||||
|
* @return true if resizable
|
||||||
*/
|
*/
|
||||||
public boolean isResizable() {
|
public boolean isResizable() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the editor component.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public JComponent getEditorComponent(Options editableOptions,
|
public JComponent getEditorComponent(Options editableOptions,
|
||||||
EditorStateFactory editorStateFactory) {
|
EditorStateFactory editorStateFactory) {
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.codebrowser;
|
package ghidra.app.plugin.core.codebrowser;
|
||||||
|
|
||||||
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.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.program.util.BytesFieldLocation;
|
import ghidra.program.util.BytesFieldLocation;
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.TestEnv;
|
import ghidra.test.TestEnv;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
import util.CollectionUtils;
|
||||||
|
|
||||||
public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest {
|
public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
private TestEnv env;
|
private TestEnv env;
|
||||||
|
@ -969,6 +971,38 @@ public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertTrue(btf.getText().endsWith("[more]"));
|
assertTrue(btf.getText().endsWith("[more]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEveryOptionHasHelp() throws Exception {
|
||||||
|
showTool(tool);
|
||||||
|
|
||||||
|
List<String> missing = new ArrayList<>();
|
||||||
|
ToolOptions[] toolOptions = tool.getOptions();
|
||||||
|
for (ToolOptions options : toolOptions) {
|
||||||
|
|
||||||
|
HelpLocation helpLocation = options.getOptionsHelpLocation();
|
||||||
|
if (helpLocation != null) {
|
||||||
|
continue; // this is a top-level help location for all sub-options
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isOneOf(options.getName(), "Key Bindings", "Listing Display")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> optionNames = options.getOptionNames();
|
||||||
|
for (String name : optionNames) {
|
||||||
|
HelpLocation hl = options.getHelpLocation(name);
|
||||||
|
if (hl == null) {
|
||||||
|
missing.add(options.getName() + "." + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!missing.isEmpty()) {
|
||||||
|
fail(missing.size() + " Tool Options is missing help\n" +
|
||||||
|
missing.stream().collect(Collectors.joining("\n")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum DUMMY {
|
enum DUMMY {
|
||||||
// nothing; just a dummy
|
// nothing; just a dummy
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,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(this, 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));
|
||||||
|
|
||||||
|
|
|
@ -1780,12 +1780,14 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||||
2) A component provider's code
|
2) A component provider's code
|
||||||
3) A dialog provider's code
|
3) A dialog provider's code
|
||||||
4) A background thread
|
4) A background thread
|
||||||
|
5) The help window
|
||||||
|
|
||||||
It seems like the parent should be the active window for 1-2.
|
It seems like the parent should be the active window for 1-2.
|
||||||
Case 3 should probably use the window of the dialog provider.
|
Case 3 should probably use the window of the dialog provider.
|
||||||
Case 4 should probably use the main tool frame, since the user may be
|
Case 4 should probably use the main tool frame, since the user may be
|
||||||
moving between windows while the thread is working. So, rather than using the
|
moving between windows while the thread is working. So, rather than using the
|
||||||
active window, we can default to the tool's frame.
|
active window, we can default to the tool's frame.
|
||||||
|
Case 5 should use the help window.
|
||||||
|
|
||||||
We have not yet solidified how we should parent. This documentation is meant to
|
We have not yet solidified how we should parent. This documentation is meant to
|
||||||
move us towards clarity as we find Use Cases that don't make sense. (Once we
|
move us towards clarity as we find Use Cases that don't make sense. (Once we
|
||||||
|
@ -1828,7 +1830,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||||
|
|
||||||
Component c = parent;
|
Component c = parent;
|
||||||
while (c != null) {
|
while (c != null) {
|
||||||
if (c instanceof Frame) {
|
if (c instanceof Window) {
|
||||||
return (Window) c;
|
return (Window) c;
|
||||||
}
|
}
|
||||||
c = c.getParent();
|
c = c.getParent();
|
||||||
|
|
|
@ -175,7 +175,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
|
||||||
for (ActionData actionData : actions) {
|
for (ActionData actionData : actions) {
|
||||||
if (actionData.isMyProvider(localContext)) {
|
if (actionData.isMyProvider(localContext)) {
|
||||||
hasLocalActionsForKeyBinding = true;
|
hasLocalActionsForKeyBinding = true;
|
||||||
if (actionData.action.isEnabledForContext(localContext)) {
|
if (isValidAndEnabled(actionData, localContext)) {
|
||||||
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
|
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
|
||||||
(ComponentBasedDockingAction) actionData.action;
|
(ComponentBasedDockingAction) actionData.action;
|
||||||
if (componentAction.isValidComponentContext(localContext)) {
|
if (componentAction.isValidComponentContext(localContext)) {
|
||||||
hasLocalActionsForKeyBinding = true;
|
hasLocalActionsForKeyBinding = true;
|
||||||
if (actionData.action.isEnabledForContext(localContext)) {
|
if (isValidAndEnabled(actionData, localContext)) {
|
||||||
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
|
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,21 +219,22 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
|
||||||
// When looking for context matches, we prefer local context, even though this
|
// When looking for context matches, we prefer local context, even though this
|
||||||
// is a 'global' action. This allows more specific context to be used when
|
// is a 'global' action. This allows more specific context to be used when
|
||||||
// available
|
// available
|
||||||
if (actionData.action.isValidContext(localContext)) {
|
if (isValidAndEnabled(actionData, localContext)) {
|
||||||
if (actionData.action.isEnabledForContext(localContext)) {
|
|
||||||
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
|
list.add(new ExecutableKeyActionAdapter(actionData.action, localContext));
|
||||||
}
|
}
|
||||||
}
|
else if (isValidAndEnabled(actionData, globalContext)) {
|
||||||
else if (actionData.action.isValidGlobalContext(globalContext)) {
|
|
||||||
if (actionData.action.isEnabledForContext(globalContext)) {
|
|
||||||
list.add(new ExecutableKeyActionAdapter(actionData.action, globalContext));
|
list.add(new ExecutableKeyActionAdapter(actionData.action, globalContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isValidAndEnabled(ActionData actionData, ActionContext localContext) {
|
||||||
|
DockingActionIf a = actionData.action;
|
||||||
|
return a.isValidContext(localContext) && a.isEnabledForContext(localContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReservedKeybindingPrecedence() {
|
public boolean isReservedKeybindingPrecedence() {
|
||||||
return false; // MultipleKeyActions can never be reserved
|
return false; // MultipleKeyActions can never be reserved
|
||||||
|
|
|
@ -142,8 +142,9 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyStroke ks = action.getKeyBinding();
|
KeyStroke ks = action.getKeyBinding();
|
||||||
|
String description = "Keybinding for " + action.getFullName();
|
||||||
keyBindingOptions.registerOption(action.getFullName(), OptionType.KEYSTROKE_TYPE, ks, null,
|
keyBindingOptions.registerOption(action.getFullName(), OptionType.KEYSTROKE_TYPE, ks, null,
|
||||||
null);
|
description);
|
||||||
KeyStroke newKs = keyBindingOptions.getKeyStroke(action.getFullName(), ks);
|
KeyStroke newKs = keyBindingOptions.getKeyStroke(action.getFullName(), ks);
|
||||||
if (!Objects.equals(ks, newKs)) {
|
if (!Objects.equals(ks, newKs)) {
|
||||||
action.setUnvalidatedKeyBindingData(new KeyBindingData(newKs));
|
action.setUnvalidatedKeyBindingData(new KeyBindingData(newKs));
|
||||||
|
@ -175,8 +176,9 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener {
|
||||||
|
|
||||||
private void registerStub(SharedStubKeyBindingAction stub, KeyStroke defaultKeyStroke) {
|
private void registerStub(SharedStubKeyBindingAction stub, KeyStroke defaultKeyStroke) {
|
||||||
stub.addPropertyChangeListener(this);
|
stub.addPropertyChangeListener(this);
|
||||||
|
String description = "Keybinding for Stub action: " + stub.getFullName();
|
||||||
keyBindingOptions.registerOption(stub.getFullName(), OptionType.KEYSTROKE_TYPE,
|
keyBindingOptions.registerOption(stub.getFullName(), OptionType.KEYSTROKE_TYPE,
|
||||||
defaultKeyStroke, null, null);
|
defaultKeyStroke, null, description);
|
||||||
keyBindingsManager.addAction(null, stub);
|
keyBindingsManager.addAction(null, stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,15 +319,16 @@ public class OptionsPanel extends JPanel {
|
||||||
return; // not sure this can happen
|
return; // not sure this can happen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HelpService help = Help.getHelpService();
|
||||||
HelpLocation location = options.getOptionsHelpLocation();
|
HelpLocation location = options.getOptionsHelpLocation();
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
// The tree node may or may not have help. The leaf options should all have help.
|
// The tree node may or may not have help. The leaf options should all have help.
|
||||||
return;
|
help.clearHelp(this);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
HelpService help = Help.getHelpService();
|
|
||||||
help.registerHelp(this, location);
|
help.registerHelp(this, location);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private OptionsEditor getOptionsEditor(OptionsTreeNode node) {
|
private OptionsEditor getOptionsEditor(OptionsTreeNode node) {
|
||||||
OptionsEditor editor = editorMap.get(node);
|
OptionsEditor editor = editorMap.get(node);
|
||||||
|
|
|
@ -26,8 +26,10 @@ import javax.swing.KeyStroke;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
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 utilities.util.reflection.ReflectionUtilities;
|
||||||
|
|
||||||
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();
|
||||||
|
@ -136,6 +138,10 @@ public abstract class AbstractOptions implements Options {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Can't register a custom option without a property editor");
|
"Can't register a custom option without a property editor");
|
||||||
}
|
}
|
||||||
|
if (description == null) {
|
||||||
|
Msg.error(this, "Registered an option without a description: " + optionName,
|
||||||
|
ReflectionUtilities.createJavaFilteredThrowable());
|
||||||
|
}
|
||||||
|
|
||||||
Option currentOption = valueMap.get(optionName);
|
Option currentOption = valueMap.get(optionName);
|
||||||
if (currentOption == null) {
|
if (currentOption == null) {
|
||||||
|
|
|
@ -116,6 +116,9 @@ public class ToolOptions extends AbstractOptions {
|
||||||
* Return an XML element for the option names and values.
|
* Return an XML element for the option names and values.
|
||||||
* Note: only those options which have been explicitly set
|
* Note: only those options which have been explicitly set
|
||||||
* will be included.
|
* will be included.
|
||||||
|
*
|
||||||
|
* @param includeDefaultBindings true to include default key binding values in the xml
|
||||||
|
* @return the xml root element
|
||||||
*/
|
*/
|
||||||
public Element getXmlRoot(boolean includeDefaultBindings) {
|
public Element getXmlRoot(boolean includeDefaultBindings) {
|
||||||
SaveState saveState = new SaveState(XML_ELEMENT_NAME);
|
SaveState saveState = new SaveState(XML_ELEMENT_NAME);
|
||||||
|
@ -268,7 +271,7 @@ public class ToolOptions extends AbstractOptions {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds all the options name/value pairs to this Options.
|
* Adds all the options name/value pairs to this Options.
|
||||||
* @param newOptions
|
* @param newOptions the new options into which the current options values will be placed
|
||||||
*/
|
*/
|
||||||
public void copyOptions(Options newOptions) {
|
public void copyOptions(Options newOptions) {
|
||||||
List<String> optionNames = newOptions.getOptionNames();
|
List<String> optionNames = newOptions.getOptionNames();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue