001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.themes;
011:
012: import java.util.Arrays;
013: import java.util.SortedSet;
014: import java.util.TreeSet;
015:
016: import org.eclipse.jface.preference.IPreferenceStore;
017: import org.eclipse.jface.preference.PreferenceConverter;
018: import org.eclipse.jface.resource.ColorRegistry;
019: import org.eclipse.jface.resource.FontRegistry;
020: import org.eclipse.swt.graphics.FontData;
021: import org.eclipse.swt.graphics.RGB;
022: import org.eclipse.ui.internal.Workbench;
023: import org.eclipse.ui.internal.WorkbenchPlugin;
024: import org.eclipse.ui.themes.ITheme;
025: import org.eclipse.ui.themes.IThemeManager;
026:
027: /**
028: * @since 3.0
029: */
030: public final class ThemeElementHelper {
031:
032: public static void populateRegistry(ITheme theme,
033: FontDefinition[] definitions, IPreferenceStore store) {
034: // sort the definitions by dependant ordering so that we process
035: // ancestors before children.
036: FontDefinition[] copyOfDefinitions = null;
037:
038: // the colors to set a default value for, but not a registry value
039: FontDefinition[] defaults = null;
040: if (!theme.getId().equals(IThemeManager.DEFAULT_THEME)) {
041: definitions = addDefaulted(definitions);
042: //compute the defaults only if we're setting preferences at this time
043: if (store != null) {
044: defaults = getDefaults(definitions);
045: }
046: }
047:
048: copyOfDefinitions = new FontDefinition[definitions.length];
049: System.arraycopy(definitions, 0, copyOfDefinitions, 0,
050: definitions.length);
051: Arrays.sort(copyOfDefinitions,
052: new IThemeRegistry.HierarchyComparator(definitions));
053:
054: for (int i = 0; i < copyOfDefinitions.length; i++) {
055: FontDefinition definition = copyOfDefinitions[i];
056: installFont(definition, theme, store, true);
057: }
058:
059: if (defaults != null) {
060: for (int i = 0; i < defaults.length; i++) {
061: installFont(defaults[i], theme, store, false);
062: }
063: }
064: }
065:
066: /**
067: * @param definitions
068: * @return
069: */
070: private static FontDefinition[] addDefaulted(
071: FontDefinition[] definitions) {
072: IThemeRegistry registry = WorkbenchPlugin.getDefault()
073: .getThemeRegistry();
074: FontDefinition[] allDefs = registry.getFonts();
075:
076: SortedSet set = addDefaulted(definitions, allDefs);
077: return (FontDefinition[]) set.toArray(new FontDefinition[set
078: .size()]);
079: }
080:
081: /**
082: * Installs the given font in the preference store and optionally the font
083: * registry.
084: *
085: * @param definition
086: * the font definition
087: * @param registry
088: * the font registry
089: * @param store
090: * the preference store from which to set and obtain font data
091: * @param setInRegistry
092: * whether the color should be put into the registry as well as
093: * having its default preference set
094: */
095: private static void installFont(FontDefinition definition,
096: ITheme theme, IPreferenceStore store, boolean setInRegistry) {
097: FontRegistry registry = theme.getFontRegistry();
098:
099: String id = definition.getId();
100: String key = createPreferenceKey(theme, id);
101: FontData[] prefFont = store != null ? PreferenceConverter
102: .getFontDataArray(store, key) : null;
103: FontData[] defaultFont = null;
104: if (definition.getValue() != null) {
105: defaultFont = definition.getValue();
106: } else if (definition.getDefaultsTo() != null) {
107: defaultFont = registry.filterData(registry
108: .getFontData(definition.getDefaultsTo()), Workbench
109: .getInstance().getDisplay());
110: } else {
111: // values pushed in from jface property files. Very ugly.
112: defaultFont = registry.bestDataArray(registry
113: .getFontData(key), Workbench.getInstance()
114: .getDisplay());
115: }
116:
117: if (setInRegistry) {
118: if (prefFont == null
119: || prefFont == PreferenceConverter.FONTDATA_ARRAY_DEFAULT_DEFAULT) {
120: prefFont = defaultFont;
121: }
122:
123: if (prefFont != null) {
124: registry.put(id, prefFont);
125: }
126: }
127:
128: if (defaultFont != null && store != null) {
129: PreferenceConverter.setDefault(store, key, defaultFont);
130: }
131: }
132:
133: public static void populateRegistry(ITheme theme,
134: ColorDefinition[] definitions, IPreferenceStore store) {
135: // sort the definitions by dependant ordering so that we process
136: // ancestors before children.
137:
138: ColorDefinition[] copyOfDefinitions = null;
139:
140: // the colors to set a default value for, but not a registry value
141: ColorDefinition[] defaults = null;
142: if (!theme.getId().equals(IThemeManager.DEFAULT_THEME)) {
143: definitions = addDefaulted(definitions);
144: //compute defaults only if we're setting preferences
145: if (store != null) {
146: defaults = getDefaults(definitions);
147: }
148: }
149:
150: copyOfDefinitions = new ColorDefinition[definitions.length];
151: System.arraycopy(definitions, 0, copyOfDefinitions, 0,
152: definitions.length);
153: Arrays.sort(copyOfDefinitions,
154: new IThemeRegistry.HierarchyComparator(definitions));
155:
156: for (int i = 0; i < copyOfDefinitions.length; i++) {
157: ColorDefinition definition = copyOfDefinitions[i];
158: installColor(definition, theme, store, true);
159: }
160:
161: if (defaults != null) {
162: for (int i = 0; i < defaults.length; i++) {
163: installColor(defaults[i], theme, store, false);
164: }
165: }
166: }
167:
168: /**
169: * Return the definitions that should have their default preference value
170: * set but nothing else.
171: *
172: * @param definitions the definitions that will be fully handled
173: * @return the remaining definitions that should be defaulted
174: */
175: private static ColorDefinition[] getDefaults(
176: ColorDefinition[] definitions) {
177: IThemeRegistry registry = WorkbenchPlugin.getDefault()
178: .getThemeRegistry();
179: ColorDefinition[] allDefs = registry.getColors();
180:
181: SortedSet set = new TreeSet(IThemeRegistry.ID_COMPARATOR);
182: set.addAll(Arrays.asList(allDefs));
183: set.removeAll(Arrays.asList(definitions));
184: return (ColorDefinition[]) set.toArray(new ColorDefinition[set
185: .size()]);
186: }
187:
188: /**
189: * Return the definitions that should have their default preference value
190: * set but nothing else.
191: *
192: * @param definitions the definitions that will be fully handled
193: * @return the remaining definitions that should be defaulted
194: */
195: private static FontDefinition[] getDefaults(
196: FontDefinition[] definitions) {
197: IThemeRegistry registry = WorkbenchPlugin.getDefault()
198: .getThemeRegistry();
199: FontDefinition[] allDefs = registry.getFonts();
200:
201: SortedSet set = new TreeSet(IThemeRegistry.ID_COMPARATOR);
202: set.addAll(Arrays.asList(allDefs));
203: set.removeAll(Arrays.asList(definitions));
204: return (FontDefinition[]) set.toArray(new FontDefinition[set
205: .size()]);
206: }
207:
208: /**
209: * @param definitions
210: * @return
211: */
212: private static ColorDefinition[] addDefaulted(
213: ColorDefinition[] definitions) {
214: IThemeRegistry registry = WorkbenchPlugin.getDefault()
215: .getThemeRegistry();
216: ColorDefinition[] allDefs = registry.getColors();
217:
218: SortedSet set = addDefaulted(definitions, allDefs);
219: return (ColorDefinition[]) set.toArray(new ColorDefinition[set
220: .size()]);
221: }
222:
223: /**
224: * @param definitions
225: * @param allDefs
226: * @return
227: */
228: private static SortedSet addDefaulted(
229: IHierarchalThemeElementDefinition[] definitions,
230: IHierarchalThemeElementDefinition[] allDefs) {
231: SortedSet set = new TreeSet(IThemeRegistry.ID_COMPARATOR);
232: set.addAll(Arrays.asList(definitions));
233:
234: IHierarchalThemeElementDefinition copy[] = new IHierarchalThemeElementDefinition[allDefs.length];
235: System.arraycopy(allDefs, 0, copy, 0, allDefs.length);
236:
237: Arrays.sort(allDefs, new IThemeRegistry.HierarchyComparator(
238: copy));
239: for (int i = 0; i < allDefs.length; i++) {
240: IHierarchalThemeElementDefinition def = allDefs[i];
241: if (def.getDefaultsTo() != null) {
242: if (set.contains(def.getDefaultsTo())) {
243: set.add(def);
244: }
245: }
246: }
247: return set;
248: }
249:
250: /**
251: * Installs the given color in the preference store and optionally the color
252: * registry.
253: *
254: * @param definition
255: * the color definition
256: * @param registry
257: * the color registry
258: * @param store
259: * the preference store from which to set and obtain color data
260: * @param setInRegistry
261: * whether the color should be put into the registry as well as
262: * having its default preference set
263: */
264: private static void installColor(ColorDefinition definition,
265: ITheme theme, IPreferenceStore store, boolean setInRegistry) {
266:
267: ColorRegistry registry = theme.getColorRegistry();
268:
269: String id = definition.getId();
270: String key = createPreferenceKey(theme, id);
271: RGB prefColor = store != null ? PreferenceConverter.getColor(
272: store, key) : null;
273: RGB defaultColor = null;
274: if (definition.getValue() != null) {
275: defaultColor = definition.getValue();
276: } else {
277: defaultColor = registry.getRGB(definition.getDefaultsTo());
278: }
279:
280: if (setInRegistry) {
281: if (prefColor == null
282: || prefColor == PreferenceConverter.COLOR_DEFAULT_DEFAULT) {
283: prefColor = defaultColor;
284: }
285:
286: if (prefColor != null) {
287: registry.put(id, prefColor);
288: }
289: }
290:
291: if (defaultColor != null && store != null) {
292: PreferenceConverter.setDefault(store, key, defaultColor);
293: }
294: }
295:
296: /**
297: * @param theme
298: * @param id
299: * @return
300: */
301: public static String createPreferenceKey(ITheme theme, String id) {
302: String themeId = theme.getId();
303: if (themeId.equals(IThemeManager.DEFAULT_THEME)) {
304: return id;
305: }
306:
307: return themeId + '.' + id;
308: }
309:
310: /**
311: * @param theme
312: * @param property
313: * @return
314: */
315: public static String[] splitPropertyName(Theme theme,
316: String property) {
317: IThemeDescriptor[] descriptors = WorkbenchPlugin.getDefault()
318: .getThemeRegistry().getThemes();
319: for (int i = 0; i < descriptors.length; i++) {
320: IThemeDescriptor themeDescriptor = descriptors[i];
321: String id = themeDescriptor.getId();
322: if (property.startsWith(id + '.')) { // the property starts with
323: // a known theme ID -
324: // extract and return it and
325: // the remaining property
326: return new String[] {
327: property.substring(0, id.length()),
328: property.substring(id.length() + 1) };
329: }
330: }
331:
332: // default is simply return the default theme ID and the raw property
333: return new String[] { IThemeManager.DEFAULT_THEME, property };
334: }
335:
336: /**
337: * Not intended to be instantiated.
338: */
339: private ThemeElementHelper() {
340: // no-op
341: }
342: }
|