mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GT-2999: fixed how comparison action is set to SHARED
This commit is contained in:
parent
ec7773b464
commit
496408f2b7
23 changed files with 264 additions and 217 deletions
|
@ -15,7 +15,7 @@
|
|||
functions in a simple side-by-side panel. </P>
|
||||
|
||||
<P>To begin, select a function (or multiple functions) from the listing or
|
||||
the function table. Then right-click and select the <b>Compare Selected
|
||||
the <A HREF="help/topics/FunctionWindowPlugin/function_window.htm">function table</a>. Then right-click and select the <b>Compare Selected
|
||||
Functions</b> option.</P>
|
||||
|
||||
<P><A name="Dual_Listing"></A>A new function comparison window will appear (subsequent
|
||||
|
|
|
@ -142,6 +142,17 @@ class FunctionComparisonData {
|
|||
return function != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class holds no function, data or address set
|
||||
* information
|
||||
*
|
||||
* @return true if this class holds no function, data or address set
|
||||
* information
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return function == null && data == null && addressSet == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all fields in this model to a nominal state
|
||||
*/
|
||||
|
@ -151,4 +162,23 @@ class FunctionComparisonData {
|
|||
this.addressSet = new AddressSet();
|
||||
this.program = null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
if (function != null) {
|
||||
str = function.getName();
|
||||
}
|
||||
else if (data != null) {
|
||||
str = data.getAddress().toString();
|
||||
}
|
||||
else if (addressSet != null) {
|
||||
str = addressSet.toString();
|
||||
}
|
||||
else {
|
||||
str = "none";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,21 +167,6 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the functions in the left/right panels if they are in the
|
||||
* given set
|
||||
*
|
||||
* @param functions the functions to remove
|
||||
*/
|
||||
public void removeFunctions(Set<Function> functions) {
|
||||
if (functions.contains(leftComparisonData.getFunction())) {
|
||||
setLeftFunction(null);
|
||||
}
|
||||
if (functions.contains(rightComparisonData.getFunction())) {
|
||||
setRightFunction(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions for this FunctionComparisonPanel
|
||||
*
|
||||
|
@ -204,16 +189,16 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
Data rightData = rightComparisonData.getData();
|
||||
|
||||
if (leftFunc != null && rightFunc != null) {
|
||||
return "Function comparison of " + leftFunc.getName(true) + " & " +
|
||||
return leftFunc.getName(true) + " & " +
|
||||
rightFunc.getName(true);
|
||||
}
|
||||
if (leftData != null && rightData != null) {
|
||||
return "Function comparison of " + leftData.getDataType().getName() + " & " +
|
||||
return leftData.getDataType().getName() + " & " +
|
||||
rightData.getDataType().getName();
|
||||
}
|
||||
|
||||
// Otherwise give a simple description for address sets
|
||||
return "Function comparison";
|
||||
return "Nothing selected";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,20 +218,20 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the comparison window has no functions to display in
|
||||
* Returns true if the comparison window has no information to display in
|
||||
* either the left or right panel
|
||||
*
|
||||
* @return true if the comparison window has no functions to display
|
||||
* @return true if the comparison window has no information to display
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return getLeftFunction() == null || getRightFunction() == null;
|
||||
return leftComparisonData.isEmpty() || rightComparisonData.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ListingCodeComparisonPanel being displayed by this panel
|
||||
* if one exists
|
||||
*
|
||||
* @return the ListingCodeComparisonPanel or null
|
||||
* @return the comparison panel or null
|
||||
*/
|
||||
public ListingCodeComparisonPanel getDualListingPanel() {
|
||||
for (CodeComparisonPanel<? extends FieldPanelCoordinator> codeComparisonPanel : codeComparisonPanels) {
|
||||
|
@ -258,9 +243,6 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a new tab on the panel has been selected
|
||||
*/
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
tabChanged();
|
||||
|
@ -388,6 +370,24 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the comparison data object for the left panel
|
||||
*
|
||||
* @return the comparison data object for the left panel
|
||||
*/
|
||||
public FunctionComparisonData getLeftComparisonData() {
|
||||
return leftComparisonData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the comparison data object for the right panel
|
||||
*
|
||||
* @return the comparison data object for the right panel
|
||||
*/
|
||||
public FunctionComparisonData getRightComparisonData() {
|
||||
return rightComparisonData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function currently displayed in the left side of this panel
|
||||
*
|
||||
|
@ -634,25 +634,6 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
toggleScrollLockAction = new ToggleScrollLockAction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator that lets CodeComparisonPanels be sorted based on their
|
||||
* title names
|
||||
*/
|
||||
private class CodeComparisonPanelComparator
|
||||
implements Comparator<CodeComparisonPanel<? extends FieldPanelCoordinator>> {
|
||||
|
||||
@Override
|
||||
public int compare(CodeComparisonPanel<? extends FieldPanelCoordinator> o1,
|
||||
CodeComparisonPanel<? extends FieldPanelCoordinator> o2) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
}
|
||||
String title1 = o1.getTitle();
|
||||
String title2 = o2.getTitle();
|
||||
return title1.compareTo(title2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action that sets the scrolling state of the comparison panels
|
||||
*/
|
||||
|
@ -716,10 +697,7 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Sort the list of code comparison panels so they display in the same order
|
||||
// each time for the user.
|
||||
CodeComparisonPanelComparator comparator = new CodeComparisonPanelComparator();
|
||||
codeComparisonPanels.sort(comparator);
|
||||
codeComparisonPanels.sort((p1, p2) -> p1.getTitle().compareTo(p2.getTitle()));
|
||||
}
|
||||
return codeComparisonPanels;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ public class FunctionComparisonPlugin extends ProgramPlugin
|
|||
|
||||
@Override
|
||||
protected void init() {
|
||||
CompareFunctionsAction compareFunctionsAction = new CompareFunctionsFromListingAction(tool);
|
||||
CompareFunctionsAction compareFunctionsAction =
|
||||
new CompareFunctionsFromListingAction(tool, getName());
|
||||
tool.addAction(compareFunctionsAction);
|
||||
}
|
||||
|
||||
|
@ -132,6 +133,12 @@ public class FunctionComparisonPlugin extends ProgramPlugin
|
|||
functionComparisonManager.addProviderListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFunctionComparisonProviderListener(
|
||||
ComponentProviderActivationListener listener) {
|
||||
functionComparisonManager.removeProviderListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFunction(Function function) {
|
||||
functionComparisonManager.removeFunction(function);
|
||||
|
|
|
@ -125,7 +125,7 @@ public class FunctionComparisonProvider extends ComponentProviderAdapter
|
|||
public void modelChanged(List<FunctionComparison> model) {
|
||||
this.model.setComparisons(model);
|
||||
functionComparisonPanel.reload();
|
||||
setTabText(functionComparisonPanel);
|
||||
setTabText(functionComparisonPanel.getDescription());
|
||||
closeIfEmpty();
|
||||
}
|
||||
|
||||
|
@ -225,25 +225,12 @@ public class FunctionComparisonProvider extends ComponentProviderAdapter
|
|||
functionComparisonPanel.writeConfigState(getName(), saveState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the text that is displayed on the tab for this provider
|
||||
*
|
||||
* @param comparisonPanel the function comparison panel for this provider
|
||||
*/
|
||||
public void setTabText(FunctionComparisonPanel comparisonPanel) {
|
||||
Function leftFunction = comparisonPanel.getLeftFunction();
|
||||
Function rightFunction = comparisonPanel.getRightFunction();
|
||||
String tabText = (leftFunction == null && rightFunction == null) ? "No Functions Yet"
|
||||
: getTabText(leftFunction, rightFunction);
|
||||
setTabText(tabText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform initialization for this provider and its panel
|
||||
*/
|
||||
protected void initFunctionComparisonPanel() {
|
||||
setTransient();
|
||||
setTabText(functionComparisonPanel);
|
||||
setTabText(functionComparisonPanel.getDescription());
|
||||
addSpecificCodeComparisonActions();
|
||||
tool.addPopupActionProvider(this);
|
||||
setHelpLocation(new HelpLocation(HELP_TOPIC, "Function Comparison"));
|
||||
|
@ -267,19 +254,6 @@ public class FunctionComparisonProvider extends ComponentProviderAdapter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text that should be displayed in the tab, given the two
|
||||
* left/right functions
|
||||
*
|
||||
* @param leftFunction
|
||||
* @param rightFunction
|
||||
* @return the tab text
|
||||
*/
|
||||
private String getTabText(Function leftFunction, Function rightFunction) {
|
||||
return ((leftFunction != null) ? leftFunction.getName() : "none") + " & " +
|
||||
((rightFunction != null) ? rightFunction.getName() : "none");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets actions specific to the code comparison panel and adds them to this
|
||||
* provider
|
||||
|
|
|
@ -159,6 +159,16 @@ public class FunctionComparisonProviderManager implements FunctionComparisonProv
|
|||
listeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a subscriber who no longer wishes to receive provider activation
|
||||
* events
|
||||
*
|
||||
* @param listener the subscriber to remove
|
||||
*/
|
||||
public void removeProviderListener(ComponentProviderActivationListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all the comparison providers that contain a function from
|
||||
* the given program
|
||||
|
|
|
@ -66,7 +66,7 @@ public class MultiFunctionComparisonPanel extends FunctionComparisonPanel {
|
|||
* @param provider the comparison provider associated with this panel
|
||||
* @param tool the active plugin tool
|
||||
*/
|
||||
public MultiFunctionComparisonPanel(FunctionComparisonProvider provider,
|
||||
public MultiFunctionComparisonPanel(MultiFunctionComparisonProvider provider,
|
||||
PluginTool tool) {
|
||||
super(provider, tool, null, null);
|
||||
|
||||
|
@ -81,16 +81,6 @@ public class MultiFunctionComparisonPanel extends FunctionComparisonPanel {
|
|||
getComparisonPanels().forEach(p -> p.setShowTitles(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the given functions from the comparison panel (both the
|
||||
* source and target lists) (the default for this method is to only clear
|
||||
* out the functions visible in the left/right panels)
|
||||
*/
|
||||
@Override
|
||||
public void removeFunctions(Set<Function> functions) {
|
||||
((MultiFunctionComparisonProvider) provider).removeFunctions(functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the source and targets lists and reloads them to
|
||||
* ensure that they reflect the current state of the data model. Any
|
||||
|
@ -105,9 +95,7 @@ public class MultiFunctionComparisonPanel extends FunctionComparisonPanel {
|
|||
reloadTargetList(selectedSource);
|
||||
loadFunctions(selectedSource, (Function) targetFunctionsCBModel.getSelectedItem());
|
||||
|
||||
((FunctionComparisonProvider) provider).setTabText(this);
|
||||
((FunctionComparisonProvider) provider)
|
||||
.setTitle(((FunctionComparisonProvider) provider).getTabText());
|
||||
updateTabText();
|
||||
|
||||
// Fire a notification to update the UI state; without this the
|
||||
// actions would not be properly enabled/disabled
|
||||
|
@ -181,6 +169,16 @@ public class MultiFunctionComparisonPanel extends FunctionComparisonPanel {
|
|||
restoreSelection(targetFunctionsCB, selection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text on the current tab to match whatever is displayed in the
|
||||
* comparison panels
|
||||
*/
|
||||
private void updateTabText() {
|
||||
String tabText = getDescription();
|
||||
provider.setTabText(tabText);
|
||||
provider.setTitle(tabText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a given function to be the selected item in a given combo
|
||||
* box. If the function isn't found, the first item in the box is
|
||||
|
@ -238,6 +236,8 @@ public class MultiFunctionComparisonPanel extends FunctionComparisonPanel {
|
|||
// to load the targets associated with it
|
||||
reloadTargetList((Function) sourceFunctionsCBModel.getSelectedItem());
|
||||
|
||||
updateTabText();
|
||||
|
||||
// Fire a notification to update the UI state; without this the
|
||||
// actions would not be properly enabled/disabled
|
||||
tool.contextChanged(provider);
|
||||
|
@ -275,6 +275,8 @@ public class MultiFunctionComparisonPanel extends FunctionComparisonPanel {
|
|||
Function selected = (Function) targetFunctionsCBModel.getSelectedItem();
|
||||
loadFunctions((Function) sourceFunctionsCBModel.getSelectedItem(), selected);
|
||||
|
||||
updateTabText();
|
||||
|
||||
// Fire a notification to update the UI state; without this the
|
||||
// actions would not be properly enabled/disabled
|
||||
tool.contextChanged(provider);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.functioncompare.actions;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
@ -57,9 +58,10 @@ public abstract class CompareFunctionsAction extends DockingAction {
|
|||
* Constructor
|
||||
*
|
||||
* @param tool the plugin tool
|
||||
* @param owner the action owner (usually the plugin name)
|
||||
*/
|
||||
public CompareFunctionsAction(PluginTool tool) {
|
||||
super("Compare Functions", tool.getName());
|
||||
public CompareFunctionsAction(PluginTool tool, String owner) {
|
||||
super("Compare Functions", owner, KeyBindingType.SHARED);
|
||||
this.comparisonService = tool.getService(FunctionComparisonService.class);
|
||||
setActionAttributes();
|
||||
}
|
||||
|
@ -101,5 +103,8 @@ public abstract class CompareFunctionsAction extends DockingAction {
|
|||
new ToolBarData(getToolBarIcon(), CREATE_COMPARISON_GROUP);
|
||||
setToolBarData(newToolBarData);
|
||||
setHelpLocation(new HelpLocation("FunctionComparison", "Function_Comparison"));
|
||||
|
||||
KeyBindingData data = new KeyBindingData('C', InputEvent.SHIFT_DOWN_MASK);
|
||||
setKeyBindingData(data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import docking.ActionContext;
|
|||
import ghidra.app.plugin.core.functionwindow.FunctionRowObject;
|
||||
import ghidra.app.plugin.core.functionwindow.FunctionTableModel;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.util.table.GhidraTable;
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,10 @@ public class CompareFunctionsFromFunctionTableAction extends CompareFunctionsAct
|
|||
* Constructor
|
||||
*
|
||||
* @param tool the plugin tool
|
||||
* @param owner the action owner
|
||||
*/
|
||||
public CompareFunctionsFromFunctionTableAction(PluginTool tool) {
|
||||
super(tool);
|
||||
public CompareFunctionsFromFunctionTableAction(PluginTool tool, String owner) {
|
||||
super(tool, owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,12 +67,9 @@ public class CompareFunctionsFromFunctionTableAction extends CompareFunctionsAct
|
|||
return Collections.emptySet();
|
||||
}
|
||||
FunctionTableModel model = (FunctionTableModel) table.getModel();
|
||||
Program program = model.getProgram();
|
||||
FunctionManager functionManager = program.getFunctionManager();
|
||||
List<FunctionRowObject> functionRowObjects = model.getRowObjects(selectedRows);
|
||||
for (FunctionRowObject functionRowObject : functionRowObjects) {
|
||||
long key = functionRowObject.getKey();
|
||||
Function rowFunction = functionManager.getFunction(key);
|
||||
Function rowFunction = functionRowObject.getFunction();
|
||||
functions.add(rowFunction);
|
||||
}
|
||||
return functions;
|
||||
|
|
|
@ -34,9 +34,10 @@ public class CompareFunctionsFromListingAction extends CompareFunctionsAction {
|
|||
* Constructor
|
||||
*
|
||||
* @param tool the plugin tool
|
||||
* @param owner the action owner
|
||||
*/
|
||||
public CompareFunctionsFromListingAction(PluginTool tool) {
|
||||
super(tool);
|
||||
public CompareFunctionsFromListingAction(PluginTool tool, String owner) {
|
||||
super(tool, owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -93,6 +93,5 @@ public class NextFunctionAction extends DockingAction {
|
|||
MultiFunctionComparisonPanel panel = (MultiFunctionComparisonPanel) provider.getComponent();
|
||||
JComboBox<Function> focusedComponent = panel.getFocusedComponent();
|
||||
focusedComponent.setSelectedIndex(focusedComponent.getSelectedIndex() + 1);
|
||||
provider.contextChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.functioncompare.actions;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -34,7 +35,6 @@ import ghidra.framework.plugintool.PluginTool;
|
|||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import resources.MultiIcon;
|
||||
import resources.ResourceManager;
|
||||
import resources.icons.ScaledImageIconWrapper;
|
||||
|
@ -86,6 +86,9 @@ public class OpenFunctionTableAction extends DockingAction {
|
|||
HelpLocation helpLocation = new HelpLocation(MultiFunctionComparisonPanel.HELP_TOPIC,
|
||||
"Add_To_Comparison");
|
||||
setHelpLocation(helpLocation);
|
||||
|
||||
KeyBindingData data = new KeyBindingData('A', InputEvent.SHIFT_DOWN_MASK);
|
||||
setKeyBindingData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,27 +98,27 @@ public class OpenFunctionTableAction extends DockingAction {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
Runnable runnable = () -> {
|
||||
FunctionComparisonProvider provider =
|
||||
(FunctionComparisonProvider) context.getComponentProvider();
|
||||
Program currentProgram = programManagerService.getCurrentProgram();
|
||||
FunctionTableModel model = new FunctionTableModel(tool, currentProgram);
|
||||
model.reload(programManagerService.getCurrentProgram());
|
||||
if (!(context.getComponentProvider() instanceof FunctionComparisonProvider)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TableChooserDialog<FunctionRowObject> diag =
|
||||
new TableChooserDialog<>("Select Functions: " + currentProgram.getName(),
|
||||
model, true);
|
||||
tool.showDialog(diag);
|
||||
List<FunctionRowObject> rows = diag.getSelectionItems();
|
||||
if (CollectionUtils.isBlank(rows)) {
|
||||
return; // the table chooser can return null if the operation was cancelled
|
||||
}
|
||||
FunctionComparisonProvider provider =
|
||||
(FunctionComparisonProvider) context.getComponentProvider();
|
||||
Program currentProgram = programManagerService.getCurrentProgram();
|
||||
FunctionTableModel model = new FunctionTableModel(tool, currentProgram);
|
||||
model.reload(programManagerService.getCurrentProgram());
|
||||
|
||||
Set<Function> functions =
|
||||
rows.stream().map(row -> row.getFunction()).collect(Collectors.toSet());
|
||||
comparisonService.compareFunctions(new HashSet<>(functions), provider);
|
||||
};
|
||||
TableChooserDialog<FunctionRowObject> diag =
|
||||
new TableChooserDialog<>("Select Functions: " + currentProgram.getName(),
|
||||
model, true);
|
||||
tool.showDialog(diag);
|
||||
List<FunctionRowObject> rows = diag.getSelectionItems();
|
||||
if (CollectionUtils.isBlank(rows)) {
|
||||
return; // the table chooser can return null if the operation was cancelled
|
||||
}
|
||||
|
||||
SystemUtilities.runSwingLater(runnable);
|
||||
Set<Function> functions =
|
||||
rows.stream().map(row -> row.getFunction()).collect(Collectors.toSet());
|
||||
comparisonService.compareFunctions(new HashSet<>(functions), provider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,5 @@ public class PreviousFunctionAction extends DockingAction {
|
|||
MultiFunctionComparisonPanel panel = (MultiFunctionComparisonPanel) provider.getComponent();
|
||||
JComboBox<Function> focusedComponent = panel.getFocusedComponent();
|
||||
focusedComponent.setSelectedIndex(focusedComponent.getSelectedIndex() - 1);
|
||||
provider.contextChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ import ghidra.util.task.SwingUpdateManager;
|
|||
category = PluginCategoryNames.CODE_VIEWER,
|
||||
shortDescription = "Function Viewer",
|
||||
description = "Provides a window that displays the list of functions in the program.",
|
||||
servicesRequired = { FunctionComparisonService.class },
|
||||
eventsConsumed = { ProgramClosedPluginEvent.class }
|
||||
)
|
||||
//@formatter:on
|
||||
|
@ -78,9 +77,7 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
|
|||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
provider = new FunctionWindowProvider(this);
|
||||
functionComparisonService = tool.getService(FunctionComparisonService.class);
|
||||
createActions();
|
||||
|
||||
/**
|
||||
|
@ -90,11 +87,6 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
|
|||
provider.getTable().getSelectionModel().addListSelectionListener(x -> {
|
||||
tool.contextChanged(provider);
|
||||
});
|
||||
|
||||
// Listen for providers being opened/closed to we can disable the
|
||||
// add-to-comparison action if there are no comparison windows
|
||||
// open.
|
||||
functionComparisonService.addFunctionComparisonProviderListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,6 +101,26 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serviceAdded(Class<?> interfaceClass, Object service) {
|
||||
if (interfaceClass == FunctionComparisonService.class) {
|
||||
functionComparisonService = (FunctionComparisonService) service;
|
||||
|
||||
// Listen for providers being opened/closed to we can disable
|
||||
// comparison actions if there are no comparison providers
|
||||
// open
|
||||
functionComparisonService.addFunctionComparisonProviderListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serviceRemoved(Class<?> interfaceClass, Object service) {
|
||||
if (interfaceClass == FunctionComparisonService.class) {
|
||||
functionComparisonService.removeFunctionComparisonProviderListener(this);
|
||||
functionComparisonService = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||
|
||||
|
@ -205,24 +217,10 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
|
|||
selectAction = new MakeProgramSelectionAction(this, provider.getTable());
|
||||
tool.addLocalAction(provider, selectAction);
|
||||
|
||||
compareFunctionsAction = new CompareFunctionsFromFunctionTableAction(tool);
|
||||
compareFunctionsAction = new CompareFunctionsFromFunctionTableAction(tool, getName());
|
||||
tool.addLocalAction(provider, compareFunctionsAction);
|
||||
}
|
||||
|
||||
// private void installDummyAction(DockingAction action) {
|
||||
// DummyKeyBindingsOptionsAction dummyAction =
|
||||
// new DummyKeyBindingsOptionsAction(action.getName(), null);
|
||||
// tool.addAction(dummyAction);
|
||||
//
|
||||
// ToolOptions options = tool.getOptions(DockingToolConstants.KEY_BINDINGS);
|
||||
// options.addOptionsChangeListener(this);
|
||||
//
|
||||
// KeyStroke keyStroke = options.getKeyStroke(dummyAction.getFullName(), null);
|
||||
// if (keyStroke != null) {
|
||||
// action.setUnvalidatedKeyBindingData(new KeyBindingData(keyStroke));
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
|
||||
Object newValue) {
|
||||
|
@ -237,11 +235,6 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
|
|||
}
|
||||
}
|
||||
|
||||
void setActionsEnabled(boolean enabled) {
|
||||
selectAction.setEnabled(enabled);
|
||||
compareFunctionsAction.setEnabled(enabled);
|
||||
}
|
||||
|
||||
void showFunctions() {
|
||||
provider.showFunctions();
|
||||
}
|
||||
|
|
|
@ -128,9 +128,7 @@ public class FunctionWindowProvider extends ComponentProviderAdapter {
|
|||
functionTable.setPreferredScrollableViewportSize(new Dimension(350, 150));
|
||||
functionTable.setRowSelectionAllowed(true);
|
||||
functionTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
functionTable.getSelectionModel()
|
||||
.addListSelectionListener(
|
||||
e -> plugin.setActionsEnabled(functionTable.getSelectedRowCount() > 0));
|
||||
functionTable.getSelectionModel().addListSelectionListener(e -> tool.contextChanged(this));
|
||||
|
||||
functionModel.addTableModelListener(e -> {
|
||||
int rowCount = functionModel.getRowCount();
|
||||
|
|
|
@ -27,7 +27,6 @@ import ghidra.app.plugin.core.functioncompare.*;
|
|||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
|
||||
/**
|
||||
|
@ -114,7 +113,7 @@ public class FunctionComparisonModel {
|
|||
* Note: It is assumed that when using this method, all functions can be
|
||||
* compared with all other functions; meaning each function will be added as
|
||||
* both a source AND a target. To specify a specific source/target
|
||||
* relationship, see {@link #compareFunctions(Function, Function)}.
|
||||
* relationship, use {@link #compareFunctions(Function, Function)}.
|
||||
*
|
||||
* @param functions the set of functions to compare
|
||||
*/
|
||||
|
@ -295,13 +294,11 @@ public class FunctionComparisonModel {
|
|||
|
||||
// Now loop over the given functions and create new comparisons
|
||||
for (Function f : functions) {
|
||||
try {
|
||||
monitor.checkCanceled();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
if (monitor.isCancelled()) {
|
||||
Msg.info(this, "Function comparison operation cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionComparison fc = new FunctionComparison();
|
||||
fc.setSource(f);
|
||||
fc.addTargets(functions);
|
||||
|
|
|
@ -25,14 +25,24 @@ import ghidra.program.model.listing.Function;
|
|||
|
||||
/**
|
||||
* Allows users to create comparisons between functions which will be displayed
|
||||
* side-by-side in a {@link FunctionComparisonProvider}
|
||||
* side-by-side in a {@link FunctionComparisonProvider}. Each side in the
|
||||
* display will allow the user to select one or more functions
|
||||
*/
|
||||
@ServiceInfo(defaultProvider = FunctionComparisonPlugin.class)
|
||||
public interface FunctionComparisonService {
|
||||
|
||||
/**
|
||||
* Creates a comparison between a set of functions, where each function
|
||||
* in the list can be compared against any other function in the list
|
||||
* in the list can be compared against any other.
|
||||
* <p>
|
||||
* eg: Given a set of 3 functions (f1, f2, f3), the comparison dialog will
|
||||
* allow the user to display either f1, f2 or f3 on EITHER side of the
|
||||
* comparison.
|
||||
* <p>
|
||||
* Note that this method will always create a new provider; if you want to
|
||||
* add functions to an existing comparison, use
|
||||
* {@link #compareFunctions(Set, FunctionComparisonProvider) this}
|
||||
* variant that takes a provider.
|
||||
*
|
||||
* @param functions the functions to compare
|
||||
* @return the new comparison provider
|
||||
|
@ -40,7 +50,14 @@ public interface FunctionComparisonService {
|
|||
public FunctionComparisonProvider compareFunctions(Set<Function> functions);
|
||||
|
||||
/**
|
||||
* Creates a comparison between two functions
|
||||
* Creates a comparison between two functions, where the source function
|
||||
* will be shown on the left side of the comparison dialog and the target
|
||||
* on the right.
|
||||
* <p>
|
||||
* Note that this will always create a new provider; if you want to add
|
||||
* functions to an existing comparison, use
|
||||
* {@link #compareFunctions(Function, Function, FunctionComparisonProvider) this}
|
||||
* variant that takes a provider.
|
||||
*
|
||||
* @param source a function in the comparison
|
||||
* @param target a function in the comparison
|
||||
|
@ -51,8 +68,11 @@ public interface FunctionComparisonService {
|
|||
|
||||
/**
|
||||
* Creates a comparison between a set of functions, adding them to the
|
||||
* given comparison provider
|
||||
* given comparison provider. Each function in the given set will be added
|
||||
* to both sides of the comparison, allowing users to compare any functions
|
||||
* in the existing provider with the new set.
|
||||
*
|
||||
* @see #compareFunctions(Set)
|
||||
* @param functions the functions to compare
|
||||
* @param provider the provider to add the comparisons to
|
||||
*/
|
||||
|
@ -61,8 +81,12 @@ public interface FunctionComparisonService {
|
|||
|
||||
/**
|
||||
* Creates a comparison between two functions and adds it to a given
|
||||
* comparison provider
|
||||
* comparison provider. The existing comparisons in the provider will not
|
||||
* be affected, unless the provider already contains a comparison with
|
||||
* the same source function; in this case the given target will be added
|
||||
* to that comparisons' list of targets.
|
||||
*
|
||||
* @see #compareFunctions(Function, Function)
|
||||
* @param source a function in the comparison
|
||||
* @param target a function in the comparison
|
||||
* @param provider the provider to add the comparison to
|
||||
|
@ -80,7 +104,7 @@ public interface FunctionComparisonService {
|
|||
|
||||
/**
|
||||
* Removes a given function from all comparisons in the given comparison
|
||||
* provider
|
||||
* provider only
|
||||
*
|
||||
* @param function the function to remove
|
||||
* @param provider the comparison provider to remove functions from
|
||||
|
@ -94,4 +118,12 @@ public interface FunctionComparisonService {
|
|||
* @param listener the listener to be added
|
||||
*/
|
||||
public void addFunctionComparisonProviderListener(ComponentProviderActivationListener listener);
|
||||
|
||||
/**
|
||||
* Removes a listener from the list of provider activation event subscribers
|
||||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeFunctionComparisonProviderListener(
|
||||
ComponentProviderActivationListener listener);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ import ghidra.util.classfinder.ExtensionPoint;
|
|||
* discovered by the {@link FunctionComparisonPanel} class and included as a
|
||||
* form of comparing two sections of code within the same or different programs
|
||||
* <p>
|
||||
* NOTE: ALL CodeComparisonPanel CLASSES MUST END IN <
|
||||
* code>CodeComparisonPanel</code> so they are discoverable by the
|
||||
* NOTE: ALL CodeComparisonPanel CLASSES MUST END IN
|
||||
* <code>CodeComparisonPanel</code> so they are discoverable by the
|
||||
* {@link ClassSearcher}
|
||||
*/
|
||||
public abstract class CodeComparisonPanel<T extends FieldPanelCoordinator> extends JPanel
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.functioncompare;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.awt.Window;
|
||||
import java.util.Date;
|
||||
|
@ -25,10 +27,10 @@ import javax.swing.JPanel;
|
|||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.widgets.dialogs.TableChooserDialog;
|
||||
import docking.widgets.table.GFilterTable;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.function.FunctionPlugin;
|
||||
import ghidra.app.plugin.core.functionwindow.FunctionRowObject;
|
||||
|
@ -46,7 +48,7 @@ import ghidra.test.TestEnv;
|
|||
* Tests for the {@link FunctionComparisonPlugin function comparison plugin}
|
||||
* that involve the GUI
|
||||
*/
|
||||
public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTest {
|
||||
public class CompareFunctionsSlowTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
private TestEnv env;
|
||||
private Program program1;
|
||||
|
@ -65,8 +67,6 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
plugin = env.addPlugin(FunctionComparisonPlugin.class);
|
||||
functionPlugin = env.addPlugin(FunctionPlugin.class);
|
||||
cbPlugin = env.addPlugin(CodeBrowserPlugin.class);
|
||||
assertNotNull(plugin);
|
||||
assertNotNull(functionPlugin);
|
||||
buildTestProgram1();
|
||||
buildTestProgram2();
|
||||
showTool(plugin.getTool());
|
||||
|
@ -84,7 +84,7 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
provider = plugin.compareFunctions(functions);
|
||||
provider = waitForComponentProvider(FunctionComparisonProvider.class);
|
||||
plugin.removeFunction(foo, provider);
|
||||
assert (!provider.isVisible());
|
||||
assertFalse(provider.isVisible());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -120,11 +120,15 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
DockingActionIf nextAction = getAction(plugin, "Compare Next Function");
|
||||
DockingActionIf prevAction = getAction(plugin, "Compare Previous Function");
|
||||
|
||||
assert (nextAction.isEnabled());
|
||||
assert (!prevAction.isEnabled());
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
assertTrue(nextAction.isEnabledForContext(context));
|
||||
assertFalse(prevAction.isEnabledForContext(context));
|
||||
|
||||
performAction(nextAction);
|
||||
assert (!nextAction.isEnabled());
|
||||
assert (prevAction.isEnabled());
|
||||
|
||||
context = provider.getActionContext(null);
|
||||
assertFalse(nextAction.isEnabledForContext(context));
|
||||
assertTrue(prevAction.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -141,11 +145,15 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
DockingActionIf nextAction = getAction(plugin, "Compare Next Function");
|
||||
DockingActionIf prevAction = getAction(plugin, "Compare Previous Function");
|
||||
|
||||
assert (nextAction.isEnabled());
|
||||
assert (!prevAction.isEnabled());
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
assertTrue(nextAction.isEnabledForContext(context));
|
||||
assertFalse(prevAction.isEnabledForContext(context));
|
||||
|
||||
performAction(nextAction);
|
||||
assert (!nextAction.isEnabled());
|
||||
assert (prevAction.isEnabled());
|
||||
|
||||
context = provider.getActionContext(null);
|
||||
assertFalse(nextAction.isEnabledForContext(context));
|
||||
assertTrue(prevAction.isEnabledForContext(context));
|
||||
|
||||
JPanel rightPanel =
|
||||
provider.getComponent().getDualListingPanel().getRightPanel().getFieldPanel();
|
||||
|
@ -153,8 +161,9 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
waitForSwing();
|
||||
provider.getComponent().updateActionEnablement();
|
||||
|
||||
assert (nextAction.isEnabled());
|
||||
assert (!prevAction.isEnabled());
|
||||
context = provider.getActionContext(null);
|
||||
assertTrue(nextAction.isEnabledForContext(context));
|
||||
assertFalse(prevAction.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -163,11 +172,15 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
provider = plugin.compareFunctions(functions);
|
||||
provider.setVisible(true);
|
||||
|
||||
// Must do this or the context for the action initiated below will be
|
||||
// for the listing, not the comparison provider
|
||||
clickComponentProvider(provider);
|
||||
|
||||
DockingActionIf openTableAction = getAction(plugin, "Add Functions To Comparison");
|
||||
performAction(openTableAction);
|
||||
|
||||
Window selectWindow = waitForWindowByTitleContaining("Select Functions");
|
||||
assert (selectWindow != null);
|
||||
assertNotNull(selectWindow);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -182,26 +195,26 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
// initiated below
|
||||
clickComponentProvider(provider);
|
||||
|
||||
assert (provider.getModel().getSourceFunctions().size() == 1);
|
||||
assert (provider.getModel().getSourceFunctions().contains(foo));
|
||||
assertTrue(provider.getModel().getSourceFunctions().size() == 1);
|
||||
assertTrue(provider.getModel().getSourceFunctions().contains(foo));
|
||||
|
||||
DockingActionIf openTableAction = getAction(plugin, "Add Functions To Comparison");
|
||||
performAction(openTableAction);
|
||||
|
||||
TableChooserDialog<FunctionTableModel> chooser =
|
||||
waitForDialogComponent(TableChooserDialog.class);
|
||||
assert (chooser != null);
|
||||
assertNotNull(chooser);
|
||||
|
||||
GFilterTable<FunctionRowObject> table =
|
||||
(GFilterTable<FunctionRowObject>) getInstanceField("gFilterTable", chooser);
|
||||
assert (table.getModel().getRowCount() == 2);
|
||||
assertTrue(table.getModel().getRowCount() == 2);
|
||||
clickTableCell(table.getTable(), 1, 0, 1);
|
||||
|
||||
pressButtonByText(chooser, "OK");
|
||||
waitForSwing();
|
||||
assert (provider.getModel().getSourceFunctions().size() == 2);
|
||||
assert (provider.getModel().getSourceFunctions().contains(foo));
|
||||
assert (provider.getModel().getSourceFunctions().contains(bat));
|
||||
assertTrue(provider.getModel().getSourceFunctions().size() == 2);
|
||||
assertTrue(provider.getModel().getSourceFunctions().contains(foo));
|
||||
assertTrue(provider.getModel().getSourceFunctions().contains(bat));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,9 +228,9 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
provider = plugin.compareFunctions(functions);
|
||||
provider.setVisible(true);
|
||||
|
||||
assert (provider.getModel().getSourceFunctions().size() == 2);
|
||||
assert (provider.getModel().getSourceFunctions().contains(foo));
|
||||
assert (provider.getModel().getSourceFunctions().contains(bar));
|
||||
assertTrue(provider.getModel().getSourceFunctions().size() == 2);
|
||||
assertTrue(provider.getModel().getSourceFunctions().contains(foo));
|
||||
assertTrue(provider.getModel().getSourceFunctions().contains(bar));
|
||||
|
||||
Address addr = program1.getAddressFactory().getAddress("10018cf");
|
||||
ProgramLocation loc = new ProgramLocation(program1, addr);
|
||||
|
@ -227,8 +240,8 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
|
||||
waitForSwing();
|
||||
|
||||
assert (provider.getModel().getSourceFunctions().size() == 1);
|
||||
assert (provider.getModel().getSourceFunctions().contains(bar));
|
||||
assertTrue(provider.getModel().getSourceFunctions().size() == 1);
|
||||
assertTrue(provider.getModel().getSourceFunctions().contains(bar));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,7 +259,6 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
bat = builder.createEmptyFunction("Bat", "100299e", 130, null, p, p, p);
|
||||
|
||||
program1 = builder.getProgram();
|
||||
AbstractGenericTest.setInstanceField("recordChanges", program1, Boolean.TRUE);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -264,7 +276,6 @@ public class CompareFunctionsTestSlow extends AbstractGhidraHeadedIntegrationTes
|
|||
bar = builder.createEmptyFunction("Bar", "10018cf", 10, null, p);
|
||||
|
||||
program2 = builder.getProgram();
|
||||
AbstractGenericTest.setInstanceField("recordChanges", program2, Boolean.TRUE);
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.functioncompare;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Date;
|
||||
|
@ -64,7 +64,6 @@ public class CompareFunctionsTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
public void setUp() throws Exception {
|
||||
DummyPluginTool tool = new DummyPluginTool();
|
||||
plugin = new FunctionComparisonPlugin(tool);
|
||||
assertNotNull(plugin);
|
||||
buildTestProgram1();
|
||||
buildTestProgram2();
|
||||
|
||||
|
@ -81,7 +80,7 @@ public class CompareFunctionsTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
public void testSetNoFunctions() throws Exception {
|
||||
Set<Function> functions = CompareFunctionsTestUtility.getFunctionsAsSet();
|
||||
FunctionComparisonProvider provider = plugin.compareFunctions(functions);
|
||||
assert (provider == null);
|
||||
assertNull(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.functioncompare;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.program.model.listing.Function;
|
||||
|
@ -23,7 +26,7 @@ import ghidra.program.model.listing.Function;
|
|||
* Helper methods for use with function comparison tests
|
||||
*
|
||||
* @see {@link CompareFunctionsTest}
|
||||
* @see {@link CompareFunctionsTestSlow}
|
||||
* @see {@link CompareFunctionsSlowTest}
|
||||
*/
|
||||
public class CompareFunctionsTestUtility {
|
||||
|
||||
|
@ -38,8 +41,8 @@ public class CompareFunctionsTestUtility {
|
|||
Function... functions) {
|
||||
Set<Function> funcs = new HashSet<>(Arrays.asList(functions));
|
||||
Set<Function> fcs = provider.getModel().getSourceFunctions();
|
||||
assert (fcs.size() == funcs.size());
|
||||
assert (fcs.containsAll(funcs));
|
||||
assertEquals(fcs.size(), funcs.size());
|
||||
assertTrue(fcs.containsAll(funcs));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,8 +57,8 @@ public class CompareFunctionsTestUtility {
|
|||
Function source, Function... targets) {
|
||||
Set<Function> targetsAsList = new HashSet<>(Arrays.asList(targets));
|
||||
Set<Function> tgts = provider.getModel().getTargetFunctions(source);
|
||||
assert (tgts.size() == targetsAsList.size());
|
||||
assert (tgts.containsAll(targetsAsList));
|
||||
assertEquals(tgts.size(), targetsAsList.size());
|
||||
assertTrue(tgts.containsAll(targetsAsList));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,8 +15,12 @@
|
|||
*/
|
||||
package ghidra.feature.vt.gui.provider.functionassociation;
|
||||
|
||||
import static ghidra.feature.vt.api.impl.VTChangeManager.*;
|
||||
import static ghidra.feature.vt.gui.provider.functionassociation.FilterSettings.*;
|
||||
import static ghidra.feature.vt.api.impl.VTChangeManager.DOCR_VT_ASSOCIATION_STATUS_CHANGED;
|
||||
import static ghidra.feature.vt.api.impl.VTChangeManager.DOCR_VT_MATCH_ADDED;
|
||||
import static ghidra.feature.vt.api.impl.VTChangeManager.DOCR_VT_MATCH_DELETED;
|
||||
import static ghidra.feature.vt.gui.provider.functionassociation.FilterSettings.SHOW_ALL;
|
||||
import static ghidra.feature.vt.gui.provider.functionassociation.FilterSettings.SHOW_UNACCEPTED;
|
||||
import static ghidra.feature.vt.gui.provider.functionassociation.FilterSettings.SHOW_UNMATCHED;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
@ -473,9 +477,11 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
|
||||
sourceFunctionsModel.addTableModelListener(new TitleUpdateListener());
|
||||
|
||||
sourceFunctionsTable.getColumnModel().getColumn(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL).setPreferredWidth(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL_WIDTH);
|
||||
sourceFunctionsTable.getColumnModel()
|
||||
.getColumn(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL)
|
||||
.setPreferredWidth(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL_WIDTH);
|
||||
|
||||
sourceTableFilterPanel =
|
||||
new GhidraTableFilterPanel<>(sourceFunctionsTable, sourceFunctionsModel);
|
||||
|
@ -530,9 +536,11 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
JTableHeader functionHeader = destinationFunctionsTable.getTableHeader();
|
||||
functionHeader.setUpdateTableInRealTime(true);
|
||||
|
||||
destinationFunctionsTable.getColumnModel().getColumn(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL).setPreferredWidth(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL_WIDTH);
|
||||
destinationFunctionsTable.getColumnModel()
|
||||
.getColumn(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL)
|
||||
.setPreferredWidth(
|
||||
VTFunctionAssociationTableModel.ADDRESS_COL_WIDTH);
|
||||
|
||||
destinationTableFilterPanel =
|
||||
new GhidraTableFilterPanel<>(destinationFunctionsTable, destinationFunctionsModel);
|
||||
|
|
|
@ -181,7 +181,7 @@ public class FunctionComparisonScreenShots extends GhidraScreenShotGenerator {
|
|||
waitForSwing();
|
||||
|
||||
DockingActionIf openTableAction = getAction(plugin, "Add Functions To Comparison");
|
||||
performAction(openTableAction);
|
||||
performAction(openTableAction, false);
|
||||
|
||||
TableChooserDialog<?> dialog =
|
||||
waitForDialogComponent(TableChooserDialog.class);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue