Permalink
Browse files

Reworking the preference system.

Parts of the old system, with the preference store overlay, are still in use.
The new system is cleaner, simpler, and easier to use and extend.
  • Loading branch information...
1 parent 3a300a2 commit 8d0358fd7fd4036f7fe33670743cf177d869c2e7 @ttencate ttencate committed Jun 22, 2009
@@ -0,0 +1,109 @@
+package net.sf.eclipsefp.common.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.osgi.service.prefs.BackingStoreException;
+
+public abstract class AbstractPreferencePage extends PreferencePage
+implements IWorkbenchPreferencePage {
+
+ /**
+ * List of all preference controls managed by this object.
+ */
+ private final List<PreferenceControl> controls = new ArrayList<PreferenceControl>();
+
+ public AbstractPreferencePage() {
+ super();
+ }
+
+ public AbstractPreferencePage(final String title) {
+ super(title);
+ }
+
+ public AbstractPreferencePage(final String title, final ImageDescriptor image) {
+ super(title, image);
+ }
+
+ public void init(final IWorkbench workbench) {
+ // do nothing; subclasses may override
+ }
+
+ /**
+ * Loads the values of all {@link PreferenceControl}s on this page.
+ */
+ public void loadControlValues() {
+ IPreferenceStore prefStore = getPreferenceStore();
+ for (PreferenceControl control : controls) {
+ control.load(prefStore);
+ }
+ }
+
+ /**
+ * Stores preferences from the controls created by the createXxx methods
+ * into the preference store returned by {@link #getPreferenceStore},
+ * then saves the preference store.
+ *
+ * @return true if saving succeeded
+ */
+ @Override
+ public boolean performOk() {
+ IPreferenceStore prefStore = getPreferenceStore();
+ for (PreferenceControl control : controls) {
+ control.store(prefStore);
+ }
+ try {
+ new InstanceScope().getNode(HaskellUIPlugin.getPluginId()).flush();
+ } catch (BackingStoreException ex) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Loads the default values into the controls.
+ */
+ @Override
+ public void performDefaults() {
+ IPreferenceStore prefStore = getPreferenceStore();
+ for (PreferenceControl control : controls) {
+ control.loadDefault(prefStore);
+ }
+ }
+
+ protected Label createLabel(final Composite parent, final String text) {
+ Label label = new Label(parent, SWT.LEFT);
+ label.setText(text);
+ return label;
+ }
+
+ protected CheckboxPreferenceControl createCheckboxControl(final Composite parent, final String text, final String name) {
+ CheckboxPreferenceControl control = new CheckboxPreferenceControl(parent, text, name);
+ controls.add(control);
+ return control;
+ }
+
+ protected StringPreferenceControl createStringControl(final Composite parent, final String label, final String name, final int maxLength) {
+ StringPreferenceControl control = new StringPreferenceControl(parent, label, name, maxLength);
+ controls.add(control);
+ return control;
+ }
+
+ protected IntegerPreferenceControl createIntegerControl(final Composite parent, final String label, final String name, final int maxLength) {
+ IntegerPreferenceControl control = new IntegerPreferenceControl(parent, label, name, maxLength);
+ controls.add(control);
+ return control;
+ }
+
+}
@@ -0,0 +1,71 @@
+package net.sf.eclipsefp.common.ui.preferences;
+
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public class CheckboxPreferenceControl extends PreferenceControl<Boolean> {
+
+ private final Button checkbox;
+
+ public CheckboxPreferenceControl(final Composite parent, final String text, final String name) {
+ super(name);
+
+ checkbox = new Button(parent, SWT.CHECK);
+ checkbox.setText(text);
+
+ checkbox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ fireValueChanged();
+ }
+ });
+ }
+
+ @Override
+ protected Boolean doLoad(final IPreferenceStore prefStore) {
+ return new Boolean(prefStore.getBoolean(getName()));
+ }
+
+ @Override
+ protected Boolean doLoadDefault(final IPreferenceStore prefStore) {
+ return new Boolean(prefStore.getDefaultBoolean(getName()));
+ }
+
+ @Override
+ protected void doStore(final IPreferenceStore prefStore, final Boolean value) {
+ prefStore.setValue(getName(), value.booleanValue());
+ }
+
+ @Override
+ public Control getControl() {
+ return checkbox;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return checkbox.isEnabled();
+ }
+
+ @Override
+ public void setEnabled(final boolean enabled) {
+ checkbox.setEnabled(enabled);
+ }
+
+ @Override
+ public Boolean getValue() {
+ return new Boolean(checkbox.getSelection());
+ }
+
+ @Override
+ public void setValue(final Boolean value) {
+ checkbox.setSelection(value.booleanValue());
+ fireValueChanged();
+ }
+
+}
@@ -0,0 +1,12 @@
+package net.sf.eclipsefp.common.ui.preferences;
+
+/**
+ * A listener that listens for changes in the value of a preference control.
+ *
+ * @author Thomas ten Cate
+ */
+public interface IValueChangedListener<T> {
+
+ public void valueChanged(PreferenceControl<T> control, T value);
+
+}
@@ -0,0 +1,55 @@
+package net.sf.eclipsefp.common.ui.preferences;
+
+import net.sf.eclipsefp.common.ui.util.DialogUtil;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+
+public class IntegerPreferenceControl extends TextPreferenceControl<Integer> {
+
+ public IntegerPreferenceControl(final Composite parent, final String labelText,
+ final String name, final int maxLength) {
+ super(parent, labelText, name);
+
+ if (maxLength > 0) {
+ text.setTextLimit(maxLength);
+ GridData gd = new GridData();
+ gd.widthHint = DialogUtil.convertWidthInCharsToPixels(text, maxLength + 1);
+ text.setLayoutData(gd);
+ }
+ }
+
+ @Override
+ protected int getTextStyle() {
+ return super.getTextStyle() | SWT.RIGHT;
+ }
+
+ @Override
+ protected Integer doLoad(final IPreferenceStore prefStore) {
+ return new Integer(prefStore.getInt(getName()));
+ }
+
+ @Override
+ protected Integer doLoadDefault(final IPreferenceStore prefStore) {
+ return new Integer(prefStore.getDefaultInt(getName()));
+ }
+
+ @Override
+ protected void doStore(final IPreferenceStore prefStore, final Integer value) {
+ prefStore.setValue(getName(), value.intValue());
+ }
+
+ @Override
+ public Integer getValue() {
+ return new Integer(text.getText());
+ }
+
+ @Override
+ public void setValue(final Integer value) {
+ text.setText(value.toString());
+ fireValueChanged();
+ }
+
+}
@@ -0,0 +1,130 @@
+package net.sf.eclipsefp.common.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A control that represents a preference on a preference page.
+ *
+ * @author Thomas ten Cate
+ */
+public abstract class PreferenceControl<T> {
+
+ private List<IValueChangedListener<T>> valueChangedListeners = null;
+ private final String name;
+
+ protected PreferenceControl(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of the associated preference.
+ */
+ protected String getName() {
+ return name;
+ }
+
+ /**
+ * Loads the value from the preference store into the control.
+ */
+ public void load(final IPreferenceStore prefStore) {
+ setValue(doLoad(prefStore));
+ }
+
+ /**
+ * Loads the default value from the preference store into the control.
+ */
+ public void loadDefault(final IPreferenceStore prefStore) {
+ setValue(doLoadDefault(prefStore));
+ }
+
+ /**
+ * Saves the value from the control into the preference store.
+ */
+ public void store(final IPreferenceStore prefStore) {
+ doStore(prefStore, getValue());
+ }
+
+ /**
+ * Loads the value from the given preference store, and returns it.
+ * Does not change the actual value in the control.
+ */
+ protected abstract T doLoad(IPreferenceStore prefStore);
+
+ /**
+ * Loads the default value from the given preference store, and returns it.
+ * Does not change the actual value in the control.
+ */
+ protected abstract T doLoadDefault(IPreferenceStore prefStore);
+
+ /**
+ * Saves the given value to the given preference store.
+ * Does not read the actual value from the control.
+ */
+ protected abstract void doStore(IPreferenceStore prefStore, T value);
+
+ /**
+ * Returns the control implementing this preference.
+ */
+ public abstract Control getControl();
+
+ /**
+ * Returns whether the control is currently enabled.
+ */
+ public abstract boolean isEnabled();
+
+ /**
+ * Sets the enablement of the control.
+ */
+ public abstract void setEnabled(boolean enabled);
+
+ /**
+ * Returns the current value of this control.
+ */
+ public abstract T getValue();
+
+ /**
+ * Sets a new value for the control.
+ * Subclasses should probably cal {@link #fireValueChanged()} from their implementations.
+ */
+ public abstract void setValue(T value);
+
+ /**
+ * Adds a new listener that will be notified after the value of this
+ * control has changed.
+ * @param init If true, an event will be fired immediately to the new listener.
+ */
+ public void addValueChangedListener(final IValueChangedListener<T> listener, final boolean init) {
+ if (valueChangedListeners == null) {
+ valueChangedListeners = new ArrayList<IValueChangedListener<T>>();
+ }
+ valueChangedListeners.add(listener);
+ if (init) {
+ listener.valueChanged(this, getValue());
+ }
+ }
+
+ /**
+ * Removes a value-changed listener.
+ */
+ public void removeValueChangedListener(final IValueChangedListener listener) {
+ if (valueChangedListeners != null) {
+ valueChangedListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Fires a value-changed event.
+ */
+ protected void fireValueChanged() {
+ if (valueChangedListeners != null) {
+ for (IValueChangedListener<T> listener : valueChangedListeners) {
+ listener.valueChanged(this, getValue());
+ }
+ }
+ }
+
+}
Oops, something went wrong.

0 comments on commit 8d0358f

Please sign in to comment.