From 421b830a666ce38eca7848389501caa086b40614 Mon Sep 17 00:00:00 2001 From: Andrew Obuchowicz Date: Sun, 17 Apr 2022 22:46:48 -0400 Subject: [PATCH] [WIP] Allow plugin fragments to supply alternate icons Allow plugin fragments to contribute alternate icons that will be loaded through the URLImageDescriptor class. The icons must be placed within a directory titled "theme" located at the root of the plugin fragment, ie. "/theme/" The file path of the replacement icons must match the file path of the icon to be replaced. For example, in order to replace an icon used by plugin org.eclipse.xxx where the path of the icon is "/path/To/icon.png" in the plugin's bundle one must: - Create a plugin fragment with org.eclipse.xxx as the Host Plug-in - Create a directory "/theme/" at the root of the plugin fragment - Place an alternate icon with the correct file path in the theme directory, ie. "/theme/path/To/icon.png" Signed-off-by: Andrew Obuchowicz --- .../jface/preference/JFacePreferences.java | 7 +++ .../jface/resource/URLImageDescriptor.java | 58 +++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/JFacePreferences.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/JFacePreferences.java index 4bb0f728acf..0ce860481fb 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/JFacePreferences.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/JFacePreferences.java @@ -111,6 +111,13 @@ public final class JFacePreferences { */ public static final String REVISION_OLDEST_COLOR = "org.eclipse.jface.REVISION_OLDEST_COLOR"; //$NON-NLS-1$ + /** + * TODO: Add javadoc + * + * @since 3.26 + */ + public static final String CUSTOM_RESOURCE_THEME = "org.eclipse.jface.CUSTOM_RESOURCE_THEME"; //$NON-NLS-1$ + private static IPreferenceStore preferenceStore; /** diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java index c150acd09f6..f3ccfe807ec 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java @@ -42,6 +42,9 @@ */ class URLImageDescriptor extends ImageDescriptor { + private static final String THEME_REPLACEMENTS_DIR = "/theme"; //$NON-NLS-1$ + private static final String PLUGIN_URL = "/plugin/"; //$NON-NLS-1$ + private static class URLImageFileNameProvider implements ImageFileNameProvider { private String url; @@ -198,9 +201,17 @@ public String toString() { } private static URL getxURL(URL url, int zoom) { - if (zoom == 100) { - return url; - } + + URL resultingURL = url; + // First we check for an image with increased zoom, if desired + + // TODO: Ideally, we shouldn't be commenting out this line. Figure out a way + // around removing it. + + // if (zoom == 100) { + // return url; + // } + String path = url.getPath(); int dot = path.lastIndexOf('.'); if (dot != -1 && (zoom == 150 || zoom == 200)) { @@ -215,12 +226,49 @@ private static URL getxURL(URL url, int zoom) { if (url.getQuery() != null) { file += '?' + url.getQuery(); } - return new URL(url.getProtocol(), url.getHost(), url.getPort(), file); + resultingURL = new URL(url.getProtocol(), url.getHost(), url.getPort(), file); + } catch (MalformedURLException e) { + Policy.getLog().log(new Status(IStatus.ERROR, Policy.JFACE, e.getLocalizedMessage(), e)); + } + } + + // Next we check if there's an alternate image that we should use + // TODO: I'm not exactly sure how we should be accessing the JFace preference + // Should a IPreferenceStore instance be retrieved? + // Or is that considered part of Eclipse RCP and not JFace? + if ( + // !JFaceResources.getString(JFacePreferences.CUSTOM_RESOURCE_THEME).equals(JFacePreferences.CUSTOM_RESOURCE_THEME) + // && + resultingURL.getFile().contains(PLUGIN_URL)) { + // The third path segment is the bundleID + String originalFilePath = resultingURL.getFile(); + for (int i = 0; i < 2; i++) { + originalFilePath = originalFilePath.substring(originalFilePath.indexOf('/') + 1); + } + // TODO: The original bundleID should only be used in the case of plugin + // fragment image replacements. + // We need an additional (optional) preference that will hold the bundleID of + // the currently used theme plugin + String bundleID = originalFilePath.substring(0, originalFilePath.indexOf('/')); + originalFilePath = originalFilePath.substring(originalFilePath.indexOf('/'), originalFilePath.length()); + + // TODO: This is a workaround and should probably be removed + if (originalFilePath.contains("/$nl$/")) { //$NON-NLS-1$ + + originalFilePath = originalFilePath.replace("/$nl$/", "/"); //$NON-NLS-1$ //$NON-NLS-2$ + } + try { + URL themedIconURL = new URL(resultingURL.getProtocol(), resultingURL.getHost(), resultingURL.getPort(), + PLUGIN_URL + bundleID + THEME_REPLACEMENTS_DIR + originalFilePath); + String found = getFilePath(themedIconURL, false); + if (found != null) { + resultingURL = themedIconURL; + } } catch (MalformedURLException e) { Policy.getLog().log(new Status(IStatus.ERROR, Policy.JFACE, e.getLocalizedMessage(), e)); } } - return null; + return resultingURL; }