diff --git a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF index a627f5c1706..9d1691303ff 100644 --- a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF @@ -37,7 +37,8 @@ Export-Package: org.eclipse.jface, Require-Bundle: org.eclipse.swt;bundle-version="[3.126.0,4.0.0)";visibility:=reexport, org.eclipse.core.commands;bundle-version="[3.4.0,4.0.0)";visibility:=reexport, org.eclipse.equinox.common;bundle-version="[3.18.0,4.0.0)", - org.eclipse.equinox.bidi;bundle-version="[0.10.0,2.0.0)";resolution:=optional + org.eclipse.equinox.bidi;bundle-version="[0.10.0,2.0.0)";resolution:=optional, + org.eclipse.equinox.preferences;bundle-version="[3.12.100,4.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-21 Import-Package: javax.xml.parsers, org.osgi.framework;version="[1.8.0,2.0.0)", diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/messages.properties b/bundles/org.eclipse.jface/src/org/eclipse/jface/messages.properties index 18ec98f0fa2..2dbb4c71ffb 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/messages.properties +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/messages.properties @@ -236,3 +236,8 @@ ConfigureColumnsDialog_down = Dow&n # org.eclipse.jface.viewers.internal.ExpandableNode ExpandableNode.defaultLabel = Show next {0} items from remaining {1} ExpandableNode.showRemaining = Show remaining {0} item{1} + +############################################################# +# org.eclipse.jface.preference.ScopedPreferenceStore +############################################################# +ScopedPreferenceStore_DefaultAddedError=Do not add the default to the search contexts diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/ScopedPreferenceStore.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/ScopedPreferenceStore.java new file mode 100644 index 00000000000..163bead2967 --- /dev/null +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/ScopedPreferenceStore.java @@ -0,0 +1,674 @@ +/******************************************************************************* + * Copyright (c) 2004, 2026 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Yves YANG - + * Initial Fix for Bug 138078 [Preferences] Preferences Store for i18n support + *******************************************************************************/ +package org.eclipse.jface.preference; + +import java.io.IOException; +import java.util.Objects; + +import org.eclipse.core.commands.common.EventManager; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.SafeRunnable; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +/** + * The ScopedPreferenceStore is an IPreferenceStore that uses the scopes + * provided in org.eclipse.core.runtime.preferences. + *

+ * A ScopedPreferenceStore does the lookup of a preference based on it's search + * scopes and sets the value of the preference based on its store scope. + *

+ *

+ * The default scope is always included in the search scopes when searching for + * preference values. + *

