Merge remote-tracking branch

'origin/GP-3683-dragonmacher-function-tags-nav-2' into patch
(Closes #5613)
This commit is contained in:
Ryan Kurtz 2023-08-04 13:15:54 -04:00
commit d39caa5f44
3 changed files with 45 additions and 77 deletions

View File

@ -26,21 +26,21 @@ import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation;
/**
* Presents the user with a {@link ComponentProvider} showing all function tags available,
* along with all those currently assigned to the selected function.
* Presents the user with a {@link ComponentProvider} showing all function tags available,along with
* all those currently assigned to the selected function.
* <p>
* Users may select, deselect, edit or delete tags.
*/
public class EditFunctionTagsAction extends ListingContextAction {
private FunctionTagPlugin plugin;
// Menu option that will show up when right-clicking on a function in
// the listing.
// Menu option that will show up when right-clicking on a function in the listing
private final String MENU_LABEL = "Edit Tags...";
/**
* Constructor.
*
*
* @param name the name for this action.
* @param plugin the plugin this action is associated with.
*/
@ -57,10 +57,6 @@ public class EditFunctionTagsAction extends ListingContextAction {
setEnabled(true);
}
/******************************************************************************
* PUBLIC METHODS
******************************************************************************/
@Override
public void actionPerformed(ListingActionContext context) {
@ -74,25 +70,22 @@ public class EditFunctionTagsAction extends ListingContextAction {
showProvider(context);
}
/******************************************************************************
* PROTECTED METHODS
******************************************************************************/
/**
* Overridden to only allow this menu option when clicking in a function.
* Note that we do not allow external functions to have tags.
*
*
* @param context the listing context
* @return
* @return true if enabled
*/
@Override
protected boolean isEnabledForContext(ListingActionContext context) {
if (context.hasSelection() || context.getAddress() == null) {
Address address = context.getAddress();
if (context.hasSelection() || address == null) {
return false;
}
if (context.getLocation().getAddress().isExternalAddress()) {
if (address.isExternalAddress()) {
return false;
}
@ -104,12 +97,9 @@ public class EditFunctionTagsAction extends ListingContextAction {
return !funcAddress.isExternalAddress();
}
/******************************************************************************
* PRIVATE METHODS
******************************************************************************/
/**
* Retrieves the address of the function associated with the given program location.
*
*
* @param loc the program location
* @return the entry point of the function, or null if not valid
*/
@ -126,7 +116,7 @@ public class EditFunctionTagsAction extends ListingContextAction {
/**
* Displays the provider.
*
*
* @param context the listing context
*/
private void showProvider(ListingActionContext context) {

View File

@ -26,9 +26,9 @@ import ghidra.program.util.ProgramLocation;
/**
* 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.
*
*
*/
//@formatter:off
@PluginInfo(
@ -51,17 +51,11 @@ public class FunctionTagPlugin extends ProgramPlugin {
public FunctionTagPlugin(PluginTool tool) {
super(tool);
provider = new FunctionTagProvider(this, getCurrentProgram());
createActions();
}
/******************************************************************************
* PUBLIC METHODS
******************************************************************************/
/**
* Returns the component provider for this plugin
*
*
* @return the component provider
*/
public FunctionTagProvider getProvider() {
@ -71,11 +65,10 @@ public class FunctionTagPlugin extends ProgramPlugin {
@Override
public void init() {
super.init();
}
/******************************************************************************
* PROTECTED METHODS
******************************************************************************/
provider = new FunctionTagProvider(this, getCurrentProgram());
createActions();
}
@Override
protected void programDeactivated(Program program) {
@ -92,10 +85,6 @@ public class FunctionTagPlugin extends ProgramPlugin {
provider.locationChanged(loc);
}
/******************************************************************************
* PRIVATE METHODS
******************************************************************************/
private void createActions() {
editFunctionTagsAction = new EditFunctionTagsAction("Edit Function Tags", this);
tool.addAction(editFunctionTagsAction);

View File

@ -50,14 +50,13 @@ import resources.ResourceManager;
* <LI>Edit tags (both name and comment)</LI>
* <LI>Delete tags</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>
* 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
* "Window" menu.
*/
public class FunctionTagProvider extends ComponentProviderAdapter
implements DomainObjectListener {
public class FunctionTagProvider extends ComponentProviderAdapter implements DomainObjectListener {
private SourceTagsPanel sourcePanel;
private TargetTagsPanel targetPanel;
@ -75,37 +74,37 @@ public class FunctionTagProvider extends ComponentProviderAdapter
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;
// Character used as a separator when entering multiple tags in
// the create tag entry field.
private static final String INPUT_DELIMITER = ",";
/**
* 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,
/**
* 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,
* they will be loaded. The file must be XML with the following
* structure:
*
*
* <tags>
* <tag>
* <name>TAG1</name>
* <comment>tag comment</comment>
* </tag>
* </tags>
*
* </tags>
*
*/
private static String TAG_FILE = "functionTags.xml";
// 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
// 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
// this we would need to reload from file on each new program activation.
private Set<FunctionTag> tagsFromFile;
/**
* Constructor
*
*
* @param plugin the function tag plugin
* @param program the current program
*/
@ -118,10 +117,6 @@ public class FunctionTagProvider extends ComponentProviderAdapter
addToTool();
}
/******************************************************************************
* PUBLIC METHODS
******************************************************************************/
@Override
public void componentShown() {
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
* at the current location.
*
*
* @param loc the address selected in the listing
*/
public void locationChanged(ProgramLocation loc) {
@ -158,12 +153,6 @@ public class FunctionTagProvider extends ComponentProviderAdapter
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
public void domainObjectChanged(DomainObjectChangedEvent ev) {
@ -244,8 +233,8 @@ public class FunctionTagProvider extends ComponentProviderAdapter
allFunctionsPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
// 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
// because of the amount of text displayed. Keep the minimum size setting on
// 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
// the source panel, however. That is generally small.
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
* tag lists. Also updates the {@link AllFunctionsPanel} so it can update
* its list.
*
*
* @param panel the panel that generated the selection event
*/
public void selectionChanged(TagListPanel panel) {
@ -330,7 +319,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
/**
* Loads tags from the external file specified.
*
*
* @return the loaded tags
*/
private Set<FunctionTag> getFileTags() {
@ -342,7 +331,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
/**
* Returns an array of all tags stored in the database.
*
*
* @return list of tags
*/
private List<? extends FunctionTag> getAllTagsFromDatabase() {
@ -355,7 +344,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
/**
* Returns the {@link Function} for the given program location
*
*
* @param loc the program location
* @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.
*
*
* @param loc the program location
* @return the entry point of the function, or null if not valid
*/
@ -408,7 +397,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
targetPanel.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.
Set<FunctionTag> sTags = sourcePanel.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() {
@ -462,7 +451,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
/**
* Returns a list of tag names the user has entered in the input` field.
* Note: This assumes that multiple entries are comma-delimited.
*
*
* @return the list of tag names to create
*/
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
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<>();
for (String name : names) {
if (!StringUtils.isBlank(name)) {
@ -483,7 +472,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter
/**
* Creates the text-entry panel for adding new tag names.
*
*
* @return the new text input panel
*/
private JPanel createInputPanel() {