mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
Merge remote-tracking branch 'origin/GP-4154-dragonmacher-theme-font-updates--SQUASHED'
This commit is contained in:
commit
86516b1718
@ -26,7 +26,8 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.*;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import db.Transaction;
|
||||
import docking.action.DockingAction;
|
||||
@ -265,8 +266,8 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(fixedWidthFont);
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +25,6 @@ import java.util.function.BiFunction;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.text.View;
|
||||
|
||||
import ghidra.docking.settings.Settings;
|
||||
@ -92,11 +91,7 @@ public class CustomToStringCellRenderer<T> extends AbstractGColumnRenderer<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(getCustomFont());
|
||||
}
|
||||
|
||||
protected Font getCustomFont() {
|
||||
protected Font getDefaultFont() {
|
||||
switch (customFont) {
|
||||
default:
|
||||
case DEFAULT:
|
||||
|
@ -15,11 +15,9 @@
|
||||
*/
|
||||
package ghidra.machinelearning.functionfinding;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import docking.widgets.table.AbstractDynamicTableColumn;
|
||||
import docking.widgets.table.TableColumnDescriptor;
|
||||
import ghidra.docking.settings.Settings;
|
||||
@ -48,7 +46,7 @@ public class SimilarStartsTableModel extends AddressBasedTableModel<SimilarStart
|
||||
* Construct a table model for a table to display the closest function starts to
|
||||
* a potential function start
|
||||
* @param plugin owning program
|
||||
* @param program program
|
||||
* @param program program
|
||||
* @param rows similar function starts
|
||||
* @param randomForestRow model and params
|
||||
*/
|
||||
@ -123,9 +121,10 @@ public class SimilarStartsTableModel extends AddressBasedTableModel<SimilarStart
|
||||
@Override
|
||||
public GColumnRenderer<String> getColumnRenderer() {
|
||||
final GColumnRenderer<String> monospacedRenderer = new AbstractGColumnRenderer<>() {
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(getFixedWidthFont());
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
package ghidra.examples;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
@ -30,8 +31,8 @@ import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class HelloWorldComponentProvider extends ComponentProviderAdapter {
|
||||
private final static HelpLocation HELP = new HelpLocation("SampleHelpTopic",
|
||||
"SampleHelpTopic_Anchor_Name");
|
||||
private final static HelpLocation HELP =
|
||||
new HelpLocation("SampleHelpTopic", "SampleHelpTopic_Anchor_Name");
|
||||
private MyButton activeButtonObj;
|
||||
private JPanel mainPanel;
|
||||
private DockingAction action;
|
||||
@ -64,8 +65,8 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
|
||||
// the menu item will appear on the local toolbar drop down.
|
||||
Icon icon = new GIcon("icon.sample.action.hello.world");
|
||||
action.setMenuBarData(new MenuData(new String[] { "Misc", "Hello World" }, icon));
|
||||
action.setKeyBindingData(new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W,
|
||||
InputEvent.CTRL_MASK)));
|
||||
action.setKeyBindingData(
|
||||
new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK)));
|
||||
|
||||
// puts the action on the local toolbar.
|
||||
action.setToolBarData(new ToolBarData(icon));
|
||||
@ -81,11 +82,11 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
|
||||
public void actionPerformed(ActionContext context) {
|
||||
announce("Hello World");
|
||||
|
||||
// To get the context object,
|
||||
// To get the context object,
|
||||
Object contextObject = context.getContextObject();
|
||||
|
||||
// ...now we can cast activeObj to be a object of MyButton
|
||||
// if that is necessary, as the overridden isAddToPopup() method below
|
||||
// if that is necessary, as the overridden isAddToPopup() method below
|
||||
// will not add the popup action if the context object is not our button
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ -120,8 +121,6 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
|
||||
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
panel.setBorder(BorderFactory.createTitledBorder("Example of a Component"));
|
||||
activeButtonObj = new MyButton("Hello World");
|
||||
Font f = activeButtonObj.getFont();
|
||||
activeButtonObj.setFont(f.deriveFont(Font.BOLD, 14));
|
||||
panel.add(activeButtonObj);
|
||||
mainPanel.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
@ -16,12 +16,11 @@
|
||||
package ghidra.features.bsim.gui.overview;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import docking.widgets.table.*;
|
||||
import generic.lsh.vector.LSHVectorFactory;
|
||||
@ -233,8 +232,8 @@ public class BSimOverviewModel extends AddressBasedTableModel<BSimOverviewRowObj
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(fixedWidthFont);
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,6 +28,7 @@ import docking.DockingWindowManager;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.textfield.FloatingPointTextField;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.features.bsim.query.BSimServerInfo;
|
||||
import ghidra.features.bsim.query.description.DatabaseInformation;
|
||||
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);
|
||||
|
||||
JLabel label = new JLabel(name);
|
||||
label.setFont(label.getFont().deriveFont(Font.BOLD));
|
||||
Gui.registerFont(label, Font.BOLD);
|
||||
titlePanel.add(label, BorderLayout.NORTH);
|
||||
|
||||
return panel;
|
||||
@ -260,7 +261,7 @@ public abstract class AbstractBSimSearchDialog extends DialogComponentProvider {
|
||||
|
||||
//==================================================================================================
|
||||
// test methods
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
protected void setServer(BSimServerInfo info) {
|
||||
initializeConnection(info);
|
||||
}
|
||||
@ -271,7 +272,7 @@ public abstract class AbstractBSimSearchDialog extends DialogComponentProvider {
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
protected abstract class BSimQueryTask extends Task {
|
||||
protected Exception errorException;
|
||||
|
||||
|
@ -18,11 +18,10 @@ package ghidra.features.bsim.gui.search.results;
|
||||
import static ghidra.features.bsim.gui.search.results.BSimResultStatus.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import docking.widgets.table.*;
|
||||
import generic.lsh.vector.LSHVectorFactory;
|
||||
@ -56,7 +55,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
private Collection<BSimMatchResult> results = new ArrayList<BSimMatchResult>();
|
||||
|
||||
// Maps functions (represented by addresses) to the number of matches in the query.
|
||||
// This is here to provide quick access for the MatchCountTableColumn.
|
||||
// This is here to provide quick access for the MatchCountTableColumn.
|
||||
private Map<Address, Integer> functionMatchMap = new HashMap<>();
|
||||
|
||||
public BSimMatchResultsModel(PluginTool tool, DatabaseInformation info,
|
||||
@ -70,15 +69,15 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
return; // Info can be null, even if FunctionDatabase return Ready (not created yet)
|
||||
}
|
||||
if (info.execats != null) {
|
||||
for (int i = 0; i < info.execats.size(); ++i) {
|
||||
addTableColumn(new ExecCategoryColumn(info.execats.get(i)));
|
||||
for (String element : info.execats) {
|
||||
addTableColumn(new ExecCategoryColumn(element));
|
||||
}
|
||||
}
|
||||
if (info.functionTags != null) {
|
||||
int mask = 1;
|
||||
mask <<= FunctionTagBSimFilterType.RESERVED_BITS;
|
||||
for (int i = 0; i < info.functionTags.size(); ++i) {
|
||||
addTableColumn(new FunctionTagColumn(info.functionTags.get(i), mask));
|
||||
for (String element : info.functionTags) {
|
||||
addTableColumn(new FunctionTagColumn(element, mask));
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
@ -90,7 +89,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
// Must add this column here because it requires that the queryManager
|
||||
// be available. At the time createTableColumnDescriptor() is called this
|
||||
// be available. At the time createTableColumnDescriptor() is called this
|
||||
// is not the case. The index is set to '-1' so it will be placed at the end
|
||||
// of the list.
|
||||
if (lshVectorFactory != null) {
|
||||
@ -114,12 +113,12 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
descriptor.addHiddenColumn(new CompilerMatchColumn());
|
||||
descriptor.addHiddenColumn(new MatchCountTableColumn());
|
||||
descriptor.addHiddenColumn(new FunctionSizeTableColumn());
|
||||
descriptor.addHiddenColumn(new FunctionTagColumn("Known Library",
|
||||
FunctionTagBSimFilterType.KNOWN_LIBRARY_MASK));
|
||||
descriptor.addHiddenColumn(
|
||||
new FunctionTagColumn("Known Library", FunctionTagBSimFilterType.KNOWN_LIBRARY_MASK));
|
||||
descriptor.addHiddenColumn(new FunctionTagColumn("Has Unimplemented",
|
||||
FunctionTagBSimFilterType.HAS_UNIMPLEMENTED_MASK));
|
||||
descriptor.addHiddenColumn(new FunctionTagColumn("Has Bad Data",
|
||||
FunctionTagBSimFilterType.HAS_BADDATA_MASK));
|
||||
descriptor.addHiddenColumn(
|
||||
new FunctionTagColumn("Has Bad Data", FunctionTagBSimFilterType.HAS_BADDATA_MASK));
|
||||
descriptor.addVisibleColumn(
|
||||
DiscoverableTableUtils.adaptColumForModel(this, new AddressTableColumn()));
|
||||
descriptor.addHiddenColumn(new MatchingFunctionAddressTableColumn());
|
||||
@ -171,9 +170,9 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given result set to find the number of matches associated with
|
||||
* each base function.
|
||||
*
|
||||
* Parses the given result set to find the number of matches associated with
|
||||
* each base function.
|
||||
*
|
||||
* @param queryResults the query results to inspect
|
||||
*/
|
||||
private void parseFunctionMatchCounts(Collection<BSimMatchResult> queryResults) {
|
||||
@ -192,7 +191,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
/**
|
||||
* Associate a given FunctionDescription with the entry point of the matching function in a program
|
||||
* @param desc is the FunctionDescription to recover
|
||||
* @param prog is the Program (possibly) containing the Function object
|
||||
* @param prog is the Program (possibly) containing the Function object
|
||||
* @return the entry point address of the function (if it exists), or just the address within the default space
|
||||
*/
|
||||
public static Address recoverAddress(FunctionDescription desc, Program prog) {
|
||||
@ -288,10 +287,10 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
Address address = rowObject.getAddress();
|
||||
Function function = program.getFunctionManager().getFunctionAt(address);
|
||||
Function function = p.getFunctionManager().getFunctionAt(address);
|
||||
boolean showNamespace = SHOW_NAMESPACE.getValue(settings);
|
||||
if (function != null) {
|
||||
return function.getName(showNamespace);
|
||||
@ -319,7 +318,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
String name = rowObject.getSimilarFunctionName();
|
||||
boolean showNamespace = SHOW_NAMESPACE.getValue(settings);
|
||||
@ -365,7 +364,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
|
||||
/**
|
||||
* Column for showing the number of matches each base function has.
|
||||
*
|
||||
*
|
||||
* Note the use of the {@link BSimMatchResultsModel#functionMatchMap}; this is
|
||||
* for performance reasons. We don't want this class looping over the entire
|
||||
* result set calculating match counts every time the table is refreshed.
|
||||
@ -380,7 +379,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public Integer getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider provider) throws IllegalArgumentException {
|
||||
return functionMatchMap.get(rowObject.getAddress());
|
||||
}
|
||||
@ -392,7 +391,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
/**
|
||||
* Column for showing the address of the matching function.
|
||||
* Column for showing the address of the matching function.
|
||||
*/
|
||||
private static class MatchingFunctionAddressTableColumn
|
||||
extends AbstractProgramBasedDynamicTableColumn<BSimMatchResult, Long> {
|
||||
@ -404,7 +403,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue(BSimMatchResult rowObject, Settings settings, Program data,
|
||||
public Long getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
Long addr = rowObject.getMatchFunctionDescription().getAddress();
|
||||
return addr;
|
||||
@ -437,8 +436,8 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(fixedWidthFont);
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -464,10 +463,10 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public Long getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider provider) throws IllegalArgumentException {
|
||||
Address address = rowObject.getAddress();
|
||||
Function function = program.getFunctionManager().getFunctionAt(address);
|
||||
Function function = p.getFunctionManager().getFunctionAt(address);
|
||||
return function.getBody().getNumAddresses();
|
||||
}
|
||||
|
||||
@ -482,7 +481,6 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
private String columnName;
|
||||
|
||||
ExecDateColumn(String name) {
|
||||
super();
|
||||
columnName = name;
|
||||
}
|
||||
|
||||
@ -492,7 +490,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public Date getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getDate();
|
||||
}
|
||||
@ -519,7 +517,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getExeCategoryAlphabetic(columnName);
|
||||
}
|
||||
@ -540,7 +538,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getArchitecture();
|
||||
}
|
||||
@ -561,7 +559,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getCompilerName();
|
||||
}
|
||||
@ -582,7 +580,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getMd5();
|
||||
}
|
||||
@ -604,7 +602,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getSimilarity();
|
||||
}
|
||||
@ -630,7 +628,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.getSignificance();
|
||||
}
|
||||
@ -662,7 +660,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program,
|
||||
public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return vectorFactory.getSelfSignificance(
|
||||
rowObject.getMatchFunctionDescription().getSignatureRecord().getLSHVector());
|
||||
@ -696,7 +694,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue(BSimMatchResult rowObject, Settings settings, Program data,
|
||||
public Boolean getValue(BSimMatchResult rowObject, Settings settings, Program p,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.isFlagSet(mask);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import java.util.stream.Collectors;
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.features.bsim.gui.BSimSearchPlugin;
|
||||
import ghidra.features.bsim.gui.search.dialog.BSimFilterSet;
|
||||
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));
|
||||
|
||||
JLabel dataLabel = new JLabel("Search Options:");
|
||||
dataLabel.setFont(dataLabel.getFont().deriveFont(Font.ITALIC));
|
||||
Gui.registerFont(dataLabel, Font.ITALIC);
|
||||
panel.add(dataLabel);
|
||||
panel.add(new JLabel(""));
|
||||
|
||||
@ -89,7 +90,7 @@ public class BSimSearchInfoDisplayDialog extends DialogComponentProvider {
|
||||
panel.add(new JLabel(""));
|
||||
panel.add(new JLabel(""));
|
||||
JLabel filterLabel = new JLabel("Filters:");
|
||||
filterLabel.setFont(filterLabel.getFont().deriveFont(Font.ITALIC));
|
||||
Gui.registerFont(filterLabel, Font.ITALIC);
|
||||
panel.add(filterLabel);
|
||||
panel.add(new JLabel(""));
|
||||
|
||||
|
@ -166,19 +166,26 @@ color.bg.plugin.windowlocation.screens = color.palette.orange
|
||||
color.bg.plugin.windowlocation.window.selected = color.palette.lime
|
||||
color.fg.plugin.windowlocation.window.text = color.palette.gray
|
||||
|
||||
|
||||
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.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.scripts.text.editor = font.monospaced
|
||||
font.plugin.assembly.dual.text.field = font.monospaced
|
||||
font.plugin.instruction.table.renderer = courier-plain-14
|
||||
font.plugin.entropy.label.knot = SansSerif-BOLD-12
|
||||
font.plugin.instruction.info = font.monospaced[14]
|
||||
font.plugin.tabs = SansSerif-PLAIN-11
|
||||
font.plugin.tabs.list = SansSerif-BOLD-9
|
||||
font.plugin.tips = Dialog-PLAIN-12
|
||||
font.plugin.tips.label = font.plugin.tips[BOLD]
|
||||
font.plugin.strings.buttons = sansserif-plain-10
|
||||
font.plugin.tabs = sansserif-plain-11
|
||||
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.completion.list = dialog-plain-12
|
||||
font.plugin.window.location = font.monospaced[40]
|
||||
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@ package ghidra.app.merge;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
|
||||
public interface MergeConstants {
|
||||
@ -29,13 +30,13 @@ public interface MergeConstants {
|
||||
public static final String LATEST_TITLE = "Latest";
|
||||
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;
|
||||
|
||||
// The following are standardized names for use in passing resolve
|
||||
// The following are standardized names for use in passing resolve
|
||||
// information between individual merge managers.
|
||||
// For example:
|
||||
// the data type merger knows what data type in the result is equivalent
|
||||
// the data type merger knows what data type in the result is equivalent
|
||||
// to a given data type from my checked out program. The code unit and
|
||||
// function mergers need to be able to get this information so they
|
||||
// don't unknowingly re-introduce a data type that was already eliminated
|
||||
|
@ -16,13 +16,14 @@
|
||||
package ghidra.app.merge.datatypes;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import generic.theme.*;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import ghidra.app.merge.MergeConstants;
|
||||
import ghidra.docking.settings.Settings;
|
||||
@ -36,23 +37,21 @@ import ghidra.util.UniversalID;
|
||||
|
||||
/**
|
||||
* Panel to show the contents of a Data Type.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DataTypePanel extends JPanel {
|
||||
|
||||
public Color SOURCE_COLOR = Palette.GREEN;
|
||||
public GColor SOURCE_COLOR = Palette.GREEN;
|
||||
private DataType dataType;
|
||||
private JTextPane textPane;
|
||||
private StyledDocument doc;
|
||||
private SimpleAttributeSet pathAttrSet;
|
||||
private SimpleAttributeSet nameAttrSet;
|
||||
private SimpleAttributeSet sourceAttrSet;
|
||||
private SimpleAttributeSet offsetAttrSet;
|
||||
private SimpleAttributeSet contentAttrSet;
|
||||
private SimpleAttributeSet fieldNameAttrSet;
|
||||
private SimpleAttributeSet commentAttrSet;
|
||||
private SimpleAttributeSet deletedAttrSet;
|
||||
private SimpleAttributeSet pathAttrs;
|
||||
private SimpleAttributeSet nameAttrs;
|
||||
private SimpleAttributeSet sourceAttrs;
|
||||
private SimpleAttributeSet offsetAttrs;
|
||||
private SimpleAttributeSet contentAttrs;
|
||||
private SimpleAttributeSet fieldNameAttrs;
|
||||
private SimpleAttributeSet commentAttrs;
|
||||
private SimpleAttributeSet deletedAttrs;
|
||||
|
||||
DataTypePanel(DataType dataType) {
|
||||
super(new BorderLayout());
|
||||
@ -91,58 +90,27 @@ class DataTypePanel extends JPanel {
|
||||
add(textPane, BorderLayout.CENTER);
|
||||
textPane.setEditable(false);
|
||||
|
||||
pathAttrSet = new SimpleAttributeSet();
|
||||
pathAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
pathAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
pathAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
|
||||
pathAttrSet.addAttribute(StyleConstants.Foreground, MergeConstants.CONFLICT_COLOR);
|
||||
Font monospaced = Gui.getFont("font.monospaced");
|
||||
Font bold = Gui.getFont("font.standard.bold");
|
||||
|
||||
nameAttrSet = new SimpleAttributeSet();
|
||||
nameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
nameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
nameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
|
||||
|
||||
sourceAttrSet = new SimpleAttributeSet();
|
||||
sourceAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
sourceAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
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);
|
||||
pathAttrs = new GAttributes(bold, MergeConstants.CONFLICT_COLOR);
|
||||
nameAttrs = new GAttributes(bold);
|
||||
sourceAttrs = new GAttributes(bold, SOURCE_COLOR);
|
||||
offsetAttrs = new GAttributes(monospaced, Palette.BLACK);
|
||||
contentAttrs = new GAttributes(monospaced, Palette.BLUE);
|
||||
fieldNameAttrs = new GAttributes(monospaced, Palette.MAGENTA);
|
||||
commentAttrs = new GAttributes(monospaced, Palette.LIME);
|
||||
deletedAttrs = new GAttributes(bold, Palette.RED);
|
||||
|
||||
setDataType(dataType);
|
||||
}
|
||||
|
||||
private void formatPath(DataType dt) {
|
||||
insertString("Path: " + dt.getCategoryPath() + "\n\n", pathAttrSet);
|
||||
insertString("Path: " + dt.getCategoryPath() + "\n\n", pathAttrs);
|
||||
}
|
||||
|
||||
private void formatSourceArchive(DataType dt) {
|
||||
insertString("Source Archive: " + getSourceArchiveName(dt) + "\n", sourceAttrSet);
|
||||
insertString("Source Archive: " + getSourceArchiveName(dt) + "\n", sourceAttrs);
|
||||
}
|
||||
|
||||
private String getSourceArchiveName(DataType dt) {
|
||||
@ -156,21 +124,21 @@ class DataTypePanel extends JPanel {
|
||||
|
||||
private void formatAlignment(Composite composite) {
|
||||
String str = CompositeInternal.getAlignmentAndPackingString(composite);
|
||||
insertString(str + "\n\n", sourceAttrSet);
|
||||
insertString(str + "\n\n", sourceAttrs);
|
||||
}
|
||||
|
||||
private void insertAlignment(Composite composite) {
|
||||
StringBuffer alignmentBuffer = new StringBuffer();
|
||||
alignmentBuffer.append("Alignment: ");
|
||||
alignmentBuffer.append(Integer.toString(composite.getAlignment()));
|
||||
insertString(alignmentBuffer.toString() + "\n", sourceAttrSet);
|
||||
insertString(alignmentBuffer.toString() + "\n", sourceAttrs);
|
||||
}
|
||||
|
||||
private void insertLength(Composite composite) {
|
||||
StringBuffer lengthBuffer = new StringBuffer();
|
||||
lengthBuffer.append("Length: ");
|
||||
lengthBuffer.append(Integer.toString(composite.getLength()));
|
||||
insertString(lengthBuffer.toString() + "\n", sourceAttrSet);
|
||||
insertString(lengthBuffer.toString() + "\n", sourceAttrs);
|
||||
}
|
||||
|
||||
private int max(String str, int length) {
|
||||
@ -184,8 +152,7 @@ class DataTypePanel extends JPanel {
|
||||
DataType dt = dtc.getDataType();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(dt.getName());
|
||||
if (dt instanceof BitFieldDataType &&
|
||||
!((Composite) dtc.getParent()).isPackingEnabled()) {
|
||||
if (dt instanceof BitFieldDataType && !((Composite) dtc.getParent()).isPackingEnabled()) {
|
||||
BitFieldDataType bfDt = (BitFieldDataType) dt;
|
||||
buffer.append("(");
|
||||
buffer.append(Integer.toString(bfDt.getBitOffset()));
|
||||
@ -210,23 +177,23 @@ class DataTypePanel extends JPanel {
|
||||
offsetStr = "0x" + Integer.toHexString(dtc.getOffset());
|
||||
offsetStr = StringUtilities.pad(offsetStr, ' ', offsetWidth - offsetStr.length());
|
||||
offsetStr += ": ";
|
||||
insertString(" " + offsetStr + " ", offsetAttrSet);
|
||||
insertString(" " + offsetStr + " ", offsetAttrs);
|
||||
}
|
||||
fieldName = pad(fieldName, fieldNameWidth);
|
||||
String typeName = pad(getDataTypeName(dtc), dtNameWidth);
|
||||
|
||||
insertString(" " + typeName + " ", contentAttrSet);
|
||||
insertString(fieldName + " ", fieldNameAttrSet);
|
||||
insertString(comment, commentAttrSet);
|
||||
insertString("\n", contentAttrSet);
|
||||
insertString(" " + typeName + " ", contentAttrs);
|
||||
insertString(fieldName + " ", fieldNameAttrs);
|
||||
insertString(comment, commentAttrs);
|
||||
insertString("\n", contentAttrs);
|
||||
}
|
||||
|
||||
private void formatCompositeText(Composite comp) {
|
||||
formatSourceArchive(comp);
|
||||
formatPath(comp);
|
||||
formatAlignment(comp);
|
||||
insertString(comp.getDisplayName(), nameAttrSet);
|
||||
insertString(" { \n", contentAttrSet);
|
||||
insertString(comp.getDisplayName(), nameAttrs);
|
||||
insertString(" { \n", contentAttrs);
|
||||
|
||||
boolean showComponentOffset = false;
|
||||
|
||||
@ -247,7 +214,7 @@ class DataTypePanel extends JPanel {
|
||||
renderComponent(component, maxDtNameLength, maxFieldNameLength, offsetLength);
|
||||
}
|
||||
|
||||
insertString("}\n\n", contentAttrSet);
|
||||
insertString("}\n\n", contentAttrs);
|
||||
insertAlignment(comp);
|
||||
insertLength(comp);
|
||||
}
|
||||
@ -279,8 +246,8 @@ class DataTypePanel extends JPanel {
|
||||
private void formatEnumText(Enum enuum) {
|
||||
formatSourceArchive(enuum);
|
||||
formatPath(enuum);
|
||||
insertString(enuum.getDisplayName(), nameAttrSet);
|
||||
insertString(" { \n", contentAttrSet);
|
||||
insertString(enuum.getDisplayName(), nameAttrs);
|
||||
insertString(" { \n", contentAttrs);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
@ -303,7 +270,7 @@ class DataTypePanel extends JPanel {
|
||||
renderEnumEntry(entry, maxNameLength, maxValueLength);
|
||||
}
|
||||
sb.append("}\n");
|
||||
insertString(sb.toString(), contentAttrSet);
|
||||
insertString(sb.toString(), contentAttrs);
|
||||
}
|
||||
|
||||
private void renderEnumEntry(EnumEntry entry, int maxNameLength, int maxValueLength) {
|
||||
@ -311,20 +278,20 @@ class DataTypePanel extends JPanel {
|
||||
name = pad(name, maxNameLength);
|
||||
String valStr = Long.toHexString(entry.value);
|
||||
valStr = pad(valStr, maxValueLength);
|
||||
insertString(" " + name, fieldNameAttrSet);
|
||||
insertString(" = 0x" + valStr, contentAttrSet);
|
||||
insertString(" " + name, fieldNameAttrs);
|
||||
insertString(" = 0x" + valStr, contentAttrs);
|
||||
if (entry.comment != null) {
|
||||
insertString(" " + entry.comment, commentAttrSet);
|
||||
insertString(" " + entry.comment, commentAttrs);
|
||||
}
|
||||
insertString("\n", contentAttrSet);
|
||||
insertString("\n", contentAttrs);
|
||||
}
|
||||
|
||||
private void formatTypeDefText(TypeDef td) {
|
||||
formatSourceArchive(td);
|
||||
formatPath(td);
|
||||
insertString(td.getDisplayName(), nameAttrSet);
|
||||
insertString("\n", contentAttrSet);
|
||||
insertString(" TypeDef on " + td.getDataType().getDisplayName(), contentAttrSet);
|
||||
insertString(td.getDisplayName(), nameAttrs);
|
||||
insertString("\n", contentAttrs);
|
||||
insertString(" TypeDef on " + td.getDataType().getDisplayName(), contentAttrs);
|
||||
}
|
||||
|
||||
private void formatDataTypeSettings(DataType dt) {
|
||||
@ -336,10 +303,10 @@ class DataTypePanel extends JPanel {
|
||||
if (defs.length == 0) {
|
||||
return;
|
||||
}
|
||||
insertString("\n\nSettings\n", sourceAttrSet);
|
||||
insertString("\n\nSettings\n", sourceAttrs);
|
||||
for (SettingsDefinition def : defs) {
|
||||
insertString(" " + def.getName() + ": " + def.getValueString(settings) + "\n",
|
||||
contentAttrSet);
|
||||
contentAttrs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,18 +317,18 @@ class DataTypePanel extends JPanel {
|
||||
|
||||
DataType returnType = fd.getReturnType();
|
||||
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();
|
||||
if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(callingConventionName)) {
|
||||
insertString(callingConventionName + " ", contentAttrSet);
|
||||
insertString(callingConventionName + " ", contentAttrs);
|
||||
}
|
||||
insertString(" " + fd.getDisplayName(), nameAttrSet);
|
||||
insertString(" (", contentAttrSet);
|
||||
insertString(" " + fd.getDisplayName(), nameAttrs);
|
||||
insertString(" (", contentAttrs);
|
||||
boolean hasVarArgs = fd.hasVarArgs();
|
||||
if ((vars.length == 0) && !hasVarArgs) {
|
||||
insertString(")", contentAttrSet);
|
||||
insertString(")", contentAttrs);
|
||||
return;
|
||||
}
|
||||
int maxLength = 0;
|
||||
@ -390,17 +357,17 @@ class DataTypePanel extends JPanel {
|
||||
sb.append(FunctionSignature.VAR_ARGS_DISPLAY_STRING);
|
||||
}
|
||||
sb.append(")");
|
||||
insertString(sb.toString(), contentAttrSet);
|
||||
insertString(sb.toString(), contentAttrs);
|
||||
}
|
||||
|
||||
private void formatDataType(DataType dt) {
|
||||
if (dt == null) {
|
||||
insertString("\n\nDeleted", deletedAttrSet);
|
||||
insertString("\n\nDeleted", deletedAttrs);
|
||||
return;
|
||||
}
|
||||
formatSourceArchive(dt);
|
||||
formatPath(dt);
|
||||
insertString(dt.getDisplayName(), nameAttrSet);
|
||||
insertString(dt.getDisplayName(), nameAttrs);
|
||||
}
|
||||
|
||||
private String pad(String str, int length) {
|
||||
|
@ -16,13 +16,16 @@
|
||||
package ghidra.app.merge.datatypes;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Font;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import generic.theme.GAttributes;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.program.model.data.ArchiveType;
|
||||
import ghidra.program.model.data.SourceArchive;
|
||||
import ghidra.util.Msg;
|
||||
@ -35,9 +38,9 @@ class SourceArchivePanel extends JPanel {
|
||||
private SourceArchive sourceArchive;
|
||||
private JTextPane textPane;
|
||||
private StyledDocument doc;
|
||||
private SimpleAttributeSet headingAttrSet;
|
||||
private SimpleAttributeSet valueAttrSet;
|
||||
private SimpleAttributeSet deletedAttrSet;
|
||||
private SimpleAttributeSet headingAttrs;
|
||||
private SimpleAttributeSet valueAttrs;
|
||||
private SimpleAttributeSet deletedAttrs;
|
||||
|
||||
SourceArchivePanel() {
|
||||
super(new BorderLayout());
|
||||
@ -57,28 +60,19 @@ class SourceArchivePanel extends JPanel {
|
||||
add(textPane, BorderLayout.CENTER);
|
||||
textPane.setEditable(false);
|
||||
|
||||
headingAttrSet = new SimpleAttributeSet();
|
||||
headingAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
|
||||
headingAttrSet.addAttribute(StyleConstants.FontSize, 12);
|
||||
headingAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLUE);
|
||||
Font monospaced = Gui.getFont("font.monospaced");
|
||||
Font bold = Gui.getFont("font.standard.bold");
|
||||
|
||||
valueAttrSet = new SimpleAttributeSet();
|
||||
valueAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
valueAttrSet.addAttribute(StyleConstants.FontSize, 11);
|
||||
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);
|
||||
headingAttrs = new GAttributes(monospaced, Palette.BLUE);
|
||||
valueAttrs = new GAttributes(bold);
|
||||
deletedAttrs = new GAttributes(bold, Palette.RED);
|
||||
|
||||
setSourceArchive(null);
|
||||
}
|
||||
|
||||
private void formatSourceArchive() {
|
||||
if (sourceArchive == null) {
|
||||
insertString("\n\nDeleted", deletedAttrSet);
|
||||
insertString("\n\nDeleted", deletedAttrs);
|
||||
return;
|
||||
}
|
||||
// formatArchiveID();
|
||||
@ -91,19 +85,19 @@ class SourceArchivePanel extends JPanel {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void formatArchiveID() {
|
||||
insertString(" Archive ID: ", headingAttrSet);
|
||||
insertString(sourceArchive.getSourceArchiveID().getValue() + "\n", valueAttrSet);
|
||||
insertString(" Archive ID: ", headingAttrs);
|
||||
insertString(sourceArchive.getSourceArchiveID().getValue() + "\n", valueAttrs);
|
||||
}
|
||||
|
||||
private void formatName() {
|
||||
insertString("Name: ", headingAttrSet);
|
||||
insertString(sourceArchive.getName() + "\n", valueAttrSet);
|
||||
insertString("Name: ", headingAttrs);
|
||||
insertString(sourceArchive.getName() + "\n", valueAttrs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void formatFileID() {
|
||||
insertString(" File ID: ", headingAttrSet);
|
||||
insertString(sourceArchive.getDomainFileID() + "\n", valueAttrSet);
|
||||
insertString(" File ID: ", headingAttrs);
|
||||
insertString(sourceArchive.getDomainFileID() + "\n", valueAttrs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ -112,21 +106,20 @@ class SourceArchivePanel extends JPanel {
|
||||
String typeString = (archiveType == ArchiveType.FILE) ? "File Archive"
|
||||
: (archiveType == ArchiveType.PROGRAM) ? "Program"
|
||||
: (archiveType == ArchiveType.PROJECT) ? "Project Archive"
|
||||
: (archiveType == ArchiveType.BUILT_IN) ? "Built-In"
|
||||
: "Invalid";
|
||||
insertString(" Type: ", headingAttrSet);
|
||||
insertString(typeString + "\n", valueAttrSet);
|
||||
: (archiveType == ArchiveType.BUILT_IN) ? "Built-In" : "Invalid";
|
||||
insertString(" Type: ", headingAttrs);
|
||||
insertString(typeString + "\n", valueAttrs);
|
||||
}
|
||||
|
||||
private void formatSyncTime() {
|
||||
String syncTime = new Date(sourceArchive.getLastSyncTime()).toString();
|
||||
insertString("Last Sync Time: ", headingAttrSet);
|
||||
insertString(syncTime + "\n", valueAttrSet);
|
||||
insertString("Last Sync Time: ", headingAttrs);
|
||||
insertString(syncTime + "\n", valueAttrs);
|
||||
}
|
||||
|
||||
private void formatDirtyFlag() {
|
||||
insertString("Changed Since Last Sync? ", headingAttrSet);
|
||||
insertString((sourceArchive.isDirty() ? "yes" : "no") + "\n", valueAttrSet);
|
||||
insertString("Changed Since Last Sync? ", headingAttrs);
|
||||
insertString((sourceArchive.isDirty() ? "yes" : "no") + "\n", valueAttrs);
|
||||
}
|
||||
|
||||
private void insertString(String str, SimpleAttributeSet attributeSet) {
|
||||
|
@ -24,13 +24,14 @@ import docking.widgets.label.GIconLabel;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
import resources.Icons;
|
||||
|
||||
/**
|
||||
* Panel to show whether tree name and tree structure changed.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
class TreeChangePanel extends JPanel {
|
||||
|
||||
@ -74,9 +75,7 @@ class TreeChangePanel extends JPanel {
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
treeNameLabel = new GDLabel("Tree Name");
|
||||
Font font = treeNameLabel.getFont();
|
||||
font = font.deriveFont(Font.BOLD);
|
||||
treeNameLabel.setFont(font);
|
||||
Gui.registerFont(treeNameLabel, Font.BOLD);
|
||||
|
||||
nameLabel = new GDLabel("Name Changed");
|
||||
nameIconLabel = new GIconLabel(CHANGED_ICON);
|
||||
|
@ -27,8 +27,8 @@ import ghidra.util.Msg;
|
||||
/**
|
||||
* Panel that shows the current conflict number and the total number of
|
||||
* conflicts.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ConflictCountPanel extends JPanel {
|
||||
|
||||
@ -87,7 +87,6 @@ public class ConflictCountPanel extends JPanel {
|
||||
set.addAttribute(StyleConstants.Foreground, Messages.ERROR);
|
||||
|
||||
textAttrSet = new SimpleAttributeSet();
|
||||
textAttrSet.addAttribute(StyleConstants.FontSize, 12);
|
||||
|
||||
countAttrSet = new SimpleAttributeSet();
|
||||
countAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
|
||||
|
@ -22,6 +22,7 @@ import javax.swing.*;
|
||||
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.options.CustomOptionsEditor;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
|
||||
@ -109,7 +110,7 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
|
||||
}
|
||||
|
||||
label = new GDLabel("TOTAL", SwingConstants.RIGHT);
|
||||
label.setFont(label.getFont().deriveFont(Font.BOLD));
|
||||
Gui.registerFont(label, Font.BOLD);
|
||||
panel.add(label);
|
||||
|
||||
JTextField valueField =
|
||||
|
@ -25,6 +25,7 @@ import docking.widgets.OptionDialog;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.GenericRunInfo;
|
||||
import ghidra.framework.model.ProjectLocator;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
@ -91,8 +92,8 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
archiveField.setText(archivePathName);
|
||||
}
|
||||
});
|
||||
Font font = archiveBrowse.getFont();
|
||||
archiveBrowse.setFont(font.deriveFont(Font.BOLD));
|
||||
|
||||
Gui.registerFont(archiveBrowse, Font.BOLD);
|
||||
archiveBrowse.setName("archiveBrowse");
|
||||
|
||||
// Layout the components.
|
||||
@ -179,7 +180,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
* @param pArchivePathName the archive file name to display when the dialog pops up.
|
||||
* @param tool the tool
|
||||
*
|
||||
* @return true if the user submitted valid values for the project and
|
||||
* @return true if the user submitted valid values for the project and
|
||||
* archive file, false if user cancelled.
|
||||
*/
|
||||
public boolean showDialog(ProjectLocator pProjectLocator, String pArchivePathName,
|
||||
@ -222,7 +223,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Check the entry to determine if the user input is valid for archiving
|
||||
* Check the entry to determine if the user input is valid for archiving
|
||||
* a project.
|
||||
*
|
||||
* @return boolean true if input is OK
|
||||
@ -269,8 +270,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
return file.getAbsolutePath()
|
||||
.toLowerCase()
|
||||
.endsWith(
|
||||
ArchivePlugin.ARCHIVE_EXTENSION);
|
||||
.endsWith(ArchivePlugin.ARCHIVE_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -302,7 +302,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Brings up a file chooser for the user to specify a directory and
|
||||
* Brings up a file chooser for the user to specify a directory and
|
||||
* filename of the archive file.
|
||||
* @param approveButtonText The label for the "Open" button on the file chooser
|
||||
* @param approveToolTip The tool tip for the "Open" button on the file chooser
|
||||
@ -311,8 +311,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
private String chooseArchiveFile(String approveButtonText, String approveToolTip) {
|
||||
|
||||
GhidraFileChooser jarFileChooser =
|
||||
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
|
||||
archivePathName);
|
||||
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", archivePathName);
|
||||
jarFileChooser.setTitle("Archive a Ghidra Project");
|
||||
File jarFile = null;
|
||||
if (archivePathName != null && archivePathName.length() != 0) {
|
||||
|
@ -26,6 +26,7 @@ import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.GenericRunInfo;
|
||||
import ghidra.framework.model.ProjectLocator;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
@ -33,7 +34,7 @@ import ghidra.util.*;
|
||||
import ghidra.util.filechooser.ExtensionFileFilter;
|
||||
|
||||
/**
|
||||
* Dialog to prompt the user for the archive file to restore
|
||||
* Dialog to prompt the user for the archive file to restore
|
||||
* and where to restore it to.
|
||||
*/
|
||||
public class RestoreDialog extends ReusableDialogComponentProvider {
|
||||
@ -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 ");
|
||||
restoreField = new JTextField();
|
||||
@ -129,8 +130,8 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
|
||||
restoreField.setText(dirPath);
|
||||
}
|
||||
});
|
||||
font = restoreBrowse.getFont();
|
||||
restoreBrowse.setFont(font.deriveFont(Font.BOLD));
|
||||
|
||||
Gui.registerFont(restoreBrowse, Font.BOLD);
|
||||
|
||||
projectNameLabel = new GDLabel(" Project Name ");
|
||||
projectNameField = new JTextField();
|
||||
@ -365,7 +366,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory chooser for selecting the directory where the
|
||||
* Creates a directory chooser for selecting the directory where the
|
||||
* archive will be restored..
|
||||
* @return the file chooser.
|
||||
*/
|
||||
@ -380,7 +381,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Brings up a file chooser for the user to specify a directory and
|
||||
* Brings up a file chooser for the user to specify a directory and
|
||||
* filename that are used for the Project location and name
|
||||
* @param approveButtonText The label for the "Open" button on the file chooser
|
||||
* @param approveToolTip The tool tip for the "Open" button on the file chooser
|
||||
@ -389,8 +390,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
|
||||
String chooseArchiveFile(String approveButtonText, String approveToolTip) {
|
||||
|
||||
GhidraFileChooser jarFileChooser =
|
||||
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
|
||||
archivePathName);
|
||||
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", archivePathName);
|
||||
jarFileChooser.setTitle("Restore a Ghidra Project - Archive");
|
||||
String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR);
|
||||
if (lastDirSelected != null) {
|
||||
|
@ -16,12 +16,13 @@
|
||||
package ghidra.app.plugin.core.comments;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.CommentHistory;
|
||||
import ghidra.program.model.listing.Program;
|
||||
@ -36,8 +37,8 @@ import ghidra.util.Msg;
|
||||
class CommentHistoryPanel extends JPanel {
|
||||
|
||||
private final static String NO_HISTORY = "No History Found";
|
||||
private SimpleAttributeSet userAttrSet;
|
||||
private SimpleAttributeSet dateAttrSet;
|
||||
private SimpleAttributeSet userAttrs;
|
||||
private SimpleAttributeSet dateAttrs;
|
||||
private SimpleAttributeSet textAttrSet;
|
||||
private SimpleAttributeSet tabAttrSet;
|
||||
|
||||
@ -47,7 +48,7 @@ class CommentHistoryPanel extends JPanel {
|
||||
private int commentType;
|
||||
|
||||
/**
|
||||
* Construct a new CommentHistoryPanel
|
||||
* Construct a new CommentHistoryPanel
|
||||
* @param commentType comment type
|
||||
*/
|
||||
CommentHistoryPanel(int commentType) {
|
||||
@ -60,7 +61,7 @@ class CommentHistoryPanel extends JPanel {
|
||||
|
||||
/**
|
||||
* Show the comment history
|
||||
* @param program program
|
||||
* @param program program
|
||||
* @param addr address of comment history
|
||||
*/
|
||||
void showCommentHistory(Program program, Address addr) {
|
||||
@ -100,11 +101,11 @@ class CommentHistoryPanel extends JPanel {
|
||||
if (offset > 0) {
|
||||
userName = "\n" + userName;
|
||||
}
|
||||
doc.insertString(offset, userName, userAttrSet);
|
||||
doc.insertString(offset, userName, userAttrs);
|
||||
|
||||
offset = doc.getLength();
|
||||
doc.insertString(offset,
|
||||
"\t" + DateUtils.formatDateTimestamp(history.getModificationDate()), dateAttrSet);
|
||||
"\t" + DateUtils.formatDateTimestamp(history.getModificationDate()), dateAttrs);
|
||||
doc.setParagraphAttributes(offset, 1, tabAttrSet, false);
|
||||
|
||||
offset = doc.getLength();
|
||||
@ -112,25 +113,13 @@ class CommentHistoryPanel extends JPanel {
|
||||
}
|
||||
|
||||
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();
|
||||
userAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
userAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
|
||||
userAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
|
||||
userAttrSet.addAttribute(StyleConstants.Foreground,
|
||||
new GColor("color.fg.plugin.comments.history.user"));
|
||||
|
||||
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"));
|
||||
Font bold = Gui.getFont("font.standard.bold");
|
||||
Font monospaced = Gui.getFont("font.monospaced");
|
||||
textAttrSet =
|
||||
new GAttributes(monospaced, new GColor("color.fg.plugin.comments.history.text"));
|
||||
userAttrs = new GAttributes(bold, new GColor("color.fg.plugin.comments.history.user"));
|
||||
dateAttrs = new GAttributes(bold, new GColor("color.fg.plugin.comments.history.date"));
|
||||
|
||||
tabAttrSet = new SimpleAttributeSet();
|
||||
TabStop tabs = new TabStop(100, StyleConstants.ALIGN_LEFT, TabStop.LEAD_NONE);
|
||||
|
@ -39,6 +39,7 @@ import docking.widgets.pathmanager.PathnameTablePanel;
|
||||
import docking.widgets.table.GTableCellRenderer;
|
||||
import docking.widgets.table.GTableCellRenderingData;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.app.plugin.core.processors.SetLanguageDialog;
|
||||
import ghidra.app.util.cparser.C.CParserUtils;
|
||||
import ghidra.framework.Application;
|
||||
@ -371,8 +372,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
|
||||
updateArchitectureDescription();
|
||||
|
||||
languageButton.setName("Set Processor Architecture");
|
||||
Font font = languageButton.getFont();
|
||||
languageButton.setFont(font.deriveFont(Font.BOLD));
|
||||
Gui.registerFont(languageButton, Font.BOLD);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(languageTextField, BorderLayout.CENTER);
|
||||
|
@ -246,8 +246,6 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
|
||||
|
||||
signatureFieldUndoRedoKeeper = DockingUtils.installUndoRedo(signatureTextField);
|
||||
|
||||
Font font = signatureTextField.getFont();
|
||||
signatureTextField.setFont(font.deriveFont(18.0f));
|
||||
panel.add(signatureTextField);
|
||||
|
||||
signatureTextField.setEscapeListener(e -> {
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.function.editor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -26,12 +27,16 @@ import javax.swing.text.*;
|
||||
|
||||
import docking.actions.KeyBindingUtils;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
class FunctionSignatureTextField extends JTextPane {
|
||||
private static final String ENTER_ACTION_NAME = "ENTER";
|
||||
private static final String ESCAPE_ACTION_NAME = "ESCAPE";
|
||||
private static final String TAB_ACTION_NAME = "TAB";
|
||||
|
||||
private static final String FONT_ID = "font.plugin.function.text.editor";
|
||||
|
||||
public static Color DEFAULT_COLOR =
|
||||
new GColor("color.fg.plugin.function.editor.dialog.textfield.default");
|
||||
public static Color PARAMETER_NAME_COLOR =
|
||||
@ -52,8 +57,7 @@ class FunctionSignatureTextField extends JTextPane {
|
||||
private SimpleAttributeSet errorAttributes;
|
||||
|
||||
FunctionSignatureTextField() {
|
||||
Font myFont = getFont();
|
||||
setFont(myFont.deriveFont(24.0f));
|
||||
Gui.registerFont(this, FONT_ID);
|
||||
doc = getStyledDocument();
|
||||
AttributeSet inputAttributes = getInputAttributes();
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package docking.widgets.textarea;
|
||||
package ghidra.app.plugin.core.instructionsearch.ui;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@ -23,8 +23,8 @@ import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
|
||||
/**
|
||||
* Simple text area that shows a text hint when the field is empty.
|
||||
*
|
||||
* Simple text area that shows a text hint when the field is empty.
|
||||
*
|
||||
* Hint text will be shown in light grey, italicized, and in angle brackets. Normal text will
|
||||
* be plain black.
|
||||
*/
|
||||
@ -34,7 +34,7 @@ public class HintTextArea extends JTextArea {
|
||||
|
||||
/**
|
||||
* Constructs the class with the hint text to be shown.
|
||||
*
|
||||
*
|
||||
* @param hint the hint
|
||||
*/
|
||||
public HintTextArea(String hint) {
|
||||
@ -42,8 +42,8 @@ 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
|
||||
*/
|
||||
@Override
|
||||
@ -74,7 +74,27 @@ public class HintTextArea extends JTextArea {
|
||||
* Sets the text attributes to be used when NOT viewing the hint.
|
||||
*/
|
||||
protected void setAttributes() {
|
||||
this.setFont(getFont().deriveFont(Font.PLAIN));
|
||||
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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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 user of what type of input is required.
|
||||
private HintTextAreaIS inputBytesTA;
|
||||
private HintTextArea inputBytesTA;
|
||||
|
||||
private SelectionModeWidget selectionModeWidget;
|
||||
private EndianFlipWidget endianFlipWidget;
|
||||
@ -79,7 +79,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param program the current program
|
||||
* @param dialog the parent search dialog
|
||||
*/
|
||||
@ -108,7 +108,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
* Load a set of bytes (in string form; hex or binary) into the search
|
||||
* dialog. The bytes are disassembled and displayed in the
|
||||
* {@link InstructionTable}.
|
||||
*
|
||||
*
|
||||
* @param bytes the bytes to load
|
||||
*/
|
||||
public void loadBytes(String bytes) {
|
||||
@ -139,7 +139,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
|
||||
/**
|
||||
* Creates the visual components for this dialog.
|
||||
*
|
||||
*
|
||||
* @return the new panel
|
||||
*/
|
||||
protected JPanel createWorkPanel() {
|
||||
@ -148,7 +148,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
contentPanel.setMinimumSize(new Dimension(500, 300));
|
||||
|
||||
// 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);
|
||||
inputBytesTA.addKeyListener(this);
|
||||
|
||||
@ -188,7 +188,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
msgPanel.clear();
|
||||
|
||||
// When bringing up the dialog, always populate it with whatever is in the main dialog so
|
||||
// the user can edit those instructions if desired. And make sure to set the entire
|
||||
// the user can edit those instructions if desired. And make sure to set the entire
|
||||
// string to be selected so they can quickly delete them with a single keystroke.
|
||||
//
|
||||
// Note: To get the correct string for the instruction, we go to the search data
|
||||
@ -251,20 +251,20 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
List<Byte> allBytes = InstructionSearchUtils.toByteArray(input);
|
||||
|
||||
// Now we have a valid byte string so we can start disassembling. To do this, we pass
|
||||
// the entire string to the pseudo-disassembler and it will return the first
|
||||
// the entire string to the pseudo-disassembler and it will return the first
|
||||
// instruction. We save that one off, then remove those bytes from the main string and
|
||||
// pass the now-shorter string to the disassembler, where it will return the next
|
||||
// pass the now-shorter string to the disassembler, where it will return the next
|
||||
// instruction, and so on, and so on...
|
||||
//
|
||||
// TODO: Possibly modify the PseudoDisassembler to disassemble the entire thing at
|
||||
// TODO: Possibly modify the PseudoDisassembler to disassemble the entire thing at
|
||||
// once, not just one instruction at a time.
|
||||
//
|
||||
// NOTE: Some instructions have operands that cannot be accurately calculated
|
||||
// without having a specific instruction instance (ie: an operand that is an
|
||||
// without having a specific instruction instance (ie: an operand that is an
|
||||
// offset from the instruction address). This is obviously problematic because we
|
||||
// aren't dealing with 'real' instructions that map to an address in a program;
|
||||
// we're just loading bytes and trying to figure out what instructions they
|
||||
// might represent. In these cases we just use the minimum address of the loaded
|
||||
// aren't dealing with 'real' instructions that map to an address in a program;
|
||||
// we're just loading bytes and trying to figure out what instructions they
|
||||
// might represent. In these cases we just use the minimum address of the loaded
|
||||
// program as the base address.
|
||||
|
||||
List<InstructionMetadata> instructions = new ArrayList<>();
|
||||
@ -272,7 +272,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
while (allBytes.size() > 0) {
|
||||
try {
|
||||
|
||||
// First call the disassembler to get the first instruction.
|
||||
// First call the disassembler to get the first instruction.
|
||||
Byte[] bytearray = new Byte[allBytes.size()];
|
||||
bytearray = allBytes.toArray(bytearray);
|
||||
|
||||
@ -318,10 +318,10 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
/**
|
||||
* Creates {@link OperandMetadata} objects for each operand in the
|
||||
* instruction provided.
|
||||
*
|
||||
*
|
||||
* @param instruction the instruction to parse
|
||||
* @return list of operand metadata
|
||||
* @throws MemoryAccessException
|
||||
* @throws MemoryAccessException if there is an exception getting instruction bytes
|
||||
*/
|
||||
private List<OperandMetadata> createOperandMetadata(PseudoInstruction instruction)
|
||||
throws MemoryAccessException {
|
||||
@ -334,7 +334,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
operandMD.setOpType(instruction.getOperandType(i));
|
||||
operandMD.setTextRep(instruction.getDefaultOperandRepresentation(i));
|
||||
|
||||
// The mask container is a bit tricky. The mask string we can get directly from the
|
||||
// The mask container is a bit tricky. The mask string we can get directly from the
|
||||
// prototype object in the pseudo instruction. For the value string we have to do
|
||||
// a bit of calculating: we know the entire instruction byte string and we know
|
||||
// this operand mask, so AND them together and we get the operand bytes.
|
||||
@ -353,15 +353,15 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
/**
|
||||
* Creates a {@link InstructionMetadata} object for the instruction
|
||||
* provided.
|
||||
*
|
||||
*
|
||||
* @param instruction the instruction to parse
|
||||
* @return the instruction metadata
|
||||
* @throws MemoryAccessException
|
||||
* @throws MemoryAccessException if there is an exception getting instruction bytes
|
||||
*/
|
||||
private InstructionMetadata createInstructionMetadata(PseudoInstruction instruction)
|
||||
throws MemoryAccessException {
|
||||
|
||||
// The mask array we can get directly from the prototype. For the value array we
|
||||
// The mask array we can get directly from the prototype. For the value array we
|
||||
// have to figure out which bits pertain to operands and just zero them out, so we're
|
||||
// just left with the instruction (mnemonic) bits.
|
||||
InstructionPrototype prototype = instruction.getPrototype();
|
||||
@ -387,7 +387,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
* <li>value = 01101100 10001110</li>
|
||||
* <li>--------------------------</li>
|
||||
* <li>ret = 01101000 10000000</li>
|
||||
*
|
||||
*
|
||||
* @param mask the mnemonic mask
|
||||
* @param value the full instruction value string
|
||||
* @return the cleared byte array
|
||||
@ -400,7 +400,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
* Verifies that the input entered by the user is valid. Meaning:
|
||||
* <li>The string represents a hex or binary number.</li>
|
||||
* <li>The string contains only full bytes.</li>
|
||||
*
|
||||
*
|
||||
* @return true if input is valid
|
||||
*/
|
||||
public boolean validateInput() {
|
||||
@ -409,7 +409,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
|
||||
/**
|
||||
* Verifies that the given string is valid binary or hex input.
|
||||
*
|
||||
*
|
||||
* @param input the string to validate
|
||||
* @return true if valid
|
||||
*/
|
||||
@ -480,7 +480,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
|
||||
/**
|
||||
* Flags the given string as invalid input
|
||||
*
|
||||
*
|
||||
*/
|
||||
public void setInputInvalid() {
|
||||
inputBytesTA.setError();
|
||||
@ -505,12 +505,12 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
|
||||
/**
|
||||
* Need to capture keystrokes so we can validate input on the fly. Every
|
||||
* time a character is typed we check the entire input for correctness.
|
||||
*
|
||||
*
|
||||
* Note that this MUST be done in the release handler; in the type or press
|
||||
* handler the input widget has not officially been updated with the new
|
||||
* character.
|
||||
*
|
||||
* @param e
|
||||
*
|
||||
* @param e the event
|
||||
*/
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
|
@ -17,8 +17,8 @@ package ghidra.app.plugin.core.instructionsearch.ui;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import docking.widgets.table.GTableCellRenderingData;
|
||||
import generic.theme.Gui;
|
||||
@ -45,20 +45,12 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
|
||||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
|
||||
Object value = data.getValue();
|
||||
JTable table = data.getTable();
|
||||
int column = data.getColumnViewIndex();
|
||||
|
||||
boolean isSelected = data.isSelected();
|
||||
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) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Get the data object backing the cell.
|
||||
InstructionTableDataObject dataObject = (InstructionTableDataObject) value;
|
||||
String strData = dataObject.getData();
|
||||
|
||||
@ -66,7 +58,7 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
|
||||
|
||||
JLabel theRenderer = (JLabel) super.getTableCellRendererComponent(renderData);
|
||||
|
||||
setTextAttributes(table, value, column);
|
||||
setTextAttributes();
|
||||
setBackgroundAttributes(isSelected, hasFocus, dataObject);
|
||||
setBorderAttributes(dataObject, theRenderer);
|
||||
setForegroundAttributes(dataObject, theRenderer);
|
||||
@ -80,8 +72,6 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
|
||||
|
||||
private void setForegroundAttributes(InstructionTableDataObject dataObject,
|
||||
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());
|
||||
Font newFont = theRenderer.getFont().deriveFont(dataObject.getFontStyle());
|
||||
theRenderer.setFont(newFont);
|
||||
@ -89,8 +79,6 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
|
||||
|
||||
private void setBackgroundAttributes(boolean isSelected, boolean hasFocus,
|
||||
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();
|
||||
if (backgroundColor != null) {
|
||||
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);
|
||||
TableModel model = table.getModel();
|
||||
configureFont(table, model, col);
|
||||
setFont(getDefaultFont());
|
||||
setOpaque(true);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import javax.swing.event.ListDataListener;
|
||||
|
||||
import docking.widgets.list.GListCellRenderer;
|
||||
import generic.theme.GThemeDefaults.Colors.Tooltips;
|
||||
import generic.theme.Gui;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.app.plugin.core.console.CodeCompletion;
|
||||
|
||||
@ -34,23 +35,25 @@ import ghidra.app.plugin.core.console.CodeCompletion;
|
||||
*/
|
||||
public class CodeCompletionWindow extends JDialog {
|
||||
|
||||
private static final String FONT_ID = "font.plugin.terminal.completion.list";
|
||||
|
||||
protected final InterpreterPanel console;
|
||||
protected final JTextPane outputTextField;
|
||||
/* List of CodeCompletions.
|
||||
* If the substitution value is null, then that attribute will not be
|
||||
* selectable for substitution.
|
||||
*/
|
||||
protected List<CodeCompletion> completion_list;
|
||||
protected List<CodeCompletion> completionData;
|
||||
/* current list of completions */
|
||||
protected JList jlist;
|
||||
protected JList<CodeCompletion> jlist;
|
||||
|
||||
public CodeCompletionWindow(Window parent, InterpreterPanel cp, JTextPane textField) {
|
||||
super(parent);
|
||||
|
||||
this.console = cp;
|
||||
outputTextField = textField;
|
||||
jlist = new JList();
|
||||
completion_list = null;
|
||||
jlist = new JList<>();
|
||||
completionData = null;
|
||||
|
||||
setUndecorated(true);
|
||||
/* don't steal focus from text input! */
|
||||
@ -58,14 +61,14 @@ public class CodeCompletionWindow extends JDialog {
|
||||
|
||||
jlist.setBackground(Tooltips.BACKGROUND);
|
||||
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() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
/* when the user clicks the popup window, make sure
|
||||
* that the outputTextField gets the focus (so that the escape
|
||||
* key and other hotkeys to manage the popup work correctly
|
||||
*/
|
||||
// when the user clicks the popup window, make sure that the outputTextField gets
|
||||
// the focus (so that the escape key and other hotkeys to manage the popup work
|
||||
// correctly
|
||||
outputTextField.requestFocusInWindow();
|
||||
/* double-click inserts a completion */
|
||||
if (e.getClickCount() == 2) {
|
||||
@ -74,9 +77,9 @@ public class CodeCompletionWindow extends JDialog {
|
||||
}
|
||||
};
|
||||
jlist.addMouseListener(mouseListener);
|
||||
/* actually put the components together */
|
||||
|
||||
getContentPane().add(new JScrollPane(jlist));
|
||||
updateCompletionList(completion_list);
|
||||
updateCompletionList(completionData);
|
||||
|
||||
jlist.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
@ -121,7 +124,7 @@ public class CodeCompletionWindow extends JDialog {
|
||||
* @param list List of code completions
|
||||
*/
|
||||
public void updateCompletionList(List<CodeCompletion> list) {
|
||||
completion_list = list;
|
||||
completionData = list;
|
||||
jlist.setModel(new CodeCompletionListModel(list));
|
||||
jlist.setSelectionModel(new CodeCompletionListSelectionModel(list));
|
||||
jlist.clearSelection();
|
||||
@ -247,7 +250,7 @@ public class CodeCompletionWindow extends JDialog {
|
||||
*/
|
||||
@Override
|
||||
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() {
|
||||
for (int i = jlist.getSelectedIndex() - 1; i >= 0; i--) {
|
||||
CodeCompletion completion = completion_list.get(i);
|
||||
CodeCompletion completion = completionData.get(i);
|
||||
if (CodeCompletion.isValid(completion)) {
|
||||
jlist.setSelectedIndex(i);
|
||||
jlist.ensureIndexIsVisible(i);
|
||||
@ -271,11 +274,11 @@ public class CodeCompletionWindow extends JDialog {
|
||||
*/
|
||||
public void selectNext() {
|
||||
|
||||
if (null == completion_list) {
|
||||
if (null == completionData) {
|
||||
return;
|
||||
}
|
||||
for (int i = jlist.getSelectedIndex() + 1; i < completion_list.size(); i++) {
|
||||
CodeCompletion completion = completion_list.get(i);
|
||||
for (int i = jlist.getSelectedIndex() + 1; i < completionData.size(); i++) {
|
||||
CodeCompletion completion = completionData.get(i);
|
||||
if (CodeCompletion.isValid(completion)) {
|
||||
jlist.setSelectedIndex(i);
|
||||
jlist.ensureIndexIsVisible(i);
|
||||
@ -296,18 +299,18 @@ public class CodeCompletionWindow extends JDialog {
|
||||
if (-1 == i) {
|
||||
return null;
|
||||
}
|
||||
return completion_list.get(i);
|
||||
return completionData.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Code completion ListModel.
|
||||
*/
|
||||
class CodeCompletionListModel implements ListModel {
|
||||
List<CodeCompletion> completion_list;
|
||||
class CodeCompletionListModel implements ListModel<CodeCompletion> {
|
||||
List<CodeCompletion> completionData;
|
||||
|
||||
public CodeCompletionListModel(List<CodeCompletion> completion_list) {
|
||||
this.completion_list = completion_list;
|
||||
this.completionData = completion_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -321,22 +324,22 @@ class CodeCompletionListModel implements ListModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
if ((null == completion_list) || completion_list.isEmpty()) {
|
||||
public CodeCompletion getElementAt(int index) {
|
||||
if ((null == completionData) || completionData.isEmpty()) {
|
||||
if (0 == index) {
|
||||
return new CodeCompletion("(no completions available)", null, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return completion_list.get(index);
|
||||
return completionData.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
if ((null == completion_list) || completion_list.isEmpty()) {
|
||||
if ((null == completionData) || completionData.isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
return completion_list.size();
|
||||
return completionData.size();
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,12 +408,8 @@ class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends CodeCompletion> list,
|
||||
CodeCompletion codeCompletion, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
if (codeCompletion.getComponent() == null) {
|
||||
return super.getListCellRendererComponent(list, codeCompletion, index, isSelected,
|
||||
cellHasFocus);
|
||||
}
|
||||
|
||||
JComponent component = codeCompletion.getComponent();
|
||||
JLabel component = (JLabel) super.getListCellRendererComponent(list, codeCompletion, index,
|
||||
isSelected, cellHasFocus);
|
||||
|
||||
// if it's selected, make sure it shows up that way
|
||||
component.setOpaque(true);
|
||||
|
@ -28,8 +28,7 @@ import javax.swing.text.*;
|
||||
|
||||
import docking.DockingUtils;
|
||||
import docking.actions.KeyBindingUtils;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.Gui;
|
||||
import generic.theme.*;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.app.plugin.core.console.CodeCompletion;
|
||||
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. " +
|
||||
"Double-click the font example to change it.";
|
||||
|
||||
private static final Color NORMAL_COLOR = new GColor("color.fg.interpreterconsole");
|
||||
private static final Color ERROR_COLOR = new GColor("color.fg.interpreterconsole.error");
|
||||
private static final Color BG_COLOR = new GColor("color.bg.interpreterconsole");
|
||||
private static final GColor NORMAL_COLOR = new GColor("color.fg.interpreterconsole");
|
||||
private static final GColor ERROR_COLOR = new GColor("color.fg.interpreterconsole.error");
|
||||
private static final GColor BG_COLOR = new GColor("color.bg.interpreterconsole");
|
||||
|
||||
public enum TextType {
|
||||
STDOUT, STDERR, STDIN;
|
||||
@ -84,16 +83,6 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
|
||||
private boolean caretGuard = true;
|
||||
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) {
|
||||
this.tool = tool;
|
||||
this.interpreter = interpreter;
|
||||
@ -373,9 +362,11 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
|
||||
|
||||
private void updateFontAttributes(Font font) {
|
||||
Font boldFont = font.deriveFont(Font.BOLD);
|
||||
STDOUT_SET = createAttributes(font, NORMAL_COLOR);
|
||||
STDERR_SET = createAttributes(font, ERROR_COLOR);
|
||||
STDIN_SET = createAttributes(boldFont, NORMAL_COLOR);
|
||||
|
||||
STDOUT_SET = new GAttributes(font, 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(promptTextPane, font);
|
||||
@ -389,8 +380,7 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
|
||||
HelpLocation help = new HelpLocation(getName(), "ConsolePlugin");
|
||||
options.setOptionsHelpLocation(help);
|
||||
|
||||
options.registerThemeFontBinding(FONT_OPTION_LABEL, FONT_ID, help,
|
||||
FONT_DESCRIPTION);
|
||||
options.registerThemeFontBinding(FONT_OPTION_LABEL, FONT_ID, help, FONT_DESCRIPTION);
|
||||
options.registerOption(COMPLETION_WINDOW_TRIGGER_LABEL, CompletionWindowTrigger.TAB, help,
|
||||
COMPLETION_WINDOW_TRIGGER_DESCRIPTION);
|
||||
|
||||
@ -490,8 +480,8 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
|
||||
completionInsertionPosition = inputTextPane.getCaretPosition();
|
||||
|
||||
String text = getInputTextPaneText();
|
||||
List<CodeCompletion> completions = InterpreterPanel.this.interpreter.getCompletions(
|
||||
text, completionInsertionPosition);
|
||||
List<CodeCompletion> completions =
|
||||
InterpreterPanel.this.interpreter.getCompletions(text, completionInsertionPosition);
|
||||
completionWindow.updateCompletionList(completions);
|
||||
});
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||
private DockingAction deleteAction;
|
||||
private DockingAction setBaseAction;
|
||||
|
||||
private MemoryMapPlugin plugin = null;
|
||||
private MemoryMapPlugin plugin;
|
||||
|
||||
private Program program;
|
||||
private MemoryMapManager memManager;
|
||||
@ -135,8 +135,12 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||
table.installNavigation(tool);
|
||||
table.setAutoCreateColumnsFromModel(false);
|
||||
|
||||
GTableCellRenderer monoRenderer = new GTableCellRenderer();
|
||||
monoRenderer.setFont(monoRenderer.getFixedWidthFont());
|
||||
GTableCellRenderer monoRenderer = new GTableCellRenderer() {
|
||||
@Override
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
};
|
||||
|
||||
TableColumn column = table.getColumn(MemoryMapModel.START_COL);
|
||||
column.setCellRenderer(monoRenderer);
|
||||
|
@ -1019,8 +1019,6 @@ public class EditReferencesProvider extends ComponentProviderAdapter
|
||||
private class RefCellTextRenderer extends GTableCellRenderer {
|
||||
|
||||
RefCellTextRenderer() {
|
||||
defaultFont = getFont();
|
||||
boldFont = defaultFont.deriveFont(defaultFont.getStyle() | Font.BOLD);
|
||||
setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ import docking.widgets.OptionDialog;
|
||||
import docking.widgets.table.*;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.app.cmd.register.SetRegisterCmd;
|
||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||
import ghidra.app.services.MarkerService;
|
||||
@ -498,7 +497,11 @@ class RegisterValueRenderer extends GTableCellRenderer {
|
||||
|
||||
RegisterValueRenderer(JTable table) {
|
||||
setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
|
||||
Gui.registerFont(this, "font.monospaced");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,6 +28,7 @@ import javax.swing.event.ChangeListener;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.label.GLabel;
|
||||
import generic.theme.GThemeDefaults.Ids.Fonts;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.app.util.bean.FixedBitSizeValueField;
|
||||
import ghidra.program.model.address.*;
|
||||
@ -77,8 +78,6 @@ public class SetRegisterValueDialog extends DialogComponentProvider {
|
||||
|
||||
private JComponent buildWorkPanel(Register[] registers) {
|
||||
registerComboBox = new GComboBox<>(wrapRegisters(registers));
|
||||
Font f = registerComboBox.getFont().deriveFont(13f);
|
||||
registerComboBox.setFont(f);
|
||||
registerValueField = new FixedBitSizeValueField(32, true, false);
|
||||
registerValueField.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
@ -93,11 +92,11 @@ public class SetRegisterValueDialog extends DialogComponentProvider {
|
||||
registerChanged();
|
||||
}
|
||||
});
|
||||
f = Gui.getFont("font.monospaced");
|
||||
|
||||
addressRangeList = new JList();
|
||||
addressRangeList.setEnabled(false);
|
||||
addressRangeList.setFont(f);
|
||||
Gui.registerFont(addressRangeList, Fonts.MONOSPACED);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(addressRangeList);
|
||||
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
Dimension d = scrollPane.getPreferredSize();
|
||||
|
@ -16,11 +16,12 @@
|
||||
package ghidra.app.plugin.core.scalartable;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import docking.widgets.table.*;
|
||||
import ghidra.docking.settings.Settings;
|
||||
@ -321,7 +322,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
|
||||
|
||||
//==================================================================================================
|
||||
// Columns & Column helpers
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
private class ScalarComparator implements Comparator<Scalar> {
|
||||
|
||||
@ -339,8 +340,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
|
||||
return (o1.isSigned() ? 1 : -1);
|
||||
}
|
||||
|
||||
return o1.isSigned()
|
||||
? Long.compare(o1.getSignedValue(), o2.getSignedValue())
|
||||
return o1.isSigned() ? Long.compare(o1.getSignedValue(), o2.getSignedValue())
|
||||
: Long.compareUnsigned(o1.getUnsignedValue(), o2.getUnsignedValue());
|
||||
}
|
||||
}
|
||||
@ -410,15 +410,14 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(fixedWidthFont);
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnConstraintFilterMode getColumnConstraintFilterMode() {
|
||||
return ColumnConstraintFilterMode.ALLOW_ALL_FILTERS;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
@ -440,10 +439,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
|
||||
public Scalar getValue(ScalarRowObject rowObject, Settings settings, Program p,
|
||||
ServiceProvider provider) throws IllegalArgumentException {
|
||||
Scalar scalar = rowObject.getScalar();
|
||||
|
||||
Scalar unsigned = new Scalar(scalar.bitLength(), scalar.getUnsignedValue(), false);
|
||||
return unsigned;
|
||||
|
||||
return new Scalar(scalar.bitLength(), scalar.getUnsignedValue(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ import docking.widgets.spinner.IntegerSpinner;
|
||||
import docking.widgets.table.threaded.ThreadedTableModelListener;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.GThemeDefaults;
|
||||
import ghidra.app.services.GoToService;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.app.services.StringTranslationService;
|
||||
import ghidra.app.services.StringTranslationService.TranslateOptions;
|
||||
import ghidra.docking.settings.Settings;
|
||||
@ -72,6 +72,8 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
Map.entry(CharsetInfo.UTF16, UnicodeDataType.dataType),
|
||||
Map.entry(CharsetInfo.UTF32, Unicode32DataType.dataType));
|
||||
|
||||
private static final String BUTTON_FONT_ID = "font.plugin.strings.buttons";
|
||||
|
||||
private final PluginTool tool;
|
||||
private final EncodedStringsPlugin plugin;
|
||||
private final Program program;
|
||||
@ -148,7 +150,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param charsetName set the charset
|
||||
*/
|
||||
public void setSelectedCharset(String charsetName) {
|
||||
@ -157,7 +159,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setRequireValidStringOption(boolean b) {
|
||||
@ -167,7 +169,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setAllowLatinScriptOption(boolean b) {
|
||||
@ -178,7 +180,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setAllowCommonScriptOption(boolean b) {
|
||||
@ -189,7 +191,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setAllowAnyScriptOption(boolean b) {
|
||||
@ -200,7 +202,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param requiredScript unicode script
|
||||
*/
|
||||
public void setRequiredScript(UnicodeScript requiredScript) {
|
||||
@ -210,7 +212,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setShowAdvancedOptions(boolean b) {
|
||||
@ -221,7 +223,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setShowScriptOptions(boolean b) {
|
||||
@ -232,7 +234,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setExcludeCodecErrors(boolean b) {
|
||||
@ -243,7 +245,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setExcludeNonStdCtrlChars(boolean b) {
|
||||
@ -254,7 +256,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @return table model
|
||||
*/
|
||||
public EncodedStringsTableModel getStringModel() {
|
||||
@ -263,7 +265,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
/**
|
||||
* For test/screen shot use
|
||||
*
|
||||
*
|
||||
* @return button
|
||||
*/
|
||||
public JButton getCreateButton() {
|
||||
@ -423,8 +425,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
table.setPreferredScrollableViewportSize(new Dimension(350, 150));
|
||||
table.getSelectionModel().addListSelectionListener(e -> selectedRowChange());
|
||||
|
||||
GoToService goToService = tool.getService(GoToService.class);
|
||||
table.installNavigation(goToService, goToService.getDefaultNavigatable());
|
||||
table.installNavigation(tool);
|
||||
|
||||
filterPanel = new GhidraTableFilterPanel<>(table, tableModel);
|
||||
}
|
||||
@ -454,7 +455,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// Note: we override the [ENTER] key handling to allow the user to invoke the
|
||||
// dialog and just hit enter to create the string without having to do any
|
||||
// clicking (otherwise the charset combobox consumes the keystroke)
|
||||
// clicking (otherwise the charset combobox consumes the keystroke)
|
||||
if (e.getKeyChar() == '\n') {
|
||||
e.consume();
|
||||
if (charsetComboBox.isPopupVisible()) {
|
||||
@ -604,10 +605,10 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
scriptFailedCountLabel
|
||||
.setToolTipText("Number of strings excluded due to failing script requirements.");
|
||||
|
||||
Font font = new JPanel().getFont().deriveFont(10.0f);
|
||||
allowLatinScriptButton = new JToggleButton("A-Z");
|
||||
allowLatinScriptButton.setName("ALLOW_LATIN_SCRIPT");
|
||||
allowLatinScriptButton.setFont(font);
|
||||
Gui.registerFont(allowLatinScriptButton, BUTTON_FONT_ID);
|
||||
|
||||
allowLatinScriptButton.setToolTipText(
|
||||
"Allow Latin characters (e.g. A-Z, etc) to also be present in the string.");
|
||||
allowLatinScriptButton.setSelected(true);
|
||||
@ -620,7 +621,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
allowCommonScriptButton = new JToggleButton("0-9,!?");
|
||||
allowCommonScriptButton.setName("ALLOW_COMMON_SCRIPT");
|
||||
allowCommonScriptButton.setFont(font);
|
||||
Gui.registerFont(allowCommonScriptButton, BUTTON_FONT_ID);
|
||||
allowCommonScriptButton.setToolTipText(
|
||||
"Allow common characters (e.g. 0-9, space, punctuation, etc) to also be present in the string.");
|
||||
allowCommonScriptButton.setSelected(true);
|
||||
@ -633,7 +634,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
|
||||
allowAnyScriptButton = new JToggleButton("Any");
|
||||
allowAnyScriptButton.setName("ALLOW_ANY_SCRIPT");
|
||||
allowAnyScriptButton.setFont(font);
|
||||
Gui.registerFont(allowAnyScriptButton, BUTTON_FONT_ID);
|
||||
allowAnyScriptButton.setToolTipText(
|
||||
"Allow all other character scripts to also be present in the string.");
|
||||
allowAnyScriptButton.setSelected(true);
|
||||
@ -747,13 +748,12 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
executeMonitoredRunnable("Creating Strings", true, true, 100, this::createStringsAndClose);
|
||||
}
|
||||
|
||||
private void setActionItemEnablement(boolean b) {
|
||||
createButton.setEnabled(b);
|
||||
cancelButton.setEnabled(b);
|
||||
private void setActionItemEnablement(boolean enabled) {
|
||||
createButton.setEnabled(enabled);
|
||||
cancelButton.setEnabled(enabled);
|
||||
table.removeNavigation();
|
||||
if (b) {
|
||||
GoToService goToService = tool.getService(GoToService.class);
|
||||
table.installNavigation(goToService, goToService.getDefaultNavigatable());
|
||||
if (enabled) {
|
||||
table.installNavigation(tool);
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,11 +834,10 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
createButton.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
String createMessage = isSingleStringMode()
|
||||
? "Create"
|
||||
: "Create %s".formatted(rowCount == selectedRowCount || selectedRowCount == 0
|
||||
? "All"
|
||||
: "Selected (%d)".formatted(selectedRowCount));
|
||||
String createMessage = isSingleStringMode() ? "Create"
|
||||
: "Create %s"
|
||||
.formatted(rowCount == selectedRowCount || selectedRowCount == 0 ? "All"
|
||||
: "Selected (%d)".formatted(selectedRowCount));
|
||||
createButton.setEnabled(true);
|
||||
createButton.setText(createMessage);
|
||||
|
||||
@ -954,8 +953,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
return null;
|
||||
}
|
||||
File f = new File(filename);
|
||||
ResourceFile rf = f.isAbsolute() && f.isFile()
|
||||
? new ResourceFile(f)
|
||||
ResourceFile rf = f.isAbsolute() && f.isFile() ? new ResourceFile(f)
|
||||
: Application.findDataFileInAnyModule(filename);
|
||||
if (rf == null) {
|
||||
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) {
|
||||
boolean enabled = showTranslateOptionsButton.isSelected();
|
||||
return ifEnabled && !enabled
|
||||
? null
|
||||
return ifEnabled && !enabled ? null
|
||||
: (StringTranslationService) translateComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
@ -1081,7 +1078,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
|
||||
* Execute a non-modal task that has progress and can be cancelled.
|
||||
* <p>
|
||||
* See {@link #executeProgressTask(Task, int)}.
|
||||
*
|
||||
*
|
||||
* @param taskTitle String title of task
|
||||
* @param canCancel boolean flag, if true task can be canceled by the user
|
||||
* @param hasProgress boolean flag, if true the task has a progress meter
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.plugin.debug;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -59,22 +58,11 @@ public class DomainEventComponentProvider extends ComponentProviderAdapter {
|
||||
return scrollPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see docking.ComponentProvider#componentHidden()
|
||||
*/
|
||||
@Override
|
||||
public void componentHidden() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public Font getFont() {
|
||||
return textArea.getFont();
|
||||
}
|
||||
|
||||
public void setFont(Font font) {
|
||||
textArea.setFont(font);
|
||||
}
|
||||
|
||||
private void createAction() {
|
||||
clearAction = new DockingAction("Clear Display", getName()) {
|
||||
@Override
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.plugin.debug;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Date;
|
||||
|
||||
import ghidra.app.DeveloperPluginPackage;
|
||||
@ -47,28 +46,18 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
|
||||
|
||||
private Program currentProgram;
|
||||
private DomainEventComponentProvider provider;
|
||||
private String padString;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DomainEventDisplayPlugin(PluginTool tool) {
|
||||
|
||||
super(tool);
|
||||
|
||||
String dateStr = new Date() + ": ";
|
||||
padString = dateStr.replaceAll(".", " ");
|
||||
|
||||
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
|
||||
HelpService helpService = Help.getHelpService();
|
||||
helpService.excludeFromHelp(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put event processing code here.
|
||||
*/
|
||||
@Override
|
||||
public void processEvent(PluginEvent event) {
|
||||
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
|
||||
public void dispose() {
|
||||
if (currentProgram != null) {
|
||||
@ -94,9 +79,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the callback method for DomainObjectChangedEvents.
|
||||
*/
|
||||
@Override
|
||||
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||
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.
|
||||
*/
|
||||
|
@ -27,6 +27,7 @@ import javax.swing.*;
|
||||
import docking.ComponentProvider;
|
||||
import docking.Tool;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.Gui;
|
||||
import generic.util.WindowUtilities;
|
||||
import generic.util.image.ImageUtils;
|
||||
import ghidra.app.DeveloperPluginPackage;
|
||||
@ -110,6 +111,8 @@ public class WindowLocationPlugin extends Plugin {
|
||||
|
||||
private class WindowLocationPanel extends JPanel {
|
||||
|
||||
private static final String FONT_ID = "font.plugin.window.location";
|
||||
|
||||
private MouseListener mousy = new MouseListener();
|
||||
|
||||
WindowLocationPanel() {
|
||||
@ -188,9 +191,8 @@ public class WindowLocationPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private void paintWindows(Graphics2D g2d, AffineTransform xform) {
|
||||
Font f = g2d.getFont();
|
||||
Font biggerFont = f.deriveFont(40f);
|
||||
g2d.setFont(biggerFont);
|
||||
Font f = Gui.getFont(FONT_ID);
|
||||
g2d.setFont(f);
|
||||
g2d.setColor(FG_COLOR_WINDOW_TEXT);
|
||||
|
||||
Window[] windows = Window.getWindows();
|
||||
@ -423,10 +425,7 @@ public class WindowLocationPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((window == null) ? 0 : window.hashCode());
|
||||
return result;
|
||||
return Objects.hash(window);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,10 +65,12 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
|
||||
* @param fieldOptions the Options for field specific properties.
|
||||
*/
|
||||
protected AbstractVariableFieldFactory(String name, FieldFormatModel model,
|
||||
ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) {
|
||||
ListingHighlightProvider highlightProvider, Options displayOptions,
|
||||
Options fieldOptions) {
|
||||
super(name, model, highlightProvider, displayOptions, fieldOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDisplayOptions(Options displayOptions) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
// we know
|
||||
@SuppressWarnings("deprecation") // ignore getFontMetrics() deprecation warning
|
||||
private void setMetrics(Font newFont, ParameterFieldOptions paramFieldOptions) {
|
||||
paramFieldOptions.defaultMetrics = Toolkit.getDefaultToolkit().getFontMetrics(newFont);
|
||||
for (int i = 0; i < paramFieldOptions.fontMetrics.length; i++) {
|
||||
|
@ -29,7 +29,6 @@ import ghidra.framework.options.ToolOptions;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.classfinder.ExtensionPoint;
|
||||
|
||||
/**
|
||||
@ -66,8 +65,8 @@ public abstract class FieldFactory implements ExtensionPoint {
|
||||
* @param fieldOptions the Options for field specific properties.
|
||||
*/
|
||||
protected FieldFactory(String name, FieldFormatModel model,
|
||||
ListingHighlightProvider highlightProvider,
|
||||
Options displayOptions, Options fieldOptions) {
|
||||
ListingHighlightProvider highlightProvider, Options displayOptions,
|
||||
Options fieldOptions) {
|
||||
this.name = name;
|
||||
this.model = model;
|
||||
this.hlProvider = highlightProvider;
|
||||
@ -135,7 +134,7 @@ public abstract class FieldFactory implements ExtensionPoint {
|
||||
public void displayOptionsChanged(Options options, String optionName, Object oldValue,
|
||||
Object newValue) {
|
||||
if (optionName.equals(FONT_OPTION_NAME)) {
|
||||
baseFont = SystemUtilities.adjustForFontSizeOverride((Font) newValue);
|
||||
baseFont = (Font) newValue;
|
||||
setMetrics(baseFont);
|
||||
}
|
||||
else if (optionName.equals(styleOptionName)) {
|
||||
@ -225,7 +224,7 @@ public abstract class FieldFactory implements ExtensionPoint {
|
||||
/**
|
||||
* Returns true if this given field represents the given location
|
||||
* @param listingField the field
|
||||
* @param location the location
|
||||
* @param location the location
|
||||
* @return true if this given field represents the given location
|
||||
*/
|
||||
public boolean supportsLocation(ListingField listingField, ProgramLocation location) {
|
||||
|
@ -40,7 +40,6 @@ import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import ghidra.GhidraOptions;
|
||||
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.
|
||||
@ -133,13 +132,13 @@ public class OptionsGui extends JPanel {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param font the base font for the fields.
|
||||
* @param listener the listener to be notified when options change.
|
||||
*/
|
||||
public OptionsGui(Font font, PropertyChangeListener listener) {
|
||||
propertyChangeListener = listener;
|
||||
setBaseFont(SystemUtilities.adjustForFontSizeOverride(font));
|
||||
setBaseFont(font);
|
||||
genLayouts();
|
||||
buildPanel();
|
||||
fieldPanel.setBackgroundColor(BACKGROUND.getColor());
|
||||
@ -217,7 +216,7 @@ public class OptionsGui extends JPanel {
|
||||
|
||||
/**
|
||||
* callback for when the selected display field changes.
|
||||
*
|
||||
*
|
||||
* @param index the index in the JList of the selected field.
|
||||
*/
|
||||
private void setSelectedIndex(int index) {
|
||||
@ -735,7 +734,7 @@ public class OptionsGui extends JPanel {
|
||||
|
||||
/**
|
||||
* This listener will be notified when changes are made that need to be applied.
|
||||
*
|
||||
*
|
||||
* @param listener The listener to be notified.
|
||||
*/
|
||||
void setOptionsPropertyChangeListener(PropertyChangeListener listener) {
|
||||
@ -774,9 +773,9 @@ public class OptionsGui extends JPanel {
|
||||
setSelectedIndex(selectedIndex);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
/**
|
||||
* Simple layoutModel to be used for the preview panel.
|
||||
@ -850,7 +849,7 @@ public class OptionsGui extends JPanel {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param size the number of fields in the layout
|
||||
*/
|
||||
LayoutBuilder(int size) {
|
||||
|
@ -21,9 +21,8 @@ import java.util.LinkedList;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.*;
|
||||
import generic.theme.GThemeDefaults.Ids.Fonts;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.options.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.Msg;
|
||||
@ -31,9 +30,9 @@ import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.task.SwingUpdateManager;
|
||||
|
||||
/**
|
||||
/**
|
||||
* A generic text pane that is used as a console to which text can be written.
|
||||
*
|
||||
*
|
||||
* There is not test for this class, but it is indirectly tested by FrontEndGuiTest.
|
||||
*/
|
||||
public class ConsoleTextPane extends JTextPane implements OptionsChangeListener {
|
||||
@ -52,8 +51,8 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
|
||||
/** % of characters to delete when truncation is necessary */
|
||||
private static double DEFAULT_TRUNCATION_FACTOR = .10;
|
||||
|
||||
private static SimpleAttributeSet outputAttributeSet;
|
||||
private static SimpleAttributeSet errorAttributeSet;
|
||||
private static SimpleAttributeSet outputAttributes;
|
||||
private static SimpleAttributeSet errorAttributes;
|
||||
|
||||
// don't update more than once per second if lots of messages are being written
|
||||
private SwingUpdateManager updateManager = new SwingUpdateManager(100, 1000, () -> doUpdate());
|
||||
@ -99,7 +98,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
|
||||
}
|
||||
//==================================================================================================
|
||||
// Non-interface Methods
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
private void initOptions(Options options) {
|
||||
options.registerOption(MAXIMUM_CHARACTERS_OPTION_NAME, DEFAULT_MAXIMUM_CHARS, null,
|
||||
@ -192,10 +191,10 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
|
||||
|
||||
private AttributeSet getAttributeSetByName(String attributeSetName) {
|
||||
if (OUTPUT_ATTRIBUTE_VALUE.equals(attributeSetName)) {
|
||||
return outputAttributeSet;
|
||||
return outputAttributes;
|
||||
}
|
||||
else if (ERROR_ATTRIBUTE_VALUE.equals(attributeSetName)) {
|
||||
return errorAttributeSet;
|
||||
return errorAttributes;
|
||||
}
|
||||
else {
|
||||
// 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) {
|
||||
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();
|
||||
errorAttributeSet.addAttribute(CUSTOM_ATTRIBUTE_KEY, ERROR_ATTRIBUTE_VALUE);
|
||||
errorAttributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
|
||||
errorAttributeSet.addAttribute(StyleConstants.FontSize, font.getSize());
|
||||
errorAttributeSet.addAttribute(StyleConstants.Italic, font.isItalic());
|
||||
errorAttributeSet.addAttribute(StyleConstants.Bold, font.isBold());
|
||||
errorAttributeSet.addAttribute(StyleConstants.Foreground,
|
||||
new GColor("color.fg.error.consoletextpane"));
|
||||
outputAttributes = new GAttributes(font, new GColor("color.fg.consoletextpane"));
|
||||
outputAttributes.addAttribute(CUSTOM_ATTRIBUTE_KEY, OUTPUT_ATTRIBUTE_VALUE);
|
||||
|
||||
errorAttributes = new GAttributes(font, new GColor("color.fg.error.consoletextpane"));
|
||||
errorAttributes.addAttribute(CUSTOM_ATTRIBUTE_KEY, ERROR_ATTRIBUTE_VALUE);
|
||||
}
|
||||
|
||||
private void doUpdate() {
|
||||
@ -316,7 +304,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
|
||||
}
|
||||
|
||||
AttributeSet getAttributes() {
|
||||
return outputAttributeSet;
|
||||
return outputAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,7 +315,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
|
||||
|
||||
@Override
|
||||
AttributeSet getAttributes() {
|
||||
return errorAttributeSet;
|
||||
return errorAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import docking.widgets.*;
|
||||
import docking.widgets.label.*;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.Gui;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.ApplicationProperties;
|
||||
@ -44,16 +45,19 @@ class InfoPanel extends JPanel {
|
||||
|
||||
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 marking;
|
||||
private String distributionInfo;
|
||||
|
||||
private Color bgColor; // background color for all panels
|
||||
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() {
|
||||
getAboutInfo();
|
||||
@ -170,9 +174,7 @@ class InfoPanel extends JPanel {
|
||||
|
||||
private Component buildVersionLabel() {
|
||||
MultiLineLabel versionLabel = new MultiLineLabel(version, 0, 3, MultiLineLabel.CENTER);
|
||||
Font font = versionLabel.getFont();
|
||||
font = font.deriveFont(14f).deriveFont(Font.BOLD);
|
||||
versionLabel.setFont(font);
|
||||
Gui.registerFont(versionLabel, FONT_ID);
|
||||
versionLabel.setForeground(new GColor("color.fg.infopanel.version"));
|
||||
return versionLabel;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import docking.widgets.dialogs.MultiLineMessageDialog;
|
||||
import docking.widgets.label.GLabel;
|
||||
import docking.widgets.list.GListCellRenderer;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.app.services.ProgramManager;
|
||||
import ghidra.app.util.*;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
@ -240,8 +241,7 @@ public class ImporterDialog extends DialogComponentProvider {
|
||||
validateFormInput();
|
||||
});
|
||||
|
||||
Font font = languageButton.getFont();
|
||||
languageButton.setFont(font.deriveFont(Font.BOLD));
|
||||
Gui.registerFont(languageButton, Font.BOLD);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(languageTextField, BorderLayout.CENTER);
|
||||
|
@ -26,6 +26,7 @@ import javax.swing.border.Border;
|
||||
import docking.widgets.checkbox.GCheckBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.util.DefaultLanguageService;
|
||||
import ghidra.util.table.*;
|
||||
@ -67,7 +68,7 @@ public class NewLanguagePanel extends JPanel {
|
||||
tableFilterPanel = new GhidraTableFilterPanel<>(table, tableModel);
|
||||
|
||||
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.addItemListener(e -> {
|
||||
@ -211,7 +212,6 @@ public class NewLanguagePanel extends JPanel {
|
||||
LanguageCompilerSpecPair selectedLcsPair = getSelectedLcsPair();
|
||||
if (selectedLcsPair == null) {
|
||||
descriptionLabel.setText(DEFAULT_DESCRIPTION_TEXT);
|
||||
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.ITALIC));
|
||||
}
|
||||
else {
|
||||
try {
|
||||
@ -220,7 +220,6 @@ public class NewLanguagePanel extends JPanel {
|
||||
catch (LanguageNotFoundException e) {
|
||||
descriptionLabel.setText("<LanguageNotFound>");
|
||||
}
|
||||
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.PLAIN));
|
||||
}
|
||||
// notifyListenersOfValidityChanged();
|
||||
if (!listeners.isEmpty()) {
|
||||
|
@ -109,7 +109,7 @@ public class ProgramDiffDetails {
|
||||
// FUTURE : Add checks to make sure programs are comparable.
|
||||
// Throw exception if not comparable.
|
||||
initDetails();
|
||||
initAttributes();
|
||||
textAttrSet = new SimpleAttributeSet();
|
||||
}
|
||||
|
||||
private static String getIndentString(int indentCount) {
|
||||
@ -121,11 +121,6 @@ public class ProgramDiffDetails {
|
||||
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
|
||||
* address. The string contains information from each program where there are differences.
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
package ghidra.util.table.field;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.TableModel;
|
||||
import java.awt.Font;
|
||||
|
||||
import ghidra.app.plugin.core.disassembler.AddressTable;
|
||||
import ghidra.docking.settings.Settings;
|
||||
@ -34,9 +33,10 @@ public class AddressTableDataTableColumn
|
||||
|
||||
private final GColumnRenderer<String> monospacedRenderer =
|
||||
new AbstractGColumnRenderer<String>() {
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(getFixedWidthFont());
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,10 +16,9 @@
|
||||
package ghidra.util.table.field;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import docking.widgets.table.GTableCellRenderingData;
|
||||
import ghidra.docking.settings.FormatSettingsDefinition;
|
||||
@ -29,14 +28,15 @@ import ghidra.util.StringFormat;
|
||||
import ghidra.util.table.column.AbstractGColumnRenderer;
|
||||
|
||||
public class MonospacedByteRenderer extends AbstractGColumnRenderer<Byte[]> {
|
||||
|
||||
@Override
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(getFixedWidthFont());
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
|
||||
private String formatBytes(Byte[] bytes, Settings settings) {
|
||||
boolean bigEndian = (EndianSettingsDefinition.DEF
|
||||
.getChoice(settings) != EndianSettingsDefinition.LITTLE);
|
||||
boolean bigEndian =
|
||||
(EndianSettingsDefinition.DEF.getChoice(settings) != EndianSettingsDefinition.LITTLE);
|
||||
|
||||
int startIx = 0;
|
||||
int endIx = bytes.length;
|
||||
|
@ -34,7 +34,8 @@ import ghidra.app.util.viewer.listingpanel.AddressSetDisplayListener;
|
||||
import ghidra.framework.options.*;
|
||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
import ghidra.util.task.SwingUpdateManager;
|
||||
|
||||
@ -60,13 +61,13 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
||||
//@formatter:off
|
||||
static final String FG = "byteviewer.color.fg";
|
||||
static final String CURSOR = "byteviewer.color.cursor";
|
||||
|
||||
static final GColor SEPARATOR_COLOR = new GColor("color.fg.byteviewer.separator");
|
||||
|
||||
static final GColor SEPARATOR_COLOR = new GColor("color.fg.byteviewer.separator");
|
||||
static final GColor CHANGED_VALUE_COLOR = new GColor("color.fg.byteviewer.changed");
|
||||
static final GColor CURSOR_ACTIVE_COLOR = new GColor("color.cursor.byteviewer.focused.active");
|
||||
static final GColor CURSOR_NON_ACTIVE_COLOR = new GColor("color.cursor.byteviewer.focused.not.active");
|
||||
static final GColor CURSOR_NOT_FOCUSED_COLOR = new GColor("color.cursor.byteviewer.unfocused");
|
||||
|
||||
|
||||
static final GColor CURRENT_LINE_COLOR = GhidraOptions.DEFAULT_CURSOR_LINE_COLOR;
|
||||
//@formatter:on
|
||||
|
||||
@ -162,7 +163,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
||||
|
||||
/**
|
||||
* Notification that an option changed.
|
||||
*
|
||||
*
|
||||
* @param options options object containing the property that changed
|
||||
* @param optionName name of option that changed
|
||||
* @param oldValue old value of the option
|
||||
@ -173,7 +174,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
||||
Object newValue) {
|
||||
if (options.getName().equals("ByteViewer")) {
|
||||
if (optionName.equals(OPTION_FONT)) {
|
||||
setFont(SystemUtilities.adjustForFontSizeOverride((Font) newValue));
|
||||
setFont((Font) newValue);
|
||||
}
|
||||
}
|
||||
else if (options.getName().equals(CATEGORY_BROWSER_FIELDS)) {
|
||||
@ -460,7 +461,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
||||
|
||||
/**
|
||||
* Set the status info on the tool.
|
||||
*
|
||||
*
|
||||
* @param message non-html text to display
|
||||
*/
|
||||
void setStatusMessage(String message) {
|
||||
@ -505,7 +506,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
||||
|
||||
/**
|
||||
* Add the {@link AddressSetDisplayListener} to the byte viewer panel
|
||||
*
|
||||
*
|
||||
* @param listener the listener to add
|
||||
*/
|
||||
public void addDisplayListener(AddressSetDisplayListener listener) {
|
||||
@ -514,7 +515,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
||||
|
||||
/**
|
||||
* Remove the {@link AddressSetDisplayListener} from the byte viewer panel
|
||||
*
|
||||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeDisplayListener(AddressSetDisplayListener listener) {
|
||||
|
@ -39,8 +39,7 @@ import docking.widgets.fieldpanel.Layout;
|
||||
import docking.widgets.fieldpanel.field.Field;
|
||||
import docking.widgets.fieldpanel.support.BackgroundColorModel;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.*;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Tooltips;
|
||||
import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel;
|
||||
@ -245,8 +244,7 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
|
||||
tooltipTitleLabel.setHorizontalAlignment(SwingConstants.LEADING);
|
||||
tooltipTitleLabel.setBackground(Tooltips.BACKGROUND);
|
||||
tooltipTitleLabel.setOpaque(true);
|
||||
Font labelFont = tooltipTitleLabel.getFont();
|
||||
tooltipTitleLabel.setFont(labelFont.deriveFont(Font.BOLD));
|
||||
Gui.registerFont(tooltipTitleLabel, Font.BOLD);
|
||||
|
||||
JPanel headerPanel = new JPanel(new BorderLayout());
|
||||
headerPanel.add(tooltipTitleLabel);
|
||||
|
@ -15,11 +15,12 @@
|
||||
*/
|
||||
package ghidra.feature.fid.debug;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
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.table.TableColumn;
|
||||
@ -63,8 +64,13 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
|
||||
}
|
||||
|
||||
private void buildFrame() {
|
||||
GTableCellRenderer renderer = new GTableCellRenderer();
|
||||
renderer.setFont(renderer.getFixedWidthFont());
|
||||
GTableCellRenderer renderer = new GTableCellRenderer() {
|
||||
@Override
|
||||
protected Font getDefaultFont() {
|
||||
return fixedWidthFont;
|
||||
}
|
||||
};
|
||||
|
||||
int columnCount = table.getColumnCount();
|
||||
for (int ii = 0; ii < columnCount; ++ii) {
|
||||
Class<?> columnClass = table.getColumnClass(ii);
|
||||
@ -314,7 +320,7 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fidQueryClosed(FidQueryService service) {
|
||||
public void fidQueryClosed(FidQueryService fqs) {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
@ -133,10 +133,18 @@ icon.task.progress.hourglass.11 = hourglass24_11.png
|
||||
|
||||
// Fonts
|
||||
|
||||
font.splash.header.default = Serif-BOLD-35
|
||||
font.splash.status = Serif-BOLD-12
|
||||
font.table.header.number = arial-BOLD-12
|
||||
font.input.hint = monospaced-PLAIN-10
|
||||
font.splash.header.default = serif-bold-35
|
||||
font.splash.status = serif-bold-12
|
||||
|
||||
// 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]
|
||||
|
||||
|
||||
|
||||
color.fg.filterfield = color.palette.darkslategray
|
||||
|
||||
color.bg.highlight = #703401 // orangish
|
||||
|
@ -59,9 +59,9 @@
|
||||
<tocdef id="Root" sortgroup="a" text="Welcome to Help">
|
||||
<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="Editing Themes" sortgroup="2" text="Editing Themes" target="help/topics/Theming/ThemingUserDocs.html"/>
|
||||
<tocdef id="Architecture" sortgroup="3" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
|
||||
<tocdef id="Developer Documentation" sortgroup="4" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
|
||||
<tocdef id="Editing Themes" sortgroup="2" text="User's Guide" target="help/topics/Theming/ThemingUserDocs.html"/>
|
||||
<tocdef id="Developer Documentation" sortgroup="3" 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>
|
||||
</tocroot>
|
||||
|
@ -13,6 +13,14 @@
|
||||
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>
|
||||
|
||||
<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>
|
||||
|
||||
<P>When developing application code for Ghidra such as plugins, actions, etc., developers often
|
||||
@ -122,8 +130,58 @@
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
@ -26,7 +26,9 @@ import docking.action.DockingActionIf;
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.widgets.label.GIconLabel;
|
||||
import generic.theme.GAttributes;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.HelpLocation;
|
||||
import resources.Icons;
|
||||
|
||||
@ -43,7 +45,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
|
||||
private KeyEntryTextField keyEntryField;
|
||||
private JTextPane collisionPane;
|
||||
private StyledDocument doc;
|
||||
private SimpleAttributeSet textAttrSet;
|
||||
|
||||
private SimpleAttributeSet textAttrs;
|
||||
private Color bgColor;
|
||||
|
||||
public KeyEntryDialog(Tool tool, DockingActionIf action) {
|
||||
@ -172,10 +175,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
|
||||
}
|
||||
|
||||
private void setUpAttributes() {
|
||||
textAttrSet = new SimpleAttributeSet();
|
||||
textAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
textAttrSet.addAttribute(StyleConstants.Foreground, Messages.NORMAL);
|
||||
Font font = Gui.getFont("font.standard");
|
||||
textAttrs = new GAttributes(font, Messages.NORMAL);
|
||||
}
|
||||
|
||||
private void updateCollisionPane(KeyStroke ks) {
|
||||
@ -194,7 +195,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
|
||||
String ksName = KeyBindingUtils.parseKeyStroke(ks);
|
||||
String text = keyBindings.getActionsForKeyStrokeText(ksName);
|
||||
try {
|
||||
doc.insertString(0, text, textAttrSet);
|
||||
doc.insertString(0, text, textAttrs);
|
||||
collisionPane.setCaretPosition(0);
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
|
@ -26,6 +26,7 @@ import javax.swing.*;
|
||||
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
/**
|
||||
@ -133,7 +134,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
||||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel styleLabel = new GDLabel("Styles");
|
||||
styleLabel.setFont(getFont().deriveFont(1));
|
||||
Gui.registerFont(styleLabel, Font.BOLD);
|
||||
styleLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(styleLabel);
|
||||
|
||||
@ -150,7 +151,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
||||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel sizeLabel = new GDLabel("Sizes");
|
||||
sizeLabel.setFont(getFont().deriveFont(1));
|
||||
Gui.registerFont(sizeLabel, Font.BOLD);
|
||||
sizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(sizeLabel);
|
||||
|
||||
@ -168,7 +169,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
||||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel fontLabel = new GDLabel("Fonts");
|
||||
fontLabel.setFont(getFont().deriveFont(1));
|
||||
Gui.registerFont(fontLabel, Font.BOLD);
|
||||
fontLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(fontLabel);
|
||||
|
||||
|
@ -25,22 +25,32 @@ import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GColorUIResource;
|
||||
import generic.theme.*;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
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.
|
||||
* <p>
|
||||
* It allows (but default-disables) HTML content, automatically paints alternating row
|
||||
* background colors, and highlights the drop target in a drag-n-drop operation.
|
||||
*
|
||||
* It allows (but default-disables) HTML content, automatically paints alternating row background
|
||||
* 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 {
|
||||
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 String BASE_FONT_ID = "font.table.base";
|
||||
|
||||
/** Allows the user to disable alternating row colors on JLists and JTables */
|
||||
private static final String DISABLE_ALTERNATING_ROW_COLORS_PROPERTY =
|
||||
"disable.alternating.row.colors";
|
||||
@ -61,6 +71,9 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
||||
private boolean instanceAlternateRowColors = true;
|
||||
|
||||
public AbstractGCellRenderer() {
|
||||
|
||||
setBaseFontId(BASE_FONT_ID);
|
||||
|
||||
noFocusBorder = BorderFactory.createEmptyBorder(0, 5, 0, 5);
|
||||
Border innerBorder = BorderFactory.createEmptyBorder(0, 4, 0, 4);
|
||||
Border outerBorder = BorderFactory.createLineBorder(Palette.YELLOW, 1);
|
||||
@ -114,34 +127,48 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
||||
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
|
||||
public void setFont(Font 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
|
||||
// getTableCellRenderer() is called, as it resets the font to the default font on each pass
|
||||
protected void setBold() {
|
||||
super.setFont(boldFont);
|
||||
String caller =
|
||||
ReflectionUtilities.getClassNameOlderThan(getClass().getName(), "generic.theme");
|
||||
Msg.debug(this, "Calling setFont() on the renderer is discouraged. " +
|
||||
"To change the font, call setBaseFontId(). Called from " + caller);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the row where DnD would perform drop operation.
|
||||
* @param dropRow the drop row
|
||||
* Sets the font of this renderer to be bold until the next time that getTableCellRenderer() is
|
||||
* called, as it resets the font to the default font on each pass.
|
||||
* @see #getDefaultFont()
|
||||
*/
|
||||
public void setDropRow(int dropRow) {
|
||||
this.dropRow = dropRow;
|
||||
}
|
||||
|
||||
protected Border getNoFocusBorder() {
|
||||
return noFocusBorder;
|
||||
protected void setBold() {
|
||||
super.setFont(boldFont);
|
||||
}
|
||||
|
||||
protected Font getDefaultFont() {
|
||||
@ -156,6 +183,18 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
||||
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() {
|
||||
return BACKGROUND_COLOR;
|
||||
}
|
||||
|
@ -72,7 +72,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||
new DropDownWindowVisibilityListener<>();
|
||||
|
||||
private GDHtmlLabel previewLabel;
|
||||
protected GList<T> list = new GList<>();
|
||||
protected DropDownList list = new DropDownList();
|
||||
|
||||
private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners =
|
||||
WeakDataStructureFactory.createSingleThreadAccessWeakSet();
|
||||
private Collection<CellEditorListener> cellEditorListeners = new HashSet<>();
|
||||
@ -82,7 +83,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||
private WindowComponentListener parentWindowListener = new WindowComponentListener();
|
||||
private T selectedValue;
|
||||
|
||||
private int cellHeight;
|
||||
private int matchingWindowHeight = MIN_HEIGHT;
|
||||
private Point lastLocation;
|
||||
protected final DropDownTextFieldDataModel<T> dataModel;
|
||||
@ -278,15 +278,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||
|
||||
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.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
|
||||
* 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() {
|
||||
Object selectedItem = list.getSelectedValue();
|
||||
if (selectedItem == null) {
|
||||
@ -747,6 +738,30 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||
// 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 {
|
||||
@Override
|
||||
public void focusLost(FocusEvent event) {
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
package docking.widgets.dialogs;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
@ -26,6 +27,7 @@ import docking.DockingUtils;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import docking.widgets.label.GLabel;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.Platform;
|
||||
|
||||
@ -34,6 +36,8 @@ public class MultiLineInputDialog extends DialogComponentProvider {
|
||||
private static final KeyStroke SUBMIT_KEYSTROKE =
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||
|
||||
private static final String FONT_ID = "font.input.hint";
|
||||
|
||||
private boolean isCanceled;
|
||||
private JTextArea inputTextArea;
|
||||
|
||||
@ -84,10 +88,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
|
||||
}
|
||||
JLabel hintLabel = new GLabel("(" + metaKeyText + "-Enter to accept)");
|
||||
hintLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
Font font = hintLabel.getFont();
|
||||
Font smallerFont = font.deriveFont(12F);
|
||||
Font smallItalicFont = smallerFont.deriveFont(Font.ITALIC);
|
||||
hintLabel.setFont(smallItalicFont);
|
||||
Gui.registerFont(hintLabel, FONT_ID);
|
||||
hintLabel.setForeground(Messages.HINT);
|
||||
|
||||
dataPanel.add(messageLabel, BorderLayout.NORTH);
|
||||
|
@ -49,39 +49,54 @@ class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryMod
|
||||
|
||||
/**
|
||||
* Create a new DirectoryList instance.
|
||||
*
|
||||
*
|
||||
* @param chooser the {@link GhidraFileChooser} this instance is nested in
|
||||
* @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);
|
||||
this.chooser = chooser;
|
||||
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);
|
||||
|
||||
FileListCellRenderer cellRenderer = new FileListCellRenderer(chooser);
|
||||
setCellRenderer(cellRenderer);
|
||||
|
||||
// Enable the list to calculate the width of the cells on its own, but manually
|
||||
// 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);
|
||||
updateCellDimensions(getFont());
|
||||
|
||||
addMouseListener(new GMouseListenerAdapter() {
|
||||
@Override
|
||||
|
@ -558,7 +558,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
|
||||
|
||||
private JScrollPane buildDirectoryList() {
|
||||
directoryListModel = new DirectoryListModel();
|
||||
directoryList = new DirectoryList(this, directoryListModel, rootPanel.getFont());
|
||||
directoryList = new DirectoryList(this, directoryListModel);
|
||||
directoryList.setName("LIST");
|
||||
directoryList.setBackground(BACKGROUND_COLOR);
|
||||
|
||||
|
@ -51,18 +51,17 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
private static final Color BG_DRAG = new GColor("color.bg.table.row.drag");
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache =
|
||||
new HashMap<>();
|
||||
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache = new HashMap<>();
|
||||
static {
|
||||
|
||||
int n = FloatingPointPrecisionSettingsDefinition.MAX_PRECISION;
|
||||
for (int i = 0; i <= n; i++) {
|
||||
int precision = i;
|
||||
ThreadLocal<DecimalFormat> localFormatter = ThreadLocal.withInitial(
|
||||
() -> new DecimalFormat(createDecimalFormat(precision)));
|
||||
ThreadLocal<DecimalFormat> localFormatter =
|
||||
ThreadLocal.withInitial(() -> new DecimalFormat(createDecimalFormat(precision)));
|
||||
decimalFormatCache.put(precision, localFormatter);
|
||||
}
|
||||
}
|
||||
@ -84,7 +83,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
|
||||
/**
|
||||
* Constructs a new GTableCellRenderer using the specified font.
|
||||
*
|
||||
*
|
||||
* @param f the font to use when rendering text in the table cells
|
||||
*/
|
||||
public GTableCellRenderer(Font f) {
|
||||
@ -94,7 +93,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
|
||||
/**
|
||||
* Return the cell renderer text
|
||||
*
|
||||
*
|
||||
* @param value Cell object value
|
||||
* @return A string interpretation of value; generated by calling value.toString()
|
||||
*/
|
||||
@ -149,7 +148,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
* Provide basic cell rendering -- setting foreground and background colors, font, text,
|
||||
* alignment, drop color, and border. Additional data that may be of use to the renderer is
|
||||
* passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
|
||||
*
|
||||
*
|
||||
* @param data Context data used in the rendering of a data cell.
|
||||
* @return The component used for drawing the table cell.
|
||||
*/
|
||||
@ -158,7 +157,6 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
Object value = data.getValue();
|
||||
JTable table = data.getTable();
|
||||
int row = data.getRowViewIndex();
|
||||
int column = data.getColumnViewIndex();
|
||||
boolean isSelected = data.isSelected();
|
||||
boolean hasFocus = data.hasFocus();
|
||||
Settings settings = data.getColumnSettings();
|
||||
@ -173,7 +171,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
}
|
||||
|
||||
TableModel model = table.getModel();
|
||||
configureFont(table, model, column);
|
||||
setFont(getDefaultFont());
|
||||
|
||||
if (isSelected) {
|
||||
setForeground(table.getSelectionForeground());
|
||||
@ -199,8 +197,14 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
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) {
|
||||
@ -217,7 +221,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
||||
|
||||
/**
|
||||
* Format a Number per the Settings parameters.
|
||||
*
|
||||
*
|
||||
* @param value the number to format
|
||||
* @param settings settings controlling the display of the Number parameter
|
||||
* @return a formatted representation of the Number value
|
||||
|
@ -67,7 +67,7 @@ public class HintTextField extends JTextField {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param hint the hint text
|
||||
* @param required true, if the field should be marked as required
|
||||
* @param verifier input verifier, or null if none needed
|
||||
@ -78,7 +78,6 @@ public class HintTextField extends JTextField {
|
||||
this.verifier = verifier;
|
||||
|
||||
addListeners();
|
||||
setFont(getFont().deriveFont(Font.PLAIN));
|
||||
validateField();
|
||||
}
|
||||
|
||||
@ -143,7 +142,7 @@ public class HintTextField extends JTextField {
|
||||
/**
|
||||
* Sets whether the field is required or not. If so, it will be rendered
|
||||
* differently to indicate that to the user.
|
||||
*
|
||||
*
|
||||
* @param required true if required, false otherwise
|
||||
*/
|
||||
public void setRequired(boolean required) {
|
||||
@ -161,7 +160,7 @@ public class HintTextField extends JTextField {
|
||||
|
||||
/**
|
||||
* Returns true if the field contains valid input.
|
||||
*
|
||||
*
|
||||
* @return true if valid, false otherwise
|
||||
*/
|
||||
public boolean isFieldValid() {
|
||||
@ -179,7 +178,7 @@ public class HintTextField extends JTextField {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validity of the field and sets the appropriate
|
||||
* Checks the validity of the field and sets the appropriate
|
||||
* field attributes.
|
||||
*/
|
||||
private void validateField() {
|
||||
|
@ -28,6 +28,7 @@ import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.*;
|
||||
import help.Help;
|
||||
import help.HelpService;
|
||||
@ -47,6 +48,8 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
||||
|
||||
private final static String INIT_TITLE = "<< untitled >>";
|
||||
|
||||
private static final String FONT_ID = "font.wizard.border.title";
|
||||
|
||||
private PanelManager panelMgr;
|
||||
private WizardPanel currWizPanel;
|
||||
private JButton backButton;
|
||||
@ -91,7 +94,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @see docking.wizard.WizardPanelListener#validityChanged()
|
||||
*/
|
||||
@Override
|
||||
@ -108,7 +111,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
||||
return getStatusText();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @see docking.wizard.WizardPanelListener#setStatusMessage(String)
|
||||
*/
|
||||
@Override
|
||||
@ -220,8 +223,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
||||
titleLabel = (wizardIcon == null ? new GDLabel(INIT_TITLE)
|
||||
: new GDLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING));
|
||||
|
||||
EmptyBorderButton helpButton =
|
||||
new EmptyBorderButton(Icons.INFO_ICON);
|
||||
EmptyBorderButton helpButton = new EmptyBorderButton(Icons.INFO_ICON);
|
||||
helpButton.setToolTipText("Help (F1)");
|
||||
helpButton.addActionListener(
|
||||
e -> DockingWindowManager.getHelpService().showHelp(rootPanel, false, rootPanel));
|
||||
@ -438,7 +440,7 @@ if (!visitedMap.containsKey(currWizPanel)) {
|
||||
return; // nothing to do
|
||||
}
|
||||
|
||||
// this will have no effect if we are not showing, but the above call will handle that
|
||||
// this will have no effect if we are not showing, but the above call will handle that
|
||||
// case
|
||||
defaultFocusComponent.requestFocusInWindow();
|
||||
}
|
||||
@ -465,14 +467,12 @@ if (!visitedMap.containsKey(currWizPanel)) {
|
||||
if (scrollPane.getVerticalScrollBar().isShowing()) {
|
||||
TitledBorder titledBorder =
|
||||
new TitledBorder(BorderFactory.createEmptyBorder(), "(scroll for more options)");
|
||||
|
||||
Font font = titledBorder.getTitleFont();
|
||||
if (font == null) {
|
||||
// workaround for bug on Java 7
|
||||
font = titleLabel.getFont();
|
||||
}
|
||||
|
||||
titledBorder.setTitleFont(font.deriveFont(10f));
|
||||
Gui.addThemeListener(e -> {
|
||||
if (e.isFontChanged(FONT_ID)) {
|
||||
titledBorder.setTitleFont(Gui.getFont(FONT_ID));
|
||||
}
|
||||
});
|
||||
titledBorder.setTitleFont(Gui.getFont(FONT_ID));
|
||||
titledBorder.setTitleColor(Messages.NORMAL);
|
||||
titledBorder.setTitlePosition(TitledBorder.BOTTOM);
|
||||
titledBorder.setTitleJustification(TitledBorder.TRAILING);
|
||||
|
@ -15,20 +15,14 @@
|
||||
*/
|
||||
package ghidra.docking.util;
|
||||
|
||||
import java.awt.Font;
|
||||
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 docking.framework.ApplicationInformationDisplayFactory;
|
||||
import generic.theme.LafType;
|
||||
import generic.theme.ThemeManager;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
//
|
||||
// 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() {
|
||||
|
@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||
import ghidra.util.datastruct.WeakSet;
|
||||
@ -43,6 +44,8 @@ import resources.Icons;
|
||||
*/
|
||||
public class TaskMonitorComponent extends JPanel implements TaskMonitor {
|
||||
|
||||
private static final String MESSAGE_FONT_ID = "font.task.monitor.label.message";
|
||||
|
||||
private WeakSet<CancelledListener> listeners =
|
||||
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||
|
||||
@ -458,7 +461,7 @@ public class TaskMonitorComponent extends JPanel implements TaskMonitor {
|
||||
// don't care
|
||||
}
|
||||
};
|
||||
messageLabel.setFont(messageLabel.getFont().deriveFont((float) 10.0));
|
||||
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
|
||||
Dimension d = messageLabel.getPreferredSize();
|
||||
d.width = 180;
|
||||
messageLabel.setPreferredSize(d);
|
||||
|
@ -35,7 +35,7 @@ public class ReflectionUtilitiesTest {
|
||||
@Test
|
||||
public void testGetClassNameAfter_NoClasses() {
|
||||
|
||||
String caller = ReflectionUtilities.getClassNameOlderThan();
|
||||
String caller = ReflectionUtilities.getClassNameOlderThan(new String[0]);
|
||||
assertThat(caller, is(equalTo(ReflectionUtilitiesTest.class.getName())));
|
||||
}
|
||||
|
||||
|
@ -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.hovered = color.palette.lime
|
||||
|
||||
|
||||
color.graphdisplay.vertex.default = color.palette.green
|
||||
color.graphdisplay.edge.default = color.palette.green
|
||||
color.graphdisplay.vertex.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.large = network-wireless.png
|
||||
icon.graph.layout.default = color_swatch.png
|
||||
|
@ -27,6 +27,7 @@ import docking.widgets.label.GDLabel;
|
||||
import edu.uci.ics.jung.visualization.RenderContext;
|
||||
import edu.uci.ics.jung.visualization.VisualizationViewer;
|
||||
import edu.uci.ics.jung.visualization.control.ScalingControl;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.graph.VisualGraph;
|
||||
import ghidra.graph.viewer.event.mouse.VertexTooltipProvider;
|
||||
import ghidra.graph.viewer.event.mouse.VisualGraphMousePlugin;
|
||||
@ -38,18 +39,18 @@ import ghidra.graph.viewer.vertex.VertexFocusListener;
|
||||
* A view object, where 'view' is used in the sense of the Model-View-Controller (MVC) pattern.
|
||||
* This class will contain all UI widgets need to display and interact with a graph.
|
||||
*
|
||||
* <p><b><u>Implementation Note:</u></b>
|
||||
* <p><b><u>Implementation Note:</u></b>
|
||||
* <ol>
|
||||
* <li>The graph of this component can be null, changing to non-null values over the
|
||||
* lifetime of this view. This allows this view to be installed in a UI component, with the
|
||||
* contents changing as needed.
|
||||
* <li>The graph of this component can be null, changing to non-null values over the
|
||||
* lifetime of this view. This allows this view to be installed in a UI component, with the
|
||||
* contents changing as needed.
|
||||
* </li>
|
||||
* <li>
|
||||
* When the graph is {@link #setGraph(VisualGraph) set}, the view portion of the class is
|
||||
* recreated.
|
||||
* </li>
|
||||
* <li>
|
||||
* At any given point in time there may not be a {@link #graphComponent}. This means that
|
||||
* At any given point in time there may not be a {@link #graphComponent}. This means that
|
||||
* this class must maintain settings state that it will apply when the component is created.
|
||||
* This state is atypical and makes this class a bit harder to understand.
|
||||
* </li>
|
||||
@ -60,14 +61,16 @@ import ghidra.graph.viewer.vertex.VertexFocusListener;
|
||||
* @param <G> the graph type
|
||||
*/
|
||||
//@formatter:off
|
||||
public class VisualGraphView<V extends VisualVertex,
|
||||
E extends VisualEdge<V>,
|
||||
public class VisualGraphView<V extends VisualVertex,
|
||||
E extends VisualEdge<V>,
|
||||
G extends VisualGraph<V, E>> {
|
||||
//@formatter:on
|
||||
//@formatter:on
|
||||
|
||||
private static final float ZOOM_OUT_AMOUNT = .9f;
|
||||
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 viewContentPanel;
|
||||
|
||||
@ -76,7 +79,7 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
* As graph data is updated, we set and clear the contents of this panel as needed. This
|
||||
* allows the client to initialize the satellite window once, with updates controlled by
|
||||
* this class.
|
||||
*
|
||||
*
|
||||
* Note: this panel will be empty when docked and when the viewer is not yet built
|
||||
*/
|
||||
private JPanel undockedSatelliteContentPanel;
|
||||
@ -99,7 +102,7 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
|
||||
private Optional<GraphSatelliteListener> clientSatelliteListener = Optional.empty();
|
||||
|
||||
// this internal listener is the way we manage keeping our state in sync with the
|
||||
// this internal listener is the way we manage keeping our state in sync with the
|
||||
// graph component, as well as how we notify the client listener
|
||||
private GraphSatelliteListener internalSatelliteListener = (docked, visible) -> {
|
||||
|
||||
@ -190,10 +193,10 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a listener that allows clients to be notified of vertex double-clicks. Normal
|
||||
* Sets a listener that allows clients to be notified of vertex double-clicks. Normal
|
||||
* mouse processing is handled by the {@link VisualGraphMousePlugin} class. This is a
|
||||
* convenience method so that clients do not have to deal with the mouse plugin.
|
||||
*
|
||||
*
|
||||
* @param l the listener
|
||||
*/
|
||||
public void setVertexClickListener(VertexClickListener<V, E> l) {
|
||||
@ -290,9 +293,9 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primary viewer of the graph (as opposed to the satellite viewer). The
|
||||
* Returns the primary viewer of the graph (as opposed to the satellite viewer). The
|
||||
* viewer returned is responsible for maintaining view information for a given graph.
|
||||
*
|
||||
*
|
||||
* @return the primary viewer
|
||||
*/
|
||||
public GraphViewer<V, E> getPrimaryGraphViewer() {
|
||||
@ -308,7 +311,7 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
|
||||
/**
|
||||
* Sets the perspective for this view
|
||||
*
|
||||
*
|
||||
* @param newPerspective the new perspective
|
||||
*/
|
||||
public void setGraphPerspective(GraphPerspectiveInfo<V, E> newPerspective) {
|
||||
@ -350,8 +353,7 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
viewContentPanel.removeAll();
|
||||
viewContentPanel.paintImmediately(viewContentPanel.getBounds());
|
||||
JLabel messageLabel = new GDLabel(errorMessage);
|
||||
Font font = messageLabel.getFont();
|
||||
messageLabel.setFont(font.deriveFont(22f)); // make a bit bigger for readability
|
||||
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
|
||||
messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
messageLabel.setFocusable(true); // we have to have something focusable in our provider
|
||||
viewContentPanel.add(messageLabel, BorderLayout.NORTH);
|
||||
@ -362,8 +364,8 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
/**
|
||||
* Sets a message to be painted on the viewer. This is useful to show a text message to the
|
||||
* user. Passing null will clear the message.
|
||||
*
|
||||
* @param message the status message
|
||||
*
|
||||
* @param message the status message
|
||||
*/
|
||||
public void setStatusMessage(String message) {
|
||||
if (graphComponent != null) {
|
||||
@ -377,10 +379,10 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
|
||||
/**
|
||||
* Returns whether the satellite intended to be visible. If this component is built, then
|
||||
* a result of true means that the satellite is showing. If the component is not yet
|
||||
* built, then a result of true means that the satellite will be made visible when the
|
||||
* a result of true means that the satellite is showing. If the component is not yet
|
||||
* built, then a result of true means that the satellite will be made visible when the
|
||||
* component is built.
|
||||
*
|
||||
*
|
||||
* @return true if visible
|
||||
*/
|
||||
public boolean isSatelliteVisible() {
|
||||
@ -421,10 +423,10 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
|
||||
/**
|
||||
* Returns whether the satellite intended to be docked. If this component is built, then
|
||||
* a result of true means that the satellite is docked. If the component is not yet
|
||||
* built, then a result of true means that the satellite will be made docked when the
|
||||
* a result of true means that the satellite is docked. If the component is not yet
|
||||
* built, then a result of true means that the satellite will be made docked when the
|
||||
* component is built.
|
||||
*
|
||||
*
|
||||
* @return true if visible
|
||||
*/
|
||||
public boolean isSatelliteDocked() {
|
||||
@ -517,8 +519,8 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
}
|
||||
|
||||
public Point translatePointFromVertexToViewSpace(V v, Point p) {
|
||||
return GraphViewerUtils.translatePointFromVertexRelativeSpaceToViewSpace(
|
||||
getPrimaryGraphViewer(), v, p);
|
||||
return GraphViewerUtils
|
||||
.translatePointFromVertexRelativeSpaceToViewSpace(getPrimaryGraphViewer(), v, p);
|
||||
}
|
||||
|
||||
public Rectangle translateRectangleFromVertexToViewSpace(V v, Rectangle r) {
|
||||
@ -577,7 +579,7 @@ public class VisualGraphView<V extends VisualVertex,
|
||||
}
|
||||
|
||||
/**
|
||||
* Effectively clears this display. This method is not called dispose, as that implies
|
||||
* Effectively clears this display. This method is not called dispose, as that implies
|
||||
* the end of an object's lifecycle. This object can be re-used after this method is
|
||||
* called.
|
||||
*/
|
||||
|
@ -34,7 +34,8 @@ color.fg.tree.selected = [color]system.color.fg.selected.view
|
||||
|
||||
// Fonts
|
||||
font.standard = [font]system.font.control
|
||||
font.monospaced = monospaced-PLAIN-12
|
||||
font.standard.bold = font.standard[bold]
|
||||
font.monospaced = monospaced-plain-12
|
||||
|
||||
|
||||
//
|
||||
|
@ -298,6 +298,11 @@ public class ApplicationThemeManager extends ThemeManager {
|
||||
lookAndFeelManager.registerFont(component, fontId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFont(Component component, String fontId, int fontStyle) {
|
||||
lookAndFeelManager.registerFont(component, fontId, fontStyle);
|
||||
}
|
||||
|
||||
private void installFlatLookAndFeels() {
|
||||
UIManager.installLookAndFeel(LafType.FLAT_LIGHT.getName(), FlatLightLaf.class.getName());
|
||||
UIManager.installLookAndFeel(LafType.FLAT_DARK.getName(), FlatDarkLaf.class.getName());
|
||||
|
@ -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.
|
||||
*/
|
||||
public void addStyleModifier(int newStyle) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -17,8 +17,9 @@ package generic.theme;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.*;
|
||||
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
private static final String FONT_SUFFIX = ".font";
|
||||
|
||||
// Start with an StubThemeManager so that simple tests can operate without having
|
||||
// to initialize the theme system. Applications and integration tests will
|
||||
// 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
|
||||
* 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 fontId the id of the font to register with the given component
|
||||
*/
|
||||
@ -153,6 +159,37 @@ public class Gui {
|
||||
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
|
||||
* @return true if the active theme is using dark defaults
|
||||
|
@ -575,6 +575,21 @@ public abstract class ThemeManager {
|
||||
// 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.
|
||||
* @return true if the current theme use dark default values.
|
||||
|
@ -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.
|
||||
*/
|
||||
public class ComponentFontRegistry {
|
||||
private WeakSet<Component> components = WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||
private WeakSet<StyledComponent> components =
|
||||
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||
private String fontId;
|
||||
|
||||
/**
|
||||
@ -45,8 +46,18 @@ public class ComponentFontRegistry {
|
||||
* @param component the component to add
|
||||
*/
|
||||
public void addComponent(Component component) {
|
||||
component.setFont(Gui.getFont(fontId));
|
||||
components.add(component);
|
||||
addComponent(component, Font.PLAIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
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();
|
||||
if (!Objects.equals(existingFont, font)) {
|
||||
component.setFont(font);
|
||||
Font styledFont = 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import generic.theme.*;
|
||||
import generic.util.action.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
/**
|
||||
* Manages installing and updating a {@link LookAndFeel}
|
||||
@ -38,6 +39,7 @@ public abstract class LookAndFeelManager {
|
||||
|
||||
private LafType laf;
|
||||
private Map<String, ComponentFontRegistry> fontRegistryMap = new HashMap<>();
|
||||
private Map<Component, String> componentToIdMap = new WeakHashMap<>();
|
||||
protected ApplicationThemeManager themeManager;
|
||||
protected Map<String, String> normalizedIdToLafIdMap;
|
||||
|
||||
@ -158,7 +160,7 @@ public abstract class LookAndFeelManager {
|
||||
* Called when one or more fonts have changed.
|
||||
* <p>
|
||||
* This will update the Java {@link UIManager} and trigger a reload of the UIs.
|
||||
*
|
||||
*
|
||||
* @param changedFontIds the set of Java Font ids that are affected by this change; these are
|
||||
* the normalized ids
|
||||
*/
|
||||
@ -202,12 +204,49 @@ public abstract class LookAndFeelManager {
|
||||
* @param fontId the id of the font to register with the given component
|
||||
*/
|
||||
public void registerFont(Component component, String fontId) {
|
||||
|
||||
checkForAlreadyRegistered(component, fontId);
|
||||
componentToIdMap.put(component, fontId);
|
||||
|
||||
ComponentFontRegistry register =
|
||||
fontRegistryMap.computeIfAbsent(fontId, id -> new ComponentFontRegistry(id));
|
||||
|
||||
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) {
|
||||
if (!(font instanceof UIResource)) {
|
||||
return new FontUIResource(font);
|
||||
@ -292,8 +331,7 @@ public abstract class LookAndFeelManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void setKeyBinding(String existingKsText, String newKsText,
|
||||
String[] prefixValues) {
|
||||
protected void setKeyBinding(String existingKsText, String newKsText, String[] prefixValues) {
|
||||
|
||||
KeyStroke existingKs = KeyStroke.getKeyStroke(existingKsText);
|
||||
KeyStroke newKs = KeyStroke.getKeyStroke(newKsText);
|
||||
|
@ -153,8 +153,8 @@ public class UiDefaultsMapper {
|
||||
* the user changeable values for affecting the Java LookAndFeel colors, fonts, and icons.
|
||||
* <p>
|
||||
* The keys in the returned map have been normalized and all start with 'laf.'
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return a map of changeable values that affect java LookAndFeel values
|
||||
*/
|
||||
public GThemeValueMap getNormalizedJavaDefaults() {
|
||||
@ -184,7 +184,7 @@ public class UiDefaultsMapper {
|
||||
* Returns a mapping of normalized LaF Ids so that when fonts and icons get changed using the
|
||||
* normalized ids that are presented to the user, we know which LaF ids need to be updated in
|
||||
* the UiDefaults so that the LookAndFeel will pick up and use the changes.
|
||||
*
|
||||
*
|
||||
* @return a mapping of normalized LaF ids to original LaF ids.
|
||||
*/
|
||||
public Map<String, String> getNormalizedIdToLafIdMap() {
|
||||
@ -281,7 +281,7 @@ public class UiDefaultsMapper {
|
||||
|
||||
/**
|
||||
* This allows clients to hard-code a chosen color for a group
|
||||
*
|
||||
*
|
||||
* @param group the system color id to assign the given color
|
||||
* @param color the color to be assigned to the system color id
|
||||
*/
|
||||
@ -291,7 +291,7 @@ public class UiDefaultsMapper {
|
||||
|
||||
/**
|
||||
* This allows clients to hard-code a chosen font for a group
|
||||
*
|
||||
*
|
||||
* @param group the system font id to assign the given font
|
||||
* @param font the font to be assigned to the system font id
|
||||
*/
|
||||
@ -693,7 +693,7 @@ public class UiDefaultsMapper {
|
||||
* Groups allow us to use the same group id for many components that by default have the same
|
||||
* value (Color or Font). This grouper allows us to specify the precedence to use when
|
||||
* searching for the best group.
|
||||
*
|
||||
*
|
||||
* @param <T> The theme value type (Color or Font)
|
||||
*/
|
||||
private abstract class ValueGrouper<T> {
|
||||
|
@ -22,9 +22,10 @@ import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.text.View;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import generic.text.TextLayoutGraphics;
|
||||
import generic.theme.GAttributes;
|
||||
import ghidra.util.html.HtmlLineSplitter;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
@ -343,6 +344,67 @@ public class HTMLUtilities {
|
||||
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.
|
||||
* If <code>foo</code> is passed for the HTML text, with a content value of <code>123456</code>, then
|
||||
@ -510,7 +572,7 @@ public class HTMLUtilities {
|
||||
|
||||
/**
|
||||
* See {@link #friendlyEncodeHTML(String)}
|
||||
*
|
||||
*
|
||||
* @param text string to be encoded
|
||||
* @param skipLeadingWhitespace true signals to ignore any leading whitespace characters.
|
||||
* This is useful when line wrapping to force wrapped lines to the left
|
||||
@ -593,8 +655,7 @@ public class HTMLUtilities {
|
||||
* Calling this twice will result in text being double-escaped, which will not display correctly.
|
||||
* <p>
|
||||
* 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 makeSpacesNonBreaking true to convert spaces into {@value #HTML_SPACE}
|
||||
* @return string with any html characters replaced with equivalents
|
||||
@ -634,7 +695,7 @@ public class HTMLUtilities {
|
||||
|
||||
/**
|
||||
* Escapes any HTML special characters in the specified text.
|
||||
*
|
||||
*
|
||||
* @param text plain-text that might have some characters that should NOT be interpreted as HTML
|
||||
* @return string with any html characters replaced with equivalents
|
||||
* @see #escapeHTML(String, boolean)
|
||||
@ -647,7 +708,7 @@ public class HTMLUtilities {
|
||||
* Tests a unicode code point (i.e., 32 bit character) to see if it needs to be escaped before
|
||||
* being added to a HTML document because it is non-printable or a non-standard control
|
||||
* character
|
||||
*
|
||||
*
|
||||
* @param codePoint character to test
|
||||
* @return boolean true if character should be escaped
|
||||
*/
|
||||
|
@ -84,8 +84,12 @@ icon.plugin.manager.default = plasma.png
|
||||
font.help.about = font.monospaced
|
||||
font.keybindings.status = sansserif-plain-11
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Insets;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.swing.*;
|
||||
@ -57,11 +58,10 @@ public class UserAgreementDialog extends DialogComponentProvider {
|
||||
}
|
||||
|
||||
private JComponent buildWorkPanel() {
|
||||
Font font = Gui.getFont(FONT_ID);
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
JLabel label = new GDLabel("Ghidra User Agreement", SwingConstants.CENTER);
|
||||
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.setBorder(BorderFactory.createEmptyBorder(10, 40, 40, 40));
|
||||
JEditorPane editorPane = new JEditorPane();
|
||||
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.client.RepositoryAdapter;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.remote.User;
|
||||
@ -33,9 +34,9 @@ import ghidra.framework.remote.User;
|
||||
*/
|
||||
public class ViewProjectAccessPanel extends ProjectAccessPanel {
|
||||
|
||||
/**
|
||||
/**
|
||||
* Construct a new panel.
|
||||
*
|
||||
*
|
||||
* @param repository handle to the repository adapter
|
||||
* @param tool the plugin tool
|
||||
* @throws IOException if there's an error processing repository information
|
||||
@ -47,13 +48,13 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
|
||||
|
||||
/**
|
||||
* Constructs a new panel.
|
||||
*
|
||||
*
|
||||
* @param knownUsers names of the users that are known to the remote server
|
||||
* @param currentUser the current user
|
||||
* @param allUsers all users known to the repository
|
||||
* @param repositoryName the name of the repository
|
||||
* @param anonymousServerAccessAllowed true if the server allows anonymous access
|
||||
* @param anonymousAccessEnabled true if the repository allows anonymous access
|
||||
* @param anonymousAccessEnabled true if the repository allows anonymous access
|
||||
* (ignored if anonymousServerAccessAllowed is false)
|
||||
* @param tool the current tool
|
||||
*/
|
||||
@ -66,7 +67,7 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main gui panel, containing the known users, button, and user access
|
||||
* Creates the main gui panel, containing the known users, button, and user access
|
||||
* panels.
|
||||
*/
|
||||
@Override
|
||||
@ -82,9 +83,7 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
|
||||
if (anonymousServerAccessAllowed && origAnonymousAccessEnabled) {
|
||||
JLabel anonymousAccessLabel = new GDLabel("Anonymous Read-Only Access Enabled");
|
||||
anonymousAccessLabel.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0));
|
||||
Font f = anonymousAccessLabel.getFont().deriveFont(Font.ITALIC);
|
||||
anonymousAccessLabel.setFont(f);
|
||||
|
||||
Gui.registerFont(anonymousAccessLabel, Font.ITALIC);
|
||||
mainPanel.add(anonymousAccessLabel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
|
@ -17,79 +17,57 @@ package ghidra.framework.plugintool.dialog;
|
||||
|
||||
import static ghidra.util.HTMLUtilities.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
import javax.swing.text.StyleConstants;
|
||||
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.GColor;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import generic.theme.*;
|
||||
|
||||
/**
|
||||
* Abstract class that defines a panel for displaying name/value pairs with html-formatting.
|
||||
*/
|
||||
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;
|
||||
protected static final int LEFT_COLUMN_WIDTH = 150;
|
||||
protected static final int RIGHT_MARGIN = 30;
|
||||
|
||||
// Font attributes for the title of each row.
|
||||
protected static SimpleAttributeSet titleAttrSet;
|
||||
protected static GAttributes titleAttrs;
|
||||
|
||||
protected JLabel textLabel;
|
||||
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.
|
||||
*/
|
||||
protected abstract void createFieldAttributes();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
protected abstract void refresh();
|
||||
|
||||
/**
|
||||
* Clears the text in the details pane.
|
||||
@ -127,27 +105,26 @@ public abstract class AbstractDetailsPanel extends JPanel {
|
||||
/**
|
||||
* Inserts an html-formatted string into the given buffer. This is meant to be used
|
||||
* for inserting the name of each row in the description text.
|
||||
*
|
||||
*
|
||||
* @param buffer the string buffer to add to
|
||||
* @param rowName the name of the row to add
|
||||
*/
|
||||
protected void insertRowTitle(StringBuilder buffer, String rowName) {
|
||||
buffer.append("<TR>");
|
||||
buffer.append("<TD VALIGN=\"TOP\">");
|
||||
insertHTMLLine(buffer, rowName + ":", titleAttrSet);
|
||||
insertHTMLLine(buffer, rowName + ":", titleAttrs);
|
||||
buffer.append("</TD>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an html-formatted string into the given buffer. This is meant to be used
|
||||
* for inserting the value of each row in the description text.
|
||||
*
|
||||
*
|
||||
* @param buffer the string buffer to add to
|
||||
* @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,
|
||||
SimpleAttributeSet attributes) {
|
||||
protected void insertRowValue(StringBuilder buffer, String value, GAttributes attributes) {
|
||||
buffer.append("<TD VALIGN=\"TOP\" WIDTH=\"80%\">");
|
||||
insertHTMLLine(buffer, value, attributes);
|
||||
buffer.append("</TD>");
|
||||
@ -161,33 +138,13 @@ public abstract class AbstractDetailsPanel extends JPanel {
|
||||
* @param string the string to add
|
||||
* @param attributes the formatting instructions
|
||||
*/
|
||||
protected void insertHTMLString(StringBuilder buffer, String string,
|
||||
SimpleAttributeSet attributes) {
|
||||
protected void insertHTMLString(StringBuilder buffer, String string, GAttributes attributes) {
|
||||
|
||||
if (string == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.append("<FONT COLOR=\"");
|
||||
|
||||
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>");
|
||||
buffer.append(attributes.toStyledHtml(string));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,8 +153,7 @@ public abstract class AbstractDetailsPanel extends JPanel {
|
||||
* @param string the string to insert
|
||||
* @param attributes the attributes to apply
|
||||
*/
|
||||
protected void insertHTMLLine(StringBuilder buffer, String string,
|
||||
SimpleAttributeSet attributes) {
|
||||
protected void insertHTMLLine(StringBuilder buffer, String string, GAttributes attributes) {
|
||||
if (string == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -15,17 +15,16 @@
|
||||
*/
|
||||
package ghidra.framework.plugintool.dialog;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
import javax.swing.text.StyleConstants;
|
||||
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.action.MenuData;
|
||||
import docking.actions.KeyBindingUtils;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.*;
|
||||
import ghidra.framework.plugintool.PluginConfigurationModel;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.PluginDescription;
|
||||
@ -37,29 +36,52 @@ import ghidra.util.HTMLUtilities;
|
||||
*/
|
||||
class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
private SimpleAttributeSet nameAttrSet;
|
||||
private SimpleAttributeSet depNameAttrSet;
|
||||
private SimpleAttributeSet descrAttrSet;
|
||||
private SimpleAttributeSet categoriesAttrSet;
|
||||
private SimpleAttributeSet classAttrSet;
|
||||
private SimpleAttributeSet locAttrSet;
|
||||
private SimpleAttributeSet developerAttrSet;
|
||||
private SimpleAttributeSet dependencyAttrSet;
|
||||
private SimpleAttributeSet noValueAttrSet;
|
||||
private static final GColor NO_VALUE_COLOR = new GColor("color.fg.pluginpanel.details.novalue");
|
||||
private static final GColor DEPENDENCY_COLOR =
|
||||
new GColor("color.fg.pluginpanel.details.dependency");
|
||||
private static final GColor LOCATION_COLOR = new GColor("color.fg.pluginpanel.details.loc");
|
||||
private static final GColor DEVELOPER_COLOR =
|
||||
new GColor("color.fg.pluginpanel.details.developer");
|
||||
private static final GColor CLASS_COLOR = new GColor("color.fg.pluginpanel.details.class");
|
||||
private static final GColor CATEGORIES_COLOR =
|
||||
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 PluginTool tool;
|
||||
private PluginDescription currentDescriptor;
|
||||
|
||||
PluginDetailsPanel(PluginTool tool, PluginConfigurationModel model) {
|
||||
super();
|
||||
this.tool = tool;
|
||||
this.model = model;
|
||||
createFieldAttributes();
|
||||
createMainPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refresh() {
|
||||
setPluginDescription(currentDescriptor);
|
||||
}
|
||||
|
||||
void setPluginDescription(PluginDescription descriptor) {
|
||||
|
||||
this.currentDescriptor = descriptor;
|
||||
textLabel.setText("");
|
||||
if (descriptor == null) {
|
||||
return;
|
||||
@ -74,43 +96,43 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
insertRowTitle(buffer, "Name");
|
||||
insertRowValue(buffer, descriptor.getName(),
|
||||
!dependencies.isEmpty() ? depNameAttrSet : nameAttrSet);
|
||||
!dependencies.isEmpty() ? dependenciesNameAttrs : nameAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Description");
|
||||
insertRowValue(buffer, descriptor.getDescription(), descrAttrSet);
|
||||
insertRowValue(buffer, descriptor.getDescription(), descriptionAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Status");
|
||||
insertRowValue(buffer, descriptor.getStatus().getDescription(),
|
||||
(descriptor.getStatus() == PluginStatus.RELEASED) ? titleAttrSet : developerAttrSet);
|
||||
(descriptor.getStatus() == PluginStatus.RELEASED) ? titleAttrs : developerAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Package");
|
||||
insertRowValue(buffer, descriptor.getPluginPackage().getName(), categoriesAttrSet);
|
||||
insertRowValue(buffer, descriptor.getPluginPackage().getName(), categoriesAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Category");
|
||||
insertRowValue(buffer, descriptor.getCategory(), categoriesAttrSet);
|
||||
insertRowValue(buffer, descriptor.getCategory(), categoriesAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Plugin Class");
|
||||
insertRowValue(buffer, descriptor.getPluginClass().getName(), classAttrSet);
|
||||
insertRowValue(buffer, descriptor.getPluginClass().getName(), classAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Class Location");
|
||||
insertRowValue(buffer, descriptor.getSourceLocation(), locAttrSet);
|
||||
insertRowValue(buffer, descriptor.getSourceLocation(), locationAttrs);
|
||||
|
||||
insertRowTitle(buffer, "Used By");
|
||||
|
||||
buffer.append("<TD VALIGN=\"TOP\">");
|
||||
|
||||
if (dependencies.isEmpty()) {
|
||||
insertHTMLLine(buffer, "None", noValueAttrSet);
|
||||
insertHTMLLine(buffer, "None", noValueAttrs);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < dependencies.size(); i++) {
|
||||
insertHTMLString(buffer, dependencies.get(i).getPluginClass().getName(),
|
||||
dependencyAttrSet);
|
||||
dependencyAttrs);
|
||||
if (i < dependencies.size() - 1) {
|
||||
buffer.append(HTMLUtilities.BR);
|
||||
}
|
||||
}
|
||||
insertHTMLLine(buffer, "", titleAttrSet); // add a newline
|
||||
insertHTMLLine(buffer, "", titleAttrs); // add a newline
|
||||
}
|
||||
buffer.append("</TD>");
|
||||
buffer.append("</TR>");
|
||||
@ -121,16 +143,16 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
List<Class<?>> servicesRequired = descriptor.getServicesRequired();
|
||||
if (servicesRequired.isEmpty()) {
|
||||
insertHTMLLine(buffer, "None", noValueAttrSet);
|
||||
insertHTMLLine(buffer, "None", noValueAttrs);
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
buffer.append(HTMLUtilities.BR);
|
||||
}
|
||||
}
|
||||
insertHTMLLine(buffer, "", titleAttrSet); // add a newline
|
||||
insertHTMLLine(buffer, "", titleAttrs); // add a newline
|
||||
}
|
||||
buffer.append("</TD>");
|
||||
buffer.append("</TR>");
|
||||
@ -158,7 +180,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
buffer.append("<TR>");
|
||||
buffer.append("<TD VALIGN=\"TOP\">");
|
||||
insertHTMLLine(buffer, "Loaded Actions:", titleAttrSet);
|
||||
insertHTMLLine(buffer, "Loaded Actions:", titleAttrs);
|
||||
buffer.append("</TD>");
|
||||
|
||||
Set<DockingActionIf> actions = Collections.emptySet();
|
||||
@ -169,7 +191,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
if (actions.isEmpty()) {
|
||||
buffer.append("<TD VALIGN=\"TOP\">");
|
||||
insertHTMLLine(buffer, "No actions for plugin", noValueAttrSet);
|
||||
insertHTMLLine(buffer, "No actions for plugin", noValueAttrs);
|
||||
buffer.append("</TD>");
|
||||
buffer.append("</TR>");
|
||||
return;
|
||||
@ -182,7 +204,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
for (DockingActionIf dockableAction : actions) {
|
||||
buffer.append("<TR><TD WIDTH=\"200\">");
|
||||
insertHTMLString(buffer, dockableAction.getName(), locAttrSet);
|
||||
insertHTMLString(buffer, dockableAction.getName(), locationAttrs);
|
||||
buffer.append("</TD>");
|
||||
|
||||
buffer.append("<TD WIDTH=\"300\">");
|
||||
@ -190,17 +212,17 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
String[] menuPath = menuBarData == null ? null : menuBarData.getMenuPath();
|
||||
String menuPathString = createStringForMenuPath(menuPath);
|
||||
if (menuPathString != null) {
|
||||
insertHTMLString(buffer, menuPathString, locAttrSet);
|
||||
insertHTMLString(buffer, menuPathString, locationAttrs);
|
||||
}
|
||||
else {
|
||||
MenuData popupMenuData = dockableAction.getPopupMenuData();
|
||||
String[] popupPath = popupMenuData == null ? null : popupMenuData.getMenuPath();
|
||||
|
||||
if (popupPath != null) {
|
||||
insertHTMLString(buffer, "(in a context popup menu)", noValueAttrSet);
|
||||
insertHTMLString(buffer, "(in a context popup menu)", noValueAttrs);
|
||||
}
|
||||
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();
|
||||
if (keyBinding != null) {
|
||||
String keyStrokeString = KeyBindingUtils.parseKeyStroke(keyBinding);
|
||||
insertHTMLString(buffer, keyStrokeString, locAttrSet);
|
||||
insertHTMLString(buffer, keyStrokeString, locationAttrs);
|
||||
}
|
||||
else {
|
||||
insertHTMLString(buffer, "No keybinding", noValueAttrSet);
|
||||
insertHTMLString(buffer, "No keybinding", noValueAttrs);
|
||||
}
|
||||
|
||||
buffer.append("</TD></TR>");
|
||||
@ -242,74 +264,19 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
|
||||
@Override
|
||||
protected void createFieldAttributes() {
|
||||
|
||||
titleAttrSet = new SimpleAttributeSet();
|
||||
titleAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
titleAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
titleAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
|
||||
titleAttrSet.addAttribute(StyleConstants.Foreground,
|
||||
new GColor("color.fg.pluginpanel.details.title"));
|
||||
Font font = Gui.getFont(FONT_DEFAULT);
|
||||
titleAttrs = new GAttributes(font, TITLE_COLOR);
|
||||
nameAttrs = new GAttributes(font, NAME_NO_DEPENDENTS_COLOR);
|
||||
dependenciesNameAttrs = new GAttributes(font, NAME_DEPENDENTS_COLOR);
|
||||
descriptionAttrs = new GAttributes(font, DESCRIPTION_COLOR);
|
||||
categoriesAttrs = new GAttributes(font, CATEGORIES_COLOR);
|
||||
locationAttrs = new GAttributes(font, LOCATION_COLOR);
|
||||
developerAttrs = new GAttributes(font, DEVELOPER_COLOR);
|
||||
|
||||
nameAttrSet = new SimpleAttributeSet();
|
||||
nameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
nameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
nameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
|
||||
nameAttrSet.addAttribute(StyleConstants.Foreground,
|
||||
new GColor("color.fg.pluginpanel.details.name.no.dependents"));
|
||||
Font fontMonospaced = Gui.getFont(FONT_MONOSPACED);
|
||||
classAttrs = new GAttributes(fontMonospaced, CLASS_COLOR);
|
||||
dependencyAttrs = new GAttributes(fontMonospaced, DEPENDENCY_COLOR);
|
||||
|
||||
depNameAttrSet = new SimpleAttributeSet();
|
||||
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"));
|
||||
noValueAttrs = new GAttributes(font, NO_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,14 @@
|
||||
*/
|
||||
package ghidra.framework.plugintool.dialog;
|
||||
|
||||
import static ghidra.framework.plugintool.dialog.PluginInstallerTableModel.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.widgets.table.*;
|
||||
@ -149,30 +152,23 @@ public class PluginInstallerDialog extends DialogComponentProvider {
|
||||
tableFilterPanel = new GTableFilterPanel<>(table, tableModel);
|
||||
|
||||
JScrollPane sp = new JScrollPane(table);
|
||||
|
||||
pluginTablePanel.add(sp, BorderLayout.CENTER);
|
||||
pluginTablePanel.add(tableFilterPanel, BorderLayout.SOUTH);
|
||||
|
||||
// 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 to restrict column width.
|
||||
TableColumn inst_col =
|
||||
table.getColumnModel().getColumn(PluginInstallerTableModel.INSTALLED_COL);
|
||||
inst_col.setMaxWidth(30);
|
||||
TableColumn status_col =
|
||||
table.getColumnModel().getColumn(PluginInstallerTableModel.STATUS_COL);
|
||||
status_col.setMaxWidth(24);
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
TableColumn installedColumn = columnModel.getColumn(INSTALLED_COL);
|
||||
installedColumn.setMaxWidth(30);
|
||||
TableColumn statusColumn = columnModel.getColumn(STATUS_COL);
|
||||
statusColumn.setMaxWidth(24);
|
||||
|
||||
tableModel.setTableSortState(
|
||||
TableSortState.createDefaultSortState(PluginInstallerTableModel.NAME_COL));
|
||||
tableModel.setTableSortState(TableSortState.createDefaultSortState(NAME_COL));
|
||||
tableModel.refresh();
|
||||
|
||||
table.getColumnModel()
|
||||
.getColumn(PluginInstallerTableModel.NAME_COL)
|
||||
.setCellRenderer(new NameCellRenderer());
|
||||
table.getColumnModel()
|
||||
.getColumn(PluginInstallerTableModel.STATUS_COL)
|
||||
.setCellRenderer(new StatusCellRenderer());
|
||||
columnModel.getColumn(NAME_COL).setCellRenderer(new NameCellRenderer());
|
||||
columnModel.getColumn(STATUS_COL).setCellRenderer(new StatusCellRenderer());
|
||||
|
||||
HelpService help = Help.getHelpService();
|
||||
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);
|
||||
String toolTipText = "";
|
||||
if (value == PluginInstallerTableModel.EXPERIMENTAL_ICON) {
|
||||
if (value == EXPERIMENTAL_ICON) {
|
||||
toolTipText = "This plugin is usable, but not fully tested or documented";
|
||||
}
|
||||
else if (value == PluginInstallerTableModel.DEV_ICON) {
|
||||
else if (value == DEV_ICON) {
|
||||
toolTipText =
|
||||
"This plugin is under development and not intended for general use.\n" +
|
||||
"It could cause Ghidra to become unstable!";
|
||||
|
@ -176,7 +176,7 @@ public class PluginManagerComponent extends JPanel implements Scrollable {
|
||||
labelPanel.setBackground(BG);
|
||||
|
||||
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"));
|
||||
labelPanel.add(nameLabel);
|
||||
|
||||
|
@ -15,13 +15,11 @@
|
||||
*/
|
||||
package ghidra.framework.project.extensions;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
|
||||
import docking.widgets.table.threaded.ThreadedTableModelListener;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.*;
|
||||
import ghidra.framework.plugintool.dialog.AbstractDetailsPanel;
|
||||
import ghidra.util.extensions.ExtensionDetails;
|
||||
|
||||
@ -33,27 +31,28 @@ import ghidra.util.extensions.ExtensionDetails;
|
||||
*/
|
||||
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");
|
||||
private static final Color FG_COLOR_DATE = new GColor("color.fg.extensionpanel.details.date");
|
||||
private static final Color FG_COLOR_DESCRIPTION =
|
||||
private static final GColor FG_COLOR_DATE = new GColor("color.fg.extensionpanel.details.date");
|
||||
private static final GColor FG_COLOR_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 Color 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 Color FG_COLOR_VERSION =
|
||||
private static final GColor FG_COLOR_NAME = new GColor("color.fg.extensionpanel.details.name");
|
||||
private static final GColor FG_COLOR_PATH = new GColor("color.fg.extensionpanel.path");
|
||||
private static final GColor FG_COLOR_TITLE =
|
||||
new GColor("color.fg.extensionpanel.details.title");
|
||||
private static final GColor FG_COLOR_VERSION =
|
||||
new GColor("color.fg.extensionpanel.details.version");
|
||||
|
||||
/** Attribute sets define the visual characteristics for each field */
|
||||
private SimpleAttributeSet nameAttrSet;
|
||||
private SimpleAttributeSet descrAttrSet;
|
||||
private SimpleAttributeSet authorAttrSet;
|
||||
private SimpleAttributeSet createdOnAttrSet;
|
||||
private SimpleAttributeSet versionAttrSet;
|
||||
private SimpleAttributeSet pathAttrSet;
|
||||
private GAttributes nameAttrSet;
|
||||
private GAttributes descrAttrSet;
|
||||
private GAttributes authorAttrSet;
|
||||
private GAttributes createdOnAttrSet;
|
||||
private GAttributes versionAttrSet;
|
||||
private GAttributes pathAttrSet;
|
||||
private ExtensionDetails currentDetails;
|
||||
|
||||
ExtensionDetailsPanel(ExtensionTablePanel tablePanel) {
|
||||
super();
|
||||
createFieldAttributes();
|
||||
createMainPanel();
|
||||
|
||||
@ -82,13 +81,19 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refresh() {
|
||||
setDescription(currentDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this panel with the given extension.
|
||||
*
|
||||
*
|
||||
* @param details the extension to display
|
||||
*/
|
||||
public void setDescription(ExtensionDetails details) {
|
||||
|
||||
this.currentDetails = details;
|
||||
clear();
|
||||
if (details == null) {
|
||||
return;
|
||||
@ -134,12 +139,14 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
|
||||
|
||||
@Override
|
||||
protected void createFieldAttributes() {
|
||||
titleAttrSet = createAttributeSet(FG_COLOR_TITLE);
|
||||
nameAttrSet = createAttributeSet(FG_COLOR_NAME);
|
||||
descrAttrSet = createAttributeSet(FG_COLOR_DESCRIPTION);
|
||||
authorAttrSet = createAttributeSet(FG_COLOR_AUTHOR);
|
||||
createdOnAttrSet = createAttributeSet(FG_COLOR_DATE);
|
||||
versionAttrSet = createAttributeSet(FG_COLOR_VERSION);
|
||||
pathAttrSet = createAttributeSet(FG_COLOR_PATH);
|
||||
|
||||
Font font = Gui.getFont(FONT_DEFAULT);
|
||||
titleAttrs = new GAttributes(font, FG_COLOR_TITLE);
|
||||
nameAttrSet = new GAttributes(font, FG_COLOR_NAME);
|
||||
descrAttrSet = new GAttributes(font, FG_COLOR_DESCRIPTION);
|
||||
authorAttrSet = new GAttributes(font, FG_COLOR_AUTHOR);
|
||||
createdOnAttrSet = new GAttributes(font, FG_COLOR_DATE);
|
||||
versionAttrSet = new GAttributes(font, FG_COLOR_VERSION);
|
||||
pathAttrSet = new GAttributes(font, FG_COLOR_PATH);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import docking.util.AnimatedIcon;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import docking.widgets.label.GIconLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.layout.VerticalLayout;
|
||||
@ -36,6 +37,8 @@ import resources.ResourceManager;
|
||||
public class GProgressBar extends JPanel {
|
||||
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 progress;
|
||||
private volatile long scaleFactor = 1;
|
||||
@ -47,7 +50,6 @@ public class GProgressBar extends JPanel {
|
||||
private volatile boolean paintProgressValue = true;
|
||||
private boolean showingIcon = true;
|
||||
|
||||
private final float fontSize;
|
||||
private JProgressBar progressBar;
|
||||
private JLabel messageLabel;
|
||||
private JLabel imageLabel;
|
||||
@ -61,10 +63,9 @@ public class GProgressBar extends JPanel {
|
||||
private CancelledListener cancelledListener;
|
||||
|
||||
public GProgressBar(CancelledListener cancelledListener, boolean includeTextField,
|
||||
boolean includeCancelButton, boolean includeAnimatedIcon, float fontSize) {
|
||||
boolean includeCancelButton, boolean includeAnimatedIcon) {
|
||||
super(new BorderLayout(5, 1));
|
||||
this.cancelledListener = cancelledListener;
|
||||
this.fontSize = fontSize;
|
||||
|
||||
buildProgressPanel(includeTextField, includeCancelButton, includeAnimatedIcon);
|
||||
|
||||
@ -217,7 +218,7 @@ public class GProgressBar extends JPanel {
|
||||
// don't care
|
||||
}
|
||||
};
|
||||
messageLabel.setFont(messageLabel.getFont().deriveFont(fontSize));
|
||||
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
|
||||
Dimension d = messageLabel.getPreferredSize();
|
||||
d.width = 180;
|
||||
messageLabel.setPreferredSize(d);
|
||||
|
@ -31,7 +31,6 @@ public class ScheduledTaskPanel extends JPanel {
|
||||
private ScheduledElementLayout layout;
|
||||
|
||||
public ScheduledTaskPanel(String labelText, int indention) {
|
||||
super();
|
||||
this.indention = indention;
|
||||
|
||||
setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
|
||||
@ -44,7 +43,7 @@ public class ScheduledTaskPanel extends JPanel {
|
||||
}
|
||||
|
||||
void addProgressBar() {
|
||||
progressBar = new GProgressBar(null, true, true, false, 12);
|
||||
progressBar = new GProgressBar(null, true, true, false);
|
||||
progressBar.setBackgroundColor(Colors.BACKGROUND);
|
||||
add(progressBar);
|
||||
layout.clearPreferredSize();
|
||||
@ -71,7 +70,7 @@ public class ScheduledTaskPanel extends JPanel {
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
// This layout handles the scrolling based on the scrollOffset as set by the setHiddenViewAmount()
|
||||
// It also optionally shows the scrollbar for the task or group.
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
package ghidra.framework.task;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@ -46,11 +45,11 @@ public class GProgressBarTest extends AbstractDockingTest {
|
||||
cancelled = true;
|
||||
}
|
||||
};
|
||||
progressBar = new GProgressBar(cancelledListener, true, true, true, 10.0f);
|
||||
progressBar = new GProgressBar(cancelledListener, true, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicProgress() {
|
||||
public void testBasicProgress() {
|
||||
progressBar.initialize(100);
|
||||
assertEquals(0, progressBar.getProgress());
|
||||
assertEquals(100, progressBar.getMax());
|
||||
@ -62,7 +61,7 @@ public class GProgressBarTest extends AbstractDockingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongValues() {
|
||||
public void testLongValues() {
|
||||
progressBar.initialize(0x400000000L);
|
||||
progressBar.setProgress(10);
|
||||
assertEquals(10, progressBar.getProgress());
|
||||
@ -73,7 +72,7 @@ public class GProgressBarTest extends AbstractDockingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessage() {
|
||||
public void testMessage() {
|
||||
progressBar.initialize(100);
|
||||
progressBar.setMessage("Hey");
|
||||
assertEquals("Hey", progressBar.getMessage());
|
||||
@ -91,7 +90,7 @@ public class GProgressBarTest extends AbstractDockingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancel() {
|
||||
public void testCancel() {
|
||||
progressBar.initialize(100);
|
||||
progressBar.setProgress(50);
|
||||
assertTrue(!cancelled);
|
||||
|
@ -100,7 +100,7 @@ public class SystemUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the specified user name to eliminate any spaces or leading domain name
|
||||
* Clean the specified user name to eliminate any spaces or leading domain name
|
||||
* which may be present (e.g., "MyDomain\John Doe" becomes "JohnDoe").
|
||||
* @param name user name string to be cleaned-up
|
||||
* @return the clean user name
|
||||
@ -127,8 +127,8 @@ public class SystemUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user that is running the application. This name may be modified to
|
||||
* eliminate any spaces or leading domain name which may be present in Java's
|
||||
* Get the user that is running the application. This name may be modified to
|
||||
* eliminate any spaces or leading domain name which may be present in Java's
|
||||
* {@code user.name} system property (see {@link #getCleanUserName(String)}).
|
||||
* @return the user name
|
||||
*/
|
||||
@ -173,20 +173,15 @@ public class SystemUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the font size override setting is enabled and adjusts
|
||||
* the given font as necessary to match the override setting. If the setting
|
||||
* is not enabled, then <code>font</code> is returned.
|
||||
* No longer supported. Use the theming system for fonts
|
||||
*
|
||||
* @param font
|
||||
* The current font to adjust, if necessary.
|
||||
* @return a font object with the proper size.
|
||||
* @param font the font
|
||||
* @return the same font passed in
|
||||
* @deprecated Use the theming system for fonts
|
||||
*/
|
||||
@Deprecated(since = "11.1", forRemoval = true)
|
||||
public static Font adjustForFontSizeOverride(Font font) {
|
||||
if (FONT_SIZE_OVERRIDE_VALUE == null) {
|
||||
return font;
|
||||
}
|
||||
|
||||
return font.deriveFont((float) FONT_SIZE_OVERRIDE_VALUE.intValue());
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,10 +345,10 @@ public class SystemUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file that contains the given class. If the class is in a jar file, then
|
||||
* the jar file will be returned. If the file is in a .class file, then the directory
|
||||
* Returns a file that contains the given class. If the class is in a jar file, then
|
||||
* the jar file will be returned. If the file is in a .class file, then the directory
|
||||
* containing the package root will be returned (i.e. the "bin" directory).
|
||||
*
|
||||
*
|
||||
* @param classObject the class for which to get the location
|
||||
* @return the containing location
|
||||
*/
|
||||
|
@ -42,12 +42,12 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the field of the name <code>fieldName</code> on the given
|
||||
* class. If the given class does not contain the field, then this
|
||||
* method will recursively call up <code>containingClass</code>'s
|
||||
* implementation tree looking for a parent implementation of the
|
||||
* Locates the field of the name <code>fieldName</code> on the given
|
||||
* class. If the given class does not contain the field, then this
|
||||
* method will recursively call up <code>containingClass</code>'s
|
||||
* implementation tree looking for a parent implementation of the
|
||||
* requested field.
|
||||
*
|
||||
*
|
||||
* @param fieldName The name of the field to locate.
|
||||
* @param containingClass The class that contains the desired field.
|
||||
* @return The Field object that matches the given name, or null if not
|
||||
@ -73,12 +73,12 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the field of the name <code>fieldName</code> on the given
|
||||
* class. If the given class does not contain the field, then this
|
||||
* method will recursively call up <code>containingClass</code>'s
|
||||
* implementation tree looking for a parent implementation of the
|
||||
* Locates the field of the name <code>fieldName</code> on the given
|
||||
* class. If the given class does not contain the field, then this
|
||||
* method will recursively call up <code>containingClass</code>'s
|
||||
* implementation tree looking for a parent implementation of the
|
||||
* requested field.
|
||||
*
|
||||
*
|
||||
* @param fieldName The name of the field to locate.
|
||||
* @param containingClass The class that contains the desired field.
|
||||
* @return The Field object that matches the given name, or null if not
|
||||
@ -104,12 +104,12 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the method of the name <code>methodName</code> on the given
|
||||
* class. If the given class does not contain the method, then this
|
||||
* method will recursively call up <code>containingClass</code>'s
|
||||
* implementation tree looking for a parent implementation of the
|
||||
* Locates the method of the name <code>methodName</code> on the given
|
||||
* class. If the given class does not contain the method, then this
|
||||
* method will recursively call up <code>containingClass</code>'s
|
||||
* implementation tree looking for a parent implementation of the
|
||||
* requested method.
|
||||
*
|
||||
*
|
||||
* @param methodName The name of the method to locate.
|
||||
* @param containingClass The class that contains the desired method.
|
||||
* @param parameterTypes The parameters of the desired method (may be null).
|
||||
@ -158,7 +158,7 @@ public class ReflectionUtilities {
|
||||
|
||||
/**
|
||||
* Get the first field specification contained within containingClass which has the type classType.
|
||||
* This method is only really useful if it is known that only a single field of
|
||||
* This method is only really useful if it is known that only a single field of
|
||||
* classType exists within the containingClass hierarchy.
|
||||
* @param classType the class
|
||||
* @param containingClass the class that contains a field of the given type
|
||||
@ -184,40 +184,52 @@ public class ReflectionUtilities {
|
||||
/**
|
||||
* Returns the class name of the entry in the stack that comes before all references to the
|
||||
* given classes. This is useful for figuring out at runtime who is calling a particular
|
||||
* method.
|
||||
* method.
|
||||
* <p>
|
||||
* This method can take multiple classes, but you really only need to pass the oldest
|
||||
* 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 desired class name
|
||||
*/
|
||||
public static String getClassNameOlderThan(Class<?>... classes) {
|
||||
|
||||
Throwable t = createThrowableWithStackOlderThan(classes);
|
||||
StackTraceElement[] stackTrace = t.getStackTrace();
|
||||
return stackTrace[0].getClassName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Returns the class name of the entry in the stack that comes before all references to the
|
||||
* given patterns. This is useful for figuring out at runtime who is calling a particular
|
||||
* method.
|
||||
*
|
||||
* @param patterns the patterns to ignore
|
||||
* @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()) {
|
||||
// Always ignore our class. We get this for free if the client passes in any
|
||||
// classes.
|
||||
toFind.add(0, ReflectionUtilities.class.getName());
|
||||
private static Throwable createThrowableWithStackOlderThan(List<String> patterns) {
|
||||
|
||||
if (patterns.isEmpty()) {
|
||||
// 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();
|
||||
@ -227,7 +239,7 @@ public class ReflectionUtilities {
|
||||
|
||||
StackTraceElement element = trace[i];
|
||||
String className = element.getClassName();
|
||||
int nameIndex = toFind.indexOf(className);
|
||||
int nameIndex = patterns.indexOf(className);
|
||||
if (nameIndex != -1) {
|
||||
lastIgnoreIndex = i;
|
||||
}
|
||||
@ -242,13 +254,13 @@ public class ReflectionUtilities {
|
||||
if (lastIgnoreIndex == -1) {
|
||||
Msg.error(ReflectionUtilities.class,
|
||||
"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) {
|
||||
Msg.error(ReflectionUtilities.class,
|
||||
"Change call to ReflectionUtils. Call stack only contains the classes to ignore: " +
|
||||
Arrays.toString(classes));
|
||||
"Change call to ReflectionUtils. Call stack contains only ignored patterns: " +
|
||||
patterns);
|
||||
}
|
||||
|
||||
int startIndex = lastIgnoreIndex + 1;
|
||||
@ -258,11 +270,27 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first occurrence of the given pattern and then stops filtering when it finds
|
||||
* 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
|
||||
* something that is not that pattern
|
||||
*
|
||||
*
|
||||
* @param trace the trace to update
|
||||
* @param pattern the non-regex patterns used to perform a
|
||||
* @param pattern the non-regex patterns used to perform a
|
||||
* {@link String#contains(CharSequence)} on each {@link StackTraceElement} line
|
||||
* @return the updated trace
|
||||
*/
|
||||
@ -296,12 +324,12 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the given <code>patterns</code> to remove elements from the given stack trace.
|
||||
* Uses the given <code>patterns</code> to remove elements from the given stack trace.
|
||||
* The current implementation will simply perform a <code>toString()</code> on each element and
|
||||
* then check to see if that string contains any of the <code>patterns</code>.
|
||||
*
|
||||
*
|
||||
* @param trace the trace to filter
|
||||
* @param patterns the non-regex patterns used to perform a
|
||||
* @param patterns the non-regex patterns used to perform a
|
||||
* {@link String#contains(CharSequence)} on each {@link StackTraceElement}
|
||||
* line.
|
||||
* @return the filtered trace
|
||||
@ -325,15 +353,15 @@ public class ReflectionUtilities {
|
||||
/**
|
||||
* A convenience method to create a throwable, filtering any lines that contain the given
|
||||
* non-regex patterns. This can be useful for emitting diagnostic stack traces.
|
||||
*
|
||||
* @param patterns the non-regex patterns used to perform a
|
||||
*
|
||||
* @param patterns the non-regex patterns used to perform a
|
||||
* {@link String#contains(CharSequence)} on each {@link StackTraceElement}
|
||||
* line.
|
||||
* @return the new throwable
|
||||
*/
|
||||
public static Throwable createFilteredThrowable(String... patterns) {
|
||||
|
||||
Throwable t = createThrowableWithStackOlderThan();
|
||||
Throwable t = createThrowableWithStackOlderThan(new ArrayList<>());
|
||||
StackTraceElement[] trace = t.getStackTrace();
|
||||
StackTraceElement[] filtered = filterStackTrace(trace, patterns);
|
||||
t.setStackTrace(filtered);
|
||||
@ -341,40 +369,39 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to create a throwable, filtering boiler-plate Java-related
|
||||
* lines (e.g., AWT, Swing, Security, etc).
|
||||
* A convenience method to create a throwable, filtering boiler-plate Java-related
|
||||
* lines (e.g., AWT, Swing, Security, etc).
|
||||
* This can be useful for emitting diagnostic stack traces with reduced noise.
|
||||
*
|
||||
*
|
||||
* @return the new throwable
|
||||
*/
|
||||
public static Throwable createJavaFilteredThrowable() {
|
||||
|
||||
Throwable t = createThrowableWithStackOlderThan();
|
||||
Throwable t = createThrowableWithStackOlderThan(List.of());
|
||||
return filterJavaThrowable(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to create a throwable, filtering boiler-plate Java-related
|
||||
* lines (e.g., AWT, Swing, Security, etc).
|
||||
* This can be useful for emitting diagnostic stack traces with reduced noise.
|
||||
*
|
||||
* A convenience method to create a throwable, filtering boiler-plate Java-related
|
||||
* lines (e.g., AWT, Swing, Security, etc).
|
||||
* This can be useful for emitting diagnostic stack traces with reduced noise.
|
||||
*
|
||||
* <p>This method differs from {@link #createJavaFilteredThrowable()} in that this method
|
||||
* returns a String, which is useful when printing log messages without having to directly
|
||||
* print the stack trace.
|
||||
*
|
||||
*
|
||||
* @return the new throwable
|
||||
*/
|
||||
public static String createJavaFilteredThrowableString() {
|
||||
Throwable t = createThrowableWithStackOlderThan();
|
||||
Throwable t = createThrowableWithStackOlderThan(List.of());
|
||||
Throwable filtered = filterJavaThrowable(t);
|
||||
return stackTraceToString(filtered);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to take a throwable, filter boiler-plate Java-related
|
||||
* lines (e.g., AWT, Swing, Security, etc).
|
||||
* A convenience method to take a throwable, filter boiler-plate Java-related
|
||||
* lines (e.g., AWT, Swing, Security, etc).
|
||||
* This can be useful for emitting diagnostic stack traces with reduced noise.
|
||||
*
|
||||
*
|
||||
* @param t the throwable to filter
|
||||
* @return the throwable
|
||||
*/
|
||||
@ -418,15 +445,15 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ordered set of interfaces and classes that are shared amongst the items in
|
||||
* Returns an ordered set of interfaces and classes that are shared amongst the items in
|
||||
* the list.
|
||||
* <p>
|
||||
* The order of the items is as they are first encountered, favoring interfaces before
|
||||
* The order of the items is as they are first encountered, favoring interfaces before
|
||||
* classes. Further, interface hierarchies are examined before concrete parent extensions.
|
||||
* <p>
|
||||
* If the given items have no parents in common, then the result will be a list with
|
||||
* only <code>Object.class</code>.
|
||||
*
|
||||
*
|
||||
* @param list the items to examine
|
||||
* @return the set of items
|
||||
*/
|
||||
@ -461,15 +488,15 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ordered set of parent interfaces and classes that are shared
|
||||
* Returns an ordered set of parent interfaces and classes that are shared
|
||||
* amongst the items in the list.
|
||||
* <p>
|
||||
* The order of the items is as they are first encountered, favoring interfaces before
|
||||
* The order of the items is as they are first encountered, favoring interfaces before
|
||||
* classes. Further, interface hierarchies are examined before concrete parent extensions.
|
||||
* <p>
|
||||
* If the given items have no parents in common, then the result will be a list with
|
||||
* only <code>Object.class</code>.
|
||||
*
|
||||
*
|
||||
* @param list the items to examine
|
||||
* @return the set of items
|
||||
*/
|
||||
@ -494,9 +521,9 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the given {@link Throwable} into a String version of its
|
||||
* Turns the given {@link Throwable} into a String version of its
|
||||
* {@link Throwable#printStackTrace()} method.
|
||||
*
|
||||
*
|
||||
* @param t the throwable
|
||||
* @return the string
|
||||
*/
|
||||
@ -505,9 +532,9 @@ public class ReflectionUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the given {@link Throwable} into a String version of its
|
||||
* Turns the given {@link Throwable} into a String version of its
|
||||
* {@link Throwable#printStackTrace()} method.
|
||||
*
|
||||
*
|
||||
* @param message the preferred message to use. If null, the throwable message will be used
|
||||
* @param t the throwable
|
||||
* @return the string
|
||||
@ -543,11 +570,11 @@ public class ReflectionUtilities {
|
||||
|
||||
/**
|
||||
* Returns an order set of all interfaces implemented and classes extended for the entire
|
||||
* type structure of the given class.
|
||||
* type structure of the given class.
|
||||
* <p>
|
||||
* If <code>Object.class</code> is passed to this method, then it will be returned in the
|
||||
* If <code>Object.class</code> is passed to this method, then it will be returned in the
|
||||
* result of this method.
|
||||
*
|
||||
*
|
||||
* @param c the class to introspect
|
||||
* @return the set of parents
|
||||
*/
|
||||
@ -581,7 +608,7 @@ public class ReflectionUtilities {
|
||||
|
||||
/**
|
||||
* Returns the type arguments for the given base class and extension.
|
||||
*
|
||||
*
|
||||
* <p>Caveat: this lookup will only work if the given child class is a concrete class that
|
||||
* has its type arguments specified. For example, these cases will work:
|
||||
* <pre>
|
||||
@ -592,17 +619,17 @@ public class ReflectionUtilities {
|
||||
*
|
||||
* // class definition
|
||||
* public class MyList implements List<String> {
|
||||
* </pre>
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* Whereas this case will not work:
|
||||
* <pre>
|
||||
* // local variable with the type specified
|
||||
* List<String> myList = new ArrayList<String>();
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>Note: a null entry in the result list will exist for any type that was unrecoverable
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param <T> the type of the base and child class
|
||||
* @param baseClass the base class
|
||||
* @param childClass the child class
|
||||
@ -618,7 +645,7 @@ public class ReflectionUtilities {
|
||||
Type baseClassAsType =
|
||||
walkClassHierarchyAndResolveTypes(baseClass, resolvedTypesDictionary, childClass);
|
||||
|
||||
// try to resolve type arguments defined by 'baseClass' to the raw runtime class
|
||||
// try to resolve type arguments defined by 'baseClass' to the raw runtime class
|
||||
Type[] baseClassDeclaredTypeArguments = getDeclaredTypeArguments(baseClassAsType);
|
||||
return resolveBaseClassTypeArguments(resolvedTypesDictionary,
|
||||
baseClassDeclaredTypeArguments);
|
||||
|
@ -33,7 +33,6 @@ import resources.ResourceManager;
|
||||
public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
|
||||
|
||||
public RepositoryCustomScreenShots() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -127,8 +126,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
|
||||
int y = p.y - radius;
|
||||
g.fillOval(x, y, radius * 2, 2 * radius);
|
||||
|
||||
Font f = g.getFont().deriveFont(12f);
|
||||
g.setFont(f);
|
||||
FontMetrics metrics = g.getFontMetrics();
|
||||
int height = metrics.getHeight();
|
||||
g.setColor(Palette.BLACK);
|
||||
@ -154,8 +151,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
|
||||
BasicStroke stroke = new BasicStroke(1);
|
||||
g.setStroke(stroke);
|
||||
|
||||
Font f = g.getFont().deriveFont(12f);
|
||||
g.setFont(f);
|
||||
FontMetrics metrics = g.getFontMetrics();
|
||||
int margin = 5;
|
||||
int height = metrics.getHeight() * text.length + 2 * margin;
|
||||
@ -189,8 +184,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
|
||||
Graphics2D g = ((BufferedImage) image).createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
Font f = g.getFont().deriveFont(12f);
|
||||
g.setFont(f);
|
||||
FontMetrics metrics = g.getFontMetrics();
|
||||
// int margin = 5;
|
||||
int height = metrics.getHeight() * text.length;
|
||||
|
Loading…
Reference in New Issue
Block a user