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.HashMap;
013: import java.util.Iterator;
014: import java.util.Map;
015:
016: import org.eclipse.core.commands.common.EventManager;
017: import org.eclipse.jface.resource.ColorRegistry;
018: import org.eclipse.jface.resource.FontRegistry;
019: import org.eclipse.jface.resource.JFaceResources;
020: import org.eclipse.jface.util.IPropertyChangeListener;
021: import org.eclipse.jface.util.PropertyChangeEvent;
022: import org.eclipse.swt.graphics.FontData;
023: import org.eclipse.swt.graphics.RGB;
024: import org.eclipse.swt.widgets.Display;
025: import org.eclipse.ui.IWorkbenchPreferenceConstants;
026: import org.eclipse.ui.PlatformUI;
027: import org.eclipse.ui.internal.WorkbenchPlugin;
028: import org.eclipse.ui.internal.misc.StatusUtil;
029: import org.eclipse.ui.internal.util.PrefUtil;
030: import org.eclipse.ui.statushandlers.StatusManager;
031: import org.eclipse.ui.themes.ITheme;
032: import org.eclipse.ui.themes.IThemeManager;
033:
034: /**
035: * Theme manager for the Workbench.
036: *
037: * @since 3.0
038: */
039: public class WorkbenchThemeManager extends EventManager implements
040: IThemeManager {
041:
042: private static final String SYSTEM_DEFAULT_THEME = "org.eclipse.ui.ide.systemDefault";//$NON-NLS-1$
043:
044: private static WorkbenchThemeManager instance;
045:
046: /**
047: * Returns the singelton instance of the WorkbenchThemeManager
048: *
049: * @return singleton instance
050: */
051: public static synchronized WorkbenchThemeManager getInstance() {
052: if (instance == null) {
053: instance = new WorkbenchThemeManager();
054: instance.getCurrentTheme(); // initialize the current theme
055: }
056: return instance;
057: }
058:
059: private ITheme currentTheme;
060:
061: private IPropertyChangeListener currentThemeListener = new IPropertyChangeListener() {
062:
063: public void propertyChange(PropertyChangeEvent event) {
064: firePropertyChange(event);
065: if (event.getSource() instanceof FontRegistry) {
066: JFaceResources.getFontRegistry().put(
067: event.getProperty(),
068: (FontData[]) event.getNewValue());
069: } else if (event.getSource() instanceof ColorRegistry) {
070: JFaceResources.getColorRegistry().put(
071: event.getProperty(), (RGB) event.getNewValue());
072: }
073: }
074: };
075:
076: private ColorRegistry defaultThemeColorRegistry;
077:
078: private FontRegistry defaultThemeFontRegistry;
079:
080: private IThemeRegistry themeRegistry;
081:
082: private Map themes = new HashMap(7);
083:
084: /*
085: * Call dispose when we close
086: */
087: private WorkbenchThemeManager() {
088: defaultThemeColorRegistry = new ColorRegistry(PlatformUI
089: .getWorkbench().getDisplay());
090:
091: defaultThemeFontRegistry = new FontRegistry(PlatformUI
092: .getWorkbench().getDisplay());
093:
094: // copy the font values from preferences.
095: FontRegistry jfaceFonts = JFaceResources.getFontRegistry();
096: for (Iterator i = jfaceFonts.getKeySet().iterator(); i
097: .hasNext();) {
098: String key = (String) i.next();
099: defaultThemeFontRegistry.put(key, jfaceFonts
100: .getFontData(key));
101: }
102:
103: String themeId = IThemeManager.DEFAULT_THEME;
104: // Check if we are in high contrast mode. If so then set the theme to
105: // the system default
106: if (PlatformUI.getWorkbench().getDisplay() != null) {
107: // Determine the high contrast setting before
108: // any access to preferences
109: final boolean[] highContrast = new boolean[] { false };
110: PlatformUI.getWorkbench().getDisplay().syncExec(
111: new Runnable() {
112:
113: /*
114: * (non-Javadoc)
115: *
116: * @see java.lang.Runnable#run()
117: */
118: public void run() {
119: highContrast[0] = Display.getCurrent()
120: .getHighContrast();
121:
122: }
123: });
124: if (highContrast[0])
125: themeId = SYSTEM_DEFAULT_THEME;
126: }
127:
128: PrefUtil.getAPIPreferenceStore()
129: .setDefault(
130: IWorkbenchPreferenceConstants.CURRENT_THEME_ID,
131: themeId);
132: }
133:
134: /*
135: * (non-Javadoc)
136: *
137: * @see org.eclipse.ui.themes.IThemeManager#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
138: */
139: public void addPropertyChangeListener(
140: IPropertyChangeListener listener) {
141: addListenerObject(listener);
142: }
143:
144: /**
145: * Disposes all ThemeEntries.
146: */
147: public void dispose() {
148: for (Iterator i = themes.values().iterator(); i.hasNext();) {
149: ITheme theme = (ITheme) i.next();
150: theme.removePropertyChangeListener(currentThemeListener);
151: theme.dispose();
152: }
153: themes.clear();
154: }
155:
156: private boolean doSetCurrentTheme(String id) {
157: ITheme oldTheme = currentTheme;
158: ITheme newTheme = getTheme(id);
159: if (oldTheme != newTheme && newTheme != null) {
160: currentTheme = newTheme;
161: return true;
162: }
163:
164: return false;
165: }
166:
167: protected void firePropertyChange(PropertyChangeEvent event) {
168: Object[] listeners = getListeners();
169:
170: for (int i = 0; i < listeners.length; i++) {
171: ((IPropertyChangeListener) listeners[i])
172: .propertyChange(event);
173: }
174: }
175:
176: protected void firePropertyChange(String changeId, ITheme oldTheme,
177: ITheme newTheme) {
178:
179: PropertyChangeEvent event = new PropertyChangeEvent(this ,
180: changeId, oldTheme, newTheme);
181: firePropertyChange(event);
182: }
183:
184: /*
185: * (non-Javadoc)
186: *
187: * @see org.eclipse.ui.themes.IThemeManager#getCurrentTheme()
188: */
189: public ITheme getCurrentTheme() {
190: if (currentTheme == null) {
191: String themeId = PrefUtil
192: .getAPIPreferenceStore()
193: .getString(
194: IWorkbenchPreferenceConstants.CURRENT_THEME_ID);
195:
196: if (themeId == null) // missing preference
197: setCurrentTheme(IThemeManager.DEFAULT_THEME);
198: else {
199: setCurrentTheme(themeId);
200: if (currentTheme == null) { // still null - the preference
201: // didn't resolve to a proper theme
202: setCurrentTheme(IThemeManager.DEFAULT_THEME);
203: StatusManager
204: .getManager()
205: .handle(
206: StatusUtil
207: .newStatus(
208: PlatformUI.PLUGIN_ID,
209: "Could not restore current theme: " + themeId, null)); //$NON-NLS-1$
210: }
211: }
212: }
213: return currentTheme;
214: }
215:
216: /**
217: * Return the default color registry.
218: *
219: * @return the default color registry
220: */
221: public ColorRegistry getDefaultThemeColorRegistry() {
222: return defaultThemeColorRegistry;
223: }
224:
225: /**
226: * Return the default font registry.
227: *
228: * @return the default font registry
229: */
230: public FontRegistry getDefaultThemeFontRegistry() {
231: return defaultThemeFontRegistry;
232: }
233:
234: private ITheme getTheme(IThemeDescriptor td) {
235: ITheme theme = (ITheme) themes.get(td);
236: if (theme == null) {
237: theme = new Theme(td);
238: themes.put(td, theme);
239: }
240: return theme;
241: }
242:
243: /*
244: * (non-Javadoc)
245: *
246: * @see org.eclipse.ui.themes.IThemeManager#getTheme(java.lang.String)
247: */
248: public ITheme getTheme(String id) {
249: if (id.equals(IThemeManager.DEFAULT_THEME)) {
250: return getTheme((IThemeDescriptor) null);
251: }
252:
253: IThemeDescriptor td = getThemeRegistry().findTheme(id);
254: if (td == null) {
255: return null;
256: }
257: return getTheme(td);
258: }
259:
260: /**
261: * Answer the IThemeRegistry for the Workbench
262: */
263: private IThemeRegistry getThemeRegistry() {
264: if (themeRegistry == null) {
265: themeRegistry = WorkbenchPlugin.getDefault()
266: .getThemeRegistry();
267: }
268: return themeRegistry;
269: }
270:
271: /*
272: * (non-Javadoc)
273: *
274: * @see org.eclipse.ui.themes.IThemeManager#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
275: */
276: public void removePropertyChangeListener(
277: IPropertyChangeListener listener) {
278: removeListenerObject(listener);
279: }
280:
281: /*
282: * (non-Javadoc)
283: *
284: * @see org.eclipse.ui.themes.IThemeManager#setCurrentTheme(java.lang.String)
285: */
286: public void setCurrentTheme(String id) {
287: ITheme oldTheme = currentTheme;
288: if (WorkbenchThemeManager.getInstance().doSetCurrentTheme(id)) {
289: firePropertyChange(CHANGE_CURRENT_THEME, oldTheme,
290: getCurrentTheme());
291: if (oldTheme != null) {
292: oldTheme
293: .removePropertyChangeListener(currentThemeListener);
294: }
295: currentTheme
296: .addPropertyChangeListener(currentThemeListener);
297:
298: // update the preference if required.
299: if (!PrefUtil.getAPIPreferenceStore().getString(
300: IWorkbenchPreferenceConstants.CURRENT_THEME_ID)
301: .equals(id)) {
302: PrefUtil.getAPIPreferenceStore().setValue(
303: IWorkbenchPreferenceConstants.CURRENT_THEME_ID,
304: id);
305: PrefUtil.saveAPIPrefs();
306: }
307:
308: // update the jface registries
309: {
310: ColorRegistry jfaceColors = JFaceResources
311: .getColorRegistry();
312: ColorRegistry themeColors = currentTheme
313: .getColorRegistry();
314: for (Iterator i = themeColors.getKeySet().iterator(); i
315: .hasNext();) {
316: String key = (String) i.next();
317: jfaceColors.put(key, themeColors.getRGB(key));
318: }
319: }
320: {
321: FontRegistry jfaceFonts = JFaceResources
322: .getFontRegistry();
323: FontRegistry themeFonts = currentTheme
324: .getFontRegistry();
325: for (Iterator i = themeFonts.getKeySet().iterator(); i
326: .hasNext();) {
327: String key = (String) i.next();
328: jfaceFonts.put(key, themeFonts.getFontData(key));
329: }
330: }
331: }
332: }
333: }
|