mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-2846 - Theming Documentation
This commit is contained in:
parent
07fc63f99f
commit
d4eae5ff3c
74 changed files with 903 additions and 598 deletions
|
@ -20,7 +20,7 @@ import java.awt.Graphics;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.program.model.address.AddressRange;
|
import ghidra.program.model.address.AddressRange;
|
||||||
import ghidra.trace.model.Lifespan;
|
import ghidra.trace.model.Lifespan;
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ public class MemoryBox {
|
||||||
int w = vertical ? getTimePixelWidth() : getAddressPixelWidth();
|
int w = vertical ? getTimePixelWidth() : getAddressPixelWidth();
|
||||||
int y = vertical ? getAddressPixelStart() : getTimePixelStart();
|
int y = vertical ? getAddressPixelStart() : getTimePixelStart();
|
||||||
int h = vertical ? getAddressPixelWidth() : getTimePixelWidth();
|
int h = vertical ? getAddressPixelWidth() : getTimePixelWidth();
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.fillRect(x - 1, y - 1, w + 2, h + 2);
|
g.fillRect(x - 1, y - 1, w + 2, h + 2);
|
||||||
g.setColor(color);
|
g.setColor(color);
|
||||||
g.fillRect(x, y, w, h);
|
g.fillRect(x, y, w, h);
|
||||||
|
@ -148,7 +148,7 @@ public class MemoryBox {
|
||||||
int w = vertical ? sz : getAddressPixelWidth();
|
int w = vertical ? sz : getAddressPixelWidth();
|
||||||
int y = vertical ? getAddressPixelStart() : 0;
|
int y = vertical ? getAddressPixelStart() : 0;
|
||||||
int h = vertical ? getAddressPixelWidth() : sz;
|
int h = vertical ? getAddressPixelWidth() : sz;
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.fillRect(x - 1, y - 1, w + 2, h + 2);
|
g.fillRect(x - 1, y - 1, w + 2, h + 2);
|
||||||
g.setColor(color);
|
g.setColor(color);
|
||||||
g.fillRect(x, y, w, h);
|
g.fillRect(x, y, w, h);
|
||||||
|
@ -159,7 +159,7 @@ public class MemoryBox {
|
||||||
int w = vertical ? 1 : sz;
|
int w = vertical ? 1 : sz;
|
||||||
int y = vertical ? 0 : getTimePixelStart();
|
int y = vertical ? 0 : getTimePixelStart();
|
||||||
int h = vertical ? sz : 1;
|
int h = vertical ? sz : 1;
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.fillRect(x - 1, y - 1, w + 2, h + 2);
|
g.fillRect(x - 1, y - 1, w + 2, h + 2);
|
||||||
g.setColor(color);
|
g.setColor(color);
|
||||||
g.fillRect(x, y, w, h);
|
g.fillRect(x, y, w, h);
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.List;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressRange;
|
import ghidra.program.model.address.AddressRange;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public class MemviewPanel extends JPanel implements MouseListener, MouseMotionLi
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
setPreferredSize(new Dimension(barWidth, barHeight));
|
setPreferredSize(new Dimension(barWidth, barHeight));
|
||||||
setSize(getPreferredSize());
|
setSize(getPreferredSize());
|
||||||
setBorder(BorderFactory.createLineBorder(Java.BORDER, 1));
|
setBorder(BorderFactory.createLineBorder(Colors.BORDER, 1));
|
||||||
setFocusable(true);
|
setFocusable(true);
|
||||||
|
|
||||||
addMouseListener(this);
|
addMouseListener(this);
|
||||||
|
|
|
@ -29,7 +29,7 @@ import docking.widgets.button.GRadioButton;
|
||||||
import docking.widgets.checkbox.GCheckBox;
|
import docking.widgets.checkbox.GCheckBox;
|
||||||
import docking.widgets.label.GDHtmlLabel;
|
import docking.widgets.label.GDHtmlLabel;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.merge.util.ConflictUtility;
|
import ghidra.app.merge.util.ConflictUtility;
|
||||||
import ghidra.util.HTMLUtilities;
|
import ghidra.util.HTMLUtilities;
|
||||||
import ghidra.util.layout.MaximizeSpecificColumnGridLayout;
|
import ghidra.util.layout.MaximizeSpecificColumnGridLayout;
|
||||||
|
@ -46,7 +46,7 @@ public class VariousChoicesPanel extends ConflictPanel {
|
||||||
|
|
||||||
private final static long serialVersionUID = 1;
|
private final static long serialVersionUID = 1;
|
||||||
private static final Border UNDERLINE_BORDER =
|
private static final Border UNDERLINE_BORDER =
|
||||||
BorderFactory.createMatteBorder(0, 0, 1, 0, Java.BORDER);
|
BorderFactory.createMatteBorder(0, 0, 1, 0, Colors.BORDER);
|
||||||
|
|
||||||
private JPanel rowPanel;
|
private JPanel rowPanel;
|
||||||
private GDHtmlLabel headerLabel;
|
private GDHtmlLabel headerLabel;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import docking.widgets.button.GRadioButton;
|
||||||
import docking.widgets.checkbox.GCheckBox;
|
import docking.widgets.checkbox.GCheckBox;
|
||||||
import docking.widgets.label.GDHtmlLabel;
|
import docking.widgets.label.GDHtmlLabel;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.merge.util.ConflictUtility;
|
import ghidra.app.merge.util.ConflictUtility;
|
||||||
import ghidra.util.HTMLUtilities;
|
import ghidra.util.HTMLUtilities;
|
||||||
import ghidra.util.datastruct.LongArrayList;
|
import ghidra.util.datastruct.LongArrayList;
|
||||||
|
@ -190,7 +190,7 @@ public class VerticalChoicesPanel extends ConflictPanel {
|
||||||
headerComps[i] = new MyLabel(items[i]);
|
headerComps[i] = new MyLabel(items[i]);
|
||||||
headerComps[i].setName(getComponentName(0, i));
|
headerComps[i].setName(getComponentName(0, i));
|
||||||
setRowComponent(headerComps[i], 0, i, defaultInsets);
|
setRowComponent(headerComps[i], 0, i, defaultInsets);
|
||||||
headerComps[i].setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Java.BORDER));
|
headerComps[i].setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Colors.BORDER));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rowPanel.validate();
|
rowPanel.validate();
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.beans.PropertyEditorSupport;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.framework.options.CustomOptionsEditor;
|
import ghidra.framework.options.CustomOptionsEditor;
|
||||||
import ghidra.util.layout.PairLayout;
|
import ghidra.util.layout.PairLayout;
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
|
||||||
new JTextField(StoredAnalyzerTimes.formatTimeMS(times.getTotalTime()));
|
new JTextField(StoredAnalyzerTimes.formatTimeMS(times.getTotalTime()));
|
||||||
valueField.setEditable(false);
|
valueField.setEditable(false);
|
||||||
valueField.setHorizontalAlignment(SwingConstants.RIGHT);
|
valueField.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
valueField.setBorder(BorderFactory.createLineBorder(Java.BORDER, 2));
|
valueField.setBorder(BorderFactory.createLineBorder(Colors.BORDER, 2));
|
||||||
panel.add(valueField);
|
panel.add(valueField);
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
|
|
|
@ -26,8 +26,6 @@ import javax.swing.*;
|
||||||
import javax.swing.event.*;
|
import javax.swing.event.*;
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
|
|
||||||
import docking.*;
|
import docking.*;
|
||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
|
@ -41,11 +39,8 @@ import docking.widgets.pathmanager.PathnameTablePanel;
|
||||||
import docking.widgets.table.GTableCellRenderer;
|
import docking.widgets.table.GTableCellRenderer;
|
||||||
import docking.widgets.table.GTableCellRenderingData;
|
import docking.widgets.table.GTableCellRenderingData;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.app.plugin.core.processors.SetLanguageDialog;
|
import ghidra.app.plugin.core.processors.SetLanguageDialog;
|
||||||
import ghidra.app.util.Option;
|
|
||||||
import ghidra.app.util.cparser.C.CParserUtils;
|
import ghidra.app.util.cparser.C.CParserUtils;
|
||||||
import ghidra.app.util.exporter.Exporter;
|
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.options.SaveState;
|
import ghidra.framework.options.SaveState;
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
|
@ -59,17 +54,17 @@ import ghidra.util.filechooser.ExtensionFileFilter;
|
||||||
import resources.Icons;
|
import resources.Icons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog that shows files used for parsing C header files. The profile has a list of
|
* Dialog that shows files used for parsing C header files. The profile has a list of
|
||||||
* source header files to parse, followed by parse options (compiler directives).
|
* source header files to parse, followed by parse options (compiler directives).
|
||||||
* Ghidra supplies a Windows profile by default in core/parserprofiles. The user can do
|
* Ghidra supplies a Windows profile by default in core/parserprofiles. The user can do
|
||||||
* "save as" on this default profile to create new profiles that will be written to the
|
* "save as" on this default profile to create new profiles that will be written to the
|
||||||
* user's <home>/userprofiles directory. The CParserPlugin creates this directory if it
|
* user's <home>/userprofiles directory. The CParserPlugin creates this directory if it
|
||||||
* doesn't exist.
|
* doesn't exist.
|
||||||
*
|
*
|
||||||
* The data types resulting from the parse operation can either be added to the data type
|
* The data types resulting from the parse operation can either be added to the data type
|
||||||
* manager in the current program, or written to an archive data file.
|
* manager in the current program, or written to an archive data file.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ParseDialog extends ReusableDialogComponentProvider {
|
class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
@ -88,13 +83,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
private PathnameTablePanel pathPanel;
|
private PathnameTablePanel pathPanel;
|
||||||
private JTextArea parseOptionsField;
|
private JTextArea parseOptionsField;
|
||||||
|
|
||||||
protected JComponent languagePanel;
|
protected JComponent languagePanel;
|
||||||
protected JTextField languageTextField;
|
protected JTextField languageTextField;
|
||||||
protected JButton languageButton;
|
protected JButton languageButton;
|
||||||
protected String languageIDString = null;
|
protected String languageIDString = null;
|
||||||
protected String compilerIDString = null;
|
protected String compilerIDString = null;
|
||||||
|
|
||||||
private GhidraComboBox<ComboBoxItem> comboBox;
|
private GhidraComboBox<ComboBoxItem> comboBox;
|
||||||
private DefaultComboBoxModel<ComboBoxItem> comboModel;
|
private DefaultComboBoxModel<ComboBoxItem> comboModel;
|
||||||
private DockingAction saveAction;
|
private DockingAction saveAction;
|
||||||
|
@ -106,7 +101,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
private TableModelListener tableListener;
|
private TableModelListener tableListener;
|
||||||
private ItemListener comboItemListener;
|
private ItemListener comboItemListener;
|
||||||
private TableModel tableModel;
|
private TableModel tableModel;
|
||||||
|
|
||||||
private PathnameTablePanel includePathPanel;
|
private PathnameTablePanel includePathPanel;
|
||||||
private TableModel parsePathTableModel;
|
private TableModel parsePathTableModel;
|
||||||
private TableModelListener parsePathTableListener;
|
private TableModelListener parsePathTableListener;
|
||||||
|
@ -116,7 +111,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
private ResourceFile parentUserFile;
|
private ResourceFile parentUserFile;
|
||||||
private boolean saveAsInProgress;
|
private boolean saveAsInProgress;
|
||||||
private boolean initialBuild = true;
|
private boolean initialBuild = true;
|
||||||
|
|
||||||
private boolean userDefined = false;
|
private boolean userDefined = false;
|
||||||
private String currentProfileName = null;
|
private String currentProfileName = null;
|
||||||
|
|
||||||
|
@ -134,27 +129,29 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
addDismissButton();
|
addDismissButton();
|
||||||
createActions();
|
createActions();
|
||||||
setActionsEnabled();
|
setActionsEnabled();
|
||||||
|
|
||||||
// setup based on save state
|
// setup based on save state
|
||||||
if (currentProfileName != null) {
|
if (currentProfileName != null) {
|
||||||
for (int i = 0; i < itemList.size(); i++) {
|
for (int i = 0; i < itemList.size(); i++) {
|
||||||
ComboBoxItem item = itemList.get(i);
|
ComboBoxItem item = itemList.get(i);
|
||||||
if (userDefined == item.isUserDefined && currentProfileName.equals(item.file.getName())) {
|
if (userDefined == item.isUserDefined &&
|
||||||
|
currentProfileName.equals(item.file.getName())) {
|
||||||
comboBox.setSelectedIndex(i);
|
comboBox.setSelectedIndex(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
toFront();
|
toFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeState(SaveState saveState) {
|
void writeState(SaveState saveState) {
|
||||||
// Get the current state if the dialog has been displayed
|
// Get the current state if the dialog has been displayed
|
||||||
if (!initialBuild) {
|
if (!initialBuild) {
|
||||||
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
|
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
|
||||||
|
|
||||||
currentProfileName = item.file.getName();
|
currentProfileName = item.file.getName();
|
||||||
userDefined = item.isUserDefined;
|
userDefined = item.isUserDefined;
|
||||||
|
|
||||||
|
@ -188,7 +185,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
protected JPanel buildMainPanel() {
|
protected JPanel buildMainPanel() {
|
||||||
initialBuild = true;
|
initialBuild = true;
|
||||||
|
|
||||||
mainPanel = new JPanel(new BorderLayout(10, 5));
|
mainPanel = new JPanel(new BorderLayout(10, 5));
|
||||||
|
|
||||||
comboModel = new DefaultComboBoxModel<>();
|
comboModel = new DefaultComboBoxModel<>();
|
||||||
|
@ -217,7 +214,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
pathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY,
|
pathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY,
|
||||||
GhidraFileChooserMode.FILES_AND_DIRECTORIES, true,
|
GhidraFileChooserMode.FILES_AND_DIRECTORIES, true,
|
||||||
new ExtensionFileFilter(new String[] { "h" }, "C Header Files"));
|
new ExtensionFileFilter(new String[] { "h" }, "C Header Files"));
|
||||||
|
|
||||||
// Set default render to display red if file would not we found
|
// Set default render to display red if file would not we found
|
||||||
// Using include paths
|
// Using include paths
|
||||||
pathPanel.getTable().setDefaultRenderer(String.class, new GTableCellRenderer() {
|
pathPanel.getTable().setDefaultRenderer(String.class, new GTableCellRenderer() {
|
||||||
|
@ -229,7 +226,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
String pathName = (String) value;
|
String pathName = (String) value;
|
||||||
pathName = (pathName == null ? "" : pathName.trim());
|
pathName = (pathName == null ? "" : pathName.trim());
|
||||||
|
|
||||||
if (pathName.length() == 0 || pathName.startsWith("#")) {
|
if (pathName.length() == 0 || pathName.startsWith("#")) {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +234,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
boolean fileExists = true;
|
boolean fileExists = true;
|
||||||
File file = new File(pathName);
|
File file = new File(pathName);
|
||||||
fileExists = file.exists();
|
fileExists = file.exists();
|
||||||
|
|
||||||
// file not found directly, see if one of the include paths will find the file
|
// file not found directly, see if one of the include paths will find the file
|
||||||
if (!fileExists) {
|
if (!fileExists) {
|
||||||
fileExists = doesFileExist(pathName, fileExists);
|
fileExists = doesFileExist(pathName, fileExists);
|
||||||
|
@ -245,14 +242,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
label.setText(pathName.toString());
|
label.setText(pathName.toString());
|
||||||
if (!fileExists) {
|
if (!fileExists) {
|
||||||
label.setForeground(data.isSelected() ? Tables.FG_ERROR_SELECTED
|
label.setForeground(getErrorForegroundColor(data.isSelected()));
|
||||||
: Tables.FG_ERROR_UNSELECTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tableListener = e -> {
|
tableListener = e -> {
|
||||||
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
|
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
|
||||||
item.isChanged = !initialBuild;
|
item.isChanged = !initialBuild;
|
||||||
|
@ -260,7 +256,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
};
|
};
|
||||||
tableModel = pathPanel.getTable().getModel();
|
tableModel = pathPanel.getTable().getModel();
|
||||||
tableModel.addTableModelListener(tableListener);
|
tableModel.addTableModelListener(tableListener);
|
||||||
|
|
||||||
includePathPanel = new PathnameTablePanel(null, true, false);
|
includePathPanel = new PathnameTablePanel(null, true, false);
|
||||||
includePathPanel.setBorder(BorderFactory.createTitledBorder("Include paths"));
|
includePathPanel.setBorder(BorderFactory.createTitledBorder("Include paths"));
|
||||||
includePathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY,
|
includePathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY,
|
||||||
|
@ -285,13 +281,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
JScrollPane pane = new JScrollPane(parseOptionsField);
|
JScrollPane pane = new JScrollPane(parseOptionsField);
|
||||||
pane.getViewport().setPreferredSize(new Dimension(300, 200));
|
pane.getViewport().setPreferredSize(new Dimension(300, 200));
|
||||||
optionsPanel.add(pane, BorderLayout.CENTER);
|
optionsPanel.add(pane, BorderLayout.CENTER);
|
||||||
|
|
||||||
JPanel archPanel = new JPanel(new BorderLayout());
|
JPanel archPanel = new JPanel(new BorderLayout());
|
||||||
archPanel.setBorder(BorderFactory.createTitledBorder("Program Architecture:"));
|
archPanel.setBorder(BorderFactory.createTitledBorder("Program Architecture:"));
|
||||||
archPanel.add(new GLabel(" ", SwingConstants.RIGHT));
|
archPanel.add(new GLabel(" ", SwingConstants.RIGHT));
|
||||||
languagePanel = buildLanguagePanel();
|
languagePanel = buildLanguagePanel();
|
||||||
archPanel.add(languagePanel);
|
archPanel.add(languagePanel);
|
||||||
|
|
||||||
// create Parse Button
|
// create Parse Button
|
||||||
|
|
||||||
parseButton = new JButton("Parse to Program");
|
parseButton = new JButton("Parse to Program");
|
||||||
|
@ -304,19 +300,19 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
parseToFileButton.setToolTipText("Parse files and output to archive file");
|
parseToFileButton.setToolTipText("Parse files and output to archive file");
|
||||||
addButton(parseToFileButton);
|
addButton(parseToFileButton);
|
||||||
|
|
||||||
|
|
||||||
mainPanel.add(comboPanel, BorderLayout.NORTH);
|
mainPanel.add(comboPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
includePathPanel.setPreferredSize(new Dimension(pathPanel.getPreferredSize().width, 200));
|
includePathPanel.setPreferredSize(new Dimension(pathPanel.getPreferredSize().width, 200));
|
||||||
JSplitPane optionsPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, includePathPanel, optionsPanel);
|
JSplitPane optionsPane =
|
||||||
|
new JSplitPane(JSplitPane.VERTICAL_SPLIT, includePathPanel, optionsPanel);
|
||||||
optionsPane.setResizeWeight(0.50);
|
optionsPane.setResizeWeight(0.50);
|
||||||
|
|
||||||
pathPanel.setPreferredSize(new Dimension(pathPanel.getPreferredSize().width, 200));
|
pathPanel.setPreferredSize(new Dimension(pathPanel.getPreferredSize().width, 200));
|
||||||
JSplitPane outerPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pathPanel, optionsPane);
|
JSplitPane outerPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pathPanel, optionsPane);
|
||||||
outerPane.setResizeWeight(0.50);
|
outerPane.setResizeWeight(0.50);
|
||||||
|
|
||||||
mainPanel.add(outerPane, BorderLayout.CENTER);
|
mainPanel.add(outerPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
mainPanel.add(archPanel, BorderLayout.SOUTH);
|
mainPanel.add(archPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), "Parse_C_Source"));
|
setHelpLocation(new HelpLocation(plugin.getName(), "Parse_C_Source"));
|
||||||
|
@ -340,8 +336,8 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fileExists;
|
return fileExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JComponent buildLanguagePanel() {
|
private JComponent buildLanguagePanel() {
|
||||||
languageTextField = new JTextField();
|
languageTextField = new JTextField();
|
||||||
languageTextField.setEditable(false);
|
languageTextField.setEditable(false);
|
||||||
|
@ -349,31 +345,31 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
languageButton = new BrowseButton();
|
languageButton = new BrowseButton();
|
||||||
languageButton.addActionListener(e -> {
|
languageButton.addActionListener(e -> {
|
||||||
SetLanguageDialog dialog = new SetLanguageDialog(plugin.getTool(), languageIDString, compilerIDString,
|
SetLanguageDialog dialog = new SetLanguageDialog(plugin.getTool(), languageIDString,
|
||||||
"Select Program Architecture for File DataType Archive");
|
compilerIDString, "Select Program Architecture for File DataType Archive");
|
||||||
LanguageID languageId = dialog.getLanguageDescriptionID();
|
LanguageID languageId = dialog.getLanguageDescriptionID();
|
||||||
CompilerSpecID compilerSpecId = dialog.getCompilerSpecDescriptionID();
|
CompilerSpecID compilerSpecId = dialog.getCompilerSpecDescriptionID();
|
||||||
if ((languageId == null) || (compilerSpecId == null)) {
|
if ((languageId == null) || (compilerSpecId == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String newLanguageIDString = languageId.getIdAsString();
|
String newLanguageIDString = languageId.getIdAsString();
|
||||||
String newCompilerIDString = compilerSpecId.getIdAsString();
|
String newCompilerIDString = compilerSpecId.getIdAsString();
|
||||||
|
|
||||||
if (!Objects.equals(newLanguageIDString, languageIDString) ||
|
if (!Objects.equals(newLanguageIDString, languageIDString) ||
|
||||||
!Objects.equals(newCompilerIDString, compilerIDString)) {
|
!Objects.equals(newCompilerIDString, compilerIDString)) {
|
||||||
itemChanged();
|
itemChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
languageIDString = newLanguageIDString;
|
languageIDString = newLanguageIDString;
|
||||||
compilerIDString = newCompilerIDString;
|
compilerIDString = newCompilerIDString;
|
||||||
|
|
||||||
updateArchitectureDescription();
|
updateArchitectureDescription();
|
||||||
});
|
});
|
||||||
|
|
||||||
updateArchitectureDescription();
|
|
||||||
|
|
||||||
languageButton.setName("Set Processor Architecture");
|
updateArchitectureDescription();
|
||||||
|
|
||||||
|
languageButton.setName("Set Processor Architecture");
|
||||||
Font font = languageButton.getFont();
|
Font font = languageButton.getFont();
|
||||||
languageButton.setFont(font.deriveFont(Font.BOLD));
|
languageButton.setFont(font.deriveFont(Font.BOLD));
|
||||||
|
|
||||||
|
@ -387,13 +383,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
String newProgramArchitectureSummary = "64/32 (primarily for backward compatibility)";
|
String newProgramArchitectureSummary = "64/32 (primarily for backward compatibility)";
|
||||||
|
|
||||||
if (languageIDString != null) {
|
if (languageIDString != null) {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
buf.append(languageIDString);
|
buf.append(languageIDString);
|
||||||
buf.append(" / ");
|
buf.append(" / ");
|
||||||
buf.append(compilerIDString != null ? compilerIDString : "none");
|
buf.append(compilerIDString != null ? compilerIDString : "none");
|
||||||
newProgramArchitectureSummary = buf.toString();
|
newProgramArchitectureSummary = buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
languageTextField.setText(newProgramArchitectureSummary);
|
languageTextField.setText(newProgramArchitectureSummary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,30 +652,30 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
String line = null;
|
String line = null;
|
||||||
while ((line = br.readLine()) != null && line.trim().length() > 0) {
|
while ((line = br.readLine()) != null && line.trim().length() > 0) {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
|
|
||||||
pathList.add(line);
|
pathList.add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((line = br.readLine()) != null && line.trim().length() > 0) {
|
while ((line = br.readLine()) != null && line.trim().length() > 0) {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
|
|
||||||
sb.append(line + "\n");
|
sb.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get paths
|
// get paths
|
||||||
while ((line = br.readLine()) != null && line.trim().length() > 0) {
|
while ((line = br.readLine()) != null && line.trim().length() > 0) {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
|
|
||||||
includeList.add(line);
|
includeList.add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get language
|
// get language
|
||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
if (line.length() > 0) {
|
if (line.length() > 0) {
|
||||||
langString = (line.length() == 0 ? null : line);
|
langString = (line.length() == 0 ? null : line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get compiler spec
|
// get compiler spec
|
||||||
|
@ -688,25 +684,24 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
if (line.length() > 0) {
|
if (line.length() > 0) {
|
||||||
compileString = (line.length() == 0 ? null : line);
|
compileString = (line.length() == 0 ? null : line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String[] paths = new String[pathList.size()];
|
String[] paths = new String[pathList.size()];
|
||||||
paths = pathList.toArray(paths);
|
paths = pathList.toArray(paths);
|
||||||
pathPanel.setPaths(paths);
|
pathPanel.setPaths(paths);
|
||||||
|
|
||||||
String[] incpaths = new String[includeList.size()];
|
String[] incpaths = new String[includeList.size()];
|
||||||
incpaths = includeList.toArray(incpaths);
|
incpaths = includeList.toArray(incpaths);
|
||||||
includePathPanel.setPaths(incpaths);
|
includePathPanel.setPaths(incpaths);
|
||||||
|
|
||||||
parseOptionsField.setText(sb.toString());
|
parseOptionsField.setText(sb.toString());
|
||||||
|
|
||||||
languageIDString = langString;
|
languageIDString = langString;
|
||||||
|
|
||||||
compilerIDString = compileString;
|
compilerIDString = compileString;
|
||||||
|
|
||||||
updateArchitectureDescription();
|
updateArchitectureDescription();
|
||||||
|
|
||||||
br.close();
|
br.close();
|
||||||
}
|
}
|
||||||
|
@ -726,7 +721,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
setActionsEnabled();
|
setActionsEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeProfile(ResourceFile outputFile) {
|
private void writeProfile(ResourceFile outputFile) {
|
||||||
// write the pathnames
|
// write the pathnames
|
||||||
try {
|
try {
|
||||||
|
@ -749,27 +744,27 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
|
||||||
// Write paths
|
// Write paths
|
||||||
String [] includePaths = includePathPanel.getPaths();
|
String[] includePaths = includePathPanel.getPaths();
|
||||||
for (String path : includePaths) {
|
for (String path : includePaths) {
|
||||||
writer.write(path.trim());
|
writer.write(path.trim());
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
}
|
}
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
|
||||||
// Write Language ID Spec
|
// Write Language ID Spec
|
||||||
if (languageIDString != null) {
|
if (languageIDString != null) {
|
||||||
writer.write(languageIDString);
|
writer.write(languageIDString);
|
||||||
}
|
}
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
|
||||||
// Write Compiler ID Spec
|
// Write Compiler ID Spec
|
||||||
if (compilerIDString != null) {
|
if (compilerIDString != null) {
|
||||||
writer.write(compilerIDString);
|
writer.write(compilerIDString);
|
||||||
}
|
}
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
|
@ -808,17 +803,18 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
paths = expandPaths(paths);
|
paths = expandPaths(paths);
|
||||||
pathPanel.setPaths(paths);
|
pathPanel.setPaths(paths);
|
||||||
|
|
||||||
if (languageIDString == null || compilerIDString == null ) {
|
if (languageIDString == null || compilerIDString == null) {
|
||||||
Msg.showWarn(getClass(), rootPanel, "Program Architecture not Specified",
|
Msg.showWarn(getClass(), rootPanel, "Program Architecture not Specified",
|
||||||
"A Program Architecture must be specified in order to parse to a file.");
|
"A Program Architecture must be specified in order to parse to a file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseToFile) {
|
if (parseToFile) {
|
||||||
File file = getSaveFile();
|
File file = getSaveFile();
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
plugin.parse(paths, includePaths, options, languageIDString, compilerIDString, file.getAbsolutePath());
|
plugin.parse(paths, includePaths, options, languageIDString, compilerIDString,
|
||||||
|
file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -996,11 +992,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
return Objects.hash(file, isUserDefined);
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((file == null) ? 0 : file.hashCode());
|
|
||||||
result = prime * result + (isUserDefined ? 1231 : 1237);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1017,55 +1009,54 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Methods for Testing
|
// Methods for Testing
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
|
GhidraComboBox<ParseDialog.ComboBoxItem> getParseComboBox() {
|
||||||
|
return comboBox;
|
||||||
|
}
|
||||||
|
|
||||||
GhidraComboBox<ParseDialog.ComboBoxItem> getParseComboBox() {
|
PathnameTablePanel getSourceFiles() {
|
||||||
return comboBox;
|
return this.pathPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathnameTablePanel getSourceFiles() {
|
PathnameTablePanel getIncludePaths() {
|
||||||
return this.pathPanel;
|
return this.includePathPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathnameTablePanel getIncludePaths() {
|
JTextArea getParseOptionsTextField() {
|
||||||
return this.includePathPanel;
|
return this.parseOptionsField;
|
||||||
}
|
}
|
||||||
|
|
||||||
JTextArea getParseOptionsTextField() {
|
JButton getLanguageButton() {
|
||||||
return this.parseOptionsField;
|
return this.languageButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
JButton getLanguageButton() {
|
JTextField getLanguageText() {
|
||||||
return this.languageButton;
|
return this.languageTextField;
|
||||||
}
|
}
|
||||||
|
|
||||||
JTextField getLanguageText() {
|
JButton getParseButton() {
|
||||||
return this.languageTextField;
|
return this.parseButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
JButton getParseButton() {
|
JButton getParseToFileButton() {
|
||||||
return this.parseButton;
|
return this.parseToFileButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
JButton getParseToFileButton() {
|
ArrayList<ComboBoxItem> getProfiles() {
|
||||||
return this.parseToFileButton;
|
return this.itemList;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<ComboBoxItem> getProfiles() {
|
ComboBoxItem getCurrentItem() {
|
||||||
return this.itemList;
|
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
|
||||||
}
|
|
||||||
|
return item;
|
||||||
ComboBoxItem getCurrentItem() {
|
}
|
||||||
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
|
|
||||||
|
ResourceFile getUserProfileParent() {
|
||||||
return item;
|
return parentUserFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceFile getUserProfileParent() {
|
|
||||||
return parentUserFile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import javax.swing.JTable;
|
||||||
|
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.app.util.ToolTipUtils;
|
import ghidra.app.util.ToolTipUtils;
|
||||||
import ghidra.docking.settings.FormatSettingsDefinition;
|
import ghidra.docking.settings.FormatSettingsDefinition;
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
|
@ -156,8 +155,7 @@ class EquateTableModel extends GDynamicColumnTableModel<Equate, Object> {
|
||||||
|
|
||||||
JTable table = data.getTable();
|
JTable table = data.getTable();
|
||||||
if (!eq.isValidUUID()) { // Error equate
|
if (!eq.isValidUUID()) { // Error equate
|
||||||
label.setForeground(
|
label.setForeground(getErrorForegroundColor(isSelected));
|
||||||
(isSelected) ? table.getSelectionForeground() : Tables.FG_ERROR_UNSELECTED);
|
|
||||||
}
|
}
|
||||||
else if (!eq.isEnumBased()) { // User label
|
else if (!eq.isEnumBased()) { // User label
|
||||||
label.setForeground(
|
label.setForeground(
|
||||||
|
|
|
@ -39,7 +39,7 @@ import docking.widgets.label.GLabel;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.*;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import generic.util.WindowUtilities;
|
import generic.util.WindowUtilities;
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.app.util.ToolTipUtils;
|
import ghidra.app.util.ToolTipUtils;
|
||||||
|
@ -213,7 +213,7 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
|
||||||
thunkedText.setEditable(false);
|
thunkedText.setEditable(false);
|
||||||
DockingUtils.setTransparent(thunkedText);
|
DockingUtils.setTransparent(thunkedText);
|
||||||
CompoundBorder border =
|
CompoundBorder border =
|
||||||
BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Java.BORDER),
|
BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Colors.BORDER),
|
||||||
BorderFactory.createEmptyBorder(0, 5, 0, 5));
|
BorderFactory.createEmptyBorder(0, 5, 0, 5));
|
||||||
thunkedText.setBorder(border);
|
thunkedText.setBorder(border);
|
||||||
thunkedText.setForeground(FunctionColors.THUNK);
|
thunkedText.setForeground(FunctionColors.THUNK);
|
||||||
|
@ -652,13 +652,12 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
|
||||||
DataType dataType = (DataType) value;
|
DataType dataType = (DataType) value;
|
||||||
Color color = isSelected ? table.getSelectionForeground() : table.getForeground();
|
Color color = isSelected ? table.getSelectionForeground() : table.getForeground();
|
||||||
if (!tableModel.isCellEditable(row, column)) {
|
if (!tableModel.isCellEditable(row, column)) {
|
||||||
color =
|
color = getUneditableForegroundColor(isSelected);
|
||||||
isSelected ? Tables.FG_UNEDITABLE_SELECTED : Tables.FG_UNEDITABLE_UNSELECTED;
|
|
||||||
}
|
}
|
||||||
if (dataType != null) {
|
if (dataType != null) {
|
||||||
setText(dataType.getName());
|
setText(dataType.getName());
|
||||||
if (dataType.isNotYetDefined()) {
|
if (dataType.isNotYetDefined()) {
|
||||||
color = isSelected ? Tables.FG_ERROR_SELECTED : Tables.FG_ERROR_UNSELECTED;
|
color = getErrorForegroundColor(isSelected);
|
||||||
}
|
}
|
||||||
String toolTipText = ToolTipUtils.getToolTipText(dataType);
|
String toolTipText = ToolTipUtils.getToolTipText(dataType);
|
||||||
String headerText = "<HTML><b>" +
|
String headerText = "<HTML><b>" +
|
||||||
|
@ -782,8 +781,7 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
|
||||||
boolean isInvalidStorage =
|
boolean isInvalidStorage =
|
||||||
!storage.isValid() || rowData.getFormalDataType().getLength() != storage.size();
|
!storage.isValid() || rowData.getFormalDataType().getLength() != storage.size();
|
||||||
if (isInvalidStorage) {
|
if (isInvalidStorage) {
|
||||||
setForeground(
|
setForeground(getErrorForegroundColor(isSelected));
|
||||||
isSelected ? Tables.FG_ERROR_SELECTED : Tables.FG_ERROR_UNSELECTED);
|
|
||||||
setToolTipText("Invalid Parameter Storage");
|
setToolTipText("Invalid Parameter Storage");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -818,8 +816,7 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
|
||||||
|
|
||||||
ParameterTableModel tableModel = (ParameterTableModel) table.getModel();
|
ParameterTableModel tableModel = (ParameterTableModel) table.getModel();
|
||||||
if (!tableModel.isCellEditable(row, column)) {
|
if (!tableModel.isCellEditable(row, column)) {
|
||||||
setForeground(
|
setForeground(getUneditableForegroundColor(isSelected));
|
||||||
isSelected ? Tables.FG_UNEDITABLE_SELECTED : Tables.FG_UNEDITABLE_UNSELECTED);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.function.editor;
|
package ghidra.app.plugin.core.function.editor;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
|
@ -53,8 +54,7 @@ class StorageTableCellEditor extends AbstractCellEditor implements TableCellEdit
|
||||||
boolean isSelected, int row, int column) {
|
boolean isSelected, int row, int column) {
|
||||||
String stringValue = value == null ? "" : value.toString();
|
String stringValue = value == null ? "" : value.toString();
|
||||||
JTextField field = new JTextField(stringValue);
|
JTextField field = new JTextField(stringValue);
|
||||||
field.setBackground(
|
field.setBackground(getUneditableForegroundColor(isSelected));
|
||||||
isSelected ? Tables.FG_UNEDITABLE_SELECTED : Tables.FG_UNEDITABLE_UNSELECTED);
|
|
||||||
field.setEditable(false);
|
field.setEditable(false);
|
||||||
ParameterTableModel tableModel = (ParameterTableModel) table.getModel();
|
ParameterTableModel tableModel = (ParameterTableModel) table.getModel();
|
||||||
FunctionVariableData rowData = tableModel.getRowObject(row);
|
FunctionVariableData rowData = tableModel.getRowObject(row);
|
||||||
|
@ -78,4 +78,9 @@ class StorageTableCellEditor extends AbstractCellEditor implements TableCellEdit
|
||||||
});
|
});
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Color getUneditableForegroundColor(boolean isSelected) {
|
||||||
|
return isSelected ? Tables.UNEDITABLE_SELECTED : Tables.UNEDITABLE_UNSELECTED;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import docking.widgets.textfield.HintTextField;
|
import docking.widgets.textfield.HintTextField;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.cmd.function.CreateFunctionTagCmd;
|
import ghidra.app.cmd.function.CreateFunctionTagCmd;
|
||||||
import ghidra.app.context.ProgramActionContext;
|
import ghidra.app.context.ProgramActionContext;
|
||||||
import ghidra.framework.cmd.Command;
|
import ghidra.framework.cmd.Command;
|
||||||
|
@ -239,9 +239,9 @@ public class FunctionTagProvider extends ComponentProviderAdapter
|
||||||
targetPanel = new TargetTagsPanel(this, tool, "Assigned To Function");
|
targetPanel = new TargetTagsPanel(this, tool, "Assigned To Function");
|
||||||
allFunctionsPanel = new AllFunctionsPanel(program, this, "Functions with Selected Tag");
|
allFunctionsPanel = new AllFunctionsPanel(program, this, "Functions with Selected Tag");
|
||||||
buttonPanel = new FunctionTagButtonPanel(sourcePanel, targetPanel);
|
buttonPanel = new FunctionTagButtonPanel(sourcePanel, targetPanel);
|
||||||
sourcePanel.setBorder(BorderFactory.createLineBorder(Java.BORDER));
|
sourcePanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
targetPanel.setBorder(BorderFactory.createLineBorder(Java.BORDER));
|
targetPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
allFunctionsPanel.setBorder(BorderFactory.createLineBorder(Java.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
|
||||||
|
|
|
@ -24,8 +24,8 @@ import javax.swing.JToolTip;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.field.Field;
|
import docking.widgets.fieldpanel.field.Field;
|
||||||
import docking.widgets.fieldpanel.support.FieldLocation;
|
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||||
|
import generic.theme.GThemeDefaults.Colors.Tooltips;
|
||||||
import ghidra.app.plugin.core.gotoquery.GoToHelper;
|
import ghidra.app.plugin.core.gotoquery.GoToHelper;
|
||||||
import ghidra.app.services.CodeFormatService;
|
import ghidra.app.services.CodeFormatService;
|
||||||
import ghidra.app.util.*;
|
import ghidra.app.util.*;
|
||||||
|
@ -46,7 +46,7 @@ import ghidra.util.bean.opteditor.OptionsVetoException;
|
||||||
public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
||||||
|
|
||||||
private static final int WINDOW_OFFSET = 50;
|
private static final int WINDOW_OFFSET = 50;
|
||||||
private static final Color BACKGROUND_COLOR = Colors.BG_TOOLTIP;
|
private static final Color BACKGROUND_COLOR = Tooltips.BACKGROUND;
|
||||||
private static final Color FG_COLOR_NOT_IN_MEMORY = Messages.HINT;
|
private static final Color FG_COLOR_NOT_IN_MEMORY = Messages.HINT;
|
||||||
|
|
||||||
private CodeFormatService codeFormatService;
|
private CodeFormatService codeFormatService;
|
||||||
|
@ -251,21 +251,21 @@ public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Format
|
Format
|
||||||
|
|
||||||
Address: ram:1234
|
Address: ram:1234
|
||||||
Address not in memory
|
Address not in memory
|
||||||
|
|
||||||
|
|
||||||
Or, when multiple symbols at destination
|
Or, when multiple symbols at destination
|
||||||
|
|
||||||
|
|
||||||
Address: ram:1234
|
Address: ram:1234
|
||||||
Symbols (3):
|
Symbols (3):
|
||||||
foo
|
foo
|
||||||
bar
|
bar
|
||||||
baz
|
baz
|
||||||
Address not in memory
|
Address not in memory
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String newline = HTMLUtilities.HTML_NEW_LINE;
|
String newline = HTMLUtilities.HTML_NEW_LINE;
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.awt.GridBagLayout;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.plugin.core.instructionsearch.InstructionSearchPlugin;
|
import ghidra.app.plugin.core.instructionsearch.InstructionSearchPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +57,7 @@ public class ControlPanel extends JPanel {
|
||||||
gbc.weightx = 1.0;
|
gbc.weightx = 1.0;
|
||||||
this.add(directionWidget, gbc);
|
this.add(directionWidget, gbc);
|
||||||
|
|
||||||
this.setBorder(BorderFactory.createLineBorder(Java.BORDER));
|
this.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SelectionScopeWidget getRangeWidget() {
|
public SelectionScopeWidget getRangeWidget() {
|
||||||
|
|
|
@ -25,20 +25,14 @@ import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.event.ListDataListener;
|
import javax.swing.event.ListDataListener;
|
||||||
|
|
||||||
import docking.widgets.list.GListCellRenderer;
|
import docking.widgets.list.GListCellRenderer;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors.Tooltips;
|
||||||
import generic.util.WindowUtilities;
|
import generic.util.WindowUtilities;
|
||||||
import ghidra.app.plugin.core.console.CodeCompletion;
|
import ghidra.app.plugin.core.console.CodeCompletion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates a code completion popup Window for the ConsolePlugin.
|
* This class encapsulates a code completion popup Window for the ConsolePlugin.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CodeCompletionWindow extends JDialog {
|
public class CodeCompletionWindow extends JDialog {
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
/* from ReferenceHoverPlugin */
|
|
||||||
private static final Color BACKGROUND_COLOR = Colors.BG_TOOLTIP;
|
|
||||||
|
|
||||||
protected final InterpreterPanel console;
|
protected final InterpreterPanel console;
|
||||||
protected final JTextPane outputTextField;
|
protected final JTextPane outputTextField;
|
||||||
|
@ -50,17 +44,6 @@ public class CodeCompletionWindow extends JDialog {
|
||||||
/* current list of completions */
|
/* current list of completions */
|
||||||
protected JList jlist;
|
protected JList jlist;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new CodeCompletionWindow.
|
|
||||||
*
|
|
||||||
* We pass in the PluginTool so we can get a reference to the Frame we are
|
|
||||||
* popping up over, as well as the text field we are coming from (so we
|
|
||||||
* can fine-tune where we pop up).
|
|
||||||
*
|
|
||||||
* @param tool the PluginTool the has the Frame we are popping up over
|
|
||||||
* @param console the ConsolePlugin we are providing services for
|
|
||||||
* @param outputTextField the JTextField from whence we came
|
|
||||||
*/
|
|
||||||
public CodeCompletionWindow(Window parent, InterpreterPanel cp, JTextPane textField) {
|
public CodeCompletionWindow(Window parent, InterpreterPanel cp, JTextPane textField) {
|
||||||
super(parent);
|
super(parent);
|
||||||
|
|
||||||
|
@ -73,7 +56,7 @@ public class CodeCompletionWindow extends JDialog {
|
||||||
/* don't steal focus from text input! */
|
/* don't steal focus from text input! */
|
||||||
setFocusableWindowState(false);
|
setFocusableWindowState(false);
|
||||||
|
|
||||||
jlist.setBackground(BACKGROUND_COLOR);
|
jlist.setBackground(Tooltips.BACKGROUND);
|
||||||
jlist.setCellRenderer(new CodeCompletionListCellRenderer());
|
jlist.setCellRenderer(new CodeCompletionListCellRenderer());
|
||||||
/* add the ability to double-click a code completion */
|
/* add the ability to double-click a code completion */
|
||||||
MouseListener mouseListener = new MouseAdapter() {
|
MouseListener mouseListener = new MouseAdapter() {
|
||||||
|
@ -105,11 +88,11 @@ public class CodeCompletionWindow extends JDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a KeyEvent for this Window.
|
* Process a KeyEvent for this Window.
|
||||||
*
|
*
|
||||||
* This method is located here so that others (e.g. ConsolePlugin) can
|
* This method is located here so that others (e.g. ConsolePlugin) can
|
||||||
* forward KeyEvents to us, or we can process KeyEvents that were directed
|
* forward KeyEvents to us, or we can process KeyEvents that were directed
|
||||||
* to us (because we had focus instead).
|
* to us (because we had focus instead).
|
||||||
*
|
*
|
||||||
* @param e KeyEvent
|
* @param e KeyEvent
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,22 +102,22 @@ public class CodeCompletionWindow extends JDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the completion list with the given completion mapping.
|
* Updates the completion list with the given completion mapping.
|
||||||
*
|
*
|
||||||
* The format, as mentioned above, is:
|
* The format, as mentioned above, is:
|
||||||
* "attribute" -> "substitution value"
|
* "attribute" -> "substitution value"
|
||||||
* If the substitution value is null, then that attribute will not be
|
* If the substitution value is null, then that attribute will not be
|
||||||
* selectable for substitution.
|
* selectable for substitution.
|
||||||
*
|
*
|
||||||
* After updating the mapping, this Window then updates its size as
|
* After updating the mapping, this Window then updates its size as
|
||||||
* appropriate.
|
* appropriate.
|
||||||
*
|
*
|
||||||
* The Window also will attempt to move out of the way of the cursor/caret
|
* The Window also will attempt to move out of the way of the cursor/caret
|
||||||
* in the textField. However, if the caret's position had recently been
|
* in the textField. However, if the caret's position had recently been
|
||||||
* changed and the caret had not been repainted yet, then the caret's
|
* changed and the caret had not been repainted yet, then the caret's
|
||||||
* location can be null. In this case, the Window will not move.
|
* location can be null. In this case, the Window will not move.
|
||||||
* You can avoid this condition by calling this method in a
|
* You can avoid this condition by calling this method in a
|
||||||
* SwingUtilities.invokeLater(Runnable).
|
* SwingUtilities.invokeLater(Runnable).
|
||||||
*
|
*
|
||||||
* @param list List of code completions
|
* @param list List of code completions
|
||||||
*/
|
*/
|
||||||
public void updateCompletionList(List<CodeCompletion> list) {
|
public void updateCompletionList(List<CodeCompletion> list) {
|
||||||
|
@ -257,9 +240,9 @@ public class CodeCompletionWindow extends JDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Font on this CodeCompletionWindow.
|
* Sets the Font on this CodeCompletionWindow.
|
||||||
*
|
*
|
||||||
* Basically sets the Font in the completion list.
|
* Basically sets the Font in the completion list.
|
||||||
*
|
*
|
||||||
* @param font the new Font
|
* @param font the new Font
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -303,9 +286,9 @@ public class CodeCompletionWindow extends JDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently selected code completion.
|
* Returns the currently selected code completion.
|
||||||
*
|
*
|
||||||
* Returns "" if there is none.
|
* Returns "" if there is none.
|
||||||
*
|
*
|
||||||
* @return the currently selected code completion, or null if none selected
|
* @return the currently selected code completion, or null if none selected
|
||||||
*/
|
*/
|
||||||
public CodeCompletion getCompletion() {
|
public CodeCompletion getCompletion() {
|
||||||
|
@ -359,12 +342,12 @@ class CodeCompletionListModel implements ListModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This data type handles selection changes in the CodeCompletionWindow.
|
* This data type handles selection changes in the CodeCompletionWindow.
|
||||||
*
|
*
|
||||||
* This contains all the "smarts" to determine whether or not indices can be
|
* This contains all the "smarts" to determine whether or not indices can be
|
||||||
* selected. So when the user clicks on an entry with the mouse, we choose
|
* selected. So when the user clicks on an entry with the mouse, we choose
|
||||||
* whether or not that index can actually be highlighted/selected.
|
* whether or not that index can actually be highlighted/selected.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CodeCompletionListSelectionModel extends DefaultListSelectionModel {
|
class CodeCompletionListSelectionModel extends DefaultListSelectionModel {
|
||||||
|
@ -372,7 +355,7 @@ class CodeCompletionListSelectionModel extends DefaultListSelectionModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new CodeCompletionListSelectionModel using the given List.
|
* Constructs a new CodeCompletionListSelectionModel using the given List.
|
||||||
*
|
*
|
||||||
* @param l the List to use
|
* @param l the List to use
|
||||||
*/
|
*/
|
||||||
public CodeCompletionListSelectionModel(List<CodeCompletion> l) {
|
public CodeCompletionListSelectionModel(List<CodeCompletion> l) {
|
||||||
|
@ -382,10 +365,10 @@ class CodeCompletionListSelectionModel extends DefaultListSelectionModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the selection needs updating.
|
* Called when the selection needs updating.
|
||||||
*
|
*
|
||||||
* Here we will check the value of the new index and determine whether or
|
* Here we will check the value of the new index and determine whether or
|
||||||
* not we actually want to select it.
|
* not we actually want to select it.
|
||||||
*
|
*
|
||||||
* @param index0 old index
|
* @param index0 old index
|
||||||
* @param index1 new index
|
* @param index1 new index
|
||||||
*/
|
*/
|
||||||
|
@ -405,9 +388,6 @@ class CodeCompletionListSelectionModel extends DefaultListSelectionModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders CodeCompletions for the CodeCompletionWindow.
|
* Renders CodeCompletions for the CodeCompletionWindow.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
|
class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
|
||||||
|
|
||||||
|
@ -418,21 +398,21 @@ class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render either a default list cell, or use the one provided.
|
* Render either a default list cell, or use the one provided.
|
||||||
*
|
*
|
||||||
* If the CodeCompletion we got has a Component to be used, then use that.
|
* If the CodeCompletion we got has a Component to be used, then use that.
|
||||||
* Otherwise, we use the DefaultListCellRenderer routine.
|
* Otherwise, we use the DefaultListCellRenderer routine.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Component getListCellRendererComponent(JList<? extends CodeCompletion> list,
|
public Component getListCellRendererComponent(JList<? extends CodeCompletion> list,
|
||||||
CodeCompletion codeCompletion, int index, boolean isSelected, boolean cellHasFocus) {
|
CodeCompletion codeCompletion, int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
if (null == codeCompletion.getComponent()) {
|
if (codeCompletion.getComponent() == null) {
|
||||||
return super.getListCellRendererComponent(list, codeCompletion, index, isSelected,
|
return super.getListCellRendererComponent(list, codeCompletion, index, isSelected,
|
||||||
cellHasFocus);
|
cellHasFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ooh, we have a fancy component! */
|
|
||||||
JComponent component = codeCompletion.getComponent();
|
JComponent component = codeCompletion.getComponent();
|
||||||
/* if it's selected, make sure it shows up that way */
|
|
||||||
|
// if it's selected, make sure it shows up that way
|
||||||
component.setOpaque(true);
|
component.setOpaque(true);
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
component.setBackground(list.getSelectionBackground());
|
component.setBackground(list.getSelectionBackground());
|
||||||
|
@ -440,7 +420,7 @@ class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
|
||||||
else {
|
else {
|
||||||
component.setBackground(list.getBackground());
|
component.setBackground(list.getBackground());
|
||||||
}
|
}
|
||||||
/* other nice formatting stuff */
|
|
||||||
component.setEnabled(list.isEnabled());
|
component.setEnabled(list.isEnabled());
|
||||||
component.setFont(list.getFont());
|
component.setFont(list.getFont());
|
||||||
component.setComponentOrientation(list.getComponentOrientation());
|
component.setComponentOrientation(list.getComponentOrientation());
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.util.*;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import docking.widgets.table.GTableCellRenderingData;
|
import docking.widgets.table.GTableCellRenderingData;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -127,8 +126,7 @@ class LocationReferencesTableModel extends AddressBasedTableModel<LocationRefere
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
private class ContextTableColumn
|
private class ContextTableColumn
|
||||||
extends
|
extends AbstractProgramBasedDynamicTableColumn<LocationReference, LocationReference> {
|
||||||
AbstractProgramBasedDynamicTableColumn<LocationReference, LocationReference> {
|
|
||||||
|
|
||||||
private ContextCellRenderer renderer = new ContextCellRenderer();
|
private ContextCellRenderer renderer = new ContextCellRenderer();
|
||||||
|
|
||||||
|
@ -189,8 +187,7 @@ class LocationReferencesTableModel extends AddressBasedTableModel<LocationRefere
|
||||||
if (!StringUtils.isBlank(refType)) {
|
if (!StringUtils.isBlank(refType)) {
|
||||||
String trailingText = "";
|
String trailingText = "";
|
||||||
if (rowObject.isOffcutReference()) {
|
if (rowObject.isOffcutReference()) {
|
||||||
setForeground(
|
setForeground(getErrorForegroundColor(isSelected));
|
||||||
isSelected ? Tables.FG_ERROR_SELECTED : Tables.FG_ERROR_UNSELECTED);
|
|
||||||
trailingText = OFFCUT_STRING;
|
trailingText = OFFCUT_STRING;
|
||||||
}
|
}
|
||||||
return refType + trailingText;
|
return refType + trailingText;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.Gui;
|
import generic.theme.Gui;
|
||||||
|
|
||||||
public class KnotLabelPanel extends JPanel {
|
public class KnotLabelPanel extends JPanel {
|
||||||
|
@ -55,7 +55,7 @@ public class KnotLabelPanel extends JPanel {
|
||||||
int fontOffset = ascent / 3; // this looks about right
|
int fontOffset = ascent / 3; // this looks about right
|
||||||
ArrayList<KnotRecord> knots = palette.getKnots();
|
ArrayList<KnotRecord> knots = palette.getKnots();
|
||||||
|
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.drawLine(5, topBottomMargin - 6, 10, topBottomMargin - ascent + 2);
|
g.drawLine(5, topBottomMargin - 6, 10, topBottomMargin - ascent + 2);
|
||||||
g.drawString("min entropy (0.0)", 20, topBottomMargin - ascent - descent);
|
g.drawString("min entropy (0.0)", 20, topBottomMargin - ascent - descent);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public class KnotLabelPanel extends JPanel {
|
||||||
g.drawLine(5, y, 10, y);
|
g.drawLine(5, y, 10, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.drawLine(5, height + topBottomMargin + 4, 10, height + topBottomMargin + 8);
|
g.drawLine(5, height + topBottomMargin + 4, 10, height + topBottomMargin + 8);
|
||||||
g.drawString("max entropy (8.0)", 20, topBottomMargin + height + ascent + descent);
|
g.drawString("max entropy (8.0)", 20, topBottomMargin + height + ascent + descent);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import java.awt.*;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
|
|
||||||
public class PalettePanel extends JPanel {
|
public class PalettePanel extends JPanel {
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public class PalettePanel extends JPanel {
|
||||||
|
|
||||||
g.setColor(getBackground());
|
g.setColor(getBackground());
|
||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
g.fillRect(0, 0, getWidth(), getHeight());
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
if (palette == null) {
|
if (palette == null) {
|
||||||
g.drawRect(0, 0, width - 1, height - 1);
|
g.drawRect(0, 0, width - 1, height - 1);
|
||||||
return;
|
return;
|
||||||
|
@ -64,7 +64,7 @@ public class PalettePanel extends JPanel {
|
||||||
g.setColor(c);
|
g.setColor(c);
|
||||||
g.fillRect(0, topBottomMargin + i, width, 1);
|
g.fillRect(0, topBottomMargin + i, width, 1);
|
||||||
}
|
}
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.drawRect(0, topBottomMargin, width - 1, height);
|
g.drawRect(0, topBottomMargin, width - 1, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import javax.swing.text.Document;
|
||||||
|
|
||||||
import docking.widgets.list.GListCellRenderer;
|
import docking.widgets.list.GListCellRenderer;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +154,7 @@ class ProgramListPanel extends JPanel {
|
||||||
|
|
||||||
// add some padding around the panel
|
// add some padding around the panel
|
||||||
Border innerBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
|
Border innerBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
|
||||||
Border outerBorder = BorderFactory.createLineBorder(Java.BORDER);
|
Border outerBorder = BorderFactory.createLineBorder(Colors.BORDER);
|
||||||
Border compoundBorder = BorderFactory.createCompoundBorder(outerBorder, innerBorder);
|
Border compoundBorder = BorderFactory.createCompoundBorder(outerBorder, innerBorder);
|
||||||
setBorder(compoundBorder);
|
setBorder(compoundBorder);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import docking.widgets.label.GDLabel;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import ghidra.app.util.AddressInput;
|
import ghidra.app.util.AddressInput;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
|
@ -534,7 +533,7 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
model = new HistoryTableModel(fromCodeUnit.getProgram());
|
model = new HistoryTableModel(fromCodeUnit.getProgram());
|
||||||
displayTable = new JTable(model);
|
displayTable = new JTable(model);
|
||||||
displayTable.setTableHeader(null);
|
displayTable.setTableHeader(null);
|
||||||
displayTable.setBorder(new LineBorder(Java.BORDER));
|
displayTable.setBorder(new LineBorder(Colors.BORDER));
|
||||||
displayTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
displayTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
|
||||||
displayTable.addMouseListener(new MouseAdapter() {
|
displayTable.addMouseListener(new MouseAdapter() {
|
||||||
|
|
|
@ -37,7 +37,6 @@ import docking.widgets.checkbox.GCheckBox;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
import ghidra.app.util.SelectionTransferData;
|
import ghidra.app.util.SelectionTransferData;
|
||||||
import ghidra.app.util.SelectionTransferable;
|
import ghidra.app.util.SelectionTransferable;
|
||||||
|
@ -115,7 +114,7 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set drag feedback according to the ok parameter.
|
* Set drag feedback according to the ok parameter.
|
||||||
*
|
*
|
||||||
* @param ok true means the drop action is OK
|
* @param ok true means the drop action is OK
|
||||||
* @param e event that has current state of drag and drop operation
|
* @param e event that has current state of drag and drop operation
|
||||||
*/
|
*/
|
||||||
|
@ -127,7 +126,7 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
/**
|
/**
|
||||||
* Return true if is OK to drop the transferable at the location
|
* Return true if is OK to drop the transferable at the location
|
||||||
* specified the event.
|
* specified the event.
|
||||||
*
|
*
|
||||||
* @param e event that has current state of drag and drop operation
|
* @param e event that has current state of drag and drop operation
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,8 +135,7 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
Memory memory = currentCodeUnit.getProgram().getMemory();
|
Memory memory = currentCodeUnit.getProgram().getMemory();
|
||||||
try {
|
try {
|
||||||
Object data = e.getTransferable()
|
Object data = e.getTransferable()
|
||||||
.getTransferData(
|
.getTransferData(SelectionTransferable.localProgramSelectionFlavor);
|
||||||
SelectionTransferable.localProgramSelectionFlavor);
|
|
||||||
AddressSetView view = ((SelectionTransferData) data).getAddressSet();
|
AddressSetView view = ((SelectionTransferData) data).getAddressSet();
|
||||||
if (memory.contains(view)) {
|
if (memory.contains(view)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -164,7 +162,7 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
/**
|
/**
|
||||||
* Add the object to the droppable component. The DropTargetAdapter
|
* Add the object to the droppable component. The DropTargetAdapter
|
||||||
* calls this method from its drop() method.
|
* calls this method from its drop() method.
|
||||||
*
|
*
|
||||||
* @param obj Transferable object that is to be dropped; in this case,
|
* @param obj Transferable object that is to be dropped; in this case,
|
||||||
* it is an AddressSetView
|
* it is an AddressSetView
|
||||||
* @param e has current state of drop operation
|
* @param e has current state of drop operation
|
||||||
|
@ -289,8 +287,8 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
enableGotoReferenceLocation(gotoReferenceLocationToggleAction.isSelected());
|
enableGotoReferenceLocation(gotoReferenceLocationToggleAction.isSelected());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gotoReferenceLocationToggleAction.setToolBarData(
|
gotoReferenceLocationToggleAction
|
||||||
new ToolBarData(SEND_LOCATION_ICON, "NavAction"));
|
.setToolBarData(new ToolBarData(SEND_LOCATION_ICON, "NavAction"));
|
||||||
gotoReferenceLocationToggleAction.setEnabled(true);
|
gotoReferenceLocationToggleAction.setEnabled(true);
|
||||||
tool.addLocalAction(this, gotoReferenceLocationToggleAction);
|
tool.addLocalAction(this, gotoReferenceLocationToggleAction);
|
||||||
|
|
||||||
|
@ -527,7 +525,7 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the Data at the currentCuAddress
|
* Find the Data at the currentCuAddress
|
||||||
*
|
*
|
||||||
* @param data place to begin searching
|
* @param data place to begin searching
|
||||||
* @return Data starting at currentCuAddress
|
* @return Data starting at currentCuAddress
|
||||||
*/
|
*/
|
||||||
|
@ -852,7 +850,7 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Inner Classes
|
// Inner Classes
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
/** Fun little storage object */
|
/** Fun little storage object */
|
||||||
private class ReferenceInfo {
|
private class ReferenceInfo {
|
||||||
|
@ -890,8 +888,8 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference ref = tableModel.getReference(row);
|
Reference ref = tableModel.getReference(row);
|
||||||
RefType[] refTypes = EditReferencesModel.getAllowedRefTypes(
|
RefType[] refTypes = EditReferencesModel
|
||||||
EditReferencesProvider.this.currentProgram, ref);
|
.getAllowedRefTypes(EditReferencesProvider.this.currentProgram, ref);
|
||||||
|
|
||||||
comboBox.removeAllItems();
|
comboBox.removeAllItems();
|
||||||
int selectedIndex = -1;
|
int selectedIndex = -1;
|
||||||
|
@ -913,10 +911,6 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
private class CellEditComboBox extends JComboBox<RefType> {
|
private class CellEditComboBox extends JComboBox<RefType> {
|
||||||
|
|
||||||
public CellEditComboBox() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSelectedIndex(int anIndex) {
|
public void setSelectedIndex(int anIndex) {
|
||||||
if (refsTable.getRowCount() == 0) {
|
if (refsTable.getRowCount() == 0) {
|
||||||
|
@ -1035,40 +1029,27 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
super.getTableCellRendererComponent(data);
|
super.getTableCellRendererComponent(data);
|
||||||
|
|
||||||
JTable table = data.getTable();
|
|
||||||
int row = data.getRowViewIndex();
|
int row = data.getRowViewIndex();
|
||||||
boolean isSelected = data.isSelected();
|
boolean isSelected = data.isSelected();
|
||||||
|
|
||||||
Reference ref = tableModel.getReference(row);
|
Reference ref = tableModel.getReference(row);
|
||||||
|
|
||||||
Address addr = ref.getToAddress();
|
Address addr = ref.getToAddress();
|
||||||
Memory memory = tableModel.getProgram().getMemory();
|
Memory memory = tableModel.getProgram().getMemory();
|
||||||
boolean bad = addr.isMemoryAddress() ? !memory.contains(addr) : false;
|
boolean bad = addr.isMemoryAddress() ? !memory.contains(addr) : false;
|
||||||
|
|
||||||
setOpaque(false); // disable table striping
|
// disable table striping when not selected to reduce clutter
|
||||||
setFont(table.getFont());
|
setOpaque(isSelected);
|
||||||
|
|
||||||
if (isSelected) {
|
if (bad) {
|
||||||
if (bad) {
|
setForeground(getErrorForegroundColor(isSelected));
|
||||||
setForeground(Tables.FG_ERROR_SELECTED);
|
setFont(boldFont);
|
||||||
setFont(boldFont);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setFont(defaultFont);
|
|
||||||
}
|
|
||||||
|
|
||||||
setOpaque(true);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// set color to red if address does not exist in memory
|
setFont(defaultFont);
|
||||||
|
}
|
||||||
|
|
||||||
if (bad) {
|
// use a special color when not selected to show which row matches the operand
|
||||||
setForeground(Tables.FG_ERROR_UNSELECTED);
|
if (!isSelected) {
|
||||||
setFont(boldFont);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setFont(defaultFont);
|
|
||||||
}
|
|
||||||
if (ref.getOperandIndex() == instrPanel.getSelectedOpIndex()) {
|
if (ref.getOperandIndex() == instrPanel.getSelectedOpIndex()) {
|
||||||
setBackground(BG_COLOR_ACTIVE_OPERAND);
|
setBackground(BG_COLOR_ACTIVE_OPERAND);
|
||||||
setOpaque(true);
|
setOpaque(true);
|
||||||
|
|
|
@ -372,7 +372,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
|
||||||
KeyBindingsInfo info = (KeyBindingsInfo) value;
|
KeyBindingsInfo info = (KeyBindingsInfo) value;
|
||||||
|
|
||||||
if (info.errorMessage != null) {
|
if (info.errorMessage != null) {
|
||||||
component.setForeground(Tables.FG_ERROR_UNSELECTED);
|
component.setForeground(Tables.ERROR_UNSELECTED);
|
||||||
component.setToolTipText(info.errorMessage);
|
component.setToolTipText(info.errorMessage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -394,7 +394,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
JTable table = data.getTable();
|
JTable table = data.getTable();
|
||||||
Color selectedForegroundColor =
|
Color selectedForegroundColor =
|
||||||
(info.errorMessage != null) ? Tables.FG_ERROR_SELECTED
|
(info.errorMessage != null) ? Tables.ERROR_SELECTED
|
||||||
: table.getSelectionForeground();
|
: table.getSelectionForeground();
|
||||||
component.setForeground(selectedForegroundColor);
|
component.setForeground(selectedForegroundColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import docking.widgets.checkbox.GCheckBox;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import generic.theme.Gui;
|
import generic.theme.Gui;
|
||||||
|
|
||||||
class TipOfTheDayDialog extends ReusableDialogComponentProvider {
|
class TipOfTheDayDialog extends ReusableDialogComponentProvider {
|
||||||
|
@ -88,7 +87,7 @@ class TipOfTheDayDialog extends ReusableDialogComponentProvider {
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
JPanel panel = new JPanel(new BorderLayout());
|
||||||
Border panelBorder =
|
Border panelBorder =
|
||||||
BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10),
|
BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10),
|
||||||
BorderFactory.createLineBorder(Java.BORDER));
|
BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
panel.setBorder(panelBorder);
|
panel.setBorder(panelBorder);
|
||||||
|
|
||||||
JLabel label = new GLabel("Did you know...", tipIcon, SwingConstants.LEFT);
|
JLabel label = new GLabel("Did you know...", tipIcon, SwingConstants.LEFT);
|
||||||
|
|
|
@ -48,7 +48,6 @@ import docking.widgets.table.threaded.ThreadedTableModel;
|
||||||
import docking.widgets.tree.GTree;
|
import docking.widgets.tree.GTree;
|
||||||
import generic.test.AbstractGenericTest;
|
import generic.test.AbstractGenericTest;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import generic.util.image.ImageUtils;
|
import generic.util.image.ImageUtils;
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
|
@ -423,7 +422,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
||||||
captureComponent(window);
|
captureComponent(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawBorder(Java.BORDER);
|
drawBorder(Colors.BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JPopupMenu getPopupMenu() {
|
public JPopupMenu getPopupMenu() {
|
||||||
|
@ -1375,7 +1374,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRectangleWithDropShadowAround(JComponent component, Color color, int padding) {
|
public void drawRectangleWithDropShadowAround(JComponent component, Color color, int padding) {
|
||||||
Rectangle r = drawRectangleAround(component, Java.BORDER, padding);
|
Rectangle r = drawRectangleAround(component, Colors.BORDER, padding);
|
||||||
|
|
||||||
// move it back a bit to create the drop-shadow effect
|
// move it back a bit to create the drop-shadow effect
|
||||||
r.x -= padding;
|
r.x -= padding;
|
||||||
|
@ -1628,7 +1627,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
||||||
|
|
||||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
g2.setColor(Java.BORDER);
|
g2.setColor(Colors.BORDER);
|
||||||
g2.setStroke(new BasicStroke(3f));
|
g2.setStroke(new BasicStroke(3f));
|
||||||
g2.draw(topPath);
|
g2.draw(topPath);
|
||||||
g2.draw(bottomPath);
|
g2.draw(bottomPath);
|
||||||
|
|
|
@ -33,7 +33,7 @@ import docking.action.DockingAction;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import docking.widgets.combobox.GComboBox;
|
import docking.widgets.combobox.GComboBox;
|
||||||
import docking.widgets.label.*;
|
import docking.widgets.label.*;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.bean.GGlassPane;
|
import ghidra.util.bean.GGlassPane;
|
||||||
|
@ -179,12 +179,12 @@ public class ImageDialogProvider extends DialogComponentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
newLabelPanel.add(createImageLabelComponent("New Image"), BorderLayout.NORTH);
|
newLabelPanel.add(createImageLabelComponent("New Image"), BorderLayout.NORTH);
|
||||||
newLabelPanel.setBorder(BorderFactory.createLineBorder(Java.BORDER, 20));
|
newLabelPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER, 20));
|
||||||
newLabelPanel.add(newImageLabel, BorderLayout.CENTER);
|
newLabelPanel.add(newImageLabel, BorderLayout.CENTER);
|
||||||
|
|
||||||
JPanel oldLabelPanel = new JPanel(new BorderLayout());
|
JPanel oldLabelPanel = new JPanel(new BorderLayout());
|
||||||
oldLabelPanel.add(createImageLabelComponent("Old Image"), BorderLayout.NORTH);
|
oldLabelPanel.add(createImageLabelComponent("Old Image"), BorderLayout.NORTH);
|
||||||
oldLabelPanel.setBorder(BorderFactory.createLineBorder(Java.BORDER, 20));
|
oldLabelPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER, 20));
|
||||||
oldLabelPanel.add(oldImageLabel, BorderLayout.CENTER);
|
oldLabelPanel.add(oldImageLabel, BorderLayout.CENTER);
|
||||||
|
|
||||||
imagePanel.add(oldLabelPanel, BorderLayout.WEST);
|
imagePanel.add(oldLabelPanel, BorderLayout.WEST);
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.FGEdge;
|
import ghidra.app.plugin.core.functiongraph.graph.FGEdge;
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.FGVertexType;
|
import ghidra.app.plugin.core.functiongraph.graph.FGVertexType;
|
||||||
import ghidra.app.plugin.core.functiongraph.mvc.FGController;
|
import ghidra.app.plugin.core.functiongraph.mvc.FGController;
|
||||||
|
@ -40,14 +39,18 @@ import ghidra.program.util.ProgramSelection;
|
||||||
*/
|
*/
|
||||||
public interface FGVertex extends VisualVertex {
|
public interface FGVertex extends VisualVertex {
|
||||||
|
|
||||||
static final Color TOOLTIP_BACKGROUND_COLOR = Colors.BG_TOOLTIP;
|
|
||||||
|
|
||||||
public FGVertex cloneVertex(FGController newController);
|
public FGVertex cloneVertex(FGController newController);
|
||||||
|
|
||||||
/** A chance for this vertex to save off changed settings */
|
/**
|
||||||
|
* A chance for this vertex to save off changed settings
|
||||||
|
* @param settings the settings
|
||||||
|
*/
|
||||||
public void writeSettings(FunctionGraphVertexAttributes settings);
|
public void writeSettings(FunctionGraphVertexAttributes settings);
|
||||||
|
|
||||||
/** A chance for this vertex to read in stored settings */
|
/**
|
||||||
|
* A chance for this vertex to read in stored settings
|
||||||
|
* @param settings the settings
|
||||||
|
*/
|
||||||
public void readSettings(FunctionGraphVertexAttributes settings);
|
public void readSettings(FunctionGraphVertexAttributes settings);
|
||||||
|
|
||||||
public void restoreColor(Color color);
|
public void restoreColor(Color color);
|
||||||
|
@ -58,7 +61,7 @@ public interface FGVertex extends VisualVertex {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the vertex type. This can only be called once. Repeated calls will except.
|
* Sets the vertex type. This can only be called once. Repeated calls will except.
|
||||||
*
|
*
|
||||||
* @param vertexType the type
|
* @param vertexType the type
|
||||||
*/
|
*/
|
||||||
public void setVertexType(FGVertexType vertexType);
|
public void setVertexType(FGVertexType vertexType);
|
||||||
|
@ -70,7 +73,7 @@ public interface FGVertex extends VisualVertex {
|
||||||
* an entry if it is a source, with no incoming edges. This vertex can be considered an
|
* an entry if it is a source, with no incoming edges. This vertex can be considered an
|
||||||
* entry even if it has incoming edges, such as when another function directly calls the
|
* entry even if it has incoming edges, such as when another function directly calls the
|
||||||
* code block associated with this vertex.
|
* code block associated with this vertex.
|
||||||
*
|
*
|
||||||
* @return true if this vertex is an entry
|
* @return true if this vertex is an entry
|
||||||
*/
|
*/
|
||||||
public boolean isEntry();
|
public boolean isEntry();
|
||||||
|
@ -95,9 +98,9 @@ public interface FGVertex extends VisualVertex {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals to this vertex that it is associated with a group
|
* Signals to this vertex that it is associated with a group
|
||||||
*
|
*
|
||||||
* @param groupInfo the new group info for this vertex; null if the vertex is no longer part
|
* @param groupInfo the new group info for this vertex; null if the vertex is no longer part
|
||||||
* of a group
|
* of a group
|
||||||
*/
|
*/
|
||||||
public void updateGroupAssociationStatus(GroupHistoryInfo groupInfo);
|
public void updateGroupAssociationStatus(GroupHistoryInfo groupInfo);
|
||||||
|
|
||||||
|
@ -149,46 +152,46 @@ public interface FGVertex extends VisualVertex {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits the label for the vertex. This could be the label for the minimum address of the
|
* Edits the label for the vertex. This could be the label for the minimum address of the
|
||||||
* vertex's code block or this could be the text of the vertex's display (as it is for a
|
* vertex's code block or this could be the text of the vertex's display (as it is for a
|
||||||
* grouped vertex).
|
* grouped vertex).
|
||||||
*
|
*
|
||||||
* @param component the parent component of any shown dialogs
|
* @param component the parent component of any shown dialogs
|
||||||
*/
|
*/
|
||||||
public void editLabel(JComponent component);
|
public void editLabel(JComponent component);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the clicked component is or is inside of the header of the vertex
|
* Returns true if the clicked component is or is inside of the header of the vertex
|
||||||
*
|
*
|
||||||
* @param clickedComponent the clicked component
|
* @param clickedComponent the clicked component
|
||||||
* @return true if the clicked component is or is inside of the header of the vertex
|
* @return true if the clicked component is or is inside of the header of the vertex
|
||||||
*/
|
*/
|
||||||
public boolean isHeaderClick(Component clickedComponent);
|
public boolean isHeaderClick(Component clickedComponent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that this vertex is being rendered such that it takes up the entire graph
|
* Signals that this vertex is being rendered such that it takes up the entire graph
|
||||||
* window.
|
* window.
|
||||||
*
|
*
|
||||||
* @return true if full-screen
|
* @return true if full-screen
|
||||||
*/
|
*/
|
||||||
public boolean isFullScreenMode();
|
public boolean isFullScreenMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this vertex is in full-screen mode. When in full-screen, a larger
|
* Sets whether this vertex is in full-screen mode. When in full-screen, a larger
|
||||||
* view of the code block will be provided. When not in full-screen, a condensed view
|
* view of the code block will be provided. When not in full-screen, a condensed view
|
||||||
* of this vertex is provided.
|
* of this vertex is provided.
|
||||||
*
|
*
|
||||||
* @param fullScreen true for full-screen
|
* @param fullScreen true for full-screen
|
||||||
*/
|
*/
|
||||||
public void setFullScreenMode(boolean fullScreen);
|
public void setFullScreenMode(boolean fullScreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full-screen view of this vertex.
|
* Returns the full-screen view of this vertex.
|
||||||
* @return the full-screen view
|
* @return the full-screen view
|
||||||
*/
|
*/
|
||||||
public Component getMaximizedViewComponent();
|
public Component getMaximizedViewComponent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals to rebuild this vertex's data model. This call will not do any real work
|
* Signals to rebuild this vertex's data model. This call will not do any real work
|
||||||
* if the model is not 'dirty'.
|
* if the model is not 'dirty'.
|
||||||
*/
|
*/
|
||||||
public void refreshModel();
|
public void refreshModel();
|
||||||
|
@ -205,13 +208,13 @@ public interface FGVertex extends VisualVertex {
|
||||||
public void refreshDisplayForAddress(Address address);
|
public void refreshDisplayForAddress(Address address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells this vertex whether it is showing. This actually overrides the underlying
|
* Tells this vertex whether it is showing. This actually overrides the underlying
|
||||||
* Java component's {@link JComponent#isShowing()} method in order to prevent it from
|
* Java component's {@link JComponent#isShowing()} method in order to prevent it from
|
||||||
* showing tooltips (we manage tooltips ourselves).
|
* showing tooltips (we manage tooltips ourselves).
|
||||||
*
|
*
|
||||||
* <P>We have to set this to true painting, but then false when we are done (Java
|
* <P>We have to set this to true painting, but then false when we are done (Java
|
||||||
* components will not paint themselves if the are not showing).
|
* components will not paint themselves if the are not showing).
|
||||||
*
|
*
|
||||||
* @param isShowing true if the component is showing
|
* @param isShowing true if the component is showing
|
||||||
*/
|
*/
|
||||||
public void setShowing(boolean isShowing);
|
public void setShowing(boolean isShowing);
|
||||||
|
|
|
@ -40,6 +40,7 @@ import docking.widgets.label.GDLabel;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
|
import generic.theme.GThemeDefaults.Colors.Tooltips;
|
||||||
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
|
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
|
||||||
import ghidra.app.plugin.core.functiongraph.FunctionGraphPlugin;
|
import ghidra.app.plugin.core.functiongraph.FunctionGraphPlugin;
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.FGEdge;
|
import ghidra.app.plugin.core.functiongraph.graph.FGEdge;
|
||||||
|
@ -203,7 +204,7 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
|
||||||
boolean useFullSizeTooltip = options.useFullSizeTooltip();
|
boolean useFullSizeTooltip = options.useFullSizeTooltip();
|
||||||
previewListingPanel = new FGVertexListingPanel(controller,
|
previewListingPanel = new FGVertexListingPanel(controller,
|
||||||
getFormatManager(useFullSizeTooltip), program, addressSet);
|
getFormatManager(useFullSizeTooltip), program, addressSet);
|
||||||
previewListingPanel.setTextBackgroundColor(FGVertex.TOOLTIP_BACKGROUND_COLOR);
|
previewListingPanel.setTextBackgroundColor(Tooltips.BACKGROUND);
|
||||||
previewListingPanel.getFieldPanel().setCursorOn(false);
|
previewListingPanel.getFieldPanel().setCursorOn(false);
|
||||||
|
|
||||||
// keep the tooltip window from getting too big; use an arbitrary, reasonable max
|
// keep the tooltip window from getting too big; use an arbitrary, reasonable max
|
||||||
|
@ -216,14 +217,14 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
|
||||||
|
|
||||||
tooltipTitleLabel = new GDLabel();
|
tooltipTitleLabel = new GDLabel();
|
||||||
tooltipTitleLabel.setHorizontalAlignment(SwingConstants.LEADING);
|
tooltipTitleLabel.setHorizontalAlignment(SwingConstants.LEADING);
|
||||||
tooltipTitleLabel.setBackground(FGVertex.TOOLTIP_BACKGROUND_COLOR);
|
tooltipTitleLabel.setBackground(Tooltips.BACKGROUND);
|
||||||
tooltipTitleLabel.setOpaque(true);
|
tooltipTitleLabel.setOpaque(true);
|
||||||
Font labelFont = tooltipTitleLabel.getFont();
|
Font labelFont = tooltipTitleLabel.getFont();
|
||||||
tooltipTitleLabel.setFont(labelFont.deriveFont(Font.BOLD));
|
tooltipTitleLabel.setFont(labelFont.deriveFont(Font.BOLD));
|
||||||
|
|
||||||
JPanel headerPanel = new JPanel(new BorderLayout());
|
JPanel headerPanel = new JPanel(new BorderLayout());
|
||||||
headerPanel.add(tooltipTitleLabel);
|
headerPanel.add(tooltipTitleLabel);
|
||||||
headerPanel.setBorder(BorderFactory.createLineBorder(Colors.Java.BORDER));
|
headerPanel.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
|
|
||||||
panel.add(headerPanel, BorderLayout.NORTH);
|
panel.add(headerPanel, BorderLayout.NORTH);
|
||||||
panel.add(previewListingPanel, BorderLayout.CENTER);
|
panel.add(previewListingPanel, BorderLayout.CENTER);
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.awt.event.ActionListener;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import generic.theme.GThemeDefaults;
|
import generic.theme.GThemeDefaults.Ids.Fonts;
|
||||||
import generic.theme.Gui;
|
import generic.theme.Gui;
|
||||||
import ghidra.feature.fid.db.*;
|
import ghidra.feature.fid.db.*;
|
||||||
import ghidra.feature.fid.service.FidService;
|
import ghidra.feature.fid.service.FidService;
|
||||||
|
@ -38,6 +38,7 @@ public class FidFunctionDebugPanel extends JPanel {
|
||||||
/**
|
/**
|
||||||
* Creates the panel.
|
* Creates the panel.
|
||||||
* @param service the FID database service
|
* @param service the FID database service
|
||||||
|
* @param fidQueryService the query service
|
||||||
* @param functionRecord the function record to debug
|
* @param functionRecord the function record to debug
|
||||||
*/
|
*/
|
||||||
public FidFunctionDebugPanel(FidService service, FidQueryService fidQueryService,
|
public FidFunctionDebugPanel(FidService service, FidQueryService fidQueryService,
|
||||||
|
@ -57,7 +58,7 @@ public class FidFunctionDebugPanel extends JPanel {
|
||||||
JButton button = new JButton(text);
|
JButton button = new JButton(text);
|
||||||
button.addActionListener(listener);
|
button.addActionListener(listener);
|
||||||
button.setHorizontalAlignment(SwingConstants.LEFT);
|
button.setHorizontalAlignment(SwingConstants.LEFT);
|
||||||
Gui.registerFont(button, GThemeDefaults.Ids.Fonts.MONOSPACED);
|
Gui.registerFont(button, Fonts.MONOSPACED);
|
||||||
add(button);
|
add(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ public class FidFunctionDebugPanel extends JPanel {
|
||||||
private void addLabel(String text) {
|
private void addLabel(String text) {
|
||||||
JLabel label = new GDLabel(text);
|
JLabel label = new GDLabel(text);
|
||||||
label.setHorizontalAlignment(SwingConstants.LEFT);
|
label.setHorizontalAlignment(SwingConstants.LEFT);
|
||||||
label.setFont(Gui.getFont("font.monospaced"));
|
Gui.registerFont(label, Fonts.MONOSPACED);
|
||||||
add(label);
|
add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,16 +86,14 @@ public class FidFunctionDebugPanel extends JPanel {
|
||||||
libraryRecord.getLibraryVersion(), libraryRecord.getLibraryVariant(),
|
libraryRecord.getLibraryVersion(), libraryRecord.getLibraryVariant(),
|
||||||
languageID.getIdAsString()));
|
languageID.getIdAsString()));
|
||||||
|
|
||||||
addButton(String.format("0x%016x", functionRecord.getID()),
|
addButton(String.format("0x%016x", functionRecord.getID()), e -> FidDebugUtils
|
||||||
e -> FidDebugUtils.searchByFunctionID(functionRecord.getID(), service,
|
.searchByFunctionID(functionRecord.getID(), service, fidQueryService));
|
||||||
fidQueryService));
|
|
||||||
|
|
||||||
addButton(functionRecord.getName(),
|
addButton(functionRecord.getName(),
|
||||||
e -> FidDebugUtils.searchByName(functionRecord.getName(), service, fidQueryService));
|
e -> FidDebugUtils.searchByName(functionRecord.getName(), service, fidQueryService));
|
||||||
|
|
||||||
addButton(shorten(functionRecord.getDomainPath()),
|
addButton(shorten(functionRecord.getDomainPath()), e -> FidDebugUtils
|
||||||
e -> FidDebugUtils.searchByDomainPath(functionRecord.getDomainPath(), service,
|
.searchByDomainPath(functionRecord.getDomainPath(), service, fidQueryService));
|
||||||
fidQueryService));
|
|
||||||
|
|
||||||
addLabel(String.format("Entry Point: 0x%x", functionRecord.getEntryPoint()));
|
addLabel(String.format("Entry Point: 0x%x", functionRecord.getEntryPoint()));
|
||||||
|
|
||||||
|
|
|
@ -77,13 +77,13 @@ public class FidSearchDebugDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
private JLabel getPreparedLabel(String text) {
|
private JLabel getPreparedLabel(String text) {
|
||||||
JLabel label = new GDLabel(text, SwingConstants.RIGHT);
|
JLabel label = new GDLabel(text, SwingConstants.RIGHT);
|
||||||
label.setFont(Gui.getFont(Fonts.MONOSPACED));
|
Gui.registerFont(label, Fonts.MONOSPACED);
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JTextField getPreparedTextField() {
|
private JTextField getPreparedTextField() {
|
||||||
JTextField textField = new JTextField(25);
|
JTextField textField = new JTextField(25);
|
||||||
textField.setFont(Gui.getFont(Fonts.MONOSPACED));
|
Gui.registerFont(textField, Fonts.MONOSPACED);
|
||||||
return textField;
|
return textField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@ import javax.swing.table.TableColumn;
|
||||||
import javax.swing.table.TableColumnModel;
|
import javax.swing.table.TableColumnModel;
|
||||||
|
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.GThemeDefaults.Ids.Fonts;
|
|
||||||
import generic.theme.Gui;
|
|
||||||
import ghidra.feature.fid.db.*;
|
import ghidra.feature.fid.db.*;
|
||||||
import ghidra.feature.fid.service.FidService;
|
import ghidra.feature.fid.service.FidService;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
@ -66,7 +64,7 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
|
||||||
|
|
||||||
private void buildFrame() {
|
private void buildFrame() {
|
||||||
GTableCellRenderer renderer = new GTableCellRenderer();
|
GTableCellRenderer renderer = new GTableCellRenderer();
|
||||||
renderer.setFont(Gui.getFont(Fonts.MONOSPACED));
|
renderer.setFont(renderer.getFixedWidthFont());
|
||||||
int columnCount = table.getColumnCount();
|
int columnCount = table.getColumnCount();
|
||||||
for (int ii = 0; ii < columnCount; ++ii) {
|
for (int ii = 0; ii < columnCount; ++ii) {
|
||||||
Class<?> columnClass = table.getColumnClass(ii);
|
Class<?> columnClass = table.getColumnClass(ii);
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
|
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.feature.vt.api.main.VTAssociationMarkupStatus;
|
import ghidra.feature.vt.api.main.VTAssociationMarkupStatus;
|
||||||
|
|
||||||
public class VTMarkupStatusIcon implements Icon {
|
public class VTMarkupStatusIcon implements Icon {
|
||||||
|
@ -74,7 +74,7 @@ public class VTMarkupStatusIcon implements Icon {
|
||||||
drawBar(g, x + startX + BORDER + 1, y + BORDER + 1, width, colors.get(i));
|
drawBar(g, x + startX + BORDER + 1, y + BORDER + 1, width, colors.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.drawRect(x, y, WIDTH, HEIGHT);
|
g.drawRect(x, y, WIDTH, HEIGHT);
|
||||||
// g.drawRect(x, y, WIDTH / 2, HEIGHT);
|
// g.drawRect(x, y, WIDTH / 2, HEIGHT);
|
||||||
g.drawRect(x + WIDTH, y + HEIGHT / 2 - 3, KNOB_WIDTH, 6);
|
g.drawRect(x + WIDTH, y + HEIGHT / 2 - 3, KNOB_WIDTH, 6);
|
||||||
|
|
|
@ -27,7 +27,9 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import docking.widgets.button.BrowseButton;
|
import docking.widgets.button.BrowseButton;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import docking.wizard.*;
|
import docking.wizard.*;
|
||||||
import generic.theme.*;
|
import generic.theme.GIcon;
|
||||||
|
import generic.theme.GThemeDefaults.Ids.Fonts;
|
||||||
|
import generic.theme.Gui;
|
||||||
import ghidra.app.util.task.OpenProgramTask;
|
import ghidra.app.util.task.OpenProgramTask;
|
||||||
import ghidra.app.util.task.OpenProgramTask.OpenProgramRequest;
|
import ghidra.app.util.task.OpenProgramTask.OpenProgramRequest;
|
||||||
import ghidra.framework.main.DataTreeDialog;
|
import ghidra.framework.main.DataTreeDialog;
|
||||||
|
@ -74,7 +76,7 @@ public class NewSessionPanel extends AbstractMageJPanel<VTWizardStateKey> {
|
||||||
folderLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
folderLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
folderLabel.setToolTipText("The folder to store the new Version Tracking Session");
|
folderLabel.setToolTipText("The folder to store the new Version Tracking Session");
|
||||||
folderNameField = new JTextField();
|
folderNameField = new JTextField();
|
||||||
Gui.registerFont(folderNameField, GThemeDefaults.Ids.Fonts.MONOSPACED);
|
Gui.registerFont(folderNameField, Fonts.MONOSPACED);
|
||||||
folderNameField.setEditable(false); // force user to browse to choose
|
folderNameField.setEditable(false); // force user to browse to choose
|
||||||
|
|
||||||
JButton browseFolderButton = new BrowseButton();
|
JButton browseFolderButton = new BrowseButton();
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META name="generator" content=
|
|
||||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
|
||||||
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
||||||
<TITLE>Developer's Guide</TITLE>
|
<TITLE>Developer's Guide</TITLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
@ -21,8 +19,8 @@
|
||||||
want to use colors, fonts, and icons. The key idea to support theming is to never
|
want to use colors, fonts, and icons. The key idea to support theming is to never
|
||||||
<B>directly</B>
|
<B>directly</B>
|
||||||
reference those resources. Instead, the developer should create an ID string for the resource
|
reference those resources. Instead, the developer should create an ID string for the resource
|
||||||
and then in a <CODE><I>module</I>.theme.properties</CODE> file, provide a default value for that ID.
|
and then in a <CODE><I>module</I>.theme.properties</CODE> file, provide a default value for that
|
||||||
(Also, you may define an alternate "dark" default value that will be used if the
|
ID. (Also, you may define an alternate "dark" default value that will be used if the
|
||||||
current theme is considered a dark theme). The way you
|
current theme is considered a dark theme). The way you
|
||||||
define and use these IDs is a bit different depending on whether the resource is a color, font,
|
define and use these IDs is a bit different depending on whether the resource is a color, font,
|
||||||
or icon. Colors and icons are similar in that developers use these types by creating either
|
or icon. Colors and icons are similar in that developers use these types by creating either
|
||||||
|
@ -182,6 +180,42 @@
|
||||||
<LI>icon.plugin.byteviewer.provider</LI>
|
<LI>icon.plugin.byteviewer.provider</LI>
|
||||||
</UL>
|
</UL>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<UL>
|
||||||
|
<LI><A NAME="System_IDs"></A><B>System IDs:</B> The following resource IDs are created and
|
||||||
|
used by the system. For a description of how these IDs are used internally by the
|
||||||
|
application, see the <CODE>UiDefaultsMapper</CODE> class . The <CODE>system.*</CODE> keys
|
||||||
|
allow users to quickly change many Look and Feel values via these high-level concepts. The
|
||||||
|
<CODE>laf.*</CODE> properties are for internal use and do not need to be changed by the user.
|
||||||
|
A description of the system properties can be found in the <CODE>SystemThemeIds</CODE> class.
|
||||||
|
</LI>
|
||||||
|
</UL>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
|
||||||
|
<UL>
|
||||||
|
<LI>laf.color.*</LI>
|
||||||
|
<LI>laf.font.*</LI>
|
||||||
|
<LI>laf.icon.*</LI>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
|
||||||
|
<UL>
|
||||||
|
<LI>system.color.*</LI>
|
||||||
|
<LI>system.font.*</LI>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The <CODE>system</CODE> property names use the standard property names, such as <CODE>
|
||||||
|
font, bg</CODE> and <CODE>fg</CODE>. These properties introduce these additional terms:
|
||||||
|
<CODE>control, view, menu and tooltip</CODE>. <CODE>control</CODE> refers to items that
|
||||||
|
generally control the state of the application, such as buttons and check boxes.
|
||||||
|
<CODE>view</CODE> refers to widgets that display data, such as trees, tables and text
|
||||||
|
fields. <CODE>menu</CODE> and <CODE>tooltip</CODE> work with the items after which they are
|
||||||
|
named.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H2>Theme Property Files</H2>
|
<H2>Theme Property Files</H2>
|
||||||
|
@ -198,7 +232,7 @@
|
||||||
they exist in a module's data directory and are named with the
|
they exist in a module's data directory and are named with the
|
||||||
<CODE>.theme.properties</CODE> suffix.</P>
|
<CODE>.theme.properties</CODE> suffix.</P>
|
||||||
|
|
||||||
<H3>Theme Properties File Naming Convention</H3>
|
<H3><A NAME="Theme_Property_Names"></A>Theme Properties File Naming Convention</H3>
|
||||||
|
|
||||||
<P>To promote consistency, theme property files should use the following naming
|
<P>To promote consistency, theme property files should use the following naming
|
||||||
convention:</P>
|
convention:</P>
|
||||||
|
@ -260,7 +294,7 @@ color.bg.listing = color.bg
|
||||||
color.fg.listing.address = black
|
color.fg.listing.address = black
|
||||||
color.fg.listing.bytes = #00ff00
|
color.fg.listing.bytes = #00ff00
|
||||||
|
|
||||||
font.global = courirer-BOLD-12
|
font.global = courier-BOLD-12
|
||||||
font.global.listing = font.global
|
font.global.listing = font.global
|
||||||
|
|
||||||
icon.error = defaultError.png
|
icon.error = defaultError.png
|
||||||
|
@ -295,11 +329,22 @@ color.fg.listing.bytes = orange
|
||||||
example, a reference color entry might be something like "color.bg.listing = color.bg". This
|
example, a reference color entry might be something like "color.bg.listing = color.bg". This
|
||||||
says that the listing's background color should be whatever "color.bg" is defined to be. Note
|
says that the listing's background color should be whatever "color.bg" is defined to be. Note
|
||||||
that all of the application's defined properties start with either "color.", "font.", or
|
that all of the application's defined properties start with either "color.", "font.", or
|
||||||
"icon.". Properties defined by a Java Look and Feel don't follow this pattern. To reference a
|
"icon.".
|
||||||
property that does not have a standard prefix, an ID can be prefixed with "[color]",
|
|
||||||
"[font]", or "[icon] as appropriate to allow the theme property parser to recognize the
|
<P>
|
||||||
values as IDs to other properties. So to refer to a Java property named "table.background",
|
Properties defined by the theming system do not follow this pattern. To reference a
|
||||||
you would use the following definition: "color.bg.table = [color]table.background".</P>
|
property that does not have a standard prefix, an ID can be prefixed with <COD>[color]
|
||||||
|
</CODE>, <CODE>[font]</CODE>, or <CODE>[icon]</CODE> as appropriate to allow the theme
|
||||||
|
property parser to recognize the values as IDs to other properties. For example, to refer to a
|
||||||
|
system property named<CODE>system.color.bg.view</CODE>,
|
||||||
|
you would use the following definition:
|
||||||
|
<P>
|
||||||
|
<BLOCKUOTE>
|
||||||
|
<P>
|
||||||
|
<CODE>color.bg.tree = [color]system.color.bg.view</CODE>
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
<H3>Color Values</H3>
|
<H3>Color Values</H3>
|
||||||
|
|
||||||
|
@ -319,8 +364,8 @@ color.fg.listing.bytes = orange
|
||||||
|
|
||||||
<LI>rgba(red, green, blue, alpha)</LI>
|
<LI>rgba(red, green, blue, alpha)</LI>
|
||||||
|
|
||||||
<LI><I>web color name</I> // the case-insensitive name of a web color such as red, olive, or
|
<LI><I>web color name</I> // the case-insensitive name of a web color such as red, olive,
|
||||||
purple</LI>
|
or purple</LI>
|
||||||
</UL>
|
</UL>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
@ -449,6 +494,126 @@ color.fg.listing.bytes = orange
|
||||||
</PRE>
|
</PRE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<H2>Useful Concepts</H2>
|
||||||
|
|
||||||
|
|
||||||
|
<H3>GThemeDefaults</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
This class contains many common application theme values for developers to use, such as
|
||||||
|
the default background color. These values can be used directly so developers do not have
|
||||||
|
to instantiate theme objects using theme IDs.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<H3>Icons</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<p>
|
||||||
|
When adding icons to the application, consider using standard icons provided by the
|
||||||
|
<CODE>Icons</CODE> class. Many generic concepts that require icons are in this class.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<H3>Palette Colors</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
A list of palette colors has been defined in <CODE>gui.palette.theme.properties.</CODE>.
|
||||||
|
These palette colors values are meant to be used by developers to reduce the total number
|
||||||
|
of colors used in the application. These color ids and values are viewable in the
|
||||||
|
<A href="ThemingUserDocs.html#Edit_Theme">Theme Editor Dialog</A>.
|
||||||
|
</P>
|
||||||
|
<P>
|
||||||
|
One of the benefits of using the palette system is that it is easy for end-users to change
|
||||||
|
one palette color to update all widgets in the application.
|
||||||
|
</P>
|
||||||
|
<P>
|
||||||
|
We recommend you use the existing palette colors when picking colors for your widgets.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
<H3>HTML Foreground Colors in Messages</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
Some developers use HTML messages in labels, tables, tooltips, and in calls to system APIs,
|
||||||
|
like <CODE>Msg</CODE>. Using HTML text allows clients to control the formatting of the
|
||||||
|
text, including the usage of color. If you use color in your HTML, then we suggest you do
|
||||||
|
so using GColors, like this:
|
||||||
|
<PRE>
|
||||||
|
String message = "Some text: <FONT COLOR=\"" + Messages.ERROR + "\">" + errorText + "</FONT>";
|
||||||
|
</PRE>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
In this example, an HTML message is created and part of that text is colored with the
|
||||||
|
standard error message color, which is red in a light mode theme. You can also use your
|
||||||
|
own <CODE>GColor</CODE> object in your HTML messages. Using standard system colors or
|
||||||
|
GColors allows these colors to be updated as the theme changes. We do not
|
||||||
|
recommend the use of hard-coded color values.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<H3>Options Usage of Colors and Fonts</H3>
|
||||||
|
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
The <CODE>Options</CODE> class in Ghidra facilitates user-configurable options in the
|
||||||
|
application. Previously, developers could use options to allow end-users to control color
|
||||||
|
values. In the new theme-based system, all colors are controlled via theming. However, to
|
||||||
|
make the transition to theming easier for developers, we added methods to the options class
|
||||||
|
that allow the developer to bind color editing via the options UI. These color options will
|
||||||
|
write any changes directly to the theme system.
|
||||||
|
</P>
|
||||||
|
<P> See: <CODE>Options.registerThemeColorBinding()</CODE> and
|
||||||
|
<CODE>Options.registerThemeFontBinding()</CODE>
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<H3>UiDefaultsMapper</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>This class discusses some of the plumbing the application uses to unify the various Look
|
||||||
|
and Feel concepts presented by the different LaFs.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
<H3>SystemThemeIds</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>This class is used by the <CODE>UiDefaultsMapper</CODE> class and presents a set of resource IDs common across all
|
||||||
|
LaFs. These values can be changed by the user. See also the description of
|
||||||
|
<A NAME="#System_IDs">System IDs in this document</A>.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<H3>Known Issues</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
Sometimes switching between themes does not reset all widgets. When
|
||||||
|
this happens, you may notice odd UI artifacts. These will go away when the application is
|
||||||
|
restarted and often when you again switch the theme.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<P class="providedbyplugin">Provided by: <I>Theme Manager</I></P>
|
<P class="providedbyplugin">Provided by: <I>Theme Manager</I></P>
|
||||||
|
|
||||||
<P class="relatedtopic">Related Topics</P>
|
<P class="relatedtopic">Related Topics</P>
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META name="generator" content=
|
|
||||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
|
||||||
|
|
||||||
<TITLE>Theming Architecture</TITLE>
|
<TITLE>Theming Architecture</TITLE>
|
||||||
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META name="generator" content=
|
|
||||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
|
||||||
|
|
||||||
<TITLE>General Overivew</TITLE>
|
<TITLE>General Overivew</TITLE>
|
||||||
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META name="generator" content=
|
|
||||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
|
||||||
|
|
||||||
<TITLE>Theming User Documentation</TITLE>
|
<TITLE>Theming User Documentation</TITLE>
|
||||||
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
@ -67,11 +64,10 @@
|
||||||
called "Button.background", it would appear in Ghidra as "laf.color.Button.background".</LI>
|
called "Button.background", it would appear in Ghidra as "laf.color.Button.background".</LI>
|
||||||
<LI>Look and Feel Palette Properties - All the color and fonts used by the Look and Feel
|
<LI>Look and Feel Palette Properties - All the color and fonts used by the Look and Feel
|
||||||
properties are grouped into either system property values or auto-generated palette
|
properties are grouped into either system property values or auto-generated palette
|
||||||
properties, sso that groups of properties can be changed together.</LI>
|
properties, so that groups of properties can be changed together.</LI>
|
||||||
|
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
|
|
||||||
<P>See the <A href="ThemingDeveloperDocs.html#Resource_Ids">Developer Documentation</A> for more
|
<P>See the <A href="ThemingDeveloperDocs.html#Resource_Ids">Developer Documentation</A> for more
|
||||||
details on the property ID format and naming conventions.
|
details on the property ID format and naming conventions.
|
||||||
</P>
|
</P>
|
||||||
|
@ -185,6 +181,14 @@
|
||||||
action, press the refresh button <IMG alt="" src="images/reload3.png" border="0"> in the top
|
action, press the refresh button <IMG alt="" src="images/reload3.png" border="0"> in the top
|
||||||
right corner of the Theme Editor dialog.
|
right corner of the Theme Editor dialog.
|
||||||
|
|
||||||
|
<H3>Toggle Showing System Values<A NAME="Toggle_Show_System_Values"></A></H3>
|
||||||
|
<P>
|
||||||
|
Toggles whether the given table shows system ID values (e.g, those starting with <CODE>
|
||||||
|
laf.</CODE> or <CODE>system.</CODE>. By default these values are hidden.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<H3>Saving Themes</H3>
|
<H3>Saving Themes</H3>
|
||||||
|
|
||||||
<P>After making changes to one or more theme values, the <A href="#Edit_Theme">Theme
|
<P>After making changes to one or more theme values, the <A href="#Edit_Theme">Theme
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 62 KiB |
|
@ -38,10 +38,6 @@ public class EditWindow extends JWindow {
|
||||||
|
|
||||||
private AssociatedComponentListener compListener = new AssociatedComponentListener();
|
private AssociatedComponentListener compListener = new AssociatedComponentListener();
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for RenameViewWindow.
|
|
||||||
* @param owner
|
|
||||||
*/
|
|
||||||
EditWindow(DockingWindowManager mgr) {
|
EditWindow(DockingWindowManager mgr) {
|
||||||
super(mgr.getRootFrame());
|
super(mgr.getRootFrame());
|
||||||
this.mgr = mgr;
|
this.mgr = mgr;
|
||||||
|
@ -52,17 +48,11 @@ public class EditWindow extends JWindow {
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see java.awt.Window#isActive()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see java.awt.Component#setVisible(boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setVisible(boolean state) {
|
public void setVisible(boolean state) {
|
||||||
|
|
||||||
|
@ -133,8 +123,7 @@ public class EditWindow extends JWindow {
|
||||||
private void create() {
|
private void create() {
|
||||||
textField = new JTextField(" ");
|
textField = new JTextField(" ");
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
JPanel panel = new JPanel(new BorderLayout());
|
||||||
Color bgColor = Colors.BG_TOOLTIP;
|
panel.setBackground(Colors.BACKGROUND);
|
||||||
panel.setBackground(bgColor);
|
|
||||||
panel.add(textField, BorderLayout.CENTER);
|
panel.add(textField, BorderLayout.CENTER);
|
||||||
|
|
||||||
textField.addKeyListener(new KeyAdapter() {
|
textField.addKeyListener(new KeyAdapter() {
|
||||||
|
@ -167,32 +156,21 @@ public class EditWindow extends JWindow {
|
||||||
|
|
||||||
private class AssociatedComponentListener implements ComponentListener, ChangeListener {
|
private class AssociatedComponentListener implements ComponentListener, ChangeListener {
|
||||||
|
|
||||||
/*
|
|
||||||
* @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void componentHidden(ComponentEvent e) {
|
public void componentHidden(ComponentEvent e) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void componentResized(ComponentEvent e) {
|
public void componentResized(ComponentEvent e) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void componentShown(ComponentEvent e) {
|
public void componentShown(ComponentEvent e) {
|
||||||
|
// stub
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void componentMoved(ComponentEvent e) {
|
public void componentMoved(ComponentEvent e) {
|
||||||
if (comp != null && comp.isVisible()) {
|
if (comp != null && comp.isVisible()) {
|
||||||
|
@ -200,9 +178,6 @@ public class EditWindow extends JWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
close();
|
close();
|
||||||
|
|
|
@ -30,7 +30,7 @@ import docking.util.AnimationUtils;
|
||||||
import docking.widgets.VariableHeightPanel;
|
import docking.widgets.VariableHeightPanel;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
|
|
||||||
// TODO: should this be put into generic?
|
// TODO: should this be put into generic?
|
||||||
|
@ -211,7 +211,7 @@ public class GenericHeader extends JPanel {
|
||||||
|
|
||||||
private void constructMultiLinePanel() {
|
private void constructMultiLinePanel() {
|
||||||
removeAll();
|
removeAll();
|
||||||
toolbar.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Java.BORDER));
|
toolbar.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Colors.BORDER));
|
||||||
add(toolbar, BorderLayout.SOUTH);
|
add(toolbar, BorderLayout.SOUTH);
|
||||||
add(titlePanel, BorderLayout.CENTER);
|
add(titlePanel, BorderLayout.CENTER);
|
||||||
add(menuCloseToolbar, BorderLayout.EAST);
|
add(menuCloseToolbar, BorderLayout.EAST);
|
||||||
|
|
|
@ -35,7 +35,6 @@ import docking.dnd.StringTransferable;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||||
import ghidra.util.ColorUtils;
|
import ghidra.util.ColorUtils;
|
||||||
import ghidra.util.WebColors;
|
import ghidra.util.WebColors;
|
||||||
|
@ -151,7 +150,7 @@ public class SettableColorSwatchChooserPanel extends AbstractColorChooserPanel {
|
||||||
recentSwatchListener = new RecentSwatchListener();
|
recentSwatchListener = new RecentSwatchListener();
|
||||||
recentSwatchPanel.addMouseListener(recentSwatchListener);
|
recentSwatchPanel.addMouseListener(recentSwatchListener);
|
||||||
|
|
||||||
LineBorder border = new LineBorder(Java.BORDER);
|
LineBorder border = new LineBorder(Colors.BORDER);
|
||||||
swatchPanel.setBorder(border);
|
swatchPanel.setBorder(border);
|
||||||
gbc.gridx = 0;
|
gbc.gridx = 0;
|
||||||
gbc.gridy = 0;
|
gbc.gridy = 0;
|
||||||
|
@ -424,7 +423,7 @@ class SwatchPanel extends JPanel {
|
||||||
}
|
}
|
||||||
int y = row * (swatchSize.height + gap.height);
|
int y = row * (swatchSize.height + gap.height);
|
||||||
g.fillRect(x, y, swatchSize.width, swatchSize.height);
|
g.fillRect(x, y, swatchSize.width, swatchSize.height);
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1,
|
g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1,
|
||||||
y + swatchSize.height - 1);
|
y + swatchSize.height - 1);
|
||||||
g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1,
|
g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1,
|
||||||
|
|
|
@ -33,6 +33,8 @@ public class ThemeColorPaletteTable extends ThemeColorTable {
|
||||||
@Override
|
@Override
|
||||||
protected void filter() {
|
protected void filter() {
|
||||||
|
|
||||||
|
super.filter(); // this call will update 'colors'
|
||||||
|
|
||||||
List<ColorValue> filtered = new ArrayList<>();
|
List<ColorValue> filtered = new ArrayList<>();
|
||||||
|
|
||||||
for (ColorValue colorValue : colors) {
|
for (ColorValue colorValue : colors) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ import ghidra.util.Swing;
|
||||||
/**
|
/**
|
||||||
* Color Table for Theme Dialog
|
* Color Table for Theme Dialog
|
||||||
*/
|
*/
|
||||||
public class ThemeColorTable extends JPanel implements ActionContextProvider {
|
public class ThemeColorTable extends JPanel implements ActionContextProvider, ThemeTable {
|
||||||
|
|
||||||
private ThemeColorTableModel colorTableModel;
|
private ThemeColorTableModel colorTableModel;
|
||||||
private ColorValueEditor colorEditor = new ColorValueEditor(this::colorValueChanged);
|
private ColorValueEditor colorEditor = new ColorValueEditor(this::colorValueChanged);
|
||||||
|
@ -87,6 +87,17 @@ public class ThemeColorTable extends JPanel implements ActionContextProvider {
|
||||||
return new ThemeColorTableModel(valuesProvider);
|
return new ThemeColorTableModel(valuesProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShowSystemValues(boolean show) {
|
||||||
|
colorTableModel.setShowSystemValues(show);
|
||||||
|
reloadAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShowingSystemValues() {
|
||||||
|
return colorTableModel.isShowingSystemValues();
|
||||||
|
}
|
||||||
|
|
||||||
void colorValueChanged(PropertyChangeEvent event) {
|
void colorValueChanged(PropertyChangeEvent event) {
|
||||||
// run later - don't rock the boat in the middle of a listener callback
|
// run later - don't rock the boat in the middle of a listener callback
|
||||||
Swing.runLater(() -> {
|
Swing.runLater(() -> {
|
||||||
|
@ -118,7 +129,7 @@ public class ThemeColorTable extends JPanel implements ActionContextProvider {
|
||||||
}
|
}
|
||||||
String id = currentValue.getId();
|
String id = currentValue.getId();
|
||||||
ColorValue themeValue = colorTableModel.getThemeValue(id);
|
ColorValue themeValue = colorTableModel.getThemeValue(id);
|
||||||
return new ThemeTableContext<>(currentValue, themeValue);
|
return new ThemeTableContext<>(currentValue, themeValue, this);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package docking.theme.gui;
|
package docking.theme.gui;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -44,6 +45,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||||
private GThemeValueMap lightDefaultValues;
|
private GThemeValueMap lightDefaultValues;
|
||||||
private GThemeValueMap darkDefaultValues;
|
private GThemeValueMap darkDefaultValues;
|
||||||
private GThemeValuesCache valuesCache;
|
private GThemeValuesCache valuesCache;
|
||||||
|
private boolean showSystemValues;
|
||||||
|
|
||||||
public ThemeColorTableModel(GThemeValuesCache valuesProvider) {
|
public ThemeColorTableModel(GThemeValuesCache valuesProvider) {
|
||||||
super(new ServiceProviderStub());
|
super(new ServiceProviderStub());
|
||||||
|
@ -51,9 +53,17 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setShowSystemValues(boolean show) {
|
||||||
|
this.showSystemValues = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShowingSystemValues() {
|
||||||
|
return showSystemValues;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the just the current values shown in the table. Called whenever a color changes.
|
* Reloads the just the current values shown in the table. Called whenever a color changes.
|
||||||
*/
|
*/
|
||||||
public void reloadCurrent() {
|
public void reloadCurrent() {
|
||||||
currentValues = valuesCache.getCurrentValues();
|
currentValues = valuesCache.getCurrentValues();
|
||||||
colors = currentValues.getColors();
|
colors = currentValues.getColors();
|
||||||
|
@ -86,7 +96,23 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void filter() {
|
protected void filter() {
|
||||||
// for subclasses
|
|
||||||
|
List<ColorValue> filtered = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ColorValue colorValue : colors) {
|
||||||
|
String id = colorValue.getId();
|
||||||
|
if (showSystemValues) {
|
||||||
|
filtered.add(colorValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Gui.isSystemId(id)) {
|
||||||
|
filtered.add(colorValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
colors = filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -50,7 +50,6 @@ public class ThemeEditorDialog extends DialogComponentProvider {
|
||||||
private ThemeColorTable paletteTable;
|
private ThemeColorTable paletteTable;
|
||||||
|
|
||||||
private ThemeManager themeManager;
|
private ThemeManager themeManager;
|
||||||
|
|
||||||
private GThemeValuesCache valuesCache;
|
private GThemeValuesCache valuesCache;
|
||||||
|
|
||||||
public ThemeEditorDialog(ThemeManager themeManager) {
|
public ThemeEditorDialog(ThemeManager themeManager) {
|
||||||
|
@ -107,6 +106,22 @@ public class ThemeEditorDialog extends DialogComponentProvider {
|
||||||
.onAction(c -> c.getThemeValue().installValue(themeManager))
|
.onAction(c -> c.getThemeValue().installValue(themeManager))
|
||||||
.build();
|
.build();
|
||||||
addAction(resetValueAction);
|
addAction(resetValueAction);
|
||||||
|
|
||||||
|
DockingAction showSystemValuesAction =
|
||||||
|
new ActionBuilder("Toggle Show System Values", getTitle())
|
||||||
|
.popupMenuPath("Toggle Show System Values")
|
||||||
|
.withContext(ThemeTableContext.class)
|
||||||
|
.popupWhen(c -> true)
|
||||||
|
.helpLocation(new HelpLocation("Theming", "Toggle_Show_System_Values"))
|
||||||
|
.onAction(context -> toggleSystemValues(context))
|
||||||
|
.build();
|
||||||
|
addAction(showSystemValuesAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleSystemValues(ThemeTableContext<?> context) {
|
||||||
|
ThemeTable themeTable = context.getThemeTable();
|
||||||
|
boolean isShowing = themeTable.isShowingSystemValues();
|
||||||
|
themeTable.setShowSystemValues(!isShowing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void adjustFonts(int amount) {
|
private void adjustFonts(int amount) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ import ghidra.util.Swing;
|
||||||
/**
|
/**
|
||||||
* Font Table for Theme Dialog
|
* Font Table for Theme Dialog
|
||||||
*/
|
*/
|
||||||
public class ThemeFontTable extends JPanel implements ActionContextProvider {
|
public class ThemeFontTable extends JPanel implements ActionContextProvider, ThemeTable {
|
||||||
|
|
||||||
private ThemeFontTableModel fontTableModel;
|
private ThemeFontTableModel fontTableModel;
|
||||||
private FontValueEditor fontEditor = new FontValueEditor(this::fontValueChanged);
|
private FontValueEditor fontEditor = new FontValueEditor(this::fontValueChanged);
|
||||||
|
@ -84,6 +84,17 @@ public class ThemeFontTable extends JPanel implements ActionContextProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShowSystemValues(boolean show) {
|
||||||
|
fontTableModel.setShowSystemValues(show);
|
||||||
|
reloadAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShowingSystemValues() {
|
||||||
|
return fontTableModel.isShowingSystemValues();
|
||||||
|
}
|
||||||
|
|
||||||
void fontValueChanged(PropertyChangeEvent event) {
|
void fontValueChanged(PropertyChangeEvent event) {
|
||||||
// run later - don't rock the boat in the middle of a listener callback
|
// run later - don't rock the boat in the middle of a listener callback
|
||||||
Swing.runLater(() -> {
|
Swing.runLater(() -> {
|
||||||
|
@ -115,7 +126,7 @@ public class ThemeFontTable extends JPanel implements ActionContextProvider {
|
||||||
}
|
}
|
||||||
String id = currentValue.getId();
|
String id = currentValue.getId();
|
||||||
FontValue themeValue = fontTableModel.getThemeValue(id);
|
FontValue themeValue = fontTableModel.getThemeValue(id);
|
||||||
return new ThemeTableContext<Font>(currentValue, themeValue);
|
return new ThemeTableContext<Font>(currentValue, themeValue, this);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,13 @@ package docking.theme.gui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.FontValue;
|
import generic.theme.*;
|
||||||
import generic.theme.GThemeValueMap;
|
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.framework.plugintool.ServiceProviderStub;
|
import ghidra.framework.plugintool.ServiceProviderStub;
|
||||||
|
@ -41,6 +39,7 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||||
private GThemeValueMap themeValues;
|
private GThemeValueMap themeValues;
|
||||||
private GThemeValueMap defaultValues;
|
private GThemeValueMap defaultValues;
|
||||||
private GThemeValuesCache valuesProvider;
|
private GThemeValuesCache valuesProvider;
|
||||||
|
private boolean showSystemValues;
|
||||||
|
|
||||||
public ThemeFontTableModel(GThemeValuesCache valuesProvider) {
|
public ThemeFontTableModel(GThemeValuesCache valuesProvider) {
|
||||||
super(new ServiceProviderStub());
|
super(new ServiceProviderStub());
|
||||||
|
@ -48,6 +47,34 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setShowSystemValues(boolean show) {
|
||||||
|
this.showSystemValues = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShowingSystemValues() {
|
||||||
|
return showSystemValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void filter() {
|
||||||
|
|
||||||
|
List<FontValue> filtered = new ArrayList<>();
|
||||||
|
|
||||||
|
for (FontValue fontValue : fonts) {
|
||||||
|
String id = fontValue.getId();
|
||||||
|
if (showSystemValues) {
|
||||||
|
filtered.add(fontValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Gui.isSystemId(id)) {
|
||||||
|
filtered.add(fontValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fonts = filtered;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the just the current values shown in the table. Called whenever a font changes.
|
* Reloads the just the current values shown in the table. Called whenever a font changes.
|
||||||
*/
|
*/
|
||||||
|
@ -71,6 +98,8 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||||
fonts = currentValues.getFonts();
|
fonts = currentValues.getFonts();
|
||||||
themeValues = valuesProvider.getThemeValues();
|
themeValues = valuesProvider.getThemeValues();
|
||||||
defaultValues = valuesProvider.getDefaultValues();
|
defaultValues = valuesProvider.getDefaultValues();
|
||||||
|
|
||||||
|
filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -172,6 +201,7 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Comparator<ResolvedFont> getComparator() {
|
public Comparator<ResolvedFont> getComparator() {
|
||||||
return (v1, v2) -> {
|
return (v1, v2) -> {
|
||||||
if (v1 == null && v2 == null) {
|
if (v1 == null && v2 == null) {
|
||||||
|
@ -220,5 +250,6 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ResolvedFont(String id, String refId, Font font) {/**/}
|
private record ResolvedFont(String id, String refId, Font font) {
|
||||||
|
/**/}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ import ghidra.util.Swing;
|
||||||
/**
|
/**
|
||||||
* Icon Table for Theme Dialog
|
* Icon Table for Theme Dialog
|
||||||
*/
|
*/
|
||||||
public class ThemeIconTable extends JPanel implements ActionContextProvider {
|
public class ThemeIconTable extends JPanel implements ActionContextProvider, ThemeTable {
|
||||||
|
|
||||||
private ThemeIconTableModel iconTableModel;
|
private ThemeIconTableModel iconTableModel;
|
||||||
private IconValueEditor iconEditor = new IconValueEditor(this::iconValueChanged);
|
private IconValueEditor iconEditor = new IconValueEditor(this::iconValueChanged);
|
||||||
|
@ -80,6 +80,17 @@ public class ThemeIconTable extends JPanel implements ActionContextProvider {
|
||||||
add(filterTable, BorderLayout.CENTER);
|
add(filterTable, BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShowSystemValues(boolean show) {
|
||||||
|
iconTableModel.setShowSystemValues(show);
|
||||||
|
reloadAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShowingSystemValues() {
|
||||||
|
return iconTableModel.isShowingSystemValues();
|
||||||
|
}
|
||||||
|
|
||||||
void iconValueChanged(PropertyChangeEvent event) {
|
void iconValueChanged(PropertyChangeEvent event) {
|
||||||
// run later - don't rock the boat in the middle of a listener callback
|
// run later - don't rock the boat in the middle of a listener callback
|
||||||
Swing.runLater(() -> {
|
Swing.runLater(() -> {
|
||||||
|
@ -111,7 +122,7 @@ public class ThemeIconTable extends JPanel implements ActionContextProvider {
|
||||||
}
|
}
|
||||||
String id = currentValue.getId();
|
String id = currentValue.getId();
|
||||||
IconValue themeValue = iconTableModel.getThemeValue(id);
|
IconValue themeValue = iconTableModel.getThemeValue(id);
|
||||||
return new ThemeTableContext<Icon>(currentValue, themeValue);
|
return new ThemeTableContext<Icon>(currentValue, themeValue, this);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
package docking.theme.gui;
|
package docking.theme.gui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -40,6 +39,7 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||||
private GThemeValueMap themeValues;
|
private GThemeValueMap themeValues;
|
||||||
private GThemeValueMap defaultValues;
|
private GThemeValueMap defaultValues;
|
||||||
private GThemeValuesCache valuesProvider;
|
private GThemeValuesCache valuesProvider;
|
||||||
|
private boolean showSystemValues;
|
||||||
|
|
||||||
public ThemeIconTableModel(GThemeValuesCache valuesProvider) {
|
public ThemeIconTableModel(GThemeValuesCache valuesProvider) {
|
||||||
super(new ServiceProviderStub());
|
super(new ServiceProviderStub());
|
||||||
|
@ -47,6 +47,34 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setShowSystemValues(boolean show) {
|
||||||
|
this.showSystemValues = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShowingSystemValues() {
|
||||||
|
return showSystemValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void filter() {
|
||||||
|
|
||||||
|
List<IconValue> filtered = new ArrayList<>();
|
||||||
|
|
||||||
|
for (IconValue iconValue : icons) {
|
||||||
|
String id = iconValue.getId();
|
||||||
|
if (showSystemValues) {
|
||||||
|
filtered.add(iconValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Gui.isSystemId(id)) {
|
||||||
|
filtered.add(iconValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
icons = filtered;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the just the current values shown in the table. Called whenever an icon changes.
|
* Reloads the just the current values shown in the table. Called whenever an icon changes.
|
||||||
*/
|
*/
|
||||||
|
@ -70,6 +98,8 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||||
icons = currentValues.getIcons();
|
icons = currentValues.getIcons();
|
||||||
themeValues = valuesProvider.getThemeValues();
|
themeValues = valuesProvider.getThemeValues();
|
||||||
defaultValues = valuesProvider.getDefaultValues();
|
defaultValues = valuesProvider.getDefaultValues();
|
||||||
|
|
||||||
|
filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -242,6 +272,6 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ResolvedIcon(String id, String refId, Icon icon) {/**/}
|
private record ResolvedIcon(String id, String refId, Icon icon) {
|
||||||
|
/**/}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package docking.theme.gui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common interface for theme tables
|
||||||
|
*/
|
||||||
|
public interface ThemeTable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True signals to show IDs used for system values
|
||||||
|
* @param show true signals to show IDs used for system values
|
||||||
|
*/
|
||||||
|
public void setShowSystemValues(boolean show);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if showing system IDs
|
||||||
|
* @return true if showing system IDs
|
||||||
|
*/
|
||||||
|
public boolean isShowingSystemValues();
|
||||||
|
}
|
|
@ -27,10 +27,21 @@ public class ThemeTableContext<T> extends ActionContext {
|
||||||
|
|
||||||
private ThemeValue<T> currentValue;
|
private ThemeValue<T> currentValue;
|
||||||
private ThemeValue<T> themeValue;
|
private ThemeValue<T> themeValue;
|
||||||
|
private ThemeTable themeTable;
|
||||||
|
|
||||||
public ThemeTableContext(ThemeValue<T> currentValue, ThemeValue<T> themeValue) {
|
public ThemeTableContext(ThemeValue<T> currentValue, ThemeValue<T> themeValue,
|
||||||
|
ThemeTable themeTable) {
|
||||||
this.currentValue = currentValue;
|
this.currentValue = currentValue;
|
||||||
this.themeValue = themeValue;
|
this.themeValue = themeValue;
|
||||||
|
this.themeTable = themeTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the theme table for this context
|
||||||
|
* @return the table
|
||||||
|
*/
|
||||||
|
public ThemeTable getThemeTable() {
|
||||||
|
return themeTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.jdesktop.animation.timing.TimingTargetAdapter;
|
||||||
import org.jdesktop.animation.timing.interpolation.PropertySetter;
|
import org.jdesktop.animation.timing.interpolation.PropertySetter;
|
||||||
|
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import generic.util.WindowUtilities;
|
import generic.util.WindowUtilities;
|
||||||
import generic.util.image.ImageUtils;
|
import generic.util.image.ImageUtils;
|
||||||
|
@ -878,7 +878,7 @@ public class AnimationUtils {
|
||||||
double cx = emphasizedBounds.getCenterX();
|
double cx = emphasizedBounds.getCenterX();
|
||||||
double cy = emphasizedBounds.getCenterY();
|
double cy = emphasizedBounds.getCenterY();
|
||||||
g2d.rotate(rad, cx, cy);
|
g2d.rotate(rad, cx, cy);
|
||||||
g.setColor(Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
|
|
||||||
int iw = emphasizedBounds.width;
|
int iw = emphasizedBounds.width;
|
||||||
int ih = emphasizedBounds.height;
|
int ih = emphasizedBounds.height;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import docking.widgets.label.GDHtmlLabel;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GColorUIResource;
|
import generic.theme.GColorUIResource;
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
|
import generic.theme.GThemeDefaults.Colors.Tables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A common base class for list and table renderer objects, unifying the Ghidra look and feel.
|
* A common base class for list and table renderer objects, unifying the Ghidra look and feel.
|
||||||
|
@ -165,6 +166,14 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
||||||
return ALT_BACKGROUND_COLOR;
|
return ALT_BACKGROUND_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Color getErrorForegroundColor(boolean isSelected) {
|
||||||
|
return isSelected ? Tables.ERROR_SELECTED : Tables.ERROR_UNSELECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color getUneditableForegroundColor(boolean isSelected) {
|
||||||
|
return isSelected ? Tables.UNEDITABLE_SELECTED : Tables.UNEDITABLE_UNSELECTED;
|
||||||
|
}
|
||||||
|
|
||||||
// ==================================================================================================
|
// ==================================================================================================
|
||||||
// Methods overridden for performance reasons (see DefaultTableCellRenderer &
|
// Methods overridden for performance reasons (see DefaultTableCellRenderer &
|
||||||
// DefaultListCellRenderer)
|
// DefaultListCellRenderer)
|
||||||
|
|
|
@ -28,9 +28,9 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of the {@link DropDownSelectionTextField} that allows multiple items to be selected.
|
* Extension of the {@link DropDownSelectionTextField} that allows multiple items to be selected.
|
||||||
* <p>
|
* <p>
|
||||||
* Note that multiple selection introduces some display complications that are not an issue with
|
* Note that multiple selection introduces some display complications that are not an issue with
|
||||||
* single selection. Namely:
|
* single selection. Namely:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>how do you display multiple selected items in the preview pane</li>
|
* <li>how do you display multiple selected items in the preview pane</li>
|
||||||
|
@ -38,7 +38,7 @@ import ghidra.util.datastruct.WeakSet;
|
||||||
* </ul>
|
* </ul>
|
||||||
* The solution here is to:
|
* The solution here is to:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>let the preview panel operate normally; it will simply display the preview text for whatever
|
* <li>let the preview panel operate normally; it will simply display the preview text for whatever
|
||||||
* was last selected</li>
|
* was last selected</li>
|
||||||
* <li>display all selected items in the drop down text field as a comma-delimited list</li>
|
* <li>display all selected items in the drop down text field as a comma-delimited list</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
@ -54,7 +54,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param dataModel the model for the drop down widget
|
* @param dataModel the model for the drop down widget
|
||||||
*/
|
*/
|
||||||
public DropDownMultiSelectionTextField(DropDownTextFieldDataModel<T> dataModel) {
|
public DropDownMultiSelectionTextField(DropDownTextFieldDataModel<T> dataModel) {
|
||||||
|
@ -63,7 +63,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the caller to a list of subscribers who will be notified when selection changes.
|
* Adds the caller to a list of subscribers who will be notified when selection changes.
|
||||||
*
|
*
|
||||||
* @param listener the subscriber to be added
|
* @param listener the subscriber to be added
|
||||||
*/
|
*/
|
||||||
public void addDropDownSelectionChoiceListener(
|
public void addDropDownSelectionChoiceListener(
|
||||||
|
@ -80,7 +80,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all selected items in the list.
|
* Returns a list of all selected items in the list.
|
||||||
*
|
*
|
||||||
* @return the selected items
|
* @return the selected items
|
||||||
*/
|
*/
|
||||||
public List<T> getSelectedValues() {
|
public List<T> getSelectedValues() {
|
||||||
|
@ -101,6 +101,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
}
|
}
|
||||||
previewList.setOpaque(true);
|
previewList.setOpaque(true);
|
||||||
previewList.setBackground(PREVIEW_WINDOW_BGCOLOR);
|
previewList.setBackground(PREVIEW_WINDOW_BGCOLOR);
|
||||||
|
previewList.setForeground(PREVIEW_WINDOW_FGCOLOR);
|
||||||
previewList.setFocusable(false);
|
previewList.setFocusable(false);
|
||||||
previewList.setModel(new DefaultListModel<String>());
|
previewList.setModel(new DefaultListModel<String>());
|
||||||
}
|
}
|
||||||
|
@ -161,9 +162,9 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representing all items selected in the drop-down. If multiple items are
|
* Returns a string representing all items selected in the drop-down. If multiple items are
|
||||||
* selected, they will be comma-delimited.
|
* selected, they will be comma-delimited.
|
||||||
*
|
*
|
||||||
* @return the comma-delimited selection
|
* @return the comma-delimited selection
|
||||||
*/
|
*/
|
||||||
private String getSelectionText() {
|
private String getSelectionText() {
|
||||||
|
@ -178,7 +179,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies subscribers when the list selection has changed.
|
* Notifies subscribers when the list selection has changed.
|
||||||
*
|
*
|
||||||
* @param selectedItems the list of selected items
|
* @param selectedItems the list of selected items
|
||||||
*/
|
*/
|
||||||
private void fireUserChoiceMade(List<T> selectedItems) {
|
private void fireUserChoiceMade(List<T> selectedItems) {
|
||||||
|
@ -189,7 +190,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the selected list items.
|
* Saves the selected list items.
|
||||||
*
|
*
|
||||||
* @param newValues the new selected items
|
* @param newValues the new selected items
|
||||||
*/
|
*/
|
||||||
private void storeSelectedValues(List<T> newValues) {
|
private void storeSelectedValues(List<T> newValues) {
|
||||||
|
@ -198,7 +199,7 @@ public class DropDownMultiSelectionTextField<T> extends DropDownSelectionTextFie
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener for the preview panel which is kicked whenever a selection has been made in the
|
* Listener for the preview panel which is kicked whenever a selection has been made in the
|
||||||
* drop down. This will prompt the preview panel to change what it displays.
|
* drop down. This will prompt the preview panel to change what it displays.
|
||||||
*/
|
*/
|
||||||
private class PreviewListener implements ListSelectionListener {
|
private class PreviewListener implements ListSelectionListener {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import docking.widgets.label.GDHtmlLabel;
|
import docking.widgets.label.GDHtmlLabel;
|
||||||
import docking.widgets.list.GList;
|
import docking.widgets.list.GList;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors.Tooltips;
|
||||||
import generic.util.WindowUtilities;
|
import generic.util.WindowUtilities;
|
||||||
import ghidra.util.StringUtilities;
|
import ghidra.util.StringUtilities;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
|
@ -39,11 +39,11 @@ import ghidra.util.task.SwingUpdateManager;
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A text field that handles comparing text typed by the user to the list of objects and then
|
* A text field that handles comparing text typed by the user to the list of objects and then
|
||||||
* presenting potential matches in a drop down window. The items in this window cannot be selected.
|
* presenting potential matches in a drop down window. The items in this window cannot be selected.
|
||||||
*
|
*
|
||||||
* <P>This class will fire {@link #fireEditingStopped()} and {@link #fireEditingCancelled()} events
|
* <P>This class will fire {@link #fireEditingStopped()} and {@link #fireEditingCancelled()} events
|
||||||
* when the user makes a choice by pressing the ENTER key, thus allowing the client code to use
|
* when the user makes a choice by pressing the ENTER key, thus allowing the client code to use
|
||||||
* this class similar in fashion to a property editor. This behavior can be configured to:
|
* this class similar in fashion to a property editor. This behavior can be configured to:
|
||||||
* <UL>
|
* <UL>
|
||||||
* <LI>Not consume the ENTER key press (it consumes by default), allowing the parent container
|
* <LI>Not consume the ENTER key press (it consumes by default), allowing the parent container
|
||||||
|
@ -53,7 +53,7 @@ import util.CollectionUtils;
|
||||||
* </LI>
|
* </LI>
|
||||||
* </UL>
|
* </UL>
|
||||||
*
|
*
|
||||||
* <p>This class is subclassed to not only have the matching behavior, but to also allow for user
|
* <p>This class is subclassed to not only have the matching behavior, but to also allow for user
|
||||||
* selections.
|
* selections.
|
||||||
*
|
*
|
||||||
* @param <T> The type of object that this model manipulates
|
* @param <T> The type of object that this model manipulates
|
||||||
|
@ -63,7 +63,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
private static final int DEFAULT_MAX_UPDATE_DELAY = 2000;
|
private static final int DEFAULT_MAX_UPDATE_DELAY = 2000;
|
||||||
private static final int MIN_HEIGHT = 300;
|
private static final int MIN_HEIGHT = 300;
|
||||||
private static final int MIN_WIDTH = 200;
|
private static final int MIN_WIDTH = 200;
|
||||||
protected static final Color PREVIEW_WINDOW_BGCOLOR = Colors.BACKGROUND;
|
protected static final Color PREVIEW_WINDOW_BGCOLOR = Tooltips.BACKGROUND;
|
||||||
|
protected static final Color PREVIEW_WINDOW_FGCOLOR = Tooltips.FOREGROUND;
|
||||||
|
|
||||||
private JWindow toolTipWindow; // delayed initialization for parenting
|
private JWindow toolTipWindow; // delayed initialization for parenting
|
||||||
private JWindow matchingWindow; // delayed initialization for parenting
|
private JWindow matchingWindow; // delayed initialization for parenting
|
||||||
|
@ -91,15 +92,15 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
private boolean ignoreEnterKeyPress = false; // do not ignore enter by default
|
private boolean ignoreEnterKeyPress = false; // do not ignore enter by default
|
||||||
private boolean ignoreCaretChanges;
|
private boolean ignoreCaretChanges;
|
||||||
|
|
||||||
// We use an update manager to buffer requests to update the matches. This allows us to be
|
// We use an update manager to buffer requests to update the matches. This allows us to be
|
||||||
// more responsive when the user is attempting to type multiple characters
|
// more responsive when the user is attempting to type multiple characters
|
||||||
private String pendingTextUpdate;
|
private String pendingTextUpdate;
|
||||||
private SwingUpdateManager updateManager;
|
private SwingUpdateManager updateManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text that was used to generate the current list of matches. This can be different than
|
* The text that was used to generate the current list of matches. This can be different than
|
||||||
* the text of this text field, as the user can move the cursor around, which will change the
|
* the text of this text field, as the user can move the cursor around, which will change the
|
||||||
* list of matches. Also, we can set the value of the text field as the user arrows through
|
* list of matches. Also, we can set the value of the text field as the user arrows through
|
||||||
* the list, which will change the contents of the text field, but not the list of matches.
|
* the list, which will change the contents of the text field, but not the list of matches.
|
||||||
*/
|
*/
|
||||||
private String currentMatchingText;
|
private String currentMatchingText;
|
||||||
|
@ -120,7 +121,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
*
|
*
|
||||||
* @param dataModel provides element storage and search capabilities to this component.
|
* @param dataModel provides element storage and search capabilities to this component.
|
||||||
* @param updateMinDelay suggestion list refresh delay, triggered after search results have
|
* @param updateMinDelay suggestion list refresh delay, triggered after search results have
|
||||||
* changed. Too low a value may cause an inconsistent view as filtering tasks complete; too
|
* changed. Too low a value may cause an inconsistent view as filtering tasks complete; too
|
||||||
* high a value delivers an unresponsive user experience.
|
* high a value delivers an unresponsive user experience.
|
||||||
*/
|
*/
|
||||||
public DropDownTextField(DropDownTextFieldDataModel<T> dataModel, int updateMinDelay) {
|
public DropDownTextField(DropDownTextFieldDataModel<T> dataModel, int updateMinDelay) {
|
||||||
|
@ -157,6 +158,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
previewLabel = new GDHtmlLabel();
|
previewLabel = new GDHtmlLabel();
|
||||||
previewLabel.setOpaque(true);
|
previewLabel.setOpaque(true);
|
||||||
previewLabel.setBackground(PREVIEW_WINDOW_BGCOLOR);
|
previewLabel.setBackground(PREVIEW_WINDOW_BGCOLOR);
|
||||||
|
previewLabel.setForeground(PREVIEW_WINDOW_FGCOLOR);
|
||||||
previewLabel.setVerticalAlignment(SwingConstants.TOP);
|
previewLabel.setVerticalAlignment(SwingConstants.TOP);
|
||||||
previewLabel.setFocusable(false);
|
previewLabel.setFocusable(false);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +218,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// O.K., if we are consuming key presses, then we only want to do so when the selection
|
// O.K., if we are consuming key presses, then we only want to do so when the selection
|
||||||
// window is showing. This will close the selection window and not send the Enter event up
|
// window is showing. This will close the selection window and not send the Enter event up
|
||||||
// to our parent component.
|
// to our parent component.
|
||||||
boolean listShowing = isMatchingListShowing();
|
boolean listShowing = isMatchingListShowing();
|
||||||
if (consumeEnterKeyPress) {
|
if (consumeEnterKeyPress) {
|
||||||
|
@ -250,10 +252,10 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
|
|
||||||
private void validateChosenItemAgainstText(boolean isListShowing) {
|
private void validateChosenItemAgainstText(boolean isListShowing) {
|
||||||
//
|
//
|
||||||
// If the text differs from that of the chosen item, then the implication is the user has
|
// If the text differs from that of the chosen item, then the implication is the user has
|
||||||
// changed the text after the last time an item was chosen and after the drop-down list was
|
// changed the text after the last time an item was chosen and after the drop-down list was
|
||||||
// closed (if they haven't changed the text, then it will have been set to the value of the
|
// closed (if they haven't changed the text, then it will have been set to the value of the
|
||||||
// currently selected item). The user will do this if they want a new item that is not in
|
// currently selected item). The user will do this if they want a new item that is not in
|
||||||
// the list, but the new item starts with the same value as something that is in the list.
|
// the list, but the new item starts with the same value as something that is in the list.
|
||||||
//
|
//
|
||||||
if (selectedValue == null) {
|
if (selectedValue == null) {
|
||||||
|
@ -343,7 +345,9 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
updateWindowLocation();
|
updateWindowLocation();
|
||||||
showMatchingWindow();
|
showMatchingWindow();
|
||||||
|
|
||||||
getPreviewPaneComponent().setBackground(PREVIEW_WINDOW_BGCOLOR);
|
JComponent previewComponent = getPreviewPaneComponent();
|
||||||
|
previewComponent.setBackground(PREVIEW_WINDOW_BGCOLOR);
|
||||||
|
previewComponent.setForeground(PREVIEW_WINDOW_FGCOLOR);
|
||||||
toolTipWindow.setVisible(hasPreview());
|
toolTipWindow.setVisible(hasPreview());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,29 +456,29 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When true, this field will not pass Enter key press events up to it's parent <b>when the
|
* When true, this field will not pass Enter key press events up to it's parent <b>when the
|
||||||
* drop-down selection window is open</b>. However, an Enter key press will still be
|
* drop-down selection window is open</b>. However, an Enter key press will still be
|
||||||
* "unconsumed" when the drop-down window is not open. When set to false, this method will
|
* "unconsumed" when the drop-down window is not open. When set to false, this method will
|
||||||
* always pass the Enter key press up to it's parent.
|
* always pass the Enter key press up to it's parent.
|
||||||
*
|
*
|
||||||
* <P>The default is true. Clients will set this to false when they wish to respond to an
|
* <P>The default is true. Clients will set this to false when they wish to respond to an
|
||||||
* Enter event. For example, a dialog may want to close itself on an Enter key press, even
|
* Enter event. For example, a dialog may want to close itself on an Enter key press, even
|
||||||
* when the drop-down selection text field is still open. Contrastingly, when this field is
|
* when the drop-down selection text field is still open. Contrastingly, when this field is
|
||||||
* embedded inside of a larger editor, like a multi-editor field dialog, the Enter key press
|
* embedded inside of a larger editor, like a multi-editor field dialog, the Enter key press
|
||||||
* should simply trigger the drop-down window to close and the editing to stop, but should not
|
* should simply trigger the drop-down window to close and the editing to stop, but should not
|
||||||
* trigger the overall dialog to close.
|
* trigger the overall dialog to close.
|
||||||
* @param consume true to consume
|
* @param consume true to consume
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void setConsumeEnterKeyPress(boolean consume) {
|
public void setConsumeEnterKeyPress(boolean consume) {
|
||||||
this.consumeEnterKeyPress = consume;
|
this.consumeEnterKeyPress = consume;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True signals to do nothing when the user presses Enter. The default is to respond to the
|
* True signals to do nothing when the user presses Enter. The default is to respond to the
|
||||||
* Enter key, using any existing selection to set this field's {@link #getSelectedValue()
|
* Enter key, using any existing selection to set this field's {@link #getSelectedValue()
|
||||||
* selected value}.
|
* selected value}.
|
||||||
*
|
*
|
||||||
* <P>This can be set to true to allow clients to show drop-down matches without allowing the
|
* <P>This can be set to true to allow clients to show drop-down matches without allowing the
|
||||||
* user to select them, triggering the window to be closed.
|
* user to select them, triggering the window to be closed.
|
||||||
*
|
*
|
||||||
* @param ignore true to ignore Enter presses; false is the default
|
* @param ignore true to ignore Enter presses; false is the default
|
||||||
|
@ -504,9 +508,9 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
* the text field.
|
* the text field.
|
||||||
*
|
*
|
||||||
* <P>Note: the listener is stored in a {@link WeakDataStructureFactory weak data structure},
|
* <P>Note: the listener is stored in a {@link WeakDataStructureFactory weak data structure},
|
||||||
* so you must maintain a reference to the listener you pass in--anonymous classes or lambdas
|
* so you must maintain a reference to the listener you pass in--anonymous classes or lambdas
|
||||||
* will not work.
|
* will not work.
|
||||||
*
|
*
|
||||||
* @param listener the listener
|
* @param listener the listener
|
||||||
*/
|
*/
|
||||||
public void addDropDownSelectionChoiceListener(DropDownSelectionChoiceListener<T> listener) {
|
public void addDropDownSelectionChoiceListener(DropDownSelectionChoiceListener<T> listener) {
|
||||||
|
@ -574,10 +578,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
matchingWindow = new JWindow(parentWindow);
|
matchingWindow = new JWindow(parentWindow);
|
||||||
matchingWindow.setFocusable(false);
|
matchingWindow.setFocusable(false);
|
||||||
JScrollPane scrollPane = new JScrollPane();
|
JScrollPane scrollPane = new JScrollPane();
|
||||||
scrollPane.setBorder(
|
scrollPane.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,
|
||||||
BorderFactory.createBevelBorder(BevelBorder.RAISED,
|
new GColor("color.border.bevel.highlight"), new GColor("color.border.bevel.shadow")));
|
||||||
new GColor("color.border.bevel.highlight"),
|
|
||||||
new GColor("color.border.bevel.shadow")));
|
|
||||||
scrollPane.setFocusable(false);
|
scrollPane.setFocusable(false);
|
||||||
scrollPane.getVerticalScrollBar().setFocusable(false);
|
scrollPane.getVerticalScrollBar().setFocusable(false);
|
||||||
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
|
@ -648,8 +650,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is more complicated that responding to the user mouse click. When clicked, the user is
|
* This is more complicated that responding to the user mouse click. When clicked, the user is
|
||||||
* signalling to use the clicked item. When pressing Enter, they may have been typing and
|
* signalling to use the clicked item. When pressing Enter, they may have been typing and
|
||||||
* ignoring the list, so we have to do some validation.
|
* ignoring the list, so we have to do some validation.
|
||||||
*/
|
*/
|
||||||
private void setTextFromListOnEnterPress() {
|
private void setTextFromListOnEnterPress() {
|
||||||
|
@ -687,11 +689,11 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current selection on this text field. This will store the provided value and set
|
* Sets the current selection on this text field. This will store the provided value and set
|
||||||
* the text of the text field to be the name of that value. If the given value is null, then
|
* the text of the text field to be the name of that value. If the given value is null, then
|
||||||
* the text of this field will be cleared.
|
* the text of this field will be cleared.
|
||||||
*
|
*
|
||||||
* @param value The value that is to be the current selection or null to clear the selected
|
* @param value The value that is to be the current selection or null to clear the selected
|
||||||
* value of this text field.
|
* value of this text field.
|
||||||
*/
|
*/
|
||||||
public void setSelectedValue(T value) {
|
public void setSelectedValue(T value) {
|
||||||
|
|
|
@ -32,7 +32,6 @@ import docking.widgets.label.GDLabel;
|
||||||
import docking.widgets.list.GList;
|
import docking.widgets.list.GList;
|
||||||
import docking.widgets.list.GListAutoLookup;
|
import docking.widgets.list.GListAutoLookup;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
|
||||||
class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryModelIf {
|
class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryModelIf {
|
||||||
|
@ -186,7 +185,7 @@ class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryMod
|
||||||
});
|
});
|
||||||
|
|
||||||
listEditor = new JPanel(new BorderLayout());
|
listEditor = new JPanel(new BorderLayout());
|
||||||
listEditor.setBorder(BorderFactory.createLineBorder(Java.BORDER));
|
listEditor.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
|
|
||||||
listEditor.add(listEditorLabel, BorderLayout.WEST);
|
listEditor.add(listEditorLabel, BorderLayout.WEST);
|
||||||
listEditor.add(listEditorField, BorderLayout.CENTER);
|
listEditor.add(listEditorField, BorderLayout.CENTER);
|
||||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.table.TableCellEditor;
|
import javax.swing.table.TableCellEditor;
|
||||||
|
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.filechooser.GhidraFileChooserModel;
|
import ghidra.util.filechooser.GhidraFileChooserModel;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class FileEditor extends AbstractCellEditor implements TableCellEditor {
|
||||||
// match the spacing of non-editing cells
|
// match the spacing of non-editing cells
|
||||||
editor.setBorder(
|
editor.setBorder(
|
||||||
BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0),
|
BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0),
|
||||||
BorderFactory.createLineBorder(Java.BORDER)));
|
BorderFactory.createLineBorder(Colors.BORDER)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDoubleClick(Point p) {
|
private void handleDoubleClick(Point p) {
|
||||||
|
|
|
@ -30,7 +30,6 @@ import docking.widgets.filechooser.GhidraFileChooser;
|
||||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import generic.util.Path;
|
import generic.util.Path;
|
||||||
import ghidra.framework.options.SaveState;
|
import ghidra.framework.options.SaveState;
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
|
@ -232,8 +231,7 @@ public class PathManager {
|
||||||
if (column == PathManagerModel.COLUMN_PATH) {
|
if (column == PathManagerModel.COLUMN_PATH) {
|
||||||
Path path = (Path) value;
|
Path path = (Path) value;
|
||||||
if (!isValidPath(path)) {
|
if (!isValidPath(path)) {
|
||||||
renderer.setForeground(data.isSelected() ? Tables.FG_ERROR_SELECTED
|
renderer.setForeground(getErrorForegroundColor(data.isSelected()));
|
||||||
: Tables.FG_ERROR_UNSELECTED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return renderer;
|
return renderer;
|
||||||
|
@ -386,7 +384,7 @@ public class PathManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore paths from user Preferences using the specified keys.
|
* Restore paths from user Preferences using the specified keys.
|
||||||
* If preferences have never been saved, the specified {@code defaultEnablePaths}
|
* If preferences have never been saved, the specified {@code defaultEnablePaths}
|
||||||
* will be used. Note: the encoded path list must have been stored
|
* will be used. Note: the encoded path list must have been stored
|
||||||
* using the same keys using the {@link #savePathsToPreferences(String, String, Path[])}
|
* using the same keys using the {@link #savePathsToPreferences(String, String, Path[])}
|
||||||
|
@ -405,7 +403,7 @@ public class PathManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore paths from user Preferences using the specified keys.
|
* Restore paths from user Preferences using the specified keys.
|
||||||
* If preferences have never been saved, the specified {@code defaultEnablePaths}
|
* If preferences have never been saved, the specified {@code defaultEnablePaths}
|
||||||
* will be returned. Note: the encoded path list must have been stored
|
* will be returned. Note: the encoded path list must have been stored
|
||||||
* using the same keys using the {@link #savePathsToPreferences(String, String, Path[])}
|
* using the same keys using the {@link #savePathsToPreferences(String, String, Path[])}
|
||||||
|
@ -472,7 +470,7 @@ public class PathManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the specified paths to the user Preferences using the specified keys.
|
* Save the specified paths to the user Preferences using the specified keys.
|
||||||
* Note: The encoded path Preferences are intended to be decoded by the
|
* Note: The encoded path Preferences are intended to be decoded by the
|
||||||
* {@link #restoreFromPreferences(String, Path[], String)} and
|
* {@link #restoreFromPreferences(String, Path[], String)} and
|
||||||
* {@link #getPathsFromPreferences(String, Path[], String)} methods.
|
* {@link #getPathsFromPreferences(String, Path[], String)} methods.
|
||||||
* @param enablePathKey preference key for storing enabled paths
|
* @param enablePathKey preference key for storing enabled paths
|
||||||
|
|
|
@ -29,7 +29,6 @@ import docking.widgets.filechooser.GhidraFileChooser;
|
||||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
import ghidra.util.filechooser.GhidraFileChooserModel;
|
import ghidra.util.filechooser.GhidraFileChooserModel;
|
||||||
import ghidra.util.filechooser.GhidraFileFilter;
|
import ghidra.util.filechooser.GhidraFileFilter;
|
||||||
|
@ -265,8 +264,7 @@ public class PathnameTablePanel extends JPanel {
|
||||||
|
|
||||||
label.setText(pathName.toString());
|
label.setText(pathName.toString());
|
||||||
if (!fileExists) {
|
if (!fileExists) {
|
||||||
label.setForeground(data.isSelected() ? Tables.FG_ERROR_SELECTED
|
label.setForeground(getErrorForegroundColor(data.isSelected()));
|
||||||
: Tables.FG_ERROR_UNSELECTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return label;
|
return label;
|
||||||
|
|
|
@ -33,7 +33,7 @@ import docking.widgets.table.GTableFilterPanel;
|
||||||
import docking.widgets.table.RowObjectFilterModel;
|
import docking.widgets.table.RowObjectFilterModel;
|
||||||
import docking.widgets.table.columnfilter.*;
|
import docking.widgets.table.columnfilter.*;
|
||||||
import docking.widgets.table.constrainteditor.ColumnConstraintEditor;
|
import docking.widgets.table.constrainteditor.ColumnConstraintEditor;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||||
import generic.util.WindowUtilities;
|
import generic.util.WindowUtilities;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
@ -383,7 +383,7 @@ public class ColumnFilterDialog<R> extends ReusableDialogComponentProvider
|
||||||
headerPanel.add(new GLabel("Filter Value", SwingConstants.CENTER));
|
headerPanel.add(new GLabel("Filter Value", SwingConstants.CENTER));
|
||||||
|
|
||||||
headerPanel.setBorder(new CompoundBorder(
|
headerPanel.setBorder(new CompoundBorder(
|
||||||
BorderFactory.createMatteBorder(0, 0, 1, 0, Java.BORDER),
|
BorderFactory.createMatteBorder(0, 0, 1, 0, Colors.BORDER),
|
||||||
BorderFactory.createEmptyBorder(4, 0, 4, 0)));
|
BorderFactory.createEmptyBorder(4, 0, 4, 0)));
|
||||||
return headerPanel;
|
return headerPanel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,7 +409,7 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
|
||||||
|
|
||||||
mainPanel.add(layeredPane, BorderLayout.CENTER);
|
mainPanel.add(layeredPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
satellite.setBorder(BorderFactory.createLineBorder(Colors.Java.BORDER));
|
satellite.setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
|
|
||||||
undockedSatellitePanel = new JPanel(new BorderLayout());
|
undockedSatellitePanel = new JPanel(new BorderLayout());
|
||||||
undockedSatellitePanel.addComponentListener(new ComponentAdapter() {
|
undockedSatellitePanel.addComponentListener(new ComponentAdapter() {
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class VisualVertexSatelliteRenderer<V extends VisualVertex, E extends Vis
|
||||||
bounds.height + (offset * 2));
|
bounds.height + (offset * 2));
|
||||||
|
|
||||||
if (isGraphScaledEnoughToBeDifficultToSee(rc)) {
|
if (isGraphScaledEnoughToBeDifficultToSee(rc)) {
|
||||||
g.setColor(Colors.Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.drawOval(bounds.x - offset, bounds.y - offset, bounds.width + (offset * 2),
|
g.drawOval(bounds.x - offset, bounds.y - offset, bounds.width + (offset * 2),
|
||||||
bounds.height + (offset * 2));
|
bounds.height + (offset * 2));
|
||||||
g.drawOval(bounds.x - offset - 1, bounds.y - offset - 1,
|
g.drawOval(bounds.x - offset - 1, bounds.y - offset - 1,
|
||||||
|
|
|
@ -153,7 +153,7 @@ public class VisualVertexRenderer<V extends VisualVertex, E extends VisualEdge<V
|
||||||
g.fill(shape);
|
g.fill(shape);
|
||||||
|
|
||||||
// an outline
|
// an outline
|
||||||
g.setColor(Colors.Java.BORDER);
|
g.setColor(Colors.BORDER);
|
||||||
g.draw(shape);
|
g.draw(shape);
|
||||||
|
|
||||||
g.setPaint(oldPaint);
|
g.setPaint(oldPaint);
|
||||||
|
|
|
@ -19,60 +19,85 @@ import static generic.theme.SystemThemeIds.*;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
/** TODO doc how clients should use this in their code, with
|
/**
|
||||||
|
* This class contains many suitable default values for commonly used concepts. See each static
|
||||||
|
* class below.
|
||||||
|
* <P>
|
||||||
|
* The values in this class can be used where standard colors are desired. For example, where
|
||||||
|
* clients used to hard-code black for the font color:
|
||||||
|
* <PRE>
|
||||||
|
* <CODE>
|
||||||
|
* JLabel label = new JLabel():
|
||||||
|
* label.setColor(Color.BLACK);
|
||||||
|
* </CODE>
|
||||||
|
* </PRE>
|
||||||
|
* Can instead be programmed to use the system's current theme font color instead:
|
||||||
|
* <PRE>
|
||||||
|
* <CODE>
|
||||||
|
* import generic.theme.GThemeDefaults.Colors;
|
||||||
|
*
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* JLabel label = new JLabel():
|
||||||
|
* label.setColor(Colors.FOREGROUND);
|
||||||
|
* </CODE>
|
||||||
|
* </PRE>
|
||||||
|
* Note that in the second example, you can use the shorthand version of the values in this class
|
||||||
|
* as long as you import them correctly. This means you do not have to use this form:
|
||||||
|
* <PRE>
|
||||||
|
* <CODE>
|
||||||
|
* component.setColor(GThemeDefaults.Colors.FOREGROUND);
|
||||||
|
* </CODE>
|
||||||
|
* </PRE>
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Colors.BACKGROUND
|
|
||||||
* Colors.Java.BORDER
|
|
||||||
*/
|
*/
|
||||||
public class GThemeDefaults {
|
public class GThemeDefaults {
|
||||||
public static class Ids {
|
|
||||||
|
|
||||||
|
public static class Ids {
|
||||||
public static class Fonts {
|
public static class Fonts {
|
||||||
public static final String MONOSPACED = "font.monospaced";
|
public static final String MONOSPACED = "font.monospaced";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Colors mapped to system values
|
* Colors mapped to common system widget concepts, such as foreground, background, border, etc.
|
||||||
*/
|
*/
|
||||||
public static class Colors {
|
public static class Colors {
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|
||||||
// standard color concepts defined by LookAndFeel
|
|
||||||
public static final GColor BG_CONTROL = new GColor(BG_CONTROL_ID);
|
|
||||||
public static final GColor BG_VIEW = new GColor(BG_VIEW_ID);
|
|
||||||
public static final GColor BG_TOOLTIP = new GColor(BG_TOOLTIP_ID);
|
|
||||||
public static final GColor BG_VIEW_SELECTED = new GColor(BG_VIEW_SELECTED_ID);
|
|
||||||
public static final GColor BG_BORDER = new GColor(BG_BORDER_ID);
|
|
||||||
|
|
||||||
public static final GColor FG_CONTROL = new GColor(FG_CONTROL_ID);
|
|
||||||
public static final GColor FG_VIEW = new GColor(FG_VIEW_ID);
|
|
||||||
public static final GColor FG_TOOLTIP = new GColor(FG_TOOLTIP_ID);
|
|
||||||
public static final GColor FG_VIEW_SELECTED = new GColor(FG_VIEW_SELECTED_ID);
|
|
||||||
public static final GColor FG_DISABLED = new GColor(FG_DISABLED_ID);
|
|
||||||
|
|
||||||
// generic color concepts
|
// generic color concepts
|
||||||
public static final GColor BACKGROUND = new GColor("color.bg");
|
public static final GColor BACKGROUND = new GColor("color.bg");
|
||||||
public static final GColor CURSOR = new GColor("color.cursor.focused");
|
|
||||||
public static final GColor ERROR = new GColor("color.fg.error");
|
|
||||||
public static final GColor FOREGROUND = new GColor("color.fg");
|
public static final GColor FOREGROUND = new GColor("color.fg");
|
||||||
public static final GColor FOREGROUND_DISABLED = new GColor("color.fg.disabled");
|
public static final GColor FOREGROUND_DISABLED = new GColor("color.fg.disabled");
|
||||||
|
public static final GColor CURSOR = new GColor("color.cursor.focused");
|
||||||
|
public static final GColor ERROR = new GColor("color.fg.error");
|
||||||
|
public static final GColor BORDER = new GColor(BG_BORDER_ID);
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
public static class Java {
|
/**
|
||||||
public static final GColor BORDER = BG_BORDER;
|
* Color values to use for tables
|
||||||
}
|
*/
|
||||||
|
|
||||||
public static class Tables {
|
public static class Tables {
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
public static final GColor FG_ERROR_SELECTED = new GColor("color.fg.error.table.selected");
|
public static final GColor ERROR_SELECTED = new GColor("color.fg.error.table.selected");
|
||||||
public static final GColor FG_ERROR_UNSELECTED = new GColor("color.fg.error.table.unselected");
|
public static final GColor ERROR_UNSELECTED = new GColor("color.fg.error.table.unselected");
|
||||||
public static final GColor FG_UNEDITABLE_SELECTED = new GColor("color.fg.table.uneditable.selected");
|
public static final GColor UNEDITABLE_SELECTED = new GColor("color.fg.table.uneditable.selected");
|
||||||
public static final GColor FG_UNEDITABLE_UNSELECTED = new GColor("color.fg.table.uneditable.unselected");
|
public static final GColor UNEDITABLE_UNSELECTED = new GColor("color.fg.table.uneditable.unselected");
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color values to use with tooltips
|
||||||
|
*/
|
||||||
|
public static class Tooltips {
|
||||||
|
@SuppressWarnings("hiding") // we know there is another 'BACKGROUND' field in this file
|
||||||
|
public static final GColor BACKGROUND = new GColor(BG_TOOLTIP_ID);
|
||||||
|
@SuppressWarnings("hiding") // we know there is another 'FOREGROUND' field in this file
|
||||||
|
public static final GColor FOREGROUND = new GColor(FG_TOOLTIP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'Messages' is primarily used by system dialogs to display status. That the colors are
|
* 'Messages' is primarily used by system dialogs to display status. That the colors are
|
||||||
* used for foregrounds is implied.
|
* used for foregrounds is implied.
|
||||||
|
@ -89,7 +114,8 @@ public class GThemeDefaults {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic palette colors, using color names, that may be changed along with the theme
|
* Generic palette colors, using color names, that may be changed along with the theme.
|
||||||
|
* These are not all defined palette colors, but some of the more commonly used colors.
|
||||||
*/
|
*/
|
||||||
public static class Palette {
|
public static class Palette {
|
||||||
|
|
||||||
|
@ -119,7 +145,7 @@ public class GThemeDefaults {
|
||||||
/**
|
/**
|
||||||
* Returns a new {@link GColor} for the given palette name.
|
* Returns a new {@link GColor} for the given palette name.
|
||||||
* <p>
|
* <p>
|
||||||
* For a list of supported palette IDs, see {@code docking.palette.theme.properties}.
|
* For a list of supported palette IDs, see {@code gui.palette.theme.properties}.
|
||||||
* <p>
|
* <p>
|
||||||
* It is preferred to use the static colors defined in {@link Palette} when possible, as
|
* It is preferred to use the static colors defined in {@link Palette} when possible, as
|
||||||
* it prevents excess object creation. This method should be used when the desired
|
* it prevents excess object creation. This method should be used when the desired
|
||||||
|
|
|
@ -161,8 +161,18 @@ public class Gui {
|
||||||
return themeManager.isDarkTheme();
|
return themeManager.isDarkTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given id is a system-defined id, such as those starting with
|
||||||
|
* {@code laf.color} or {@code system.color}.
|
||||||
|
*
|
||||||
|
* @param id the id
|
||||||
|
* @return true if the given id is a system-defined id
|
||||||
|
*/
|
||||||
|
public static boolean isSystemId(String id) {
|
||||||
|
return id.startsWith("laf.") || id.startsWith("system.");
|
||||||
|
}
|
||||||
|
|
||||||
static void setThemeManager(ThemeManager manager) {
|
static void setThemeManager(ThemeManager manager) {
|
||||||
themeManager = manager;
|
themeManager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,19 @@ package generic.theme;
|
||||||
import generic.theme.laf.UiDefaultsMapper;
|
import generic.theme.laf.UiDefaultsMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are the standard system ids defined to represent general LookAndFeel color and font
|
* This class provides a set of IDs that can be used in the application, regardless of which Look
|
||||||
* concepts. Various LaF have different names for these concepts and even defines additional
|
* and Feel (LaF) is being used.
|
||||||
* concepts. These are the ones we use regardless of the LookAndFeel being used. When we
|
* <P>
|
||||||
* load a specific LookAndFeel, a {@link UiDefaultsMapper}, specific to that LaF is used to map
|
* Various LaFs have different names for common concepts and even define additional concepts not
|
||||||
* its system ids to our standard system ids. Also, {@link GThemeDefaults} uses these system
|
* listed here. The values in this class are those the application used use regardless of the LaF
|
||||||
* ids to define colors that can be used throughout the application without using these ids
|
* being used. When we load a specific LaF, a {@link UiDefaultsMapper} specific to that LaF is used
|
||||||
|
* to map its common LaF ids to these standard system ids. The {@link GThemeDefaults} uses these
|
||||||
|
* system ids to define colors that can be used throughout the application without using these ids
|
||||||
* directly.
|
* directly.
|
||||||
* <P>
|
* <P>
|
||||||
* The ids are assigned to categories as follows:
|
* The ids are assigned to categories as follows:
|
||||||
* <UL>
|
* <UL>
|
||||||
* <LI>CONTROL- these ids are used for colors and fonts for general system components such as
|
* <LI>CONTROL- these ids are used for colors and fonts for general system components such as
|
||||||
* Buttons, Checkboxes, or anything that doesn't fit into one of the other areas</LI>
|
* Buttons, Checkboxes, or anything that doesn't fit into one of the other areas</LI>
|
||||||
* <LI>VIEW - these ids are used for the colors and fonts used for widgets that display data
|
* <LI>VIEW - these ids are used for the colors and fonts used for widgets that display data
|
||||||
* such as Trees, Tables, TextFieds, and Lists</LI>
|
* such as Trees, Tables, TextFieds, and Lists</LI>
|
||||||
|
@ -45,7 +47,6 @@ import generic.theme.laf.UiDefaultsMapper;
|
||||||
* <LI> FG_DISABLED - the foreground color when the component is disabled
|
* <LI> FG_DISABLED - the foreground color when the component is disabled
|
||||||
* <LI> BG_BORDER - the border color
|
* <LI> BG_BORDER - the border color
|
||||||
* <LI> FONT - the font
|
* <LI> FONT - the font
|
||||||
*
|
|
||||||
* </UL>
|
* </UL>
|
||||||
*/
|
*/
|
||||||
public class SystemThemeIds {
|
public class SystemThemeIds {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains a week set of components associated with a given font id. Whenever the font changes
|
* Maintains a weak set of components associated with a given font id. Whenever the font changes
|
||||||
* for the font id, this class will update the component's font to the new value.
|
* for the font id, this class will update the component's font to the new value.
|
||||||
*/
|
*/
|
||||||
public class ComponentFontRegistry {
|
public class ComponentFontRegistry {
|
||||||
|
|
|
@ -194,7 +194,7 @@ public abstract class LookAndFeelManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds the component to the font identified by the given font id. Whenever the font for
|
* Binds the component to the font identified by the given font id. Whenever the font for
|
||||||
* the font id changes, the component will updated with the new font.
|
* the font id changes, the component will be updated with the new font.
|
||||||
* @param component the component to set/update the font
|
* @param component the component to set/update the font
|
||||||
* @param fontId the id of the font to register with the given component
|
* @param fontId the id of the font to register with the given component
|
||||||
*/
|
*/
|
||||||
|
@ -213,7 +213,7 @@ public abstract class LookAndFeelManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass provide this method to install the specific look and feel.
|
* Subclasses may override this method to install a specific look and feel.
|
||||||
*
|
*
|
||||||
* @throws ClassNotFoundException if the <code>LookAndFeel</code>
|
* @throws ClassNotFoundException if the <code>LookAndFeel</code>
|
||||||
* class could not be found
|
* class could not be found
|
||||||
|
@ -231,7 +231,7 @@ public abstract class LookAndFeelManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass can override this method to do specific LookAndFeel fix ups
|
* Subclass may override this method to do specific LookAndFeel fix ups
|
||||||
*/
|
*/
|
||||||
protected void fixupLookAndFeelIssues() {
|
protected void fixupLookAndFeelIssues() {
|
||||||
// no generic fix-ups at this time.
|
// no generic fix-ups at this time.
|
||||||
|
|
|
@ -25,8 +25,8 @@ import ghidra.util.exception.AssertException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nimbus {@link LookAndFeelManager}. Specialized so that it can return the Nimbus installer and
|
* Nimbus {@link LookAndFeelManager}. Specialized so that it can return the Nimbus installer and
|
||||||
* do specialized updating when icons or fonts change. Basically, needs to re-install a new
|
* perform specialized updating when icons or fonts change. Basically, this class needs to
|
||||||
* instance of the Nimbus LookAndFeel each time a font or icon changes
|
* re-install a new instance of the Nimbus LookAndFeel each time a font or icon changes.
|
||||||
*/
|
*/
|
||||||
public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||||
|
|
||||||
|
@ -60,9 +60,9 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||||
|
|
||||||
private void reinstallNimubus() {
|
private void reinstallNimubus() {
|
||||||
try {
|
try {
|
||||||
/**
|
/*
|
||||||
* In order to get Nimbus to honor changes to fonts and icons in the UiDefaults,
|
* In order to get Nimbus to honor changes to fonts and icons in the UiDefaults,
|
||||||
* we have to reinstall nimbus. Reinstalling nimbus is a bit different that the first
|
* we have to reinstall Nimbus. Reinstalling Nimbus is a bit different than the original
|
||||||
* install. First, we don't want to re-install the java defaults, the current ones are
|
* install. First, we don't want to re-install the java defaults, the current ones are
|
||||||
* fine and we don't want loose any current theme values changes. Second, when we
|
* fine and we don't want loose any current theme values changes. Second, when we
|
||||||
* get font and theme value overrides, we want to use all the current values as they
|
* get font and theme value overrides, we want to use all the current values as they
|
||||||
|
@ -93,16 +93,16 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processJavaDefaults() {
|
protected void processJavaDefaults() {
|
||||||
// The GNimbusLookAndFeel already extracted the java defaults and installed them in the Gui
|
// We already extracted the java defaults and installed them in the Gui
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void fixupLookAndFeelIssues() {
|
protected void fixupLookAndFeelIssues() {
|
||||||
super.fixupLookAndFeelIssues();
|
super.fixupLookAndFeelIssues();
|
||||||
|
|
||||||
// fix scroll bar grabber disappearing. See https://bugs.openjdk.java.net/browse/JDK-8134828
|
// fix scroll bar grabber disappearing. See
|
||||||
// This fix looks like it should not cause harm even if the bug is fixed on the jdk side.
|
// https://bugs.openjdk.java.net/browse/JDK-8134828. This fix looks like it should not cause
|
||||||
|
// harm even if the bug is fixed on the jdk side.
|
||||||
UIDefaults defaults = UIManager.getDefaults();
|
UIDefaults defaults = UIManager.getDefaults();
|
||||||
defaults.put("ScrollBar.minimumThumbSize", new Dimension(30, 30));
|
defaults.put("ScrollBar.minimumThumbSize", new Dimension(30, 30));
|
||||||
|
|
||||||
|
|
|
@ -33,42 +33,42 @@ import generic.theme.*;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The purpose of this class is to introduce multiple levels of indirection into the Java
|
* The purpose of this class is to introduce multiple levels of indirection into the Java
|
||||||
* {@code LookAndFeel} (LaF), which allows the user to change these values. Further, when
|
* {@code LookAndFeel} (LaF), which allows the user to change these values. Further, when
|
||||||
* introducing this indirection we combine the Java settings into user-friendly system ids to make
|
* introducing this indirection we combine the Java settings into user-friendly system ids to make
|
||||||
* changing these values easier.
|
* changing these values easier.
|
||||||
* <P>
|
* <P>
|
||||||
* This class defines these user-friendly groups. The default system assignments are based on the
|
* This class defines these user-friendly groups. The default system assignments are based on the
|
||||||
* {@link BasicLookAndFeel} values.
|
* {@link BasicLookAndFeel} values.
|
||||||
* <P>
|
* <P>
|
||||||
* Subclasses can override the mapping of these standard system values for particular LaFs that have
|
* Subclasses can override the mapping of these standard system values for particular LaFs that have
|
||||||
* different keys or color assignments.
|
* different ids or color assignments.
|
||||||
* <P>
|
* <P>
|
||||||
* Some basic concepts:
|
* Some basic concepts:
|
||||||
* <UL>
|
* <UL>
|
||||||
* <LI>UI Defaults - key-value pairs defined by the Java LaF; there are 2 key types, widget
|
* <LI>UI Defaults - key-value pairs defined by the Java LaF; there are 2 key types, widget
|
||||||
* keys and Java group/reusable keys (e.g., Button.background; control)
|
* keys and Java group/reusable keys (e.g., Button.background; control)
|
||||||
* <LI>UI Indirection - UI Defaults values are changed to point to custom terms we created to
|
* <LI>UI Indirection - UI Defaults values are changed to point to custom terms we created to
|
||||||
* allow for indirection (e.g., Button.background -> laf.color.Button.background)
|
* allow for indirection (e.g., Button.background -> laf.color.Button.background)
|
||||||
* <LI>Normalized Keys - keys we created to facilitate the UI Indirection, based upon the Java
|
* <LI>Normalized Keys - keys we created to facilitate the UI Indirection, based upon the Java
|
||||||
* keys (e.g., laf.color.Button.background)
|
* keys (e.g., laf.color.Button.background)
|
||||||
* <LI>System Color/Font Keys - user facing terms for common color or font concepts into an
|
* <LI>System Color/Font Keys - user facing terms for common color or font concepts into an
|
||||||
* easy-to-change setting (e.g., system.color.fg.text)
|
* easy-to-change setting (e.g., system.color.fg.text)
|
||||||
* <LI>Palette Keys - dynamically generated color palette keys based on the LaF for any colors
|
* <LI>Palette Keys - dynamically generated color palette keys based on the LaF for any colors
|
||||||
* and fonts that were not mapped into an system color or font (e.g.,
|
* and fonts that were not mapped into an system color or font (e.g.,
|
||||||
* laf.palette.color.01)
|
* laf.palette.color.01)
|
||||||
* </UL>
|
* </UL>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* The mapper performs the following operations:
|
* The mapper performs the following operations:
|
||||||
* <OL>
|
* <OL>
|
||||||
* <LI>Extracts all color, font, and icon values from the UI Defaults.</LI>
|
* <LI>Extracts all color, font, and icon values from the UI Defaults.</LI>
|
||||||
* <LI>Use the current LaF values to populate the pre-defined system colors and fonts.</LI>
|
* <LI>Use the current LaF values to populate the pre-defined system colors and fonts.</LI>
|
||||||
* <LI>Any UI Defaults values not assigned in the previous step will be assigned to a dynamic shared
|
* <LI>Any UI Defaults values not assigned in the previous step will be assigned to a dynamic shared
|
||||||
* palette color or font.
|
* palette color or font.
|
||||||
* <LI>Update Java UI Defaults to use our indirection and system values.</LI>
|
* <LI>Update Java UI Defaults to use our indirection and system values.</LI>
|
||||||
* </OL>
|
* </OL>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class UiDefaultsMapper {
|
public class UiDefaultsMapper {
|
||||||
public static final String LAF_COLOR_ID_PREFIX = "laf.color.";
|
public static final String LAF_COLOR_ID_PREFIX = "laf.color.";
|
||||||
|
@ -96,17 +96,17 @@ public class UiDefaultsMapper {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
protected ColorMatcher viewColorMatcher = new ColorMatcher(BG_VIEW_ID,
|
protected ColorMatcher viewColorMatcher = new ColorMatcher(BG_VIEW_ID,
|
||||||
FG_VIEW_ID,
|
FG_VIEW_ID,
|
||||||
BG_VIEW_SELECTED_ID,
|
BG_VIEW_SELECTED_ID,
|
||||||
FG_VIEW_SELECTED_ID);
|
FG_VIEW_SELECTED_ID);
|
||||||
protected ColorMatcher tooltipColorMatcher = new ColorMatcher(BG_TOOLTIP_ID,
|
protected ColorMatcher tooltipColorMatcher = new ColorMatcher(BG_TOOLTIP_ID,
|
||||||
FG_TOOLTIP_ID);
|
FG_TOOLTIP_ID);
|
||||||
protected ColorMatcher defaultColorMatcher = new ColorMatcher(BG_CONTROL_ID,
|
protected ColorMatcher defaultColorMatcher = new ColorMatcher(BG_CONTROL_ID,
|
||||||
FG_CONTROL_ID,
|
FG_CONTROL_ID,
|
||||||
BG_VIEW_ID,
|
BG_VIEW_ID,
|
||||||
FG_VIEW_ID,
|
FG_VIEW_ID,
|
||||||
FG_DISABLED_ID,
|
FG_DISABLED_ID,
|
||||||
BG_VIEW_SELECTED_ID,
|
BG_VIEW_SELECTED_ID,
|
||||||
FG_VIEW_SELECTED_ID,
|
FG_VIEW_SELECTED_ID,
|
||||||
BG_TOOLTIP_ID,
|
BG_TOOLTIP_ID,
|
||||||
BG_BORDER_ID);
|
BG_BORDER_ID);
|
||||||
|
@ -187,7 +187,7 @@ public class UiDefaultsMapper {
|
||||||
/**
|
/**
|
||||||
* Registers any {@link LookAndFeel} ids that are not used directly (e.g. "control", "text",
|
* Registers any {@link LookAndFeel} ids that are not used directly (e.g. "control", "text",
|
||||||
* etc.) so that these values won't get mapped to any normalized id. There is no need for these
|
* etc.) so that these values won't get mapped to any normalized id. There is no need for these
|
||||||
* values to show up in the theme values, since changing them will have no effect. They are
|
* values to show up in the theme values, since changing them will have no effect. They are
|
||||||
* used to seed the values for the system color and fonts. Subclasses should
|
* used to seed the values for the system color and fonts. Subclasses should
|
||||||
* override this method to add additional ids so they won't show up in the theme values.
|
* override this method to add additional ids so they won't show up in the theme values.
|
||||||
*/
|
*/
|
||||||
|
@ -228,11 +228,11 @@ public class UiDefaultsMapper {
|
||||||
protected void assignSystemColorValues() {
|
protected void assignSystemColorValues() {
|
||||||
// Originally, these values were assigned to the corresponding concepts as defined
|
// Originally, these values were assigned to the corresponding concepts as defined
|
||||||
// in the BasicLookAndFeel such as "control", "text", etc. Unfortunately, those
|
// in the BasicLookAndFeel such as "control", "text", etc. Unfortunately, those
|
||||||
// conventions are rarely used by specific look and feels. It was discovered that using a
|
// conventions are rarely used by specific look and feels. It was discovered that using a
|
||||||
// representative component value worked much better. So each Look and Feel was examined and
|
// representative component value worked much better. So each Look and Feel was examined and
|
||||||
// those component values chosen here are the ones that seemed to work for the most look and
|
// those component values chosen here are the ones that seemed to work for the most look and
|
||||||
// feels. If a specific look and feel needs different values, this class is designed to be
|
// feels. If a specific look and feel needs different values, this class is designed to be
|
||||||
// subclassed where the values can be overridden. See the NimbusUiDefaultsMapper as an
|
// subclassed where the values can be overridden. See the NimbusUiDefaultsMapper as an
|
||||||
// example.
|
// example.
|
||||||
|
|
||||||
assignSystemColorFromLafId(BG_CONTROL_ID, "Button.background");
|
assignSystemColorFromLafId(BG_CONTROL_ID, "Button.background");
|
||||||
|
@ -325,7 +325,7 @@ public class UiDefaultsMapper {
|
||||||
/**
|
/**
|
||||||
* Assigns every component name in the component group to the given ColorValueMatcher
|
* Assigns every component name in the component group to the given ColorValueMatcher
|
||||||
* @param componentGroups a list of component names
|
* @param componentGroups a list of component names
|
||||||
* @param matcher the ColorMatcher that will provide the precedence of system ids to
|
* @param matcher the ColorMatcher that will provide the precedence of system ids to
|
||||||
* search when replacing LaF component specific values
|
* search when replacing LaF component specific values
|
||||||
*/
|
*/
|
||||||
private void defineComponentColorMatcher(String[] componentGroups, ColorMatcher matcher) {
|
private void defineComponentColorMatcher(String[] componentGroups, ColorMatcher matcher) {
|
||||||
|
@ -337,7 +337,7 @@ public class UiDefaultsMapper {
|
||||||
/**
|
/**
|
||||||
* Assigns every component name in a component group to the given FontValueMapper
|
* Assigns every component name in a component group to the given FontValueMapper
|
||||||
* @param componentGroups a list of component names
|
* @param componentGroups a list of component names
|
||||||
* @param matcher the FontValueMatcher that will provide the precedence of ststem font ids to
|
* @param matcher the FontValueMatcher that will provide the precedence of ststem font ids to
|
||||||
* search when replacing LaF component specific fonts with a system Font
|
* search when replacing LaF component specific fonts with a system Font
|
||||||
*/
|
*/
|
||||||
private void defineComponentFontMatcher(String[] componentGroups, FontMatcher matcher) {
|
private void defineComponentFontMatcher(String[] componentGroups, FontMatcher matcher) {
|
||||||
|
@ -477,7 +477,7 @@ public class UiDefaultsMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to find a system color id that matches the given color. The order system ids are
|
* Attempts to find a system color id that matches the given color. The order system ids are
|
||||||
* searched depends on the component (Button, Menu, etc.) which is derived from the given
|
* searched depends on the component (Button, Menu, etc.) which is derived from the given
|
||||||
* lafId.
|
* lafId.
|
||||||
* @param lafId the lafId we are attempting to get a system color for
|
* @param lafId the lafId we are attempting to get a system color for
|
||||||
|
@ -499,7 +499,7 @@ public class UiDefaultsMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to find a system font id that matches the given font. The order system fonts are
|
* Attempts to find a system font id that matches the given font. The order system fonts are
|
||||||
* searched depends on the component (Button, Menu, etc.) which is derived from the given
|
* searched depends on the component (Button, Menu, etc.) which is derived from the given
|
||||||
* lafId.
|
* lafId.
|
||||||
* @param lafId the lafId we are attempting to get a system font for
|
* @param lafId the lafId we are attempting to get a system font for
|
||||||
|
|
|
@ -30,8 +30,8 @@ import docking.dnd.GClipboard;
|
||||||
import docking.dnd.StringTransferable;
|
import docking.dnd.StringTransferable;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import docking.widgets.label.GIconLabel;
|
import docking.widgets.label.GIconLabel;
|
||||||
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.Gui;
|
import generic.theme.Gui;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
@ -118,7 +118,7 @@ public class AboutDomainObjectUtils {
|
||||||
auxArea.setCaretPosition(0); // move cursor to BOF...
|
auxArea.setCaretPosition(0); // move cursor to BOF...
|
||||||
JScrollPane sp = new JScrollPane(auxArea);
|
JScrollPane sp = new JScrollPane(auxArea);
|
||||||
sp.setBorder(BorderFactory.createTitledBorder(
|
sp.setBorder(BorderFactory.createTitledBorder(
|
||||||
BorderFactory.createLineBorder(Java.BORDER), "Additional Information"));
|
BorderFactory.createLineBorder(Colors.BORDER), "Additional Information"));
|
||||||
sp.setPreferredSize(new Dimension(1, 175)); //width is ignored by border layout...
|
sp.setPreferredSize(new Dimension(1, 175)); //width is ignored by border layout...
|
||||||
|
|
||||||
JScrollBar sb = sp.getVerticalScrollBar();
|
JScrollBar sb = sp.getVerticalScrollBar();
|
||||||
|
|
|
@ -37,7 +37,6 @@ import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import docking.widgets.list.GListCellRenderer;
|
import docking.widgets.list.GListCellRenderer;
|
||||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
@ -60,8 +59,6 @@ class EditPluginPathDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
static final String ADD_DIR_BUTTON_TEXT = "Add Dir ...";
|
static final String ADD_DIR_BUTTON_TEXT = "Add Dir ...";
|
||||||
static final String ADD_JAR_BUTTON_TEXT = "Add Jar ...";
|
static final String ADD_JAR_BUTTON_TEXT = "Add Jar ...";
|
||||||
private final static Color INVALID_PATH_COLOR = Tables.FG_ERROR_UNSELECTED;
|
|
||||||
private final static Color INVALID_SELECTED_PATH_COLOR = Tables.FG_ERROR_SELECTED;
|
|
||||||
private final static Color STATUS_MESSAGE_COLOR = Messages.NORMAL;
|
private final static Color STATUS_MESSAGE_COLOR = Messages.NORMAL;
|
||||||
final static String EMPTY_STATUS = " ";
|
final static String EMPTY_STATUS = " ";
|
||||||
|
|
||||||
|
@ -467,7 +464,7 @@ class EditPluginPathDialog extends DialogComponentProvider {
|
||||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||||
boolean pathOK = new File(value).canRead();
|
boolean pathOK = new File(value).canRead();
|
||||||
if (!pathOK) {
|
if (!pathOK) {
|
||||||
setForeground(isSelected ? INVALID_SELECTED_PATH_COLOR : INVALID_PATH_COLOR);
|
setForeground(getErrorForegroundColor(isSelected));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.util.*;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.threaded.ThreadedTableModel;
|
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
|
@ -47,13 +46,13 @@ import utilities.util.FileUtilities;
|
||||||
* - Archive directory (hidden)
|
* - Archive directory (hidden)
|
||||||
* </pre>
|
* </pre>
|
||||||
* <p>
|
* <p>
|
||||||
* All columns are for display purposes only, except for the <code>installed</code> column, which
|
* All columns are for display purposes only, except for the <code>installed</code> column, which
|
||||||
* is a checkbox allowing users to install/uninstall a particular extension.
|
* is a checkbox allowing users to install/uninstall a particular extension.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
|
|
||||||
/** We don't care about the ordering of other columns, but the install/uninstall checkbox should be
|
/** We don't care about the ordering of other columns, but the install/uninstall checkbox should be
|
||||||
the first one and the name col is our initial sort column. */
|
the first one and the name col is our initial sort column. */
|
||||||
final static int INSTALLED_COL = 0;
|
final static int INSTALLED_COL = 0;
|
||||||
final static int NAME_COL = 1;
|
final static int NAME_COL = 1;
|
||||||
|
@ -66,7 +65,7 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param serviceProvider the tool providing the extensions table
|
* @param serviceProvider the tool providing the extensions table
|
||||||
*/
|
*/
|
||||||
protected ExtensionTableModel(ServiceProvider serviceProvider) {
|
protected ExtensionTableModel(ServiceProvider serviceProvider) {
|
||||||
|
@ -76,8 +75,7 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
@Override
|
@Override
|
||||||
protected TableColumnDescriptor<ExtensionDetails> createTableColumnDescriptor() {
|
protected TableColumnDescriptor<ExtensionDetails> createTableColumnDescriptor() {
|
||||||
|
|
||||||
TableColumnDescriptor<ExtensionDetails> descriptor =
|
TableColumnDescriptor<ExtensionDetails> descriptor = new TableColumnDescriptor<>();
|
||||||
new TableColumnDescriptor<>();
|
|
||||||
|
|
||||||
descriptor.addVisibleColumn(new ExtensionInstalledColumn(), INSTALLED_COL, true);
|
descriptor.addVisibleColumn(new ExtensionInstalledColumn(), INSTALLED_COL, true);
|
||||||
descriptor.addVisibleColumn(new ExtensionNameColumn(), NAME_COL, true);
|
descriptor.addVisibleColumn(new ExtensionNameColumn(), NAME_COL, true);
|
||||||
|
@ -105,7 +103,7 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not allow GUI uninstallation of extensions manually installed in installation
|
// Do not allow GUI uninstallation of extensions manually installed in installation
|
||||||
// directory
|
// directory
|
||||||
if (extension.getInstallPath() != null && FileUtilities.isPathContainedWithin(
|
if (extension.getInstallPath() != null && FileUtilities.isPathContainedWithin(
|
||||||
Application.getApplicationLayout().getApplicationInstallationDir().getFile(false),
|
Application.getApplicationLayout().getApplicationInstallationDir().getFile(false),
|
||||||
|
@ -125,12 +123,12 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
super.setValueAt(aValue, rowIndex, columnIndex);
|
super.setValueAt(aValue, rowIndex, columnIndex);
|
||||||
|
|
||||||
// We only care about the install column here, as it's the only one that
|
// We only care about the install column here, as it's the only one that
|
||||||
// is editable.
|
// is editable.
|
||||||
if (columnIndex != INSTALLED_COL) {
|
if (columnIndex != INSTALLED_COL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user does not have write permissions on the installation dir, they cannot
|
// If the user does not have write permissions on the installation dir, they cannot
|
||||||
// install.
|
// install.
|
||||||
ResourceFile installDir =
|
ResourceFile installDir =
|
||||||
Application.getApplicationLayout().getExtensionInstallationDirs().get(0);
|
Application.getApplicationLayout().getExtensionInstallationDirs().get(0);
|
||||||
|
@ -202,7 +200,7 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the model has changed as a result of installing or uninstalling an extension
|
* Returns true if the model has changed as a result of installing or uninstalling an extension
|
||||||
*
|
*
|
||||||
* @return true if the model has changed as a result of installing or uninstalling an extension
|
* @return true if the model has changed as a result of installing or uninstalling an extension
|
||||||
*/
|
*/
|
||||||
public boolean hasModelChanged() {
|
public boolean hasModelChanged() {
|
||||||
|
@ -211,7 +209,7 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces the table model data with the given list.
|
* Replaces the table model data with the given list.
|
||||||
*
|
*
|
||||||
* @param model the list to use as the model
|
* @param model the list to use as the model
|
||||||
*/
|
*/
|
||||||
public void setModelData(List<ExtensionDetails> model) {
|
public void setModelData(List<ExtensionDetails> model) {
|
||||||
|
@ -228,11 +226,11 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the selected extension.
|
* Returns the selected extension.
|
||||||
* <p>
|
* <p>
|
||||||
* Note that this table is single-selection only, so this will only
|
* Note that this table is single-selection only, so this will only
|
||||||
* ever return 1 item.
|
* ever return 1 item.
|
||||||
*
|
*
|
||||||
* @param row the selected row
|
* @param row the selected row
|
||||||
* @return the selected extension, or null if nothing is selected
|
* @return the selected extension, or null if nothing is selected
|
||||||
*/
|
*/
|
||||||
|
@ -259,8 +257,8 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(ExtensionDetails rowObject, Settings settings,
|
public String getValue(ExtensionDetails rowObject, Settings settings, Object data,
|
||||||
Object data, ServiceProvider sp) throws IllegalArgumentException {
|
ServiceProvider sp) throws IllegalArgumentException {
|
||||||
return rowObject.getName();
|
return rowObject.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,8 +287,8 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(ExtensionDetails rowObject, Settings settings,
|
public String getValue(ExtensionDetails rowObject, Settings settings, Object data,
|
||||||
Object data, ServiceProvider sp) throws IllegalArgumentException {
|
ServiceProvider sp) throws IllegalArgumentException {
|
||||||
return rowObject.getDescription();
|
return rowObject.getDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,8 +317,8 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(ExtensionDetails rowObject, Settings settings,
|
public String getValue(ExtensionDetails rowObject, Settings settings, Object data,
|
||||||
Object data, ServiceProvider sp) throws IllegalArgumentException {
|
ServiceProvider sp) throws IllegalArgumentException {
|
||||||
|
|
||||||
String version = rowObject.getVersion();
|
String version = rowObject.getVersion();
|
||||||
|
|
||||||
|
@ -356,8 +354,8 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean getValue(ExtensionDetails rowObject, Settings settings,
|
public Boolean getValue(ExtensionDetails rowObject, Settings settings, Object data,
|
||||||
Object data, ServiceProvider sp) throws IllegalArgumentException {
|
ServiceProvider sp) throws IllegalArgumentException {
|
||||||
return rowObject.isInstalled();
|
return rowObject.isInstalled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,8 +377,8 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(ExtensionDetails rowObject, Settings settings,
|
public String getValue(ExtensionDetails rowObject, Settings settings, Object data,
|
||||||
Object data, ServiceProvider sp) throws IllegalArgumentException {
|
ServiceProvider sp) throws IllegalArgumentException {
|
||||||
return rowObject.getInstallPath();
|
return rowObject.getInstallPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,8 +400,8 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(ExtensionDetails rowObject, Settings settings,
|
public String getValue(ExtensionDetails rowObject, Settings settings, Object data,
|
||||||
Object data, ServiceProvider sp) throws IllegalArgumentException {
|
ServiceProvider sp) throws IllegalArgumentException {
|
||||||
return rowObject.getArchivePath();
|
return rowObject.getArchivePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,8 +414,7 @@ class ExtensionTableModel extends ThreadedTableModel<ExtensionDetails, Object> {
|
||||||
|
|
||||||
ExtensionDetails extension = getSelectedExtension(data.getRowViewIndex());
|
ExtensionDetails extension = getSelectedExtension(data.getRowViewIndex());
|
||||||
if (!isValidVersion(extension)) {
|
if (!isValidVersion(extension)) {
|
||||||
comp.setForeground(
|
comp.setForeground(getErrorForegroundColor(data.isSelected()));
|
||||||
data.isSelected() ? Tables.FG_ERROR_SELECTED : Tables.FG_ERROR_UNSELECTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return comp;
|
return comp;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import docking.widgets.HyperlinkComponent;
|
||||||
import docking.widgets.checkbox.GCheckBox;
|
import docking.widgets.checkbox.GCheckBox;
|
||||||
import docking.widgets.label.*;
|
import docking.widgets.label.*;
|
||||||
import generic.theme.*;
|
import generic.theme.*;
|
||||||
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.framework.plugintool.PluginConfigurationModel;
|
import ghidra.framework.plugintool.PluginConfigurationModel;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.util.*;
|
import ghidra.framework.plugintool.util.*;
|
||||||
|
@ -130,7 +131,7 @@ public class PluginManagerComponent extends JPanel implements Scrollable {
|
||||||
initializeLabelSection();
|
initializeLabelSection();
|
||||||
initializeDescriptionSection();
|
initializeDescriptionSection();
|
||||||
|
|
||||||
setBorder(BorderFactory.createLineBorder(GThemeDefaults.Colors.Java.BORDER));
|
setBorder(BorderFactory.createLineBorder(Colors.BORDER));
|
||||||
updateCheckBoxState();
|
updateCheckBoxState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import docking.DialogComponentProvider;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.fieldpanel.FieldPanel;
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.plugin.core.clipboard.*;
|
import ghidra.app.plugin.core.clipboard.*;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||||
|
@ -75,7 +75,7 @@ public class ClipboardPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
captureListingCallMnemonic(start, end);
|
captureListingCallMnemonic(start, end);
|
||||||
|
|
||||||
placeImagesSideBySide(image, menuImage);
|
placeImagesSideBySide(image, menuImage);
|
||||||
drawBorder(Java.BORDER);
|
drawBorder(Colors.BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cropCopyMenu() {
|
private void cropCopyMenu() {
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.junit.Test;
|
||||||
import docking.DockableComponent;
|
import docking.DockableComponent;
|
||||||
import docking.widgets.fieldpanel.FieldPanel;
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import ghidra.GhidraOptions;
|
import ghidra.GhidraOptions;
|
||||||
import ghidra.app.cmd.comments.SetCommentCmd;
|
import ghidra.app.cmd.comments.SetCommentCmd;
|
||||||
|
@ -74,7 +73,7 @@ public class CodeBrowserPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
|
|
||||||
Rectangle cursor = getCursorBounds();
|
Rectangle cursor = getCursorBounds();
|
||||||
captureListingRange(0x0040be40, 0x0040be56, 600);
|
captureListingRange(0x0040be40, 0x0040be56, 600);
|
||||||
drawBorder(Java.BORDER);
|
drawBorder(Colors.BORDER);
|
||||||
|
|
||||||
drawTextWithArrowNearOpenStructureIcon("Closed", cursor);
|
drawTextWithArrowNearOpenStructureIcon("Closed", cursor);
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ public class CodeBrowserPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
Rectangle cursor = getCursorBounds();
|
Rectangle cursor = getCursorBounds();
|
||||||
captureListingRange(0x0040be40, 0x0040be56, 600);
|
captureListingRange(0x0040be40, 0x0040be56, 600);
|
||||||
|
|
||||||
drawBorder(Java.BORDER);
|
drawBorder(Colors.BORDER);
|
||||||
|
|
||||||
drawTextWithArrowNearOpenStructureIcon("Open", cursor);
|
drawTextWithArrowNearOpenStructureIcon("Open", cursor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ import docking.widgets.OptionDialog;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Java;
|
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.LoggingInitialization;
|
import ghidra.framework.LoggingInitialization;
|
||||||
|
@ -138,7 +137,7 @@ public class ToolScreenShots extends GhidraScreenShotGenerator {
|
||||||
tool.executeBackgroundCommand(new DummyBackgroundCommand(), program);
|
tool.executeBackgroundCommand(new DummyBackgroundCommand(), program);
|
||||||
|
|
||||||
Border inner = BorderFactory.createRaisedBevelBorder();
|
Border inner = BorderFactory.createRaisedBevelBorder();
|
||||||
Border outer = BorderFactory.createLineBorder(Java.BORDER);
|
Border outer = BorderFactory.createLineBorder(Colors.BORDER);
|
||||||
statusBar.setBorder(BorderFactory.createCompoundBorder(outer, inner));
|
statusBar.setBorder(BorderFactory.createCompoundBorder(outer, inner));
|
||||||
captureComponent(statusBar);
|
captureComponent(statusBar);
|
||||||
program.endTransaction(id, false);
|
program.endTransaction(id, false);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue