GP-4154 - Theming - Fixed font issues; updated font usage with attributes

This commit is contained in:
dragonmacher 2024-02-23 13:13:06 -05:00
parent c5bad0a88f
commit b586d65a3b
91 changed files with 1309 additions and 1191 deletions

View file

@ -26,7 +26,8 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.*; import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import db.Transaction; import db.Transaction;
import docking.action.DockingAction; import docking.action.DockingAction;
@ -265,8 +266,8 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter {
} }
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(fixedWidthFont); return fixedWidthFont;
} }
@Override @Override

View file

@ -25,7 +25,6 @@ import java.util.function.BiFunction;
import javax.swing.*; import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML; import javax.swing.plaf.basic.BasicHTML;
import javax.swing.table.TableModel;
import javax.swing.text.View; import javax.swing.text.View;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -92,11 +91,7 @@ public class CustomToStringCellRenderer<T> extends AbstractGColumnRenderer<T> {
} }
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(getCustomFont());
}
protected Font getCustomFont() {
switch (customFont) { switch (customFont) {
default: default:
case DEFAULT: case DEFAULT:

View file

@ -15,11 +15,9 @@
*/ */
package ghidra.machinelearning.functionfinding; package ghidra.machinelearning.functionfinding;
import java.awt.Font;
import java.util.List; import java.util.List;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.AbstractDynamicTableColumn; import docking.widgets.table.AbstractDynamicTableColumn;
import docking.widgets.table.TableColumnDescriptor; import docking.widgets.table.TableColumnDescriptor;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -123,9 +121,10 @@ public class SimilarStartsTableModel extends AddressBasedTableModel<SimilarStart
@Override @Override
public GColumnRenderer<String> getColumnRenderer() { public GColumnRenderer<String> getColumnRenderer() {
final GColumnRenderer<String> monospacedRenderer = new AbstractGColumnRenderer<>() { final GColumnRenderer<String> monospacedRenderer = new AbstractGColumnRenderer<>() {
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(getFixedWidthFont()); return fixedWidthFont;
} }
@Override @Override

View file

@ -15,7 +15,8 @@
*/ */
package ghidra.examples; package ghidra.examples;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.*; import java.awt.event.*;
import javax.swing.*; import javax.swing.*;
@ -30,8 +31,8 @@ import ghidra.util.HelpLocation;
import ghidra.util.Msg; import ghidra.util.Msg;
public class HelloWorldComponentProvider extends ComponentProviderAdapter { public class HelloWorldComponentProvider extends ComponentProviderAdapter {
private final static HelpLocation HELP = new HelpLocation("SampleHelpTopic", private final static HelpLocation HELP =
"SampleHelpTopic_Anchor_Name"); new HelpLocation("SampleHelpTopic", "SampleHelpTopic_Anchor_Name");
private MyButton activeButtonObj; private MyButton activeButtonObj;
private JPanel mainPanel; private JPanel mainPanel;
private DockingAction action; private DockingAction action;
@ -64,8 +65,8 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
// the menu item will appear on the local toolbar drop down. // the menu item will appear on the local toolbar drop down.
Icon icon = new GIcon("icon.sample.action.hello.world"); Icon icon = new GIcon("icon.sample.action.hello.world");
action.setMenuBarData(new MenuData(new String[] { "Misc", "Hello World" }, icon)); action.setMenuBarData(new MenuData(new String[] { "Misc", "Hello World" }, icon));
action.setKeyBindingData(new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W, action.setKeyBindingData(
InputEvent.CTRL_MASK))); new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK)));
// puts the action on the local toolbar. // puts the action on the local toolbar.
action.setToolBarData(new ToolBarData(icon)); action.setToolBarData(new ToolBarData(icon));
@ -120,8 +121,6 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER)); JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
panel.setBorder(BorderFactory.createTitledBorder("Example of a Component")); panel.setBorder(BorderFactory.createTitledBorder("Example of a Component"));
activeButtonObj = new MyButton("Hello World"); activeButtonObj = new MyButton("Hello World");
Font f = activeButtonObj.getFont();
activeButtonObj.setFont(f.deriveFont(Font.BOLD, 14));
panel.add(activeButtonObj); panel.add(activeButtonObj);
mainPanel.add(panel, BorderLayout.CENTER); mainPanel.add(panel, BorderLayout.CENTER);
} }

View file

@ -16,12 +16,11 @@
package ghidra.features.bsim.gui.overview; package ghidra.features.bsim.gui.overview;
import java.awt.Component; import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.*; import docking.widgets.table.*;
import generic.lsh.vector.LSHVectorFactory; import generic.lsh.vector.LSHVectorFactory;
@ -233,8 +232,8 @@ public class BSimOverviewModel extends AddressBasedTableModel<BSimOverviewRowObj
} }
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(fixedWidthFont); return fixedWidthFont;
} }
@Override @Override

View file

@ -28,6 +28,7 @@ import docking.DockingWindowManager;
import docking.widgets.EmptyBorderButton; import docking.widgets.EmptyBorderButton;
import docking.widgets.combobox.GComboBox; import docking.widgets.combobox.GComboBox;
import docking.widgets.textfield.FloatingPointTextField; import docking.widgets.textfield.FloatingPointTextField;
import generic.theme.Gui;
import ghidra.features.bsim.query.BSimServerInfo; import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.description.DatabaseInformation; import ghidra.features.bsim.query.description.DatabaseInformation;
import ghidra.features.bsim.query.facade.QueryDatabaseException; import ghidra.features.bsim.query.facade.QueryDatabaseException;
@ -243,7 +244,7 @@ public abstract class AbstractBSimSearchDialog extends DialogComponentProvider {
contentPanel.add(comp, fullWidth ? BorderLayout.CENTER : BorderLayout.WEST); contentPanel.add(comp, fullWidth ? BorderLayout.CENTER : BorderLayout.WEST);
JLabel label = new JLabel(name); JLabel label = new JLabel(name);
label.setFont(label.getFont().deriveFont(Font.BOLD)); Gui.registerFont(label, Font.BOLD);
titlePanel.add(label, BorderLayout.NORTH); titlePanel.add(label, BorderLayout.NORTH);
return panel; return panel;

View file

@ -18,11 +18,10 @@ package ghidra.features.bsim.gui.search.results;
import static ghidra.features.bsim.gui.search.results.BSimResultStatus.*; import static ghidra.features.bsim.gui.search.results.BSimResultStatus.*;
import java.awt.Component; import java.awt.Component;
import java.awt.Font;
import java.util.*; import java.util.*;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.*; import docking.widgets.table.*;
import generic.lsh.vector.LSHVectorFactory; import generic.lsh.vector.LSHVectorFactory;
@ -70,15 +69,15 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
return; // Info can be null, even if FunctionDatabase return Ready (not created yet) return; // Info can be null, even if FunctionDatabase return Ready (not created yet)
} }
if (info.execats != null) { if (info.execats != null) {
for (int i = 0; i < info.execats.size(); ++i) { for (String element : info.execats) {
addTableColumn(new ExecCategoryColumn(info.execats.get(i))); addTableColumn(new ExecCategoryColumn(element));
} }
} }
if (info.functionTags != null) { if (info.functionTags != null) {
int mask = 1; int mask = 1;
mask <<= FunctionTagBSimFilterType.RESERVED_BITS; mask <<= FunctionTagBSimFilterType.RESERVED_BITS;
for (int i = 0; i < info.functionTags.size(); ++i) { for (String element : info.functionTags) {
addTableColumn(new FunctionTagColumn(info.functionTags.get(i), mask)); addTableColumn(new FunctionTagColumn(element, mask));
mask <<= 1; mask <<= 1;
} }
} }
@ -114,12 +113,12 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
descriptor.addHiddenColumn(new CompilerMatchColumn()); descriptor.addHiddenColumn(new CompilerMatchColumn());
descriptor.addHiddenColumn(new MatchCountTableColumn()); descriptor.addHiddenColumn(new MatchCountTableColumn());
descriptor.addHiddenColumn(new FunctionSizeTableColumn()); descriptor.addHiddenColumn(new FunctionSizeTableColumn());
descriptor.addHiddenColumn(new FunctionTagColumn("Known Library", descriptor.addHiddenColumn(
FunctionTagBSimFilterType.KNOWN_LIBRARY_MASK)); new FunctionTagColumn("Known Library", FunctionTagBSimFilterType.KNOWN_LIBRARY_MASK));
descriptor.addHiddenColumn(new FunctionTagColumn("Has Unimplemented", descriptor.addHiddenColumn(new FunctionTagColumn("Has Unimplemented",
FunctionTagBSimFilterType.HAS_UNIMPLEMENTED_MASK)); FunctionTagBSimFilterType.HAS_UNIMPLEMENTED_MASK));
descriptor.addHiddenColumn(new FunctionTagColumn("Has Bad Data", descriptor.addHiddenColumn(
FunctionTagBSimFilterType.HAS_BADDATA_MASK)); new FunctionTagColumn("Has Bad Data", FunctionTagBSimFilterType.HAS_BADDATA_MASK));
descriptor.addVisibleColumn( descriptor.addVisibleColumn(
DiscoverableTableUtils.adaptColumForModel(this, new AddressTableColumn())); DiscoverableTableUtils.adaptColumForModel(this, new AddressTableColumn()));
descriptor.addHiddenColumn(new MatchingFunctionAddressTableColumn()); descriptor.addHiddenColumn(new MatchingFunctionAddressTableColumn());
@ -288,10 +287,10 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program, public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
Address address = rowObject.getAddress(); Address address = rowObject.getAddress();
Function function = program.getFunctionManager().getFunctionAt(address); Function function = p.getFunctionManager().getFunctionAt(address);
boolean showNamespace = SHOW_NAMESPACE.getValue(settings); boolean showNamespace = SHOW_NAMESPACE.getValue(settings);
if (function != null) { if (function != null) {
return function.getName(showNamespace); return function.getName(showNamespace);
@ -319,7 +318,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program, public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
String name = rowObject.getSimilarFunctionName(); String name = rowObject.getSimilarFunctionName();
boolean showNamespace = SHOW_NAMESPACE.getValue(settings); boolean showNamespace = SHOW_NAMESPACE.getValue(settings);
@ -380,7 +379,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Integer getValue(BSimMatchResult rowObject, Settings settings, Program program, public Integer getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider provider) throws IllegalArgumentException { ServiceProvider provider) throws IllegalArgumentException {
return functionMatchMap.get(rowObject.getAddress()); return functionMatchMap.get(rowObject.getAddress());
} }
@ -404,7 +403,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Long getValue(BSimMatchResult rowObject, Settings settings, Program data, public Long getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
Long addr = rowObject.getMatchFunctionDescription().getAddress(); Long addr = rowObject.getMatchFunctionDescription().getAddress();
return addr; return addr;
@ -437,8 +436,8 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(fixedWidthFont); return fixedWidthFont;
} }
@Override @Override
@ -464,10 +463,10 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Long getValue(BSimMatchResult rowObject, Settings settings, Program program, public Long getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider provider) throws IllegalArgumentException { ServiceProvider provider) throws IllegalArgumentException {
Address address = rowObject.getAddress(); Address address = rowObject.getAddress();
Function function = program.getFunctionManager().getFunctionAt(address); Function function = p.getFunctionManager().getFunctionAt(address);
return function.getBody().getNumAddresses(); return function.getBody().getNumAddresses();
} }
@ -482,7 +481,6 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
private String columnName; private String columnName;
ExecDateColumn(String name) { ExecDateColumn(String name) {
super();
columnName = name; columnName = name;
} }
@ -492,7 +490,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Date getValue(BSimMatchResult rowObject, Settings settings, Program program, public Date getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getDate(); return rowObject.getDate();
} }
@ -519,7 +517,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program, public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getExeCategoryAlphabetic(columnName); return rowObject.getExeCategoryAlphabetic(columnName);
} }
@ -540,7 +538,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program, public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getArchitecture(); return rowObject.getArchitecture();
} }
@ -561,7 +559,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program, public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getCompilerName(); return rowObject.getCompilerName();
} }
@ -582,7 +580,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program, public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getMd5(); return rowObject.getMd5();
} }
@ -604,7 +602,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program, public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getSimilarity(); return rowObject.getSimilarity();
} }
@ -630,7 +628,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program, public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getSignificance(); return rowObject.getSignificance();
} }
@ -662,7 +660,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program, public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return vectorFactory.getSelfSignificance( return vectorFactory.getSelfSignificance(
rowObject.getMatchFunctionDescription().getSignatureRecord().getLSHVector()); rowObject.getMatchFunctionDescription().getSignatureRecord().getLSHVector());
@ -696,7 +694,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
} }
@Override @Override
public Boolean getValue(BSimMatchResult rowObject, Settings settings, Program data, public Boolean getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException { ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.isFlagSet(mask); return rowObject.isFlagSet(mask);
} }

