diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/HeadlessThemeManager.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/HeadlessThemeManager.java index 192fcc5f1f..f543c1164e 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/HeadlessThemeManager.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/HeadlessThemeManager.java @@ -15,6 +15,9 @@ */ package generic.theme; +import java.awt.Color; +import java.awt.Font; + import ghidra.util.Msg; /** @@ -41,8 +44,35 @@ public class HeadlessThemeManager extends ThemeManager { } private void doInitialize() { + initializeSystemValues(); buildCurrentValues(); GColor.refreshAll(currentValues); GIcon.refreshAll(currentValues); } + + private void initializeSystemValues() { + + // + // These values may be referenced by Java clients. The headless env does not load the + // Java LookAndFeel, which is from where the values are usually defined. So, add dummy + // definitions for these values here. + // + + Font font = new Font("Arial", Font.PLAIN, 12); + javaDefaults.addFont(new FontValue(SystemThemeIds.FONT_CONTROL_ID, font)); + javaDefaults.addFont(new FontValue(SystemThemeIds.FONT_VIEW_ID, font)); + javaDefaults.addFont(new FontValue(SystemThemeIds.FONT_MENU_ID, font)); + + javaDefaults.addColor(new ColorValue(SystemThemeIds.BG_CONTROL_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.BG_VIEW_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.BG_TOOLTIP_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.BG_VIEW_SELECTED_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.BG_BORDER_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.FG_CONTROL_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.FG_VIEW_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.FG_TOOLTIP_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.FG_VIEW_SELECTED_ID, Color.CYAN)); + javaDefaults.addColor(new ColorValue(SystemThemeIds.FG_DISABLED_ID, Color.CYAN)); + + } } diff --git a/Ghidra/Framework/Help/src/main/java/help/GHelpHTMLEditorKit.java b/Ghidra/Framework/Help/src/main/java/help/GHelpHTMLEditorKit.java index 405476b8f0..456287c685 100644 --- a/Ghidra/Framework/Help/src/main/java/help/GHelpHTMLEditorKit.java +++ b/Ghidra/Framework/Help/src/main/java/help/GHelpHTMLEditorKit.java @@ -26,7 +26,6 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.swing.Icon; import javax.swing.JEditorPane; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; @@ -35,8 +34,8 @@ import javax.swing.text.html.*; import javax.swing.text.html.HTML.Tag; import generic.jar.ResourceFile; -import generic.theme.*; -import generic.theme.GThemeDefaults.Colors; +import generic.theme.GColor; +import generic.theme.Gui; import ghidra.framework.Application; import ghidra.framework.preferences.Preferences; import ghidra.util.Msg; @@ -471,11 +470,6 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit { */ private class GHelpImageView extends ImageView { - private static final String HELP_SHARED_ARROW = "help/shared/arrow.gif"; - private static final Icon SHARED_ARROW_ICON = new HelpRightArrowIcon(Colors.FOREGROUND); - private static final IconProvider SHARED_ARROW_ICON_PROVIDER = - new IconProvider(SHARED_ARROW_ICON, null); - /* * Unusual Code Alert! * This class exists to enable our help system to find custom icons defined in source @@ -547,61 +541,15 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit { return null; } - // - // This code is looking for the specific referenced image file and then replacing that - // image file with something that can update its content at runtime, based on theme. - // Alternatively, we could have updated all help files to point to a GIcon, which - // handles updating itself when the theme changes. We chose to replace the icon here - // instead of in the source code to prevent changing many files. - // String srcString = src.toString().trim(); - if (srcString.equals(HELP_SHARED_ARROW)) { - return installImageFromCustomIcon(SHARED_ARROW_ICON_PROVIDER); - } - - // check if the srcString is a defined theme icon id - if (Gui.hasIcon(srcString)) { - // - // Wrap the GIcon inside of an IconProvider, as that class can handle a null URL - // returned from GIcon. (This can happen if the GIcon is based on a modified icon.) - // - GIcon gIcon = new GIcon(srcString); - IconProvider iconProvider = new IconProvider(gIcon, gIcon.getUrl()); + IconProvider iconProvider = HelpBuildUtils.getRuntimeIcon(srcString); + if (iconProvider != null && !iconProvider.isInvalid()) { + // note: store the image off for later use; the url will not be used by us + this.image = iconProvider.getImage(); return iconProvider.getOrCreateUrl(); } - if (isJavaCode(srcString)) { - return installImageFromJavaCode(srcString); - } - - URL url = doGetImageURL(srcString); - return url; - } - - private URL installImageFromCustomIcon(IconProvider iconProvider) { - - if (iconProvider == null || iconProvider.isInvalid()) { - return null; - } - - this.image = iconProvider.getImage(); - - // note: this icon is not used to load the image; the 'image' we set is used instead - URL url = iconProvider.getOrCreateUrl(); - return url; - } - - private URL installImageFromJavaCode(String srcString) { - - IconProvider iconProvider = getIconFromJavaCode(srcString); - if (iconProvider == null || iconProvider.isInvalid()) { - return null; - } - - this.image = iconProvider.getImage(); - - URL url = iconProvider.getOrCreateUrl(); - return url; + return doGetImageURL(srcString); } private URL doGetImageURL(String srcString) { @@ -624,16 +572,6 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit { URL resource = ResourceManager.getResource(srcString); return resource; } - - private boolean isJavaCode(String src) { - // not sure of the best way to handle this--be exact for now - return Icons.isIconsReference(src); - } - - private IconProvider getIconFromJavaCode(String src) { - return Icons.getIconForIconsReference(src); - } - } } diff --git a/Ghidra/Framework/Help/src/main/java/help/HelpBuildUtils.java b/Ghidra/Framework/Help/src/main/java/help/HelpBuildUtils.java index 7d6cca5473..25c2cd7216 100644 --- a/Ghidra/Framework/Help/src/main/java/help/HelpBuildUtils.java +++ b/Ghidra/Framework/Help/src/main/java/help/HelpBuildUtils.java @@ -23,8 +23,11 @@ import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.swing.Icon; + import generic.jar.ResourceFile; import generic.theme.GIcon; +import generic.theme.GThemeDefaults.Colors; import generic.theme.Gui; import ghidra.framework.Application; import ghidra.util.HelpLocation; @@ -44,6 +47,11 @@ public class HelpBuildUtils { public static boolean debug = true; + private static final String HELP_SHARED_ARROW = "help/shared/arrow.gif"; + private static final Icon SHARED_ARROW_ICON = new HelpRightArrowIcon(Colors.FOREGROUND); + private static final IconProvider SHARED_ARROW_ICON_PROVIDER = + new IconProvider(SHARED_ARROW_ICON, null); + private HelpBuildUtils() { // utils class; can't create } @@ -491,6 +499,45 @@ public class HelpBuildUtils { return null; } + public static IconProvider getRuntimeIcon(String ref) { + + if (Icons.isIconsReference(ref)) { + // help system syntax: + IconProvider iconProvider = Icons.getIconForIconsReference(ref); + if (iconProvider == null) { + return new IconProvider(null, null); // return a non-null 'invalid' provider + } + return iconProvider; + } + if (Gui.hasIcon(ref)) { + + // + // Wrap the GIcon inside of an IconProvider, as that class can handle a null URL + // returned from GIcon. (This can happen if the GIcon is based on a modified icon.) + // + GIcon gIcon = new GIcon(ref); + return new IconProvider(gIcon, gIcon.getUrl()); + } + + // + // Handle any hard-coded special cases + // + + // + // This code is looking for the specific referenced image file and then replacing that + // image file with something that can update its content at runtime, based on theme. + // Alternatively, we could have updated all help files to point to a GIcon, which + // handles updating itself when the theme changes. We chose to replace the icon here + // instead of in the source code to prevent changing many files. + // + String srcString = ref.toString().trim(); + if (srcString.equals(HELP_SHARED_ARROW)) { + return SHARED_ARROW_ICON_PROVIDER; + } + + return null; + } + /** * Turn an HTML IMG reference into a location object that has resolved path info. This will * locate files based upon relative references, specialized help system references (i.e., @@ -504,16 +551,14 @@ public class HelpBuildUtils { public static ImageLocation locateImageReference(Path sourceFile, String ref) throws URISyntaxException { - if (Icons.isIconsReference(ref)) { - - // help system syntax: - IconProvider iconProvider = Icons.getIconForIconsReference(ref); - if (iconProvider == null || iconProvider.isInvalid()) { + IconProvider runtimeIconProvider = getRuntimeIcon(ref); + if (runtimeIconProvider != null) { + if (runtimeIconProvider.isInvalid()) { // bad icon name return ImageLocation.createInvalidRuntimeLocation(sourceFile, ref); } - URL url = iconProvider.getUrl(); + URL url = runtimeIconProvider.getUrl(); URI resolved = null; Path path = null; if (url != null) { // we may have an icon with an invalid URL (e.g., a MultiIcon) @@ -522,19 +567,6 @@ public class HelpBuildUtils { } return ImageLocation.createRuntimeLocation(sourceFile, ref, resolved, path); } - if (Gui.hasIcon(ref)) { - - // - // Wrap the GIcon inside of an IconProvider, as that class can handle a null URL - // returned from GIcon. (This can happen if the GIcon is based on a modified icon.) - // - GIcon gIcon = new GIcon(ref); - IconProvider iconProvider = new IconProvider(gIcon, gIcon.getUrl()); - URL url = iconProvider.getOrCreateUrl(); - URI resolved = url.toURI(); - Path path = toPath(resolved); - return ImageLocation.createRuntimeLocation(sourceFile, ref, resolved, path); - } URI resolved = resolve(sourceFile, ref); if (isRemote(resolved)) {