GP-1981 - Updated help to allow authors to use theme image ids; updated
help to only allow modules that live on the classpath. Dpdating themd documentation. Fixing gradle help build
@ -92,8 +92,8 @@ icon.debugger.thread = thread.png
|
||||
icon.debugger.processor = memory16.gif // TODO this icon was missing 'kcmprocessor.png'
|
||||
icon.debugger.launch = launch.png
|
||||
icon.debugger.attach = attach.png
|
||||
icon.debugger.resume = continue.png
|
||||
icon.debugger.terminate = stop.png
|
||||
icon.debugger.resume = resume.png
|
||||
icon.debugger.interrupt = interrupt.png
|
||||
icon.debugger.kill = kill.png
|
||||
icon.debugger.detach = detach.png
|
||||
icon.debugger.record = record.png
|
||||
@ -101,10 +101,11 @@ icon.debugger.step.into = stepinto.png
|
||||
icon.debugger.step.over = stepover.png
|
||||
icon.debugger.step.back = stepback.png
|
||||
icon.debugger.step.finish = stepout.png
|
||||
icon.debugger.step.last = steplast.png
|
||||
icon.debugger.skip.over = skipover.png
|
||||
icon.debugger.snap.forward = 2rightarrow.png
|
||||
icon.debugger.snap.backward = 2leftarrow.png
|
||||
icon.debugger.seek.present = icon.debugger.resume
|
||||
icon.debugger.seek.present = seek-present.png
|
||||
|
||||
icon.debugger.breakpoint.set = breakpoint-enable.png
|
||||
icon.debugger.breakpoint.clear = breakpoint-clear.png
|
||||
|
@ -60,7 +60,6 @@ import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import resources.MultiIcon;
|
||||
import resources.ResourceManager;
|
||||
|
||||
public interface DebuggerResources {
|
||||
String OPTIONS_CATEGORY_DEBUGGER = "Debugger";
|
||||
@ -77,23 +76,20 @@ public interface DebuggerResources {
|
||||
Icon ICON_PROGRAM = ProgramContentHandler.PROGRAM_ICON;
|
||||
Icon ICON_PROCESSOR = new GIcon("icon.debugger.processor");
|
||||
|
||||
Icon ICON_INTERRUPT = ResourceManager.loadImage("images/interrupt.png"); // TODO do gColor
|
||||
|
||||
Icon ICON_LAUNCH = new GIcon("icon.debugger.launch");
|
||||
Icon ICON_ATTACH = new GIcon("icon.debugger.attach");
|
||||
Icon ICON_RESUME = new GIcon("icon.debugger.resume");
|
||||
Icon ICON_TERMINATE = new GIcon("icon.debugger.terminate"); // TODO was this deleted
|
||||
Icon ICON_INTERRUPT = new GIcon("icon.debugger.interrupt");
|
||||
Icon ICON_KILL = new GIcon("icon.debugger.kill");
|
||||
Icon ICON_DETACH = new GIcon("icon.debugger.detach");
|
||||
Icon ICON_RECORD = new GIcon("icon.debugger.record");
|
||||
|
||||
Icon ICON_STEP_LAST = ResourceManager.loadImage("images/steplast.png"); // TODO GColor
|
||||
|
||||
Icon ICON_STEP_INTO = new GIcon("icon.debugger.step.into");
|
||||
Icon ICON_STEP_OVER = new GIcon("icon.debugger.step.over");
|
||||
Icon ICON_SKIP_OVER = new GIcon("icon.debugger.step.back");
|
||||
Icon ICON_STEP_FINISH = new GIcon("icon.debugger.step.finish");
|
||||
Icon ICON_STEP_BACK = new GIcon("icon.debugger.skip.over");
|
||||
Icon ICON_STEP_LAST = new GIcon("icon.debugger.step.last");
|
||||
|
||||
Icon ICON_SNAP_FORWARD = new GIcon("icon.debugger.snap.forward");
|
||||
Icon ICON_SNAP_BACKWARD = new GIcon("icon.debugger.snap.backward");
|
||||
|
@ -640,7 +640,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||
}
|
||||
assertEquals(2, filtLocs.size());
|
||||
|
||||
breakpointsProvider.setSelectedBreakpoints(Set.of(data.get(0).getLogicalBreakpoint()));
|
||||
LogicalBreakpointRow bpRow = data.get(0);
|
||||
runSwing(() -> breakpointsProvider
|
||||
.setSelectedBreakpoints(Set.of(bpRow.getLogicalBreakpoint())));
|
||||
waitForSwing();
|
||||
|
||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
|
@ -66,6 +66,7 @@ dependencies {
|
||||
testImplementation project(path: ':Project', configuration: 'testArtifacts')
|
||||
testImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
|
||||
testImplementation project(path: ':DB', configuration: 'testArtifacts')
|
||||
helpPath project(path: ':Docking', configuration: 'helpPath') // this module's help has links to Base help files
|
||||
|
||||
javacc 'net.java.dev.javacc:javacc:5.0'
|
||||
}
|
||||
|
@ -1032,7 +1032,6 @@ src/main/resources/images/empty8x16.png||GHIDRA||||END|
|
||||
src/main/resources/images/emptyFragment.gif||GHIDRA||||END|
|
||||
src/main/resources/images/emptyFragmentInView.gif||GHIDRA||||END|
|
||||
src/main/resources/images/enum.png||GHIDRA||||END|
|
||||
src/main/resources/images/erase16.png||GHIDRA||||END|
|
||||
src/main/resources/images/famfamfam_silk_icons_v013/application_cascade.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/famfamfam_silk_icons_v013/application_get.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/famfamfam_silk_icons_v013/application_key.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
@ -1071,6 +1070,8 @@ src/main/resources/images/fingerPointer.png||GHIDRA||||END|
|
||||
src/main/resources/images/font.png||FAMFAMFAM Icons - CC 2.5||||END|
|
||||
src/main/resources/images/format-text-bold.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/functionDef.png||GHIDRA||||END|
|
||||
src/main/resources/images/function_graph.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/function_graph_curvey.png||GHIDRA||||END|
|
||||
src/main/resources/images/functions.gif||GHIDRA||||END|
|
||||
src/main/resources/images/go-down.tango.16.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/go-home.png||Tango Icons - Public Domain|||Tango|END|
|
||||
@ -1139,7 +1140,7 @@ src/main/resources/images/package.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set
|
||||
src/main/resources/images/package_development.png||Nuvola Icons - LGPL 2.1|||nuvola|END|
|
||||
src/main/resources/images/package_green.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/page_white.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/page_white_copy.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/page_white_c.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/pencil.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/pencil16.png||GHIDRA||||END|
|
||||
src/main/resources/images/phone.png||Oxygen Icons - LGPL 3.0||||END|
|
||||
@ -1167,11 +1168,11 @@ src/main/resources/images/stopNode.png||FAMFAMFAM Icons - CC 2.5|||famfamfam sil
|
||||
src/main/resources/images/table.png||FAMFAMFAM Icons - CC 2.5|||silk|END|
|
||||
src/main/resources/images/table_delete.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/table_go.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/table_relationship.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/table_row_delete.png||FAMFAMFAM Icons - CC 2.5|||silk|END|
|
||||
src/main/resources/images/tag_yellow.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/text-x-csrc.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/text_list_bullets.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/text_lowercase.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/textfield.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/tools-report-bug.png||Oxygen Icons - LGPL 3.0||||END|
|
||||
src/main/resources/images/twosComplement.png||GHIDRA||||END|
|
||||
|
@ -23,6 +23,8 @@ icon.base.application.64 = GhidraIcon64.png
|
||||
icon.base.application.128 = GhidraIcon128.png
|
||||
icon.base.application.256 = GhidraIcon256.png
|
||||
|
||||
icon.help.home = GHIDRA_1.png
|
||||
|
||||
icon.provider.clone = camera-photo.png
|
||||
|
||||
icon.plugin.datatypes.built.in = package_development.png
|
||||
|
@ -49,10 +49,7 @@
|
||||
|
||||
<tocroot>
|
||||
|
||||
<tocdef id="Root"
|
||||
sortgroup="a"
|
||||
text="Welcome to Ghidra Help"
|
||||
target="help/topics/Misc/Welcome_to_Ghidra_Help.htm">
|
||||
<tocref id="Root">
|
||||
|
||||
<tocdef id="Intro" sortgroup="1a" text="Introduction" target="help/topics/Intro/Intro.htm" />
|
||||
|
||||
@ -383,11 +380,11 @@
|
||||
<tocdef id="Glossary" sortgroup="i" text="Glossary" target="help/topics/Glossary/glossary.htm" />
|
||||
<tocdef id="What's New" sortgroup="j" text="What's New" target="docs/WhatsNew.html" />
|
||||
<tocdef id="Tips of the Day" sortgroup="k" text="Tips of the Day" target="help/topics/Misc/Tips.htm" />
|
||||
<tocdef id="Appendix" sortgroup="m" text="Appendix" target="help/topics/Misc/Appendix.htm">
|
||||
<tocdef id="Appendix" sortgroup="z" text="Appendix" target="help/topics/Misc/Appendix.htm">
|
||||
<tocdef id="Block Models" sortgroup="a" text="Block Models" target="help/topics/BlockModel/Block_Model.htm" />
|
||||
<tocdef id="Languages" sortgroup="b" text="Languages" target="help/topics/LanguageProviderPlugin/Languages.htm" />
|
||||
</tocdef>
|
||||
|
||||
</tocdef> <!-- End Welcome to Ghidra Help -->
|
||||
</tocref> <!-- End Welcome to Ghidra Help -->
|
||||
|
||||
</tocroot>
|
||||
|
@ -58,8 +58,8 @@ import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class ListingMergePanel extends JPanel
|
||||
implements MergeConstants, FocusListener, CodeFormatService {
|
||||
private static final Icon HIDE_ICON = new GIcon("icons.base.listing.conflict.collapse");
|
||||
private static final Icon SHOW_ICON = new GIcon("icons.base.listing.conflict.expand");
|
||||
private static final Icon HIDE_ICON = new GIcon("icon.plugin.merge.conflict.collapse");
|
||||
private static final Icon SHOW_ICON = new GIcon("icon.plugin.merge.conflict.expand");
|
||||
|
||||
private JComponent topComp;
|
||||
private JComponent bottomComp;
|
||||
|
@ -317,7 +317,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||
|
||||
private void createCopyBtn(JToolBar toolbar1) {
|
||||
Icon copyIcon = Icons.COPY_ICON;
|
||||
Action copyAction = new CopyAction("copy", (ImageIcon) copyIcon,
|
||||
Action copyAction = new CopyAction("copy", copyIcon,
|
||||
"Copy the full search string to clipboard");
|
||||
EmptyBorderButton copyBtn = new EmptyBorderButton();
|
||||
copyBtn.setAction(copyAction);
|
||||
@ -328,7 +328,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||
|
||||
private EmptyBorderToggleButton createHexViewBtn(JToolBar toolbar1) {
|
||||
Icon hexIcon = new GIcon("icon.plugin.instructiontable.hex");
|
||||
Action hexAction = new HexAction("hex", (ImageIcon) hexIcon, "hex view");
|
||||
Action hexAction = new HexAction("hex", hexIcon, "hex view");
|
||||
EmptyBorderToggleButton hexBtn = new EmptyBorderToggleButton();
|
||||
hexBtn.setAction(hexAction);
|
||||
hexBtn.setName("Hex View Button");
|
||||
@ -340,7 +340,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||
|
||||
private EmptyBorderToggleButton createBinaryViewBtn(JToolBar toolbar1) {
|
||||
Icon binaryIcon = new GIcon("icon.plugin.instructiontable.binary");
|
||||
Action binaryAction = new BinaryAction("binary", (ImageIcon) binaryIcon, "binary view");
|
||||
Action binaryAction = new BinaryAction("binary", binaryIcon, "binary view");
|
||||
EmptyBorderToggleButton binaryBtn = new EmptyBorderToggleButton();
|
||||
binaryBtn.setAction(binaryAction);
|
||||
binaryBtn.setName("binary view button");
|
||||
@ -558,7 +558,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||
|
||||
private class BinaryAction extends AbstractAction {
|
||||
|
||||
public BinaryAction(String text, ImageIcon icon, String desc) {
|
||||
public BinaryAction(String text, Icon icon, String desc) {
|
||||
super(text, icon);
|
||||
putValue(SHORT_DESCRIPTION, desc);
|
||||
}
|
||||
@ -572,7 +572,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||
|
||||
private class HexAction extends AbstractAction {
|
||||
|
||||
public HexAction(String text, ImageIcon icon, String desc) {
|
||||
public HexAction(String text, Icon icon, String desc) {
|
||||
super(text, icon);
|
||||
putValue(SHORT_DESCRIPTION, desc);
|
||||
}
|
||||
@ -586,7 +586,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||
|
||||
private class CopyAction extends AbstractAction {
|
||||
|
||||
public CopyAction(String text, ImageIcon icon, String desc) {
|
||||
public CopyAction(String text, Icon icon, String desc) {
|
||||
super(text, icon);
|
||||
putValue(SHORT_DESCRIPTION, desc);
|
||||
|
||||
|
@ -515,17 +515,9 @@ public class ProgramTreePlugin extends ProgramPlugin
|
||||
|
||||
/**
|
||||
* Method renameView.
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
*
|
||||
* @param treeViewProvider
|
||||
* @param newName
|
||||
* @return boolean
|
||||
=======
|
||||
*
|
||||
* @param treeViewProvider the provider
|
||||
* @param newName the new name
|
||||
* @return true if renamed
|
||||
>>>>>>> 0eb4b9d GP-1981 - Theming - Base Module
|
||||
*/
|
||||
boolean renameView(TreeViewProvider treeViewProvider, String newName) {
|
||||
Listing listing = currentProgram.getListing();
|
||||
|
@ -296,16 +296,10 @@ public class FieldHeaderComp extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
* Returns the index of the field on the given row containing the give x pos.
|
||||
* @param row the row on which to find the index of the field contianing the x coordinate.
|
||||
* @param x the horizontal coordinate (in pixels)
|
||||
=======
|
||||
* Returns the index of the field on the given row containing the give x position.
|
||||
* @param row the row on which to find the index of the field containing the x coordinate.
|
||||
* @param x the horizontal coordinate (in pixels)
|
||||
* @return the column
|
||||
>>>>>>> 1c5bb47 GP-1981 - Theming - GColor migration fixes
|
||||
*/
|
||||
public int getCol(int row, int x) {
|
||||
if (x < 0) {
|
||||
|
@ -22,7 +22,8 @@ import java.util.Map.Entry;
|
||||
import javax.help.HelpSet;
|
||||
import javax.help.HelpSetException;
|
||||
|
||||
import docking.help.*;
|
||||
import docking.help.GHelpClassLoader;
|
||||
import docking.help.HelpManager;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.*;
|
||||
import ghidra.framework.Application;
|
||||
@ -36,6 +37,12 @@ import resources.ResourceManager;
|
||||
*/
|
||||
public class GhidraHelpService extends HelpManager {
|
||||
|
||||
/**
|
||||
* The hardcoded value to use for all HelpSet 'home id' values. Subclasses may change this
|
||||
* value by overriding {@link #getHomeId()}.
|
||||
*/
|
||||
private static final String GHIDRA_HOME_ID = "Misc_Ghidra_Help_Contents";
|
||||
|
||||
private static final String MASTER_HELP_SET_HS = "Base_HelpSet.hs";
|
||||
private ThemeListener listener = new HelpThemeListener();
|
||||
|
||||
@ -68,6 +75,11 @@ public class GhidraHelpService extends HelpManager {
|
||||
return ResourceManager.getResource("help/" + HelpService.DUMMY_HELP_SET_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHomeId() {
|
||||
return GHIDRA_HOME_ID;
|
||||
}
|
||||
|
||||
private void loadHelpSets() {
|
||||
|
||||
Map<ResourceFile, Set<URL>> helpSetsByModule = findHelpSetsByModule();
|
||||
|
Before Width: | Height: | Size: 444 B After Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 587 B |
Before Width: | Height: | Size: 663 B After Width: | Height: | Size: 663 B |
@ -22,6 +22,7 @@ import java.awt.Color;
|
||||
import org.junit.Test;
|
||||
|
||||
import docking.AbstractErrDialog;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import ghidra.program.database.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.util.*;
|
||||
@ -64,8 +65,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddVoidProperty() throws Exception {
|
||||
@Test
|
||||
public void testAddVoidProperty() throws Exception {
|
||||
mtf.initialize("DiffTestPgm1", new ProgramModifierListener() {
|
||||
|
||||
@Override
|
||||
@ -127,8 +128,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddSpaceProperty() throws Exception {
|
||||
@Test
|
||||
public void testAddSpaceProperty() throws Exception {
|
||||
// ********************
|
||||
// *** DiffTestPgm2 ***
|
||||
// ********************
|
||||
@ -217,8 +218,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddObjectProperty() throws Exception {
|
||||
@Test
|
||||
public void testAddObjectProperty() throws Exception {
|
||||
// ********************
|
||||
// *** DiffTestPgm1 ***
|
||||
// ********************
|
||||
@ -334,7 +335,7 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddStringProperty() throws Exception {
|
||||
public void testAddStringProperty() throws Exception {
|
||||
mtf.initialize("DiffTestPgm1", new ProgramModifierListener() {
|
||||
|
||||
@Override
|
||||
@ -656,7 +657,7 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
|
||||
AbstractErrDialog errDlg = waitForErrorDialog();
|
||||
String message = errDlg.getMessage();
|
||||
assertEquals("Latest and Checked Out program versions do not have the same type for " +
|
||||
assertEquals("Latest and Checked Out program versions do not have the same type for " +
|
||||
"'testMap' property.", message);
|
||||
pressButtonByText(errDlg, "OK");
|
||||
|
||||
@ -683,7 +684,7 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveSpaceProperty() throws Exception {
|
||||
public void testRemoveSpaceProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -745,8 +746,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveColorProperty() throws Exception {
|
||||
@Test
|
||||
public void testRemoveColorProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -800,13 +801,13 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
Address address = resultProgram.getMinAddress();
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.GREEN), pm.get(address));
|
||||
assertEquals(new SaveableColor(Palette.GREEN), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveVsChangeSpaceProperty() throws Exception {
|
||||
@Test
|
||||
public void testRemoveVsChangeSpaceProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -882,8 +883,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveVsChangeTestColorProperty() throws Exception {
|
||||
@Test
|
||||
public void testRemoveVsChangeTestColorProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -953,8 +954,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeSpaceProperty() throws Exception {
|
||||
@Test
|
||||
public void testChangeSpaceProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1031,8 +1032,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeTestColorProperty() throws Exception {
|
||||
@Test
|
||||
public void testChangeTestColorProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1103,8 +1104,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyToAllSpacePropertyConflicts() throws Exception {
|
||||
@Test
|
||||
public void testApplyToAllSpacePropertyConflicts() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1172,8 +1173,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyToAllColorPropertyConflicts() throws Exception {
|
||||
@Test
|
||||
public void testApplyToAllColorPropertyConflicts() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1240,8 +1241,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiplePropertyTypeConflicts() throws Exception {
|
||||
@Test
|
||||
public void testMultiplePropertyTypeConflicts() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1350,8 +1351,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyToAllSpaceForMultipleTypeConflicts() throws Exception {
|
||||
@Test
|
||||
public void testApplyToAllSpaceForMultipleTypeConflicts() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1453,8 +1454,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyToAllForEachConflict() throws Exception {
|
||||
@Test
|
||||
public void testApplyToAllForEachConflict() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1563,8 +1564,8 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyToAllForEachConflictPickOriginal() throws Exception {
|
||||
@Test
|
||||
public void testApplyToAllForEachConflictPickOriginal() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
// 10018ce = 2
|
||||
@ -1665,16 +1666,16 @@ public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeMan
|
||||
address = resultProgram.getMinAddress();
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x100248c"), address);
|
||||
assertEquals(new SaveableColor(Color.WHITE), opm.get(address));
|
||||
assertEquals(new SaveableColor(Palette.WHITE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
assertEquals(new SaveableColor(Palette.BLACK), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
assertEquals(new SaveableColor(Palette.BLACK), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.GREEN), opm.get(address));
|
||||
assertEquals(new SaveableColor(Palette.GREEN), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -351,27 +351,27 @@ public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest
|
||||
assertEquals("01", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
FieldElement fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001104"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("05 06 07 08", btf.getText());
|
||||
assertEquals(12, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 3);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 6);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 9);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001108"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("09", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -393,39 +393,39 @@ public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest
|
||||
assertEquals("0102 0304", btf.getText());
|
||||
assertEquals(10, btf.getNumCols(0));
|
||||
FieldElement fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 2);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 5);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 7);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001104"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("0506 0708", btf.getText());
|
||||
assertEquals(10, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 2);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 5);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 7);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001108"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("090a 0b0c", btf.getText());
|
||||
assertEquals(10, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 2);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 5);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 7);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -445,7 +445,7 @@ public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest
|
||||
assertEquals("01 02 03 04", btf.getText());
|
||||
assertEquals(12, btf.getNumCols(0));
|
||||
FieldElement fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 3);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 6);
|
||||
@ -458,26 +458,26 @@ public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest
|
||||
assertEquals("05 06 07 08", btf.getText());
|
||||
assertEquals(12, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 3);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 6);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 9);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001108"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("09 0a 0b 0c", btf.getText());
|
||||
assertEquals(12, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 3);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 6);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 9);
|
||||
assertEquals(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.ALIGNMENT_BYTES_COLOR, fe.getColor(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -498,69 +498,69 @@ public class CodeBrowserOptionsTest extends AbstractGhidraHeadedIntegrationTest
|
||||
assertEquals("01", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
FieldElement fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001201"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("02", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001202"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("03", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001203"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("04", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001204"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("05 06 07 08", btf.getText());
|
||||
assertEquals(12, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 3);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 6);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
fe = btf.getFieldElement(0, 9);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001208"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("09", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x1001209"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("0a", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x100120a"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("0b", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
|
||||
cb.goToField(addr("0x100120b"), "Bytes", 0, 0);
|
||||
btf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("0c", btf.getText());
|
||||
assertEquals(3, btf.getNumCols(0));
|
||||
fe = btf.getFieldElement(0, 1);
|
||||
assertEquals(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
assertColorsEqual(BytesFieldFactory.DEFAULT_COLOR, fe.getColor(0));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -441,7 +441,7 @@ public class ColorizingPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
private void assertColorForAddress(Color color, Address address) {
|
||||
Color appliedColor = colorizingService.getBackgroundColor(address);
|
||||
assertEquals(color, appliedColor);
|
||||
assertColorsEqual(color, appliedColor);
|
||||
|
||||
assertMarkerColorAtAddress(address, color);
|
||||
}
|
||||
|
@ -42,13 +42,8 @@ import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.program.util.GroupPath;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import resources.ResourceManager;
|
||||
=======
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
>>>>>>> 0eb4b9d GP-1981 - Theming - Base Module
|
||||
|
||||
public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest {
|
||||
|
||||
@ -740,15 +735,9 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest {
|
||||
runSwing(() -> tree.removeFromView(finalNode.getTreePath()));
|
||||
|
||||
int row = getRowForPath(node.getTreePath());
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
Component comp = runSwing(() -> tree.getCellRenderer()
|
||||
.getTreeCellRendererComponent(tree, node, true, false, true, row, false));
|
||||
assertEquals(ResourceManager.loadImage(DnDTreeCellRenderer.CLOSED_FOLDER),
|
||||
=======
|
||||
Component comp = tree.getCellRenderer()
|
||||
.getTreeCellRendererComponent(tree, node, true, false, true, row, false);
|
||||
assertEquals(new GIcon(DnDTreeCellRenderer.CLOSED_FOLDER),
|
||||
>>>>>>> 0eb4b9d GP-1981 - Theming - Base Module
|
||||
((JLabel) comp).getIcon());
|
||||
}
|
||||
|
||||
@ -844,15 +833,10 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest {
|
||||
assertTrue(getView().hasSameAddresses(viewMgrService.getCurrentView()));
|
||||
|
||||
int row = getRowForPath(child.getTreePath());
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
Component comp = runSwing(() -> tree.getCellRenderer()
|
||||
.getTreeCellRendererComponent(tree, child, true, false, true, row, false));
|
||||
assertEquals(ResourceManager.loadImage(DnDTreeCellRenderer.VIEWED_FRAGMENT),
|
||||
=======
|
||||
Component comp = tree.getCellRenderer()
|
||||
.getTreeCellRendererComponent(tree, child, true, false, true, row, false);
|
||||
assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT),
|
||||
>>>>>>> 0eb4b9d GP-1981 - Theming - Base Module
|
||||
|
||||
((JLabel) comp).getIcon());
|
||||
}
|
||||
|
||||
|
@ -631,23 +631,14 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
JComponent comp = simpleOptionsPanel.getComponent();
|
||||
assertTrue(comp.isShowing());
|
||||
|
||||
Component component = findPairedComponent(comp, "Favorite Color");
|
||||
Component component = findPairedComponent(comp, "Favorite String");
|
||||
assertNotNull(component);
|
||||
Rectangle rect = component.getBounds();
|
||||
clickMouse(component, 1, rect.x, rect.y, 2, 0);
|
||||
|
||||
waitForSwing();
|
||||
|
||||
Window window = waitForWindow("Color Editor");
|
||||
assertNotNull(window);
|
||||
|
||||
JColorChooser chooser = findComponent(window, JColorChooser.class);
|
||||
assertNotNull(chooser);
|
||||
chooser.setColor(Palette.BLUE);
|
||||
|
||||
JButton okButton = findButtonByText(window, "OK");
|
||||
assertNotNull(okButton);
|
||||
pressButton(okButton);
|
||||
triggerText(component, "Bar");
|
||||
|
||||
waitForSwing();
|
||||
|
||||
@ -658,8 +649,8 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
Options options = tool.getOptions(ToolConstants.TOOL_OPTIONS);
|
||||
|
||||
Color c = options.getColor("Favorite Color", Palette.RED);
|
||||
|
||||
assertColorsEqual(Palette.BLUE, c);
|
||||
String currentValue = options.getString("Favorite String", null);
|
||||
assertEquals("Bar", currentValue);
|
||||
|
||||
assertTrue(tool.hasConfigChanged());
|
||||
}
|
||||
@ -718,10 +709,6 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
// Inner Classes
|
||||
//=================================================================================================
|
||||
|
||||
private void assertColorsEqual(Color c1, Color c2) {
|
||||
assertEquals(c1.getRGB(), c2.getRGB());
|
||||
}
|
||||
|
||||
private KeyStroke getKeyBinding(String actionName) throws Exception {
|
||||
OptionsEditor editor = seleNodeWithCustomEditor("Key Bindings");
|
||||
KeyBindingsPanel panel = (KeyBindingsPanel) getInstanceField("panel", editor);
|
||||
@ -1117,8 +1104,11 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
options.setInt(name, 300);
|
||||
|
||||
name = "Favorite Color";
|
||||
|
||||
options.registerOption(name, Palette.RED, null, "description");
|
||||
options.setColor(name, Palette.RED);
|
||||
|
||||
name = "Favorite String";
|
||||
options.registerOption(name, "Foo", null, "description");
|
||||
|
||||
// select the middle button
|
||||
name = "Mouse Buttons" + Options.DELIMITER + "Mouse Button To Activate";
|
||||
|
@ -17,6 +17,7 @@ package ghidra.framework.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
@ -28,8 +29,10 @@ import javax.swing.KeyStroke;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import docking.test.AbstractDockingTest;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.options.*;
|
||||
import ghidra.framework.options.OptionsTest.FRUIT;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
@ -37,11 +40,12 @@ import ghidra.program.database.ProgramDB;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class OptionsDBTest extends AbstractGenericTest {
|
||||
public class OptionsDBTest extends AbstractDockingTest {
|
||||
|
||||
private OptionsDB options;
|
||||
private ProgramBuilder builder;
|
||||
private int txID;
|
||||
private GColor testColor;
|
||||
|
||||
public enum fruit {
|
||||
Apple, Pear, Orange
|
||||
@ -57,6 +61,8 @@ public class OptionsDBTest extends AbstractGenericTest {
|
||||
ProgramDB program = builder.getProgram();
|
||||
txID = program.startTransaction("Test");
|
||||
options = new OptionsDB(program);
|
||||
Gui.setColor("color.test", Palette.MAGENTA);
|
||||
testColor = new GColor("color.test");
|
||||
}
|
||||
|
||||
private void saveAndRestoreOptions() {
|
||||
@ -280,16 +286,25 @@ public class OptionsDBTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testGetDefaultValue() {
|
||||
options.registerOption("Foo", Palette.RED, null, "description");
|
||||
options.setColor("Foo", Palette.BLUE);
|
||||
assertEquals(Palette.BLUE, options.getColor("Foo", null));
|
||||
assertEquals(Palette.RED, options.getDefaultValue("Foo"));
|
||||
options.registerOption("Foo", Color.RED, null, "description");
|
||||
options.setColor("Foo", Color.BLUE);
|
||||
assertColorsEqual(Color.BLUE, options.getColor("Foo", null));
|
||||
assertColorsEqual(Color.RED, (Color) options.getDefaultValue("Foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultValueWithThemeValues() {
|
||||
options.registerOption("Foo", testColor, null, "description");
|
||||
options.setColor("Foo", Color.BLUE);
|
||||
assertColorsEqual(Color.BLUE, options.getColor("Foo", null));
|
||||
// registered options using theme values, don't have defaults
|
||||
assertColorsEqual(Color.BLUE, (Color) options.getDefaultValue("Foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterPropertyEditor() {
|
||||
MyPropertyEditor editor = new MyPropertyEditor();
|
||||
options.registerOption("color", OptionType.COLOR_TYPE, Palette.RED, null, "description",
|
||||
options.registerOption("color", OptionType.COLOR_TYPE, testColor, null, "description",
|
||||
editor);
|
||||
assertEquals(editor, options.getRegisteredPropertyEditor("color"));
|
||||
|
||||
@ -304,11 +319,20 @@ public class OptionsDBTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testRestoreOptionValue() {
|
||||
options.registerOption("Foo", Palette.RED, null, "description");
|
||||
options.setColor("Foo", Palette.BLUE);
|
||||
assertEquals(Palette.BLUE, options.getColor("Foo", null));
|
||||
options.registerOption("Foo", 4, null, "description");
|
||||
options.setInt("Foo", 7);
|
||||
assertEquals(7, options.getInt("Foo", 0));
|
||||
options.restoreDefaultValue("Foo");
|
||||
assertEquals(Palette.RED, options.getColor("Foo", null));
|
||||
assertEquals(4, options.getInt("Foo", 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestoreThemeOptionValue() {
|
||||
options.registerOption("Foo", testColor, null, "description");
|
||||
options.setColor("Foo", Palette.BLUE);
|
||||
assertColorsEqual(Palette.BLUE, options.getColor("Foo", null));
|
||||
options.restoreDefaultValue("Foo");
|
||||
assertColorsEqual(Palette.MAGENTA, options.getColor("Foo", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -549,7 +573,19 @@ public class OptionsDBTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testSettingValueToNull() {
|
||||
options.registerOption("Bar", Palette.BLUE, null, "description");
|
||||
// this will cause the palette color LAVENDER to be null - make sure to not use it in other
|
||||
//tests
|
||||
options.registerOption("Bar", "HEY", null, "description");
|
||||
options.setString("Bar", "THERE");
|
||||
options.setString("Bar", null);
|
||||
assertEquals(null, options.getString("Bar", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingThemeValueToNull() {
|
||||
// this will cause the palette color LAVENDER to be null - make sure to not use it in other
|
||||
//tests
|
||||
options.registerOption("Bar", testColor, null, "description");
|
||||
options.setColor("Bar", Palette.RED);
|
||||
options.setColor("Bar", null);
|
||||
assertEquals(null, options.getColor("Bar", null));
|
||||
|
@ -17,6 +17,7 @@ package ghidra.framework.options;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@ -33,17 +34,17 @@ public class FileOptionsTest extends AbstractGenericTest {
|
||||
|
||||
options.registerOption("aaa", Integer.valueOf(5), null, "aaa description");
|
||||
options.registerOption("bbb", Integer.valueOf(5), null, "bbb description");
|
||||
options.registerOption("ccc", Palette.RED, null, "ccc description");
|
||||
options.registerOption("ccc", Color.RED, null, "ccc description");
|
||||
|
||||
TestCustomOption custom = new TestCustomOption("bob", 23, true);
|
||||
|
||||
options.setInt("aaa", 10);
|
||||
options.setColor("ccc", Palette.BLUE);
|
||||
options.setColor("ccc", Color.BLUE);
|
||||
options.setCustomOption("ddd", custom);
|
||||
|
||||
assertEquals(10, options.getInt("aaa", 0));
|
||||
assertEquals(5, options.getInt("bbb", 0));
|
||||
assertEquals(Palette.BLUE, options.getColor("ccc", null));
|
||||
assertEquals(Color.BLUE, options.getColor("ccc", null));
|
||||
assertEquals(custom, options.getCustomOption("ddd", null));
|
||||
|
||||
File file = createTempFile("optionsFile", "options");
|
||||
@ -54,7 +55,7 @@ public class FileOptionsTest extends AbstractGenericTest {
|
||||
|
||||
assertEquals(10, restored.getInt("aaa", 0));
|
||||
assertFalse(restored.contains("bbb")); // default value should not have been saved
|
||||
assertEquals(Palette.BLUE.getRGB(), restored.getColor("ccc", null).getRGB());
|
||||
assertEquals(Color.BLUE.getRGB(), restored.getColor("ccc", null).getRGB());
|
||||
assertEquals(custom, restored.getCustomOption("ddd", null));
|
||||
}
|
||||
|
||||
|
@ -281,16 +281,16 @@ public class OptionsTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testGetDefaultValue() {
|
||||
options.registerOption("Foo", Palette.RED, null, null);
|
||||
options.setColor("Foo", Palette.BLUE);
|
||||
assertColorsEqual(Palette.BLUE, options.getColor("Foo", null));
|
||||
assertColorsEqual(Palette.RED, (Color) options.getDefaultValue("Foo"));
|
||||
options.registerOption("Foo", Color.RED, null, null);
|
||||
options.setColor("Foo", Color.BLUE);
|
||||
assertColorsEqual(Color.BLUE, options.getColor("Foo", null));
|
||||
assertColorsEqual(Color.RED, (Color) options.getDefaultValue("Foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterPropertyEditor() {
|
||||
MyPropertyEditor editor = new MyPropertyEditor();
|
||||
options.registerOption("color", OptionType.COLOR_TYPE, Palette.RED, null, null, editor);
|
||||
options.registerOption("color", OptionType.COLOR_TYPE, Color.RED, null, null, editor);
|
||||
assertEquals(editor, options.getRegisteredPropertyEditor("color"));
|
||||
}
|
||||
|
||||
@ -304,12 +304,12 @@ public class OptionsTest extends AbstractGenericTest {
|
||||
@Test
|
||||
public void testRestoreOptionValue() {
|
||||
|
||||
options.registerOption("Foo", Palette.RED, null, null);
|
||||
options.setColor("Foo", Palette.BLUE);
|
||||
assertColorsEqual(Palette.BLUE, options.getColor("Foo", null));
|
||||
options.registerOption("Foo", Color.RED, null, null);
|
||||
options.setColor("Foo", Color.BLUE);
|
||||
assertColorsEqual(Color.BLUE, options.getColor("Foo", null));
|
||||
|
||||
options.restoreDefaultValue("Foo");
|
||||
assertColorsEqual(Palette.RED, options.getColor("Foo", null));
|
||||
assertColorsEqual(Color.RED, options.getColor("Foo", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -593,10 +593,6 @@ public class OptionsTest extends AbstractGenericTest {
|
||||
assertEquals(OptionType.NO_TYPE, options.getType("bar"));// there is no bar
|
||||
}
|
||||
|
||||
private void assertColorsEqual(Color c1, Color c2) {
|
||||
assertEquals(c1.getRGB(), c2.getRGB());
|
||||
}
|
||||
|
||||
private void saveAndRestoreOptions() {
|
||||
Element root = options.getXmlRoot(false);
|
||||
options = new ToolOptions(root);
|
||||
|
@ -18,10 +18,7 @@ font.byteviewer.status = SansSerif-PLAIN-11
|
||||
[Dark Defaults]
|
||||
|
||||
color.bg.byteviewer.highlight = rgb(191, 191, 64) // olive
|
||||
|
||||
color.fg.byteviewer.novalue = DarkBlue
|
||||
color.fg.byteviewer.changed = indianRed
|
||||
color.cursor.focused.byteviewer.current = color.cursor.focused
|
||||
color.cursor.focused.byteviewer.noncurrent = gray
|
||||
color.cursor.unfocused.byteviewer = color.cursor.unfocused
|
||||
color.fg.byteviewer.separator = darkBlue
|
||||
color.cursor.byteviewer.focused.not.active = gray
|
||||
|
||||
|
@ -74,7 +74,6 @@ public class ByteViewerPanel extends JPanel
|
||||
private ByteViewerComponent currentView;
|
||||
private Color editColor;
|
||||
private Color currentCursorColor;
|
||||
private Color cursorColor;
|
||||
private Color currentCursorLineColor;
|
||||
private Color highlightColor;
|
||||
private int highlightButton;
|
||||
@ -218,7 +217,6 @@ public class ByteViewerPanel extends JPanel
|
||||
}
|
||||
|
||||
void setCursorColor(Color c) {
|
||||
cursorColor = c;
|
||||
for (int i = 0; i < viewList.size(); i++) {
|
||||
ByteViewerComponent comp = viewList.get(i);
|
||||
comp.setNonFocusCursorColor(c);
|
||||
@ -418,7 +416,7 @@ public class ByteViewerPanel extends JPanel
|
||||
|
||||
ByteViewerComponent c = newByteViewerComponent(model);
|
||||
c.setEditColor(editColor);
|
||||
c.setNonFocusCursorColor(cursorColor);
|
||||
c.setNonFocusCursorColor(ByteViewerComponentProvider.CURSOR_NOT_FOCUSED_COLOR);
|
||||
c.setCurrentCursorColor(currentCursorColor);
|
||||
c.setCurrentCursorLineColor(currentCursorLineColor);
|
||||
c.setEditMode(editMode);
|
||||
|
@ -157,8 +157,6 @@ public class ByteViewerConnectedToolBehaviorTest extends AbstractGhidraHeadedInt
|
||||
});
|
||||
assertTrue(action.isSelected());
|
||||
final ByteViewerComponent c = panelOne.getCurrentComponent();
|
||||
assertEquals(ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR,
|
||||
c.getFocusedCursorColor());
|
||||
runSwing(() -> {
|
||||
KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
|
||||
c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(),
|
||||
@ -168,7 +166,7 @@ public class ByteViewerConnectedToolBehaviorTest extends AbstractGhidraHeadedInt
|
||||
|
||||
ByteViewerComponent c2 = panel2.getCurrentComponent();
|
||||
ByteField f2 = c2.getField(BigInteger.ZERO, 0);
|
||||
assertEquals(ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR, f2.getForeground());
|
||||
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, f2.getForeground());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -189,8 +187,6 @@ public class ByteViewerConnectedToolBehaviorTest extends AbstractGhidraHeadedInt
|
||||
});
|
||||
assertTrue(action.isSelected());
|
||||
final ByteViewerComponent c = panelOne.getCurrentComponent();
|
||||
assertEquals(ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR,
|
||||
c.getFocusedCursorColor());
|
||||
runSwing(() -> {
|
||||
KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
|
||||
c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(),
|
||||
@ -200,7 +196,7 @@ public class ByteViewerConnectedToolBehaviorTest extends AbstractGhidraHeadedInt
|
||||
|
||||
ByteViewerComponent c2 = panel2.getCurrentComponent();
|
||||
ByteField f2 = c2.getField(BigInteger.ZERO, 0);
|
||||
assertEquals(ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR, f2.getForeground());
|
||||
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, f2.getForeground());
|
||||
|
||||
undo(program);
|
||||
|
||||
|
@ -1219,7 +1219,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
putColor(opt, ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR_OPTION_NAME, Palette.GREEN);
|
||||
|
||||
ByteViewerComponent c = panel.getCurrentComponent();
|
||||
assertEquals(Palette.GREEN, c.getFocusedCursorColor());
|
||||
assertColorsEqual(Palette.GREEN, c.getFocusedCursorColor());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1236,11 +1236,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
Options opt = tool.getOptions("ByteViewer");
|
||||
// change the color for Current View Cursor Color
|
||||
putColor(opt, ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR_OPTION_NAME,
|
||||
putColor(opt, ByteViewerComponentProvider.CURSOR_NOT_FOCUSED_COLOR_OPTION_NAME,
|
||||
Palette.GREEN);
|
||||
|
||||
ByteViewerComponent c = findComponent(panel, "Octal");
|
||||
assertEquals(Palette.GREEN, c.getNonFocusCursorColor());
|
||||
assertColorsEqual(Palette.GREEN, c.getNonFocusCursorColor());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1260,7 +1260,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
Palette.CYAN);
|
||||
|
||||
ByteViewerComponent c = findComponent(panel, "Octal");
|
||||
assertEquals(Palette.CYAN, c.getNonFocusCursorColor());
|
||||
assertColorsEqual(Palette.CYAN, c.getNonFocusCursorColor());
|
||||
}
|
||||
|
||||
private void putFont(final Options options, final String optionName, final Font font) {
|
||||
@ -1305,7 +1305,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
program.flushEvents();
|
||||
ByteViewerComponent c = panel.getCurrentComponent();
|
||||
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
|
||||
assertEquals(Palette.GREEN, field.getForeground());
|
||||
assertColorsEqual(Palette.GREEN, field.getForeground());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1348,7 +1348,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
ByteViewerComponent c = panel.getCurrentComponent();
|
||||
FieldLocation loc = getFieldLocation(getAddr(0x0f001000));
|
||||
ByteField field = c.getField(loc.getIndex().subtract(BigInteger.ONE), 0);
|
||||
assertEquals(Palette.GREEN, field.getForeground());
|
||||
assertColorsEqual(Palette.GREEN, field.getForeground());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -436,7 +436,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
|
||||
intComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
|
||||
});
|
||||
// color should indicate the edit
|
||||
assertEquals(ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR,
|
||||
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
|
||||
((ByteField) intComp.getCurrentField()).getForeground());
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ color.fg.decompiler.constant = forestGreen
|
||||
color.fg.decompiler.type = mediumBlue
|
||||
color.fg.decompiler.parameter = darkMagenta
|
||||
color.fg.decompiler.global = darkCyan
|
||||
color.fg.decompiler.special = #cc0033
|
||||
|
||||
color.bg.decompiler.current.variable = rgba(255,255,0,0.5)
|
||||
color.fg.line.numbers = gray
|
||||
|
@ -330,11 +330,11 @@ public class DecompileOptions {
|
||||
private final static Color HIGHLIGHT_PARAMETER_COLOR = new GColor("color.fg.decompiler.parameter");
|
||||
|
||||
private final static String HIGHLIGHT_GLOBAL_MSG = "Display.Color for Globals";
|
||||
private Color globalColor;
|
||||
private final static String HIGHLIGHT_SPECIAL_MSG = "Display.Color for Special";
|
||||
private final static Color HIGHLIGHT_SPECIAL_DEF = Color.decode("0xCC0033");
|
||||
private Color specialColor;
|
||||
private final static Color HIGHLIGHT_GLOBAL_COLOR = new GColor("color.fg.decompiler.global");
|
||||
|
||||
private final static String HIGHLIGHT_SPECIAL_MSG = "Display.Color for Special";
|
||||
private final static Color HIGHLIGHT_SPECIAL_COLOR = new GColor("color.fg.decompiler.special");
|
||||
|
||||
private final static String HIGHLIGHT_DEFAULT_MSG = "Display.Color Default";
|
||||
private final static Color HIGHLIGHT_DEFAULT_COLOR = new GColor("color.fg.decompiler");
|
||||
|
||||
@ -399,21 +399,6 @@ public class DecompileOptions {
|
||||
commentHeadInclude = COMMENTHEAD_OPTIONDEFAULT;
|
||||
namespaceStrategy = NAMESPACE_OPTIONDEFAULT;
|
||||
integerFormat = INTEGERFORMAT_OPTIONDEFAULT;
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
keywordColor = HIGHLIGHT_KEYWORD_DEF;
|
||||
functionColor = HIGHLIGHT_FUNCTION_DEF;
|
||||
commentColor = HIGHLIGHT_COMMENT_DEF;
|
||||
variableColor = HIGHLIGHT_VARIABLE_DEF;
|
||||
constantColor = HIGHLIGHT_CONST_DEF;
|
||||
typeColor = HIGHLIGHT_TYPE_DEF;
|
||||
parameterColor = HIGHLIGHT_PARAMETER_DEF;
|
||||
globalColor = HIGHLIGHT_GLOBAL_DEF;
|
||||
specialColor = HIGHLIGHT_SPECIAL_DEF;
|
||||
defaultColor = HIGHLIGHT_DEFAULT_DEF;
|
||||
codeViewerBackgroundColor = CODE_VIEWER_BACKGROUND_COLOR;
|
||||
defaultFont = DEFAULT_FONT;
|
||||
=======
|
||||
>>>>>>> 47fa38a GP-1981 converting option colors to theme colors and font usages to theme properties
|
||||
displayLineNumbers = LINE_NUMBER_DEF;
|
||||
displayLanguage = ProgramCompilerSpec.DECOMPILER_OUTPUT_DEF;
|
||||
protoEvalModel = "default";
|
||||
@ -466,26 +451,7 @@ public class DecompileOptions {
|
||||
commentHeadInclude = opt.getBoolean(COMMENTHEAD_OPTIONSTRING, COMMENTHEAD_OPTIONDEFAULT);
|
||||
namespaceStrategy = opt.getEnum(NAMESPACE_OPTIONSTRING, NAMESPACE_OPTIONDEFAULT);
|
||||
integerFormat = opt.getEnum(INTEGERFORMAT_OPTIONSTRING, INTEGERFORMAT_OPTIONDEFAULT);
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
keywordColor = opt.getColor(HIGHLIGHT_KEYWORD_MSG, HIGHLIGHT_KEYWORD_DEF);
|
||||
typeColor = opt.getColor(HIGHLIGHT_TYPE_MSG, HIGHLIGHT_TYPE_DEF);
|
||||
functionColor = opt.getColor(HIGHLIGHT_FUNCTION_MSG, HIGHLIGHT_FUNCTION_DEF);
|
||||
commentColor = opt.getColor(HIGHLIGHT_COMMENT_MSG, HIGHLIGHT_COMMENT_DEF);
|
||||
variableColor = opt.getColor(HIGHLIGHT_VARIABLE_MSG, HIGHLIGHT_VARIABLE_DEF);
|
||||
constantColor = opt.getColor(HIGHLIGHT_CONST_MSG, HIGHLIGHT_CONST_DEF);
|
||||
parameterColor = opt.getColor(HIGHLIGHT_PARAMETER_MSG, HIGHLIGHT_PARAMETER_DEF);
|
||||
globalColor = opt.getColor(HIGHLIGHT_GLOBAL_MSG, HIGHLIGHT_GLOBAL_DEF);
|
||||
specialColor = opt.getColor(HIGHLIGHT_SPECIAL_MSG, HIGHLIGHT_SPECIAL_DEF);
|
||||
defaultColor = opt.getColor(HIGHLIGHT_DEFAULT_MSG, HIGHLIGHT_DEFAULT_DEF);
|
||||
codeViewerBackgroundColor =
|
||||
opt.getColor(CODE_VIEWER_BACKGROUND_COLOR_MSG, CODE_VIEWER_BACKGROUND_COLOR);
|
||||
currentVariableHighlightColor =
|
||||
opt.getColor(HIGHLIGHT_CURRENT_VARIABLE_MSG, HIGHLIGHT_CURRENT_VARIABLE_DEF);
|
||||
defaultFont = opt.getFont(FONT_MSG, DEFAULT_FONT);
|
||||
defaultFont = SystemUtilities.adjustForFontSizeOverride(defaultFont);
|
||||
defaultSearchHighlightColor = opt.getColor(SEARCH_HIGHLIGHT_MSG, SEARCH_HIGHLIGHT_DEF);
|
||||
=======
|
||||
>>>>>>> 47fa38a GP-1981 converting option colors to theme colors and font usages to theme properties
|
||||
|
||||
displayLineNumbers = opt.getBoolean(LINE_NUMBER_MSG, LINE_NUMBER_DEF);
|
||||
decompileTimeoutSeconds = opt.getInt(DECOMPILE_TIMEOUT, SUGGESTED_DECOMPILE_TIMEOUT_SECS);
|
||||
payloadLimitMBytes = opt.getInt(PAYLOAD_LIMIT, SUGGESTED_MAX_PAYLOAD_BYTES);
|
||||
@ -643,14 +609,10 @@ public class DecompileOptions {
|
||||
opt.registerOption(HIGHLIGHT_GLOBAL_MSG, HIGHLIGHT_GLOBAL_COLOR,
|
||||
new HelpLocation(HelpTopics.DECOMPILER, "DisplayTokenColor"),
|
||||
"Color used for highlighting global variables.");
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
opt.registerOption(HIGHLIGHT_SPECIAL_MSG, HIGHLIGHT_SPECIAL_DEF,
|
||||
opt.registerOption(HIGHLIGHT_SPECIAL_MSG, HIGHLIGHT_SPECIAL_COLOR,
|
||||
new HelpLocation(HelpTopics.DECOMPILER, "DisplayTokenColor"),
|
||||
"Color used for volatile or other exceptional variables.");
|
||||
opt.registerOption(HIGHLIGHT_DEFAULT_MSG, HIGHLIGHT_DEFAULT_DEF,
|
||||
=======
|
||||
opt.registerOption(HIGHLIGHT_DEFAULT_MSG, HIGHLIGHT_DEFAULT_COLOR,
|
||||
>>>>>>> 47fa38a GP-1981 converting option colors to theme colors and font usages to theme properties
|
||||
new HelpLocation(HelpTopics.DECOMPILER, "DisplayColorDefault"),
|
||||
"The color used when a specific color is not specified.");
|
||||
opt.registerOption(BACKGROUND_COLOR_MSG, BACKGROUND_COLOR,
|
||||
@ -874,7 +836,7 @@ public class DecompileOptions {
|
||||
* @return color associated with volatile variables or other special tokens
|
||||
*/
|
||||
public Color getSpecialColor() {
|
||||
return specialColor;
|
||||
return HIGHLIGHT_SPECIAL_COLOR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -971,7 +971,7 @@ public class DecompilerClangTest extends AbstractDecompilerTest {
|
||||
removeSecondaryHighlight();
|
||||
|
||||
Color hlColor2 = highlight();
|
||||
assertEquals(myColor, hlColor2);
|
||||
assertEquals(myColor.getRGB(), hlColor2.getRGB());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1981,7 +1981,7 @@ public class DecompilerClangTest extends AbstractDecompilerTest {
|
||||
|
||||
Color hlColor = getSecondaryHighlight(token);
|
||||
assertNotNull("No highlight for token: " + token, hlColor);
|
||||
assertEquals(color, hlColor);
|
||||
assertEquals(color.getRGB(), hlColor.getRGB());
|
||||
}
|
||||
|
||||
private void removeSecondaryHighlight() {
|
||||
@ -2279,7 +2279,17 @@ public class DecompilerClangTest extends AbstractDecompilerTest {
|
||||
|
||||
public boolean matches(Color otherColor) {
|
||||
for (Color c : myColors) {
|
||||
if (Objects.equals(c, otherColor)) {
|
||||
if (c == null) {
|
||||
if (otherColor == null) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (otherColor == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c.getRGB() == otherColor.getRGB()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2082,8 +2082,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
|
||||
|
||||
protected void verifyColor(FGVertex vertex, Color expectedColor) {
|
||||
Color currentBackgroundColor = vertex.getBackgroundColor();
|
||||
assertEquals("Color of vertex is not as expected - vertex: " + vertex, expectedColor,
|
||||
currentBackgroundColor);
|
||||
assertColorsEqual(expectedColor, currentBackgroundColor);
|
||||
}
|
||||
|
||||
protected void verifyDefaultColor(FGVertex... vertices) {
|
||||
|
@ -627,7 +627,7 @@ public class FunctionGraphPlugin1Test extends AbstractFunctionGraphTest {
|
||||
chooseColor(focusedVertex, testColor);
|
||||
|
||||
Color newVertexBackgroundColor = focusedVertex.getUserDefinedColor();
|
||||
assertEquals("Background color not set", testColor, newVertexBackgroundColor);
|
||||
assertColorsEqual(testColor, newVertexBackgroundColor);
|
||||
|
||||
DockingAction clearColorAction = getClearColorAction(focusedVertex);
|
||||
performAction(clearColorAction, graphProvider, true);
|
||||
|
@ -285,7 +285,7 @@ public class FunctionGraphPlugin2Test extends AbstractFunctionGraphTest {
|
||||
|
||||
// make sure the service is also cognizant of the color change
|
||||
appliedBackgroundColor = colorizingService.getBackgroundColor(vertex.getVertexAddress());
|
||||
assertEquals(testColor, appliedBackgroundColor);
|
||||
assertColorsEqual(testColor, appliedBackgroundColor);
|
||||
|
||||
Color vBg = vertex.getBackgroundColor();
|
||||
assertEquals(appliedBackgroundColor, vBg);
|
||||
@ -333,8 +333,8 @@ public class FunctionGraphPlugin2Test extends AbstractFunctionGraphTest {
|
||||
|
||||
Color newBackgroundColor =
|
||||
colorizingService.getBackgroundColor(focusedVertex.getVertexAddress());
|
||||
assertEquals("'Set Most Recent Color' action did not apply that color to the color service",
|
||||
mostRecentColor, newBackgroundColor);
|
||||
// "'Set Most Recent Color' action did not apply that color to the color service"
|
||||
assertColorsEqual(mostRecentColor, newBackgroundColor);
|
||||
}
|
||||
|
||||
// TODO: see SCR 9208 - we don't currently support this, although we could
|
||||
|
@ -12,7 +12,11 @@ data/ExtensionPoint.manifest||GHIDRA||||END|
|
||||
data/docking.palette.theme.properties||GHIDRA||||END|
|
||||
data/docking.theme.properties||GHIDRA||||END|
|
||||
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/Theming.htm||GHIDRA||||END|
|
||||
src/main/help/help/topics/Misc/Welcome_to_Help.htm||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/ThemingDeveloperDocs.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/ThemingInternals.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/ThemingOverview.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/ThemingUserDocs.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/images/ColorEditor.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/images/FontEditor.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/Theming/images/IconEditor.png||GHIDRA||||END|
|
||||
@ -22,8 +26,6 @@ src/main/java/docking/options/editor/package.html||GHIDRA||reviewed||END|
|
||||
src/main/java/docking/widgets/fieldpanel/package.html||GHIDRA||reviewed||END|
|
||||
src/main/java/docking/widgets/filechooser/package.html||GHIDRA||reviewed||END|
|
||||
src/main/java/docking/wizard/package.html||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/EmptyIcon.gif||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/EmptyIcon16.gif||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/Plus.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/StackFrameElement.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/StackFrame_Red.png||GHIDRA||reviewed||END|
|
||||
@ -32,18 +34,15 @@ src/main/resources/images/application-vnd.oasis.opendocument.spreadsheet-templat
|
||||
src/main/resources/images/application_xp.png||FAMFAMFAM Icons - CC 2.5|||fam fam|END|
|
||||
src/main/resources/images/arrow.gif||GHIDRA||||END|
|
||||
src/main/resources/images/bullet_delete.png||FAMFAMFAM Icons - CC 2.5||||END|
|
||||
src/main/resources/images/check.png||GHIDRA||||END|
|
||||
src/main/resources/images/checkmark_green.gif||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/close16.gif||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/closedFolder.png||Modified Nuvola Icons - LGPL 2.1||||END|
|
||||
src/main/resources/images/collapse.gif||GHIDRA||||END|
|
||||
src/main/resources/images/collapse_all.png||GHIDRA||||END|
|
||||
src/main/resources/images/computer.png||Tango Icons - Public Domain|||tango|END|
|
||||
src/main/resources/images/desktop.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/dialog-cancel.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/dialog-warning.png||Oxygen Icons - LGPL 3.0||||END|
|
||||
src/main/resources/images/disk.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/document-properties.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/down.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/drive.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/eatbits.gif||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/eatbits1.png||GHIDRA||reviewed||END|
|
||||
@ -54,8 +53,6 @@ src/main/resources/images/eatbits5.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/eatbits6.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/eatbits7.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/edit-clear.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/edit-cut.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/edit-cut22.png||Tango Icons - Public Domain|||original name edit-cut.png in tango 22x22|END|
|
||||
src/main/resources/images/edit-delete.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/edit-undo.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/expand.gif||GHIDRA||||END|
|
||||
@ -63,7 +60,6 @@ src/main/resources/images/filter_off.png||GHIDRA||||END|
|
||||
src/main/resources/images/filter_on.png||GHIDRA||||END|
|
||||
src/main/resources/images/folder-open.png||Tango Icons - Public Domain||||END|
|
||||
src/main/resources/images/folder_add.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/go-home.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/hourglass.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/hourglass24_01.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/hourglass24_02.png||GHIDRA||reviewed||END|
|
||||
@ -79,13 +75,8 @@ src/main/resources/images/hourglass24_11.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/image-missing.png||Oxygen Icons - LGPL 3.0||||END|
|
||||
src/main/resources/images/info_small.png||GHIDRA||||END|
|
||||
src/main/resources/images/info_small_hover.png||GHIDRA||||END|
|
||||
src/main/resources/images/information.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/inode-directory.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/left.alternate.png||GHIDRA||||END|
|
||||
src/main/resources/images/left.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/list-remove.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/locationIn.gif||GHIDRA||||END|
|
||||
src/main/resources/images/locationOut.gif||GHIDRA||||END|
|
||||
src/main/resources/images/magnifier.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/mail-folder-outbox.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/mail-receive.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
@ -102,24 +93,17 @@ src/main/resources/images/page_green.png||FAMFAMFAM Icons - CC 2.5||||END|
|
||||
src/main/resources/images/play.png||GHIDRA||||END|
|
||||
src/main/resources/images/preferences-system-windows.png||Tango Icons - Public Domain||||END|
|
||||
src/main/resources/images/redo.png||GHIDRA||||END|
|
||||
src/main/resources/images/reload.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/right.alternate.png||GHIDRA||||END|
|
||||
src/main/resources/images/right.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/software-update-available.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/sortascending.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/sortdescending.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/table.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/tag.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/text_lowercase.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/textfield_rename.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/tip.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/trash-empty.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/undo.png||GHIDRA||||END|
|
||||
src/main/resources/images/up.png||GHIDRA||reviewed||END|
|
||||
src/main/resources/images/user-home.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/view-filter.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/viewmagfit.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/warning.help.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/warning.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/weather-clear.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/weather-few-clouds-reverse.png||Tango Icons - Public Domain||||END|
|
||||
src/main/resources/images/weather-few-clouds.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
|
@ -91,56 +91,14 @@ color.bg.fieldpanel.selection.and.highlight = green
|
||||
// docking buttons
|
||||
color.fg.button = black
|
||||
|
||||
// Icons files
|
||||
icon.empty = EmptyIcon16.gif
|
||||
icon.empty.20 = EmptyIcon.gif
|
||||
icon.help = help-browser.png
|
||||
icon.home = go-home.png
|
||||
icon.add = Plus2.png
|
||||
icon.folder.new = folder_add.png
|
||||
icon.subtract = list-remove.png
|
||||
icon.clear = erase16.png
|
||||
icon.error = emblem-important.png
|
||||
icon.delete = icon.error
|
||||
icon.collapse.all = collapse_all.png
|
||||
icon.expand.all = expand_all.png
|
||||
icon.toggle.expand = expand.gif
|
||||
icon.toggle.collapse = collapse.gif
|
||||
icon.configure.filter = exec.png
|
||||
icon.navigate.in = locationIn.gif
|
||||
icon.navigate.out = locationOut.gif
|
||||
icon.not.allowed = dialog-cancel.png
|
||||
icon.folder.closed = closedSmallFolder.png
|
||||
icon.folder.open = openSmallFolder.png
|
||||
icon.folder.new = folder_add.png
|
||||
icon.refresh = reload3.png
|
||||
icon.sort.ascending = sortascending.png
|
||||
icon.sort.descending = sortdescending.png
|
||||
icon.stop = process-stop.png
|
||||
icon.information = information.png
|
||||
icon.warning = warning.png
|
||||
icon.warning.strong = software-update-urgent.png
|
||||
icon.left = left.png
|
||||
icon.right = right.png
|
||||
icon.left.alt = left.alternate.png
|
||||
icon.right.alt = right.alternate.png
|
||||
icon.save = disk.png
|
||||
icon.save.as = disk_save_as.png
|
||||
icon.make.selection = text_align_justify.png
|
||||
icon.arrow.down.right = viewmagfit.png[rotate(90)]
|
||||
icon.arrow.up.left = viewmagfit.png[rotate(275)]
|
||||
icon.flag = flag.png
|
||||
icon.lock = kgpg.png
|
||||
icon.checkmark.green = checkmark_green.gif
|
||||
icon.filter.not.accepted = icon.flag{dialog-cancel.png[size(10,10)][move(6,6)]}
|
||||
icon.blocked.match = icon.lock{icon.checkmark.green[size(12,12)][move(4,0)]}
|
||||
|
||||
icon.undo = undo.png
|
||||
icon.redo = redo.png
|
||||
icon.font = text_lowercase.png
|
||||
icon.up = up.png
|
||||
icon.down = down.png
|
||||
icon.copy = page_white_copy.png
|
||||
icon.cut = edit-cut.png
|
||||
icon.paste = page_paste.png
|
||||
icon.rename = textfield_rename.png
|
||||
icon.check = check.png
|
||||
icon.search = magnifier.png
|
||||
|
@ -49,8 +49,19 @@
|
||||
|
||||
|
||||
<tocroot>
|
||||
<tocdef id="Theming"
|
||||
text="Theming"
|
||||
target="help/topics/Theming/Theming.htm" >
|
||||
|
||||
<!--
|
||||
Note: we have omitted the target url for the root node. Rather than defining a help page
|
||||
for this node, we allow the system's default 'home id' to be used. (Any time a help item
|
||||
has no help defined, the 'home id' is displayed.) When the system's HelpManager loads
|
||||
GHelpSets, it will specify the 'home id' specific to that application.
|
||||
-->
|
||||
<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="Developer Documentation" sortgroup="3" text="Developer Documentation" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
|
||||
<tocdef id="Architecture Documentation" sortgroup="4" text="Architecture Documentation" target="help/topics/Theming/ThemingInternals.html"/>
|
||||
</tocdef>
|
||||
</tocdef>
|
||||
</tocroot>
|
||||
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE doctype PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to Help</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
|
||||
|
||||
<meta name="generator" content="Microsoft FrontPage 4.0">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center"><a name="Help_Contents"></a>Welcome to Help...</h1>
|
||||
|
||||
<div align="left">
|
||||
<p>We provide context sensitive help on menu items, dialogs, buttons,
|
||||
and tool windows. To access the help, press <F1> or <Help> on
|
||||
any menu item or dialog. If specific help is not available for an item,
|
||||
this page will be displayed.</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,441 @@
|
||||
<!DOCTYPE doctype>
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META name="generator" content=
|
||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
||||
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
|
||||
<TITLE>Theming Developer Documentation</TITLE>
|
||||
|
||||
<TITLE></TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
Theming Development Documentation
|
||||
|
||||
<H1>Ghidra Theming Developer Documentation</H1>
|
||||
|
||||
<P>This document provides everything an application developer should know when developing
|
||||
plugins, scripts, etc., that use colors, fonts, or icons. By following these guidelines,
|
||||
developers can easily make use of Ghidra's theming capabilities.</P>
|
||||
|
||||
<H2>Theme Resource Types</H2>
|
||||
|
||||
<P>When developing application code for Ghidra such as plugins, actions, etc., developers often
|
||||
want to use a color, font, or icon. The key idea to support theming is to never directly
|
||||
reference these resources. Instead, the developer should "create" an id string for the resource
|
||||
and then in a .theme.properties file provide a default value for that id (and if appropriate,
|
||||
also define an alternate default value if the theme is a "dark" theme). The way you
|
||||
define and use these ids is a bit different depending on whether the resource is a color, font,
|
||||
or icon. Colors and Icons are similar in that references are done using either GColor or GIcon,
|
||||
Unfortunately, because of the way Fonts are implemented, there is no GFont, so using fonts is a
|
||||
bit more involved.</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<H3>Colors</H3>
|
||||
|
||||
<P>For colors, developers should use the GColor class. Simply construct a new GColor object
|
||||
passing in the color resource id as the argument. GColor is a subclass of Color, so it can be
|
||||
used anywhere a Color would be used. The developer then needs to provide a default value for
|
||||
that id in the module's theme.properties file. So, for example:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">panel.setBackground(Color.Red);</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>becomes</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">panel.setBackground(new GColor("color.bg.abc"));</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>and</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">public static final Color MY_COLOR = Color.BLUE;</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>becomes</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">public static final Color MY_COLOR = new
|
||||
GColor("color.fg.xzy");</CODE>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>The GColor class uses a delegation model where all method calls to GColor get mapped to
|
||||
its delegate. If ever the color associated with a GColor's resource id changes, the GColor is
|
||||
refreshed by calling the refresh() method. This is done automatically whenever the
|
||||
Gui.setColor(id) is called or a new theme is loaded.</P>
|
||||
|
||||
<H3>Fonts</H3>
|
||||
|
||||
<P>Unfortunately, fonts able to use the delegation trick that was used for colors. Therefore,
|
||||
there is no GFont class. Programming fonts requires a bit more work. If the use of a font is
|
||||
in a renderer or in a paint method, imply get the font each time from the Gui class (Font
|
||||
font = Gui.getFont(String id)). To set a font on a component, use the "registerFont" method
|
||||
on the Gui class. Once the component is registered, the application will automatically update
|
||||
the component's font if the font associated with that id changes. So, for example:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">Font font = new Font("Monospaced", Font.BOLD, 12);</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>becomes</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">Font font = Gui.getFont("font.xyz");</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>or</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">myLabel.setFont(new Font("Dialog", Font.PLAIN, 14)</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>becomes</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">Gui.registerFont(myLabel, "font.xyz");</CODE>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>Icons</H3>
|
||||
|
||||
<P>Icons work just like colors, so you can just create a GIcon(String id). So, for
|
||||
example, </P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">public static final Icon MY_ICON =
|
||||
ResourceManager("images/balloon.png");</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>becomes</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE class="code">public static final Icon MY_ICON = new
|
||||
GIcon("icon.text.bubble");</CODE>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2>Resource Id Strings<A name="Resource_Ids"></A></H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>Resource Ids are strings used to identify the color, font, or icon. These strings are
|
||||
"made up" by the developer and should be chosen in a way that it is as self describing as
|
||||
possible. So, for example, if you wanted the text color in some error message in some widget
|
||||
"abc", you might create the color id "color.fg.abc.error". To make resource ids as consistent
|
||||
as possible, we created a convention for ids as follows: </P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
<CODE>
|
||||
[type].[category[...]].[client].[specialized uses]
|
||||
</CODE>
|
||||
</PRE>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<UL>
|
||||
<LI><B>type:</B> color, font, or icon.</LI>
|
||||
|
||||
<LI><B>category:</B> any value, examples include 'bg'(background), 'fg'(foreground),
|
||||
'cursor'. There may be multiple dot-separated values.</LI>
|
||||
|
||||
<LI><B>client:</B> the plugin name or feature name; any value usd to represent a more
|
||||
specialized use.</LI>
|
||||
|
||||
<LI><B>specialized uses:</B> any key value here that applies to the client, such as
|
||||
"vertex' for a graph client.</LI>
|
||||
</UL>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>Examples:</P>
|
||||
|
||||
<UL>
|
||||
<LI>color.bg</LI>
|
||||
|
||||
<LI>color.bg.listing</LI>
|
||||
|
||||
<LI>font.listing</LI>
|
||||
|
||||
<LI>font.listing.header</LI>
|
||||
|
||||
<LI>icon.error</LI>
|
||||
|
||||
<LI>icon.delete</LI>
|
||||
|
||||
<LI>icon.plugin.byteviewer.provider</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2>Theme Property Files</H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>The default values for resource ids are defined in "theme property" files that created in
|
||||
each module's data directory. For small modules there can be just one theme properties, but
|
||||
larger modules should probably use multiple files; one for each sub-feature. The application
|
||||
will find all theme property files as long as they exist in a module's data directory and end
|
||||
with '.theme.properties'.</P>
|
||||
|
||||
<H3>Theme Properties File Naming Convention</H3>
|
||||
|
||||
<P>To promote consistency, theme property files should use the following naming
|
||||
convention:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
<CODE>
|
||||
[module name][.additional name]].theme.properties
|
||||
</CODE>
|
||||
</PRE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Examples:</P>
|
||||
|
||||
<UL>
|
||||
<LI>base.theme.properties</LI>
|
||||
|
||||
<LI>base.funtiongraph.theme.properties</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>Theme Properties File Format</H3>
|
||||
|
||||
<P>Theme files uses a very simple format for specifying theme property values. Each line
|
||||
specifies a property id (sometimes referfed to as key) and a value, separated by an "=". A
|
||||
theme properties file consists of two sections: the standard defaults section and a section
|
||||
for specifying defaults for "dark" themes. So a file theme file uses the following
|
||||
format:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<CODE>
|
||||
<PRE>
|
||||
[Defaults]
|
||||
|
||||
[property id 1] = [some value]
|
||||
[property id 2] = [some value]
|
||||
[property id 3] = [some value]
|
||||
...
|
||||
|
||||
[Dark Defaults]
|
||||
|
||||
[property id 1] = [some value]
|
||||
[property id 2] = [some value]
|
||||
...
|
||||
</PRE>
|
||||
</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Example:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
[Defaults]
|
||||
|
||||
color.bg = white
|
||||
color.bg.listing = color.bg
|
||||
|
||||
color.fg.listing.address = black
|
||||
color.fg.listing.bytes = #00ff00
|
||||
|
||||
font.global = courirer-BOLD-12
|
||||
font.global.listing = font.global
|
||||
|
||||
icon.error = defaultError.png
|
||||
|
||||
|
||||
[Dark Defaults]
|
||||
|
||||
color.bg = black
|
||||
|
||||
color.fg.listing.address = gray
|
||||
color.fg.listing.bytes = orange
|
||||
</PRE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>NOTE: The [Dark Defaults] section is for overriding values defined in the standard
|
||||
[Defaults] section. If a property id is not given a value in the defaults section, it is an
|
||||
error. If a value is not defined in the [Dark Defaults] section, then the value defined in
|
||||
the [Defaults] section will be used in a dark theme.</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2>Theme Property Values<A name="Theme_Property_Values"></A></H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>The values specified in the theme properties files can be specified in a variety of ways,
|
||||
including ways to modify other property values. For example, an icon's size can be modified
|
||||
directly in the theme properties file. A font value can specified as a reference to another
|
||||
defined font, but with a different size or style.</P>
|
||||
|
||||
<P>Also, any value can also be a reference to some other id of the same type. So, for
|
||||
example, a reference color entry might be something like "color.bg.listing = color.bg". This
|
||||
says that the listing's background color should be whatever "color.bg" is defined to be. Note
|
||||
that all of the application's defined properties start with either "color.", "font.", or
|
||||
"icon.". Properties defined by a Java LookAndFeel don't follow this pattern. To reference a
|
||||
property that does not have a standard prefix, an id can be prefixed with "[color]",
|
||||
"[font]", or "[icon] as appropriate to allow the theme property parser to recognize the
|
||||
values as ids to other properties. So to refer to a property named "table.background, it
|
||||
would be "color.bg.table = [color]table.background".</P>
|
||||
|
||||
<H3>Color Values</H3>
|
||||
|
||||
<P>Color values supports the following formats:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<UL>
|
||||
<LI>#rrggbb</LI>
|
||||
|
||||
<LI>#rrggbbaa</LI>
|
||||
|
||||
<LI>0xrrggbb</LI>
|
||||
|
||||
<LI>0xrrggbbaa</LI>
|
||||
|
||||
<LI>rgb(red, green, blue)</LI>
|
||||
|
||||
<LI>rgba(red, green, blue, alpha)</LI>
|
||||
|
||||
<LI>[web color name] the name of a web color such as red, olive, or purple</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Examples:</P>
|
||||
<PRE>
|
||||
color.foo = #0000ff // blue
|
||||
color.foo = #ff000080 // red with half transparency
|
||||
color.foo = 0x00ff00 // green
|
||||
color.foo = 0xff000080 // red with half transparency
|
||||
color.foo = rgb(0, 0, 255) // blue
|
||||
color.foo = rgba(255,0, 0, 128) // red with half transparency
|
||||
color.foo = blue // web color defined as 0x0000FF
|
||||
color.foo = LawnGreen // web color defined as 0x7CFC00
|
||||
</PRE>
|
||||
|
||||
<H3>Font Values</H3>
|
||||
|
||||
<P>Font values are specified using the following format:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
<CODE>
|
||||
[family name]-[style]-[size]
|
||||
</CODE>
|
||||
</PRE>
|
||||
|
||||
<UL>
|
||||
<LI>family name: the font name such as monospaced, dialog, courier.</LI>
|
||||
|
||||
<LI>style: One of PLAIN, BOLD, ITALIC, or BOLDITALIC.</LI>
|
||||
|
||||
<LI>size: the font point size. 12 is very common.</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Examples:</P>
|
||||
<PRE>
|
||||
font.foo = monospaced-PLAIN-12
|
||||
font.foo = courier-BOLD-14
|
||||
font.foo = SansSerif-ITALIC=10
|
||||
</PRE>
|
||||
|
||||
<H4>Font Modifiers</H4>
|
||||
|
||||
<P>When referencing another font, the referenced font can be modified using the following
|
||||
format:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
<CODE>
|
||||
font.ref[family name][style][size]
|
||||
</CODE>
|
||||
</PRE>
|
||||
|
||||
<UL>
|
||||
<LI>font.ref - the theme property id of some other font</LI>
|
||||
|
||||
<LI>family name: use the size and style of the reference font, but use this font
|
||||
family</LI>
|
||||
|
||||
<LI>style: use the same font as the reference font, but with this style. One of PLAIN,
|
||||
BOLD, ITALIC, or BOLDITALIC</LI>
|
||||
|
||||
<LI>size: use the same font as the reference font, but with this size.</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Examples:</P>
|
||||
<PRE>
|
||||
font.foo = SansSerif-PLAIN-12 // standard font spec
|
||||
font.bar = font.foo[BOLD] // results in SansSerif-BOLD-12
|
||||
font.bar = font.foo[15] // results in SansSerif-PLAIN-15
|
||||
font.bar = font.foo[monospaced] // results in monospaced-PLAIN-12
|
||||
font.bar = font.foo[ITALIC][15] // results in SansSerif-ITALIC-15
|
||||
</PRE>
|
||||
|
||||
<H3>Icon Values</H3>
|
||||
|
||||
<P>Icon are specified by simply entering the name of an icon that is in the classpath.
|
||||
However, an icon value can get complicated because it can be modified in a number of ways,
|
||||
such as scaling, disabling, even overlaying other icons. The format is as follows:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
<CODE>
|
||||
iconName[size(width,height)][disabled]{iconOverlayName[size(width,geight)[disabled][move(x,y)]}{...}
|
||||
|
||||
</CODE>
|
||||
</PRE>
|
||||
|
||||
<UL>
|
||||
<LI>iconName - the name the base icon</LI>
|
||||
|
||||
<LI>size(width,height) - optional modifier to scale the image to the given size.</LI>
|
||||
|
||||
<LI>disabled - optional modifier to create a disabled version of the icon.</LI>
|
||||
|
||||
<LI>{...} - optional modifier to overlay an icon on the base icon. It is recursively
|
||||
defined using the same format.</LI>
|
||||
|
||||
<LI>move(x,y) - optional modifier on overlays to position them relative to the base
|
||||
icon.</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Examples:</P>
|
||||
<PRE>
|
||||
icon.foo = house.png // using the icon house.png found as an image resource on the classpath
|
||||
icon.foo = house.png[size(10,10)] // uses the house.png icon, but scales it to 10x10
|
||||
icon.foo = house.png[disabled] // creates a disabled version of house.png
|
||||
icon.foo = house.png[16,16]{hammer.png[size(4,4)][move(12,12)]}
|
||||
// creates a 16x16 version of the house icon with a 4x4 scaled
|
||||
// hammer.icon overlayed in its lower right corner
|
||||
</PRE>
|
||||
|
||||
<P>To create an icon suitable for dynamically overlaying other icons, there is special syntax
|
||||
for specifying an empty base icon, then overlay another icon in some specific area of the
|
||||
empty icon. This icon can then be used to overlay dynamically in the code. For example, to
|
||||
create an overlay icon that would add a flag to the bottom, right corner any other iconw:</P>
|
||||
<PRE>
|
||||
icon.foo = EMPTY_ICON[size(16,16)]{flag.png[size(6,6)][move(10,10)]}
|
||||
</PRE>
|
||||
|
||||
<P class="relatedtopic">Related Topics</P>
|
||||
|
||||
<UL>
|
||||
<LI><A href="ThemingOverview.html">Theming Overview</A></LI>
|
||||
|
||||
<LI><A href="ThemingUserDocs.html">Theming User Documentation</A></LI>
|
||||
|
||||
<LI><A href="ThemingInternals.html">Theming Architecture Documentation</A></LI>
|
||||
</UL><BR>
|
||||
</BLOCKQUOTE>
|
||||
</BODY>
|
||||
</HTML>
|
@ -0,0 +1,186 @@
|
||||
<!DOCTYPE doctype>
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META name="generator" content=
|
||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
||||
|
||||
<TITLE>Theming Internals Documentation</TITLE>
|
||||
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<H1>Ghidra Theming Internals Documentation</H1>
|
||||
|
||||
<P>This document describes the api for initializing and managing themes. A theme (the GTheme
|
||||
class) in Ghidra represents a specific LookAndFeel as well the set of values for the color,
|
||||
font, and icon resource ids used in the application. The Gui class provides a set of
|
||||
static methods that serves as the primary interface for managing all aspects of theming.</P>
|
||||
|
||||
<H2>GTheme class</H2>
|
||||
|
||||
<P>The GTheme class is the implementation of the theme concept. At any giving time, the
|
||||
application is using resource values as specified by an active theme. The theme specifies
|
||||
the LookAndFeel, whether or not the overall theme is "dark" (which determines which default
|
||||
values to use) and any resource values which have been overridden specifically by that theme.
|
||||
There are two types of of themes; "built-in" themes and file based themes. "Built-in"
|
||||
themes are implemented directly as sub-classes of GTheme and simply specify a Java LookAndFeel
|
||||
and whether or not the theme is "dark". There is one "built-in" theme for each supported
|
||||
LookAndFeel. File based themes read their values from a theme file. Theme files are created by
|
||||
editing and saving existing themes.</P>
|
||||
|
||||
<H2>GThemeValueMap / ThemeValue class</H2>
|
||||
|
||||
<P>These are the base classes for storing values for resource ids. A GThemeValueMap
|
||||
consists of three hashmaps; one each for colors, fonts, and icons. Each hashmap maps an id to a
|
||||
appropriate subclass of ThemeValue, which is the base class for ColorValue, FontValue, and
|
||||
IconValue. Resource values are stored in these ThemeValue sub-classes because the value can be
|
||||
either a concrete value or be a reference to some other resource of the same type. So, for
|
||||
example, "color.bg.foo" could map directly to an actual color or its value could be reference
|
||||
to some other indirect color like "color.bg.bar". In any ThemeValue object, either the
|
||||
referenceId or the direct value must be null. To get the ultimate concrete value, there
|
||||
is a convenience method called "get" on ThemeValues that takes a GThemeValueMap as an argument.
|
||||
This method will recursively resolve referenceIds which is why it needs a value map as an
|
||||
argument.</P>
|
||||
|
||||
<P>GThemeValueMaps have some convenience methods for doing set operations. You can load
|
||||
values from other GThemeValueMaps into this map, which adds to the current map, replacing
|
||||
values with the same id with values from the other map. Also, there is a method for getting the
|
||||
differences from one GThemeValueMap to another. </P>
|
||||
|
||||
<H2>Gui class</H2>
|
||||
|
||||
<P>The Gui class is a set of static methods that provides the primary API for managing themes.
|
||||
It has methods for switching themes, adding themes, deleting themes, saving themes, restoring
|
||||
themes, getting/setting values for resource ids, adding theme listeners, and others.</P>
|
||||
|
||||
<H2>Application Initialization</H2>
|
||||
|
||||
<P>Applications need to call Gui.initialize() before any uses of color, fonts, or icons occur.
|
||||
This will load all resource defaults from the theme.properties files, read the last used theme
|
||||
from preferences, and load that theme which includes setting the LookAndFeel.</P>
|
||||
|
||||
<H2>Loading a Theme</H2>
|
||||
|
||||
<P>Loading a theme consists of two main operations. Loading the LookAndFeel and building the
|
||||
set of values for the resource ids.</P>
|
||||
|
||||
<H2>Loading the LookAndFeel</H2>
|
||||
|
||||
<P>Because each LookAndFeel present different challenges to the theming feature, there is a
|
||||
LookAndFeelManager for each LookAndFeel. The LookAndFeelManager is responsible for installing
|
||||
the lookAndFeel (in the case of Nimbus, we had to install a special subclass of the
|
||||
NimbusLookAndFeel), extracting the Java resources mappings(Java LookAndFeel objects also
|
||||
use a resource id concept), group the java resources into common groups, possibly fix up
|
||||
some issues specific to that LookAndFeel, possibly install global properties, and have specific
|
||||
update (kicking) techniques to get that LookAndFeel to update its componentUIs when values
|
||||
change.</P>
|
||||
|
||||
<H2>Creating the Active Theme Values</H2>
|
||||
|
||||
<P>After the LookAndFeel is loaded and the java values extracted, the final resource mapping is
|
||||
created. This is done by loading various resource values sets(each stored in a GThemeValueMap)
|
||||
in the correct order into a new GThemeValueMap in GUI called "currentValues" . When
|
||||
values are loaded into a GThemeValueMap, they will replace any existing values with the same
|
||||
id. The values are loaded in the following order:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<UL>
|
||||
<LI>java defaults (values from LookAndFeel)</LI>
|
||||
|
||||
<LI>application defaults (from theme.properties files)</LI>
|
||||
|
||||
<LI>applications dark defaults (if theme is dark)</LI>
|
||||
|
||||
<LI>theme values (values that were overridden by a specific theme)</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2>Changing Values Associated With Resource Ids</H2>
|
||||
|
||||
<P>Whenever the value associated with a resource id changes, the application gets "kicked" in
|
||||
various ways to update the display with the new value. The technique used to "kick" the
|
||||
application differs depending on the resource type and the LookAndFeel (these differences are
|
||||
captured in the LookAndFeelManager sub-classes for each LookAndFeel). It can also vary
|
||||
depending on whether the value is an application defined resource or a java defined
|
||||
resource.</P>
|
||||
|
||||
<H3>Updating Colors</H3>
|
||||
|
||||
<P>Updating Colors is the easiest of all the resource. First GColor.refreshAll() is called,
|
||||
which causes every GColor to refresh its delegate. Next, repaint() is called on all the top
|
||||
level java windows in the application. Also, since color values in the UIDefaults are actually
|
||||
replaced with GColor objects, this technique works for both application defined resources and
|
||||
java defined resources.</P>
|
||||
|
||||
<H3>Updating Fonts</H3>
|
||||
|
||||
<P>Updating Fonts is a bit more involved. First, if the changed font is java defined, the
|
||||
UIDefaults for that font Id (and any that derive from it) are updated. Next, all the components
|
||||
that have a registeredFontId are updated, and finally the updateComponentTreeUI method is
|
||||
called on all windows in the application.</P>
|
||||
|
||||
<H3>Updating Icons</H3>
|
||||
|
||||
<P>Updating Icons is a mixed bag. If the Icon is application defined, GIcon.refreshAll() is
|
||||
called which causes every GIcon to refresh its delegate and then call repaint on all the
|
||||
windows. If the icon is java defined, then the UIDefaults has to be updated and the
|
||||
updateComponentTreeUI method on all windows is called.</P>
|
||||
|
||||
<H2>Creating/Editing/Saving Themes</H2>
|
||||
|
||||
<P>New themes can be created and saved to files in the theme directory in the users ghidra
|
||||
application directory. When the application is started, this directory is scanned and any
|
||||
.theme files are loaded and available to be selected as the active theme. The Gui class has
|
||||
methods for setting the value of a color, font, or icon for a given resource id. If any values
|
||||
are currently different from the active theme, the theme can be saved. If the active theme is a
|
||||
built-in theme, then the only choice is to save the theme with a new theme name. Saving the
|
||||
theme will create a new xxx.theme file where xxx is the name of the theme. Otherwise, the
|
||||
existing theme file can be overwritten or a new theme name can be supplied to save to a new
|
||||
file.</P>
|
||||
|
||||
<H2>External Icons</H2>
|
||||
|
||||
<P>When settings icons for an icon resource id, the user has the option of using a icon that
|
||||
exists on the application classpath or using any supported icon file (.png or .gif) If the user
|
||||
chooses to use an icon file, then that icon will be copied into an images directory in their
|
||||
application directory (.ghidra). These icons are considered external in that if the theme were
|
||||
given to another user, you would also need to give them the icon files.</P>
|
||||
|
||||
<H2>Importing/Exporting Themes</H2>
|
||||
|
||||
<P>Themes can be shared with other users by exporting and importing themes. When exporting a
|
||||
theme that doesn't use any external icons (icons not on the classpath), the theme can be
|
||||
exported to a .theme file of the users choosing. If the theme does contain external icons, the
|
||||
user has the option to save the theme as a .zip file which would contain both the .theme file
|
||||
and all the external icon files.</P>
|
||||
|
||||
<H2>LookAndFeel Notes</H2>
|
||||
|
||||
<P>Getting the theming feature to work on all the various Java LookAndFeels is a
|
||||
challenge. Java created the concept of UiDefaults, which is a mapping of property names
|
||||
to values. The implication is that users can change default values by setting values on the
|
||||
UIDefaults. Unfortunately, not all LookAndFeels support this concept. Nimbus and GTK+, in
|
||||
particular are problematic. Nimbus sort of honors values in UIDefaults, but only if they are
|
||||
installed before Nimbus is loaded. So for out theming purposes, we had to extend the Nimbus
|
||||
LookAndFeel in order to override the getDefaults() method (this is the method where
|
||||
LookAndFeels populate the UiDefaults) so that we can install any overridden values from the
|
||||
selected theme. Also, every time a Java defined property changes, we have to re-install the
|
||||
Nimbus LookAndFeel because once it is installed, it no longer pays attention to changes to the
|
||||
UIDefaults. The GTK+ LookAndFeel is even more problematic. It gets many of its properties
|
||||
from native libraries and there doesn't appear to be anyway of changing them. Therefore, themes
|
||||
based on GTK+ doesn't allow for changing java defined values. To compensate for the
|
||||
differences among LookAndFeels, we created a LookAndFeelManager base class with sub-classes for
|
||||
each LookAndFeel that addresses these differences.</P>
|
||||
|
||||
<P class="relatedtopic">Related Topics</P>
|
||||
|
||||
<UL>
|
||||
<LI><A href="ThemingOverview.html">Theming Overview</A></LI>
|
||||
|
||||
<LI><A href="ThemingUserDocs.html">Theming User Documentation</A></LI>
|
||||
|
||||
<LI><A href="ThemingDeveloperDocs.html">Theming Developer Documentation</A></LI>
|
||||
</UL><BR>
|
||||
</BODY>
|
||||
</HTML>
|
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE doctype>
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META name="generator" content=
|
||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
||||
|
||||
<TITLE>Theming Overivew</TITLE>
|
||||
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<H1>Ghidra Theming Overview</H1>
|
||||
|
||||
<H2>Goal</H2>
|
||||
|
||||
<P>The goal was to add a theming infrastructure/feature to Ghidra that would allow
|
||||
users/developers to completely configure the colors, fonts, and icons used within Ghidra. There
|
||||
are two main reasons for creating this feature. The first reason is to create the much
|
||||
requested "Dark Theme". Many people find Ghidra's current color scheme to be hard on the eyes
|
||||
and would greatly appreciate a color scheme that is not so bright. The second reason is
|
||||
for accessibility purposes. For example, the themeing feature would allow for the creating of a
|
||||
high contrast color scheme, or a color scheme that helps mitigate color blindness or a theme
|
||||
that uses larger fonts.</P>
|
||||
|
||||
|
||||
<H2>Background</H2>
|
||||
|
||||
<P>Ghidra previously used hundreds of hard coded colors, fonts, and icons. They are
|
||||
defined throughout the code in a somewhat haphazard fashion. Many features use colors to convey
|
||||
similar concepts, but no effort was even made to use similar colors for those similar concepts.
|
||||
Also, these colors were generally chosen to work with one of the common "light" java look and
|
||||
feels. They often look terrible when used in conjunction with other LookAndFeels, especially
|
||||
dark ones.</P>
|
||||
|
||||
<P>Ghidra does allow some customization of the current colors using "options", but this falls
|
||||
short for several reasons. One problem is that not all colors or fonts are changeable via the
|
||||
options. Another problem is that the options are tool based and you have to make the same
|
||||
customization for each tool. A third problem is that options are unrelated to the LookAndFeel
|
||||
option. In other words you can't have different option choices depending on the current
|
||||
LookAndFeel.</P>
|
||||
|
||||
<P>Also, all of Ghidra's icons are hard coded and many are not suitable to use in a dark theme.
|
||||
Overall, the hard coding of colors, fonts, and icons and the limitation of options makes
|
||||
creating a good dark theme virtually impossible. So to address these issues, a new theming
|
||||
infrastructure was created.</P>
|
||||
|
||||
<H2>General Concepts and Approach</H2>
|
||||
|
||||
<P>To achieve a theming capability in Ghidra, we had to implement the following concepts.
|
||||
First, provide a level of indirection when using colors, fonts, or icons in code. Second,
|
||||
introduce the concept of a theme which maps the indirect colors. font, and icons to actual
|
||||
values in the context of a java LookAndFeel. Third, provide access to (and the ability to
|
||||
change), the colors, fonts, and icons supplied by the Java LookAndFeel. And finally, provide
|
||||
the GUIs needed to allow users to switch between, create, edit, save, import, and export
|
||||
themes.</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<H3>Indirection</H3>
|
||||
|
||||
<P>The basic idea for indirection is to never directly use a hard coded color, font, or icon
|
||||
when developing a feature in the application. Instead, these properties will be indirectly
|
||||
referred to by an identifying string such as "color.bg.mywidget", where the string will
|
||||
follow a known convention that helps indicate its use. Default values for these identifying
|
||||
strings will be specified in data files that exist in the module where the code that defined
|
||||
id is located. Also, the values associated with these ids can be either a concrete value such
|
||||
as an actual color, font, or icon, or the value can be just an identifying string to
|
||||
different property. This allows users to change individual values or entire groups of values
|
||||
with one change.</P>
|
||||
|
||||
<H3>Theme</H3>
|
||||
|
||||
<P>A theme is simply the object that specifies all the values for colors, fonts, and icons
|
||||
used in the application as well as the LookAndFeel. The idea is that there will be a set of
|
||||
themes to choose from and by simply switching the theme, the LookAndFeel and all the colors,
|
||||
fonts, and icons can be switched out at one time. The set of themes to choose from are a mix
|
||||
of built-in themes and saved custom themes. There is one built-in theme for each supported
|
||||
LookAndFeel, which will use the values from the LookAndFeel as well as all the default values
|
||||
for the defined property ids. Users will be able to create custom themes where they can
|
||||
basically change any defined color, font, or icon, including those supplied by the associated
|
||||
LookAndFeel for that theme.</P>
|
||||
|
||||
<H3>Look and Feel Values</H3>
|
||||
|
||||
<P>The Java LookAndFeel is specified by the active theme. The Java LookAndFeel objects also
|
||||
define colors, fonts, and icons indirectly using identifying strings such as "Button.font"
|
||||
and "Menu.background". These values determine the default values used by all GUI elements
|
||||
unless overridden by developers in code when they create the components. Uses have the
|
||||
ability to change these values in the same way as values defined by Ghidra code. This will
|
||||
allow users to generate themes that completely change the look of the GUI with out the
|
||||
developers having to explicitly set a color, font and icon on every component as they get
|
||||
created in code. Another concept used by Java LookAndFeels is that many of the
|
||||
individual components share the same colors and those shared colors are defined using a group
|
||||
key such as "control", "text", or "menu". The idea is that by changing a group color, all
|
||||
components that share that group color are changed together. Or an individual components
|
||||
color can be changed by changing its specific key such as "Menu.background".</P>
|
||||
|
||||
<H3>User Interaction</H3>
|
||||
|
||||
<P>Users will be able create, edit, delete, import, export, and of course switch the
|
||||
application's active theme. The GUI theme editor allows users to do all of these actions.
|
||||
Using the active theme as a starting point, users will be able to change any color, font, or
|
||||
icon defined either by the LookAndFeel or the application. One or more of these changes can
|
||||
be saved as a new theme and stored in a file in their application directory. Themes can be
|
||||
shared with other users by exporting and import themes.</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P class="relatedtopic">Related Topics</P>
|
||||
|
||||
<UL>
|
||||
<LI><A href="ThemingUserDocs.html">Theming User Documentation</A></LI>
|
||||
|
||||
<LI><A href="ThemingDeveloperDocs.html">Theming Developer Documentation</A></LI>
|
||||
|
||||
<LI><A href="ThemingInternals.html">Theming Architecture Documentation</A></LI>
|
||||
</UL><BR>
|
||||
</BODY>
|
||||
</HTML>
|
@ -5,14 +5,14 @@
|
||||
<META name="generator" content=
|
||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
||||
|
||||
<TITLE>Theming</TITLE>
|
||||
<TITLE>Theming User Documentation</TITLE>
|
||||
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<H1 align="center">Theming</H1>
|
||||
<H1 align="center">Theming User Help</H1>
|
||||
|
||||
<H2>Overview</H2>
|
||||
<H2>Description</H2>
|
||||
|
||||
<P>The Theming feature allows users to customize the colors, fonts, and icons used throughout
|
||||
the application. The active theme determines the Java LookAndFeel, whether the theme should use
|
||||
@ -21,7 +21,7 @@
|
||||
their home application directory</P>
|
||||
|
||||
<P>Users can also edit and create their own themes using the Theme Editor. Custom themes are
|
||||
stored in the users <application dir>/themes. These are simple text files that can also
|
||||
stored in the users <application dir>/themes. These are simple text files that can
|
||||
easily be modified using any text editor. Also, users can share themes by exporting them to a
|
||||
file that can be given to other users who can them import them into their own system.</P>
|
||||
|
||||
@ -171,52 +171,39 @@
|
||||
<H2>Theme Property Names</H2>
|
||||
|
||||
<P>Theme Property Names (also referred to as ids or keys) that are defined by Ghidra use a
|
||||
common format to help make sorting and viewing properties more intuitive as to their use.</P>
|
||||
|
||||
<P>The general format is:</P>
|
||||
common format to help make sorting and viewing properties more intuitive as to their use. See
|
||||
the <A href="ThemingDeveloperDocs.html#Resource_Ids">Developer Documentation</A> for more details on the property id
|
||||
format and naming conventions.</P>
|
||||
|
||||
<H2>Theme Files</H2>
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
[type].[category[...]].[client].[specialized uses]
|
||||
|
||||
<UL>
|
||||
<LI><B>type:</B> color, font, or icon</LI>
|
||||
<P>Theme Files are used to store saved custom themes. They are simple text files and are
|
||||
stored in the user's home application directory. The first three properties are always the
|
||||
theme name, the look and feel name, and whether the theme uses standard defaults or dark
|
||||
defaults. Then there is just a list of overridden property "name = value" lines.So the format
|
||||
is:</P>
|
||||
<CODE>
|
||||
<PRE>
|
||||
name = [theme name]
|
||||
lookAndFeel = [lookAndFeel name]
|
||||
useDarkDefaults = [true or false]
|
||||
|
||||
[theme id 1]= [color, icon, or font value]
|
||||
[theme id 2]= [color, icon, or font value]
|
||||
[theme id 3]= [color, icon, or font value]
|
||||
[theme id 4]= [color, icon, or font value]
|
||||
...
|
||||
</PRE>
|
||||
</CODE>
|
||||
|
||||
<LI><B>category:</B> any value, examples include "bg" (background), "fg" (foreground);
|
||||
this may be multiple separated values</LI>
|
||||
|
||||
<LI><B>client:</B> the plugin name or feature name; any value used to represent a more
|
||||
specialized use</LI>
|
||||
|
||||
<LI><B>specialized uses:</B> any key value here that applies to the client, such as
|
||||
"vertex" for a vertex background</LI>
|
||||
</UL>Examples:
|
||||
|
||||
<UL>
|
||||
<LI>color.bg</LI>
|
||||
|
||||
<LI>color.bg.listing</LI>
|
||||
|
||||
<LI>font.button</LI>
|
||||
|
||||
<LI>icon.refresh</LI>
|
||||
|
||||
<LI>icon.refresh.disabled</LI>
|
||||
</UL>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2>Theme File Format</H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>Saved theme files have the following format:</P>
|
||||
<PRE>
|
||||
<CODE class="code">
|
||||
|
||||
name = ThemeName
|
||||
<BLOCKQUOTE>
|
||||
<P>Example:</P>
|
||||
<PRE>
|
||||
name = BigFontTheme
|
||||
lookAndFeel = Nimbus
|
||||
useDarkDefaults = false
|
||||
|
||||
|
||||
color.bg = Black
|
||||
color.bg.foo = #012345
|
||||
[color]Panel.background = Red
|
||||
@ -224,13 +211,8 @@
|
||||
icon.refresh = images/reload3.png
|
||||
color.bg.bar = color.bg.foo
|
||||
color.bg.xxx = [color]Panel.background
|
||||
</CODE>
|
||||
|
||||
</PRE>
|
||||
</PRE>
|
||||
|
||||
<P>The first three properties are always the theme name, the look and feel name, and whether
|
||||
the theme uses standard defaults or dark defaults. Then there is just a list of overridden
|
||||
property "name = value" lines.</P>
|
||||
|
||||
<P>Each property line is expected to begin with either "color.", "font.", or "icon." Since
|
||||
java defined properties don't start with these prefixes, they will have "[color]", "[font]",
|
||||
@ -242,61 +224,17 @@
|
||||
right side of the assignment is a property name and not a value, then it must also use the
|
||||
bracketed prefix if the property name doesn't start with "color.", "font.", or "icon."</P>
|
||||
|
||||
<H3>Specifying Color Values</H3>
|
||||
<H3>Specifying Theme Property Values</H3>
|
||||
<P>Specifying property values varies depending on whether it is a color, font, or icon. Fonts
|
||||
and icons also support specifying modifiers. For a complete description of how to specify
|
||||
these values, see the <A href="ThemingDeveloperDocs.html#Theme_Property_Values">Developer Documentation</A>.
|
||||
|
||||
<P>To specify the value for a color, there are 3 acceptable formats:</P>
|
||||
|
||||
<UL>
|
||||
<LI><B>Web Color Name</B> - Examples: Blue, Red, Black, etc.</LI>
|
||||
|
||||
<LI><B>Hex value</B> - #rrggbb, Example: #ff01a4, where ff is the red value, 01 is the
|
||||
green value, and a4 is the blue value</LI>
|
||||
|
||||
<LI><B>Hex with alpha value</B> -Example: #ff01a480, where ff is the red value, 01 is the
|
||||
green value, and a4 is the blue value, and 80 is the alpha value</LI>
|
||||
|
||||
<LI><B>RGB values</B> - Example: rgb(12, 34, 56) where red is 12(decimal), green is 34, and
|
||||
blue is 56</LI>
|
||||
|
||||
<LI><B>RGBA values</B> - Eample: rgba(12, 34, 56, 127) where red is 12(decimal), green is
|
||||
34, blue is 56, and alpha is 127</LI>
|
||||
</UL>
|
||||
|
||||
<H3>Specifying Font Values</H3>
|
||||
|
||||
<P>Font values are specified as follows:</P>
|
||||
<PRE>
|
||||
familyName-style-size
|
||||
|
||||
</PRE>
|
||||
|
||||
<UL>
|
||||
<LI><B>familyName:</B> the font family name such as "monospace", "dialog", "courier"</LI>
|
||||
|
||||
<LI><B>style:</B>either PLAIN, BOLD, ITALIC, or BOLDITALIC</LI>
|
||||
|
||||
<LI><B>size:</B> the font size such as 12, 14, 22</LI>
|
||||
</UL>
|
||||
|
||||
<P>Examples: monospace-PLAIN-12 or courier-BOLD-15</P>
|
||||
|
||||
<H3>Specifying Icon Values</H3>
|
||||
|
||||
<P>Icon values are specified by a relative path to the icon file. There are two types of
|
||||
icons; those that are included with Ghidra and those that were selected from the filesystem
|
||||
and imported into the theme. Icons that have been imported into the theme are stored in an
|
||||
images directory in the users Ghidra application directory. Icons included with Ghidra are
|
||||
relative to an images data directory in some module. So for example,</P>
|
||||
<PRE>
|
||||
icon.refresh = images/view-refresh.png
|
||||
icon.push = [EXTERNAL]images/energy.png
|
||||
|
||||
</PRE>
|
||||
|
||||
<P>The first example is a standard icon included with Ghidra. It exists in a module's data
|
||||
directory in the images folder. The second example is for an icon that is not included with
|
||||
Ghidra. The "[EXTERNAL]" prefix indicates that this icon is being stored in the user's
|
||||
application directory in the images folder.</P>
|
||||
</BLOCKQUOTE>
|
||||
<P class="relatedtopic">Related Topics</P>
|
||||
<UL>
|
||||
<LI><A href="ThemingOverview.html">Theming Overview</A></LI>
|
||||
<LI><A href="ThemingDeveloperDocs.html">Theming Developer Documentation</A></LI>
|
||||
<LI><A href="ThemingInternals.html">Theming Architecture Documentation</A></LI>
|
||||
</UL><BR>
|
||||
</BODY>
|
||||
</HTML>
|
@ -72,11 +72,7 @@ public class DockingApplicationLayout extends ApplicationLayout {
|
||||
* properties.
|
||||
*
|
||||
* @param applicationRootDirs list of application root directories which should be
|
||||
<<<<<<< Upstream, based on origin/master
|
||||
* used to identify modules and resources. The first entry will be treated as the
|
||||
=======
|
||||
* used to identify modules and resources. The first entry will be treated as the
|
||||
>>>>>>> 4485b75 GP-1981 - Support Tool - initial support tool fixes; updates to module discovery to use the classpath in dev mode for filtering
|
||||
* installation root.
|
||||
* @param applicationProperties The properties object that will be read system properties.
|
||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
||||
|
@ -51,6 +51,12 @@ import utilities.util.reflection.ReflectionUtilities;
|
||||
*/
|
||||
public class HelpManager implements HelpService {
|
||||
|
||||
/**
|
||||
* The hardcoded value to use for all HelpSet 'home id' values. Subclasses may change this
|
||||
* value by overriding {@link #getHomeId()}.
|
||||
*/
|
||||
private static final String HOME_ID = "Misc_Help_Contents";
|
||||
|
||||
public static final String SHOW_AID_KEY = "SHOW.HELP.NAVIGATION.AID";
|
||||
private static final String TABLE_OF_CONTENTS_FILENAME_KEY = "data";
|
||||
|
||||
@ -84,6 +90,7 @@ public class HelpManager implements HelpService {
|
||||
*/
|
||||
protected HelpManager(URL url) throws HelpSetException {
|
||||
mainHS = new DockingHelpSet(new GHelpClassLoader(null), url);
|
||||
mainHS.setHomeID(getHomeId());
|
||||
mainHB = mainHS.createHelpBroker();
|
||||
mainHS.setTitle(GHIDRA_HELP_TITLE);
|
||||
|
||||
@ -121,6 +128,15 @@ public class HelpManager implements HelpService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 'home id' to be used by all help sets in the system (as opposed to allowing each
|
||||
* help set to define its own home id.
|
||||
* @return the home id
|
||||
*/
|
||||
protected String getHomeId() {
|
||||
return HOME_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void excludeFromHelp(Object helpObject) {
|
||||
excludedFromHelp.add(helpObject);
|
||||
@ -695,6 +711,7 @@ public class HelpManager implements HelpService {
|
||||
private HelpSet createHelpSet(URL url, GHelpClassLoader classLoader) throws HelpSetException {
|
||||
if (!urlToHelpSets.containsKey(url)) {
|
||||
GHelpSet hs = new GHelpSet(classLoader, url);
|
||||
hs.setHomeID(getHomeId());
|
||||
urlToHelpSets.put(url, hs);
|
||||
return hs;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
|
||||
}
|
||||
|
||||
private ImageIcon getImageIcon(String name) {
|
||||
ImageIcon image = ResourceManager.loadImage(name);
|
||||
ImageIcon image = ResourceManager.findIcon(name);
|
||||
if (image instanceof UnresolvedIcon) {
|
||||
return null;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 305 B |
Before Width: | Height: | Size: 848 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 709 B After Width: | Height: | Size: 709 B |
@ -15,10 +15,6 @@
|
||||
*/
|
||||
package docking.widgets.fieldpanel;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import docking.widgets.fieldpanel.internal.ColorRangeMap;
|
||||
@ -60,8 +56,4 @@ public class ColorRangeMapTest extends AbstractGenericTest {
|
||||
assertColorsEqual(Palette.WHITE, map.getColor(100, Palette.WHITE));
|
||||
}
|
||||
|
||||
private void assertColorsEqual(Color c1, Color c2) {
|
||||
assertEquals(c1.getRGB(), c2.getRGB());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ src/main/resources/generic.log4j.xml||GHIDRA||||END|
|
||||
src/main/resources/generic.log4jdev.xml||GHIDRA||||END|
|
||||
src/main/resources/generic.log4jfile.xml||GHIDRA||||END|
|
||||
src/main/resources/generic.log4jtest.xml||GHIDRA||||END|
|
||||
src/main/resources/images/EmptyIcon.gif||GHIDRA||||END|
|
||||
src/main/resources/images/EmptyIcon16.gif||GHIDRA||||END|
|
||||
src/main/resources/images/GhidraIcon128.png||GHIDRA||||END|
|
||||
src/main/resources/images/GhidraIcon16.png||GHIDRA||||END|
|
||||
src/main/resources/images/GhidraIcon24.png||GHIDRA||||END|
|
||||
@ -36,34 +38,57 @@ src/main/resources/images/GhidraIcon64.png||GHIDRA||||END|
|
||||
src/main/resources/images/Plus2.png||GHIDRA||||END|
|
||||
src/main/resources/images/applications-multimedia16.png||Tango Icons - Public Domain|||tango|END|
|
||||
src/main/resources/images/checkmark_green.gif||GHIDRA||||END|
|
||||
src/main/resources/images/closedSmallFolder.png||Modified Nuvola Icons - LGPL 2.1||||END|
|
||||
src/main/resources/images/collapse_all.png||GHIDRA||||END|
|
||||
src/main/resources/images/core.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/core24.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/dialog-cancel.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/disk.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/disk_save_as.png||FAMFAMFAM Icons - CC 2.5||||END|
|
||||
src/main/resources/images/down.png||GHIDRA||||END|
|
||||
src/main/resources/images/dragon16.gif||GHIDRA||||END|
|
||||
src/main/resources/images/edit-cut.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/edit-cut22.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/emblem-important.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/erase16.png||GHIDRA||||END|
|
||||
src/main/resources/images/error.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/exec.png||Crystal Clear Icons - LGPL 2.1||||END|
|
||||
src/main/resources/images/expand_all.png||GHIDRA||||END|
|
||||
src/main/resources/images/face-monkey16.png||Tango Icons - Public Domain|||originally face-monkey from tango|END|
|
||||
src/main/resources/images/flag.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/go-home.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/greenDragon16.png||GHIDRA||||END|
|
||||
src/main/resources/images/greenDragon24.png||GHIDRA||||END|
|
||||
src/main/resources/images/help-browser.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/information.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/internet-web-browser16.png||Tango Icons - Public Domain|||originally internet-web-browser.png from tango|END|
|
||||
src/main/resources/images/kgpg.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/left.alternate.png||GHIDRA||||END|
|
||||
src/main/resources/images/left.png||GHIDRA||||END|
|
||||
src/main/resources/images/locationIn.gif||GHIDRA||||END|
|
||||
src/main/resources/images/locationOut.gif||GHIDRA||||END|
|
||||
src/main/resources/images/mergemgr16.gif||GHIDRA||||END|
|
||||
src/main/resources/images/network-receive16.png||Tango Icons - Public Domain|||originally network-receive.png from tango|END|
|
||||
src/main/resources/images/openFolder.png||Modified Nuvola Icons - LGPL 2.1||||END|
|
||||
src/main/resources/images/openSmallFolder.png||Modified Nuvola Icons - LGPL 2.1||||END|
|
||||
src/main/resources/images/page_paste.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/page_white_copy.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/process-stop.png||Tango Icons - Public Domain|||Theirs: Oxygen icon theme (dual license; LGPL or CC-SA-3.0)tango icon set|END|
|
||||
src/main/resources/images/program_obj.png||GHIDRA|||Custom Icon|END|
|
||||
src/main/resources/images/redDragon16.png||GHIDRA|||Renamed GIF version of redDragon16.png|END|
|
||||
src/main/resources/images/redDragon24.png||GHIDRA||||END|
|
||||
src/main/resources/images/redDragon32.png||GHIDRA||||END|
|
||||
src/main/resources/images/reload3.png||Crystal Clear Icons - LGPL 2.1||||END|
|
||||
src/main/resources/images/right.alternate.png||GHIDRA||||END|
|
||||
src/main/resources/images/right.png||GHIDRA||||END|
|
||||
src/main/resources/images/software-update-urgent.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/sortascending.png||GHIDRA||||END|
|
||||
src/main/resources/images/sortdescending.png||GHIDRA||||END|
|
||||
src/main/resources/images/text_align_justify.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/images/up.png||GHIDRA||||END|
|
||||
src/main/resources/images/video-x-generic16.png||Tango Icons - Public Domain|||tango|END|
|
||||
src/main/resources/images/viewmagfit.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/warning.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
src/main/resources/log4j-appender-console-with-links.xml||GHIDRA||||END|
|
||||
src/main/resources/log4j-appender-console.xml||GHIDRA||||END|
|
||||
src/main/resources/log4j-appender-logpanel.xml||GHIDRA||||END|
|
||||
|
@ -7,5 +7,65 @@ font.italics = font.standard[italic]
|
||||
font.bold.italic = font.standard[bold][italic]
|
||||
font.monospaced = monospaced-PLAIN-12
|
||||
|
||||
// Icons files
|
||||
|
||||
icon.flag = flag.png
|
||||
icon.lock = kgpg.png
|
||||
icon.checkmark.green = checkmark_green.gif
|
||||
|
||||
icon.empty = EmptyIcon16.gif
|
||||
icon.empty.20 = EmptyIcon.gif
|
||||
|
||||
icon.help = help-browser.png
|
||||
|
||||
icon.add = Plus2.png
|
||||
icon.copy = page_white_copy.png
|
||||
icon.cut = edit-cut.png
|
||||
icon.paste = page_paste.png
|
||||
|
||||
icon.collapse.all = collapse_all.png
|
||||
icon.expand.all = expand_all.png
|
||||
|
||||
icon.configure.filter = exec.png
|
||||
icon.clear = erase16.png
|
||||
icon.delete = icon.error
|
||||
icon.error = emblem-important.png
|
||||
|
||||
icon.home = go-home.png
|
||||
icon.navigate.in = locationIn.gif
|
||||
icon.navigate.out = locationOut.gif
|
||||
|
||||
icon.not.allowed = dialog-cancel.png
|
||||
icon.folder.open = openSmallFolder.png
|
||||
icon.folder.closed = closedSmallFolder.png
|
||||
icon.refresh = reload3.png
|
||||
|
||||
icon.sort.ascending = sortascending.png
|
||||
icon.sort.descending = sortdescending.png
|
||||
|
||||
icon.stop = process-stop.png
|
||||
icon.warning.strong = software-update-urgent.png
|
||||
icon.warning = warning.png
|
||||
icon.information = information.png
|
||||
|
||||
icon.left = left.png
|
||||
icon.right = right.png
|
||||
icon.up = up.png
|
||||
icon.down = down.png
|
||||
|
||||
icon.left.alt = left.alternate.png
|
||||
icon.right.alt = right.alternate.png
|
||||
|
||||
icon.save = disk.png
|
||||
icon.save.as = disk_save_as.png
|
||||
|
||||
icon.make.selection = text_align_justify.png
|
||||
|
||||
icon.arrow.down.right = viewmagfit.png[rotate(90)]
|
||||
icon.arrow.up.left = viewmagfit.png[rotate(275)]
|
||||
icon.filter.not.accepted = icon.flag{dialog-cancel.png[size(10,10)][move(6,6)]}
|
||||
icon.blocked.match = icon.lock{icon.checkmark.green[size(12,12)][move(4,0)]}
|
||||
|
||||
|
||||
|
||||
[Dark Defaults]
|
@ -45,6 +45,7 @@ import org.junit.runner.Description;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.test.rule.Repeated;
|
||||
import generic.test.rule.RepeatedTestRule;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.Gui;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.GhidraTestApplicationLayout;
|
||||
@ -56,6 +57,7 @@ import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.task.AbstractSwingUpdateManager;
|
||||
import ghidra.util.task.SwingUpdateManager;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import resources.icons.UrlImageIcon;
|
||||
import sun.awt.AppContext;
|
||||
import utilities.util.FileUtilities;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
@ -2050,4 +2052,51 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the two colors have the same rgb values (handles GColor)
|
||||
* @param expected the expected color
|
||||
* @param actual the actual color
|
||||
*/
|
||||
public void assertColorsEqual(Color expected, Color actual) {
|
||||
if (expected.getRGB() == actual.getRGB()) {
|
||||
return;
|
||||
}
|
||||
fail("Expected: [" + expected.getClass().getSimpleName() + "]" + expected +
|
||||
", but got: [" + actual.getClass().getSimpleName() + "]" + actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the two icons are or refer to the same icon (handles GIcon)
|
||||
* @param expected the expected icon
|
||||
* @param actual the actual icon
|
||||
*/
|
||||
public void assertIconsEqual(Icon expected, Icon actual) {
|
||||
if (expected.equals(actual)) {
|
||||
return;
|
||||
}
|
||||
URL url1 = getURL(expected);
|
||||
URL url2 = getURL(actual);
|
||||
|
||||
if (url1 != null && url1.equals(url2)) {
|
||||
return;
|
||||
}
|
||||
fail("Expected icon [" + expected.getClass().getSimpleName() + "]" + expected.toString() +
|
||||
", but got: [" + actual.getClass().getSimpleName() + "]" + actual.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL for the given icon
|
||||
* @param icon the icon to get a URL for
|
||||
* @return the URL for the given icon
|
||||
*/
|
||||
public URL getURL(Icon icon) {
|
||||
if (icon instanceof UrlImageIcon urlIcon) {
|
||||
return urlIcon.getUrl();
|
||||
}
|
||||
if (icon instanceof GIcon gIcon) {
|
||||
return gIcon.getUrl();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class ColorValue extends ThemeValue<Color> {
|
||||
private static final String EXTERNAL_PREFIX = "[color]";
|
||||
private static final String SYSTEM_COLOR_PREFIX = "system.color";
|
||||
|
||||
public static final Color LAST_RESORT_DEFAULT = Color.GRAY;
|
||||
public static final Color LAST_RESORT_DEFAULT = new Color(128, 128, 128);
|
||||
|
||||
/**
|
||||
* Constructor used when the ColorValue will have a direct {@link Color} value. The refId will
|
||||
@ -93,7 +93,7 @@ public class ColorValue extends ThemeValue<Color> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getUnresolvedReferenceValue(String unresolvedId) {
|
||||
protected Color getUnresolvedReferenceValue(String id, String unresolvedId) {
|
||||
|
||||
Throwable t = ReflectionUtilities.createThrowableWithStackOlderThan();
|
||||
StackTraceElement[] trace = t.getStackTrace();
|
||||
@ -103,9 +103,8 @@ public class ColorValue extends ThemeValue<Color> {
|
||||
t.setStackTrace(filtered);
|
||||
|
||||
Msg.error(this,
|
||||
"Could not resolve indirect color for \"" + unresolvedId +
|
||||
"\", using last resort default!",
|
||||
t);
|
||||
"Could not resolve indirect color path for \"" + unresolvedId +
|
||||
"\" for primary id \"" + id + "\", using last resort default");
|
||||
return LAST_RESORT_DEFAULT;
|
||||
}
|
||||
|
||||
|
@ -143,9 +143,10 @@ public class FontValue extends ThemeValue<Font> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Font getUnresolvedReferenceValue(String unresolvedId) {
|
||||
Msg.warn(this, "Could not resolve indirect font for " + unresolvedId +
|
||||
", using last resort default");
|
||||
protected Font getUnresolvedReferenceValue(String id, String unresolvedId) {
|
||||
Msg.warn(this,
|
||||
"Could not resolve indirect font path for \"" + unresolvedId +
|
||||
"\" for primary id \"" + id + "\", using last resort default");
|
||||
return LAST_RESORT_DEFAULT;
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,10 @@ public class GColor extends Color {
|
||||
return delegate.darker();
|
||||
}
|
||||
|
||||
public boolean isUnresolved() {
|
||||
return delegate == ColorValue.LAST_RESORT_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toHexString();
|
||||
|
@ -321,7 +321,11 @@ public class Gui {
|
||||
* @return the current {@link Font} associated with the given id.
|
||||
*/
|
||||
public static Font getFont(String id) {
|
||||
return getFont(id, true);
|
||||
Font font = getFont(id, true);
|
||||
if (font == FontValue.LAST_RESORT_DEFAULT) {
|
||||
return null;
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -390,6 +394,15 @@ public class Gui {
|
||||
* @param color the new color for the id
|
||||
*/
|
||||
public static void setColor(String id, Color color) {
|
||||
if (color == null) {
|
||||
|
||||
}
|
||||
if (color instanceof GColor gColor) {
|
||||
if (id.equals(gColor.getId())) {
|
||||
Msg.warn(Gui.class, "Attempted to set a color to a reference to itself!");
|
||||
return; // this would create a circular reference to itself, don't do it
|
||||
}
|
||||
}
|
||||
setColor(new ColorValue(id, color));
|
||||
}
|
||||
|
||||
@ -407,7 +420,9 @@ public class Gui {
|
||||
notifyThemeChanged(new ColorChangedThemeEvent(currentValues, newValue));
|
||||
|
||||
// now update the ui
|
||||
lookAndFeelManager.colorsChanged();
|
||||
if (lookAndFeelManager != null) {
|
||||
lookAndFeelManager.colorsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,7 +180,7 @@ public class IconValue extends ThemeValue<Icon> {
|
||||
}
|
||||
|
||||
private static int getModifierIndex(String value) {
|
||||
int baseModifierIndex = value.indexOf("[", 1); // start past first char as it coud be valid "[EXTERNAL]" prefix
|
||||
int baseModifierIndex = value.indexOf("[", 1); // start past first char as it could be valid "[EXTERNAL]" prefix
|
||||
int overlayModifierIndex = value.indexOf("{");
|
||||
if (baseModifierIndex < 0) {
|
||||
return overlayModifierIndex;
|
||||
@ -197,10 +197,10 @@ public class IconValue extends ThemeValue<Icon> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Icon getUnresolvedReferenceValue(String unresolvedId) {
|
||||
protected Icon getUnresolvedReferenceValue(String id, String unresolvedId) {
|
||||
Msg.warn(this,
|
||||
"Could not resolve indirect icon path for \"" + unresolvedId +
|
||||
"\", using last resort default");
|
||||
"\" for primary id \"" + id + "\", using last resort default");
|
||||
return LAST_RESORT_DEFAULT;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,9 @@ public abstract class ThemeValue<T> implements Comparable<ThemeValue<T>> {
|
||||
protected final String referenceId;
|
||||
|
||||
protected ThemeValue(String id, String referenceId, T value) {
|
||||
if (id.equals(referenceId)) {
|
||||
throw new IllegalArgumentException("Can't create a themeValue that referencs itself");
|
||||
}
|
||||
this.id = id;
|
||||
this.referenceId = referenceId;
|
||||
this.value = value;
|
||||
@ -92,11 +95,11 @@ public abstract class ThemeValue<T> implements Comparable<ThemeValue<T>> {
|
||||
visitedKeys.add(parent.id);
|
||||
if (visitedKeys.contains(parent.referenceId)) {
|
||||
Msg.warn(this, "Theme value reference loop detected for key: " + id);
|
||||
return getUnresolvedReferenceValue(id);
|
||||
return getUnresolvedReferenceValue(id, parent.referenceId);
|
||||
}
|
||||
parent = getReferredValue(values, parent.referenceId);
|
||||
}
|
||||
return getUnresolvedReferenceValue(id);
|
||||
return getUnresolvedReferenceValue(id, referenceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,10 +154,11 @@ public abstract class ThemeValue<T> implements Comparable<ThemeValue<T>> {
|
||||
|
||||
/**
|
||||
* Returns the T to be used if the indirect reference couldn't be resolved.
|
||||
* @param unresolvedId the id that couldn't be resolved
|
||||
* @param id the id we are trying to get a value foe
|
||||
* @param unresolvedId the reference id that couldn't be resolved
|
||||
* @return the default value to be used if the indirect reference couldn't be resolved.
|
||||
*/
|
||||
protected abstract T getUnresolvedReferenceValue(String unresolvedId);
|
||||
protected abstract T getUnresolvedReferenceValue(String id, String unresolvedId);
|
||||
|
||||
/**
|
||||
* Returns the ThemeValue referred to by this ThemeValue. Needs to be overridden by
|
||||
|
@ -141,7 +141,7 @@ public abstract class AbstractOptions implements Options {
|
||||
|
||||
if (type == OptionType.COLOR_TYPE) {
|
||||
if (defaultValue instanceof GColor gColor) {
|
||||
registerThemeColor(optionName, gColor.getId(), help, description);
|
||||
registerThemeColor(optionName, gColor.getId(), help, description, editor);
|
||||
return;
|
||||
}
|
||||
warnNonThemeValue("Registering non theme color: " + optionName);
|
||||
@ -197,14 +197,14 @@ public abstract class AbstractOptions implements Options {
|
||||
}
|
||||
|
||||
private void registerThemeColor(String optionName, String colorId, HelpLocation help,
|
||||
String description) {
|
||||
String description, PropertyEditor editor) {
|
||||
Option currentOption = getExistingComptibleOption(optionName, OptionType.COLOR_TYPE);
|
||||
if (currentOption != null && currentOption instanceof ThemeColorOption) {
|
||||
currentOption.updateRegistration(description, help, null, null);
|
||||
currentOption.updateRegistration(description, help, null, editor);
|
||||
return;
|
||||
}
|
||||
description += " (Theme Color: " + colorId + ")";
|
||||
Option option = new ThemeColorOption(optionName, colorId, description, help);
|
||||
Option option = new ThemeColorOption(optionName, colorId, description, help, editor);
|
||||
valueMap.put(optionName, option);
|
||||
}
|
||||
|
||||
|
@ -186,4 +186,9 @@ public class EditorState implements PropertyChangeListener {
|
||||
return options.getDescription(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EditorState: " + name + "= " + currentValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,9 @@
|
||||
package ghidra.framework.options;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
@ -30,14 +32,23 @@ public class ThemeColorOption extends Option {
|
||||
private String colorId;
|
||||
|
||||
public ThemeColorOption(String optionName, String colorId, String description,
|
||||
HelpLocation help) {
|
||||
super(optionName, OptionType.COLOR_TYPE, description, help, null, true, null);
|
||||
HelpLocation help, PropertyEditor editor) {
|
||||
super(optionName, OptionType.COLOR_TYPE, description, help, null, true, editor);
|
||||
this.colorId = colorId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getCurrentValue() {
|
||||
return Gui.getColor(colorId);
|
||||
GColor gColor = new GColor(colorId);
|
||||
if (gColor.isUnresolved()) {
|
||||
return null;
|
||||
}
|
||||
return gColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue() {
|
||||
return getCurrentValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,6 +40,11 @@ public class ThemeFontOption extends Option {
|
||||
return Gui.getFont(fontId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue() {
|
||||
return getCurrentValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSetCurrentValue(Object value) {
|
||||
Gui.setFont(fontId, (Font) value);
|
||||
|
Before Width: | Height: | Size: 58 B After Width: | Height: | Size: 58 B |
Before Width: | Height: | Size: 61 B After Width: | Height: | Size: 61 B |
Before Width: | Height: | Size: 501 B After Width: | Height: | Size: 501 B |
Before Width: | Height: | Size: 771 B After Width: | Height: | Size: 771 B |
Before Width: | Height: | Size: 620 B After Width: | Height: | Size: 620 B |
Before Width: | Height: | Size: 974 B After Width: | Height: | Size: 974 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 807 B After Width: | Height: | Size: 807 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 606 B |
Before Width: | Height: | Size: 778 B After Width: | Height: | Size: 778 B |
Before Width: | Height: | Size: 540 B After Width: | Height: | Size: 540 B |
Before Width: | Height: | Size: 188 B After Width: | Height: | Size: 188 B |
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 219 B |
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 703 B After Width: | Height: | Size: 703 B |
Before Width: | Height: | Size: 309 B After Width: | Height: | Size: 309 B |
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 547 B |
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 190 B |
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 200 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 193 B After Width: | Height: | Size: 193 B |
Before Width: | Height: | Size: 975 B After Width: | Height: | Size: 975 B |
Before Width: | Height: | Size: 666 B After Width: | Height: | Size: 666 B |
@ -28,7 +28,6 @@ import org.junit.Test;
|
||||
|
||||
import generic.constraint.DecisionNode.PropertyValue;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
|
||||
public class DecisionTreeTest extends AbstractGenericTest {
|
||||
|
||||
@ -134,7 +133,7 @@ public class DecisionTreeTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testMatchFromFirstXML() {
|
||||
Color c = Palette.WHITE;
|
||||
Color c = Color.WHITE;
|
||||
DecisionSet decisionSet = decisionTree.getDecisionsSet(c, "NAME");
|
||||
List<Decision> decisions = decisionSet.getDecisions();
|
||||
assertEquals(1, decisions.size());
|
||||
@ -147,7 +146,7 @@ public class DecisionTreeTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testMatchFromAdditionalXML() {
|
||||
Color c = Palette.MAGENTA;
|
||||
Color c = new Color(255, 0, 255);
|
||||
DecisionSet decisionSet = decisionTree.getDecisionsSet(c, "NAME");
|
||||
List<Decision> decisions = decisionSet.getDecisions();
|
||||
assertEquals(1, decisions.size());
|
||||
@ -160,7 +159,7 @@ public class DecisionTreeTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testMatchMultiple() {
|
||||
Color c = Palette.YELLOW;
|
||||
Color c = Color.YELLOW;
|
||||
DecisionSet decisionSet = decisionTree.getDecisionsSet(c, "NAME");
|
||||
List<Decision> decisions = decisionSet.getDecisions();
|
||||
assertEquals(2, decisions.size());
|
||||
@ -179,7 +178,7 @@ public class DecisionTreeTest extends AbstractGenericTest {
|
||||
|
||||
@Test
|
||||
public void testNoMatchUsingDefault() {
|
||||
Color c = Palette.GRAY;
|
||||
Color c = Color.GRAY;
|
||||
DecisionSet decisionSet = decisionTree.getDecisionsSet(c, "NAME");
|
||||
List<Decision> decisions = decisionSet.getDecisions();
|
||||
assertEquals(1, decisions.size());
|
||||
|
@ -69,6 +69,7 @@ public class GuiTest {
|
||||
|
||||
Gui.setThemePreferenceManager(new ThemePreferenceManager() {
|
||||
|
||||
@Override
|
||||
public GTheme getTheme() {
|
||||
return new MetalTheme();
|
||||
}
|
||||
@ -337,7 +338,7 @@ public class GuiTest {
|
||||
|
||||
@Test
|
||||
public void testGetApplicationDarkDefaults() {
|
||||
// dark defaults are a combination of standard defalts overlayed with dark defaults
|
||||
// dark defaults are a combination of standard defaults overlayed with dark defaults
|
||||
GThemeValueMap expected = new GThemeValueMap();
|
||||
expected.load(defaultValues);
|
||||
expected.load(darkDefaultValues);
|
||||
|
@ -21,8 +21,6 @@ import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
|
||||
public class HTMLUtilitiesTest {
|
||||
|
||||
private SpyErrorLogger spyLogger = new SpyErrorLogger();
|
||||
@ -128,13 +126,13 @@ public class HTMLUtilitiesTest {
|
||||
|
||||
@Test
|
||||
public void testToRGBString() {
|
||||
String rgb = HTMLUtilities.toRGBString(Palette.RED);
|
||||
String rgb = HTMLUtilities.toRGBString(WebColors.RED);
|
||||
assertEquals("255000000", rgb);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToHexString() {
|
||||
String rgb = HTMLUtilities.toHexString(Palette.RED);
|
||||
String rgb = HTMLUtilities.toHexString(WebColors.RED);
|
||||
assertEquals("#FF0000", rgb);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package ghidra.graph;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
@ -25,6 +25,8 @@ import javax.swing.JFrame;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import docking.framework.DockingApplicationConfiguration;
|
||||
import ghidra.framework.ApplicationConfiguration;
|
||||
import ghidra.graph.algo.*;
|
||||
import ghidra.graph.algo.viewer.*;
|
||||
import ghidra.util.SystemUtilities;
|
||||
@ -37,6 +39,13 @@ import ghidra.util.exception.CancelledException;
|
||||
*/
|
||||
public class GraphAlgorithmsVisualDebugger extends AbstractGraphAlgorithmsTest {
|
||||
|
||||
@Override
|
||||
protected ApplicationConfiguration createApplicationConfiguration() {
|
||||
DockingApplicationConfiguration config = new DockingApplicationConfiguration();
|
||||
config.setShowSplashScreen(false);
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GDirectedGraph<TestV, TestE> createGraph() {
|
||||
return GraphFactory.createDirectedGraph();
|
||||
|
@ -17,6 +17,7 @@ package ghidra.service.graph;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -24,22 +25,47 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import docking.FakeDockingTool;
|
||||
import docking.test.AbstractDockingTest;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.options.ToolOptions;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
public class GraphDisplayOptionsTest {
|
||||
public class GraphDisplayOptionsTest extends AbstractDockingTest {
|
||||
|
||||
private GraphType graphType;
|
||||
private GraphDisplayOptions options;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Gui.setColor("color.V1", Palette.BLACK);
|
||||
Gui.setColor("color.V2", Palette.BLACK);
|
||||
Gui.setColor("color.V3", Palette.BLACK);
|
||||
Gui.setColor("color.E1", Palette.BLACK);
|
||||
Gui.setColor("color.E2", Palette.BLACK);
|
||||
Gui.setColor("color.E3", Palette.BLACK);
|
||||
Gui.setColor("color.edge.default", Palette.BLACK);
|
||||
Gui.setColor("color.vertex.default", Palette.BLACK);
|
||||
Gui.setColor("color.edge.selected", Palette.BLACK);
|
||||
Gui.setColor("color.vertex.selected", Palette.BLACK);
|
||||
Gui.setFont("font.graph", new Font("monospaced", Font.PLAIN, 12));
|
||||
List<String> vertexTypes = Arrays.asList("V1", "V2", "V3");
|
||||
List<String> edgeTypes = Arrays.asList("E1", "E2", "E3");
|
||||
graphType = new GraphType("Test", "Test Description", vertexTypes, edgeTypes);
|
||||
options = new GraphDisplayOptions(graphType);
|
||||
options.setVertexColor("V1", "color.V1");
|
||||
options.setVertexColor("V2", "color.V2");
|
||||
options.setVertexColor("V3", "color.V3");
|
||||
options.setEdgeColor("E1", "color.E1");
|
||||
options.setEdgeColor("E2", "color.E2");
|
||||
options.setEdgeColor("E3", "color.E3");
|
||||
options.setDefaultEdgeColor("color.edge.default");
|
||||
options.setDefaultVertexColor("color.vertex.default");
|
||||
options.setEdgeSelectionColor("color.edge.selected");
|
||||
options.setVertexSelectionColor("color.vertex.selected");
|
||||
options.setFont("font.graph");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -204,9 +230,10 @@ public class GraphDisplayOptionsTest {
|
||||
|
||||
@Test
|
||||
public void testGetVertexColorForType() {
|
||||
assertEquals(options.getDefaultVertexColor(), options.getVertexColor("V1"));
|
||||
assertEquals(options.getDefaultVertexColor().getRGB(),
|
||||
options.getVertexColor("V1").getRGB());
|
||||
options.setVertexColor("V1", Palette.RED);
|
||||
assertEquals(Palette.RED, options.getVertexColor("V1"));
|
||||
assertEquals(Palette.RED.getRGB(), options.getVertexColor("V1").getRGB());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -235,8 +262,8 @@ public class GraphDisplayOptionsTest {
|
||||
Options vertexColorOptions = graphDisplayOptions.getOptions("Vertex Colors");
|
||||
List<String> leafOptionNames = vertexColorOptions.getLeafOptionNames();
|
||||
assertEquals(Arrays.asList("V1", "V2", "V3"), leafOptionNames);
|
||||
assertEquals(options.getDefaultVertexColor(),
|
||||
vertexColorOptions.getColor("V1", Palette.WHITE));
|
||||
assertEquals(options.getDefaultVertexColor().getRGB(),
|
||||
vertexColorOptions.getColor("V1", Palette.BLACK).getRGB());
|
||||
|
||||
Options vertexShapeOptions = graphDisplayOptions.getOptions("Vertex Shapes");
|
||||
leafOptionNames = vertexShapeOptions.getLeafOptionNames();
|
||||
@ -247,8 +274,8 @@ public class GraphDisplayOptionsTest {
|
||||
Options edgeColorOptions = graphDisplayOptions.getOptions("Edge Colors");
|
||||
leafOptionNames = edgeColorOptions.getLeafOptionNames();
|
||||
assertEquals(Arrays.asList("E1", "E2", "E3"), leafOptionNames);
|
||||
assertEquals(options.getDefaultEdgeColor(),
|
||||
edgeColorOptions.getColor("E1", Palette.WHITE));
|
||||
assertEquals(options.getDefaultEdgeColor().getRGB(),
|
||||
edgeColorOptions.getColor("E1", Palette.WHITE).getRGB());
|
||||
|
||||
Options miscellaneousOptions = graphDisplayOptions.getOptions("Miscellaneous");
|
||||
leafOptionNames = miscellaneousOptions.getLeafOptionNames();
|
||||
@ -268,13 +295,13 @@ public class GraphDisplayOptionsTest {
|
||||
|
||||
AttributedVertex vertex = new AttributedVertex("Foo");
|
||||
vertex.setVertexType("V1");
|
||||
assertEquals(Palette.BLUE.getRGB(), options.getVertexColor(vertex).getRGB());
|
||||
assertEquals(Palette.BLACK.getRGB(), options.getVertexColor(vertex).getRGB());
|
||||
|
||||
Options graphDisplayOptions = toolOptions.getOptions(options.getRootOptionsName());
|
||||
Options vertexColorOptions = graphDisplayOptions.getOptions("Vertex Colors");
|
||||
vertexColorOptions.setColor("V1", Palette.CYAN);
|
||||
vertexColorOptions.setColor("V1", Palette.GOLD);
|
||||
|
||||
assertEquals(Palette.CYAN, options.getVertexColor(vertex));
|
||||
assertEquals(Palette.GOLD.getRGB(), options.getVertexColor(vertex).getRGB());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ package help;
|
||||
import java.awt.Component;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Locale;
|
||||
import java.util.*;
|
||||
|
||||
import javax.help.*;
|
||||
import javax.help.Map;
|
||||
import javax.help.Map.ID;
|
||||
import javax.help.event.HelpModelEvent;
|
||||
import javax.help.plaf.HelpNavigatorUI;
|
||||
@ -143,6 +143,8 @@ public class CustomTOCView extends TOCView {
|
||||
* Our hook to install our custom cell renderer.
|
||||
*/
|
||||
class CustomTOCNavigatorUI extends BasicTOCNavigatorUI {
|
||||
private static final String ROOT_TOC_ID = "Root";
|
||||
|
||||
public CustomTOCNavigatorUI(JHelpTOCNavigator b) {
|
||||
super(b);
|
||||
}
|
||||
@ -184,27 +186,42 @@ public class CustomTOCView extends TOCView {
|
||||
}
|
||||
|
||||
TOCItem item = (TOCItem) treeItem;
|
||||
ID itemID = item.getID();
|
||||
if (itemID == null) {
|
||||
Msg.debug(this, "No help ID for " + item);
|
||||
return;
|
||||
}
|
||||
|
||||
String presentation = item.getPresentation();
|
||||
if (presentation != null) {
|
||||
return; // don't currently support presentations
|
||||
}
|
||||
|
||||
CustomTreeItemDecorator customItem = (CustomTreeItemDecorator) item;
|
||||
ID itemId = getId(customItem, helpModel);
|
||||
if (itemId == null) {
|
||||
Msg.debug(this, "No help ID for " + item);
|
||||
return;
|
||||
}
|
||||
|
||||
String customDisplayText = customItem.getDisplayText();
|
||||
try {
|
||||
helpModel.setCurrentID(itemID, customDisplayText, navigator);
|
||||
helpModel.setCurrentID(itemId, customDisplayText, navigator);
|
||||
}
|
||||
catch (InvalidHelpSetContextException ex) {
|
||||
Msg.error(this, "Exception setting new help item ID", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private ID getId(CustomTreeItemDecorator item, HelpModel helpModel) {
|
||||
ID itemId = item.getID();
|
||||
if (itemId != null) {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
String tocID = item.getTocID();
|
||||
if (Objects.equals(tocID, ROOT_TOC_ID)) {
|
||||
HelpSet hs = helpModel.getHelpSet();
|
||||
return hs.getHomeID();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private TOCItem getSelectedItem(TreeSelectionEvent e, JHelpNavigator navigator) {
|
||||
TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
|
||||
if (newLeadSelectionPath == null) {
|
||||
|
@ -21,7 +21,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.ApplicationConfiguration;
|
||||
import help.validator.*;
|
||||
@ -55,8 +55,8 @@ public class GHelpBuilder {
|
||||
|
||||
private String outputDirectoryName;
|
||||
private String moduleName;
|
||||
private Collection<File> dependencyHelpPaths = new LinkedHashSet<File>();
|
||||
private Collection<File> helpInputDirectories = new LinkedHashSet<File>();
|
||||
private Collection<File> dependencyHelpPaths = new LinkedHashSet<>();
|
||||
private Collection<File> helpInputDirectories = new LinkedHashSet<>();
|
||||
private static boolean debugEnabled = false;
|
||||
private boolean ignoreInvalid = false; // TODO: Do actual validation here
|
||||
|
||||
@ -66,9 +66,18 @@ public class GHelpBuilder {
|
||||
public static void main(String[] args) throws Exception {
|
||||
GHelpBuilder builder = new GHelpBuilder();
|
||||
builder.exitOnError = true;
|
||||
ApplicationConfiguration config = new ApplicationConfiguration() {
|
||||
@Override
|
||||
protected void initializeApplication() {
|
||||
Gui.initialize();
|
||||
}
|
||||
|
||||
ApplicationConfiguration config = new ApplicationConfiguration();
|
||||
Application.initializeApplication(new GhidraApplicationLayout(), config);
|
||||
@Override
|
||||
public boolean isHeadless() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Application.initializeApplication(new HelpApplicationLayout("Help Builder", "0.1"), config);
|
||||
|
||||
builder.build(args);
|
||||
}
|
||||
@ -98,7 +107,7 @@ public class GHelpBuilder {
|
||||
}
|
||||
|
||||
private HelpModuleCollection collectAllHelp() {
|
||||
List<File> allHelp = new ArrayList<File>(helpInputDirectories);
|
||||
List<File> allHelp = new ArrayList<>(helpInputDirectories);
|
||||
for (File file : dependencyHelpPaths) {
|
||||
allHelp.add(file);
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ import javax.swing.text.html.*;
|
||||
import javax.swing.text.html.HTML.Tag;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
import ghidra.util.Msg;
|
||||
@ -480,6 +482,12 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
||||
}
|
||||
|
||||
String srcString = src.toString();
|
||||
|
||||
//check if the icon is a defined icon theme id
|
||||
if (Gui.hasIcon(srcString)) {
|
||||
return new GIcon(srcString).getUrl();
|
||||
}
|
||||
|
||||
if (isJavaCode(srcString)) {
|
||||
return installImageFromJavaCode(srcString);
|
||||
}
|
||||
|
@ -54,8 +54,6 @@ import ghidra.util.SystemUtilities;
|
||||
*/
|
||||
public class GHelpSet extends HelpSet {
|
||||
|
||||
private static final String HOME_ID = "Misc_Welcome_to_Ghidra_Help";
|
||||
|
||||
/** <b>static</b> map that contains all known help sets in the system. */
|
||||
private static java.util.Map<HelpSet, Map> helpSetsToCombinedMaps = new java.util.HashMap<>();
|
||||
private static java.util.Map<HelpSet, Map> helpSetsToLocalMaps = new java.util.HashMap<>();
|
||||
@ -79,8 +77,6 @@ public class GHelpSet extends HelpSet {
|
||||
setKeyData(kitTypeRegistry, type, editorKit);
|
||||
setKeyData(kitLoaderRegistry, type, classLoader);
|
||||
|
||||
setHomeID(HOME_ID);
|
||||
|
||||
initializeCombinedMapWrapper();
|
||||
}
|
||||
|
||||
@ -121,6 +117,11 @@ public class GHelpSet extends HelpSet {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getHelpSetURL().toString();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
@ -0,0 +1,154 @@
|
||||
/* ###
|
||||
* 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 help;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.framework.ApplicationProperties;
|
||||
import ghidra.framework.GModule;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import util.CollectionUtils;
|
||||
import utility.application.ApplicationLayout;
|
||||
import utility.application.ApplicationUtilities;
|
||||
import utility.module.ClasspathFilter;
|
||||
import utility.module.ModuleUtilities;
|
||||
|
||||
//
|
||||
// TODO this class should be deleted when the GP-1981 branch is merged into master. The
|
||||
// DockingApplicationLayout is not accessible by help, due to Docking depending on Help.
|
||||
// Much of the application layout code should live in Utility so that it is reachable by more
|
||||
// modules. Docking and Ghidra application layout classes should also have their names
|
||||
// changed.
|
||||
//
|
||||
// Perhaps: ModuleAppliactionLayout and ClasspathApplicationLayout.
|
||||
//
|
||||
public class HelpApplicationLayout extends ApplicationLayout {
|
||||
|
||||
private static final String NO_RELEASE_NAME = "NO_RELEASE";
|
||||
|
||||
/** Dev mode main source bin dir pattern */
|
||||
private static final Pattern CLASS_PATH_MODULE_NAME_PATTERN =
|
||||
Pattern.compile(".*/(\\w+)/bin/main");
|
||||
|
||||
/**
|
||||
* Constructs a new docking application layout object with the given name and version.
|
||||
*
|
||||
* @param name The name of the application.
|
||||
* @param version The version of the application.
|
||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
||||
*/
|
||||
public HelpApplicationLayout(String name, String version) throws FileNotFoundException {
|
||||
|
||||
this.applicationProperties =
|
||||
Objects.requireNonNull(new ApplicationProperties(name, version, NO_RELEASE_NAME));
|
||||
this.applicationRootDirs = getDefaultApplicationRootDirs();
|
||||
applicationRootDirs.addAll(getAdditionalApplicationRootDirs(applicationRootDirs));
|
||||
|
||||
// Application installation directory
|
||||
applicationInstallationDir = applicationRootDirs.iterator().next().getParentFile();
|
||||
if (SystemUtilities.isInDevelopmentMode()) {
|
||||
applicationInstallationDir = applicationInstallationDir.getParentFile();
|
||||
}
|
||||
|
||||
// Modules
|
||||
if (SystemUtilities.isInDevelopmentMode()) {
|
||||
|
||||
// In development mode we rely on the IDE's classpath to determine which modules to
|
||||
// include, as opposed to scanning the filesystem. This prevents unrelated modules
|
||||
// from being used.
|
||||
|
||||
modules = ModuleUtilities.findModules(applicationRootDirs,
|
||||
ModuleUtilities.findModuleRootDirectories(applicationRootDirs),
|
||||
new ClasspathFilter());
|
||||
}
|
||||
else {
|
||||
modules = ModuleUtilities.findModules(applicationRootDirs, applicationRootDirs);
|
||||
}
|
||||
|
||||
// User directories
|
||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(applicationProperties);
|
||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(applicationProperties,
|
||||
applicationInstallationDir);
|
||||
}
|
||||
|
||||
protected Collection<ResourceFile> getAdditionalApplicationRootDirs(
|
||||
Collection<ResourceFile> roots) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected Map<String, GModule> findModules() {
|
||||
if (!SystemUtilities.isInDevelopmentMode()) {
|
||||
// in release mode we only have one application root, so no need to find all others
|
||||
return ModuleUtilities.findModules(applicationRootDirs, applicationRootDirs);
|
||||
}
|
||||
|
||||
// In development mode we may have multiple module root directories under which modules may
|
||||
// be found. Search all roots for modules.
|
||||
Collection<ResourceFile> roots =
|
||||
ModuleUtilities.findModuleRootDirectories(applicationRootDirs, new ArrayList<>());
|
||||
Map<String, GModule> allModules = ModuleUtilities.findModules(applicationRootDirs, roots);
|
||||
|
||||
// Filter any modules found to ensure that we only include those that are listed on the
|
||||
// classpath. (Due to the nature of how the development classpath is created, not all
|
||||
// found modules may match the classpath entries.)
|
||||
Set<String> cpNames = getClassPathModuleNames();
|
||||
Map<String, GModule> filteredModules = new HashMap<>();
|
||||
Set<Entry<String, GModule>> entrySet = allModules.entrySet();
|
||||
for (Entry<String, GModule> entry : entrySet) {
|
||||
GModule module = entry.getValue();
|
||||
if (cpNames.contains(module.getName())) {
|
||||
filteredModules.put(entry.getKey(), module);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredModules;
|
||||
}
|
||||
|
||||
private Set<String> getClassPathModuleNames() {
|
||||
String cp = System.getProperty("java.class.path");
|
||||
String[] pathParts = cp.split(File.pathSeparator);
|
||||
Set<String> paths = new HashSet<>(Arrays.asList(pathParts));
|
||||
Set<String> cpNames = new HashSet<>();
|
||||
for (String cpEntry : paths) {
|
||||
Matcher matcher = CLASS_PATH_MODULE_NAME_PATTERN.matcher(cpEntry);
|
||||
if (matcher.matches()) {
|
||||
cpNames.add(matcher.group(1));
|
||||
}
|
||||
}
|
||||
return cpNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default list of Application directories. In repo-based
|
||||
* development mode this includes the root Ghidra directory within each repo.
|
||||
* When not in development mode, the requirement is that the current working
|
||||
* directory correspond to the installation root. The first entry will be
|
||||
* the primary root in both cases.
|
||||
* @return root directories
|
||||
*/
|
||||
public static Collection<ResourceFile> getDefaultApplicationRootDirs() {
|
||||
if (SystemUtilities.isInDevelopmentMode()) {
|
||||
return ApplicationUtilities.findDefaultApplicationRootDirs();
|
||||
}
|
||||
return CollectionUtils.asList(new ResourceFile(System.getProperty("user.dir")));
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@ import java.util.Collections;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.Gui;
|
||||
import help.validator.location.*;
|
||||
import resources.IconProvider;
|
||||
import resources.Icons;
|
||||
@ -73,9 +75,12 @@ public class HelpBuildUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file object that is the help topic directory for the given file.
|
||||
* This method is useful for finding the help topic directory when the given
|
||||
* file doesn't live directly under a help topic.
|
||||
* Returns a file object that is the help topic directory for the given file.
|
||||
*
|
||||
* <p>This method is useful for finding the help topic directory when the given file doesn't
|
||||
* live directly under a help topic.
|
||||
* @param file the file for which to find a topic
|
||||
* @return the path to the help topic directory
|
||||
*/
|
||||
public static Path getHelpTopicDir(Path file) {
|
||||
Path helpTopics = file.getFileSystem().getPath("help", "topics");
|
||||
@ -540,7 +545,7 @@ public class HelpBuildUtils {
|
||||
* @param sourceFile the source file path of the image reference
|
||||
* @param ref the reference text
|
||||
* @return an absolute path; null if the URI is remote
|
||||
* @throws URISyntaxException
|
||||
* @throws URISyntaxException if there is an exception creating a URL/URI for the image location
|
||||
*/
|
||||
public static ImageLocation locateImageReference(Path sourceFile, String ref)
|
||||
throws URISyntaxException {
|
||||
@ -563,6 +568,13 @@ public class HelpBuildUtils {
|
||||
}
|
||||
return ImageLocation.createRuntimeLocation(sourceFile, ref, resolved, path);
|
||||
}
|
||||
if (Gui.hasIcon(ref)) {
|
||||
GIcon gIcon = new GIcon(ref);
|
||||
URL url = gIcon.getUrl();
|
||||
URI resolved = url.toURI();
|
||||
Path path = toPath(resolved);
|
||||
return ImageLocation.createRuntimeLocation(sourceFile, ref, resolved, path);
|
||||
}
|
||||
|
||||
URI resolved = resolve(sourceFile, ref);
|
||||
if (isRemote(resolved)) {
|
||||
@ -574,13 +586,14 @@ public class HelpBuildUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn an HTML HREF reference into an absolute path. This will
|
||||
* locate files based upon relative references, specialized help system references (i.e.,
|
||||
* help/topics/...), and absolute URLs.
|
||||
* Turn an HTML HREF reference into an absolute path. This will locate files based upon
|
||||
* relative references, specialized help system references (i.e., help/topics/...), and
|
||||
* absolute URLs.
|
||||
*
|
||||
* @param sourceFile the reference's source file
|
||||
* @param ref the reference text
|
||||
* @return an absolute path; null if the URI is remote
|
||||
* @throws URISyntaxException
|
||||
* @throws URISyntaxException if there is an exception creating a URL/URI for the image location
|
||||
*/
|
||||
public static Path locateReference(Path sourceFile, String ref) throws URISyntaxException {
|
||||
|
||||
|