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.ResourceBundle;
013: import java.util.Set;
014:
015: import org.eclipse.core.commands.common.EventManager;
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.DataFormatException;
020: import org.eclipse.jface.resource.FontRegistry;
021: import org.eclipse.jface.resource.StringConverter;
022: import org.eclipse.jface.util.IPropertyChangeListener;
023: import org.eclipse.jface.util.PropertyChangeEvent;
024: import org.eclipse.swt.graphics.FontData;
025: import org.eclipse.swt.graphics.RGB;
026: import org.eclipse.ui.IWorkbench;
027: import org.eclipse.ui.IWorkbenchPreferenceConstants;
028: import org.eclipse.ui.PlatformUI;
029: import org.eclipse.ui.internal.WorkbenchPlugin;
030: import org.eclipse.ui.internal.util.PrefUtil;
031: import org.eclipse.ui.internal.util.Util;
032: import org.eclipse.ui.themes.ITheme;
033: import org.eclipse.ui.themes.IThemeManager;
034:
035: /**
036: * @since 3.0
037: */
038: public class Theme extends EventManager implements ITheme {
039:
040: /**
041: * The translation bundle in which to look up internationalized text.
042: */
043: private final static ResourceBundle RESOURCE_BUNDLE = ResourceBundle
044: .getBundle(Theme.class.getName());
045:
046: private CascadingColorRegistry themeColorRegistry;
047:
048: private CascadingFontRegistry themeFontRegistry;
049:
050: private IThemeDescriptor descriptor;
051:
052: private IPropertyChangeListener themeListener;
053:
054: private CascadingMap dataMap;
055:
056: private ThemeRegistry themeRegistry;
057:
058: private IPropertyChangeListener propertyListener;
059:
060: /**
061: * @param descriptor
062: */
063: public Theme(IThemeDescriptor descriptor) {
064: themeRegistry = ((ThemeRegistry) WorkbenchPlugin.getDefault()
065: .getThemeRegistry());
066: this .descriptor = descriptor;
067: IWorkbench workbench = PlatformUI.getWorkbench();
068: if (descriptor != null) {
069: ITheme defaultTheme = workbench.getThemeManager().getTheme(
070: IThemeManager.DEFAULT_THEME);
071:
072: ColorDefinition[] colorDefinitions = this .descriptor
073: .getColors();
074: themeColorRegistry = new CascadingColorRegistry(
075: defaultTheme.getColorRegistry());
076: if (colorDefinitions.length > 0) {
077: ThemeElementHelper.populateRegistry(this ,
078: colorDefinitions, PrefUtil
079: .getInternalPreferenceStore());
080: }
081:
082: FontDefinition[] fontDefinitions = this .descriptor
083: .getFonts();
084: themeFontRegistry = new CascadingFontRegistry(defaultTheme
085: .getFontRegistry());
086: if (fontDefinitions.length > 0) {
087: ThemeElementHelper.populateRegistry(this ,
088: fontDefinitions, PrefUtil
089: .getInternalPreferenceStore());
090: }
091:
092: dataMap = new CascadingMap(((ThemeRegistry) WorkbenchPlugin
093: .getDefault().getThemeRegistry()).getData(),
094: descriptor.getData());
095: }
096:
097: getColorRegistry().addListener(getCascadeListener());
098: getFontRegistry().addListener(getCascadeListener());
099: PrefUtil.getInternalPreferenceStore()
100: .addPropertyChangeListener(getPropertyListener());
101: }
102:
103: /**
104: * Listener that is responsible for responding to preference changes.
105: *
106: * @return the property change listener
107: */
108: private IPropertyChangeListener getPropertyListener() {
109: if (propertyListener == null) {
110: propertyListener = new IPropertyChangeListener() {
111:
112: /* (non-Javadoc)
113: * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
114: */
115: public void propertyChange(PropertyChangeEvent event) {
116: String[] split = ThemeElementHelper
117: .splitPropertyName(Theme.this , event
118: .getProperty());
119: String key = split[1];
120: String theme = split[0];
121: if (key
122: .equals(IWorkbenchPreferenceConstants.CURRENT_THEME_ID)) {
123: return;
124: }
125: try {
126: String this Theme = getId();
127:
128: if (Util.equals(this Theme, theme)) {
129: if (getFontRegistry().hasValueFor(key)) {
130: FontData[] data = PreferenceConverter
131: .basicGetFontData((String) event
132: .getNewValue());
133:
134: getFontRegistry().put(key, data);
135: processDefaultsTo(key, data);
136: return;
137: } else if (getColorRegistry().hasValueFor(
138: key)) {
139: RGB rgb = StringConverter
140: .asRGB((String) event
141: .getNewValue());
142: getColorRegistry().put(key, rgb);
143: processDefaultsTo(key, rgb);
144: return;
145: }
146: }
147: } catch (DataFormatException e) {
148: //no-op
149: }
150: }
151:
152: /**
153: * Process all fonts that default to the given ID.
154: *
155: * @param key the font ID
156: * @param fd the new FontData for defaulted fonts
157: */
158: private void processDefaultsTo(String key, FontData[] fd) {
159: FontDefinition[] defs = WorkbenchPlugin
160: .getDefault().getThemeRegistry()
161: .getFontsFor(getId());
162: for (int i = 0; i < defs.length; i++) {
163: String defaultsTo = defs[i].getDefaultsTo();
164: if (defaultsTo != null
165: && defaultsTo.equals(key)) {
166: IPreferenceStore store = WorkbenchPlugin
167: .getDefault().getPreferenceStore();
168: if (store.isDefault(ThemeElementHelper
169: .createPreferenceKey(Theme.this ,
170: defs[i].getId()))) {
171: getFontRegistry().put(defs[i].getId(),
172: fd);
173: processDefaultsTo(defs[i].getId(), fd);
174: }
175: }
176: }
177: }
178:
179: /**
180: * Process all colors that default to the given ID.
181: *
182: * @param key the color ID
183: * @param rgb the new RGB value for defaulted colors
184: */
185: private void processDefaultsTo(String key, RGB rgb) {
186: ColorDefinition[] defs = WorkbenchPlugin
187: .getDefault().getThemeRegistry()
188: .getColorsFor(getId());
189: for (int i = 0; i < defs.length; i++) {
190: String defaultsTo = defs[i].getDefaultsTo();
191: if (defaultsTo != null
192: && defaultsTo.equals(key)) {
193: IPreferenceStore store = WorkbenchPlugin
194: .getDefault().getPreferenceStore();
195: if (store.isDefault(ThemeElementHelper
196: .createPreferenceKey(Theme.this ,
197: defs[i].getId()))) {
198: getColorRegistry().put(defs[i].getId(),
199: rgb);
200: processDefaultsTo(defs[i].getId(), rgb);
201: }
202: }
203: }
204: }
205: };
206: }
207: return propertyListener;
208: }
209:
210: /**
211: * Listener that is responsible for rebroadcasting events fired from the base font/color registry
212: */
213: private IPropertyChangeListener getCascadeListener() {
214: if (themeListener == null) {
215: themeListener = new IPropertyChangeListener() {
216:
217: /* (non-Javadoc)
218: * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
219: */
220: public void propertyChange(PropertyChangeEvent event) {
221: firePropertyChange(event);
222: }
223: };
224: }
225: return themeListener;
226: }
227:
228: public ColorRegistry getColorRegistry() {
229: if (themeColorRegistry != null) {
230: return themeColorRegistry;
231: }
232:
233: return WorkbenchThemeManager.getInstance()
234: .getDefaultThemeColorRegistry();
235: }
236:
237: public FontRegistry getFontRegistry() {
238: if (themeFontRegistry != null) {
239: return themeFontRegistry;
240: }
241:
242: return WorkbenchThemeManager.getInstance()
243: .getDefaultThemeFontRegistry();
244: }
245:
246: public void dispose() {
247: if (themeColorRegistry != null) {
248: themeColorRegistry.removeListener(themeListener);
249: themeColorRegistry.dispose();
250: }
251: if (themeFontRegistry != null) {
252: themeFontRegistry.removeListener(themeListener);
253: themeFontRegistry.dispose();
254: }
255: PrefUtil.getInternalPreferenceStore()
256: .removePropertyChangeListener(getPropertyListener());
257: }
258:
259: /* (non-Javadoc)
260: * @see org.eclipse.ui.internal.themes.ITheme#getId()
261: */
262: public String getId() {
263: return descriptor == null ? IThemeManager.DEFAULT_THEME
264: : descriptor.getId();
265: }
266:
267: /* (non-Javadoc)
268: * @see org.eclipse.ui.IWorkbench#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
269: */
270: public void addPropertyChangeListener(
271: IPropertyChangeListener listener) {
272: addListenerObject(listener);
273: }
274:
275: /* (non-Javadoc)
276: * @see org.eclipse.ui.IWorkbench#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
277: */
278: public void removePropertyChangeListener(
279: IPropertyChangeListener listener) {
280: removeListenerObject(listener);
281: }
282:
283: private void firePropertyChange(PropertyChangeEvent event) {
284: Object[] listeners = getListeners();
285: for (int i = 0; i < listeners.length; i++) {
286: ((IPropertyChangeListener) listeners[i])
287: .propertyChange(event);
288: }
289: }
290:
291: /* (non-Javadoc)
292: * @see org.eclipse.ui.internal.themes.ITheme#getLabel()
293: */
294: public String getLabel() {
295: return descriptor == null ? RESOURCE_BUNDLE
296: .getString("DefaultTheme.label") : descriptor.getName(); //$NON-NLS-1$
297: }
298:
299: /* (non-Javadoc)
300: * @see org.eclipse.ui.themes.ITheme#getString(java.lang.String)
301: */
302: public String getString(String key) {
303: if (dataMap != null) {
304: return (String) dataMap.get(key);
305: }
306: return (String) themeRegistry.getData().get(key);
307: }
308:
309: /* (non-Javadoc)
310: * @see org.eclipse.ui.themes.ITheme#keySet()
311: */
312: public Set keySet() {
313: if (dataMap != null) {
314: return dataMap.keySet();
315: }
316:
317: return themeRegistry.getData().keySet();
318: }
319:
320: /* (non-Javadoc)
321: * @see org.eclipse.ui.themes.ITheme#getInt(java.lang.String)
322: */
323: public int getInt(String key) {
324: String string = getString(key);
325: if (string == null) {
326: return 0;
327: }
328: try {
329: return Integer.parseInt(string);
330: } catch (NumberFormatException e) {
331: return 0;
332: }
333: }
334:
335: /* (non-Javadoc)
336: * @see org.eclipse.ui.themes.ITheme#getBoolean(java.lang.String)
337: */
338: public boolean getBoolean(String key) {
339: String string = getString(key);
340: if (string == null) {
341: return false;
342: }
343:
344: return Boolean.valueOf(getString(key)).booleanValue();
345: }
346: }
|