diff --git a/Ghidra/Features/Base/data/base.theme.properties b/Ghidra/Features/Base/data/base.theme.properties
index f461cc6537..5012f9cc33 100644
--- a/Ghidra/Features/Base/data/base.theme.properties
+++ b/Ghidra/Features/Base/data/base.theme.properties
@@ -186,6 +186,7 @@ font.splash.infopanel = SansSerif-BOLD-14
font.plugin.assembly.dual.text.field = font.monospaced
font.plugin.console = font.monospaced
+font.plugin.datamgr.compare.name = [font]system.font.control[bold]
font.plugin.entropy.label.knot = sansserif-bold-12
font.plugin.function.text.editor = sansserif-plain-18
font.plugin.instruction.table.renderer = courier-plain-14
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeComparePanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeComparePanel.java
index 5f5fd203d0..5b36ed18e4 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeComparePanel.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeComparePanel.java
@@ -16,34 +16,38 @@
package ghidra.app.plugin.core.datamgr;
import java.awt.*;
+import java.awt.event.MouseEvent;
import javax.swing.*;
-import docking.widgets.label.GDHtmlLabel;
+import docking.widgets.label.GDLabel;
import docking.widgets.textpane.GHtmlTextPane;
import generic.theme.GThemeDefaults.Colors;
+import generic.theme.Gui;
import ghidra.app.util.ToolTipUtils;
import ghidra.app.util.html.HTMLDataTypeRepresentation;
-import ghidra.program.model.data.DataType;
-import ghidra.util.HTMLUtilities;
+import ghidra.program.model.data.*;
/**
* Panel that displays two data types side by side.
*/
class DataTypeComparePanel extends JPanel {
+ private static final String NAME_FONT_ID = "font.plugin.datamgr.compare.name";
private GHtmlTextPane leftDtPane;
private GHtmlTextPane rightDtPane;
private JPanel leftPanel;
private JPanel rightPanel;
private JLabel leftNameLabel;
private JLabel rightNameLabel;
- private String clientName;
+ private JLabel leftDescriptionLabel;
+ private JLabel rightDescriptionLabel;
+ private String localName;
private String sourceName;
- DataTypeComparePanel(String clientName, String sourceName) {
+ DataTypeComparePanel(String localName, String sourceName) {
super(new GridLayout(0, 2));
- this.clientName = clientName;
+ this.localName = localName;
this.sourceName = sourceName;
init();
}
@@ -54,13 +58,23 @@ class DataTypeComparePanel extends JPanel {
leftPanel = new JPanel(new BorderLayout());
rightPanel = new JPanel(new BorderLayout());
- leftNameLabel = new GDHtmlLabel();
- rightNameLabel = new GDHtmlLabel();
- leftNameLabel.setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 0));
- rightNameLabel.setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 0));
+ leftNameLabel = createLabelWidet();
+ rightNameLabel = createLabelWidet();
+ leftDescriptionLabel = createLabelWidet();
+ rightDescriptionLabel = createLabelWidet();
- setLabelText(leftNameLabel, HTMLUtilities.escapeHTML(clientName) + ":");
- setLabelText(rightNameLabel, HTMLUtilities.escapeHTML(sourceName) + ":");
+ leftNameLabel.setText(localName + ":");
+ rightNameLabel.setText(sourceName + ":");
+
+ JPanel leftLabelPanel = new JPanel();
+ leftLabelPanel.setLayout(new BoxLayout(leftLabelPanel, BoxLayout.PAGE_AXIS));
+ leftLabelPanel.add(leftNameLabel);
+ leftLabelPanel.add(leftDescriptionLabel);
+
+ JPanel rightLabelPanel = new JPanel();
+ rightLabelPanel.setLayout(new BoxLayout(rightLabelPanel, BoxLayout.PAGE_AXIS));
+ rightLabelPanel.add(rightNameLabel);
+ rightLabelPanel.add(rightDescriptionLabel);
add(leftPanel);
add(rightPanel);
@@ -79,10 +93,31 @@ class DataTypeComparePanel extends JPanel {
rightScrollPane.getVerticalScrollBar().setUnitIncrement(9);
leftPanel.add(leftScrollPane);
rightPanel.add(rightScrollPane);
- leftPanel.add(leftNameLabel, BorderLayout.NORTH);
- rightPanel.add(rightNameLabel, BorderLayout.NORTH);
+ leftPanel.add(leftLabelPanel, BorderLayout.NORTH);
+ rightPanel.add(rightLabelPanel, BorderLayout.NORTH);
syncScrollers(leftScrollPane, rightScrollPane);
+ }
+ private JLabel createLabelWidet() {
+ JLabel label = new GDLabel() {
+ @Override
+ public String getToolTipText(MouseEvent e) {
+ FontMetrics fm = getFontMetrics(getFont());
+ int textWidth = fm.stringWidth(getText());
+ int availableWidth = getWidth() - getInsets().left - getInsets().right;
+ if (textWidth > availableWidth) {
+ return getText();
+ }
+ return null;
+ }
+ };
+ ToolTipManager.sharedInstance().registerComponent(label);
+ label.setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 0));
+
+ Font font = Gui.getFont(NAME_FONT_ID);
+ label.setFont(font);
+
+ return label;
}
private void syncScrollers(JScrollPane leftScrollPane, JScrollPane rightScrollPane) {
@@ -104,11 +139,17 @@ class DataTypeComparePanel extends JPanel {
* @param dataType2 the second data type to display.
*/
void setDataTypes(DataType dataType1, DataType dataType2) {
- String path1 = dataType1 != null ? dataType1.getPathName() : "";
- String path2 = dataType2 != null ? dataType2.getPathName() : "";
- setLabelText(leftNameLabel, clientName + ":
" + path1);
- setLabelText(rightNameLabel, sourceName + ":
" + path2);
+ DataTypePath path1 = dataType1 != null ? dataType1.getDataTypePath() : null;
+ DataTypePath path2 = dataType2 != null ? dataType2.getDataTypePath() : null;
+
+ CategoryPath catPath1 = path1.getCategoryPath();
+ CategoryPath catPath2 = path2.getCategoryPath();
+ leftNameLabel.setText(localName + ':' + catPath1.getPath());
+ rightNameLabel.setText(sourceName + ':' + catPath2.getPath());
+
+ leftDescriptionLabel.setText(path1.getDataTypeName());
+ rightDescriptionLabel.setText(path2.getDataTypeName());
HTMLDataTypeRepresentation representation1 = ToolTipUtils.getHTMLRepresentation(dataType1);
HTMLDataTypeRepresentation representation2 = ToolTipUtils.getHTMLRepresentation(dataType2);
@@ -123,11 +164,6 @@ class DataTypeComparePanel extends JPanel {
rightDtPane.setText(dt2Text);
}
- private void setLabelText(JLabel label, String text) {
- label.setText(HTMLUtilities.wrapAsHTML(HTMLUtilities.bold(text)));
-
- }
-
public boolean isLeft(Component component) {
return SwingUtilities.isDescendingFrom(component, leftPanel);
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeCompareProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeCompareProvider.java
index 57fa90da29..2e6b6f9b7d 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeCompareProvider.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeCompareProvider.java
@@ -26,6 +26,7 @@ import ghidra.app.services.DataTypeManagerService;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;
import ghidra.util.HelpLocation;
+import resources.Icons;
/**
* A provider that shows a comparison between two data types.
@@ -60,6 +61,11 @@ public class DataTypeCompareProvider extends ComponentProvider {
.popupMenuPath("Show Data Type")
.onAction(this::showType)
.buildAndInstallLocal(this);
+
+ new ActionBuilder("Refresh", getOwner())
+ .toolBarIcon(Icons.REFRESH_ICON)
+ .onAction(this::refresh)
+ .buildAndInstallLocal(this);
}
private void showType(ActionContext context) {
@@ -74,6 +80,15 @@ public class DataTypeCompareProvider extends ComponentProvider {
service.setDataTypeSelected(dt);
}
+ private void refresh(ActionContext context) {
+ DataTypeManager leftDtm = leftDt.getDataTypeManager();
+ DataTypeManager rightDtm = rightDt.getDataTypeManager();
+ leftDt = leftDtm.resolve(leftDt, null);
+ rightDt = rightDtm.resolve(rightDt, null);
+
+ compareComponent.setDataTypes(leftDt, rightDt);
+ }
+
private void build() {
DataTypeManager leftDtm = leftDt.getDataTypeManager();
DataTypeManager rightDtm = rightDt.getDataTypeManager();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSyncDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSyncDialog.java
index 749891120a..bdceee562a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSyncDialog.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSyncDialog.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -100,9 +100,6 @@ public class DataTypeSyncDialog extends DialogComponentProvider implements DataT
}
- /* (non-Javadoc)
- * @see ghidra.app.plugin.core.datamgr.DataTypeSyncListener#dataTypeSelected(ghidra.program.model.data.DataType)
- */
@Override
public void dataTypeSelected(DataTypeSyncInfo syncInfo) {
if (syncInfo != null) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypesProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypesProvider.java
index 69620997db..84fc1f2832 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypesProvider.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypesProvider.java
@@ -300,8 +300,8 @@ public class DataTypesProvider extends ComponentProviderAdapter {
addLocalAction(viewCheckOutsAction);
}
- private boolean hasFilter() {
- return archiveGTree.isFiltered();
+ private boolean isFiltered(DataType dt) {
+ return archiveGTree.isFiltered() || !filterState.passesFilters(dt);
}
public DtFilterState getFilterState() {
@@ -791,7 +791,7 @@ public class DataTypesProvider extends ComponentProviderAdapter {
DataTypeNode dataTypeNode = node.getNode(dataType);
if (dataTypeNode == null) {
- if (hasFilter()) {
+ if (isFiltered(dataType)) {
plugin.setStatus("Unable to find " + dataType.getName() +
". It may be filtered out of view. (Data Type Manager)");
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java b/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java
index b0eef5138e..9ccaddfdb8 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java
@@ -25,6 +25,7 @@ import javax.swing.KeyStroke;
import docking.*;
import docking.action.*;
import docking.actions.KeyBindingUtils;
+import generic.theme.GIcon;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import resources.ResourceManager;
@@ -440,6 +441,9 @@ public abstract class AbstractActionBuilder
+ * Clients should be passing in {@link GIcon}s so that icons can be changed via the theme
+ * framework.
*
* @param icon the icon to use in the action's tool bar
* @return this builder (for chaining)
@@ -457,7 +461,9 @@ public abstract class AbstractActionBuilder