+ * + * @see org.eclipse.core.runtime.preferences + * @since 3.40 + */ +public class ScopedPreferenceStore extends EventManager implements IPersistentPreferenceStore { + + /** + * The storeContext is the context where values will stored with the setValue + * methods. If there are no searchContexts this will be the search context. + * (along with the "default" context) + */ + private final IScopeContext storeContext; + + /** + * The searchContext is the array of contexts that will be used by the get + * methods for searching for values. + */ + private IScopeContext[] searchContexts; + + /** + * A boolean to indicate the property changes should not be propagated. + */ + protected boolean silentRunning = false; + + /** + * The listener on the IEclipsePreferences. This is used to forward updates to + * the property change listeners on the preference store. + */ + private EclipsePreferencesListener preferencesListener; + + /** + * The default context is the context where getDefault and setDefault methods + * will search. This context is also used in the search. + */ + private final IScopeContext defaultContext = DefaultScope.INSTANCE; + + /** + * The nodeQualifer is the string used to look up the node in the contexts. + */ + String nodeQualifier; + + /** + * The defaultQualifier is the string used to look up the default node. + */ + String defaultQualifier; + + /** + * Boolean value indicating whether or not this store has changes to be saved. + */ + private boolean dirty; + + /** + * Create a new instance of the receiver. Store the values in context in the + * node looked up by qualifier. NOTE: Any instance of + * ScopedPreferenceStore should call + * + * @param context the scope to store to + * @param qualifier the qualifier used to look up the preference node + * @param defaultQualifierPath the qualifier used when looking up the defaults + */ + public ScopedPreferenceStore(IScopeContext context, String qualifier, String defaultQualifierPath) { + this(context, qualifier); + this.defaultQualifier = defaultQualifierPath; + } + + /** + * Create a new instance of the receiver. Store the values in context in the + * node looked up by qualifier. + * + * @param context the scope to store to + * @param qualifier the qualifer used to look up the preference node + */ + public ScopedPreferenceStore(IScopeContext context, String qualifier) { + storeContext = context; + this.nodeQualifier = qualifier; + this.defaultQualifier = qualifier; + } + + /** + * Initialize the preferences listener. + */ + private void initializePreferencesListener() { + if (preferencesListener == null) { + preferencesListener = new EclipsePreferencesListener(this); + } + + } + + /** + * Does its best at determining the default value for the given key. Checks the + * given object's type and then looks in the list of defaults to see if a value + * exists. If not or if there is a problem converting the value, the default + * default value for that type is returned. + * + * @param key the key to search + * @param obj the object who default we are looking for + * @return Object or null + */ + Object getDefault(String key, Object obj) { + IEclipsePreferences defaults = getDefaultPreferences(); + if (obj instanceof String) { + return defaults.get(key, STRING_DEFAULT_DEFAULT); + } else if (obj instanceof Integer) { + return Integer.valueOf(defaults.getInt(key, INT_DEFAULT_DEFAULT)); + } else if (obj instanceof Double) { + return Double.valueOf(defaults.getDouble(key, DOUBLE_DEFAULT_DEFAULT)); + } else if (obj instanceof Float) { + return Float.valueOf(defaults.getFloat(key, FLOAT_DEFAULT_DEFAULT)); + } else if (obj instanceof Long) { + return Long.valueOf(defaults.getLong(key, LONG_DEFAULT_DEFAULT)); + } else if (obj instanceof Boolean) { + return defaults.getBoolean(key, BOOLEAN_DEFAULT_DEFAULT) ? Boolean.TRUE : Boolean.FALSE; + } else { + return null; + } + } + + /** + * Return the IEclipsePreferences node associated with this store. + * + * @return the preference node for this store + */ + IEclipsePreferences getStorePreferences() { + return storeContext.getNode(nodeQualifier); + } + + /** + * Return the default IEclipsePreferences for this store. + * + * @return this store's default preference node + */ + private IEclipsePreferences getDefaultPreferences() { + return defaultContext.getNode(defaultQualifier); + } + + @Override + public void addPropertyChangeListener(IPropertyChangeListener listener) { + initializePreferencesListener();// Create the preferences listener if it + // does not exist + addListenerObject(listener); + } + + /** + * Return the preference path to search preferences on. This is the list of + * preference nodes based on the scope contexts for this store. If there are no + * search contexts set, then return this store's context. + *

+ * Whether or not the default context should be included in the resulting list + * is specified by the includeDefault parameter. + *

+ * + * @param includeDefault true if the default context should be + * included and false otherwise + * @return IEclipsePreferences[] + * @since 3.4 public, was added in 3.1 as private method + */ + public IEclipsePreferences[] getPreferenceNodes(boolean includeDefault) { + // if the user didn't specify a search order, then return the scope that + // this store was created on. (and optionally the default) + if (searchContexts == null) { + if (includeDefault) { + return new IEclipsePreferences[] { getStorePreferences(), getDefaultPreferences() }; + } + return new IEclipsePreferences[] { getStorePreferences() }; + } + // otherwise the user specified a search order so return the appropriate + // nodes based on it + int length = searchContexts.length; + if (includeDefault) { + length++; + } + IEclipsePreferences[] preferences = new IEclipsePreferences[length]; + for (int i = 0; i < searchContexts.length; i++) { + preferences[i] = searchContexts[i].getNode(nodeQualifier); + } + if (includeDefault) { + preferences[length - 1] = getDefaultPreferences(); + } + return preferences; + } + + /** + * Set the search contexts to scopes. When searching for a value the seach will + * be done in the order of scope contexts and will not search the storeContext + * unless it is in this list. + *

+ * If the given list is null, then clear this store's search + * contexts. This means that only this store's scope context and default scope + * will be used during preference value searching. + *

+ *

+ * The defaultContext will be added to the end of this list automatically and + * MUST NOT be included by the user. + *

+ * + * @param scopes a list of scope contexts to use when searching, or + * null + */ + public void setSearchContexts(IScopeContext[] scopes) { + this.searchContexts = scopes; + if (scopes == null) { + return; + } + + // Assert that the default was not included (we automatically add it to + // the end) + for (IScopeContext scope : scopes) { + if (scope.equals(defaultContext)) { + Assert.isTrue(false, JFaceResources.getString("ScopedPreferenceStore_DefaultAddedError")); //$NON-NLS-1$ + } + } + } + + @Override + public boolean contains(String name) { + if (name == null) { + return false; + } + return internalGet(name, true) != null; + } + + @Override + public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) { + // important: create intermediate array to protect against listeners + // being added/removed during the notification + final Object[] listeners = getListeners(); + if (listeners.length == 0) { + return; + } + final PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue); + for (Object listener : listeners) { + final IPropertyChangeListener propertyChangeListener = (IPropertyChangeListener) listener; + SafeRunner.run(new SafeRunnable(JFaceResources.getString("PreferenceStore.changeError")) { //$NON-NLS-1$ + @Override + public void run() { + propertyChangeListener.propertyChange(event); + } + }); + } + } + + @Override + public boolean getBoolean(String name) { + String value = internalGet(name, true); + return value == null ? BOOLEAN_DEFAULT_DEFAULT : Boolean.parseBoolean(value); + } + + @Override + public boolean getDefaultBoolean(String name) { + return getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT); + } + + @Override + public double getDefaultDouble(String name) { + return getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT); + } + + @Override + public float getDefaultFloat(String name) { + return getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT); + } + + @Override + public int getDefaultInt(String name) { + return getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT); + } + + @Override + public long getDefaultLong(String name) { + return getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT); + } + + @Override + public String getDefaultString(String name) { + return getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT); + } + + @Override + public double getDouble(String name) { + String value = internalGet(name, true); + if (value == null) { + return DOUBLE_DEFAULT_DEFAULT; + } + try { + return Double.parseDouble(value); + } catch (NumberFormatException e) { + return DOUBLE_DEFAULT_DEFAULT; + } + } + + /** + * Return the string value for the specified key. Look in the nodes which are + * specified by this object's list of search scopes. If the value does not exist + * then return null. + * + * @param key the key to search with + * @param includeDefault {@code true} if the default context should be included + * and {@code true} otherwise + * @return String or null if the value does not exist. + */ + private String internalGet(String key, boolean includeDefault) { + for (Preferences node : getPreferenceNodes(includeDefault)) { + if (node != null) { + String result = node.get(key, null); + if (result != null) { + return result; + } + } + } + return null; + } + + @Override + public float getFloat(String name) { + String value = internalGet(name, true); + if (value == null) { + return FLOAT_DEFAULT_DEFAULT; + } + try { + return Float.parseFloat(value); + } catch (NumberFormatException e) { + return FLOAT_DEFAULT_DEFAULT; + } + } + + @Override + public int getInt(String name) { + String value = internalGet(name, true); + if (value == null) { + return INT_DEFAULT_DEFAULT; + } + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return INT_DEFAULT_DEFAULT; + } + } + + @Override + public long getLong(String name) { + String value = internalGet(name, true); + if (value == null) { + return LONG_DEFAULT_DEFAULT; + } + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + return LONG_DEFAULT_DEFAULT; + } + } + + @Override + public String getString(String name) { + String value = internalGet(name, true); + return value == null ? STRING_DEFAULT_DEFAULT : value; + } + + @Override + public boolean isDefault(String name) { + if (name == null) { + return false; + } + return internalGet(name, false) == null; + } + + @Override + public boolean needsSaving() { + return dirty; + } + + @Override + public void putValue(String name, String value) { + try { + // Do not notify listeners + silentRunning = true; + getStorePreferences().put(name, value); + } finally { + // Be sure that an exception does not stop property updates + silentRunning = false; + dirty = true; + } + } + + @Override + public void removePropertyChangeListener(IPropertyChangeListener listener) { + removeListenerObject(listener); + if (!isListenerAttached()) { + disposePreferenceStoreListener(); + } + } + + @Override + public void setDefault(String name, double value) { + getDefaultPreferences().putDouble(name, value); + } + + @Override + public void setDefault(String name, float value) { + getDefaultPreferences().putFloat(name, value); + } + + @Override + public void setDefault(String name, int value) { + getDefaultPreferences().putInt(name, value); + } + + @Override + public void setDefault(String name, long value) { + getDefaultPreferences().putLong(name, value); + } + + @Override + public void setDefault(String name, String defaultObject) { + getDefaultPreferences().put(name, defaultObject); + } + + @Override + public void setDefault(String name, boolean value) { + getDefaultPreferences().putBoolean(name, value); + } + + @Override + public void setToDefault(String name) { + + String oldValue = getString(name); + String defaultValue = getDefaultString(name); + try { + silentRunning = true;// Turn off updates from the store + // removing a non-existing preference is a no-op so call the Core + // API directly + getStorePreferences().remove(name); + if (!Objects.equals(oldValue, defaultValue)) { + dirty = true; + firePropertyChangeEvent(name, oldValue, defaultValue); + } + + } finally { + silentRunning = false;// Restart listening to preferences + } + + } + + @Override + public void setValue(String name, double value) { + double oldValue = getDouble(name); + if (oldValue == value) { + return; + } + try { + silentRunning = true;// Turn off updates from the store + if (getDefaultDouble(name) == value) { + getStorePreferences().remove(name); + } else { + getStorePreferences().putDouble(name, value); + } + dirty = true; + firePropertyChangeEvent(name, Double.valueOf(oldValue), Double.valueOf(value)); + } finally { + silentRunning = false;// Restart listening to preferences + } + } + + @Override + public void setValue(String name, float value) { + float oldValue = getFloat(name); + if (oldValue == value) { + return; + } + try { + silentRunning = true;// Turn off updates from the store + if (getDefaultFloat(name) == value) { + getStorePreferences().remove(name); + } else { + getStorePreferences().putFloat(name, value); + } + dirty = true; + firePropertyChangeEvent(name, Float.valueOf(oldValue), Float.valueOf(value)); + } finally { + silentRunning = false;// Restart listening to preferences + } + } + + @Override + public void setValue(String name, int value) { + int oldValue = getInt(name); + if (oldValue == value) { + return; + } + try { + silentRunning = true;// Turn off updates from the store + if (getDefaultInt(name) == value) { + getStorePreferences().remove(name); + } else { + getStorePreferences().putInt(name, value); + } + dirty = true; + firePropertyChangeEvent(name, Integer.valueOf(oldValue), Integer.valueOf(value)); + } finally { + silentRunning = false;// Restart listening to preferences + } + } + + @Override + public void setValue(String name, long value) { + long oldValue = getLong(name); + if (oldValue == value) { + return; + } + try { + silentRunning = true;// Turn off updates from the store + if (getDefaultLong(name) == value) { + getStorePreferences().remove(name); + } else { + getStorePreferences().putLong(name, value); + } + dirty = true; + firePropertyChangeEvent(name, Long.valueOf(oldValue), Long.valueOf(value)); + } finally { + silentRunning = false;// Restart listening to preferences + } + } + + @Override + public void setValue(String name, String value) { + // Do not turn on silent running here as Strings are propagated + if (getDefaultString(name).equals(value)) { + getStorePreferences().remove(name); + } else { + getStorePreferences().put(name, value); + } + dirty = true; + } + + @Override + public void setValue(String name, boolean value) { + boolean oldValue = getBoolean(name); + if (oldValue == value) { + return; + } + try { + silentRunning = true;// Turn off updates from the store + if (getDefaultBoolean(name) == value) { + getStorePreferences().remove(name); + } else { + getStorePreferences().putBoolean(name, value); + } + dirty = true; + firePropertyChangeEvent(name, oldValue ? Boolean.TRUE : Boolean.FALSE, + value ? Boolean.TRUE : Boolean.FALSE); + } finally { + silentRunning = false;// Restart listening to preferences + } + } + + @Override + public void save() throws IOException { + try { + getStorePreferences().flush(); + dirty = false; + } catch (BackingStoreException e) { + throw new IOException(e.getMessage()); + } + + } + + /** + * Dispose the receiver. + */ + private void disposePreferenceStoreListener() { + if (preferencesListener != null) { + preferencesListener.dispose(); + preferencesListener = null; + } + } + + private static final class EclipsePreferencesListener + implements IEclipsePreferences.IPreferenceChangeListener, INodeChangeListener { + + private final ScopedPreferenceStore store; + private final IEclipsePreferences preferences; + private final IEclipsePreferences parent; + + EclipsePreferencesListener(ScopedPreferenceStore store) { + this.store = store; + preferences = store.getStorePreferences(); + preferences.addPreferenceChangeListener(this); + parent = (IEclipsePreferences) preferences.parent(); + parent.addNodeChangeListener(this); + } + + void dispose() { + parent.removeNodeChangeListener(this); + preferences.removePreferenceChangeListener(this); + } + + @Override + public void preferenceChange(PreferenceChangeEvent event) { + if (store.silentRunning) { + return; + } + + Object oldValue = event.getOldValue(); + Object newValue = event.getNewValue(); + String key = event.getKey(); + if (newValue == null) { + newValue = store.getDefault(key, oldValue); + } else if (oldValue == null) { + oldValue = store.getDefault(key, newValue); + } + store.firePropertyChangeEvent(event.getKey(), oldValue, newValue); + } + + @Override + public void added(NodeChangeEvent event) { + if (store.nodeQualifier.equals(event.getChild().name())) { + store.getStorePreferences().addPreferenceChangeListener(this); + } + } + + @Override + public void removed(NodeChangeEvent event) { + // Do nothing as there are no events from removed node + } + + } + +} diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java index e279e37989e..caf1c2e5152 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java @@ -26,12 +26,12 @@ import org.eclipse.jface.preference.FontFieldEditor; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.texteditor.AbstractTextEditor; diff --git a/bundles/org.eclipse.ui.genericeditor/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.genericeditor/META-INF/MANIFEST.MF index cf09678b4e8..f28fe7c793b 100644 --- a/bundles/org.eclipse.ui.genericeditor/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.genericeditor/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.ui.genericeditor;singleton:=true -Bundle-Version: 1.4.100.qualifier +Bundle-Version: 1.4.200.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-21 Require-Bundle: org.eclipse.ui.workbench.texteditor;bundle-version="3.10.0", diff --git a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java index 489e806d8a4..2ecff02872d 100644 --- a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java +++ b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java @@ -25,6 +25,7 @@ import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -41,7 +42,6 @@ import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.internal.genericeditor.Messages; -import org.eclipse.ui.preferences.ScopedPreferenceStore; public class GenericEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { private final ArrayList leadFollowerListeners = new ArrayList<>(); diff --git a/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java b/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java index 23f25a15925..6ecf3ded110 100644 --- a/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java +++ b/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java @@ -52,6 +52,7 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.preference.IPersistentPreferenceStore; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.window.Window; import org.eclipse.osgi.service.datalocation.Location; import org.eclipse.osgi.util.NLS; @@ -76,7 +77,6 @@ import org.eclipse.ui.internal.ide.IDEInternalPreferences; import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.osgi.framework.Bundle; import org.osgi.framework.Version; diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java index c94640113d9..9ba3b607739 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java @@ -23,8 +23,8 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.ui.ide.IDE; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java index c3bc654590a..c37d677330d 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java @@ -42,6 +42,7 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.util.BidiUtils; import org.eclipse.osgi.util.NLS; @@ -67,7 +68,6 @@ import org.eclipse.ui.internal.ide.IIDEHelpContextIds; import org.eclipse.ui.internal.ide.LineDelimiterEditor; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.views.markers.internal.MarkerMessages; /** diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/WorkbenchChainedTextFontFieldEditor.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/WorkbenchChainedTextFontFieldEditor.java index 7d038f359ea..5ec7150beaf 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/WorkbenchChainedTextFontFieldEditor.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/WorkbenchChainedTextFontFieldEditor.java @@ -21,12 +21,11 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.PropagatingFontFieldEditor; -import org.eclipse.ui.preferences.ScopedPreferenceStore; - /** * This font field editor implements chaining between the workbench's preference diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/PlatformUI.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/PlatformUI.java index b176fb9147c..c80730105d2 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/PlatformUI.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/PlatformUI.java @@ -23,6 +23,7 @@ import org.eclipse.e4.ui.services.help.EHelpService; import org.eclipse.jface.dialogs.IDialogSettingsProvider; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.application.WorkbenchAdvisor; @@ -30,7 +31,6 @@ import org.eclipse.ui.internal.WorkbenchMessages; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.util.PrefUtil; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.testing.TestableObject; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java index cf676246aa7..469de885aeb 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java @@ -876,7 +876,6 @@ public class WorkbenchMessages extends NLS { public static String FilteredTree_FilteredDialogTitle; public static String FilteredTree_AccessibleListenerFiltered; public static String Workbench_startingPlugins; - public static String ScopedPreferenceStore_DefaultAddedError; public static String WorkbenchEncoding_invalidCharset; diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java index 92cb3e25d13..10da19bed2c 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java @@ -62,6 +62,7 @@ import org.eclipse.jface.preference.IPersistentPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelection; @@ -90,7 +91,6 @@ import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.themes.IThemeDescriptor; import org.eclipse.ui.internal.util.PrefUtil; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.themes.IThemeManager; import org.osgi.service.prefs.BackingStoreException; diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties index c7153c6b09a..8920f9043be 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties @@ -857,7 +857,6 @@ FilteredTree_FilterMessage=type filter text FilteredTree_FilteredDialogTitle={0} (Filtered) FilteredTree_AccessibleListenerFiltered={0} {1} matches. Workbench_startingPlugins = Starting plug-ins -ScopedPreferenceStore_DefaultAddedError=Do not add the default to the search contexts WorkbenchEncoding_invalidCharset = {0} is not a valid charset. diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/plugin/AbstractUIPlugin.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/plugin/AbstractUIPlugin.java index fa809e76b46..d891ce9c54a 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/plugin/AbstractUIPlugin.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/plugin/AbstractUIPlugin.java @@ -23,6 +23,7 @@ import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IDialogSettingsProvider; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.resource.ResourceLocator; @@ -34,7 +35,6 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WWinPluginAction; import org.eclipse.ui.internal.util.BundleUtility; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/preferences/ScopedPreferenceStore.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/preferences/ScopedPreferenceStore.java index 65ffaf9f820..e0d9d502bd0 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/preferences/ScopedPreferenceStore.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/preferences/ScopedPreferenceStore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2018 IBM Corporation and others. + * Copyright (c) 2004, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,26 +15,7 @@ *******************************************************************************/ package org.eclipse.ui.preferences; -import java.io.IOException; -import java.util.Objects; -import org.eclipse.core.commands.common.EventManager; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.preferences.DefaultScope; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener; -import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent; -import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.core.runtime.preferences.IScopeContext; -import org.eclipse.jface.preference.IPersistentPreferenceStore; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.internal.WorkbenchMessages; -import org.osgi.service.prefs.BackingStoreException; /** * The ScopedPreferenceStore is an IPreferenceStore that uses the scopes @@ -51,52 +32,7 @@ * @see org.eclipse.core.runtime.preferences * @since 3.1 */ -public class ScopedPreferenceStore extends EventManager implements IPreferenceStore, IPersistentPreferenceStore { - - /** - * The storeContext is the context where values will stored with the setValue - * methods. If there are no searchContexts this will be the search context. - * (along with the "default" context) - */ - private final IScopeContext storeContext; - - /** - * The searchContext is the array of contexts that will be used by the get - * methods for searching for values. - */ - private IScopeContext[] searchContexts; - - /** - * A boolean to indicate the property changes should not be propagated. - */ - protected boolean silentRunning = false; - - /** - * The listener on the IEclipsePreferences. This is used to forward updates to - * the property change listeners on the preference store. - */ - private EclipsePreferencesListener preferencesListener; - - /** - * The default context is the context where getDefault and setDefault methods - * will search. This context is also used in the search. - */ - private final IScopeContext defaultContext = DefaultScope.INSTANCE; - - /** - * The nodeQualifer is the string used to look up the node in the contexts. - */ - String nodeQualifier; - - /** - * The defaultQualifier is the string used to look up the default node. - */ - String defaultQualifier; - - /** - * Boolean value indicating whether or not this store has changes to be saved. - */ - private boolean dirty; +public class ScopedPreferenceStore extends org.eclipse.jface.preference.ScopedPreferenceStore { /** * Create a new instance of the receiver. Store the values in context in the @@ -108,8 +44,7 @@ public class ScopedPreferenceStore extends EventManager implements IPreferenceSt * @param defaultQualifierPath the qualifier used when looking up the defaults */ public ScopedPreferenceStore(IScopeContext context, String qualifier, String defaultQualifierPath) { - this(context, qualifier); - this.defaultQualifier = defaultQualifierPath; + super(context, qualifier, defaultQualifierPath); } /** @@ -120,547 +55,6 @@ public ScopedPreferenceStore(IScopeContext context, String qualifier, String def * @param qualifier the qualifer used to look up the preference node */ public ScopedPreferenceStore(IScopeContext context, String qualifier) { - storeContext = context; - this.nodeQualifier = qualifier; - this.defaultQualifier = qualifier; - } - - /** - * Initialize the preferences listener. - */ - private void initializePreferencesListener() { - if (preferencesListener == null) { - preferencesListener = new EclipsePreferencesListener(this); - } - - } - - /** - * Does its best at determining the default value for the given key. Checks the - * given object's type and then looks in the list of defaults to see if a value - * exists. If not or if there is a problem converting the value, the default - * default value for that type is returned. - * - * @param key the key to search - * @param obj the object who default we are looking for - * @return Object or null - */ - Object getDefault(String key, Object obj) { - IEclipsePreferences defaults = getDefaultPreferences(); - if (obj instanceof String) { - return defaults.get(key, STRING_DEFAULT_DEFAULT); - } else if (obj instanceof Integer) { - return Integer.valueOf(defaults.getInt(key, INT_DEFAULT_DEFAULT)); - } else if (obj instanceof Double) { - return Double.valueOf(defaults.getDouble(key, DOUBLE_DEFAULT_DEFAULT)); - } else if (obj instanceof Float) { - return Float.valueOf(defaults.getFloat(key, FLOAT_DEFAULT_DEFAULT)); - } else if (obj instanceof Long) { - return Long.valueOf(defaults.getLong(key, LONG_DEFAULT_DEFAULT)); - } else if (obj instanceof Boolean) { - return defaults.getBoolean(key, BOOLEAN_DEFAULT_DEFAULT) ? Boolean.TRUE : Boolean.FALSE; - } else { - return null; - } - } - - /** - * Return the IEclipsePreferences node associated with this store. - * - * @return the preference node for this store - */ - IEclipsePreferences getStorePreferences() { - return storeContext.getNode(nodeQualifier); - } - - /** - * Return the default IEclipsePreferences for this store. - * - * @return this store's default preference node - */ - private IEclipsePreferences getDefaultPreferences() { - return defaultContext.getNode(defaultQualifier); - } - - @Override - public void addPropertyChangeListener(IPropertyChangeListener listener) { - initializePreferencesListener();// Create the preferences listener if it - // does not exist - addListenerObject(listener); - } - - /** - * Return the preference path to search preferences on. This is the list of - * preference nodes based on the scope contexts for this store. If there are no - * search contexts set, then return this store's context. - *

- * Whether or not the default context should be included in the resulting list - * is specified by the includeDefault parameter. - *

- * - * @param includeDefault true if the default context should be - * included and false otherwise - * @return IEclipsePreferences[] - * @since 3.4 public, was added in 3.1 as private method - */ - public IEclipsePreferences[] getPreferenceNodes(boolean includeDefault) { - // if the user didn't specify a search order, then return the scope that - // this store was created on. (and optionally the default) - if (searchContexts == null) { - if (includeDefault) { - return new IEclipsePreferences[] { getStorePreferences(), getDefaultPreferences() }; - } - return new IEclipsePreferences[] { getStorePreferences() }; - } - // otherwise the user specified a search order so return the appropriate - // nodes based on it - int length = searchContexts.length; - if (includeDefault) { - length++; - } - IEclipsePreferences[] preferences = new IEclipsePreferences[length]; - for (int i = 0; i < searchContexts.length; i++) { - preferences[i] = searchContexts[i].getNode(nodeQualifier); - } - if (includeDefault) { - preferences[length - 1] = getDefaultPreferences(); - } - return preferences; - } - - /** - * Set the search contexts to scopes. When searching for a value the seach will - * be done in the order of scope contexts and will not search the storeContext - * unless it is in this list. - *

- * If the given list is null, then clear this store's search - * contexts. This means that only this store's scope context and default scope - * will be used during preference value searching. - *

- *

- * The defaultContext will be added to the end of this list automatically and - * MUST NOT be included by the user. - *

- * - * @param scopes a list of scope contexts to use when searching, or - * null - */ - public void setSearchContexts(IScopeContext[] scopes) { - this.searchContexts = scopes; - if (scopes == null) { - return; - } - - // Assert that the default was not included (we automatically add it to - // the end) - for (IScopeContext scope : scopes) { - if (scope.equals(defaultContext)) { - Assert.isTrue(false, WorkbenchMessages.ScopedPreferenceStore_DefaultAddedError); - } - } - } - - @Override - public boolean contains(String name) { - if (name == null) { - return false; - } - return (Platform.getPreferencesService().get(name, null, getPreferenceNodes(true))) != null; - } - - @Override - public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) { - // important: create intermediate array to protect against listeners - // being added/removed during the notification - final Object[] listeners = getListeners(); - if (listeners.length == 0) { - return; - } - final PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue); - for (Object listener : listeners) { - final IPropertyChangeListener propertyChangeListener = (IPropertyChangeListener) listener; - SafeRunner.run(new SafeRunnable(JFaceResources.getString("PreferenceStore.changeError")) { //$NON-NLS-1$ - @Override - public void run() { - propertyChangeListener.propertyChange(event); - } - }); - } - } - - @Override - public boolean getBoolean(String name) { - String value = internalGet(name); - return value == null ? BOOLEAN_DEFAULT_DEFAULT : Boolean.parseBoolean(value); - } - - @Override - public boolean getDefaultBoolean(String name) { - return getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT); - } - - @Override - public double getDefaultDouble(String name) { - return getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT); - } - - @Override - public float getDefaultFloat(String name) { - return getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT); - } - - @Override - public int getDefaultInt(String name) { - return getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT); - } - - @Override - public long getDefaultLong(String name) { - return getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT); + super(context, qualifier); } - - @Override - public String getDefaultString(String name) { - return getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT); - } - - @Override - public double getDouble(String name) { - String value = internalGet(name); - if (value == null) { - return DOUBLE_DEFAULT_DEFAULT; - } - try { - return Double.parseDouble(value); - } catch (NumberFormatException e) { - return DOUBLE_DEFAULT_DEFAULT; - } - } - - /** - * Return the string value for the specified key. Look in the nodes which are - * specified by this object's list of search scopes. If the value does not exist - * then return null. - * - * @param key the key to search with - * @return String or null if the value does not exist. - */ - private String internalGet(String key) { - return Platform.getPreferencesService().get(key, null, getPreferenceNodes(true)); - } - - @Override - public float getFloat(String name) { - String value = internalGet(name); - if (value == null) { - return FLOAT_DEFAULT_DEFAULT; - } - try { - return Float.parseFloat(value); - } catch (NumberFormatException e) { - return FLOAT_DEFAULT_DEFAULT; - } - } - - @Override - public int getInt(String name) { - String value = internalGet(name); - if (value == null) { - return INT_DEFAULT_DEFAULT; - } - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return INT_DEFAULT_DEFAULT; - } - } - - @Override - public long getLong(String name) { - String value = internalGet(name); - if (value == null) { - return LONG_DEFAULT_DEFAULT; - } - try { - return Long.parseLong(value); - } catch (NumberFormatException e) { - return LONG_DEFAULT_DEFAULT; - } - } - - @Override - public String getString(String name) { - String value = internalGet(name); - return value == null ? STRING_DEFAULT_DEFAULT : value; - } - - @Override - public boolean isDefault(String name) { - if (name == null) { - return false; - } - return (Platform.getPreferencesService().get(name, null, getPreferenceNodes(false))) == null; - } - - @Override - public boolean needsSaving() { - return dirty; - } - - @Override - public void putValue(String name, String value) { - try { - // Do not notify listeners - silentRunning = true; - getStorePreferences().put(name, value); - } finally { - // Be sure that an exception does not stop property updates - silentRunning = false; - dirty = true; - } - } - - @Override - public void removePropertyChangeListener(IPropertyChangeListener listener) { - removeListenerObject(listener); - if (!isListenerAttached()) { - disposePreferenceStoreListener(); - } - } - - @Override - public void setDefault(String name, double value) { - getDefaultPreferences().putDouble(name, value); - } - - @Override - public void setDefault(String name, float value) { - getDefaultPreferences().putFloat(name, value); - } - - @Override - public void setDefault(String name, int value) { - getDefaultPreferences().putInt(name, value); - } - - @Override - public void setDefault(String name, long value) { - getDefaultPreferences().putLong(name, value); - } - - @Override - public void setDefault(String name, String defaultObject) { - getDefaultPreferences().put(name, defaultObject); - } - - @Override - public void setDefault(String name, boolean value) { - getDefaultPreferences().putBoolean(name, value); - } - - @Override - public void setToDefault(String name) { - - String oldValue = getString(name); - String defaultValue = getDefaultString(name); - try { - silentRunning = true;// Turn off updates from the store - // removing a non-existing preference is a no-op so call the Core - // API directly - getStorePreferences().remove(name); - if (!Objects.equals(oldValue, defaultValue)) { - dirty = true; - firePropertyChangeEvent(name, oldValue, defaultValue); - } - - } finally { - silentRunning = false;// Restart listening to preferences - } - - } - - @Override - public void setValue(String name, double value) { - double oldValue = getDouble(name); - if (oldValue == value) { - return; - } - try { - silentRunning = true;// Turn off updates from the store - if (getDefaultDouble(name) == value) { - getStorePreferences().remove(name); - } else { - getStorePreferences().putDouble(name, value); - } - dirty = true; - firePropertyChangeEvent(name, Double.valueOf(oldValue), Double.valueOf(value)); - } finally { - silentRunning = false;// Restart listening to preferences - } - } - - @Override - public void setValue(String name, float value) { - float oldValue = getFloat(name); - if (oldValue == value) { - return; - } - try { - silentRunning = true;// Turn off updates from the store - if (getDefaultFloat(name) == value) { - getStorePreferences().remove(name); - } else { - getStorePreferences().putFloat(name, value); - } - dirty = true; - firePropertyChangeEvent(name, Float.valueOf(oldValue), Float.valueOf(value)); - } finally { - silentRunning = false;// Restart listening to preferences - } - } - - @Override - public void setValue(String name, int value) { - int oldValue = getInt(name); - if (oldValue == value) { - return; - } - try { - silentRunning = true;// Turn off updates from the store - if (getDefaultInt(name) == value) { - getStorePreferences().remove(name); - } else { - getStorePreferences().putInt(name, value); - } - dirty = true; - firePropertyChangeEvent(name, Integer.valueOf(oldValue), Integer.valueOf(value)); - } finally { - silentRunning = false;// Restart listening to preferences - } - } - - @Override - public void setValue(String name, long value) { - long oldValue = getLong(name); - if (oldValue == value) { - return; - } - try { - silentRunning = true;// Turn off updates from the store - if (getDefaultLong(name) == value) { - getStorePreferences().remove(name); - } else { - getStorePreferences().putLong(name, value); - } - dirty = true; - firePropertyChangeEvent(name, Long.valueOf(oldValue), Long.valueOf(value)); - } finally { - silentRunning = false;// Restart listening to preferences - } - } - - @Override - public void setValue(String name, String value) { - // Do not turn on silent running here as Strings are propagated - if (getDefaultString(name).equals(value)) { - getStorePreferences().remove(name); - } else { - getStorePreferences().put(name, value); - } - dirty = true; - } - - @Override - public void setValue(String name, boolean value) { - boolean oldValue = getBoolean(name); - if (oldValue == value) { - return; - } - try { - silentRunning = true;// Turn off updates from the store - if (getDefaultBoolean(name) == value) { - getStorePreferences().remove(name); - } else { - getStorePreferences().putBoolean(name, value); - } - dirty = true; - firePropertyChangeEvent(name, oldValue ? Boolean.TRUE : Boolean.FALSE, - value ? Boolean.TRUE : Boolean.FALSE); - } finally { - silentRunning = false;// Restart listening to preferences - } - } - - @Override - public void save() throws IOException { - try { - getStorePreferences().flush(); - dirty = false; - } catch (BackingStoreException e) { - throw new IOException(e.getMessage()); - } - - } - - /** - * Dispose the receiver. - */ - private void disposePreferenceStoreListener() { - if (preferencesListener != null) { - preferencesListener.dispose(); - preferencesListener = null; - } - } - - private static final class EclipsePreferencesListener - implements IEclipsePreferences.IPreferenceChangeListener, INodeChangeListener { - - private final ScopedPreferenceStore store; - private final IEclipsePreferences preferences; - private final IEclipsePreferences parent; - - EclipsePreferencesListener(ScopedPreferenceStore store) { - this.store = store; - preferences = store.getStorePreferences(); - preferences.addPreferenceChangeListener(this); - parent = (IEclipsePreferences) preferences.parent(); - parent.addNodeChangeListener(this); - } - - void dispose() { - parent.removeNodeChangeListener(this); - preferences.removePreferenceChangeListener(this); - } - - @Override - public void preferenceChange(PreferenceChangeEvent event) { - if (store.silentRunning) { - return; - } - - Object oldValue = event.getOldValue(); - Object newValue = event.getNewValue(); - String key = event.getKey(); - if (newValue == null) { - newValue = store.getDefault(key, oldValue); - } else if (oldValue == null) { - oldValue = store.getDefault(key, newValue); - } - store.firePropertyChangeEvent(event.getKey(), oldValue, newValue); - } - - @Override - public void added(NodeChangeEvent event) { - if (store.nodeQualifier.equals(event.getChild().name())) { - store.getStorePreferences().addPreferenceChangeListener(this); - } - } - - @Override - public void removed(NodeChangeEvent event) { - // Do nothing as there are no events from removed node - } - - } - } diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/AllPrefsTests.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/AllPrefsTests.java index 770e8dae7f8..ec92176a038 100644 --- a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/AllPrefsTests.java +++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/AllPrefsTests.java @@ -21,7 +21,8 @@ BooleanFieldEditorTest.class, // StringFieldEditorTest.class, // IntegerFieldEditorTest.class, // - ScaleFieldEditorTest.class // + ScaleFieldEditorTest.class, // + ScopedPreferenceStoreTest.class // }) public class AllPrefsTests { diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/ScopedPreferenceStoreTestCase.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/ScopedPreferenceStoreTest.java similarity index 63% rename from tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/ScopedPreferenceStoreTestCase.java rename to tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/ScopedPreferenceStoreTest.java index 1019f5c3afa..dbcb49a8c2d 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/ScopedPreferenceStoreTestCase.java +++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/preferences/ScopedPreferenceStoreTest.java @@ -11,22 +11,22 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.ui.tests.preferences; +package org.eclipse.jface.tests.preferences; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.ScopedPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.ui.preferences.ScopedPreferenceStore; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ScopedPreferenceStoreTestCase { +public class ScopedPreferenceStoreTest { final String DEFAULT_DEFAULT_STRING = ""; @@ -34,35 +34,34 @@ public class ScopedPreferenceStoreTestCase { public void testNeedsSaving() throws IOException { IScopeContext context = InstanceScope.INSTANCE; String qualifier = "org.eclipse.ui.tests.preferences"; - ScopedPreferenceStore store = new ScopedPreferenceStore(context, - qualifier); + ScopedPreferenceStore store = new ScopedPreferenceStore(context, qualifier); String key = "key1"; String value = "value1"; // nothing there - assertFalse("0.1", store.needsSaving()); - assertFalse("0.2", store.contains(key)); - assertEquals("0.3", DEFAULT_DEFAULT_STRING, store.getString(key)); + assertFalse(store.needsSaving(), "0.1"); + assertFalse(store.contains(key), "0.2"); + assertEquals(DEFAULT_DEFAULT_STRING, store.getString(key), "0.3"); // set the value store.setValue(key, value); - assertTrue("1.0", store.needsSaving()); - assertTrue("1.1", store.contains(key)); - assertEquals("1.2", value, store.getString(key)); + assertTrue(store.needsSaving(), "1.0"); + assertTrue(store.contains(key), "1.1"); + assertEquals(value, store.getString(key), "1.2"); // flush store.save(); // do the test - assertFalse("3.0", store.needsSaving()); + assertFalse(store.needsSaving(), "3.0"); // change the node outside of the scoped store String key2 = "key2"; String value2 = "value2"; IEclipsePreferences node = context.getNode(qualifier); node.put(key2, value2); - assertEquals("4.0", value2, node.get(key2, null)); - assertFalse("4.1", store.needsSaving()); + assertEquals(value2, node.get(key2, null), "4.0"); + assertFalse(store.needsSaving(), "4.1"); } @Test @@ -74,16 +73,16 @@ public void testRestoreDefaults() { final String value = "value"; // setup and initial assertions - assertFalse("0.1", store.contains(key)); - assertEquals("0.2", DEFAULT_DEFAULT_STRING, store.getString(key)); + assertFalse(store.contains(key), "0.1"); + assertEquals(DEFAULT_DEFAULT_STRING, store.getString(key), "0.2"); // set the value store.setValue(key, value); - assertTrue("1.0", store.contains(key)); - assertEquals("1.1", value, store.getString(key)); + assertTrue(store.contains(key), "1.0"); + assertEquals(value, store.getString(key), "1.1"); final boolean[] found = new boolean[1]; - IPropertyChangeListener listener= event -> { + IPropertyChangeListener listener = event -> { if (key.equals(event.getProperty()) && value.equals(event.getOldValue())) { found[0] = true; } @@ -92,11 +91,11 @@ public void testRestoreDefaults() { // restore the default store.setToDefault(key); - assertFalse("2.0", store.contains(key)); - assertEquals("2.1", DEFAULT_DEFAULT_STRING, store.getString(key)); + assertFalse(store.contains(key), "2.0"); + assertEquals(DEFAULT_DEFAULT_STRING, store.getString(key), "2.1"); // check it - assertTrue("3.0", found[0]); -} + assertTrue(found[0], "3.0"); + } } diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/PreferencesTestSuite.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/PreferencesTestSuite.java index a6526ee5d33..0e2a768597f 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/PreferencesTestSuite.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/preferences/PreferencesTestSuite.java @@ -27,7 +27,6 @@ @SelectClasses({ FontPreferenceTestCase.class, DeprecatedFontPreferenceTestCase.class, - ScopedPreferenceStoreTestCase.class, WorkingCopyPreferencesTestCase.class, PropertyPageEnablementTest.class, ListenerRemovalTestCase.class,