001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 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.preferences;
011:
012: import java.io.IOException;
013:
014: import org.eclipse.core.commands.common.EventManager;
015: import org.eclipse.core.runtime.Assert;
016: import org.eclipse.core.runtime.Platform;
017: import org.eclipse.core.runtime.Plugin;
018: import org.eclipse.core.runtime.SafeRunner;
019: import org.eclipse.core.runtime.preferences.DefaultScope;
020: import org.eclipse.core.runtime.preferences.IEclipsePreferences;
021: import org.eclipse.core.runtime.preferences.IScopeContext;
022: import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener;
023: import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent;
024: import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
025: import org.eclipse.jface.preference.IPersistentPreferenceStore;
026: import org.eclipse.jface.preference.IPreferenceStore;
027: import org.eclipse.jface.resource.JFaceResources;
028: import org.eclipse.jface.util.IPropertyChangeListener;
029: import org.eclipse.jface.util.PropertyChangeEvent;
030: import org.eclipse.jface.util.SafeRunnable;
031: import org.eclipse.ui.internal.WorkbenchMessages;
032: import org.osgi.service.prefs.BackingStoreException;
033:
034: /**
035: * The ScopedPreferenceStore is an IPreferenceStore that uses the scopes
036: * provided in org.eclipse.core.runtime.preferences.
037: * <p>
038: * A ScopedPreferenceStore does the lookup of a preference based on it's search
039: * scopes and sets the value of the preference based on its store scope.
040: * </p>
041: * <p>
042: * The default scope is always included in the search scopes when searching for
043: * preference values.
044: * </p>
045: *
046: * @see org.eclipse.core.runtime.preferences
047: * @since 3.1
048: */
049: public class ScopedPreferenceStore extends EventManager implements
050: IPreferenceStore, IPersistentPreferenceStore {
051:
052: /**
053: * The storeContext is the context where values will stored with the
054: * setValue methods. If there are no searchContexts this will be the search
055: * context. (along with the "default" context)
056: */
057: private IScopeContext storeContext;
058:
059: /**
060: * The searchContext is the array of contexts that will be used by the get
061: * methods for searching for values.
062: */
063: private IScopeContext[] searchContexts;
064:
065: /**
066: * A boolean to indicate the property changes should not be propagated.
067: */
068: protected boolean silentRunning = false;
069:
070: /**
071: * The listener on the IEclipsePreferences. This is used to forward updates
072: * to the property change listeners on the preference store.
073: */
074: IEclipsePreferences.IPreferenceChangeListener preferencesListener;
075:
076: /**
077: * The default context is the context where getDefault and setDefault
078: * methods will search. This context is also used in the search.
079: */
080: private IScopeContext defaultContext = new DefaultScope();
081:
082: /**
083: * The nodeQualifer is the string used to look up the node in the contexts.
084: */
085: String nodeQualifier;
086:
087: /**
088: * The defaultQualifier is the string used to look up the default node.
089: */
090: String defaultQualifier;
091:
092: /**
093: * Boolean value indicating whether or not this store has changes to be
094: * saved.
095: */
096: private boolean dirty;
097:
098: /**
099: * Create a new instance of the receiver. Store the values in context in the
100: * node looked up by qualifier. <strong>NOTE:</strong> Any instance of
101: * ScopedPreferenceStore should call
102: *
103: * @param context
104: * the scope to store to
105: * @param qualifier
106: * the qualifier used to look up the preference node
107: * @param defaultQualifierPath
108: * the qualifier used when looking up the defaults
109: */
110: public ScopedPreferenceStore(IScopeContext context,
111: String qualifier, String defaultQualifierPath) {
112: this (context, qualifier);
113: this .defaultQualifier = defaultQualifierPath;
114: }
115:
116: /**
117: * Create a new instance of the receiver. Store the values in context in the
118: * node looked up by qualifier.
119: *
120: * @param context
121: * the scope to store to
122: * @param qualifier
123: * the qualifer used to look up the preference node
124: */
125: public ScopedPreferenceStore(IScopeContext context, String qualifier) {
126: storeContext = context;
127: this .nodeQualifier = qualifier;
128: this .defaultQualifier = qualifier;
129:
130: ((IEclipsePreferences) getStorePreferences().parent())
131: .addNodeChangeListener(getNodeChangeListener());
132: }
133:
134: /**
135: * Return a node change listener that adds a removes the receiver when nodes
136: * change.
137: *
138: * @return INodeChangeListener
139: */
140: private INodeChangeListener getNodeChangeListener() {
141: return new IEclipsePreferences.INodeChangeListener() {
142: /*
143: * (non-Javadoc)
144: *
145: * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#added(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent)
146: */
147: public void added(NodeChangeEvent event) {
148: if (nodeQualifier.equals(event.getChild().name())
149: && isListenerAttached()) {
150: getStorePreferences().addPreferenceChangeListener(
151: preferencesListener);
152: }
153: }
154:
155: /*
156: * (non-Javadoc)
157: *
158: * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#removed(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent)
159: */
160: public void removed(NodeChangeEvent event) {
161: // Do nothing as there are no events from removed node
162: }
163: };
164: }
165:
166: /**
167: * Initialize the preferences listener.
168: */
169: private void initializePreferencesListener() {
170: if (preferencesListener == null) {
171: preferencesListener = new IEclipsePreferences.IPreferenceChangeListener() {
172: /*
173: * (non-Javadoc)
174: *
175: * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent)
176: */
177: public void preferenceChange(PreferenceChangeEvent event) {
178:
179: if (silentRunning) {
180: return;
181: }
182:
183: Object oldValue = event.getOldValue();
184: Object newValue = event.getNewValue();
185: String key = event.getKey();
186: if (newValue == null) {
187: newValue = getDefault(key, oldValue);
188: } else if (oldValue == null) {
189: oldValue = getDefault(key, newValue);
190: }
191: firePropertyChangeEvent(event.getKey(), oldValue,
192: newValue);
193: }
194: };
195: getStorePreferences().addPreferenceChangeListener(
196: preferencesListener);
197: }
198:
199: }
200:
201: /**
202: * Does its best at determining the default value for the given key. Checks
203: * the given object's type and then looks in the list of defaults to see if
204: * a value exists. If not or if there is a problem converting the value, the
205: * default default value for that type is returned.
206: *
207: * @param key
208: * the key to search
209: * @param obj
210: * the object who default we are looking for
211: * @return Object or <code>null</code>
212: */
213: Object getDefault(String key, Object obj) {
214: IEclipsePreferences defaults = getDefaultPreferences();
215: if (obj instanceof String) {
216: return defaults.get(key, STRING_DEFAULT_DEFAULT);
217: } else if (obj instanceof Integer) {
218: return new Integer(defaults
219: .getInt(key, INT_DEFAULT_DEFAULT));
220: } else if (obj instanceof Double) {
221: return new Double(defaults.getDouble(key,
222: DOUBLE_DEFAULT_DEFAULT));
223: } else if (obj instanceof Float) {
224: return new Float(defaults.getFloat(key,
225: FLOAT_DEFAULT_DEFAULT));
226: } else if (obj instanceof Long) {
227: return new Long(defaults.getLong(key, LONG_DEFAULT_DEFAULT));
228: } else if (obj instanceof Boolean) {
229: return defaults.getBoolean(key, BOOLEAN_DEFAULT_DEFAULT) ? Boolean.TRUE
230: : Boolean.FALSE;
231: } else {
232: return null;
233: }
234: }
235:
236: /**
237: * Return the IEclipsePreferences node associated with this store.
238: *
239: * @return the preference node for this store
240: */
241: IEclipsePreferences getStorePreferences() {
242: return storeContext.getNode(nodeQualifier);
243: }
244:
245: /**
246: * Return the default IEclipsePreferences for this store.
247: *
248: * @return this store's default preference node
249: */
250: private IEclipsePreferences getDefaultPreferences() {
251: return defaultContext.getNode(defaultQualifier);
252: }
253:
254: /*
255: * (non-Javadoc)
256: *
257: * @see org.eclipse.jface.preference.IPreferenceStore#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
258: */
259: public void addPropertyChangeListener(
260: IPropertyChangeListener listener) {
261: initializePreferencesListener();// Create the preferences listener if it
262: // does not exist
263: addListenerObject(listener);
264: }
265:
266: /**
267: * Return the preference path to search preferences on. This is the list of
268: * preference nodes based on the scope contexts for this store. If there are
269: * no search contexts set, then return this store's context.
270: * <p>
271: * Whether or not the default context should be included in the resulting
272: * list is specified by the <code>includeDefault</code> parameter.
273: * </p>
274: *
275: * @param includeDefault
276: * <code>true</code> if the default context should be included
277: * and <code>false</code> otherwise
278: * @return IEclipsePreferences[]
279: */
280: private IEclipsePreferences[] getPreferenceNodes(
281: boolean includeDefault) {
282: // if the user didn't specify a search order, then return the scope that
283: // this store was created on. (and optionally the default)
284: if (searchContexts == null) {
285: if (includeDefault) {
286: return new IEclipsePreferences[] {
287: getStorePreferences(), getDefaultPreferences() };
288: }
289: return new IEclipsePreferences[] { getStorePreferences() };
290: }
291: // otherwise the user specified a search order so return the appropriate
292: // nodes based on it
293: int length = searchContexts.length;
294: if (includeDefault) {
295: length++;
296: }
297: IEclipsePreferences[] preferences = new IEclipsePreferences[length];
298: for (int i = 0; i < searchContexts.length; i++) {
299: preferences[i] = searchContexts[i].getNode(nodeQualifier);
300: }
301: if (includeDefault) {
302: preferences[length - 1] = getDefaultPreferences();
303: }
304: return preferences;
305: }
306:
307: /**
308: * Set the search contexts to scopes. When searching for a value the seach
309: * will be done in the order of scope contexts and will not search the
310: * storeContext unless it is in this list.
311: * <p>
312: * If the given list is <code>null</code>, then clear this store's search
313: * contexts. This means that only this store's scope context and default
314: * scope will be used during preference value searching.
315: * </p>
316: * <p>
317: * The defaultContext will be added to the end of this list automatically
318: * and <em>MUST NOT</em> be included by the user.
319: * </p>
320: *
321: * @param scopes
322: * a list of scope contexts to use when searching, or
323: * <code>null</code>
324: */
325: public void setSearchContexts(IScopeContext[] scopes) {
326: this .searchContexts = scopes;
327: if (scopes == null) {
328: return;
329: }
330:
331: // Assert that the default was not included (we automatically add it to
332: // the end)
333: for (int i = 0; i < scopes.length; i++) {
334: if (scopes[i].equals(defaultContext)) {
335: Assert
336: .isTrue(
337: false,
338: WorkbenchMessages.ScopedPreferenceStore_DefaultAddedError);
339: }
340: }
341: }
342:
343: /*
344: * (non-Javadoc)
345: *
346: * @see org.eclipse.jface.preference.IPreferenceStore#contains(java.lang.String)
347: */
348: public boolean contains(String name) {
349: if (name == null) {
350: return false;
351: }
352: return (Platform.getPreferencesService().get(name, null,
353: getPreferenceNodes(true))) != null;
354: }
355:
356: /*
357: * (non-Javadoc)
358: *
359: * @see org.eclipse.jface.preference.IPreferenceStore#firePropertyChangeEvent(java.lang.String,
360: * java.lang.Object, java.lang.Object)
361: */
362: public void firePropertyChangeEvent(String name, Object oldValue,
363: Object newValue) {
364: // important: create intermediate array to protect against listeners
365: // being added/removed during the notification
366: final Object[] list = getListeners();
367: if (list.length == 0) {
368: return;
369: }
370: final PropertyChangeEvent event = new PropertyChangeEvent(this ,
371: name, oldValue, newValue);
372: for (int i = 0; i < list.length; i++) {
373: final IPropertyChangeListener listener = (IPropertyChangeListener) list[i];
374: SafeRunner.run(new SafeRunnable(JFaceResources
375: .getString("PreferenceStore.changeError")) { //$NON-NLS-1$
376: public void run() {
377: listener.propertyChange(event);
378: }
379: });
380: }
381: }
382:
383: /*
384: * (non-Javadoc)
385: *
386: * @see org.eclipse.jface.preference.IPreferenceStore#getBoolean(java.lang.String)
387: */
388: public boolean getBoolean(String name) {
389: String value = internalGet(name);
390: return value == null ? BOOLEAN_DEFAULT_DEFAULT : Boolean
391: .valueOf(value).booleanValue();
392: }
393:
394: /*
395: * (non-Javadoc)
396: *
397: * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultBoolean(java.lang.String)
398: */
399: public boolean getDefaultBoolean(String name) {
400: return getDefaultPreferences().getBoolean(name,
401: BOOLEAN_DEFAULT_DEFAULT);
402: }
403:
404: /*
405: * (non-Javadoc)
406: *
407: * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultDouble(java.lang.String)
408: */
409: public double getDefaultDouble(String name) {
410: return getDefaultPreferences().getDouble(name,
411: DOUBLE_DEFAULT_DEFAULT);
412: }
413:
414: /*
415: * (non-Javadoc)
416: *
417: * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultFloat(java.lang.String)
418: */
419: public float getDefaultFloat(String name) {
420: return getDefaultPreferences().getFloat(name,
421: FLOAT_DEFAULT_DEFAULT);
422: }
423:
424: /*
425: * (non-Javadoc)
426: *
427: * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultInt(java.lang.String)
428: */
429: public int getDefaultInt(String name) {
430: return getDefaultPreferences()
431: .getInt(name, INT_DEFAULT_DEFAULT);
432: }
433:
434: /*
435: * (non-Javadoc)
436: *
437: * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultLong(java.lang.String)
438: */
439: public long getDefaultLong(String name) {
440: return getDefaultPreferences().getLong(name,
441: LONG_DEFAULT_DEFAULT);
442: }
443:
444: /*
445: * (non-Javadoc)
446: *
447: * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultString(java.lang.String)
448: */
449: public String getDefaultString(String name) {
450: return getDefaultPreferences()
451: .get(name, STRING_DEFAULT_DEFAULT);
452: }
453:
454: /*
455: * (non-Javadoc)
456: *
457: * @see org.eclipse.jface.preference.IPreferenceStore#getDouble(java.lang.String)
458: */
459: public double getDouble(String name) {
460: String value = internalGet(name);
461: if (value == null) {
462: return DOUBLE_DEFAULT_DEFAULT;
463: }
464: try {
465: return Double.parseDouble(value);
466: } catch (NumberFormatException e) {
467: return DOUBLE_DEFAULT_DEFAULT;
468: }
469: }
470:
471: /**
472: * Return the string value for the specified key. Look in the nodes which
473: * are specified by this object's list of search scopes. If the value does
474: * not exist then return <code>null</code>.
475: *
476: * @param key
477: * the key to search with
478: * @return String or <code>null</code> if the value does not exist.
479: */
480: private String internalGet(String key) {
481: return Platform.getPreferencesService().get(key, null,
482: getPreferenceNodes(true));
483: }
484:
485: /*
486: * (non-Javadoc)
487: *
488: * @see org.eclipse.jface.preference.IPreferenceStore#getFloat(java.lang.String)
489: */
490: public float getFloat(String name) {
491: String value = internalGet(name);
492: if (value == null) {
493: return FLOAT_DEFAULT_DEFAULT;
494: }
495: try {
496: return Float.parseFloat(value);
497: } catch (NumberFormatException e) {
498: return FLOAT_DEFAULT_DEFAULT;
499: }
500: }
501:
502: /*
503: * (non-Javadoc)
504: *
505: * @see org.eclipse.jface.preference.IPreferenceStore#getInt(java.lang.String)
506: */
507: public int getInt(String name) {
508: String value = internalGet(name);
509: if (value == null) {
510: return INT_DEFAULT_DEFAULT;
511: }
512: try {
513: return Integer.parseInt(value);
514: } catch (NumberFormatException e) {
515: return INT_DEFAULT_DEFAULT;
516: }
517: }
518:
519: /*
520: * (non-Javadoc)
521: *
522: * @see org.eclipse.jface.preference.IPreferenceStore#getLong(java.lang.String)
523: */
524: public long getLong(String name) {
525: String value = internalGet(name);
526: if (value == null) {
527: return LONG_DEFAULT_DEFAULT;
528: }
529: try {
530: return Long.parseLong(value);
531: } catch (NumberFormatException e) {
532: return LONG_DEFAULT_DEFAULT;
533: }
534: }
535:
536: /*
537: * (non-Javadoc)
538: *
539: * @see org.eclipse.jface.preference.IPreferenceStore#getString(java.lang.String)
540: */
541: public String getString(String name) {
542: String value = internalGet(name);
543: return value == null ? STRING_DEFAULT_DEFAULT : value;
544: }
545:
546: /*
547: * (non-Javadoc)
548: *
549: * @see org.eclipse.jface.preference.IPreferenceStore#isDefault(java.lang.String)
550: */
551: public boolean isDefault(String name) {
552: if (name == null) {
553: return false;
554: }
555: return (Platform.getPreferencesService().get(name, null,
556: getPreferenceNodes(false))) == null;
557: }
558:
559: /*
560: * (non-Javadoc)
561: *
562: * @see org.eclipse.jface.preference.IPreferenceStore#needsSaving()
563: */
564: public boolean needsSaving() {
565: return dirty;
566: }
567:
568: /*
569: * (non-Javadoc)
570: *
571: * @see org.eclipse.jface.preference.IPreferenceStore#putValue(java.lang.String,
572: * java.lang.String)
573: */
574: public void putValue(String name, String value) {
575: try {
576: // Do not notify listeners
577: silentRunning = true;
578: getStorePreferences().put(name, value);
579: } finally {
580: // Be sure that an exception does not stop property updates
581: silentRunning = false;
582: dirty = true;
583: }
584: }
585:
586: /*
587: * (non-Javadoc)
588: *
589: * @see org.eclipse.jface.preference.IPreferenceStore#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
590: */
591: public void removePropertyChangeListener(
592: IPropertyChangeListener listener) {
593: removeListenerObject(listener);
594: if (!isListenerAttached()) {
595: disposePreferenceStoreListener();
596: }
597: }
598:
599: /*
600: * (non-Javadoc)
601: *
602: * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
603: * double)
604: */
605: public void setDefault(String name, double value) {
606: getDefaultPreferences().putDouble(name, value);
607: }
608:
609: /*
610: * (non-Javadoc)
611: *
612: * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
613: * float)
614: */
615: public void setDefault(String name, float value) {
616: getDefaultPreferences().putFloat(name, value);
617: }
618:
619: /*
620: * (non-Javadoc)
621: *
622: * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
623: * int)
624: */
625: public void setDefault(String name, int value) {
626: getDefaultPreferences().putInt(name, value);
627: }
628:
629: /*
630: * (non-Javadoc)
631: *
632: * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
633: * long)
634: */
635: public void setDefault(String name, long value) {
636: getDefaultPreferences().putLong(name, value);
637: }
638:
639: /*
640: * (non-Javadoc)
641: *
642: * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
643: * java.lang.String)
644: */
645: public void setDefault(String name, String defaultObject) {
646: getDefaultPreferences().put(name, defaultObject);
647: }
648:
649: /*
650: * (non-Javadoc)
651: *
652: * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
653: * boolean)
654: */
655: public void setDefault(String name, boolean value) {
656: getDefaultPreferences().putBoolean(name, value);
657: }
658:
659: /*
660: * (non-Javadoc)
661: *
662: * @see org.eclipse.jface.preference.IPreferenceStore#setToDefault(java.lang.String)
663: */
664: public void setToDefault(String name) {
665:
666: String oldValue = getString(name);
667: String defaultValue = getDefaultString(name);
668: try {
669: silentRunning = true;// Turn off updates from the store
670: // removing a non-existing preference is a no-op so call the Core
671: // API directly
672: getStorePreferences().remove(name);
673: dirty = true;
674: firePropertyChangeEvent(name, oldValue, defaultValue);
675: } finally {
676: silentRunning = false;// Restart listening to preferences
677: }
678:
679: }
680:
681: /*
682: * (non-Javadoc)
683: *
684: * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
685: * double)
686: */
687: public void setValue(String name, double value) {
688: double oldValue = getDouble(name);
689: if (oldValue == value) {
690: return;
691: }
692: try {
693: silentRunning = true;// Turn off updates from the store
694: if (getDefaultDouble(name) == value) {
695: getStorePreferences().remove(name);
696: } else {
697: getStorePreferences().putDouble(name, value);
698: }
699: dirty = true;
700: firePropertyChangeEvent(name, new Double(oldValue),
701: new Double(value));
702: } finally {
703: silentRunning = false;// Restart listening to preferences
704: }
705: }
706:
707: /*
708: * (non-Javadoc)
709: *
710: * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
711: * float)
712: */
713: public void setValue(String name, float value) {
714: float oldValue = getFloat(name);
715: if (oldValue == value) {
716: return;
717: }
718: try {
719: silentRunning = true;// Turn off updates from the store
720: if (getDefaultFloat(name) == value) {
721: getStorePreferences().remove(name);
722: } else {
723: getStorePreferences().putFloat(name, value);
724: }
725: dirty = true;
726: firePropertyChangeEvent(name, new Float(oldValue),
727: new Float(value));
728: } finally {
729: silentRunning = false;// Restart listening to preferences
730: }
731: }
732:
733: /*
734: * (non-Javadoc)
735: *
736: * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
737: * int)
738: */
739: public void setValue(String name, int value) {
740: int oldValue = getInt(name);
741: if (oldValue == value) {
742: return;
743: }
744: try {
745: silentRunning = true;// Turn off updates from the store
746: if (getDefaultInt(name) == value) {
747: getStorePreferences().remove(name);
748: } else {
749: getStorePreferences().putInt(name, value);
750: }
751: dirty = true;
752: firePropertyChangeEvent(name, new Integer(oldValue),
753: new Integer(value));
754: } finally {
755: silentRunning = false;// Restart listening to preferences
756: }
757: }
758:
759: /*
760: * (non-Javadoc)
761: *
762: * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
763: * long)
764: */
765: public void setValue(String name, long value) {
766: long oldValue = getLong(name);
767: if (oldValue == value) {
768: return;
769: }
770: try {
771: silentRunning = true;// Turn off updates from the store
772: if (getDefaultLong(name) == value) {
773: getStorePreferences().remove(name);
774: } else {
775: getStorePreferences().putLong(name, value);
776: }
777: dirty = true;
778: firePropertyChangeEvent(name, new Long(oldValue), new Long(
779: value));
780: } finally {
781: silentRunning = false;// Restart listening to preferences
782: }
783: }
784:
785: /*
786: * (non-Javadoc)
787: *
788: * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
789: * java.lang.String)
790: */
791: public void setValue(String name, String value) {
792: // Do not turn on silent running here as Strings are propagated
793: if (getDefaultString(name).equals(value)) {
794: getStorePreferences().remove(name);
795: } else {
796: getStorePreferences().put(name, value);
797: }
798: dirty = true;
799: }
800:
801: /*
802: * (non-Javadoc)
803: *
804: * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
805: * boolean)
806: */
807: public void setValue(String name, boolean value) {
808: boolean oldValue = getBoolean(name);
809: if (oldValue == value) {
810: return;
811: }
812: try {
813: silentRunning = true;// Turn off updates from the store
814: if (getDefaultBoolean(name) == value) {
815: getStorePreferences().remove(name);
816: } else {
817: getStorePreferences().putBoolean(name, value);
818: }
819: dirty = true;
820: firePropertyChangeEvent(name, oldValue ? Boolean.TRUE
821: : Boolean.FALSE, value ? Boolean.TRUE
822: : Boolean.FALSE);
823: } finally {
824: silentRunning = false;// Restart listening to preferences
825: }
826: }
827:
828: /*
829: * (non-Javadoc)
830: *
831: * @see org.eclipse.jface.preference.IPersistentPreferenceStore#save()
832: */
833: public void save() throws IOException {
834: try {
835: getStorePreferences().flush();
836: dirty = false;
837: } catch (BackingStoreException e) {
838: throw new IOException(e.getMessage());
839: }
840:
841: }
842:
843: /**
844: * Dispose the receiver.
845: */
846: private void disposePreferenceStoreListener() {
847:
848: IEclipsePreferences root = (IEclipsePreferences) Platform
849: .getPreferencesService().getRootNode().node(
850: Plugin.PLUGIN_PREFERENCE_SCOPE);
851: try {
852: if (!(root.nodeExists(nodeQualifier))) {
853: return;
854: }
855: } catch (BackingStoreException e) {
856: return;// No need to report here as the node won't have the
857: // listener
858: }
859:
860: IEclipsePreferences preferences = getStorePreferences();
861: if (preferences == null) {
862: return;
863: }
864: if (preferencesListener != null) {
865: preferences
866: .removePreferenceChangeListener(preferencesListener);
867: preferencesListener = null;
868: }
869: }
870:
871: }
|