mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-15 08:32:07 +00:00
Merge remote-tracking branch
'origin/GP-3683-dragonmacher-function-tags-nav-2' into patch (Closes #5613)
This commit is contained in:
commit
d39caa5f44
@ -26,21 +26,21 @@ import ghidra.program.util.ProgramLocation;
|
|||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Presents the user with a {@link ComponentProvider} showing all function tags available,
|
* Presents the user with a {@link ComponentProvider} showing all function tags available,along with
|
||||||
* along with all those currently assigned to the selected function.
|
* all those currently assigned to the selected function.
|
||||||
|
* <p>
|
||||||
* Users may select, deselect, edit or delete tags.
|
* Users may select, deselect, edit or delete tags.
|
||||||
*/
|
*/
|
||||||
public class EditFunctionTagsAction extends ListingContextAction {
|
public class EditFunctionTagsAction extends ListingContextAction {
|
||||||
|
|
||||||
private FunctionTagPlugin plugin;
|
private FunctionTagPlugin plugin;
|
||||||
|
|
||||||
// Menu option that will show up when right-clicking on a function in
|
// Menu option that will show up when right-clicking on a function in the listing
|
||||||
// the listing.
|
|
||||||
private final String MENU_LABEL = "Edit Tags...";
|
private final String MENU_LABEL = "Edit Tags...";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param name the name for this action.
|
* @param name the name for this action.
|
||||||
* @param plugin the plugin this action is associated with.
|
* @param plugin the plugin this action is associated with.
|
||||||
*/
|
*/
|
||||||
@ -57,10 +57,6 @@ public class EditFunctionTagsAction extends ListingContextAction {
|
|||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* PUBLIC METHODS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ListingActionContext context) {
|
public void actionPerformed(ListingActionContext context) {
|
||||||
|
|
||||||
@ -74,25 +70,22 @@ public class EditFunctionTagsAction extends ListingContextAction {
|
|||||||
showProvider(context);
|
showProvider(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* PROTECTED METHODS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overridden to only allow this menu option when clicking in a function.
|
* Overridden to only allow this menu option when clicking in a function.
|
||||||
* Note that we do not allow external functions to have tags.
|
* Note that we do not allow external functions to have tags.
|
||||||
*
|
*
|
||||||
* @param context the listing context
|
* @param context the listing context
|
||||||
* @return
|
* @return true if enabled
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean isEnabledForContext(ListingActionContext context) {
|
protected boolean isEnabledForContext(ListingActionContext context) {
|
||||||
|
|
||||||
if (context.hasSelection() || context.getAddress() == null) {
|
Address address = context.getAddress();
|
||||||
|
if (context.hasSelection() || address == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.getLocation().getAddress().isExternalAddress()) {
|
if (address.isExternalAddress()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,12 +97,9 @@ public class EditFunctionTagsAction extends ListingContextAction {
|
|||||||
return !funcAddress.isExternalAddress();
|
return !funcAddress.isExternalAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* PRIVATE METHODS
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the address of the function associated with the given program location.
|
* Retrieves the address of the function associated with the given program location.
|
||||||
*
|
*
|
||||||
* @param loc the program location
|
* @param loc the program location
|
||||||
* @return the entry point of the function, or null if not valid
|
* @return the entry point of the function, or null if not valid
|
||||||
*/
|
*/
|
||||||
@ -126,7 +116,7 @@ public class EditFunctionTagsAction extends ListingContextAction {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the provider.
|
* Displays the provider.
|
||||||
*
|
*
|
||||||
* @param context the listing context
|
* @param context the listing context
|
||||||
*/
|
*/
|
||||||
private void showProvider(ListingActionContext context) {
|
private void showProvider(ListingActionContext context) {
|
||||||
|
@ -26,9 +26,9 @@ import ghidra.program.util.ProgramLocation;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin for managing function tags. This works with the associated
|
* Plugin for managing function tags. This works with the associated
|
||||||
* {@link FunctionTagProvider} to allow users to view and
|
* {@link FunctionTagProvider} to allow users to view and
|
||||||
* edit function tags both globally and for individual functions.
|
* edit function tags both globally and for individual functions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
@ -51,17 +51,11 @@ public class FunctionTagPlugin extends ProgramPlugin {
|
|||||||
|
|
||||||
public FunctionTagPlugin(PluginTool tool) {
|
public FunctionTagPlugin(PluginTool tool) {
|
||||||
super(tool);
|
super(tool);
|
||||||
provider = new FunctionTagProvider(this, getCurrentProgram());
|
|
||||||
createActions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* PUBLIC METHODS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the component provider for this plugin
|
* Returns the component provider for this plugin
|
||||||
*
|
*
|
||||||
* @return the component provider
|
* @return the component provider
|
||||||
*/
|
*/
|
||||||
public FunctionTagProvider getProvider() {
|
public FunctionTagProvider getProvider() {
|
||||||
@ -71,11 +65,10 @@ public class FunctionTagPlugin extends ProgramPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
super.init();
|
super.init();
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
provider = new FunctionTagProvider(this, getCurrentProgram());
|
||||||
* PROTECTED METHODS
|
createActions();
|
||||||
******************************************************************************/
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void programDeactivated(Program program) {
|
protected void programDeactivated(Program program) {
|
||||||
@ -92,10 +85,6 @@ public class FunctionTagPlugin extends ProgramPlugin {
|
|||||||
provider.locationChanged(loc);
|
provider.locationChanged(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* PRIVATE METHODS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
editFunctionTagsAction = new EditFunctionTagsAction("Edit Function Tags", this);
|
editFunctionTagsAction = new EditFunctionTagsAction("Edit Function Tags", this);
|
||||||
tool.addAction(editFunctionTagsAction);
|
tool.addAction(editFunctionTagsAction);
|
||||||
|
@ -50,14 +50,13 @@ import resources.ResourceManager;
|
|||||||
* <LI>Edit tags (both name and comment)</LI>
|
* <LI>Edit tags (both name and comment)</LI>
|
||||||
* <LI>Delete tags</LI>
|
* <LI>Delete tags</LI>
|
||||||
* <LI>Assign tags to the currently selected function</LI>
|
* <LI>Assign tags to the currently selected function</LI>
|
||||||
* <LI>Remove tags from the currently selected function</LI>
|
* <LI>Remove tags from the currently selected function</LI>
|
||||||
* </UL>
|
* </UL>
|
||||||
* This provider can be shown by right-clicking on a function and selecting the
|
* This provider can be shown by right-clicking on a function and selecting the
|
||||||
* "Edit Tags" option, or by selecting the "Edit Function Tags" option from the
|
* "Edit Tags" option, or by selecting the "Edit Function Tags" option from the
|
||||||
* "Window" menu.
|
* "Window" menu.
|
||||||
*/
|
*/
|
||||||
public class FunctionTagProvider extends ComponentProviderAdapter
|
public class FunctionTagProvider extends ComponentProviderAdapter implements DomainObjectListener {
|
||||||
implements DomainObjectListener {
|
|
||||||
|
|
||||||
private SourceTagsPanel sourcePanel;
|
private SourceTagsPanel sourcePanel;
|
||||||
private TargetTagsPanel targetPanel;
|
private TargetTagsPanel targetPanel;
|
||||||
@ -75,37 +74,37 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
private SwingUpdateManager updater = new SwingUpdateManager(this::doUpdate);
|
private SwingUpdateManager updater = new SwingUpdateManager(this::doUpdate);
|
||||||
|
|
||||||
// The current program location selected in the listing.
|
// The current program location selected in the listing.
|
||||||
private ProgramLocation currentLocation = null;
|
private ProgramLocation currentLocation = null;
|
||||||
|
|
||||||
// Character used as a separator when entering multiple tags in
|
// Character used as a separator when entering multiple tags in
|
||||||
// the create tag entry field.
|
// the create tag entry field.
|
||||||
private static final String INPUT_DELIMITER = ",";
|
private static final String INPUT_DELIMITER = ",";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional! If there is a file with this name which can be found by the
|
* Optional! If there is a file with this name which can be found by the
|
||||||
* {@link ResourceManager}, and it contains a valid list of tag names,
|
* {@link ResourceManager}, and it contains a valid list of tag names,
|
||||||
* they will be loaded. The file must be XML with the following
|
* they will be loaded. The file must be XML with the following
|
||||||
* structure:
|
* structure:
|
||||||
*
|
*
|
||||||
* <tags>
|
* <tags>
|
||||||
* <tag>
|
* <tag>
|
||||||
* <name>TAG1</name>
|
* <name>TAG1</name>
|
||||||
* <comment>tag comment</comment>
|
* <comment>tag comment</comment>
|
||||||
* </tag>
|
* </tag>
|
||||||
* </tags>
|
* </tags>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static String TAG_FILE = "functionTags.xml";
|
private static String TAG_FILE = "functionTags.xml";
|
||||||
|
|
||||||
// Keeps a list of the original tags as loaded from file. This is necessary when switching
|
// Keeps a list of the original tags as loaded from file. This is necessary when switching
|
||||||
// between programs where we need to know the original state of the disabled tags. Without
|
// between programs where we need to know the original state of the disabled tags. Without
|
||||||
// this we would need to reload from file on each new program activation.
|
// this we would need to reload from file on each new program activation.
|
||||||
private Set<FunctionTag> tagsFromFile;
|
private Set<FunctionTag> tagsFromFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param plugin the function tag plugin
|
* @param plugin the function tag plugin
|
||||||
* @param program the current program
|
* @param program the current program
|
||||||
*/
|
*/
|
||||||
@ -118,10 +117,6 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
addToTool();
|
addToTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* PUBLIC METHODS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentShown() {
|
public void componentShown() {
|
||||||
updateView();
|
updateView();
|
||||||
@ -133,10 +128,10 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when a new location has been detected in the listing. When
|
* Invoked when a new location has been detected in the listing. When
|
||||||
* this happens we need to update the tag list to show what tags are assigned
|
* this happens we need to update the tag list to show what tags are assigned
|
||||||
* at the current location.
|
* at the current location.
|
||||||
*
|
*
|
||||||
* @param loc the address selected in the listing
|
* @param loc the address selected in the listing
|
||||||
*/
|
*/
|
||||||
public void locationChanged(ProgramLocation loc) {
|
public void locationChanged(ProgramLocation loc) {
|
||||||
@ -158,12 +153,6 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
this.program = null;
|
this.program = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This class needs to listen for changes to the domain object (tag create, delete, etc...)
|
|
||||||
* so it can update the display accordingly.
|
|
||||||
*
|
|
||||||
* @param ev the change event
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||||
|
|
||||||
@ -244,8 +233,8 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
allFunctionsPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
allFunctionsPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
|
|
||||||
// If we don't set this, then the splitter won't be able to shrink the
|
// If we don't set this, then the splitter won't be able to shrink the
|
||||||
// target panels below the size required by its header, which can be large
|
// target panels below the size required by its header, which can be large
|
||||||
// because of the amount of text displayed. Keep the minimum size setting on
|
// because of the amount of text displayed. Keep the minimum size setting on
|
||||||
// the source panel, however. That is generally small.
|
// the source panel, however. That is generally small.
|
||||||
targetPanel.setMinimumSize(new Dimension(0, 0));
|
targetPanel.setMinimumSize(new Dimension(0, 0));
|
||||||
|
|
||||||
@ -270,7 +259,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
* Updates the button panel depending on the selection state of the
|
* Updates the button panel depending on the selection state of the
|
||||||
* tag lists. Also updates the {@link AllFunctionsPanel} so it can update
|
* tag lists. Also updates the {@link AllFunctionsPanel} so it can update
|
||||||
* its list.
|
* its list.
|
||||||
*
|
*
|
||||||
* @param panel the panel that generated the selection event
|
* @param panel the panel that generated the selection event
|
||||||
*/
|
*/
|
||||||
public void selectionChanged(TagListPanel panel) {
|
public void selectionChanged(TagListPanel panel) {
|
||||||
@ -330,7 +319,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads tags from the external file specified.
|
* Loads tags from the external file specified.
|
||||||
*
|
*
|
||||||
* @return the loaded tags
|
* @return the loaded tags
|
||||||
*/
|
*/
|
||||||
private Set<FunctionTag> getFileTags() {
|
private Set<FunctionTag> getFileTags() {
|
||||||
@ -342,7 +331,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all tags stored in the database.
|
* Returns an array of all tags stored in the database.
|
||||||
*
|
*
|
||||||
* @return list of tags
|
* @return list of tags
|
||||||
*/
|
*/
|
||||||
private List<? extends FunctionTag> getAllTagsFromDatabase() {
|
private List<? extends FunctionTag> getAllTagsFromDatabase() {
|
||||||
@ -355,7 +344,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Function} for the given program location
|
* Returns the {@link Function} for the given program location
|
||||||
*
|
*
|
||||||
* @param loc the program location
|
* @param loc the program location
|
||||||
* @return function containing the location, or null if not applicable
|
* @return function containing the location, or null if not applicable
|
||||||
*/
|
*/
|
||||||
@ -371,7 +360,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the address of the function associated with the given program location.
|
* Retrieves the address of the function associated with the given program location.
|
||||||
*
|
*
|
||||||
* @param loc the program location
|
* @param loc the program location
|
||||||
* @return the entry point of the function, or null if not valid
|
* @return the entry point of the function, or null if not valid
|
||||||
*/
|
*/
|
||||||
@ -408,7 +397,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
targetPanel.setProgram(program);
|
targetPanel.setProgram(program);
|
||||||
allFunctionsPanel.setProgram(program);
|
allFunctionsPanel.setProgram(program);
|
||||||
|
|
||||||
// Get the currently selected tags and use them to update the all functions panel. If
|
// Get the currently selected tags and use them to update the all functions panel. If
|
||||||
// there is no current selection, leave the table as-is.
|
// there is no current selection, leave the table as-is.
|
||||||
Set<FunctionTag> sTags = sourcePanel.getSelectedTags();
|
Set<FunctionTag> sTags = sourcePanel.getSelectedTags();
|
||||||
Set<FunctionTag> tTags = targetPanel.getSelectedTags();
|
Set<FunctionTag> tTags = targetPanel.getSelectedTags();
|
||||||
@ -423,7 +412,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses all items in the text input field and adds them as new tags.
|
* Parses all items in the text input field and adds them as new tags.
|
||||||
*/
|
*/
|
||||||
private void processCreates() {
|
private void processCreates() {
|
||||||
|
|
||||||
@ -462,7 +451,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
/**
|
/**
|
||||||
* Returns a list of tag names the user has entered in the input` field.
|
* Returns a list of tag names the user has entered in the input` field.
|
||||||
* Note: This assumes that multiple entries are comma-delimited.
|
* Note: This assumes that multiple entries are comma-delimited.
|
||||||
*
|
*
|
||||||
* @return the list of tag names to create
|
* @return the list of tag names to create
|
||||||
*/
|
*/
|
||||||
private List<String> getInputNames() {
|
private List<String> getInputNames() {
|
||||||
@ -470,7 +459,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
// first split the string on the delimiter to get all the entries
|
// first split the string on the delimiter to get all the entries
|
||||||
String[] names = tagInputField.getText().split(INPUT_DELIMITER);
|
String[] names = tagInputField.getText().split(INPUT_DELIMITER);
|
||||||
|
|
||||||
// trim each item to remove any leading/trailing whitespace and add to the return list
|
// trim each item to remove any leading/trailing whitespace and add to the return list
|
||||||
List<String> nameList = new ArrayList<>();
|
List<String> nameList = new ArrayList<>();
|
||||||
for (String name : names) {
|
for (String name : names) {
|
||||||
if (!StringUtils.isBlank(name)) {
|
if (!StringUtils.isBlank(name)) {
|
||||||
@ -483,7 +472,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the text-entry panel for adding new tag names.
|
* Creates the text-entry panel for adding new tag names.
|
||||||
*
|
*
|
||||||
* @return the new text input panel
|
* @return the new text input panel
|
||||||
*/
|
*/
|
||||||
private JPanel createInputPanel() {
|
private JPanel createInputPanel() {
|
||||||
|
Loading…
Reference in New Issue
Block a user