View file

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import javax.swing.*; import javax.swing.*;
import docking.DialogComponentProvider; import docking.DialogComponentProvider;
import generic.theme.Gui;
import ghidra.features.bsim.gui.BSimSearchPlugin; import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.search.dialog.BSimFilterSet; import ghidra.features.bsim.gui.search.dialog.BSimFilterSet;
import ghidra.features.bsim.gui.search.dialog.BSimFilterSet.FilterEntry; import ghidra.features.bsim.gui.search.dialog.BSimFilterSet.FilterEntry;
@ -64,7 +65,7 @@ public class BSimSearchInfoDisplayDialog extends DialogComponentProvider {
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JLabel dataLabel = new JLabel("Search Options:"); JLabel dataLabel = new JLabel("Search Options:");
dataLabel.setFont(dataLabel.getFont().deriveFont(Font.ITALIC)); Gui.registerFont(dataLabel, Font.ITALIC);
panel.add(dataLabel); panel.add(dataLabel);
panel.add(new JLabel("")); panel.add(new JLabel(""));
@ -89,7 +90,7 @@ public class BSimSearchInfoDisplayDialog extends DialogComponentProvider {
panel.add(new JLabel("")); panel.add(new JLabel(""));
panel.add(new JLabel("")); panel.add(new JLabel(""));
JLabel filterLabel = new JLabel("Filters:"); JLabel filterLabel = new JLabel("Filters:");
filterLabel.setFont(filterLabel.getFont().deriveFont(Font.ITALIC)); Gui.registerFont(filterLabel, Font.ITALIC);
panel.add(filterLabel); panel.add(filterLabel);
panel.add(new JLabel("")); panel.add(new JLabel(""));

View file

@ -166,19 +166,26 @@ color.bg.plugin.windowlocation.screens = color.palette.orange
color.bg.plugin.windowlocation.window.selected = color.palette.lime color.bg.plugin.windowlocation.window.selected = color.palette.lime
color.fg.plugin.windowlocation.window.text = color.palette.gray color.fg.plugin.windowlocation.window.text = color.palette.gray
font.print = SansSerif-PLAIN-10 font.print = SansSerif-PLAIN-10
font.splash.infopanel = SansSerif-BOLD-14
font.plugin.assembly.dual.text.field = font.monospaced
font.plugin.console = font.monospaced font.plugin.console = font.monospaced
font.plugin.entropy.label.knot = sansserif-bold-12
font.plugin.function.text.editor = sansserif-plain-18
font.plugin.instruction.table.renderer = courier-plain-14
font.plugin.instruction.info = font.monospaced[14]
font.plugin.service.text.editor = font.monospaced font.plugin.service.text.editor = font.monospaced
font.plugin.scripts.text.editor = font.monospaced font.plugin.scripts.text.editor = font.monospaced
font.plugin.assembly.dual.text.field = font.monospaced font.plugin.strings.buttons = sansserif-plain-10
font.plugin.instruction.table.renderer = courier-plain-14 font.plugin.tabs = sansserif-plain-11
font.plugin.entropy.label.knot = SansSerif-BOLD-12 font.plugin.tabs.list = sansserif-bold-9
font.plugin.instruction.info = font.monospaced[14] font.plugin.tips = dialog-plain-12
font.plugin.tabs = SansSerif-PLAIN-11 font.plugin.tips.label = font.plugin.tips[bold]
font.plugin.tabs.list = SansSerif-BOLD-9
font.plugin.tips = Dialog-PLAIN-12
font.plugin.tips.label = font.plugin.tips[BOLD]
font.plugin.terminal = font.monospaced font.plugin.terminal = font.monospaced
font.plugin.terminal.completion.list = dialog-plain-12
font.plugin.window.location = font.monospaced[40]

View file

@ -17,6 +17,7 @@ package ghidra.app.merge;
import java.awt.Color; import java.awt.Color;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
public interface MergeConstants { public interface MergeConstants {
@ -29,7 +30,7 @@ public interface MergeConstants {
public static final String LATEST_TITLE = "Latest"; public static final String LATEST_TITLE = "Latest";
public static final String MY_TITLE = "Checked Out"; public static final String MY_TITLE = "Checked Out";
public Color CONFLICT_COLOR = Palette.MAROON; public GColor CONFLICT_COLOR = Palette.MAROON;
public static final Color HIGHLIGHT_COLOR = Palette.LIGHT_GRAY; public static final Color HIGHLIGHT_COLOR = Palette.LIGHT_GRAY;
// The following are standardized names for use in passing resolve // The following are standardized names for use in passing resolve

View file

@ -16,13 +16,14 @@
package ghidra.app.merge.datatypes; package ghidra.app.merge.datatypes;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Font;
import java.util.Arrays; import java.util.Arrays;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.text.*; import javax.swing.text.*;
import generic.theme.*;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.merge.MergeConstants; import ghidra.app.merge.MergeConstants;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -36,23 +37,21 @@ import ghidra.util.UniversalID;
/** /**
* Panel to show the contents of a Data Type. * Panel to show the contents of a Data Type.
*
*
*/ */
class DataTypePanel extends JPanel { class DataTypePanel extends JPanel {
public Color SOURCE_COLOR = Palette.GREEN; public GColor SOURCE_COLOR = Palette.GREEN;
private DataType dataType; private DataType dataType;
private JTextPane textPane; private JTextPane textPane;
private StyledDocument doc; private StyledDocument doc;
private SimpleAttributeSet pathAttrSet; private SimpleAttributeSet pathAttrs;
private SimpleAttributeSet nameAttrSet; private SimpleAttributeSet nameAttrs;
private SimpleAttributeSet sourceAttrSet; private SimpleAttributeSet sourceAttrs;
private SimpleAttributeSet offsetAttrSet; private SimpleAttributeSet offsetAttrs;
private SimpleAttributeSet contentAttrSet; private SimpleAttributeSet contentAttrs;
private SimpleAttributeSet fieldNameAttrSet; private SimpleAttributeSet fieldNameAttrs;
private SimpleAttributeSet commentAttrSet; private SimpleAttributeSet commentAttrs;
private SimpleAttributeSet deletedAttrSet; private SimpleAttributeSet deletedAttrs;
DataTypePanel(DataType dataType) { DataTypePanel(DataType dataType) {
super(new BorderLayout()); super(new BorderLayout());
@ -91,58 +90,27 @@ class DataTypePanel extends JPanel {
add(textPane, BorderLayout.CENTER); add(textPane, BorderLayout.CENTER);
textPane.setEditable(false); textPane.setEditable(false);
pathAttrSet = new SimpleAttributeSet(); Font monospaced = Gui.getFont("font.monospaced");
pathAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); Font bold = Gui.getFont("font.standard.bold");
pathAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
pathAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
pathAttrSet.addAttribute(StyleConstants.Foreground, MergeConstants.CONFLICT_COLOR);
nameAttrSet = new SimpleAttributeSet(); pathAttrs = new GAttributes(bold, MergeConstants.CONFLICT_COLOR);
nameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); nameAttrs = new GAttributes(bold);
nameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11)); sourceAttrs = new GAttributes(bold, SOURCE_COLOR);
nameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE); offsetAttrs = new GAttributes(monospaced, Palette.BLACK);
contentAttrs = new GAttributes(monospaced, Palette.BLUE);
sourceAttrSet = new SimpleAttributeSet(); fieldNameAttrs = new GAttributes(monospaced, Palette.MAGENTA);
sourceAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); commentAttrs = new GAttributes(monospaced, Palette.LIME);
sourceAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11)); deletedAttrs = new GAttributes(bold, Palette.RED);
sourceAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
sourceAttrSet.addAttribute(StyleConstants.Foreground, SOURCE_COLOR);
offsetAttrSet = new SimpleAttributeSet();
offsetAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
offsetAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
offsetAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLACK);
contentAttrSet = new SimpleAttributeSet();
contentAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
contentAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
contentAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLUE);
fieldNameAttrSet = new SimpleAttributeSet();
fieldNameAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
fieldNameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
fieldNameAttrSet.addAttribute(StyleConstants.Foreground, Palette.MAGENTA);
commentAttrSet = new SimpleAttributeSet();
commentAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
commentAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
commentAttrSet.addAttribute(StyleConstants.Foreground, Palette.LIME);
deletedAttrSet = new SimpleAttributeSet();
deletedAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
deletedAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
deletedAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
deletedAttrSet.addAttribute(StyleConstants.Foreground, Palette.RED);
setDataType(dataType); setDataType(dataType);
} }
private void formatPath(DataType dt) { private void formatPath(DataType dt) {
insertString("Path: " + dt.getCategoryPath() + "\n\n", pathAttrSet); insertString("Path: " + dt.getCategoryPath() + "\n\n", pathAttrs);
} }
private void formatSourceArchive(DataType dt) { private void formatSourceArchive(DataType dt) {
insertString("Source Archive: " + getSourceArchiveName(dt) + "\n", sourceAttrSet); insertString("Source Archive: " + getSourceArchiveName(dt) + "\n", sourceAttrs);
} }
private String getSourceArchiveName(DataType dt) { private String getSourceArchiveName(DataType dt) {
@ -156,21 +124,21 @@ class DataTypePanel extends JPanel {
private void formatAlignment(Composite composite) { private void formatAlignment(Composite composite) {
String str = CompositeInternal.getAlignmentAndPackingString(composite); String str = CompositeInternal.getAlignmentAndPackingString(composite);
insertString(str + "\n\n", sourceAttrSet); insertString(str + "\n\n", sourceAttrs);
} }
private void insertAlignment(Composite composite) { private void insertAlignment(Composite composite) {
StringBuffer alignmentBuffer = new StringBuffer(); StringBuffer alignmentBuffer = new StringBuffer();
alignmentBuffer.append("Alignment: "); alignmentBuffer.append("Alignment: ");
alignmentBuffer.append(Integer.toString(composite.getAlignment())); alignmentBuffer.append(Integer.toString(composite.getAlignment()));
insertString(alignmentBuffer.toString() + "\n", sourceAttrSet); insertString(alignmentBuffer.toString() + "\n", sourceAttrs);
} }
private void insertLength(Composite composite) { private void insertLength(Composite composite) {
StringBuffer lengthBuffer = new StringBuffer(); StringBuffer lengthBuffer = new StringBuffer();
lengthBuffer.append("Length: "); lengthBuffer.append("Length: ");
lengthBuffer.append(Integer.toString(composite.getLength())); lengthBuffer.append(Integer.toString(composite.getLength()));
insertString(lengthBuffer.toString() + "\n", sourceAttrSet); insertString(lengthBuffer.toString() + "\n", sourceAttrs);
} }
private int max(String str, int length) { private int max(String str, int length) {
@ -184,8 +152,7 @@ class DataTypePanel extends JPanel {
DataType dt = dtc.getDataType(); DataType dt = dtc.getDataType();
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
buffer.append(dt.getName()); buffer.append(dt.getName());
if (dt instanceof BitFieldDataType && if (dt instanceof BitFieldDataType && !((Composite) dtc.getParent()).isPackingEnabled()) {
!((Composite) dtc.getParent()).isPackingEnabled()) {
BitFieldDataType bfDt = (BitFieldDataType) dt; BitFieldDataType bfDt = (BitFieldDataType) dt;
buffer.append("("); buffer.append("(");
buffer.append(Integer.toString(bfDt.getBitOffset())); buffer.append(Integer.toString(bfDt.getBitOffset()));
@ -210,23 +177,23 @@ class DataTypePanel extends JPanel {
offsetStr = "0x" + Integer.toHexString(dtc.getOffset()); offsetStr = "0x" + Integer.toHexString(dtc.getOffset());
offsetStr = StringUtilities.pad(offsetStr, ' ', offsetWidth - offsetStr.length()); offsetStr = StringUtilities.pad(offsetStr, ' ', offsetWidth - offsetStr.length());
offsetStr += ": "; offsetStr += ": ";
insertString(" " + offsetStr + " ", offsetAttrSet); insertString(" " + offsetStr + " ", offsetAttrs);
} }
fieldName = pad(fieldName, fieldNameWidth); fieldName = pad(fieldName, fieldNameWidth);
String typeName = pad(getDataTypeName(dtc), dtNameWidth); String typeName = pad(getDataTypeName(dtc), dtNameWidth);
insertString(" " + typeName + " ", contentAttrSet); insertString(" " + typeName + " ", contentAttrs);
insertString(fieldName + " ", fieldNameAttrSet); insertString(fieldName + " ", fieldNameAttrs);
insertString(comment, commentAttrSet); insertString(comment, commentAttrs);
insertString("\n", contentAttrSet); insertString("\n", contentAttrs);
} }
private void formatCompositeText(Composite comp) { private void formatCompositeText(Composite comp) {
formatSourceArchive(comp); formatSourceArchive(comp);
formatPath(comp); formatPath(comp);
formatAlignment(comp); formatAlignment(comp);
insertString(comp.getDisplayName(), nameAttrSet); insertString(comp.getDisplayName(), nameAttrs);
insertString(" { \n", contentAttrSet); insertString(" { \n", contentAttrs);
boolean showComponentOffset = false; boolean showComponentOffset = false;
@ -247,7 +214,7 @@ class DataTypePanel extends JPanel {
renderComponent(component, maxDtNameLength, maxFieldNameLength, offsetLength); renderComponent(component, maxDtNameLength, maxFieldNameLength, offsetLength);
} }
insertString("}\n\n", contentAttrSet); insertString("}\n\n", contentAttrs);
insertAlignment(comp); insertAlignment(comp);
insertLength(comp); insertLength(comp);
} }
@ -279,8 +246,8 @@ class DataTypePanel extends JPanel {
private void formatEnumText(Enum enuum) { private void formatEnumText(Enum enuum) {
formatSourceArchive(enuum); formatSourceArchive(enuum);
formatPath(enuum); formatPath(enuum);
insertString(enuum.getDisplayName(), nameAttrSet); insertString(enuum.getDisplayName(), nameAttrs);
insertString(" { \n", contentAttrSet); insertString(" { \n", contentAttrs);
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
@ -303,7 +270,7 @@ class DataTypePanel extends JPanel {
renderEnumEntry(entry, maxNameLength, maxValueLength); renderEnumEntry(entry, maxNameLength, maxValueLength);
} }
sb.append("}\n"); sb.append("}\n");
insertString(sb.toString(), contentAttrSet); insertString(sb.toString(), contentAttrs);
} }
private void renderEnumEntry(EnumEntry entry, int maxNameLength, int maxValueLength) { private void renderEnumEntry(EnumEntry entry, int maxNameLength, int maxValueLength) {
@ -311,20 +278,20 @@ class DataTypePanel extends JPanel {
name = pad(name, maxNameLength); name = pad(name, maxNameLength);
String valStr = Long.toHexString(entry.value); String valStr = Long.toHexString(entry.value);
valStr = pad(valStr, maxValueLength); valStr = pad(valStr, maxValueLength);
insertString(" " + name, fieldNameAttrSet); insertString(" " + name, fieldNameAttrs);
insertString(" = 0x" + valStr, contentAttrSet); insertString(" = 0x" + valStr, contentAttrs);
if (entry.comment != null) { if (entry.comment != null) {
insertString(" " + entry.comment, commentAttrSet); insertString(" " + entry.comment, commentAttrs);
} }
insertString("\n", contentAttrSet); insertString("\n", contentAttrs);
} }
private void formatTypeDefText(TypeDef td) { private void formatTypeDefText(TypeDef td) {
formatSourceArchive(td); formatSourceArchive(td);
formatPath(td); formatPath(td);
insertString(td.getDisplayName(), nameAttrSet); insertString(td.getDisplayName(), nameAttrs);
insertString("\n", contentAttrSet); insertString("\n", contentAttrs);
insertString(" TypeDef on " + td.getDataType().getDisplayName(), contentAttrSet); insertString(" TypeDef on " + td.getDataType().getDisplayName(), contentAttrs);
} }
private void formatDataTypeSettings(DataType dt) { private void formatDataTypeSettings(DataType dt) {
@ -336,10 +303,10 @@ class DataTypePanel extends JPanel {
if (defs.length == 0) { if (defs.length == 0) {
return; return;
} }
insertString("\n\nSettings\n", sourceAttrSet); insertString("\n\nSettings\n", sourceAttrs);
for (SettingsDefinition def : defs) { for (SettingsDefinition def : defs) {
insertString(" " + def.getName() + ": " + def.getValueString(settings) + "\n", insertString(" " + def.getName() + ": " + def.getValueString(settings) + "\n",
contentAttrSet); contentAttrs);
} }
} }
@ -350,18 +317,18 @@ class DataTypePanel extends JPanel {
DataType returnType = fd.getReturnType(); DataType returnType = fd.getReturnType();
if (fd.hasNoReturn()) { if (fd.hasNoReturn()) {
insertString(FunctionSignature.NORETURN_DISPLAY_STRING + " ", contentAttrSet); insertString(FunctionSignature.NORETURN_DISPLAY_STRING + " ", contentAttrs);
} }
insertString(returnType.getDisplayName(), contentAttrSet); insertString(returnType.getDisplayName(), contentAttrs);
String callingConventionName = fd.getCallingConventionName(); String callingConventionName = fd.getCallingConventionName();
if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(callingConventionName)) { if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(callingConventionName)) {
insertString(callingConventionName + " ", contentAttrSet); insertString(callingConventionName + " ", contentAttrs);
} }
insertString(" " + fd.getDisplayName(), nameAttrSet); insertString(" " + fd.getDisplayName(), nameAttrs);
insertString(" (", contentAttrSet); insertString(" (", contentAttrs);
boolean hasVarArgs = fd.hasVarArgs(); boolean hasVarArgs = fd.hasVarArgs();
if ((vars.length == 0) && !hasVarArgs) { if ((vars.length == 0) && !hasVarArgs) {
insertString(")", contentAttrSet); insertString(")", contentAttrs);
return; return;
} }
int maxLength = 0; int maxLength = 0;
@ -390,17 +357,17 @@ class DataTypePanel extends JPanel {
sb.append(FunctionSignature.VAR_ARGS_DISPLAY_STRING); sb.append(FunctionSignature.VAR_ARGS_DISPLAY_STRING);
} }
sb.append(")"); sb.append(")");
insertString(sb.toString(), contentAttrSet); insertString(sb.toString(), contentAttrs);
} }
private void formatDataType(DataType dt) { private void formatDataType(DataType dt) {
if (dt == null) { if (dt == null) {
insertString("\n\nDeleted", deletedAttrSet); insertString("\n\nDeleted", deletedAttrs);
return; return;
} }
formatSourceArchive(dt); formatSourceArchive(dt);
formatPath(dt); formatPath(dt);
insertString(dt.getDisplayName(), nameAttrSet); insertString(dt.getDisplayName(), nameAttrs);
} }
private String pad(String str, int length) { private String pad(String str, int length) {

View file

@ -16,13 +16,16 @@
package ghidra.app.merge.datatypes; package ghidra.app.merge.datatypes;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Font;
import java.util.Date; import java.util.Date;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.text.*; import javax.swing.text.*;
import generic.theme.GAttributes;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui;
import ghidra.program.model.data.ArchiveType; import ghidra.program.model.data.ArchiveType;
import ghidra.program.model.data.SourceArchive; import ghidra.program.model.data.SourceArchive;
import ghidra.util.Msg; import ghidra.util.Msg;
@ -35,9 +38,9 @@ class SourceArchivePanel extends JPanel {
private SourceArchive sourceArchive; private SourceArchive sourceArchive;
private JTextPane textPane; private JTextPane textPane;
private StyledDocument doc; private StyledDocument doc;
private SimpleAttributeSet headingAttrSet; private SimpleAttributeSet headingAttrs;
private SimpleAttributeSet valueAttrSet; private SimpleAttributeSet valueAttrs;
private SimpleAttributeSet deletedAttrSet; private SimpleAttributeSet deletedAttrs;
SourceArchivePanel() { SourceArchivePanel() {
super(new BorderLayout()); super(new BorderLayout());
@ -57,28 +60,19 @@ class SourceArchivePanel extends JPanel {
add(textPane, BorderLayout.CENTER); add(textPane, BorderLayout.CENTER);
textPane.setEditable(false); textPane.setEditable(false);
headingAttrSet = new SimpleAttributeSet(); Font monospaced = Gui.getFont("font.monospaced");
headingAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced"); Font bold = Gui.getFont("font.standard.bold");
headingAttrSet.addAttribute(StyleConstants.FontSize, 12);
headingAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLUE);
valueAttrSet = new SimpleAttributeSet(); headingAttrs = new GAttributes(monospaced, Palette.BLUE);
valueAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); valueAttrs = new GAttributes(bold);
valueAttrSet.addAttribute(StyleConstants.FontSize, 11); deletedAttrs = new GAttributes(bold, Palette.RED);
valueAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
deletedAttrSet = new SimpleAttributeSet();
deletedAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
deletedAttrSet.addAttribute(StyleConstants.FontSize, 12);
deletedAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
deletedAttrSet.addAttribute(StyleConstants.Foreground, Palette.RED);
setSourceArchive(null); setSourceArchive(null);
} }
private void formatSourceArchive() { private void formatSourceArchive() {
if (sourceArchive == null) { if (sourceArchive == null) {
insertString("\n\nDeleted", deletedAttrSet); insertString("\n\nDeleted", deletedAttrs);
return; return;
} }
// formatArchiveID(); // formatArchiveID();
@ -91,19 +85,19 @@ class SourceArchivePanel extends JPanel {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void formatArchiveID() { private void formatArchiveID() {
insertString(" Archive ID: ", headingAttrSet); insertString(" Archive ID: ", headingAttrs);
insertString(sourceArchive.getSourceArchiveID().getValue() + "\n", valueAttrSet); insertString(sourceArchive.getSourceArchiveID().getValue() + "\n", valueAttrs);
} }
private void formatName() { private void formatName() {
insertString("Name: ", headingAttrSet); insertString("Name: ", headingAttrs);
insertString(sourceArchive.getName() + "\n", valueAttrSet); insertString(sourceArchive.getName() + "\n", valueAttrs);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void formatFileID() { private void formatFileID() {
insertString(" File ID: ", headingAttrSet); insertString(" File ID: ", headingAttrs);
insertString(sourceArchive.getDomainFileID() + "\n", valueAttrSet); insertString(sourceArchive.getDomainFileID() + "\n", valueAttrs);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -112,21 +106,20 @@ class SourceArchivePanel extends JPanel {
String typeString = (archiveType == ArchiveType.FILE) ? "File Archive" String typeString = (archiveType == ArchiveType.FILE) ? "File Archive"
: (archiveType == ArchiveType.PROGRAM) ? "Program" : (archiveType == ArchiveType.PROGRAM) ? "Program"
: (archiveType == ArchiveType.PROJECT) ? "Project Archive" : (archiveType == ArchiveType.PROJECT) ? "Project Archive"
: (archiveType == ArchiveType.BUILT_IN) ? "Built-In" : (archiveType == ArchiveType.BUILT_IN) ? "Built-In" : "Invalid";
: "Invalid"; insertString(" Type: ", headingAttrs);
insertString(" Type: ", headingAttrSet); insertString(typeString + "\n", valueAttrs);
insertString(typeString + "\n", valueAttrSet);
} }
private void formatSyncTime() { private void formatSyncTime() {
String syncTime = new Date(sourceArchive.getLastSyncTime()).toString(); String syncTime = new Date(sourceArchive.getLastSyncTime()).toString();
insertString("Last Sync Time: ", headingAttrSet); insertString("Last Sync Time: ", headingAttrs);
insertString(syncTime + "\n", valueAttrSet); insertString(syncTime + "\n", valueAttrs);
} }
private void formatDirtyFlag() { private void formatDirtyFlag() {
insertString("Changed Since Last Sync? ", headingAttrSet); insertString("Changed Since Last Sync? ", headingAttrs);
insertString((sourceArchive.isDirty() ? "yes" : "no") + "\n", valueAttrSet); insertString((sourceArchive.isDirty() ? "yes" : "no") + "\n", valueAttrs);
} }
private void insertString(String str, SimpleAttributeSet attributeSet) { private void insertString(String str, SimpleAttributeSet attributeSet) {

View file

@ -24,6 +24,7 @@ import docking.widgets.label.GIconLabel;
import generic.theme.GIcon; import generic.theme.GIcon;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.util.layout.PairLayout; import ghidra.util.layout.PairLayout;
import resources.Icons; import resources.Icons;
@ -74,9 +75,7 @@ class TreeChangePanel extends JPanel {
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
treeNameLabel = new GDLabel("Tree Name"); treeNameLabel = new GDLabel("Tree Name");
Font font = treeNameLabel.getFont(); Gui.registerFont(treeNameLabel, Font.BOLD);
font = font.deriveFont(Font.BOLD);
treeNameLabel.setFont(font);
nameLabel = new GDLabel("Name Changed"); nameLabel = new GDLabel("Name Changed");
nameIconLabel = new GIconLabel(CHANGED_ICON); nameIconLabel = new GIconLabel(CHANGED_ICON);

View file

@ -87,7 +87,6 @@ public class ConflictCountPanel extends JPanel {
set.addAttribute(StyleConstants.Foreground, Messages.ERROR); set.addAttribute(StyleConstants.Foreground, Messages.ERROR);
textAttrSet = new SimpleAttributeSet(); textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontSize, 12);
countAttrSet = new SimpleAttributeSet(); countAttrSet = new SimpleAttributeSet();
countAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE); countAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);

View file

@ -22,6 +22,7 @@ import javax.swing.*;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import generic.theme.Gui;
import ghidra.framework.options.CustomOptionsEditor; import ghidra.framework.options.CustomOptionsEditor;
import ghidra.util.layout.PairLayout; import ghidra.util.layout.PairLayout;
@ -109,7 +110,7 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
} }
label = new GDLabel("TOTAL", SwingConstants.RIGHT); label = new GDLabel("TOTAL", SwingConstants.RIGHT);
label.setFont(label.getFont().deriveFont(Font.BOLD)); Gui.registerFont(label, Font.BOLD);
panel.add(label); panel.add(label);
JTextField valueField = JTextField valueField =

View file

@ -25,6 +25,7 @@ import docking.widgets.OptionDialog;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.framework.GenericRunInfo; import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator; import ghidra.framework.model.ProjectLocator;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@ -91,8 +92,8 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
archiveField.setText(archivePathName); archiveField.setText(archivePathName);
} }
}); });
Font font = archiveBrowse.getFont();
archiveBrowse.setFont(font.deriveFont(Font.BOLD)); Gui.registerFont(archiveBrowse, Font.BOLD);
archiveBrowse.setName("archiveBrowse"); archiveBrowse.setName("archiveBrowse");
// Layout the components. // Layout the components.
@ -269,8 +270,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
return file.getAbsolutePath() return file.getAbsolutePath()
.toLowerCase() .toLowerCase()
.endsWith( .endsWith(ArchivePlugin.ARCHIVE_EXTENSION);
ArchivePlugin.ARCHIVE_EXTENSION);
} }
@Override @Override
@ -311,8 +311,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
private String chooseArchiveFile(String approveButtonText, String approveToolTip) { private String chooseArchiveFile(String approveButtonText, String approveToolTip) {
GhidraFileChooser jarFileChooser = GhidraFileChooser jarFileChooser =
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", archivePathName);
archivePathName);
jarFileChooser.setTitle("Archive a Ghidra Project"); jarFileChooser.setTitle("Archive a Ghidra Project");
File jarFile = null; File jarFile = null;
if (archivePathName != null && archivePathName.length() != 0) { if (archivePathName != null && archivePathName.length() != 0) {

View file

@ -26,6 +26,7 @@ import docking.ReusableDialogComponentProvider;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.framework.GenericRunInfo; import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator; import ghidra.framework.model.ProjectLocator;
import ghidra.framework.preferences.Preferences; import ghidra.framework.preferences.Preferences;
@ -112,8 +113,8 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
} }
} }
}); });
Font font = archiveBrowse.getFont();
archiveBrowse.setFont(font.deriveFont(Font.BOLD)); Gui.registerFont(archiveBrowse, Font.BOLD);
restoreLabel = new GDLabel(" Restore Directory "); restoreLabel = new GDLabel(" Restore Directory ");
restoreField = new JTextField(); restoreField = new JTextField();
@ -129,8 +130,8 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
restoreField.setText(dirPath); restoreField.setText(dirPath);
} }
}); });
font = restoreBrowse.getFont();
restoreBrowse.setFont(font.deriveFont(Font.BOLD)); Gui.registerFont(restoreBrowse, Font.BOLD);
projectNameLabel = new GDLabel(" Project Name "); projectNameLabel = new GDLabel(" Project Name ");
projectNameField = new JTextField(); projectNameField = new JTextField();
@ -389,8 +390,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
String chooseArchiveFile(String approveButtonText, String approveToolTip) { String chooseArchiveFile(String approveButtonText, String approveToolTip) {
GhidraFileChooser jarFileChooser = GhidraFileChooser jarFileChooser =
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", archivePathName);
archivePathName);
jarFileChooser.setTitle("Restore a Ghidra Project - Archive"); jarFileChooser.setTitle("Restore a Ghidra Project - Archive");
String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR); String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR);
if (lastDirSelected != null) { if (lastDirSelected != null) {

View file

@ -16,12 +16,13 @@
package ghidra.app.plugin.core.comments; package ghidra.app.plugin.core.comments;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.text.*; import javax.swing.text.*;
import generic.theme.GColor; import generic.theme.*;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CommentHistory; import ghidra.program.model.listing.CommentHistory;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
@ -36,8 +37,8 @@ import ghidra.util.Msg;
class CommentHistoryPanel extends JPanel { class CommentHistoryPanel extends JPanel {
private final static String NO_HISTORY = "No History Found"; private final static String NO_HISTORY = "No History Found";
private SimpleAttributeSet userAttrSet; private SimpleAttributeSet userAttrs;
private SimpleAttributeSet dateAttrSet; private SimpleAttributeSet dateAttrs;
private SimpleAttributeSet textAttrSet; private SimpleAttributeSet textAttrSet;
private SimpleAttributeSet tabAttrSet; private SimpleAttributeSet tabAttrSet;
@ -100,11 +101,11 @@ class CommentHistoryPanel extends JPanel {
if (offset > 0) { if (offset > 0) {
userName = "\n" + userName; userName = "\n" + userName;
} }
doc.insertString(offset, userName, userAttrSet); doc.insertString(offset, userName, userAttrs);
offset = doc.getLength(); offset = doc.getLength();
doc.insertString(offset, doc.insertString(offset,
"\t" + DateUtils.formatDateTimestamp(history.getModificationDate()), dateAttrSet); "\t" + DateUtils.formatDateTimestamp(history.getModificationDate()), dateAttrs);
doc.setParagraphAttributes(offset, 1, tabAttrSet, false); doc.setParagraphAttributes(offset, 1, tabAttrSet, false);
offset = doc.getLength(); offset = doc.getLength();
@ -112,25 +113,13 @@ class CommentHistoryPanel extends JPanel {
} }
private void setUpAttributes() { private void setUpAttributes() {
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
textAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.plugin.comments.history.text"));
userAttrSet = new SimpleAttributeSet(); Font bold = Gui.getFont("font.standard.bold");
userAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); Font monospaced = Gui.getFont("font.monospaced");
userAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12)); textAttrSet =
userAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE); new GAttributes(monospaced, new GColor("color.fg.plugin.comments.history.text"));
userAttrSet.addAttribute(StyleConstants.Foreground, userAttrs = new GAttributes(bold, new GColor("color.fg.plugin.comments.history.user"));
new GColor("color.fg.plugin.comments.history.user")); dateAttrs = new GAttributes(bold, new GColor("color.fg.plugin.comments.history.date"));
dateAttrSet = new SimpleAttributeSet();
dateAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
dateAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
dateAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
dateAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.plugin.comments.history.date"));
tabAttrSet = new SimpleAttributeSet(); tabAttrSet = new SimpleAttributeSet();
TabStop tabs = new TabStop(100, StyleConstants.ALIGN_LEFT, TabStop.LEAD_NONE); TabStop tabs = new TabStop(100, StyleConstants.ALIGN_LEFT, TabStop.LEAD_NONE);

View file

@ -39,6 +39,7 @@ 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.Gui;
import ghidra.app.plugin.core.processors.SetLanguageDialog; import ghidra.app.plugin.core.processors.SetLanguageDialog;
import ghidra.app.util.cparser.C.CParserUtils; import ghidra.app.util.cparser.C.CParserUtils;
import ghidra.framework.Application; import ghidra.framework.Application;
@ -371,8 +372,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
updateArchitectureDescription(); updateArchitectureDescription();
languageButton.setName("Set Processor Architecture"); languageButton.setName("Set Processor Architecture");
Font font = languageButton.getFont(); Gui.registerFont(languageButton, Font.BOLD);
languageButton.setFont(font.deriveFont(Font.BOLD));
JPanel panel = new JPanel(new BorderLayout()); JPanel panel = new JPanel(new BorderLayout());
panel.add(languageTextField, BorderLayout.CENTER); panel.add(languageTextField, BorderLayout.CENTER);

View file

@ -246,8 +246,6 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
signatureFieldUndoRedoKeeper = DockingUtils.installUndoRedo(signatureTextField); signatureFieldUndoRedoKeeper = DockingUtils.installUndoRedo(signatureTextField);
Font font = signatureTextField.getFont();
signatureTextField.setFont(font.deriveFont(18.0f));
panel.add(signatureTextField); panel.add(signatureTextField);
signatureTextField.setEscapeListener(e -> { signatureTextField.setEscapeListener(e -> {

View file

@ -15,7 +15,8 @@
*/ */
package ghidra.app.plugin.core.function.editor; package ghidra.app.plugin.core.function.editor;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*; import java.awt.event.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -26,12 +27,16 @@ import javax.swing.text.*;
import docking.actions.KeyBindingUtils; import docking.actions.KeyBindingUtils;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.Gui;
import ghidra.util.Swing; import ghidra.util.Swing;
class FunctionSignatureTextField extends JTextPane { class FunctionSignatureTextField extends JTextPane {
private static final String ENTER_ACTION_NAME = "ENTER"; private static final String ENTER_ACTION_NAME = "ENTER";
private static final String ESCAPE_ACTION_NAME = "ESCAPE"; private static final String ESCAPE_ACTION_NAME = "ESCAPE";
private static final String TAB_ACTION_NAME = "TAB"; private static final String TAB_ACTION_NAME = "TAB";
private static final String FONT_ID = "font.plugin.function.text.editor";
public static Color DEFAULT_COLOR = public static Color DEFAULT_COLOR =
new GColor("color.fg.plugin.function.editor.dialog.textfield.default"); new GColor("color.fg.plugin.function.editor.dialog.textfield.default");
public static Color PARAMETER_NAME_COLOR = public static Color PARAMETER_NAME_COLOR =
@ -52,8 +57,7 @@ class FunctionSignatureTextField extends JTextPane {
private SimpleAttributeSet errorAttributes; private SimpleAttributeSet errorAttributes;
FunctionSignatureTextField() { FunctionSignatureTextField() {
Font myFont = getFont(); Gui.registerFont(this, FONT_ID);
setFont(myFont.deriveFont(24.0f));
doc = getStyledDocument(); doc = getStyledDocument();
AttributeSet inputAttributes = getInputAttributes(); AttributeSet inputAttributes = getInputAttributes();

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package docking.widgets.textarea; package ghidra.app.plugin.core.instructionsearch.ui;
import java.awt.*; import java.awt.*;
@ -42,7 +42,7 @@ public class HintTextArea extends JTextArea {
} }
/** /**
* Need to override the setText method so we can set font attributes. * Need to override the setText method so we can set formatting attributes.
* *
* @param text the text * @param text the text
*/ */
@ -74,7 +74,27 @@ public class HintTextArea extends JTextArea {
* Sets the text attributes to be used when NOT viewing the hint. * Sets the text attributes to be used when NOT viewing the hint.
*/ */
protected void setAttributes() { protected void setAttributes() {
this.setFont(getFont().deriveFont(Font.PLAIN));
setForeground(Colors.FOREGROUND); setForeground(Colors.FOREGROUND);
} }
/**
* Sets the text attributes to be used when there is an error in the input.
*/
private void setErrorAttributes() {
setForeground(Colors.ERROR);
}
/**
* Invoked. when the text in the box does not pass validation.
*/
public void setError() {
setErrorAttributes();
}
/**
* Invoked when the text in the box passes validation.
*/
public void setValid() {
setAttributes();
}
} }

View file

@ -1,62 +0,0 @@
/* ###
* 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 ghidra.app.plugin.core.instructionsearch.ui;
import java.awt.Font;
import docking.widgets.textarea.HintTextArea;
import generic.theme.GThemeDefaults.Colors;
/**
* Allows users to provide a text hint in a text field, shown only when the text is empty.
* <p>
* Hint text will be shown in light grey, italicized, and in angle brackets. Normal text will
* be plain black.
*/
public class HintTextAreaIS extends HintTextArea {
/**
* Constructs the class with the hint text to be shown.
*
* @param hint the hint
*/
public HintTextAreaIS(final String hint) {
super(hint);
}
/**
* Invoked. when the text in the box does not pass validation.
*/
public void setError() {
setErrorAttributes();
}
/**
* Invoked when the text in the box passes validation.
*/
public void setValid() {
setAttributes();
}
/**
* Sets the text attributes to be used when there is an error in the input.
*/
private void setErrorAttributes() {
this.setFont(getFont().deriveFont(Font.PLAIN));
setForeground(Colors.ERROR);
}
}

View file

@ -47,7 +47,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
// The input text area. This is a generic JTextArea but displays a textual 'hint' to inform // The input text area. This is a generic JTextArea but displays a textual 'hint' to inform
// the user of what type of input is required. // the user of what type of input is required.
private HintTextAreaIS inputBytesTA; private HintTextArea inputBytesTA;
private SelectionModeWidget selectionModeWidget; private SelectionModeWidget selectionModeWidget;
private EndianFlipWidget endianFlipWidget; private EndianFlipWidget endianFlipWidget;
@ -148,7 +148,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
contentPanel.setMinimumSize(new Dimension(500, 300)); contentPanel.setMinimumSize(new Dimension(500, 300));
// Create the input text widget and give it a scrollbar. // Create the input text widget and give it a scrollbar.
inputBytesTA = new HintTextAreaIS(HINT_TEXT); inputBytesTA = new HintTextArea(HINT_TEXT);
JScrollPane scrollPane = new JScrollPane(inputBytesTA); JScrollPane scrollPane = new JScrollPane(inputBytesTA);
inputBytesTA.addKeyListener(this); inputBytesTA.addKeyListener(this);
@ -321,7 +321,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
* *
* @param instruction the instruction to parse * @param instruction the instruction to parse
* @return list of operand metadata * @return list of operand metadata
* @throws MemoryAccessException * @throws MemoryAccessException if there is an exception getting instruction bytes
*/ */
private List<OperandMetadata> createOperandMetadata(PseudoInstruction instruction) private List<OperandMetadata> createOperandMetadata(PseudoInstruction instruction)
throws MemoryAccessException { throws MemoryAccessException {
@ -356,7 +356,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
* *
* @param instruction the instruction to parse * @param instruction the instruction to parse
* @return the instruction metadata * @return the instruction metadata
* @throws MemoryAccessException * @throws MemoryAccessException if there is an exception getting instruction bytes
*/ */
private InstructionMetadata createInstructionMetadata(PseudoInstruction instruction) private InstructionMetadata createInstructionMetadata(PseudoInstruction instruction)
throws MemoryAccessException { throws MemoryAccessException {
@ -510,7 +510,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
* handler the input widget has not officially been updated with the new * handler the input widget has not officially been updated with the new
* character. * character.
* *
* @param e * @param e the event
*/ */
@Override @Override
public void keyReleased(KeyEvent e) { public void keyReleased(KeyEvent e) {

View file

@ -17,8 +17,8 @@ package ghidra.app.plugin.core.instructionsearch.ui;
import java.awt.*; import java.awt.*;
import javax.swing.*; import javax.swing.JLabel;
import javax.swing.table.TableModel; import javax.swing.SwingConstants;
import docking.widgets.table.GTableCellRenderingData; import docking.widgets.table.GTableCellRenderingData;
import generic.theme.Gui; import generic.theme.Gui;
@ -45,20 +45,12 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
public Component getTableCellRendererComponent(GTableCellRenderingData data) { public Component getTableCellRendererComponent(GTableCellRenderingData data) {
Object value = data.getValue(); Object value = data.getValue();
JTable table = data.getTable();
int column = data.getColumnViewIndex();
boolean isSelected = data.isSelected(); boolean isSelected = data.isSelected();
boolean hasFocus = data.hasFocus(); boolean hasFocus = data.hasFocus();
// Do a null check on the input here to protect ourselves. This value can be null
// in certain cases (eg: change resolution on the screen [ctrl-+ on mac], then move the
// instruction window to a different monitor, then click on a cell).
if (value == null) { if (value == null) {
return this; return this;
} }
// Get the data object backing the cell.
InstructionTableDataObject dataObject = (InstructionTableDataObject) value; InstructionTableDataObject dataObject = (InstructionTableDataObject) value;
String strData = dataObject.getData(); String strData = dataObject.getData();
@ -66,7 +58,7 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
JLabel theRenderer = (JLabel) super.getTableCellRendererComponent(renderData); JLabel theRenderer = (JLabel) super.getTableCellRendererComponent(renderData);
setTextAttributes(table, value, column); setTextAttributes();
setBackgroundAttributes(isSelected, hasFocus, dataObject); setBackgroundAttributes(isSelected, hasFocus, dataObject);
setBorderAttributes(dataObject, theRenderer); setBorderAttributes(dataObject, theRenderer);
setForegroundAttributes(dataObject, theRenderer); setForegroundAttributes(dataObject, theRenderer);
@ -80,8 +72,6 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
private void setForegroundAttributes(InstructionTableDataObject dataObject, private void setForegroundAttributes(InstructionTableDataObject dataObject,
JLabel theRenderer) { JLabel theRenderer) {
// Change the foreground to use a font of our choosing. The main reason is that we
// want to use a monospaced font for binary rendering.
theRenderer.setForeground(dataObject.getForegroundColor()); theRenderer.setForeground(dataObject.getForegroundColor());
Font newFont = theRenderer.getFont().deriveFont(dataObject.getFontStyle()); Font newFont = theRenderer.getFont().deriveFont(dataObject.getFontStyle());
theRenderer.setFont(newFont); theRenderer.setFont(newFont);
@ -89,8 +79,6 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
private void setBackgroundAttributes(boolean isSelected, boolean hasFocus, private void setBackgroundAttributes(boolean isSelected, boolean hasFocus,
InstructionTableDataObject dataObject) { InstructionTableDataObject dataObject) {
// Set the background color based on what the cell says. If it's selected, make it a
// bit darker.
Color backgroundColor = dataObject.getBackgroundColor(); Color backgroundColor = dataObject.getBackgroundColor();
if (backgroundColor != null) { if (backgroundColor != null) {
if (isSelected || hasFocus) { if (isSelected || hasFocus) {
@ -102,10 +90,9 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
} }
} }
private void setTextAttributes(JTable table, Object value, int col) { private void setTextAttributes() {
setHorizontalAlignment(SwingConstants.LEFT); setHorizontalAlignment(SwingConstants.LEFT);
TableModel model = table.getModel(); setFont(getDefaultFont());
configureFont(table, model, col);
setOpaque(true); setOpaque(true);
} }
} }

View file

@ -26,6 +26,7 @@ import javax.swing.event.ListDataListener;
import docking.widgets.list.GListCellRenderer; import docking.widgets.list.GListCellRenderer;
import generic.theme.GThemeDefaults.Colors.Tooltips; import generic.theme.GThemeDefaults.Colors.Tooltips;
import generic.theme.Gui;
import generic.util.WindowUtilities; import generic.util.WindowUtilities;
import ghidra.app.plugin.core.console.CodeCompletion; import ghidra.app.plugin.core.console.CodeCompletion;
@ -34,23 +35,25 @@ import ghidra.app.plugin.core.console.CodeCompletion;
*/ */
public class CodeCompletionWindow extends JDialog { public class CodeCompletionWindow extends JDialog {
private static final String FONT_ID = "font.plugin.terminal.completion.list";
protected final InterpreterPanel console; protected final InterpreterPanel console;
protected final JTextPane outputTextField; protected final JTextPane outputTextField;
/* List of CodeCompletions. /* List of CodeCompletions.
* 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.
*/ */
protected List<CodeCompletion> completion_list; protected List<CodeCompletion> completionData;
/* current list of completions */ /* current list of completions */
protected JList jlist; protected JList<CodeCompletion> jlist;
public CodeCompletionWindow(Window parent, InterpreterPanel cp, JTextPane textField) { public CodeCompletionWindow(Window parent, InterpreterPanel cp, JTextPane textField) {
super(parent); super(parent);
this.console = cp; this.console = cp;
outputTextField = textField; outputTextField = textField;
jlist = new JList(); jlist = new JList<>();
completion_list = null; completionData = null;
setUndecorated(true); setUndecorated(true);
/* don't steal focus from text input! */ /* don't steal focus from text input! */
@ -58,14 +61,14 @@ public class CodeCompletionWindow extends JDialog {
jlist.setBackground(Tooltips.BACKGROUND); 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() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
/* when the user clicks the popup window, make sure // when the user clicks the popup window, make sure that the outputTextField gets
* that the outputTextField gets the focus (so that the escape // the focus (so that the escape key and other hotkeys to manage the popup work
* key and other hotkeys to manage the popup work correctly // correctly
*/
outputTextField.requestFocusInWindow(); outputTextField.requestFocusInWindow();
/* double-click inserts a completion */ /* double-click inserts a completion */
if (e.getClickCount() == 2) { if (e.getClickCount() == 2) {
@ -74,9 +77,9 @@ public class CodeCompletionWindow extends JDialog {
} }
}; };
jlist.addMouseListener(mouseListener); jlist.addMouseListener(mouseListener);
/* actually put the components together */
getContentPane().add(new JScrollPane(jlist)); getContentPane().add(new JScrollPane(jlist));
updateCompletionList(completion_list); updateCompletionList(completionData);
jlist.addKeyListener(new KeyAdapter() { jlist.addKeyListener(new KeyAdapter() {
@Override @Override
@ -121,7 +124,7 @@ public class CodeCompletionWindow extends JDialog {
* @param list List of code completions * @param list List of code completions
*/ */
public void updateCompletionList(List<CodeCompletion> list) { public void updateCompletionList(List<CodeCompletion> list) {
completion_list = list; completionData = list;
jlist.setModel(new CodeCompletionListModel(list)); jlist.setModel(new CodeCompletionListModel(list));
jlist.setSelectionModel(new CodeCompletionListSelectionModel(list)); jlist.setSelectionModel(new CodeCompletionListSelectionModel(list));
jlist.clearSelection(); jlist.clearSelection();
@ -247,7 +250,7 @@ public class CodeCompletionWindow extends JDialog {
*/ */
@Override @Override
public void setFont(Font font) { public void setFont(Font font) {
jlist.setFont(font); Gui.registerFont(jlist, FONT_ID);
} }
/** /**
@ -256,7 +259,7 @@ public class CodeCompletionWindow extends JDialog {
*/ */
public void selectPrevious() { public void selectPrevious() {
for (int i = jlist.getSelectedIndex() - 1; i >= 0; i--) { for (int i = jlist.getSelectedIndex() - 1; i >= 0; i--) {
CodeCompletion completion = completion_list.get(i); CodeCompletion completion = completionData.get(i);
if (CodeCompletion.isValid(completion)) { if (CodeCompletion.isValid(completion)) {
jlist.setSelectedIndex(i); jlist.setSelectedIndex(i);
jlist.ensureIndexIsVisible(i); jlist.ensureIndexIsVisible(i);
@ -271,11 +274,11 @@ public class CodeCompletionWindow extends JDialog {
*/ */
public void selectNext() { public void selectNext() {
if (null == completion_list) { if (null == completionData) {
return; return;
} }
for (int i = jlist.getSelectedIndex() + 1; i < completion_list.size(); i++) { for (int i = jlist.getSelectedIndex() + 1; i < completionData.size(); i++) {
CodeCompletion completion = completion_list.get(i); CodeCompletion completion = completionData.get(i);
if (CodeCompletion.isValid(completion)) { if (CodeCompletion.isValid(completion)) {
jlist.setSelectedIndex(i); jlist.setSelectedIndex(i);
jlist.ensureIndexIsVisible(i); jlist.ensureIndexIsVisible(i);
@ -296,18 +299,18 @@ public class CodeCompletionWindow extends JDialog {
if (-1 == i) { if (-1 == i) {
return null; return null;
} }
return completion_list.get(i); return completionData.get(i);
} }
} }
/** /**
* Code completion ListModel. * Code completion ListModel.
*/ */
class CodeCompletionListModel implements ListModel { class CodeCompletionListModel implements ListModel<CodeCompletion> {
List<CodeCompletion> completion_list; List<CodeCompletion> completionData;
public CodeCompletionListModel(List<CodeCompletion> completion_list) { public CodeCompletionListModel(List<CodeCompletion> completion_list) {
this.completion_list = completion_list; this.completionData = completion_list;
} }
@Override @Override
@ -321,22 +324,22 @@ class CodeCompletionListModel implements ListModel {
} }
@Override @Override
public Object getElementAt(int index) { public CodeCompletion getElementAt(int index) {
if ((null == completion_list) || completion_list.isEmpty()) { if ((null == completionData) || completionData.isEmpty()) {
if (0 == index) { if (0 == index) {
return new CodeCompletion("(no completions available)", null, null); return new CodeCompletion("(no completions available)", null, null);
} }
return null; return null;
} }
return completion_list.get(index); return completionData.get(index);
} }
@Override @Override
public int getSize() { public int getSize() {
if ((null == completion_list) || completion_list.isEmpty()) { if ((null == completionData) || completionData.isEmpty()) {
return 1; return 1;
} }
return completion_list.size(); return completionData.size();
} }
} }
@ -405,12 +408,8 @@ class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
@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 (codeCompletion.getComponent() == null) { JLabel component = (JLabel) super.getListCellRendererComponent(list, codeCompletion, index,
return super.getListCellRendererComponent(list, codeCompletion, index, isSelected, isSelected, cellHasFocus);
cellHasFocus);
}
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);

View file

@ -28,8 +28,7 @@ import javax.swing.text.*;
import docking.DockingUtils; import docking.DockingUtils;
import docking.actions.KeyBindingUtils; import docking.actions.KeyBindingUtils;
import generic.theme.GColor; import generic.theme.*;
import generic.theme.Gui;
import generic.util.WindowUtilities; import generic.util.WindowUtilities;
import ghidra.app.plugin.core.console.CodeCompletion; import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
@ -50,9 +49,9 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
"This is the font that will be used in the Console. " + "This is the font that will be used in the Console. " +
"Double-click the font example to change it."; "Double-click the font example to change it.";
private static final Color NORMAL_COLOR = new GColor("color.fg.interpreterconsole"); private static final GColor NORMAL_COLOR = new GColor("color.fg.interpreterconsole");
private static final Color ERROR_COLOR = new GColor("color.fg.interpreterconsole.error"); private static final GColor ERROR_COLOR = new GColor("color.fg.interpreterconsole.error");
private static final Color BG_COLOR = new GColor("color.bg.interpreterconsole"); private static final GColor BG_COLOR = new GColor("color.bg.interpreterconsole");
public enum TextType { public enum TextType {
STDOUT, STDERR, STDIN; STDOUT, STDERR, STDIN;
@ -84,16 +83,6 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
private boolean caretGuard = true; private boolean caretGuard = true;
private PluginTool tool; private PluginTool tool;
private static SimpleAttributeSet createAttributes(Font font, Color color) {
SimpleAttributeSet attributeSet = new SimpleAttributeSet();
attributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
attributeSet.addAttribute(StyleConstants.FontSize, font.getSize());
attributeSet.addAttribute(StyleConstants.Italic, font.isItalic());
attributeSet.addAttribute(StyleConstants.Bold, font.isBold());
attributeSet.addAttribute(StyleConstants.Foreground, color);
return attributeSet;
}
public InterpreterPanel(PluginTool tool, InterpreterConnection interpreter) { public InterpreterPanel(PluginTool tool, InterpreterConnection interpreter) {
this.tool = tool; this.tool = tool;
this.interpreter = interpreter; this.interpreter = interpreter;
@ -373,9 +362,11 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
private void updateFontAttributes(Font font) { private void updateFontAttributes(Font font) {
Font boldFont = font.deriveFont(Font.BOLD); Font boldFont = font.deriveFont(Font.BOLD);
STDOUT_SET = createAttributes(font, NORMAL_COLOR);
STDERR_SET = createAttributes(font, ERROR_COLOR); STDOUT_SET = new GAttributes(font, NORMAL_COLOR);
STDIN_SET = createAttributes(boldFont, NORMAL_COLOR); STDOUT_SET = new GAttributes(font, NORMAL_COLOR);
STDERR_SET = new GAttributes(font, ERROR_COLOR);
STDIN_SET = new GAttributes(boldFont, NORMAL_COLOR);
setTextPaneFont(inputTextPane, boldFont); setTextPaneFont(inputTextPane, boldFont);
setTextPaneFont(promptTextPane, font); setTextPaneFont(promptTextPane, font);
@ -389,8 +380,7 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
HelpLocation help = new HelpLocation(getName(), "ConsolePlugin"); HelpLocation help = new HelpLocation(getName(), "ConsolePlugin");
options.setOptionsHelpLocation(help); options.setOptionsHelpLocation(help);
options.registerThemeFontBinding(FONT_OPTION_LABEL, FONT_ID, help, options.registerThemeFontBinding(FONT_OPTION_LABEL, FONT_ID, help, FONT_DESCRIPTION);
FONT_DESCRIPTION);
options.registerOption(COMPLETION_WINDOW_TRIGGER_LABEL, CompletionWindowTrigger.TAB, help, options.registerOption(COMPLETION_WINDOW_TRIGGER_LABEL, CompletionWindowTrigger.TAB, help,
COMPLETION_WINDOW_TRIGGER_DESCRIPTION); COMPLETION_WINDOW_TRIGGER_DESCRIPTION);
@ -490,8 +480,8 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
completionInsertionPosition = inputTextPane.getCaretPosition(); completionInsertionPosition = inputTextPane.getCaretPosition();
String text = getInputTextPaneText(); String text = getInputTextPaneText();
List<CodeCompletion> completions = InterpreterPanel.this.interpreter.getCompletions( List<CodeCompletion> completions =
text, completionInsertionPosition); InterpreterPanel.this.interpreter.getCompletions(text, completionInsertionPosition);
completionWindow.updateCompletionList(completions); completionWindow.updateCompletionList(completions);
}); });
} }

View file

@ -67,7 +67,7 @@ class MemoryMapProvider extends ComponentProviderAdapter {
private DockingAction deleteAction; private DockingAction deleteAction;
private DockingAction setBaseAction; private DockingAction setBaseAction;
private MemoryMapPlugin plugin = null; private MemoryMapPlugin plugin;
private Program program; private Program program;
private MemoryMapManager memManager; private MemoryMapManager memManager;
@ -135,8 +135,12 @@ class MemoryMapProvider extends ComponentProviderAdapter {
table.installNavigation(tool); table.installNavigation(tool);
table.setAutoCreateColumnsFromModel(false); table.setAutoCreateColumnsFromModel(false);
GTableCellRenderer monoRenderer = new GTableCellRenderer(); GTableCellRenderer monoRenderer = new GTableCellRenderer() {
monoRenderer.setFont(monoRenderer.getFixedWidthFont()); @Override
protected Font getDefaultFont() {
return fixedWidthFont;
}
};
TableColumn column = table.getColumn(MemoryMapModel.START_COL); TableColumn column = table.getColumn(MemoryMapModel.START_COL);
column.setCellRenderer(monoRenderer); column.setCellRenderer(monoRenderer);

View file

@ -1019,8 +1019,6 @@ public class EditReferencesProvider extends ComponentProviderAdapter
private class RefCellTextRenderer extends GTableCellRenderer { private class RefCellTextRenderer extends GTableCellRenderer {
RefCellTextRenderer() { RefCellTextRenderer() {
defaultFont = getFont();
boldFont = defaultFont.deriveFont(defaultFont.getStyle() | Font.BOLD);
setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
} }

View file

@ -28,7 +28,6 @@ import docking.widgets.OptionDialog;
import docking.widgets.table.*; import docking.widgets.table.*;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui;
import ghidra.app.cmd.register.SetRegisterCmd; import ghidra.app.cmd.register.SetRegisterCmd;
import ghidra.app.events.ProgramSelectionPluginEvent; import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.services.MarkerService; import ghidra.app.services.MarkerService;
@ -498,7 +497,11 @@ class RegisterValueRenderer extends GTableCellRenderer {
RegisterValueRenderer(JTable table) { RegisterValueRenderer(JTable table) {
setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
Gui.registerFont(this, "font.monospaced"); }
@Override
protected Font getDefaultFont() {
return fixedWidthFont;
} }
@Override @Override

View file

@ -28,6 +28,7 @@ import javax.swing.event.ChangeListener;
import docking.DialogComponentProvider; import docking.DialogComponentProvider;
import docking.widgets.combobox.GComboBox; import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GLabel; import docking.widgets.label.GLabel;
import generic.theme.GThemeDefaults.Ids.Fonts;
import generic.theme.Gui; import generic.theme.Gui;
import ghidra.app.util.bean.FixedBitSizeValueField; import ghidra.app.util.bean.FixedBitSizeValueField;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
@ -77,8 +78,6 @@ public class SetRegisterValueDialog extends DialogComponentProvider {
private JComponent buildWorkPanel(Register[] registers) { private JComponent buildWorkPanel(Register[] registers) {
registerComboBox = new GComboBox<>(wrapRegisters(registers)); registerComboBox = new GComboBox<>(wrapRegisters(registers));
Font f = registerComboBox.getFont().deriveFont(13f);
registerComboBox.setFont(f);
registerValueField = new FixedBitSizeValueField(32, true, false); registerValueField = new FixedBitSizeValueField(32, true, false);
registerValueField.addChangeListener(new ChangeListener() { registerValueField.addChangeListener(new ChangeListener() {
@Override @Override
@ -93,11 +92,11 @@ public class SetRegisterValueDialog extends DialogComponentProvider {
registerChanged(); registerChanged();
} }
}); });
f = Gui.getFont("font.monospaced");
addressRangeList = new JList(); addressRangeList = new JList();
addressRangeList.setEnabled(false); addressRangeList.setEnabled(false);
addressRangeList.setFont(f); Gui.registerFont(addressRangeList, Fonts.MONOSPACED);
JScrollPane scrollPane = new JScrollPane(addressRangeList); JScrollPane scrollPane = new JScrollPane(addressRangeList);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Dimension d = scrollPane.getPreferredSize(); Dimension d = scrollPane.getPreferredSize();

View file

@ -16,11 +16,12 @@
package ghidra.app.plugin.core.scalartable; package ghidra.app.plugin.core.scalartable;
import java.awt.Component; import java.awt.Component;
import java.awt.Font;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Comparator; import java.util.Comparator;
import javax.swing.*; import javax.swing.JLabel;
import javax.swing.table.TableModel; import javax.swing.SwingConstants;
import docking.widgets.table.*; import docking.widgets.table.*;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -339,8 +340,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
return (o1.isSigned() ? 1 : -1); return (o1.isSigned() ? 1 : -1);
} }
return o1.isSigned() return o1.isSigned() ? Long.compare(o1.getSignedValue(), o2.getSignedValue())
? Long.compare(o1.getSignedValue(), o2.getSignedValue())
: Long.compareUnsigned(o1.getUnsignedValue(), o2.getUnsignedValue()); : Long.compareUnsigned(o1.getUnsignedValue(), o2.getUnsignedValue());
} }
} }
@ -410,15 +410,14 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
} }
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(fixedWidthFont); return fixedWidthFont;
} }
@Override @Override
public ColumnConstraintFilterMode getColumnConstraintFilterMode() { public ColumnConstraintFilterMode getColumnConstraintFilterMode() {
return ColumnConstraintFilterMode.ALLOW_ALL_FILTERS; return ColumnConstraintFilterMode.ALLOW_ALL_FILTERS;
} }
}; };
@Override @Override
@ -440,10 +439,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
public Scalar getValue(ScalarRowObject rowObject, Settings settings, Program p, public Scalar getValue(ScalarRowObject rowObject, Settings settings, Program p,
ServiceProvider provider) throws IllegalArgumentException { ServiceProvider provider) throws IllegalArgumentException {
Scalar scalar = rowObject.getScalar(); Scalar scalar = rowObject.getScalar();
return new Scalar(scalar.bitLength(), scalar.getUnsignedValue(), false);
Scalar unsigned = new Scalar(scalar.bitLength(), scalar.getUnsignedValue(), false);
return unsigned;
} }
} }

View file

@ -38,7 +38,7 @@ import docking.widgets.spinner.IntegerSpinner;
import docking.widgets.table.threaded.ThreadedTableModelListener; import docking.widgets.table.threaded.ThreadedTableModelListener;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import generic.theme.GThemeDefaults; import generic.theme.GThemeDefaults;
import ghidra.app.services.GoToService; import generic.theme.Gui;
import ghidra.app.services.StringTranslationService; import ghidra.app.services.StringTranslationService;
import ghidra.app.services.StringTranslationService.TranslateOptions; import ghidra.app.services.StringTranslationService.TranslateOptions;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -72,6 +72,8 @@ public class EncodedStringsDialog extends DialogComponentProvider {
Map.entry(CharsetInfo.UTF16, UnicodeDataType.dataType), Map.entry(CharsetInfo.UTF16, UnicodeDataType.dataType),
Map.entry(CharsetInfo.UTF32, Unicode32DataType.dataType)); Map.entry(CharsetInfo.UTF32, Unicode32DataType.dataType));
private static final String BUTTON_FONT_ID = "font.plugin.strings.buttons";
private final PluginTool tool; private final PluginTool tool;
private final EncodedStringsPlugin plugin; private final EncodedStringsPlugin plugin;
private final Program program; private final Program program;
@ -423,8 +425,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
table.setPreferredScrollableViewportSize(new Dimension(350, 150)); table.setPreferredScrollableViewportSize(new Dimension(350, 150));
table.getSelectionModel().addListSelectionListener(e -> selectedRowChange()); table.getSelectionModel().addListSelectionListener(e -> selectedRowChange());
GoToService goToService = tool.getService(GoToService.class); table.installNavigation(tool);
table.installNavigation(goToService, goToService.getDefaultNavigatable());
filterPanel = new GhidraTableFilterPanel<>(table, tableModel); filterPanel = new GhidraTableFilterPanel<>(table, tableModel);
} }
@ -604,10 +605,10 @@ public class EncodedStringsDialog extends DialogComponentProvider {
scriptFailedCountLabel scriptFailedCountLabel
.setToolTipText("Number of strings excluded due to failing script requirements."); .setToolTipText("Number of strings excluded due to failing script requirements.");
Font font = new JPanel().getFont().deriveFont(10.0f);
allowLatinScriptButton = new JToggleButton("A-Z"); allowLatinScriptButton = new JToggleButton("A-Z");
allowLatinScriptButton.setName("ALLOW_LATIN_SCRIPT"); allowLatinScriptButton.setName("ALLOW_LATIN_SCRIPT");
allowLatinScriptButton.setFont(font); Gui.registerFont(allowLatinScriptButton, BUTTON_FONT_ID);
allowLatinScriptButton.setToolTipText( allowLatinScriptButton.setToolTipText(
"Allow Latin characters (e.g. A-Z, etc) to also be present in the string."); "Allow Latin characters (e.g. A-Z, etc) to also be present in the string.");
allowLatinScriptButton.setSelected(true); allowLatinScriptButton.setSelected(true);
@ -620,7 +621,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
allowCommonScriptButton = new JToggleButton("0-9,!?"); allowCommonScriptButton = new JToggleButton("0-9,!?");
allowCommonScriptButton.setName("ALLOW_COMMON_SCRIPT"); allowCommonScriptButton.setName("ALLOW_COMMON_SCRIPT");
allowCommonScriptButton.setFont(font); Gui.registerFont(allowCommonScriptButton, BUTTON_FONT_ID);
allowCommonScriptButton.setToolTipText( allowCommonScriptButton.setToolTipText(
"Allow common characters (e.g. 0-9, space, punctuation, etc) to also be present in the string."); "Allow common characters (e.g. 0-9, space, punctuation, etc) to also be present in the string.");
allowCommonScriptButton.setSelected(true); allowCommonScriptButton.setSelected(true);
@ -633,7 +634,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
allowAnyScriptButton = new JToggleButton("Any"); allowAnyScriptButton = new JToggleButton("Any");
allowAnyScriptButton.setName("ALLOW_ANY_SCRIPT"); allowAnyScriptButton.setName("ALLOW_ANY_SCRIPT");
allowAnyScriptButton.setFont(font); Gui.registerFont(allowAnyScriptButton, BUTTON_FONT_ID);
allowAnyScriptButton.setToolTipText( allowAnyScriptButton.setToolTipText(
"Allow all other character scripts to also be present in the string."); "Allow all other character scripts to also be present in the string.");
allowAnyScriptButton.setSelected(true); allowAnyScriptButton.setSelected(true);
@ -747,13 +748,12 @@ public class EncodedStringsDialog extends DialogComponentProvider {
executeMonitoredRunnable("Creating Strings", true, true, 100, this::createStringsAndClose); executeMonitoredRunnable("Creating Strings", true, true, 100, this::createStringsAndClose);
} }
private void setActionItemEnablement(boolean b) { private void setActionItemEnablement(boolean enabled) {
createButton.setEnabled(b); createButton.setEnabled(enabled);
cancelButton.setEnabled(b); cancelButton.setEnabled(enabled);
table.removeNavigation(); table.removeNavigation();
if (b) { if (enabled) {
GoToService goToService = tool.getService(GoToService.class); table.installNavigation(tool);
table.installNavigation(goToService, goToService.getDefaultNavigatable());
} }
} }
@ -834,11 +834,10 @@ public class EncodedStringsDialog extends DialogComponentProvider {
createButton.setEnabled(false); createButton.setEnabled(false);
return; return;
} }
String createMessage = isSingleStringMode() String createMessage = isSingleStringMode() ? "Create"
? "Create" : "Create %s"
: "Create %s".formatted(rowCount == selectedRowCount || selectedRowCount == 0 .formatted(rowCount == selectedRowCount || selectedRowCount == 0 ? "All"
? "All" : "Selected (%d)".formatted(selectedRowCount));
: "Selected (%d)".formatted(selectedRowCount));
createButton.setEnabled(true); createButton.setEnabled(true);
createButton.setText(createMessage); createButton.setText(createMessage);
@ -954,8 +953,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
return null; return null;
} }
File f = new File(filename); File f = new File(filename);
ResourceFile rf = f.isAbsolute() && f.isFile() ResourceFile rf = f.isAbsolute() && f.isFile() ? new ResourceFile(f)
? new ResourceFile(f)
: Application.findDataFileInAnyModule(filename); : Application.findDataFileInAnyModule(filename);
if (rf == null) { if (rf == null) {
Msg.error(this, "Unable to find string model file: %s".formatted(filename)); Msg.error(this, "Unable to find string model file: %s".formatted(filename));
@ -1012,8 +1010,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
private StringTranslationService getSelectedStringTranslationService(boolean ifEnabled) { private StringTranslationService getSelectedStringTranslationService(boolean ifEnabled) {
boolean enabled = showTranslateOptionsButton.isSelected(); boolean enabled = showTranslateOptionsButton.isSelected();
return ifEnabled && !enabled return ifEnabled && !enabled ? null
? null
: (StringTranslationService) translateComboBox.getSelectedItem(); : (StringTranslationService) translateComboBox.getSelectedItem();
} }

View file

@ -15,7 +15,6 @@
*/ */
package ghidra.app.plugin.debug; package ghidra.app.plugin.debug;
import java.awt.Font;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -59,22 +58,11 @@ public class DomainEventComponentProvider extends ComponentProviderAdapter {
return scrollPane; return scrollPane;
} }
/**
* @see docking.ComponentProvider#componentHidden()
*/
@Override @Override
public void componentHidden() { public void componentHidden() {
clear(); clear();
} }
public Font getFont() {
return textArea.getFont();
}
public void setFont(Font font) {
textArea.setFont(font);
}
private void createAction() { private void createAction() {
clearAction = new DockingAction("Clear Display", getName()) { clearAction = new DockingAction("Clear Display", getName()) {
@Override @Override

View file

@ -15,7 +15,6 @@
*/ */
package ghidra.app.plugin.debug; package ghidra.app.plugin.debug;
import java.awt.Font;
import java.util.Date; import java.util.Date;
import ghidra.app.DeveloperPluginPackage; import ghidra.app.DeveloperPluginPackage;
@ -47,18 +46,11 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
private Program currentProgram; private Program currentProgram;
private DomainEventComponentProvider provider; private DomainEventComponentProvider provider;
private String padString;
/**
* Constructor
*/
public DomainEventDisplayPlugin(PluginTool tool) { public DomainEventDisplayPlugin(PluginTool tool) {
super(tool); super(tool);
String dateStr = new Date() + ": ";
padString = dateStr.replaceAll(".", " ");
provider = new DomainEventComponentProvider(tool, getName()); provider = new DomainEventComponentProvider(tool, getName());
// Note: this plugin in the 'Developer' category and as such does not need help // Note: this plugin in the 'Developer' category and as such does not need help
@ -66,9 +58,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
helpService.excludeFromHelp(provider); helpService.excludeFromHelp(provider);
} }
/**
* Put event processing code here.
*/
@Override @Override
public void processEvent(PluginEvent event) { public void processEvent(PluginEvent event) {
if (event instanceof ProgramActivatedPluginEvent) { if (event instanceof ProgramActivatedPluginEvent) {
@ -83,10 +72,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
} }
} }
/**
* Tells a plugin that it is no longer needed. The plugin should remove
* itself from anything that it is registered to and release any resources.
*/
@Override @Override
public void dispose() { public void dispose() {
if (currentProgram != null) { if (currentProgram != null) {
@ -94,9 +79,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
} }
} }
/**
* This is the callback method for DomainObjectChangedEvents.
*/
@Override @Override
public void domainObjectChanged(DomainObjectChangedEvent ev) { public void domainObjectChanged(DomainObjectChangedEvent ev) {
if (tool != null && provider.isVisible()) { if (tool != null && provider.isVisible()) {
@ -104,24 +86,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
} }
} }
/**
* Get the font for the text area; font property will show up on the
* plugin property sheet.
*/
public Font getFont() {
return provider.getFont();
}
/**
* Set the font for the text area; font property will show up on the
* plugin property sheet.
*/
public void setFont(Font font) {
provider.setFont(font);
tool.setConfigChanged(true);
}
/** /**
* Display the change event. * Display the change event.
*/ */

View file

@ -27,6 +27,7 @@ import javax.swing.*;
import docking.ComponentProvider; import docking.ComponentProvider;
import docking.Tool; import docking.Tool;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.Gui;
import generic.util.WindowUtilities; import generic.util.WindowUtilities;
import generic.util.image.ImageUtils; import generic.util.image.ImageUtils;
import ghidra.app.DeveloperPluginPackage; import ghidra.app.DeveloperPluginPackage;
@ -110,6 +111,8 @@ public class WindowLocationPlugin extends Plugin {
private class WindowLocationPanel extends JPanel { private class WindowLocationPanel extends JPanel {
private static final String FONT_ID = "font.plugin.window.location";
private MouseListener mousy = new MouseListener(); private MouseListener mousy = new MouseListener();
WindowLocationPanel() { WindowLocationPanel() {
@ -188,9 +191,8 @@ public class WindowLocationPlugin extends Plugin {
} }
private void paintWindows(Graphics2D g2d, AffineTransform xform) { private void paintWindows(Graphics2D g2d, AffineTransform xform) {
Font f = g2d.getFont(); Font f = Gui.getFont(FONT_ID);
Font biggerFont = f.deriveFont(40f); g2d.setFont(f);
g2d.setFont(biggerFont);
g2d.setColor(FG_COLOR_WINDOW_TEXT); g2d.setColor(FG_COLOR_WINDOW_TEXT);
Window[] windows = Window.getWindows(); Window[] windows = Window.getWindows();
@ -423,10 +425,7 @@ public class WindowLocationPlugin extends Plugin {
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; return Objects.hash(window);
int result = 1;
result = prime * result + ((window == null) ? 0 : window.hashCode());
return result;
} }
@Override @Override

View file

@ -65,10 +65,12 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected AbstractVariableFieldFactory(String name, FieldFormatModel model, protected AbstractVariableFieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider highlightProvider, Options displayOptions,
Options fieldOptions) {
super(name, model, highlightProvider, displayOptions, fieldOptions); super(name, model, highlightProvider, displayOptions, fieldOptions);
} }
@Override
protected void initDisplayOptions(Options displayOptions) { protected void initDisplayOptions(Options displayOptions) {
// display options for local variables handled by FieldFactory base class // display options for local variables handled by FieldFactory base class
@ -110,8 +112,7 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
super.displayOptionsChanged(options, optionName, oldValue, newValue); super.displayOptionsChanged(options, optionName, oldValue, newValue);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation") // ignore getFontMetrics() deprecation warning
// we know
private void setMetrics(Font newFont, ParameterFieldOptions paramFieldOptions) { private void setMetrics(Font newFont, ParameterFieldOptions paramFieldOptions) {
paramFieldOptions.defaultMetrics = Toolkit.getDefaultToolkit().getFontMetrics(newFont); paramFieldOptions.defaultMetrics = Toolkit.getDefaultToolkit().getFontMetrics(newFont);
for (int i = 0; i < paramFieldOptions.fontMetrics.length; i++) { for (int i = 0; i < paramFieldOptions.fontMetrics.length; i++) {

View file

@ -29,7 +29,6 @@ import ghidra.framework.options.ToolOptions;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.SystemUtilities;
import ghidra.util.classfinder.ExtensionPoint; import ghidra.util.classfinder.ExtensionPoint;
/** /**
@ -66,8 +65,8 @@ public abstract class FieldFactory implements ExtensionPoint {
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected FieldFactory(String name, FieldFormatModel model, protected FieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider highlightProvider, ListingHighlightProvider highlightProvider, Options displayOptions,
Options displayOptions, Options fieldOptions) { Options fieldOptions) {
this.name = name; this.name = name;
this.model = model; this.model = model;
this.hlProvider = highlightProvider; this.hlProvider = highlightProvider;
@ -135,7 +134,7 @@ public abstract class FieldFactory implements ExtensionPoint {
public void displayOptionsChanged(Options options, String optionName, Object oldValue, public void displayOptionsChanged(Options options, String optionName, Object oldValue,
Object newValue) { Object newValue) {
if (optionName.equals(FONT_OPTION_NAME)) { if (optionName.equals(FONT_OPTION_NAME)) {
baseFont = SystemUtilities.adjustForFontSizeOverride((Font) newValue); baseFont = (Font) newValue;
setMetrics(baseFont); setMetrics(baseFont);
} }
else if (optionName.equals(styleOptionName)) { else if (optionName.equals(styleOptionName)) {

View file

@ -40,7 +40,6 @@ import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.viewer.field.ListingColors; import ghidra.app.util.viewer.field.ListingColors;
import ghidra.app.util.viewer.field.ListingColors.*; import ghidra.app.util.viewer.field.ListingColors.*;
import ghidra.util.SystemUtilities;
/** /**
* Class for displaying and manipulating field colors and fonts. * Class for displaying and manipulating field colors and fonts.
@ -139,7 +138,7 @@ public class OptionsGui extends JPanel {
*/ */
public OptionsGui(Font font, PropertyChangeListener listener) { public OptionsGui(Font font, PropertyChangeListener listener) {
propertyChangeListener = listener; propertyChangeListener = listener;
setBaseFont(SystemUtilities.adjustForFontSizeOverride(font)); setBaseFont(font);
genLayouts(); genLayouts();
buildPanel(); buildPanel();
fieldPanel.setBackgroundColor(BACKGROUND.getColor()); fieldPanel.setBackgroundColor(BACKGROUND.getColor());

View file

@ -21,9 +21,8 @@ import java.util.LinkedList;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.text.*; import javax.swing.text.*;
import generic.theme.GColor; import generic.theme.*;
import generic.theme.GThemeDefaults.Ids.Fonts; import generic.theme.GThemeDefaults.Ids.Fonts;
import generic.theme.Gui;
import ghidra.framework.options.*; import ghidra.framework.options.*;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.util.Msg; import ghidra.util.Msg;
@ -52,8 +51,8 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
/** % of characters to delete when truncation is necessary */ /** % of characters to delete when truncation is necessary */
private static double DEFAULT_TRUNCATION_FACTOR = .10; private static double DEFAULT_TRUNCATION_FACTOR = .10;
private static SimpleAttributeSet outputAttributeSet; private static SimpleAttributeSet outputAttributes;
private static SimpleAttributeSet errorAttributeSet; private static SimpleAttributeSet errorAttributes;
// don't update more than once per second if lots of messages are being written // don't update more than once per second if lots of messages are being written
private SwingUpdateManager updateManager = new SwingUpdateManager(100, 1000, () -> doUpdate()); private SwingUpdateManager updateManager = new SwingUpdateManager(100, 1000, () -> doUpdate());
@ -192,10 +191,10 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
private AttributeSet getAttributeSetByName(String attributeSetName) { private AttributeSet getAttributeSetByName(String attributeSetName) {
if (OUTPUT_ATTRIBUTE_VALUE.equals(attributeSetName)) { if (OUTPUT_ATTRIBUTE_VALUE.equals(attributeSetName)) {
return outputAttributeSet; return outputAttributes;
} }
else if (ERROR_ATTRIBUTE_VALUE.equals(attributeSetName)) { else if (ERROR_ATTRIBUTE_VALUE.equals(attributeSetName)) {
return errorAttributeSet; return errorAttributes;
} }
else { else {
// we found an attribute type that we do not know about // we found an attribute type that we do not know about
@ -208,23 +207,12 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
} }
private void createAttributes(Font font) { private void createAttributes(Font font) {
outputAttributeSet = new SimpleAttributeSet();
outputAttributeSet.addAttribute(CUSTOM_ATTRIBUTE_KEY, OUTPUT_ATTRIBUTE_VALUE);
outputAttributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
outputAttributeSet.addAttribute(StyleConstants.FontSize, font.getSize());
outputAttributeSet.addAttribute(StyleConstants.Italic, font.isItalic());
outputAttributeSet.addAttribute(StyleConstants.Bold, font.isBold());
outputAttributeSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.consoletextpane"));
errorAttributeSet = new SimpleAttributeSet(); outputAttributes = new GAttributes(font, new GColor("color.fg.consoletextpane"));
errorAttributeSet.addAttribute(CUSTOM_ATTRIBUTE_KEY, ERROR_ATTRIBUTE_VALUE); outputAttributes.addAttribute(CUSTOM_ATTRIBUTE_KEY, OUTPUT_ATTRIBUTE_VALUE);
errorAttributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
errorAttributeSet.addAttribute(StyleConstants.FontSize, font.getSize()); errorAttributes = new GAttributes(font, new GColor("color.fg.error.consoletextpane"));
errorAttributeSet.addAttribute(StyleConstants.Italic, font.isItalic()); errorAttributes.addAttribute(CUSTOM_ATTRIBUTE_KEY, ERROR_ATTRIBUTE_VALUE);
errorAttributeSet.addAttribute(StyleConstants.Bold, font.isBold());
errorAttributeSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.error.consoletextpane"));
} }
private void doUpdate() { private void doUpdate() {
@ -316,7 +304,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
} }
AttributeSet getAttributes() { AttributeSet getAttributes() {
return outputAttributeSet; return outputAttributes;
} }
} }
@ -327,7 +315,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
@Override @Override
AttributeSet getAttributes() { AttributeSet getAttributes() {
return errorAttributeSet; return errorAttributes;
} }
} }

View file

@ -29,6 +29,7 @@ import docking.widgets.*;
import docking.widgets.label.*; import docking.widgets.label.*;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui;
import generic.util.WindowUtilities; import generic.util.WindowUtilities;
import ghidra.framework.Application; import ghidra.framework.Application;
import ghidra.framework.ApplicationProperties; import ghidra.framework.ApplicationProperties;
@ -44,16 +45,19 @@ class InfoPanel extends JPanel {
private final static int MARGIN = 10; private final static int MARGIN = 10;
private final static String SPLASH_FILENAME = "splash.txt";
private final static String CLOUD_REV_FILENAME = "images/cloudbarReversed.jpg";
private final static String GHIDRA_FILENAME = "images/GHIDRA_Splash.png";
private final static String CLOUD_FILENAME = "images/cloudbar.jpg";
private static final String FONT_ID = "font.splash.infopanel";
private String version; private String version;
private String marking; private String marking;
private String distributionInfo; private String distributionInfo;
private Color bgColor; // background color for all panels private Color bgColor; // background color for all panels
private int imageWidth; private int imageWidth;
private final static String SPLASH_FILENAME = "splash.txt";
private final static String CLOUD_REV_FILENAME = "images/cloudbarReversed.jpg";
private final static String GHIDRA_FILENAME = "images/GHIDRA_Splash.png";
private final static String CLOUD_FILENAME = "images/cloudbar.jpg";
InfoPanel() { InfoPanel() {
getAboutInfo(); getAboutInfo();
@ -170,9 +174,7 @@ class InfoPanel extends JPanel {
private Component buildVersionLabel() { private Component buildVersionLabel() {
MultiLineLabel versionLabel = new MultiLineLabel(version, 0, 3, MultiLineLabel.CENTER); MultiLineLabel versionLabel = new MultiLineLabel(version, 0, 3, MultiLineLabel.CENTER);
Font font = versionLabel.getFont(); Gui.registerFont(versionLabel, FONT_ID);
font = font.deriveFont(14f).deriveFont(Font.BOLD);
versionLabel.setFont(font);
versionLabel.setForeground(new GColor("color.fg.infopanel.version")); versionLabel.setForeground(new GColor("color.fg.infopanel.version"));
return versionLabel; return versionLabel;
} }

View file

@ -38,6 +38,7 @@ import docking.widgets.dialogs.MultiLineMessageDialog;
import docking.widgets.label.GLabel; import docking.widgets.label.GLabel;
import docking.widgets.list.GListCellRenderer; import docking.widgets.list.GListCellRenderer;
import generic.theme.GIcon; import generic.theme.GIcon;
import generic.theme.Gui;
import ghidra.app.services.ProgramManager; import ghidra.app.services.ProgramManager;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.ByteProvider;
@ -240,8 +241,7 @@ public class ImporterDialog extends DialogComponentProvider {
validateFormInput(); validateFormInput();
}); });
Font font = languageButton.getFont(); Gui.registerFont(languageButton, Font.BOLD);
languageButton.setFont(font.deriveFont(Font.BOLD));
JPanel panel = new JPanel(new BorderLayout()); JPanel panel = new JPanel(new BorderLayout());
panel.add(languageTextField, BorderLayout.CENTER); panel.add(languageTextField, BorderLayout.CENTER);

View file

@ -26,6 +26,7 @@ import javax.swing.border.Border;
import docking.widgets.checkbox.GCheckBox; import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
import ghidra.program.util.DefaultLanguageService; import ghidra.program.util.DefaultLanguageService;
import ghidra.util.table.*; import ghidra.util.table.*;
@ -67,7 +68,7 @@ public class NewLanguagePanel extends JPanel {
tableFilterPanel = new GhidraTableFilterPanel<>(table, tableModel); tableFilterPanel = new GhidraTableFilterPanel<>(table, tableModel);
descriptionLabel = new GDLabel(DEFAULT_DESCRIPTION_TEXT); descriptionLabel = new GDLabel(DEFAULT_DESCRIPTION_TEXT);
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.ITALIC)); Gui.registerFont(descriptionLabel, Font.ITALIC);
recommendedCheckbox = new GCheckBox("Show Only Recommended Language/Compiler Specs"); recommendedCheckbox = new GCheckBox("Show Only Recommended Language/Compiler Specs");
recommendedCheckbox.addItemListener(e -> { recommendedCheckbox.addItemListener(e -> {
@ -211,7 +212,6 @@ public class NewLanguagePanel extends JPanel {
LanguageCompilerSpecPair selectedLcsPair = getSelectedLcsPair(); LanguageCompilerSpecPair selectedLcsPair = getSelectedLcsPair();
if (selectedLcsPair == null) { if (selectedLcsPair == null) {
descriptionLabel.setText(DEFAULT_DESCRIPTION_TEXT); descriptionLabel.setText(DEFAULT_DESCRIPTION_TEXT);
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.ITALIC));
} }
else { else {
try { try {
@ -220,7 +220,6 @@ public class NewLanguagePanel extends JPanel {
catch (LanguageNotFoundException e) { catch (LanguageNotFoundException e) {
descriptionLabel.setText("<LanguageNotFound>"); descriptionLabel.setText("<LanguageNotFound>");
} }
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.PLAIN));
} }
// notifyListenersOfValidityChanged(); // notifyListenersOfValidityChanged();
if (!listeners.isEmpty()) { if (!listeners.isEmpty()) {

View file

@ -109,7 +109,7 @@ public class ProgramDiffDetails {
// FUTURE : Add checks to make sure programs are comparable. // FUTURE : Add checks to make sure programs are comparable.
// Throw exception if not comparable. // Throw exception if not comparable.
initDetails(); initDetails();
initAttributes(); textAttrSet = new SimpleAttributeSet();
} }
private static String getIndentString(int indentCount) { private static String getIndentString(int indentCount) {
@ -121,11 +121,6 @@ public class ProgramDiffDetails {
return buf.toString(); return buf.toString();
} }
private void initAttributes() {
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontSize, 12);
}
/** /**
* Gets a string indicating the types of differences for the code units at the indicated * Gets a string indicating the types of differences for the code units at the indicated
* address. The string contains information from each program where there are differences. * address. The string contains information from each program where there are differences.

View file

@ -15,8 +15,7 @@
*/ */
package ghidra.util.table.field; package ghidra.util.table.field;
import javax.swing.JTable; import java.awt.Font;
import javax.swing.table.TableModel;
import ghidra.app.plugin.core.disassembler.AddressTable; import ghidra.app.plugin.core.disassembler.AddressTable;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -34,9 +33,10 @@ public class AddressTableDataTableColumn
private final GColumnRenderer<String> monospacedRenderer = private final GColumnRenderer<String> monospacedRenderer =
new AbstractGColumnRenderer<String>() { new AbstractGColumnRenderer<String>() {
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(getFixedWidthFont()); return fixedWidthFont;
} }
@Override @Override

View file

@ -16,10 +16,9 @@
package ghidra.util.table.field; package ghidra.util.table.field;
import java.awt.Component; import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.GTableCellRenderingData; import docking.widgets.table.GTableCellRenderingData;
import ghidra.docking.settings.FormatSettingsDefinition; import ghidra.docking.settings.FormatSettingsDefinition;
@ -29,14 +28,15 @@ import ghidra.util.StringFormat;
import ghidra.util.table.column.AbstractGColumnRenderer; import ghidra.util.table.column.AbstractGColumnRenderer;
public class MonospacedByteRenderer extends AbstractGColumnRenderer<Byte[]> { public class MonospacedByteRenderer extends AbstractGColumnRenderer<Byte[]> {
@Override @Override
protected void configureFont(JTable table, TableModel model, int column) { protected Font getDefaultFont() {
setFont(getFixedWidthFont()); return fixedWidthFont;
} }
private String formatBytes(Byte[] bytes, Settings settings) { private String formatBytes(Byte[] bytes, Settings settings) {
boolean bigEndian = (EndianSettingsDefinition.DEF boolean bigEndian =
.getChoice(settings) != EndianSettingsDefinition.LITTLE); (EndianSettingsDefinition.DEF.getChoice(settings) != EndianSettingsDefinition.LITTLE);
int startIx = 0; int startIx = 0;
int endIx = bytes.length; int endIx = bytes.length;

View file

@ -34,7 +34,8 @@ import ghidra.app.util.viewer.listingpanel.AddressSetDisplayListener;
import ghidra.framework.options.*; import ghidra.framework.options.*;
import ghidra.framework.plugintool.ComponentProviderAdapter; import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.util.*; import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.classfinder.ClassSearcher; import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.task.SwingUpdateManager; import ghidra.util.task.SwingUpdateManager;
@ -173,7 +174,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
Object newValue) { Object newValue) {
if (options.getName().equals("ByteViewer")) { if (options.getName().equals("ByteViewer")) {
if (optionName.equals(OPTION_FONT)) { if (optionName.equals(OPTION_FONT)) {
setFont(SystemUtilities.adjustForFontSizeOverride((Font) newValue)); setFont((Font) newValue);
} }
} }
else if (options.getName().equals(CATEGORY_BROWSER_FIELDS)) { else if (options.getName().equals(CATEGORY_BROWSER_FIELDS)) {

View file

@ -39,8 +39,7 @@ import docking.widgets.fieldpanel.Layout;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.BackgroundColorModel; import docking.widgets.fieldpanel.support.BackgroundColorModel;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.GColor; import generic.theme.*;
import generic.theme.GIcon;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import generic.theme.GThemeDefaults.Colors.Tooltips; import generic.theme.GThemeDefaults.Colors.Tooltips;
import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel; import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel;
@ -245,8 +244,7 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
tooltipTitleLabel.setHorizontalAlignment(SwingConstants.LEADING); tooltipTitleLabel.setHorizontalAlignment(SwingConstants.LEADING);
tooltipTitleLabel.setBackground(Tooltips.BACKGROUND); tooltipTitleLabel.setBackground(Tooltips.BACKGROUND);
tooltipTitleLabel.setOpaque(true); tooltipTitleLabel.setOpaque(true);
Font labelFont = tooltipTitleLabel.getFont(); Gui.registerFont(tooltipTitleLabel, 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);

View file

@ -15,11 +15,12 @@
*/ */
package ghidra.feature.fid.debug; package ghidra.feature.fid.debug;
import java.awt.BorderLayout; import java.awt.*;
import java.awt.Dimension;
import java.awt.event.*; import java.awt.event.*;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
@ -63,8 +64,13 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
} }
private void buildFrame() { private void buildFrame() {
GTableCellRenderer renderer = new GTableCellRenderer(); GTableCellRenderer renderer = new GTableCellRenderer() {
renderer.setFont(renderer.getFixedWidthFont()); @Override
protected Font getDefaultFont() {
return fixedWidthFont;
}
};
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);
@ -314,7 +320,7 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
} }
@Override @Override
public void fidQueryClosed(FidQueryService service) { public void fidQueryClosed(FidQueryService fqs) {
dispose(); dispose();
} }
} }

View file

@ -133,10 +133,18 @@ icon.task.progress.hourglass.11 = hourglass24_11.png
// Fonts // Fonts
font.splash.header.default = Serif-BOLD-35 font.splash.header.default = serif-bold-35
font.splash.status = Serif-BOLD-12 font.splash.status = serif-bold-12
font.table.header.number = arial-BOLD-12
font.input.hint = monospaced-PLAIN-10 // default table renderer uses the JLabel font, which is mapped to system.font.control
font.table.base = [font]system.font.control
font.table.header.number = arial-bold-12
font.input.hint = monospaced-plain-10
font.task.monitor.label.message = sansserif-plain-10
font.wizard.border.title = sansserif-plain-10
@ -144,7 +152,6 @@ font.input.hint = monospaced-PLAIN-10
[Dark Defaults] [Dark Defaults]
color.fg.filterfield = color.palette.darkslategray color.fg.filterfield = color.palette.darkslategray
color.bg.highlight = #703401 // orangish color.bg.highlight = #703401 // orangish

View file

@ -59,9 +59,9 @@
<tocdef id="Root" sortgroup="a" text="Welcome to Help"> <tocdef id="Root" sortgroup="a" text="Welcome to Help">
<tocdef id="Theming" text="Theming" sortgroup="t" target="help/topics/Theming/ThemingOverview.html"> <tocdef id="Theming" text="Theming" sortgroup="t" target="help/topics/Theming/ThemingOverview.html">
<tocdef id="Overview" sortgroup="1" text="Overview" target="help/topics/Theming/ThemingOverview.html"/> <tocdef id="Overview" sortgroup="1" text="Overview" target="help/topics/Theming/ThemingOverview.html"/>
<tocdef id="Editing Themes" sortgroup="2" text="Editing Themes" target="help/topics/Theming/ThemingUserDocs.html"/> <tocdef id="Editing Themes" sortgroup="2" text="User's Guide" target="help/topics/Theming/ThemingUserDocs.html"/>
<tocdef id="Architecture" sortgroup="3" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/> <tocdef id="Developer Documentation" sortgroup="3" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
<tocdef id="Developer Documentation" sortgroup="4" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/> <tocdef id="Architecture" sortgroup="4" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
</tocdef> </tocdef>
</tocdef> </tocdef>
</tocroot> </tocroot>

View file

@ -13,6 +13,14 @@
plugins, actions, scripts, etc., that use colors, fonts, or icons. By following these guidelines, plugins, actions, scripts, etc., that use colors, fonts, or icons. By following these guidelines,
developers can easily make use of Ghidra's theming capabilities.</P> developers can easily make use of Ghidra's theming capabilities.</P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P><IMG border="0" src="help/shared/tip.png" alt="Tip">Most classes referenced in this document
live in the <CODE>generic.theme</CODE> package.
</P>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H2>Theme Resource Types</H2> <H2>Theme Resource Types</H2>
<P>When developing application code for Ghidra such as plugins, actions, etc., developers often <P>When developing application code for Ghidra such as plugins, actions, etc., developers often
@ -122,8 +130,58 @@
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE>Gui.registerFont(myLabel, "font.xyz");</CODE> <CODE>Gui.registerFont(myLabel, "font.xyz");</CODE>
</BLOCKQUOTE>
<H3>Font Usage in Tables, Lists and Custom Painting</H3>
<P>
Ghidra makes great use of tables and to a lesser extent, lists. Both tables and lists
use renderers to paint cell values.
</P>
<UL>
<LI>
Java - By default, Java will use the font of the table/list as the font used during rendering.
</LI>
<LI>
Ghidra Tables - Ghidra does <U>not</U> use the table's font for rendering by default. Instead,
the renderer is initialized with the fonts used by <CODE>JLabel</CODE>, with additional
fonts for bold and monospaced text.
</LI>
<LI>
Ghidra Lists - Ghidra does not currently use custom rendering for lists. Thus, list cell
rendering will make use of the list's font, which is Java's default behavior.
</LI>
</UL>
<P>
We point out this difference between Java and Ghidra here so that developers understand
that changing fonts used for tables differs from Java. Specifically, calling
<BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
<CODE>
table.setFont(newFont);
</CODE>
</PRE>
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>
will not affect the font used when rendering the table. To programmatically change the
fonts used for tables, you can set the font directly on each cell renderer. As with a
any custom fonts used, be sure to define theme properties file and register then with the
Gui class as outlined above.
</P>
<P>
The fonts used for any painting operations, including table and list cell rendering, as well
as any code that overrides <CODE>paint</CODE> will work correctly within the theming
environment as long as the fonts are derived from the default Look and Feel values or are
obtained from the <CODE>Gui</CODE> class. In other words, as long as the
fonts used in custom painting are not hard-coded, any changes to the fonts via the theming
API will appear on the next call to paint the UI.
</P>
</BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>

View file

@ -26,7 +26,9 @@ import docking.action.DockingActionIf;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import docking.widgets.label.GIconLabel; import docking.widgets.label.GIconLabel;
import generic.theme.GAttributes;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import resources.Icons; import resources.Icons;
@ -43,7 +45,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
private KeyEntryTextField keyEntryField; private KeyEntryTextField keyEntryField;
private JTextPane collisionPane; private JTextPane collisionPane;
private StyledDocument doc; private StyledDocument doc;
private SimpleAttributeSet textAttrSet;
private SimpleAttributeSet textAttrs;
private Color bgColor; private Color bgColor;
public KeyEntryDialog(Tool tool, DockingActionIf action) { public KeyEntryDialog(Tool tool, DockingActionIf action) {
@ -172,10 +175,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
} }
private void setUpAttributes() { private void setUpAttributes() {
textAttrSet = new SimpleAttributeSet(); Font font = Gui.getFont("font.standard");
textAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); textAttrs = new GAttributes(font, Messages.NORMAL);
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
textAttrSet.addAttribute(StyleConstants.Foreground, Messages.NORMAL);
} }
private void updateCollisionPane(KeyStroke ks) { private void updateCollisionPane(KeyStroke ks) {
@ -194,7 +195,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
String ksName = KeyBindingUtils.parseKeyStroke(ks); String ksName = KeyBindingUtils.parseKeyStroke(ks);
String text = keyBindings.getActionsForKeyStrokeText(ksName); String text = keyBindings.getActionsForKeyStrokeText(ksName);
try { try {
doc.insertString(0, text, textAttrSet); doc.insertString(0, text, textAttrs);
collisionPane.setCaretPosition(0); collisionPane.setCaretPosition(0);
} }
catch (BadLocationException e) { catch (BadLocationException e) {

View file

@ -26,6 +26,7 @@ import javax.swing.*;
import docking.widgets.combobox.GComboBox; import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.util.Swing; import ghidra.util.Swing;
/** /**
@ -133,7 +134,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
JPanel panel = new JPanel(new GridLayout(2, 1)); JPanel panel = new JPanel(new GridLayout(2, 1));
GDLabel styleLabel = new GDLabel("Styles"); GDLabel styleLabel = new GDLabel("Styles");
styleLabel.setFont(getFont().deriveFont(1)); Gui.registerFont(styleLabel, Font.BOLD);
styleLabel.setHorizontalAlignment(SwingConstants.CENTER); styleLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(styleLabel); panel.add(styleLabel);
@ -150,7 +151,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
JPanel panel = new JPanel(new GridLayout(2, 1)); JPanel panel = new JPanel(new GridLayout(2, 1));
GDLabel sizeLabel = new GDLabel("Sizes"); GDLabel sizeLabel = new GDLabel("Sizes");
sizeLabel.setFont(getFont().deriveFont(1)); Gui.registerFont(sizeLabel, Font.BOLD);
sizeLabel.setHorizontalAlignment(SwingConstants.CENTER); sizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(sizeLabel); panel.add(sizeLabel);
@ -168,7 +169,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
JPanel panel = new JPanel(new GridLayout(2, 1)); JPanel panel = new JPanel(new GridLayout(2, 1));
GDLabel fontLabel = new GDLabel("Fonts"); GDLabel fontLabel = new GDLabel("Fonts");
fontLabel.setFont(getFont().deriveFont(1)); Gui.registerFont(fontLabel, Font.BOLD);
fontLabel.setHorizontalAlignment(SwingConstants.CENTER); fontLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(fontLabel); panel.add(fontLabel);

View file

@ -25,22 +25,32 @@ import javax.swing.plaf.basic.BasicHTML;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import docking.widgets.label.GDHtmlLabel; import docking.widgets.label.GDHtmlLabel;
import generic.theme.GColor; import generic.theme.*;
import generic.theme.GColorUIResource;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.GThemeDefaults.Colors.Tables; import generic.theme.GThemeDefaults.Colors.Tables;
import ghidra.util.Msg;
import util.CollectionUtils;
import utilities.util.reflection.ReflectionUtilities;
/** /**
* 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.
* <p> * <p>
* It allows (but default-disables) HTML content, automatically paints alternating row * It allows (but default-disables) HTML content, automatically paints alternating row background
* background colors, and highlights the drop target in a drag-n-drop operation. * colors, and highlights the drop target in a drag-n-drop operation.
* * <p>
* The preferred method to change the font used by this renderer is {@link #setBaseFontId(String)}.
* If you would like this renderer to use a monospaced font, then, as an alternative to creating a
* font ID, you can instead override {@link #getDefaultFont()} to return this
* class's {@link #fixedWidthFont}. Also, the fixed width font of this class is based on the
* default font set when calling {@link #setBaseFontId(String)}, so it stays up-to-date with theme
* changes.
*/ */
public abstract class AbstractGCellRenderer extends GDHtmlLabel { public abstract class AbstractGCellRenderer extends GDHtmlLabel {
private static final Color BACKGROUND_COLOR = new GColor("color.bg.table.row"); private static final Color BACKGROUND_COLOR = new GColor("color.bg.table.row");
private static final Color ALT_BACKGROUND_COLOR = new GColor("color.bg.table.row.alt"); private static final Color ALT_BACKGROUND_COLOR = new GColor("color.bg.table.row.alt");
private static final String BASE_FONT_ID = "font.table.base";
/** Allows the user to disable alternating row colors on JLists and JTables */ /** Allows the user to disable alternating row colors on JLists and JTables */
private static final String DISABLE_ALTERNATING_ROW_COLORS_PROPERTY = private static final String DISABLE_ALTERNATING_ROW_COLORS_PROPERTY =
"disable.alternating.row.colors"; "disable.alternating.row.colors";
@ -61,6 +71,9 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
private boolean instanceAlternateRowColors = true; private boolean instanceAlternateRowColors = true;
public AbstractGCellRenderer() { public AbstractGCellRenderer() {
setBaseFontId(BASE_FONT_ID);
noFocusBorder = BorderFactory.createEmptyBorder(0, 5, 0, 5); noFocusBorder = BorderFactory.createEmptyBorder(0, 5, 0, 5);
Border innerBorder = BorderFactory.createEmptyBorder(0, 4, 0, 4); Border innerBorder = BorderFactory.createEmptyBorder(0, 4, 0, 4);
Border outerBorder = BorderFactory.createLineBorder(Palette.YELLOW, 1); Border outerBorder = BorderFactory.createLineBorder(Palette.YELLOW, 1);
@ -114,34 +127,48 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
return getBackgroundColorForRow(row); return getBackgroundColorForRow(row);
} }
/**
* Sets this renderer's theme font id. This will be used to load the base font and to create
* the derived fonts, such as bold and fixed width.
* @param fontId the font id
* @see Gui#registerFont(Component, String)
*/
public void setBaseFontId(String fontId) {
Font f = Gui.getFont(fontId);
defaultFont = f;
fixedWidthFont = new Font("monospaced", f.getStyle(), f.getSize());
boldFont = f.deriveFont(Font.BOLD);
Gui.registerFont(this, fontId);
}
@Override @Override
public void setFont(Font f) { public void setFont(Font f) {
super.setFont(f); super.setFont(f);
defaultFont = f;
fixedWidthFont = new Font("monospaced", defaultFont.getStyle(), defaultFont.getSize());
boldFont = f.deriveFont(Font.BOLD);
}
protected void superSetFont(Font font) { //
super.setFont(font); // Due to the nature of how setFont() is typically used (external client setup vs internal
} // rendering), we created setBaseFontId() to allow external clients to set the base font in
// a way that is consistent with theming. Ignore any request to use one of our existing
// fonts, as some clients may do that from the getTableCellRendererComponent() method.
//
if (defaultFont != null &&
!CollectionUtils.isOneOf(f, defaultFont, fixedWidthFont, boldFont)) {
// sets the font of this renderer to be bold until the next time that String caller =
// getTableCellRenderer() is called, as it resets the font to the default font on each pass ReflectionUtilities.getClassNameOlderThan(getClass().getName(), "generic.theme");
protected void setBold() { Msg.debug(this, "Calling setFont() on the renderer is discouraged. " +
super.setFont(boldFont); "To change the font, call setBaseFontId(). Called from " + caller);
}
} }
/** /**
* Sets the row where DnD would perform drop operation. * Sets the font of this renderer to be bold until the next time that getTableCellRenderer() is
* @param dropRow the drop row * called, as it resets the font to the default font on each pass.
* @see #getDefaultFont()
*/ */
public void setDropRow(int dropRow) { protected void setBold() {
this.dropRow = dropRow; super.setFont(boldFont);
}
protected Border getNoFocusBorder() {
return noFocusBorder;
} }
protected Font getDefaultFont() { protected Font getDefaultFont() {
@ -156,6 +183,18 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
return boldFont; return boldFont;
} }
/**
* Sets the row where DnD would perform drop operation.
* @param dropRow the drop row
*/
public void setDropRow(int dropRow) {
this.dropRow = dropRow;
}
protected Border getNoFocusBorder() {
return noFocusBorder;
}
protected Color getDefaultBackgroundColor() { protected Color getDefaultBackgroundColor() {
return BACKGROUND_COLOR; return BACKGROUND_COLOR;
} }

View file

@ -72,7 +72,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
new DropDownWindowVisibilityListener<>(); new DropDownWindowVisibilityListener<>();
private GDHtmlLabel previewLabel; private GDHtmlLabel previewLabel;
protected GList<T> list = new GList<>(); protected DropDownList list = new DropDownList();
private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners = private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners =
WeakDataStructureFactory.createSingleThreadAccessWeakSet(); WeakDataStructureFactory.createSingleThreadAccessWeakSet();
private Collection<CellEditorListener> cellEditorListeners = new HashSet<>(); private Collection<CellEditorListener> cellEditorListeners = new HashSet<>();
@ -82,7 +83,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
private WindowComponentListener parentWindowListener = new WindowComponentListener(); private WindowComponentListener parentWindowListener = new WindowComponentListener();
private T selectedValue; private T selectedValue;
private int cellHeight;
private int matchingWindowHeight = MIN_HEIGHT; private int matchingWindowHeight = MIN_HEIGHT;
private Point lastLocation; private Point lastLocation;
protected final DropDownTextFieldDataModel<T> dataModel; protected final DropDownTextFieldDataModel<T> dataModel;
@ -278,15 +278,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
private void initDataList() { private void initDataList() {
Font font = list.getFont();
FontMetrics fontMetrics = list.getFontMetrics(font);
int padding = 2; // top and bottom border height
int lineHeight = fontMetrics.getHeight() + padding;
int iconAndPaddingHeight = 16 + padding;
cellHeight = Math.max(lineHeight, iconAndPaddingHeight);
list.setFixedCellHeight(cellHeight);
list.setFixedCellWidth(MIN_WIDTH - 20); // add some fudge for scrollbars
list.setCellRenderer(dataModel.getListRenderer()); list.setCellRenderer(dataModel.getListRenderer());
list.addKeyListener(keyListener); list.addKeyListener(keyListener);
@ -654,7 +645,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
* 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.
*/ */
@SuppressWarnings("unchecked") // for the cast to T @SuppressWarnings("unchecked") // the item better be our type
private void setTextFromListOnEnterPress() { private void setTextFromListOnEnterPress() {
Object selectedItem = list.getSelectedValue(); Object selectedItem = list.getSelectedValue();
if (selectedItem == null) { if (selectedItem == null) {
@ -747,6 +738,30 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
// Inner Classes // Inner Classes
//================================================================================================= //=================================================================================================
protected class DropDownList extends GList<T> {
@Override
public void setFont(Font f) {
super.setFont(f);
updateCellDimensions(f);
}
private void updateCellDimensions(Font font) {
if (font == null || list == null) {
return; // UI is initializing
}
FontMetrics fontMetrics = list.getFontMetrics(font);
int padding = 2; // top and bottom border height
int lineHeight = fontMetrics.getHeight() + padding;
int iconAndPaddingHeight = 16 + padding;
int cellHeight = Math.max(lineHeight, iconAndPaddingHeight);
list.setFixedCellHeight(cellHeight);
list.setFixedCellWidth(MIN_WIDTH - 20); // add some fudge for scrollbars
}
}
private class HideWindowFocusListener extends FocusAdapter { private class HideWindowFocusListener extends FocusAdapter {
@Override @Override
public void focusLost(FocusEvent event) { public void focusLost(FocusEvent event) {

View file

@ -15,7 +15,8 @@
*/ */
package docking.widgets.dialogs; package docking.widgets.dialogs;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
@ -26,6 +27,7 @@ import docking.DockingUtils;
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.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.framework.OperatingSystem; import ghidra.framework.OperatingSystem;
import ghidra.framework.Platform; import ghidra.framework.Platform;
@ -34,6 +36,8 @@ public class MultiLineInputDialog extends DialogComponentProvider {
private static final KeyStroke SUBMIT_KEYSTROKE = private static final KeyStroke SUBMIT_KEYSTROKE =
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, DockingUtils.CONTROL_KEY_MODIFIER_MASK); KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
private static final String FONT_ID = "font.input.hint";
private boolean isCanceled; private boolean isCanceled;
private JTextArea inputTextArea; private JTextArea inputTextArea;
@ -84,10 +88,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
} }
JLabel hintLabel = new GLabel("(" + metaKeyText + "-Enter to accept)"); JLabel hintLabel = new GLabel("(" + metaKeyText + "-Enter to accept)");
hintLabel.setHorizontalAlignment(SwingConstants.CENTER); hintLabel.setHorizontalAlignment(SwingConstants.CENTER);
Font font = hintLabel.getFont(); Gui.registerFont(hintLabel, FONT_ID);
Font smallerFont = font.deriveFont(12F);
Font smallItalicFont = smallerFont.deriveFont(Font.ITALIC);
hintLabel.setFont(smallItalicFont);
hintLabel.setForeground(Messages.HINT); hintLabel.setForeground(Messages.HINT);
dataPanel.add(messageLabel, BorderLayout.NORTH); dataPanel.add(messageLabel, BorderLayout.NORTH);

View file

@ -52,36 +52,51 @@ class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryMod
* *
* @param chooser the {@link GhidraFileChooser} this instance is nested in * @param chooser the {@link GhidraFileChooser} this instance is nested in
* @param model the {@link DirectoryListModel} * @param model the {@link DirectoryListModel}
* @param font the parent component's font, used to calculate row height in the list once
*/ */
DirectoryList(GhidraFileChooser chooser, DirectoryListModel model, Font font) { DirectoryList(GhidraFileChooser chooser, DirectoryListModel model) {
super(model); super(model);
this.chooser = chooser; this.chooser = chooser;
this.model = model; this.model = model;
build(font); build();
} }
private void build(Font font) { @Override
public void setFont(Font font) {
super.setFont(font);
updateCellDimensions(font);
}
private void updateCellDimensions(Font font) {
if (font == null) {
return; // UI is being updated
}
FileListCellRenderer cellRenderer = (FileListCellRenderer) getCellRenderer();
if (cellRenderer == null) {
return; // initializing
}
// Enable the list to calculate the width of the cells on its own, but manually specify the
// height to ensure some padding between rows.
//
// Use 1/3 of the line height of the font to ensure visually consistent padding between
// rows. (Historically, 5px was used as the padding between the default 12pt (15px line
// height) rows, so 15px line height/5px padding equals .333 ratio.)
FontMetrics metrics = cellRenderer.getFontMetrics(font);
setFixedCellHeight(Math.max(metrics.getHeight(), DEFAULT_ICON_SIZE) +
Math.max(metrics.getHeight() / 3, MIN_HEIGHT_PADDING));
setFixedCellWidth(-1);
}
private void build() {
setLayoutOrientation(JList.VERTICAL_WRAP); setLayoutOrientation(JList.VERTICAL_WRAP);
FileListCellRenderer cellRenderer = new FileListCellRenderer(chooser); FileListCellRenderer cellRenderer = new FileListCellRenderer(chooser);
setCellRenderer(cellRenderer); setCellRenderer(cellRenderer);
// Enable the list to calculate the width of the cells on its own, but manually updateCellDimensions(getFont());
// specify the height to ensure some padding between rows.
// We need the parent component's Font instead of using our
// own #getFont() because we are not a child of the parent yet and
// the font may be set to something other than the default.
// Use 1/3 of the line height of the font to ensure visually consistent
// padding between rows. (historically, 5px was used as the padding
// between the default 12pt (15px lineht) rows, so 15px lineht/5px padding
// equals .333 ratio.)
FontMetrics metrics = cellRenderer.getFontMetrics(font);
setFixedCellHeight(
Math.max(metrics.getHeight(), DEFAULT_ICON_SIZE) +
Math.max(metrics.getHeight() / 3, MIN_HEIGHT_PADDING));
setFixedCellWidth(-1);
addMouseListener(new GMouseListenerAdapter() { addMouseListener(new GMouseListenerAdapter() {
@Override @Override

View file

@ -558,7 +558,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
private JScrollPane buildDirectoryList() { private JScrollPane buildDirectoryList() {
directoryListModel = new DirectoryListModel(); directoryListModel = new DirectoryListModel();
directoryList = new DirectoryList(this, directoryListModel, rootPanel.getFont()); directoryList = new DirectoryList(this, directoryListModel);
directoryList.setName("LIST"); directoryList.setName("LIST");
directoryList.setBackground(BACKGROUND_COLOR); directoryList.setBackground(BACKGROUND_COLOR);

View file

@ -54,15 +54,14 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
* The map uses thread local variables to ensure that rendering and background model * The map uses thread local variables to ensure that rendering and background model
* manipulation are thread safe. * manipulation are thread safe.
*/ */
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache = private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache = new HashMap<>();
new HashMap<>();
static { static {
int n = FloatingPointPrecisionSettingsDefinition.MAX_PRECISION; int n = FloatingPointPrecisionSettingsDefinition.MAX_PRECISION;
for (int i = 0; i <= n; i++) { for (int i = 0; i <= n; i++) {
int precision = i; int precision = i;
ThreadLocal<DecimalFormat> localFormatter = ThreadLocal.withInitial( ThreadLocal<DecimalFormat> localFormatter =
() -> new DecimalFormat(createDecimalFormat(precision))); ThreadLocal.withInitial(() -> new DecimalFormat(createDecimalFormat(precision)));
decimalFormatCache.put(precision, localFormatter); decimalFormatCache.put(precision, localFormatter);
} }
} }
@ -158,7 +157,6 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
Object value = data.getValue(); Object value = data.getValue();
JTable table = data.getTable(); JTable table = data.getTable();
int row = data.getRowViewIndex(); int row = data.getRowViewIndex();
int column = data.getColumnViewIndex();
boolean isSelected = data.isSelected(); boolean isSelected = data.isSelected();
boolean hasFocus = data.hasFocus(); boolean hasFocus = data.hasFocus();
Settings settings = data.getColumnSettings(); Settings settings = data.getColumnSettings();
@ -173,7 +171,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
} }
TableModel model = table.getModel(); TableModel model = table.getModel();
configureFont(table, model, column); setFont(getDefaultFont());
if (isSelected) { if (isSelected) {
setForeground(table.getSelectionForeground()); setForeground(table.getSelectionForeground());
@ -199,8 +197,14 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
setForeground(table.getForeground()); setForeground(table.getForeground());
} }
protected void configureFont(JTable table, TableModel model, int column) { /**
setFont(defaultFont); * Override to change the font that will be used each time the renderer is initialized inside
* of {@link #getTableCellRendererComponent(GTableCellRenderingData)}
* @return the font
*/
@Override
protected Font getDefaultFont() {
return defaultFont;
} }
protected int getRadix(Settings settings) { protected int getRadix(Settings settings) {

View file

@ -78,7 +78,6 @@ public class HintTextField extends JTextField {
this.verifier = verifier; this.verifier = verifier;
addListeners(); addListeners();
setFont(getFont().deriveFont(Font.PLAIN));
validateField(); validateField();
} }

View file

@ -28,6 +28,7 @@ import docking.ReusableDialogComponentProvider;
import docking.widgets.EmptyBorderButton; import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.util.*; import ghidra.util.*;
import help.Help; import help.Help;
import help.HelpService; import help.HelpService;
@ -47,6 +48,8 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
private final static String INIT_TITLE = "<< untitled >>"; private final static String INIT_TITLE = "<< untitled >>";
private static final String FONT_ID = "font.wizard.border.title";
private PanelManager panelMgr; private PanelManager panelMgr;
private WizardPanel currWizPanel; private WizardPanel currWizPanel;
private JButton backButton; private JButton backButton;
@ -220,8 +223,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
titleLabel = (wizardIcon == null ? new GDLabel(INIT_TITLE) titleLabel = (wizardIcon == null ? new GDLabel(INIT_TITLE)
: new GDLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING)); : new GDLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING));
EmptyBorderButton helpButton = EmptyBorderButton helpButton = new EmptyBorderButton(Icons.INFO_ICON);
new EmptyBorderButton(Icons.INFO_ICON);
helpButton.setToolTipText("Help (F1)"); helpButton.setToolTipText("Help (F1)");
helpButton.addActionListener( helpButton.addActionListener(
e -> DockingWindowManager.getHelpService().showHelp(rootPanel, false, rootPanel)); e -> DockingWindowManager.getHelpService().showHelp(rootPanel, false, rootPanel));
@ -465,14 +467,12 @@ if (!visitedMap.containsKey(currWizPanel)) {
if (scrollPane.getVerticalScrollBar().isShowing()) { if (scrollPane.getVerticalScrollBar().isShowing()) {
TitledBorder titledBorder = TitledBorder titledBorder =
new TitledBorder(BorderFactory.createEmptyBorder(), "(scroll for more options)"); new TitledBorder(BorderFactory.createEmptyBorder(), "(scroll for more options)");
Gui.addThemeListener(e -> {
Font font = titledBorder.getTitleFont(); if (e.isFontChanged(FONT_ID)) {
if (font == null) { titledBorder.setTitleFont(Gui.getFont(FONT_ID));
// workaround for bug on Java 7 }
font = titleLabel.getFont(); });
} titledBorder.setTitleFont(Gui.getFont(FONT_ID));
titledBorder.setTitleFont(font.deriveFont(10f));
titledBorder.setTitleColor(Messages.NORMAL); titledBorder.setTitleColor(Messages.NORMAL);
titledBorder.setTitlePosition(TitledBorder.BOTTOM); titledBorder.setTitlePosition(TitledBorder.BOTTOM);
titledBorder.setTitleJustification(TitledBorder.TRAILING); titledBorder.setTitleJustification(TitledBorder.TRAILING);

View file

@ -15,20 +15,14 @@
*/ */
package ghidra.docking.util; package ghidra.docking.util;
import java.awt.Font;
import java.awt.Taskbar; import java.awt.Taskbar;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.*; import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import docking.framework.ApplicationInformationDisplayFactory; import docking.framework.ApplicationInformationDisplayFactory;
import generic.theme.LafType; import generic.theme.LafType;
import generic.theme.ThemeManager; import generic.theme.ThemeManager;
import ghidra.framework.preferences.Preferences;
import ghidra.util.SystemUtilities;
/** /**
* A utility class to manage LookAndFeel (LaF) settings. * A utility class to manage LookAndFeel (LaF) settings.
@ -40,38 +34,12 @@ public class LookAndFeelUtils {
} }
/** /**
* Loads settings from {@link Preferences}. * This method does nothing. This is not handled by the theming system in the look and feel
* manager.
*/ */
@Deprecated(since = "11.1", forRemoval = true)
public static void installGlobalOverrides() { public static void installGlobalOverrides() {
// //
// Users can change this via the SystemUtilities.FONT_SIZE_OVERRIDE_PROPERTY_NAME
// system property.
//
Integer fontOverride = SystemUtilities.getFontSizeOverrideValue();
if (fontOverride != null) {
setGlobalFontSizeOverride(fontOverride);
}
}
/** Allows you to globally set the font size (don't use this method!) */
private static void setGlobalFontSizeOverride(int fontSize) {
UIDefaults defaults = UIManager.getDefaults();
Set<Entry<Object, Object>> set = defaults.entrySet();
Iterator<Entry<Object, Object>> iterator = set.iterator();
while (iterator.hasNext()) {
Entry<Object, Object> entry = iterator.next();
Object key = entry.getKey();
if (key.toString().toLowerCase().indexOf("font") != -1) {
Font currentFont = defaults.getFont(key);
if (currentFont != null) {
Font newFont = currentFont.deriveFont((float) fontSize);
UIManager.put(key, newFont);
}
}
}
} }
public static void performPlatformSpecificFixups() { public static void performPlatformSpecificFixups() {

View file

@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.EmptyBorderButton; import docking.widgets.EmptyBorderButton;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.label.GDHtmlLabel; import docking.widgets.label.GDHtmlLabel;
import generic.theme.Gui;
import ghidra.util.Swing; import ghidra.util.Swing;
import ghidra.util.datastruct.WeakDataStructureFactory; import ghidra.util.datastruct.WeakDataStructureFactory;
import ghidra.util.datastruct.WeakSet; import ghidra.util.datastruct.WeakSet;
@ -43,6 +44,8 @@ import resources.Icons;
*/ */
public class TaskMonitorComponent extends JPanel implements TaskMonitor { public class TaskMonitorComponent extends JPanel implements TaskMonitor {
private static final String MESSAGE_FONT_ID = "font.task.monitor.label.message";
private WeakSet<CancelledListener> listeners = private WeakSet<CancelledListener> listeners =
WeakDataStructureFactory.createCopyOnReadWeakSet(); WeakDataStructureFactory.createCopyOnReadWeakSet();
@ -458,7 +461,7 @@ public class TaskMonitorComponent extends JPanel implements TaskMonitor {
// don't care // don't care
} }
}; };
messageLabel.setFont(messageLabel.getFont().deriveFont((float) 10.0)); Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
Dimension d = messageLabel.getPreferredSize(); Dimension d = messageLabel.getPreferredSize();
d.width = 180; d.width = 180;
messageLabel.setPreferredSize(d); messageLabel.setPreferredSize(d);

View file

@ -35,7 +35,7 @@ public class ReflectionUtilitiesTest {
@Test @Test
public void testGetClassNameAfter_NoClasses() { public void testGetClassNameAfter_NoClasses() {
String caller = ReflectionUtilities.getClassNameOlderThan(); String caller = ReflectionUtilities.getClassNameOlderThan(new String[0]);
assertThat(caller, is(equalTo(ReflectionUtilitiesTest.class.getName()))); assertThat(caller, is(equalTo(ReflectionUtilitiesTest.class.getName())));
} }

View file

@ -23,12 +23,13 @@ color.visualgraph.view.satellite.edge.focused = color.palette.green
color.visualgraph.view.satellite.edge.selected = color.palette.lime color.visualgraph.view.satellite.edge.selected = color.palette.lime
color.visualgraph.view.satellite.edge.hovered = color.palette.lime color.visualgraph.view.satellite.edge.hovered = color.palette.lime
color.graphdisplay.vertex.default = color.palette.green color.graphdisplay.vertex.default = color.palette.green
color.graphdisplay.edge.default = color.palette.green color.graphdisplay.edge.default = color.palette.green
color.graphdisplay.vertex.selected = color.palette.blue color.graphdisplay.vertex.selected = color.palette.blue
color.graphdisplay.edge.selected = color.palette.blue color.graphdisplay.edge.selected = color.palette.blue
font.visualgraph.view.label.message = SansSerif-PLAIN-22 // bigger for legibility in the graph
icon.graph.satellite = network-wireless-16.png icon.graph.satellite = network-wireless-16.png
icon.graph.satellite.large = network-wireless.png icon.graph.satellite.large = network-wireless.png
icon.graph.layout.default = color_swatch.png icon.graph.layout.default = color_swatch.png

View file

@ -27,6 +27,7 @@ import docking.widgets.label.GDLabel;
import edu.uci.ics.jung.visualization.RenderContext; import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.ScalingControl; import edu.uci.ics.jung.visualization.control.ScalingControl;
import generic.theme.Gui;
import ghidra.graph.VisualGraph; import ghidra.graph.VisualGraph;
import ghidra.graph.viewer.event.mouse.VertexTooltipProvider; import ghidra.graph.viewer.event.mouse.VertexTooltipProvider;
import ghidra.graph.viewer.event.mouse.VisualGraphMousePlugin; import ghidra.graph.viewer.event.mouse.VisualGraphMousePlugin;
@ -68,6 +69,8 @@ public class VisualGraphView<V extends VisualVertex,
private static final float ZOOM_OUT_AMOUNT = .9f; private static final float ZOOM_OUT_AMOUNT = .9f;
private static final float ZOOM_IN_AMOUNT = 1.1f; private static final float ZOOM_IN_AMOUNT = 1.1f;
private static final String MESSAGE_FONT_ID = "font.visualgraph.view.label.message";
private JPanel viewPanel; private JPanel viewPanel;
private JPanel viewContentPanel; private JPanel viewContentPanel;
@ -350,8 +353,7 @@ public class VisualGraphView<V extends VisualVertex,
viewContentPanel.removeAll(); viewContentPanel.removeAll();
viewContentPanel.paintImmediately(viewContentPanel.getBounds()); viewContentPanel.paintImmediately(viewContentPanel.getBounds());
JLabel messageLabel = new GDLabel(errorMessage); JLabel messageLabel = new GDLabel(errorMessage);
Font font = messageLabel.getFont(); Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
messageLabel.setFont(font.deriveFont(22f)); // make a bit bigger for readability
messageLabel.setHorizontalAlignment(SwingConstants.CENTER); messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
messageLabel.setFocusable(true); // we have to have something focusable in our provider messageLabel.setFocusable(true); // we have to have something focusable in our provider
viewContentPanel.add(messageLabel, BorderLayout.NORTH); viewContentPanel.add(messageLabel, BorderLayout.NORTH);
@ -517,8 +519,8 @@ public class VisualGraphView<V extends VisualVertex,
} }
public Point translatePointFromVertexToViewSpace(V v, Point p) { public Point translatePointFromVertexToViewSpace(V v, Point p) {
return GraphViewerUtils.translatePointFromVertexRelativeSpaceToViewSpace( return GraphViewerUtils
getPrimaryGraphViewer(), v, p); .translatePointFromVertexRelativeSpaceToViewSpace(getPrimaryGraphViewer(), v, p);
} }
public Rectangle translateRectangleFromVertexToViewSpace(V v, Rectangle r) { public Rectangle translateRectangleFromVertexToViewSpace(V v, Rectangle r) {

View file

@ -34,7 +34,8 @@ color.fg.tree.selected = [color]system.color.fg.selected.view
// Fonts // Fonts
font.standard = [font]system.font.control font.standard = [font]system.font.control
font.monospaced = monospaced-PLAIN-12 font.standard.bold = font.standard[bold]
font.monospaced = monospaced-plain-12
// //

View file

@ -298,6 +298,11 @@ public class ApplicationThemeManager extends ThemeManager {
lookAndFeelManager.registerFont(component, fontId); lookAndFeelManager.registerFont(component, fontId);
} }
@Override
public void registerFont(Component component, String fontId, int fontStyle) {
lookAndFeelManager.registerFont(component, fontId, fontStyle);
}
private void installFlatLookAndFeels() { private void installFlatLookAndFeels() {
UIManager.installLookAndFeel(LafType.FLAT_LIGHT.getName(), FlatLightLaf.class.getName()); UIManager.installLookAndFeel(LafType.FLAT_LIGHT.getName(), FlatLightLaf.class.getName());
UIManager.installLookAndFeel(LafType.FLAT_DARK.getName(), FlatDarkLaf.class.getName()); UIManager.installLookAndFeel(LafType.FLAT_DARK.getName(), FlatDarkLaf.class.getName());

View file

@ -68,7 +68,7 @@ public class FontModifier {
} }
/** /**
* Sets the font stle modifier. This can be called multiple times to bold and italicize. * Sets the font style modifier. This can be called multiple times to bold and italicize.
* @param newStyle the style to use for the font. * @param newStyle the style to use for the font.
*/ */
public void addStyleModifier(int newStyle) { public void addStyleModifier(int newStyle) {

View file

@ -0,0 +1,57 @@
/* ###
* 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 generic.theme;
import java.awt.Font;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import ghidra.util.HTMLUtilities;
/**
* A drop-in replacement for clients using {@link SimpleAttributeSet}s. This class will apply a
* default set of font attributes based on the given font and optional color.
*/
public class GAttributes extends SimpleAttributeSet {
public GAttributes(Font f) {
this(f, null);
}
public GAttributes(Font f, GColor c) {
addAttribute(StyleConstants.FontFamily, f.getFamily());
addAttribute(StyleConstants.FontSize, f.getSize());
addAttribute(StyleConstants.Bold, f.isBold());
addAttribute(StyleConstants.Italic, f.isItalic());
if (c != null) {
addAttribute(StyleConstants.Foreground, c);
}
}
/**
* A convenience method to style the given text in HTML using the font and color attributes
* defined in this attribute set. The text will be HTML escaped.
*
* @param content the content
* @return the styled content
* @see HTMLUtilities#styleText(SimpleAttributeSet, String)
*/
public String toStyledHtml(String content) {
return HTMLUtilities.styleText(this, content);
}
}

View file

@ -17,8 +17,9 @@ package generic.theme;
import java.awt.*; import java.awt.*;
import javax.swing.Icon; import javax.swing.*;
import javax.swing.LookAndFeel;
import ghidra.util.Msg;
/** /**
* Provides a static set of methods for globally managing application themes and their values. * Provides a static set of methods for globally managing application themes and their values.
@ -36,6 +37,8 @@ import javax.swing.LookAndFeel;
* *
*/ */
public class Gui { public class Gui {
private static final String FONT_SUFFIX = ".font";
// Start with an StubThemeManager so that simple tests can operate without having // Start with an StubThemeManager so that simple tests can operate without having
// to initialize the theme system. Applications and integration tests will // to initialize the theme system. Applications and integration tests will
// called ThemeManager.initialize() which will replace this with a fully initialized version. // called ThemeManager.initialize() which will replace this with a fully initialized version.
@ -146,6 +149,9 @@ public class Gui {
/** /**
* 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 updated with the new font.
* <p>
* Calling this method will trigger a call to {@link JComponent#setFont(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
*/ */
@ -153,6 +159,37 @@ public class Gui {
themeManager.registerFont(component, fontId); themeManager.registerFont(component, fontId);
} }
/**
* Registers the given component with the given font style. This method allows clients to not
* define a font id in the theme system, but instead to signal that they want the default font
* for the given component, modified with the given style. As the underlying font is changed,
* the client will be updated with that new font with the given style applied.
* <P>
* Most clients should <b>not</b> be using this method. Instead, use
* {@link #registerFont(JComponent, int)}.
* <P>
* The downside of using this method is that the end user cannot modify the style of the font.
* By using the standard theming mechanism for registering fonts, the end user has full control.
*
* @param component the component to set/update the font
* @param fontStyle the font style, one of Font.BOLD, Font.ITALIC,
*/
public static void registerFont(JComponent component, int fontStyle) {
if (fontStyle == Font.PLAIN) {
Msg.warn(Gui.class,
"Gui.registerFont(Component, int) may only be used for a non-plain font style. " +
"Use registerFont(Component, String) instead.");
return;
}
String id = component.getUIClassID(); // e.g., ButtonUI
String name = id.substring(0, id.length() - 2); // strip off "UI"
String fontId = FontValue.LAF_ID_PREFIX + name + FONT_SUFFIX; // e.g., laf.font.Button.font
themeManager.registerFont(component, fontId, fontStyle);
}
/** /**
* Returns true if the active theme is using dark defaults * Returns true if the active theme is using dark defaults
* @return true if the active theme is using dark defaults * @return true if the active theme is using dark defaults

View file

@ -575,6 +575,21 @@ public abstract class ThemeManager {
// do nothing // do nothing
} }
/**
* 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.
* <p>
* This method is fairly niche and should not be called by most clients. Instead, call
* {@link #registerFont(Component, String)}.
*
* @param component the component to set/update the font
* @param fontId the id of the font to register with the given component
* @param fontStyle the font style
*/
public void registerFont(Component component, String fontId, int fontStyle) {
// do nothing
}
/** /**
* Returns true if the current theme use dark default values. * Returns true if the current theme use dark default values.
* @return true if the current theme use dark default values. * @return true if the current theme use dark default values.

View file

@ -28,7 +28,8 @@ import ghidra.util.datastruct.WeakSet;
* 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 {
private WeakSet<Component> components = WeakDataStructureFactory.createCopyOnReadWeakSet(); private WeakSet<StyledComponent> components =
WeakDataStructureFactory.createCopyOnReadWeakSet();
private String fontId; private String fontId;
/** /**
@ -45,8 +46,18 @@ public class ComponentFontRegistry {
* @param component the component to add * @param component the component to add
*/ */
public void addComponent(Component component) { public void addComponent(Component component) {
component.setFont(Gui.getFont(fontId)); addComponent(component, Font.PLAIN);
components.add(component); }
/**
* Allows clients to update the default font being used for a component to use the given style.
* @param component the component
* @param fontStyle the font style (e.g., {@link Font#BOLD})
*/
public void addComponent(Component component, int fontStyle) {
StyledComponent sc = new StyledComponent(component, fontStyle);
sc.setFont(Gui.getFont(fontId));
components.add(sc);
} }
/** /**
@ -54,10 +65,26 @@ public class ComponentFontRegistry {
*/ */
public void updateComponentFonts() { public void updateComponentFonts() {
Font font = Gui.getFont(fontId); Font font = Gui.getFont(fontId);
for (Component component : components) { for (StyledComponent c : components) {
c.setFont(font);
}
}
private record StyledComponent(Component component, int fontStyle) {
void setFont(Font font) {
Font existingFont = component.getFont(); Font existingFont = component.getFont();
if (!Objects.equals(existingFont, font)) { Font styledFont = font;
component.setFont(font); int style = fontStyle();
if (style != Font.PLAIN) {
// Only style the font when it is not plain. Doing this means that clients cannot
// override a non-plain font to be plain. If clients need that behavior, they must
// create their own custom font id and register their component with Gui.
styledFont = font.deriveFont(style);
}
if (!Objects.equals(existingFont, styledFont)) {
component.setFont(styledFont);
} }
} }
} }

View file

@ -30,6 +30,7 @@ import generic.theme.*;
import generic.util.action.*; import generic.util.action.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import utilities.util.reflection.ReflectionUtilities;
/** /**
* Manages installing and updating a {@link LookAndFeel} * Manages installing and updating a {@link LookAndFeel}
@ -38,6 +39,7 @@ public abstract class LookAndFeelManager {
private LafType laf; private LafType laf;
private Map<String, ComponentFontRegistry> fontRegistryMap = new HashMap<>(); private Map<String, ComponentFontRegistry> fontRegistryMap = new HashMap<>();
private Map<Component, String> componentToIdMap = new WeakHashMap<>();
protected ApplicationThemeManager themeManager; protected ApplicationThemeManager themeManager;
protected Map<String, String> normalizedIdToLafIdMap; protected Map<String, String> normalizedIdToLafIdMap;
@ -202,12 +204,49 @@ public abstract class LookAndFeelManager {
* @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
*/ */
public void registerFont(Component component, String fontId) { public void registerFont(Component component, String fontId) {
checkForAlreadyRegistered(component, fontId);
componentToIdMap.put(component, fontId);
ComponentFontRegistry register = ComponentFontRegistry register =
fontRegistryMap.computeIfAbsent(fontId, id -> new ComponentFontRegistry(id)); fontRegistryMap.computeIfAbsent(fontId, id -> new ComponentFontRegistry(id));
register.addComponent(component); register.addComponent(component);
} }
/**
* Binds the component to the font identified by the given font id. Whenever the font for
* the font id changes, the component will be updated with the new font.
* <p>
* This method is fairly niche and should not be called by most clients. Instead, call
* {@link #registerFont(Component, String)}.
*
* @param component the component to set/update the font
* @param fontId the id of the font to register with the given component
* @param fontStyle the font style
*/
public void registerFont(Component component, String fontId, int fontStyle) {
checkForAlreadyRegistered(component, fontId);
componentToIdMap.put(component, fontId);
ComponentFontRegistry register =
fontRegistryMap.computeIfAbsent(fontId, id -> new ComponentFontRegistry(id));
register.addComponent(component, fontStyle);
}
private void checkForAlreadyRegistered(Component component, String newFontId) {
String existingFontId = componentToIdMap.get(component);
if (existingFontId != null) {
Msg.warn(this, """
Component has a Font ID registered more than once. \
Previously registered ID: '%s'. Newly registered ID: '%s'.
""".formatted(existingFontId, newFontId),
ReflectionUtilities.createJavaFilteredThrowable());
}
}
private Font toUiResource(Font font) { private Font toUiResource(Font font) {
if (!(font instanceof UIResource)) { if (!(font instanceof UIResource)) {
return new FontUIResource(font); return new FontUIResource(font);
@ -292,8 +331,7 @@ public abstract class LookAndFeelManager {
return false; return false;
} }
protected void setKeyBinding(String existingKsText, String newKsText, protected void setKeyBinding(String existingKsText, String newKsText, String[] prefixValues) {
String[] prefixValues) {
KeyStroke existingKs = KeyStroke.getKeyStroke(existingKsText); KeyStroke existingKs = KeyStroke.getKeyStroke(existingKsText);
KeyStroke newKs = KeyStroke.getKeyStroke(newKsText); KeyStroke newKs = KeyStroke.getKeyStroke(newKsText);

View file

@ -22,9 +22,10 @@ import java.util.regex.Pattern;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.plaf.basic.BasicHTML; import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View; import javax.swing.text.*;
import generic.text.TextLayoutGraphics; import generic.text.TextLayoutGraphics;
import generic.theme.GAttributes;
import ghidra.util.html.HtmlLineSplitter; import ghidra.util.html.HtmlLineSplitter;
import utilities.util.reflection.ReflectionUtilities; import utilities.util.reflection.ReflectionUtilities;
@ -343,6 +344,67 @@ public class HTMLUtilities {
return buffy.toString(); return buffy.toString();
} }
/**
* Escapes and wraps the given text in {@code SPAN} tag with font attributes specified in the
* given attributes. Specifically, these attributes are used:
*
* <UL>
* <LI>{@link StyleConstants#Foreground} - {@link Color} object</LI>
* <LI>{@link StyleConstants#FontFamily} - font name</LI>
* <LI>{@link StyleConstants#FontSize} - size in pixels</LI>
* <LI>{@link StyleConstants#Italic} - true if italic</LI>
* <LI>{@link StyleConstants#Bold} - true if bold</LI>
* </UL>
* <P>
* See {@link GAttributes} for a convenient way to create the correct attributes for a font and
* color.
*
* @param attributes the attributes
* @param text the content to style
* @return the styled content
* @see GAttributes
*/
public static String styleText(SimpleAttributeSet attributes, String text) {
// StyleConstants.Foreground color: #00FF00;
// StyleConstants.FontFamily font-family: "Tahoma";
// StyleConstants.FontSize font-size: 40px;
// StyleConstants.Italic font-style: italic;
// StyleConstants.Bold font-weight: bold;
String family = attributes.getAttribute(StyleConstants.FontFamily).toString();
String size = attributes.getAttribute(StyleConstants.FontSize).toString();
String style = "plain";
String weight = "plain";
Boolean isItalic = (Boolean) attributes.getAttribute(StyleConstants.Italic);
Boolean isBold = (Boolean) attributes.getAttribute(StyleConstants.Bold);
if (Boolean.TRUE.equals(isItalic)) {
style = "italic";
}
if (Boolean.TRUE.equals(isBold)) {
weight = "bold";
}
// color is optional and defaults to the containing component's color
String color = "";
Object colorAttribute = attributes.getAttribute(StyleConstants.Foreground);
if (colorAttribute instanceof Color fgColor) {
String hexColor = HTMLUtilities.toHexString(fgColor);
color = "color: % s;".formatted(hexColor);
}
String escaped = escapeHTML(text);
//@formatter:off
return """
<SPAN STYLE=\"%s font-family: '%s'; font-size: %spx; font-style: %s; font-weight: %s;\">\
%s\
</SPAN>
""".formatted(color, family, size, style, weight, escaped);
//@formatter:on
}
/** /**
* Returns the given text wrapped in {@link #LINK_PLACEHOLDER_OPEN} and close tags. * Returns the given text wrapped in {@link #LINK_PLACEHOLDER_OPEN} and close tags.
* If <code>foo</code> is passed for the HTML text, with a content value of <code>123456</code>, then * If <code>foo</code> is passed for the HTML text, with a content value of <code>123456</code>, then
@ -593,7 +655,6 @@ public class HTMLUtilities {
* Calling this twice will result in text being double-escaped, which will not display correctly. * Calling this twice will result in text being double-escaped, which will not display correctly.
* <p> * <p>
* See also <code>StringEscapeUtils#escapeHtml3(String)</code> if you need quote-safe html encoding. * See also <code>StringEscapeUtils#escapeHtml3(String)</code> if you need quote-safe html encoding.
* <p>
* *
* @param text plain-text that might have some characters that should NOT be interpreted as HTML * @param text plain-text that might have some characters that should NOT be interpreted as HTML
* @param makeSpacesNonBreaking true to convert spaces into {@value #HTML_SPACE} * @param makeSpacesNonBreaking true to convert spaces into {@value #HTML_SPACE}

View file

@ -84,8 +84,12 @@ icon.plugin.manager.default = plasma.png
font.help.about = font.monospaced font.help.about = font.monospaced
font.keybindings.status = sansserif-plain-11 font.keybindings.status = sansserif-plain-11
font.task.viewer = sansserif-bold-36 font.task.viewer = sansserif-bold-36
font.user.agreement = sansserif-plain-16 font.task.progress.label.message = sansserif-plain-12
font.user.agreement = sansserif-italic-22
font.panel.details = font.standard
font.panel.details.monospaced = font.monospaced[bold]
font.pluginpanel.name = sansserif-plain-18

View file

@ -15,7 +15,8 @@
*/ */
package ghidra.framework.main; package ghidra.framework.main;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Insets;
import java.io.InputStream; import java.io.InputStream;
import javax.swing.*; import javax.swing.*;
@ -57,11 +58,10 @@ public class UserAgreementDialog extends DialogComponentProvider {
} }
private JComponent buildWorkPanel() { private JComponent buildWorkPanel() {
Font font = Gui.getFont(FONT_ID);
JPanel panel = new JPanel(new BorderLayout()); JPanel panel = new JPanel(new BorderLayout());
JLabel label = new GDLabel("Ghidra User Agreement", SwingConstants.CENTER); JLabel label = new GDLabel("Ghidra User Agreement", SwingConstants.CENTER);
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); label.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
label.setFont(font.deriveFont(Font.ITALIC, 22f)); Gui.registerFont(label, FONT_ID);
panel.add(label, BorderLayout.NORTH); panel.add(label, BorderLayout.NORTH);
panel.setBorder(BorderFactory.createEmptyBorder(10, 40, 40, 40)); panel.setBorder(BorderFactory.createEmptyBorder(10, 40, 40, 40));
JEditorPane editorPane = new JEditorPane(); JEditorPane editorPane = new JEditorPane();

View file

@ -23,6 +23,7 @@ import java.util.List;
import javax.swing.*; import javax.swing.*;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.framework.client.RepositoryAdapter; import ghidra.framework.client.RepositoryAdapter;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.remote.User; import ghidra.framework.remote.User;
@ -82,9 +83,7 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
if (anonymousServerAccessAllowed && origAnonymousAccessEnabled) { if (anonymousServerAccessAllowed && origAnonymousAccessEnabled) {
JLabel anonymousAccessLabel = new GDLabel("Anonymous Read-Only Access Enabled"); JLabel anonymousAccessLabel = new GDLabel("Anonymous Read-Only Access Enabled");
anonymousAccessLabel.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0)); anonymousAccessLabel.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0));
Font f = anonymousAccessLabel.getFont().deriveFont(Font.ITALIC); Gui.registerFont(anonymousAccessLabel, Font.ITALIC);
anonymousAccessLabel.setFont(f);
mainPanel.add(anonymousAccessLabel, BorderLayout.SOUTH); mainPanel.add(anonymousAccessLabel, BorderLayout.SOUTH);
} }

View file

@ -17,79 +17,57 @@ package ghidra.framework.plugintool.dialog;
import static ghidra.util.HTMLUtilities.*; import static ghidra.util.HTMLUtilities.*;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import docking.widgets.label.GDHtmlLabel; import docking.widgets.label.GDHtmlLabel;
import generic.theme.GColor; import generic.theme.*;
import ghidra.util.HTMLUtilities;
/** /**
* Abstract class that defines a panel for displaying name/value pairs with html-formatting. * Abstract class that defines a panel for displaying name/value pairs with html-formatting.
*/ */
public abstract class AbstractDetailsPanel extends JPanel { public abstract class AbstractDetailsPanel extends JPanel {
protected static final String FONT_DEFAULT = "font.panel.details";
protected static final String FONT_MONOSPACED = "font.panel.details.monospaced";
private static final int MIN_WIDTH = 700; private static final int MIN_WIDTH = 700;
protected static final int LEFT_COLUMN_WIDTH = 150; protected static final int LEFT_COLUMN_WIDTH = 150;
protected static final int RIGHT_MARGIN = 30; protected static final int RIGHT_MARGIN = 30;
// Font attributes for the title of each row. // Font attributes for the title of each row.
protected static SimpleAttributeSet titleAttrSet; protected static GAttributes titleAttrs;
protected JLabel textLabel; protected JLabel textLabel;
protected JScrollPane sp; protected JScrollPane sp;
private ThemeListener themeListener = e -> {
if (e.isFontChanged(FONT_DEFAULT) || e.isFontChanged(FONT_MONOSPACED)) {
updateFieldAttributes();
}
};
protected AbstractDetailsPanel() {
createFieldAttributes();
Gui.addThemeListener(themeListener);
}
private void updateFieldAttributes() {
createFieldAttributes();
refresh();
repaint();
}
/** /**
* Sets attributes for the different pieces of information being displayed in this * Sets attributes for the different pieces of information being displayed in this
* panel. * panel.
*/ */
protected abstract void createFieldAttributes(); protected abstract void createFieldAttributes();
/** protected abstract void refresh();
* Returns a new {@link SimpleAttributeSet} with all attributes set by the caller.
*
* @param fontFamily the font to use
* @param fontSize the font size
* @param bold if true, render text bold
* @param color the foreground text color
* @return a new attribute set
*/
protected SimpleAttributeSet createAttributeSet(String fontFamily, int fontSize, boolean bold,
Color color) {
SimpleAttributeSet attrSet = new SimpleAttributeSet();
attrSet.addAttribute(StyleConstants.FontFamily, fontFamily);
attrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(fontSize));
attrSet.addAttribute(StyleConstants.Bold, bold);
attrSet.addAttribute(StyleConstants.Foreground, color);
return attrSet;
}
/**
* Returns a new {@link SimpleAttributeSet} with the following default attributes set:
* <ul>
* <li>FontFamily: "Tahoma"</li>
* <li>FontSize: 11</li>
* <li>Bold: True</li>
* </ul>
*
* @param color the foreground text color
* @return a new attribute set
*/
protected SimpleAttributeSet createAttributeSet(Color color) {
SimpleAttributeSet attrSet = new SimpleAttributeSet();
attrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
attrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
attrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
attrSet.addAttribute(StyleConstants.Foreground, color);
return attrSet;
}
/** /**
* Clears the text in the details pane. * Clears the text in the details pane.
@ -134,7 +112,7 @@ public abstract class AbstractDetailsPanel extends JPanel {
protected void insertRowTitle(StringBuilder buffer, String rowName) { protected void insertRowTitle(StringBuilder buffer, String rowName) {
buffer.append("<TR>"); buffer.append("<TR>");
buffer.append("<TD VALIGN=\"TOP\">"); buffer.append("<TD VALIGN=\"TOP\">");
insertHTMLLine(buffer, rowName + ":", titleAttrSet); insertHTMLLine(buffer, rowName + ":", titleAttrs);
buffer.append("</TD>"); buffer.append("</TD>");
} }
@ -146,8 +124,7 @@ public abstract class AbstractDetailsPanel extends JPanel {
* @param value the text to add * @param value the text to add
* @param attributes the structure containing formatting information * @param attributes the structure containing formatting information
*/ */
protected void insertRowValue(StringBuilder buffer, String value, protected void insertRowValue(StringBuilder buffer, String value, GAttributes attributes) {
SimpleAttributeSet attributes) {
buffer.append("<TD VALIGN=\"TOP\" WIDTH=\"80%\">"); buffer.append("<TD VALIGN=\"TOP\" WIDTH=\"80%\">");
insertHTMLLine(buffer, value, attributes); insertHTMLLine(buffer, value, attributes);
buffer.append("</TD>"); buffer.append("</TD>");
@ -161,33 +138,13 @@ public abstract class AbstractDetailsPanel extends JPanel {
* @param string the string to add * @param string the string to add
* @param attributes the formatting instructions * @param attributes the formatting instructions
*/ */
protected void insertHTMLString(StringBuilder buffer, String string, protected void insertHTMLString(StringBuilder buffer, String string, GAttributes attributes) {
SimpleAttributeSet attributes) {
if (string == null) { if (string == null) {
return; return;
} }
buffer.append("<FONT COLOR=\""); buffer.append(attributes.toStyledHtml(string));
Color foregroundColor = (Color) attributes.getAttribute(StyleConstants.Foreground);
buffer.append(HTMLUtilities.toHexString(foregroundColor));
buffer.append("\" FACE=\"");
buffer.append(attributes.getAttribute(StyleConstants.FontFamily).toString());
buffer.append("\">");
Boolean isBold = (Boolean) attributes.getAttribute(StyleConstants.Bold);
isBold = (isBold == null) ? Boolean.FALSE : isBold;
String text = HTMLUtilities.escapeHTML(string);
if (isBold) {
text = HTMLUtilities.bold(text);
}
buffer.append(text);
buffer.append("</FONT>");
} }
/** /**
@ -196,8 +153,7 @@ public abstract class AbstractDetailsPanel extends JPanel {
* @param string the string to insert * @param string the string to insert
* @param attributes the attributes to apply * @param attributes the attributes to apply
*/ */
protected void insertHTMLLine(StringBuilder buffer, String string, protected void insertHTMLLine(StringBuilder buffer, String string, GAttributes attributes) {
SimpleAttributeSet attributes) {
if (string == null) { if (string == null) {
return; return;
} }

View file

@ -15,17 +15,16 @@
*/ */
package ghidra.framework.plugintool.dialog; package ghidra.framework.plugintool.dialog;
import java.awt.Font;
import java.awt.Point; import java.awt.Point;
import java.util.*; import java.util.*;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.action.MenuData; import docking.action.MenuData;
import docking.actions.KeyBindingUtils; import docking.actions.KeyBindingUtils;
import generic.theme.GColor; import generic.theme.*;
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.PluginDescription; import ghidra.framework.plugintool.util.PluginDescription;
@ -37,29 +36,52 @@ import ghidra.util.HTMLUtilities;
*/ */
class PluginDetailsPanel extends AbstractDetailsPanel { class PluginDetailsPanel extends AbstractDetailsPanel {
private SimpleAttributeSet nameAttrSet; private static final GColor NO_VALUE_COLOR = new GColor("color.fg.pluginpanel.details.novalue");
private SimpleAttributeSet depNameAttrSet; private static final GColor DEPENDENCY_COLOR =
private SimpleAttributeSet descrAttrSet; new GColor("color.fg.pluginpanel.details.dependency");
private SimpleAttributeSet categoriesAttrSet; private static final GColor LOCATION_COLOR = new GColor("color.fg.pluginpanel.details.loc");
private SimpleAttributeSet classAttrSet; private static final GColor DEVELOPER_COLOR =
private SimpleAttributeSet locAttrSet; new GColor("color.fg.pluginpanel.details.developer");
private SimpleAttributeSet developerAttrSet; private static final GColor CLASS_COLOR = new GColor("color.fg.pluginpanel.details.class");
private SimpleAttributeSet dependencyAttrSet; private static final GColor CATEGORIES_COLOR =
private SimpleAttributeSet noValueAttrSet; new GColor("color.fg.pluginpanel.details.category");
private static final GColor TITLE_COLOR = new GColor("color.fg.pluginpanel.details.title");
private static final GColor DESCRIPTION_COLOR =
new GColor("color.fg.pluginpanel.details.description");
private static final GColor NAME_NO_DEPENDENTS_COLOR =
new GColor("color.fg.pluginpanel.details.name.no.dependents");
private static final GColor NAME_DEPENDENTS_COLOR =
new GColor("color.fg.pluginpanel.details.name.has.dependents");
private GAttributes nameAttrs;
private GAttributes dependenciesNameAttrs;
private GAttributes descriptionAttrs;
private GAttributes categoriesAttrs;
private GAttributes classAttrs;
private GAttributes locationAttrs;
private GAttributes developerAttrs;
private GAttributes dependencyAttrs;
private GAttributes noValueAttrs;
private final PluginConfigurationModel model; private final PluginConfigurationModel model;
private PluginTool tool; private PluginTool tool;
private PluginDescription currentDescriptor;
PluginDetailsPanel(PluginTool tool, PluginConfigurationModel model) { PluginDetailsPanel(PluginTool tool, PluginConfigurationModel model) {
super();
this.tool = tool; this.tool = tool;
this.model = model; this.model = model;
createFieldAttributes(); createFieldAttributes();
createMainPanel(); createMainPanel();
} }
@Override
protected void refresh() {
setPluginDescription(currentDescriptor);
}
void setPluginDescription(PluginDescription descriptor) { void setPluginDescription(PluginDescription descriptor) {
this.currentDescriptor = descriptor;
textLabel.setText(""); textLabel.setText("");
if (descriptor == null) { if (descriptor == null) {
return; return;
@ -74,43 +96,43 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
insertRowTitle(buffer, "Name"); insertRowTitle(buffer, "Name");
insertRowValue(buffer, descriptor.getName(), insertRowValue(buffer, descriptor.getName(),
!dependencies.isEmpty() ? depNameAttrSet : nameAttrSet); !dependencies.isEmpty() ? dependenciesNameAttrs : nameAttrs);
insertRowTitle(buffer, "Description"); insertRowTitle(buffer, "Description");
insertRowValue(buffer, descriptor.getDescription(), descrAttrSet); insertRowValue(buffer, descriptor.getDescription(), descriptionAttrs);
insertRowTitle(buffer, "Status"); insertRowTitle(buffer, "Status");
insertRowValue(buffer, descriptor.getStatus().getDescription(), insertRowValue(buffer, descriptor.getStatus().getDescription(),
(descriptor.getStatus() == PluginStatus.RELEASED) ? titleAttrSet : developerAttrSet); (descriptor.getStatus() == PluginStatus.RELEASED) ? titleAttrs : developerAttrs);
insertRowTitle(buffer, "Package"); insertRowTitle(buffer, "Package");
insertRowValue(buffer, descriptor.getPluginPackage().getName(), categoriesAttrSet); insertRowValue(buffer, descriptor.getPluginPackage().getName(), categoriesAttrs);
insertRowTitle(buffer, "Category"); insertRowTitle(buffer, "Category");
insertRowValue(buffer, descriptor.getCategory(), categoriesAttrSet); insertRowValue(buffer, descriptor.getCategory(), categoriesAttrs);
insertRowTitle(buffer, "Plugin Class"); insertRowTitle(buffer, "Plugin Class");
insertRowValue(buffer, descriptor.getPluginClass().getName(), classAttrSet); insertRowValue(buffer, descriptor.getPluginClass().getName(), classAttrs);
insertRowTitle(buffer, "Class Location"); insertRowTitle(buffer, "Class Location");
insertRowValue(buffer, descriptor.getSourceLocation(), locAttrSet); insertRowValue(buffer, descriptor.getSourceLocation(), locationAttrs);
insertRowTitle(buffer, "Used By"); insertRowTitle(buffer, "Used By");
buffer.append("<TD VALIGN=\"TOP\">"); buffer.append("<TD VALIGN=\"TOP\">");
if (dependencies.isEmpty()) { if (dependencies.isEmpty()) {
insertHTMLLine(buffer, "None", noValueAttrSet); insertHTMLLine(buffer, "None", noValueAttrs);
} }
else { else {
for (int i = 0; i < dependencies.size(); i++) { for (int i = 0; i < dependencies.size(); i++) {
insertHTMLString(buffer, dependencies.get(i).getPluginClass().getName(), insertHTMLString(buffer, dependencies.get(i).getPluginClass().getName(),
dependencyAttrSet); dependencyAttrs);
if (i < dependencies.size() - 1) { if (i < dependencies.size() - 1) {
buffer.append(HTMLUtilities.BR); buffer.append(HTMLUtilities.BR);
} }
} }
insertHTMLLine(buffer, "", titleAttrSet); // add a newline insertHTMLLine(buffer, "", titleAttrs); // add a newline
} }
buffer.append("</TD>"); buffer.append("</TD>");
buffer.append("</TR>"); buffer.append("</TR>");
@ -121,16 +143,16 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
List<Class<?>> servicesRequired = descriptor.getServicesRequired(); List<Class<?>> servicesRequired = descriptor.getServicesRequired();
if (servicesRequired.isEmpty()) { if (servicesRequired.isEmpty()) {
insertHTMLLine(buffer, "None", noValueAttrSet); insertHTMLLine(buffer, "None", noValueAttrs);
} }
else { else {
for (int i = 0; i < servicesRequired.size(); i++) { for (int i = 0; i < servicesRequired.size(); i++) {
insertHTMLString(buffer, servicesRequired.get(i).getName(), dependencyAttrSet); insertHTMLString(buffer, servicesRequired.get(i).getName(), dependencyAttrs);
if (i < servicesRequired.size() - 1) { if (i < servicesRequired.size() - 1) {
buffer.append(HTMLUtilities.BR); buffer.append(HTMLUtilities.BR);
} }
} }
insertHTMLLine(buffer, "", titleAttrSet); // add a newline insertHTMLLine(buffer, "", titleAttrs); // add a newline
} }
buffer.append("</TD>"); buffer.append("</TD>");
buffer.append("</TR>"); buffer.append("</TR>");
@ -158,7 +180,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
buffer.append("<TR>"); buffer.append("<TR>");
buffer.append("<TD VALIGN=\"TOP\">"); buffer.append("<TD VALIGN=\"TOP\">");
insertHTMLLine(buffer, "Loaded Actions:", titleAttrSet); insertHTMLLine(buffer, "Loaded Actions:", titleAttrs);
buffer.append("</TD>"); buffer.append("</TD>");
Set<DockingActionIf> actions = Collections.emptySet(); Set<DockingActionIf> actions = Collections.emptySet();
@ -169,7 +191,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
if (actions.isEmpty()) { if (actions.isEmpty()) {
buffer.append("<TD VALIGN=\"TOP\">"); buffer.append("<TD VALIGN=\"TOP\">");
insertHTMLLine(buffer, "No actions for plugin", noValueAttrSet); insertHTMLLine(buffer, "No actions for plugin", noValueAttrs);
buffer.append("</TD>"); buffer.append("</TD>");
buffer.append("</TR>"); buffer.append("</TR>");
return; return;
@ -182,7 +204,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
for (DockingActionIf dockableAction : actions) { for (DockingActionIf dockableAction : actions) {
buffer.append("<TR><TD WIDTH=\"200\">"); buffer.append("<TR><TD WIDTH=\"200\">");
insertHTMLString(buffer, dockableAction.getName(), locAttrSet); insertHTMLString(buffer, dockableAction.getName(), locationAttrs);
buffer.append("</TD>"); buffer.append("</TD>");
buffer.append("<TD WIDTH=\"300\">"); buffer.append("<TD WIDTH=\"300\">");
@ -190,17 +212,17 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
String[] menuPath = menuBarData == null ? null : menuBarData.getMenuPath(); String[] menuPath = menuBarData == null ? null : menuBarData.getMenuPath();
String menuPathString = createStringForMenuPath(menuPath); String menuPathString = createStringForMenuPath(menuPath);
if (menuPathString != null) { if (menuPathString != null) {
insertHTMLString(buffer, menuPathString, locAttrSet); insertHTMLString(buffer, menuPathString, locationAttrs);
} }
else { else {
MenuData popupMenuData = dockableAction.getPopupMenuData(); MenuData popupMenuData = dockableAction.getPopupMenuData();
String[] popupPath = popupMenuData == null ? null : popupMenuData.getMenuPath(); String[] popupPath = popupMenuData == null ? null : popupMenuData.getMenuPath();
if (popupPath != null) { if (popupPath != null) {
insertHTMLString(buffer, "(in a context popup menu)", noValueAttrSet); insertHTMLString(buffer, "(in a context popup menu)", noValueAttrs);
} }
else { else {
insertHTMLString(buffer, "Not in a menu", noValueAttrSet); insertHTMLString(buffer, "Not in a menu", noValueAttrs);
} }
} }
@ -210,10 +232,10 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
KeyStroke keyBinding = dockableAction.getKeyBinding(); KeyStroke keyBinding = dockableAction.getKeyBinding();
if (keyBinding != null) { if (keyBinding != null) {
String keyStrokeString = KeyBindingUtils.parseKeyStroke(keyBinding); String keyStrokeString = KeyBindingUtils.parseKeyStroke(keyBinding);
insertHTMLString(buffer, keyStrokeString, locAttrSet); insertHTMLString(buffer, keyStrokeString, locationAttrs);
} }
else { else {
insertHTMLString(buffer, "No keybinding", noValueAttrSet); insertHTMLString(buffer, "No keybinding", noValueAttrs);
} }
buffer.append("</TD></TR>"); buffer.append("</TD></TR>");
@ -242,74 +264,19 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
@Override @Override
protected void createFieldAttributes() { protected void createFieldAttributes() {
titleAttrSet = new SimpleAttributeSet(); Font font = Gui.getFont(FONT_DEFAULT);
titleAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); titleAttrs = new GAttributes(font, TITLE_COLOR);
titleAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11)); nameAttrs = new GAttributes(font, NAME_NO_DEPENDENTS_COLOR);
titleAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE); dependenciesNameAttrs = new GAttributes(font, NAME_DEPENDENTS_COLOR);
titleAttrSet.addAttribute(StyleConstants.Foreground, descriptionAttrs = new GAttributes(font, DESCRIPTION_COLOR);
new GColor("color.fg.pluginpanel.details.title")); categoriesAttrs = new GAttributes(font, CATEGORIES_COLOR);
locationAttrs = new GAttributes(font, LOCATION_COLOR);
developerAttrs = new GAttributes(font, DEVELOPER_COLOR);
nameAttrSet = new SimpleAttributeSet(); Font fontMonospaced = Gui.getFont(FONT_MONOSPACED);
nameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma"); classAttrs = new GAttributes(fontMonospaced, CLASS_COLOR);
nameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11)); dependencyAttrs = new GAttributes(fontMonospaced, DEPENDENCY_COLOR);
nameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
nameAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.name.no.dependents"));
depNameAttrSet = new SimpleAttributeSet(); noValueAttrs = new GAttributes(font, NO_VALUE_COLOR);
depNameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
depNameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
depNameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
depNameAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.name.has.dependents"));
descrAttrSet = new SimpleAttributeSet();
descrAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
descrAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
descrAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
descrAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.description"));
categoriesAttrSet = new SimpleAttributeSet();
categoriesAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
categoriesAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
categoriesAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
categoriesAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.category"));
classAttrSet = new SimpleAttributeSet();
classAttrSet.addAttribute(StyleConstants.FontFamily, "monospaced");
classAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
classAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
classAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.class"));
locAttrSet = new SimpleAttributeSet();
locAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
locAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
locAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
locAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.loc"));
developerAttrSet = new SimpleAttributeSet();
developerAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
developerAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
developerAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
developerAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.developer"));
dependencyAttrSet = new SimpleAttributeSet();
dependencyAttrSet.addAttribute(StyleConstants.FontFamily, "monospaced");
dependencyAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
dependencyAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
dependencyAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.dependency"));
noValueAttrSet = new SimpleAttributeSet();
noValueAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
noValueAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
noValueAttrSet.addAttribute(StyleConstants.Italic, Boolean.TRUE);
noValueAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.novalue"));
} }
} }

View file

@ -15,11 +15,14 @@
*/ */
package ghidra.framework.plugintool.dialog; package ghidra.framework.plugintool.dialog;
import static ghidra.framework.plugintool.dialog.PluginInstallerTableModel.*;
import java.awt.*; import java.awt.*;
import java.util.List; import java.util.List;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import docking.DialogComponentProvider; import docking.DialogComponentProvider;
import docking.widgets.table.*; import docking.widgets.table.*;
@ -149,30 +152,23 @@ public class PluginInstallerDialog extends DialogComponentProvider {
tableFilterPanel = new GTableFilterPanel<>(table, tableModel); tableFilterPanel = new GTableFilterPanel<>(table, tableModel);
JScrollPane sp = new JScrollPane(table); JScrollPane sp = new JScrollPane(table);
pluginTablePanel.add(sp, BorderLayout.CENTER); pluginTablePanel.add(sp, BorderLayout.CENTER);
pluginTablePanel.add(tableFilterPanel, BorderLayout.SOUTH); pluginTablePanel.add(tableFilterPanel, BorderLayout.SOUTH);
// Restrict the size of the first couple columns - the default size is // Restrict the size of the first couple columns - the default size is
// way too large. This is annoying but our table column classes don't have a nice // way too large. This is annoying but our table column classes don't have a nice
// way to restrict column width. // way to restrict column width.
TableColumn inst_col = TableColumnModel columnModel = table.getColumnModel();
table.getColumnModel().getColumn(PluginInstallerTableModel.INSTALLED_COL); TableColumn installedColumn = columnModel.getColumn(INSTALLED_COL);
inst_col.setMaxWidth(30); installedColumn.setMaxWidth(30);
TableColumn status_col = TableColumn statusColumn = columnModel.getColumn(STATUS_COL);
table.getColumnModel().getColumn(PluginInstallerTableModel.STATUS_COL); statusColumn.setMaxWidth(24);
status_col.setMaxWidth(24);
tableModel.setTableSortState( tableModel.setTableSortState(TableSortState.createDefaultSortState(NAME_COL));
TableSortState.createDefaultSortState(PluginInstallerTableModel.NAME_COL));
tableModel.refresh(); tableModel.refresh();
table.getColumnModel() columnModel.getColumn(NAME_COL).setCellRenderer(new NameCellRenderer());
.getColumn(PluginInstallerTableModel.NAME_COL) columnModel.getColumn(STATUS_COL).setCellRenderer(new StatusCellRenderer());
.setCellRenderer(new NameCellRenderer());
table.getColumnModel()
.getColumn(PluginInstallerTableModel.STATUS_COL)
.setCellRenderer(new StatusCellRenderer());
HelpService help = Help.getHelpService(); HelpService help = Help.getHelpService();
help.registerHelp(table, new HelpLocation(GenericHelpTopics.TOOL, "PluginDialog")); help.registerHelp(table, new HelpLocation(GenericHelpTopics.TOOL, "PluginDialog"));
@ -214,10 +210,10 @@ public class PluginInstallerDialog extends DialogComponentProvider {
renderer.setIcon((value instanceof Icon) ? (Icon) value : null); renderer.setIcon((value instanceof Icon) ? (Icon) value : null);
String toolTipText = ""; String toolTipText = "";
if (value == PluginInstallerTableModel.EXPERIMENTAL_ICON) { if (value == EXPERIMENTAL_ICON) {
toolTipText = "This plugin is usable, but not fully tested or documented"; toolTipText = "This plugin is usable, but not fully tested or documented";
} }
else if (value == PluginInstallerTableModel.DEV_ICON) { else if (value == DEV_ICON) {
toolTipText = toolTipText =
"This plugin is under development and not intended for general use.\n" + "This plugin is under development and not intended for general use.\n" +
"It could cause Ghidra to become unstable!"; "It could cause Ghidra to become unstable!";

View file

@ -176,7 +176,7 @@ public class PluginManagerComponent extends JPanel implements Scrollable {
labelPanel.setBackground(BG); labelPanel.setBackground(BG);
GLabel nameLabel = new GLabel(pluginPackage.getName()); GLabel nameLabel = new GLabel(pluginPackage.getName());
nameLabel.setFont(nameLabel.getFont().deriveFont(18f)); Gui.registerFont(nameLabel, "font.pluginpanel.name");
nameLabel.setForeground(new GColor("color.fg.pluginpanel.name")); nameLabel.setForeground(new GColor("color.fg.pluginpanel.name"));
labelPanel.add(nameLabel); labelPanel.add(nameLabel);

View file

@ -15,13 +15,11 @@
*/ */
package ghidra.framework.project.extensions; package ghidra.framework.project.extensions;
import java.awt.Color; import java.awt.Font;
import java.awt.Point; import java.awt.Point;
import javax.swing.text.SimpleAttributeSet;
import docking.widgets.table.threaded.ThreadedTableModelListener; import docking.widgets.table.threaded.ThreadedTableModelListener;
import generic.theme.GColor; import generic.theme.*;
import ghidra.framework.plugintool.dialog.AbstractDetailsPanel; import ghidra.framework.plugintool.dialog.AbstractDetailsPanel;
import ghidra.util.extensions.ExtensionDetails; import ghidra.util.extensions.ExtensionDetails;
@ -33,27 +31,28 @@ import ghidra.util.extensions.ExtensionDetails;
*/ */
class ExtensionDetailsPanel extends AbstractDetailsPanel { class ExtensionDetailsPanel extends AbstractDetailsPanel {
private static final Color FG_COLOR_AUTHOR = private static final GColor FG_COLOR_AUTHOR =
new GColor("color.fg.extensionpanel.details.author"); new GColor("color.fg.extensionpanel.details.author");
private static final Color FG_COLOR_DATE = new GColor("color.fg.extensionpanel.details.date"); private static final GColor FG_COLOR_DATE = new GColor("color.fg.extensionpanel.details.date");
private static final Color FG_COLOR_DESCRIPTION = private static final GColor FG_COLOR_DESCRIPTION =
new GColor("color.fg.extensionpanel.details.description"); new GColor("color.fg.extensionpanel.details.description");
private static final Color FG_COLOR_NAME = new GColor("color.fg.extensionpanel.details.name"); private static final GColor FG_COLOR_NAME = new GColor("color.fg.extensionpanel.details.name");
private static final Color FG_COLOR_PATH = new GColor("color.fg.extensionpanel.path"); private static final GColor FG_COLOR_PATH = new GColor("color.fg.extensionpanel.path");
private static final Color FG_COLOR_TITLE = new GColor("color.fg.extensionpanel.details.title"); private static final GColor FG_COLOR_TITLE =
private static final Color FG_COLOR_VERSION = new GColor("color.fg.extensionpanel.details.title");
private static final GColor FG_COLOR_VERSION =
new GColor("color.fg.extensionpanel.details.version"); new GColor("color.fg.extensionpanel.details.version");
/** Attribute sets define the visual characteristics for each field */ /** Attribute sets define the visual characteristics for each field */
private SimpleAttributeSet nameAttrSet; private GAttributes nameAttrSet;
private SimpleAttributeSet descrAttrSet; private GAttributes descrAttrSet;
private SimpleAttributeSet authorAttrSet; private GAttributes authorAttrSet;
private SimpleAttributeSet createdOnAttrSet; private GAttributes createdOnAttrSet;
private SimpleAttributeSet versionAttrSet; private GAttributes versionAttrSet;
private SimpleAttributeSet pathAttrSet; private GAttributes pathAttrSet;
private ExtensionDetails currentDetails;
ExtensionDetailsPanel(ExtensionTablePanel tablePanel) { ExtensionDetailsPanel(ExtensionTablePanel tablePanel) {
super();
createFieldAttributes(); createFieldAttributes();
createMainPanel(); createMainPanel();
@ -82,6 +81,11 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
}); });
} }
@Override
protected void refresh() {
setDescription(currentDetails);
}
/** /**
* Updates this panel with the given extension. * Updates this panel with the given extension.
* *
@ -89,6 +93,7 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
*/ */
public void setDescription(ExtensionDetails details) { public void setDescription(ExtensionDetails details) {
this.currentDetails = details;
clear(); clear();
if (details == null) { if (details == null) {
return; return;
@ -134,12 +139,14 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
@Override @Override
protected void createFieldAttributes() { protected void createFieldAttributes() {
titleAttrSet = createAttributeSet(FG_COLOR_TITLE);
nameAttrSet = createAttributeSet(FG_COLOR_NAME); Font font = Gui.getFont(FONT_DEFAULT);
descrAttrSet = createAttributeSet(FG_COLOR_DESCRIPTION); titleAttrs = new GAttributes(font, FG_COLOR_TITLE);
authorAttrSet = createAttributeSet(FG_COLOR_AUTHOR); nameAttrSet = new GAttributes(font, FG_COLOR_NAME);
createdOnAttrSet = createAttributeSet(FG_COLOR_DATE); descrAttrSet = new GAttributes(font, FG_COLOR_DESCRIPTION);
versionAttrSet = createAttributeSet(FG_COLOR_VERSION); authorAttrSet = new GAttributes(font, FG_COLOR_AUTHOR);
pathAttrSet = createAttributeSet(FG_COLOR_PATH); createdOnAttrSet = new GAttributes(font, FG_COLOR_DATE);
versionAttrSet = new GAttributes(font, FG_COLOR_VERSION);
pathAttrSet = new GAttributes(font, FG_COLOR_PATH);
} }
} }

View file

@ -25,6 +25,7 @@ import docking.util.AnimatedIcon;
import docking.widgets.EmptyBorderButton; import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDHtmlLabel; import docking.widgets.label.GDHtmlLabel;
import docking.widgets.label.GIconLabel; import docking.widgets.label.GIconLabel;
import generic.theme.Gui;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import ghidra.util.layout.VerticalLayout; import ghidra.util.layout.VerticalLayout;
@ -36,6 +37,8 @@ import resources.ResourceManager;
public class GProgressBar extends JPanel { public class GProgressBar extends JPanel {
private static final NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance(); private static final NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance();
private static final String MESSAGE_FONT_ID = "font.task.progress.label.message";
private volatile long lastProgress = -1; private volatile long lastProgress = -1;
private volatile long progress; private volatile long progress;
private volatile long scaleFactor = 1; private volatile long scaleFactor = 1;
@ -47,7 +50,6 @@ public class GProgressBar extends JPanel {
private volatile boolean paintProgressValue = true; private volatile boolean paintProgressValue = true;
private boolean showingIcon = true; private boolean showingIcon = true;
private final float fontSize;
private JProgressBar progressBar; private JProgressBar progressBar;
private JLabel messageLabel; private JLabel messageLabel;
private JLabel imageLabel; private JLabel imageLabel;
@ -61,10 +63,9 @@ public class GProgressBar extends JPanel {
private CancelledListener cancelledListener; private CancelledListener cancelledListener;
public GProgressBar(CancelledListener cancelledListener, boolean includeTextField, public GProgressBar(CancelledListener cancelledListener, boolean includeTextField,
boolean includeCancelButton, boolean includeAnimatedIcon, float fontSize) { boolean includeCancelButton, boolean includeAnimatedIcon) {
super(new BorderLayout(5, 1)); super(new BorderLayout(5, 1));
this.cancelledListener = cancelledListener; this.cancelledListener = cancelledListener;
this.fontSize = fontSize;
buildProgressPanel(includeTextField, includeCancelButton, includeAnimatedIcon); buildProgressPanel(includeTextField, includeCancelButton, includeAnimatedIcon);
@ -217,7 +218,7 @@ public class GProgressBar extends JPanel {
// don't care // don't care
} }
}; };
messageLabel.setFont(messageLabel.getFont().deriveFont(fontSize)); Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
Dimension d = messageLabel.getPreferredSize(); Dimension d = messageLabel.getPreferredSize();
d.width = 180; d.width = 180;
messageLabel.setPreferredSize(d); messageLabel.setPreferredSize(d);

View file

@ -31,7 +31,6 @@ public class ScheduledTaskPanel extends JPanel {
private ScheduledElementLayout layout; private ScheduledElementLayout layout;
public ScheduledTaskPanel(String labelText, int indention) { public ScheduledTaskPanel(String labelText, int indention) {
super();
this.indention = indention; this.indention = indention;
setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
@ -44,7 +43,7 @@ public class ScheduledTaskPanel extends JPanel {
} }
void addProgressBar() { void addProgressBar() {
progressBar = new GProgressBar(null, true, true, false, 12); progressBar = new GProgressBar(null, true, true, false);
progressBar.setBackgroundColor(Colors.BACKGROUND); progressBar.setBackgroundColor(Colors.BACKGROUND);
add(progressBar); add(progressBar);
layout.clearPreferredSize(); layout.clearPreferredSize();

View file

@ -15,8 +15,7 @@
*/ */
package ghidra.framework.task; package ghidra.framework.task;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -46,11 +45,11 @@ public class GProgressBarTest extends AbstractDockingTest {
cancelled = true; cancelled = true;
} }
}; };
progressBar = new GProgressBar(cancelledListener, true, true, true, 10.0f); progressBar = new GProgressBar(cancelledListener, true, true, true);
} }
@Test @Test
public void testBasicProgress() { public void testBasicProgress() {
progressBar.initialize(100); progressBar.initialize(100);
assertEquals(0, progressBar.getProgress()); assertEquals(0, progressBar.getProgress());
assertEquals(100, progressBar.getMax()); assertEquals(100, progressBar.getMax());
@ -62,7 +61,7 @@ public class GProgressBarTest extends AbstractDockingTest {
} }
@Test @Test
public void testLongValues() { public void testLongValues() {
progressBar.initialize(0x400000000L); progressBar.initialize(0x400000000L);
progressBar.setProgress(10); progressBar.setProgress(10);
assertEquals(10, progressBar.getProgress()); assertEquals(10, progressBar.getProgress());
@ -73,7 +72,7 @@ public class GProgressBarTest extends AbstractDockingTest {
} }
@Test @Test
public void testMessage() { public void testMessage() {
progressBar.initialize(100); progressBar.initialize(100);
progressBar.setMessage("Hey"); progressBar.setMessage("Hey");
assertEquals("Hey", progressBar.getMessage()); assertEquals("Hey", progressBar.getMessage());
@ -91,7 +90,7 @@ public class GProgressBarTest extends AbstractDockingTest {
} }
@Test @Test
public void testCancel() { public void testCancel() {
progressBar.initialize(100); progressBar.initialize(100);
progressBar.setProgress(50); progressBar.setProgress(50);
assertTrue(!cancelled); assertTrue(!cancelled);

View file

@ -173,20 +173,15 @@ public class SystemUtilities {
} }
/** /**
* Checks to see if the font size override setting is enabled and adjusts * No longer supported. Use the theming system for fonts
* the given font as necessary to match the override setting. If the setting
* is not enabled, then <code>font</code> is returned.
* *
* @param font * @param font the font
* The current font to adjust, if necessary. * @return the same font passed in
* @return a font object with the proper size. * @deprecated Use the theming system for fonts
*/ */
@Deprecated(since = "11.1", forRemoval = true)
public static Font adjustForFontSizeOverride(Font font) { public static Font adjustForFontSizeOverride(Font font) {
if (FONT_SIZE_OVERRIDE_VALUE == null) { return font;
return font;
}
return font.deriveFont((float) FONT_SIZE_OVERRIDE_VALUE.intValue());
} }
/** /**

View file

@ -193,31 +193,43 @@ public class ReflectionUtilities {
* @return the desired class name * @return the desired class name
*/ */
public static String getClassNameOlderThan(Class<?>... classes) { public static String getClassNameOlderThan(Class<?>... classes) {
Throwable t = createThrowableWithStackOlderThan(classes); Throwable t = createThrowableWithStackOlderThan(classes);
StackTraceElement[] stackTrace = t.getStackTrace(); StackTraceElement[] stackTrace = t.getStackTrace();
return stackTrace[0].getClassName(); return stackTrace[0].getClassName();
} }
/** /**
* Creates a throwable whose stack trace is based upon the current call stack, with any * Returns the class name of the entry in the stack that comes before all references to the
* information coming before, and including, the given classes removed. * given patterns. This is useful for figuring out at runtime who is calling a particular
* <p> * method.
* This method can take multiple classes, but you really only need to pass the oldest
* class of disinterest.
* *
* @param classes the classes to ignore * @param patterns the patterns to ignore
* @return the new throwable * @return the desired class name
*/ */
public static Throwable createThrowableWithStackOlderThan(Class<?>... classes) { public static String getClassNameOlderThan(String... patterns) {
Throwable t = createThrowableWithStackOlderThan(patterns);
StackTraceElement[] stackTrace = t.getStackTrace();
return stackTrace[0].getClassName();
}
List<String> toFind = /**
Arrays.stream(classes).map(c -> c.getName()).collect(Collectors.toList()); * Creates a throwable whose stack trace is based upon the current call stack, with any
* information coming before, and including, the given patterns removed.
*
* @param patterns the strings to ignore (e.g., class or package names)
* @return the new throwable
* @see #createThrowableWithStackOlderThan(Class...)
*/
public static Throwable createThrowableWithStackOlderThan(String... patterns) {
return createThrowableWithStackOlderThan(List.of(patterns));
}
if (toFind.isEmpty()) { private static Throwable createThrowableWithStackOlderThan(List<String> patterns) {
// Always ignore our class. We get this for free if the client passes in any
// classes. if (patterns.isEmpty()) {
toFind.add(0, ReflectionUtilities.class.getName()); // always ignore our class. We get this for free if the client passes in any classes
patterns = new ArrayList<>();
patterns.add(0, ReflectionUtilities.class.getName());
} }
Throwable t = new Throwable(); Throwable t = new Throwable();
@ -227,7 +239,7 @@ public class ReflectionUtilities {
StackTraceElement element = trace[i]; StackTraceElement element = trace[i];
String className = element.getClassName(); String className = element.getClassName();
int nameIndex = toFind.indexOf(className); int nameIndex = patterns.indexOf(className);
if (nameIndex != -1) { if (nameIndex != -1) {
lastIgnoreIndex = i; lastIgnoreIndex = i;
} }
@ -242,13 +254,13 @@ public class ReflectionUtilities {
if (lastIgnoreIndex == -1) { if (lastIgnoreIndex == -1) {
Msg.error(ReflectionUtilities.class, Msg.error(ReflectionUtilities.class,
"Change call to ReflectionUtils. Did not find the " + "Change call to ReflectionUtils. Did not find the " +
"following classes in the call stack: " + Arrays.toString(classes)); "following patterns in the call stack: " + patterns);
} }
if (lastIgnoreIndex == trace.length - 1) { if (lastIgnoreIndex == trace.length - 1) {
Msg.error(ReflectionUtilities.class, Msg.error(ReflectionUtilities.class,
"Change call to ReflectionUtils. Call stack only contains the classes to ignore: " + "Change call to ReflectionUtils. Call stack contains only ignored patterns: " +
Arrays.toString(classes)); patterns);
} }
int startIndex = lastIgnoreIndex + 1; int startIndex = lastIgnoreIndex + 1;
@ -257,6 +269,22 @@ public class ReflectionUtilities {
return t; return t;
} }
/**
* Creates a throwable whose stack trace is based upon the current call stack, with any
* information coming before, and including, the given classes removed.
* <p>
* This method can take multiple classes, but you really only need to pass the oldest
* class of disinterest.
*
* @param classes the classes to ignore
* @return the new throwable
*/
public static Throwable createThrowableWithStackOlderThan(Class<?>... classes) {
List<String> patterns =
Arrays.stream(classes).map(c -> c.getName()).collect(Collectors.toList());
return createThrowableWithStackOlderThan(patterns);
}
/** /**
* Finds the first occurrence of the given pattern and then stops filtering when it finds * Finds the first occurrence of the given pattern and then stops filtering when it finds
* something that is not that pattern * something that is not that pattern
@ -333,7 +361,7 @@ public class ReflectionUtilities {
*/ */
public static Throwable createFilteredThrowable(String... patterns) { public static Throwable createFilteredThrowable(String... patterns) {
Throwable t = createThrowableWithStackOlderThan(); Throwable t = createThrowableWithStackOlderThan(new ArrayList<>());
StackTraceElement[] trace = t.getStackTrace(); StackTraceElement[] trace = t.getStackTrace();
StackTraceElement[] filtered = filterStackTrace(trace, patterns); StackTraceElement[] filtered = filterStackTrace(trace, patterns);
t.setStackTrace(filtered); t.setStackTrace(filtered);
@ -348,8 +376,7 @@ public class ReflectionUtilities {
* @return the new throwable * @return the new throwable
*/ */
public static Throwable createJavaFilteredThrowable() { public static Throwable createJavaFilteredThrowable() {
Throwable t = createThrowableWithStackOlderThan(List.of());
Throwable t = createThrowableWithStackOlderThan();
return filterJavaThrowable(t); return filterJavaThrowable(t);
} }
@ -365,7 +392,7 @@ public class ReflectionUtilities {
* @return the new throwable * @return the new throwable
*/ */
public static String createJavaFilteredThrowableString() { public static String createJavaFilteredThrowableString() {
Throwable t = createThrowableWithStackOlderThan(); Throwable t = createThrowableWithStackOlderThan(List.of());
Throwable filtered = filterJavaThrowable(t); Throwable filtered = filterJavaThrowable(t);
return stackTraceToString(filtered); return stackTraceToString(filtered);
} }

View file

@ -33,7 +33,6 @@ import resources.ResourceManager;
public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator { public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
public RepositoryCustomScreenShots() { public RepositoryCustomScreenShots() {
super();
} }
@Test @Test
@ -127,8 +126,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
int y = p.y - radius; int y = p.y - radius;
g.fillOval(x, y, radius * 2, 2 * radius); g.fillOval(x, y, radius * 2, 2 * radius);
Font f = g.getFont().deriveFont(12f);
g.setFont(f);
FontMetrics metrics = g.getFontMetrics(); FontMetrics metrics = g.getFontMetrics();
int height = metrics.getHeight(); int height = metrics.getHeight();
g.setColor(Palette.BLACK); g.setColor(Palette.BLACK);
@ -154,8 +151,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
BasicStroke stroke = new BasicStroke(1); BasicStroke stroke = new BasicStroke(1);
g.setStroke(stroke); g.setStroke(stroke);
Font f = g.getFont().deriveFont(12f);
g.setFont(f);
FontMetrics metrics = g.getFontMetrics(); FontMetrics metrics = g.getFontMetrics();
int margin = 5; int margin = 5;
int height = metrics.getHeight() * text.length + 2 * margin; int height = metrics.getHeight() * text.length + 2 * margin;
@ -189,8 +184,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
Graphics2D g = ((BufferedImage) image).createGraphics(); Graphics2D g = ((BufferedImage) image).createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Font f = g.getFont().deriveFont(12f);
g.setFont(f);
FontMetrics metrics = g.getFontMetrics(); FontMetrics metrics = g.getFontMetrics();
// int margin = 5; // int margin = 5;
int height = metrics.getHeight() * text.length; int height = metrics.getHeight() * text.length;