summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Drossel2009-04-22 09:57:36 (EDT)
committerCarsten Drossel2009-04-22 09:57:36 (EDT)
commit3cc908a42edf254da3f9a55f76211c6b90764cee (patch)
tree6dbdeab7ab08a8f51fbf646e0ce5effdac9c4ef8
parentcf523787d8bedb728671f7234589e4d8b6edb7ec (diff)
downloadorg.eclipse.riena-3cc908a42edf254da3f9a55f76211c6b90764cee.zip
org.eclipse.riena-3cc908a42edf254da3f9a55f76211c6b90764cee.tar.gz
org.eclipse.riena-3cc908a42edf254da3f9a55f76211c6b90764cee.tar.bz2
extracted SWT-control independent superclasses of Ridgets to allow reuse by Ridgets for custom controls
-rw-r--r--org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/ComboRidget.java434
-rw-r--r--org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/LabelRidget.java141
-rw-r--r--org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractComboRidget.java484
-rw-r--r--org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractLabelRidget.java175
4 files changed, 691 insertions, 543 deletions
diff --git a/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/ComboRidget.java b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/ComboRidget.java
index d6394e3..31bb92c 100644
--- a/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/ComboRidget.java
+++ b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/ComboRidget.java
@@ -10,118 +10,20 @@
*******************************************************************************/
package org.eclipse.riena.internal.ui.ridgets.swt;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.BindingException;
-import org.eclipse.core.databinding.DataBindingContext;
-import org.eclipse.core.databinding.UpdateListStrategy;
-import org.eclipse.core.databinding.UpdateValueStrategy;
-import org.eclipse.core.databinding.beans.BeansObservables;
-import org.eclipse.core.databinding.beans.PojoObservables;
-import org.eclipse.core.databinding.conversion.Converter;
import org.eclipse.core.databinding.observable.list.IObservableList;
-import org.eclipse.core.databinding.observable.list.WritableList;
-import org.eclipse.core.databinding.observable.value.IObservableValue;
-import org.eclipse.core.databinding.observable.value.IValueChangeListener;
-import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
-import org.eclipse.core.databinding.observable.value.WritableValue;
-import org.eclipse.core.databinding.validation.IValidator;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Combo;
-import org.eclipse.riena.core.util.ReflectionUtils;
-import org.eclipse.riena.ui.common.IComboEntryFactory;
-import org.eclipse.riena.ui.ridgets.IComboRidget;
-import org.eclipse.riena.ui.ridgets.IMarkableRidget;
-import org.eclipse.riena.ui.ridgets.IRidget;
+import org.eclipse.riena.ui.ridgets.swt.AbstractComboRidget;
import org.eclipse.riena.ui.ridgets.swt.AbstractSWTRidget;
-import org.eclipse.riena.ui.ridgets.swt.AbstractSWTWidgetRidget;
/**
* Ridget for {@link Combo} widgets.
*/
-public class ComboRidget extends AbstractSWTRidget implements IComboRidget {
-
- /** List of choices (Objects). */
- private final IObservableList rowObservables;
- /** An observable with the current selection. */
- private final IObservableValue selectionObservable;
- /**
- * Converts from objects (rowObsservables) to strings (Combo) using the
- * renderingMethod.
- */
- private final Converter objToStrConverter;
- /** Convers from strings (Combo) to objects (rowObservables). */
- private final Converter strToObjConverter;
- /** Selection validator that allows or cancels a selection request. */
- private final SelectionBindingValidator selectionValidator;
- /** IValueChangeListener that allows or cancels a value change */
- private final IValueChangeListener valueChangeValidator;
-
- /** If this item is selected, treat it as if nothing is selected */
- private Object emptySelection;
-
- /** List observable bean (model) */
- private IObservableList rowObservablesModel;
- /** Selection observable bean (model) */
- private IObservableValue selectionObservableModel;
- /** A string used for converting from Object to String */
- private String renderingMethod;
-
- /**
- * Binding between the list of choices in the combo and the rowObservables.
- * May be null, when there is no control or model.
- */
- private Binding listBindingInternal;
- /**
- * Binding between the rowObservables and the list of choices from the
- * model. May be null, when there is no model.
- */
- private Binding listBindingExternal;
- /**
- * Binding between the selection in the combo and the selectionObservable.
- * May be null, when there is no control or model.
- */
- private Binding selectionBindingInternal;
- /**
- * Binding between the selectionObservable and the selection in the model.
- * May be null, when there is no model.
- */
- private Binding selectionBindingExternal;
-
- public ComboRidget() {
- super();
- rowObservables = new WritableList();
- selectionObservable = new WritableValue();
- selectionObservable.addValueChangeListener(new IValueChangeListener() {
- public void handleValueChange(ValueChangeEvent event) {
- Object oldValue = event.diff.getOldValue();
- Object newValue = event.diff.getNewValue();
- firePropertyChange(IComboRidget.PROPERTY_SELECTION, oldValue, newValue);
- disableMandatoryMarkers(hasInput());
- }
- });
- objToStrConverter = new ObjectToStringConverter();
- strToObjConverter = new StringToObjectConverter();
- selectionValidator = new SelectionBindingValidator();
- valueChangeValidator = new ValueChangeValidator();
- addPropertyChangeListener(IRidget.PROPERTY_ENABLED, new PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent evt) {
- applyEnabled();
- }
- });
- }
-
- @Override
- public Combo getUIControl() {
- return (Combo) super.getUIControl();
- }
+public class ComboRidget extends AbstractComboRidget {
@Override
protected void checkUIControl(Object uiControl) {
@@ -135,334 +37,42 @@ public class ComboRidget extends AbstractSWTRidget implements IComboRidget {
}
@Override
- protected void bindUIControl() {
- Combo control = getUIControl();
- if (rowObservablesModel != null) {
- // These bindings are only necessary when we have a model
- DataBindingContext dbc = new DataBindingContext();
- if (control != null) {
- // These bindings are only necessary when we have a Combo
- listBindingInternal = dbc.bindList(SWTObservables.observeItems(control), rowObservables,
- new UpdateListStrategy(UpdateListStrategy.POLICY_ON_REQUEST).setConverter(strToObjConverter),
- new UpdateListStrategy(UpdateValueStrategy.POLICY_ON_REQUEST).setConverter(objToStrConverter));
- listBindingInternal.updateModelToTarget();
- applyEnabled();
- }
- listBindingExternal = dbc
- .bindList(rowObservables, rowObservablesModel, new UpdateListStrategy(
- UpdateListStrategy.POLICY_ON_REQUEST), new UpdateListStrategy(
- UpdateListStrategy.POLICY_ON_REQUEST));
- selectionBindingExternal = dbc
- .bindValue(selectionObservable, selectionObservableModel, new UpdateValueStrategy(
- UpdateValueStrategy.POLICY_UPDATE).setAfterGetValidator(selectionValidator),
- new UpdateValueStrategy(UpdateValueStrategy.POLICY_ON_REQUEST));
-
- }
+ public Combo getUIControl() {
+ return (Combo) super.getUIControl();
}
@Override
- protected void unbindUIControl() {
- super.unbindUIControl();
- disposeBinding(listBindingInternal);
- listBindingInternal = null;
- disposeBinding(listBindingExternal);
- listBindingExternal = null;
- disposeBinding(selectionBindingInternal);
- selectionBindingInternal = null;
- disposeBinding(selectionBindingExternal);
- selectionBindingExternal = null;
+ protected IObservableList getUIControlItemsObservable() {
+ return SWTObservables.observeItems(getUIControl());
}
@Override
- public void updateFromModel() {
- assertIsBoundToModel();
- super.updateFromModel();
- // disable the selection binding, because updating the combo items
- // causes the selection to change temporarily
- selectionValidator.enableBinding(false);
- listBindingExternal.updateModelToTarget();
- if (listBindingInternal != null) {
- listBindingInternal.updateModelToTarget();
- }
- selectionValidator.enableBinding(true);
- selectionBindingExternal.updateModelToTarget();
- if (selectionBindingInternal != null) {
- selectionBindingInternal.updateModelToTarget();
- }
- }
-
- public void bindToModel(IObservableList listObservableValue, Class<? extends Object> rowValueClass,
- String renderingMethod, IObservableValue selectionObservableValue) {
- unbindUIControl();
-
- this.rowObservablesModel = listObservableValue;
- this.renderingMethod = renderingMethod;
- this.selectionObservableModel = selectionObservableValue;
-
- bindUIControl();
- }
-
- public void bindToModel(Object listPojo, String listPropertyName, Class<? extends Object> rowValueClass,
- String renderingMethod, Object selectionPojo, String selectionPropertyName) {
- IObservableList listObservableValue;
- if (AbstractSWTWidgetRidget.isBean(rowValueClass)) {
- listObservableValue = BeansObservables.observeList(listPojo, listPropertyName);
- } else {
- listObservableValue = PojoObservables.observeList(listPojo, listPropertyName);
- }
- IObservableValue selectionObservableValue = PojoObservables.observeValue(selectionPojo, selectionPropertyName);
- bindToModel(listObservableValue, rowValueClass, renderingMethod, selectionObservableValue);
- }
-
- /**
- * @deprecated
- */
- public void bindToModel(Object listPojo, String listPropertyName, Class<? extends Object> rowValueClass,
- String renderingMethod, Object selectionPojo, String selectionPropertyName, IComboEntryFactory entryFactory) {
- throw new UnsupportedOperationException();
- }
-
- public Object getEmptySelectionItem() {
- return emptySelection;
- }
-
- // TODO [ev] should method return null when not bound? See ListRidget#getObservableList()
- public IObservableList getObservableList() {
- return rowObservables;
- }
-
- public Object getSelection() {
- Object selection = selectionObservable.getValue();
- return selection == emptySelection ? null : selection;
- }
-
- public int getSelectionIndex() {
- int result = -1;
- Object selection = selectionObservable.getValue();
- if (emptySelection != selection) {
- result = rowObservables.indexOf(selection);
- }
- return result;
- }
-
- public boolean isAddable() {
- throw new UnsupportedOperationException(); // TODO implement
+ protected ISWTObservableValue getUIControlSelectionObservable() {
+ return SWTObservables.observeSelection(getUIControl());
}
@Override
- public boolean isDisableMandatoryMarker() {
- return hasInput();
+ protected void clearUIControlListSelection() {
+ getUIControl().deselectAll();
}
- public boolean isListMutable() {
- throw new UnsupportedOperationException(); // TODO implement
- }
-
- public boolean isReadonly() {
- throw new UnsupportedOperationException(); // TODO implement
- }
-
- public void setAddable(boolean addable) {
- throw new UnsupportedOperationException(); // TODO implement
- }
-
- public void setEmptySelectionItem(Object emptySelectionItem) {
- this.emptySelection = emptySelectionItem;
- }
-
- public void setListMutable(boolean mutable) {
- throw new UnsupportedOperationException(); // TODO implement
- }
-
- public void setReadonly(boolean readonly) {
- throw new UnsupportedOperationException(); // TODO implement
- }
-
- public void setSelection(Object newSelection) {
- assertIsBoundToModel();
- Object oldSelection = selectionObservable.getValue();
- if (oldSelection != newSelection) {
- if (newSelection == null || !rowObservables.contains(newSelection)) {
- if (getUIControl() != null) {
- getUIControl().deselectAll();
- }
- selectionObservable.setValue(null);
- } else {
- selectionObservable.setValue(newSelection);
- }
- }
- }
-
- public void setSelection(int index) {
- if (index == -1) {
- setSelection(null);
- } else {
- Object newSelection = rowObservables.get(index);
- setSelection(newSelection);
- }
- }
-
- // helping methods
- // ////////////////
-
- private void applyEnabled() {
- if (isEnabled()) {
- bindControlToSelectionAndUpdate();
- } else {
- unbindControlFromSelectionAndClear();
- }
- }
-
- private void assertIsBoundToModel() {
- if (rowObservablesModel == null) {
- throw new BindingException("ridget not bound to model"); //$NON-NLS-1$
- }
- }
-
- /**
- * Restores the list of items / selection in the combo, when the ridget is
- * enabled.
- */
- private void bindControlToSelectionAndUpdate() {
- Combo control = getUIControl();
- if (control != null && listBindingInternal != null) {
- /* update list of items in combo */
- listBindingInternal.updateModelToTarget();
- /* re-create selectionBinding */
- ISWTObservableValue controlSelection = SWTObservables.observeSelection(control);
- controlSelection.addValueChangeListener(valueChangeValidator);
- DataBindingContext dbc = new DataBindingContext();
- selectionBindingInternal = dbc.bindValue(controlSelection, selectionObservable, new UpdateValueStrategy(
- UpdateValueStrategy.POLICY_UPDATE).setConverter(strToObjConverter).setAfterGetValidator(
- selectionValidator), new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
- .setConverter(objToStrConverter));
- /* update selection in combo */
- selectionBindingInternal.updateModelToTarget();
- }
- }
-
- private void disposeBinding(Binding binding) {
- if (binding != null && !binding.isDisposed()) {
- binding.dispose();
- }
- }
-
- private String getItemFromValue(Object value) {
- Object valueObject = value;
- if (value != null && renderingMethod != null) {
- valueObject = ReflectionUtils.invoke(value, renderingMethod, (Object[]) null);
- }
- return String.valueOf(valueObject);
- }
-
- private Object getValueFromItem(String item) {
- String[] items = getUIControl().getItems();
- for (int i = 0; i < items.length; i++) {
- if (items[i].equals(item)) {
- return rowObservables.get(i);
- }
- }
- return item;
- }
-
- private boolean hasInput() {
- Object selection = selectionObservable.getValue();
- return selection != null && selection != emptySelection;
- }
-
- /**
- * Clears the list of items in the combo, when the ridget is disabled.
- */
- private void unbindControlFromSelectionAndClear() {
- Combo control = getUIControl();
- if (control != null && !isEnabled()) {
- /* dispose selectionBinding to avoid sync */
- disposeBinding(selectionBindingInternal);
- selectionBindingInternal = null;
- /* clear combo */
- if (MarkerSupport.HIDE_DISABLED_RIDGET_CONTENT) {
- control.removeAll();
- }
- }
- }
-
- // helping classes
- // ////////////////
-
- /**
- * Convert from model object to combo box items (strings).
- */
- private final class ObjectToStringConverter extends Converter {
- public ObjectToStringConverter() {
- super(Object.class, String.class);
- }
-
- public Object convert(Object fromObject) {
- return getItemFromValue(fromObject);
- }
+ @Override
+ protected String[] getUIControlItems() {
+ return getUIControl().getItems();
}
- /**
- * Convert from combo box items (strings) to model objects.
- */
- private final class StringToObjectConverter extends Converter {
- public StringToObjectConverter() {
- super(String.class, Object.class);
- }
-
- public Object convert(Object fromObject) {
- return getValueFromItem((String) fromObject);
- }
+ @Override
+ protected void removeAllFromUIControl() {
+ getUIControl().removeAll();
}
- /**
- * This validator can be used to interrupt an update request
- */
- private final class SelectionBindingValidator implements IValidator {
-
- private boolean isEnabled = true;
-
- public IStatus validate(Object value) {
- IStatus result = Status.OK_STATUS;
- // disallow control to ridget update, isEnabled == false || output
- if (!isEnabled || isOutputOnly()) {
- result = Status.CANCEL_STATUS;
- }
- return result;
- }
-
- void enableBinding(final boolean isEnabled) {
- this.isEnabled = isEnabled;
- }
+ @Override
+ protected int indexOfInUIControl(String item) {
+ return getUIControl().indexOf(item);
}
- /**
- * Ensures the user cannot change the Combo when isOutputOnly is enabled.
- *
- * @see IMarkableRidget#setOutputOnly(boolean)
- */
- private final class ValueChangeValidator implements IValueChangeListener {
-
- private volatile boolean changing = false;
-
- public void handleValueChange(ValueChangeEvent event) {
- if (changing || !isOutputOnly()) {
- return;
- }
- changing = true;
- try {
- Combo combo = getUIControl();
- String oldValue = (String) event.diff.getOldValue();
- int index = oldValue != null ? combo.indexOf(oldValue) : -1;
- if (index > -1) {
- combo.select(index);
- } else {
- combo.deselectAll();
- }
- } finally {
- changing = false;
- }
- }
-
+ @Override
+ protected void selectInUIControl(int index) {
+ getUIControl().select(index);
}
}
diff --git a/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/LabelRidget.java b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/LabelRidget.java
index 06b9452..a4c94d2 100644
--- a/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/LabelRidget.java
+++ b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/internal/ui/ridgets/swt/LabelRidget.java
@@ -10,169 +10,48 @@
*******************************************************************************/
package org.eclipse.riena.internal.ui.ridgets.swt;
-import java.net.URL;
-
-import org.eclipse.core.databinding.beans.BeansObservables;
-import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Label;
-import org.eclipse.riena.ui.ridgets.AbstractMarkerSupport;
-import org.eclipse.riena.ui.ridgets.ILabelRidget;
+import org.eclipse.riena.ui.ridgets.swt.AbstractLabelRidget;
import org.eclipse.riena.ui.ridgets.swt.AbstractSWTRidget;
-import org.eclipse.riena.ui.ridgets.swt.AbstractValueRidget;
/**
* Ridget for an SWT {@link Label} widget.
*/
-public class LabelRidget extends AbstractValueRidget implements ILabelRidget {
-
- private static final String EMPTY_STRING = ""; //$NON-NLS-1$
- private String text;
- private String icon;
- private URL iconLocation;
- private boolean textAlreadyInitialized;
- private boolean useRidgetIcon;
+public class LabelRidget extends AbstractLabelRidget {
public LabelRidget() {
this(null);
}
public LabelRidget(Label label) {
- textAlreadyInitialized = false;
- useRidgetIcon = false;
setUIControl(label);
}
@Override
- protected AbstractMarkerSupport createMarkerSupport() {
- return new BasicMarkerSupport(this, propertyChangeSupport);
- }
-
- @Override
- protected IObservableValue getRidgetObservable() {
- return BeansObservables.observeValue(this, ILabelRidget.PROPERTY_TEXT);
- }
-
- @Override
protected void checkUIControl(Object uiControl) {
AbstractSWTRidget.assertType(uiControl, Label.class);
}
@Override
- protected void bindUIControl() {
- initText();
- updateUIText();
- updateUIIcon();
- }
-
- /**
- * If the text of the ridget has no value, initialize it with the text of
- * the UI control.
- */
- private void initText() {
- if ((text == null) && (!textAlreadyInitialized)) {
- if ((getUIControl()) != null && !(getUIControl().isDisposed())) {
- text = getUIControl().getText();
- if (text == null) {
- text = EMPTY_STRING;
- }
- textAlreadyInitialized = true;
- }
- }
- }
-
- @Override
public Label getUIControl() {
return (Label) super.getUIControl();
}
- public String getIcon() {
- return icon;
- }
-
- public URL getIconLocation() {
- return iconLocation;
- }
-
- public String getText() {
- return text;
- }
-
- /**
- * Always returns true because mandatory markers do not make sense for this
- * ridget.
- */
@Override
- public boolean isDisableMandatoryMarker() {
- return true;
- }
-
- public void setIcon(String icon) {
- boolean oldUseRidgetIcon = useRidgetIcon;
- useRidgetIcon = true;
- String oldIcon = this.icon;
- this.icon = icon;
- if (hasChanged(oldIcon, icon) || !oldUseRidgetIcon) {
- updateUIIcon();
- }
- }
-
- public void setIconLocation(URL location) {
- useRidgetIcon = true;
- URL oldUrl = this.iconLocation;
- this.iconLocation = location;
- if (hasChanged(oldUrl, location)) {
- updateUIIcon();
- }
- }
-
- public void setText(String text) {
- String oldValue = this.text;
- this.text = text;
- updateUIText();
- firePropertyChange(ILabelRidget.PROPERTY_TEXT, oldValue, this.text);
- }
-
- // helping methods
- // ////////////////
-
- private void updateUIText() {
- Label control = getUIControl();
- if (control != null) {
- control.setText(text);
- }
+ protected String getUIControlText() {
+ return getUIControl().getText();
}
- private void updateUIIcon() {
- Label control = getUIControl();
- if (control != null) {
- Image image = null;
- if (icon != null) {
- image = getManagedImage(icon);
- } else if (iconLocation != null) {
- String key = iconLocation.toExternalForm();
- image = getManagedImage(key);
- }
- if ((image != null) || useRidgetIcon) {
- control.setImage(image);
- }
- }
+ @Override
+ protected void setUIControlText(String text) {
+ getUIControl().setText(text);
}
- private boolean hasChanged(URL oldValue, URL newValue) {
-
- if (oldValue == null && newValue == null) {
- return false;
- }
- if (oldValue == null || newValue == null) {
- return true;
- }
-
- // avoid URL.equals(...) since it opens a network connection :(
- String str1 = oldValue.toExternalForm();
- String str2 = newValue.toExternalForm();
- return !str1.equals(str2);
+ @Override
+ protected void setUIControlImage(Image image) {
+ getUIControl().setImage(image);
}
}
diff --git a/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractComboRidget.java b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractComboRidget.java
new file mode 100644
index 0000000..70c6166
--- /dev/null
+++ b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractComboRidget.java
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 compeople AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.ui.ridgets.swt;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.BindingException;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.UpdateListStrategy;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.beans.BeansObservables;
+import org.eclipse.core.databinding.beans.PojoObservables;
+import org.eclipse.core.databinding.conversion.Converter;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+
+import org.eclipse.riena.core.util.ReflectionUtils;
+import org.eclipse.riena.internal.ui.ridgets.swt.MarkerSupport;
+import org.eclipse.riena.ui.common.IComboEntryFactory;
+import org.eclipse.riena.ui.ridgets.IComboRidget;
+import org.eclipse.riena.ui.ridgets.IMarkableRidget;
+import org.eclipse.riena.ui.ridgets.IRidget;
+
+/**
+ * Superclass of ComboRidget that does not depend on the Combo SWT control. May
+ * be reused for custom Combo controls.
+ */
+public abstract class AbstractComboRidget extends AbstractSWTRidget implements IComboRidget {
+ /** List of choices (Objects). */
+ private final IObservableList rowObservables;
+ /** An observable with the current selection. */
+ private final IObservableValue selectionObservable;
+ /**
+ * Converts from objects (rowObsservables) to strings (Combo) using the
+ * renderingMethod.
+ */
+ private final Converter objToStrConverter;
+ /** Convers from strings (Combo) to objects (rowObservables). */
+ private final Converter strToObjConverter;
+ /** Selection validator that allows or cancels a selection request. */
+ private final SelectionBindingValidator selectionValidator;
+ /** IValueChangeListener that allows or cancels a value change */
+ private final IValueChangeListener valueChangeValidator;
+
+ /** If this item is selected, treat it as if nothing is selected */
+ private Object emptySelection;
+
+ /** List observable bean (model) */
+ private IObservableList rowObservablesModel;
+ /** Selection observable bean (model) */
+ private IObservableValue selectionObservableModel;
+ /** A string used for converting from Object to String */
+ private String renderingMethod;
+
+ /**
+ * Binding between the list of choices in the combo and the rowObservables.
+ * May be null, when there is no control or model.
+ */
+ private Binding listBindingInternal;
+ /**
+ * Binding between the rowObservables and the list of choices from the
+ * model. May be null, when there is no model.
+ */
+ private Binding listBindingExternal;
+ /**
+ * Binding between the selection in the combo and the selectionObservable.
+ * May be null, when there is no control or model.
+ */
+ private Binding selectionBindingInternal;
+ /**
+ * Binding between the selectionObservable and the selection in the model.
+ * May be null, when there is no model.
+ */
+ private Binding selectionBindingExternal;
+
+ public AbstractComboRidget() {
+ super();
+ rowObservables = new WritableList();
+ selectionObservable = new WritableValue();
+ selectionObservable.addValueChangeListener(new IValueChangeListener() {
+ public void handleValueChange(ValueChangeEvent event) {
+ Object oldValue = event.diff.getOldValue();
+ Object newValue = event.diff.getNewValue();
+ firePropertyChange(IComboRidget.PROPERTY_SELECTION, oldValue, newValue);
+ disableMandatoryMarkers(hasInput());
+ }
+ });
+ objToStrConverter = new ObjectToStringConverter();
+ strToObjConverter = new StringToObjectConverter();
+ selectionValidator = new SelectionBindingValidator();
+ valueChangeValidator = new ValueChangeValidator();
+ addPropertyChangeListener(IRidget.PROPERTY_ENABLED, new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent evt) {
+ applyEnabled();
+ }
+ });
+ }
+
+ @Override
+ protected void bindUIControl() {
+ if (rowObservablesModel != null) {
+ // These bindings are only necessary when we have a model
+ DataBindingContext dbc = new DataBindingContext();
+ if (getUIControl() != null) {
+ // These bindings are only necessary when we have a Combo
+ listBindingInternal = dbc.bindList(getUIControlItemsObservable(), rowObservables,
+ new UpdateListStrategy(UpdateListStrategy.POLICY_ON_REQUEST).setConverter(strToObjConverter),
+ new UpdateListStrategy(UpdateValueStrategy.POLICY_ON_REQUEST).setConverter(objToStrConverter));
+ listBindingInternal.updateModelToTarget();
+ applyEnabled();
+ }
+ listBindingExternal = dbc
+ .bindList(rowObservables, rowObservablesModel, new UpdateListStrategy(
+ UpdateListStrategy.POLICY_ON_REQUEST), new UpdateListStrategy(
+ UpdateListStrategy.POLICY_ON_REQUEST));
+ selectionBindingExternal = dbc
+ .bindValue(selectionObservable, selectionObservableModel, new UpdateValueStrategy(
+ UpdateValueStrategy.POLICY_UPDATE).setAfterGetValidator(selectionValidator),
+ new UpdateValueStrategy(UpdateValueStrategy.POLICY_ON_REQUEST));
+
+ }
+ }
+
+ @Override
+ protected void unbindUIControl() {
+ super.unbindUIControl();
+ disposeBinding(listBindingInternal);
+ listBindingInternal = null;
+ disposeBinding(listBindingExternal);
+ listBindingExternal = null;
+ disposeBinding(selectionBindingInternal);
+ selectionBindingInternal = null;
+ disposeBinding(selectionBindingExternal);
+ selectionBindingExternal = null;
+ }
+
+ @Override
+ public void updateFromModel() {
+ assertIsBoundToModel();
+ super.updateFromModel();
+ // disable the selection binding, because updating the combo items
+ // causes the selection to change temporarily
+ selectionValidator.enableBinding(false);
+ listBindingExternal.updateModelToTarget();
+ if (listBindingInternal != null) {
+ listBindingInternal.updateModelToTarget();
+ }
+ selectionValidator.enableBinding(true);
+ selectionBindingExternal.updateModelToTarget();
+ if (selectionBindingInternal != null) {
+ selectionBindingInternal.updateModelToTarget();
+ }
+ }
+
+ public void bindToModel(IObservableList listObservableValue, Class<? extends Object> rowValueClass,
+ String renderingMethod, IObservableValue selectionObservableValue) {
+ unbindUIControl();
+
+ this.rowObservablesModel = listObservableValue;
+ this.renderingMethod = renderingMethod;
+ this.selectionObservableModel = selectionObservableValue;
+
+ bindUIControl();
+ }
+
+ public void bindToModel(Object listPojo, String listPropertyName, Class<? extends Object> rowValueClass,
+ String renderingMethod, Object selectionPojo, String selectionPropertyName) {
+ IObservableList listObservableValue;
+ if (AbstractSWTWidgetRidget.isBean(rowValueClass)) {
+ listObservableValue = BeansObservables.observeList(listPojo, listPropertyName);
+ } else {
+ listObservableValue = PojoObservables.observeList(listPojo, listPropertyName);
+ }
+ IObservableValue selectionObservableValue = PojoObservables.observeValue(selectionPojo, selectionPropertyName);
+ bindToModel(listObservableValue, rowValueClass, renderingMethod, selectionObservableValue);
+ }
+
+ /**
+ * @deprecated
+ */
+ public void bindToModel(Object listPojo, String listPropertyName, Class<? extends Object> rowValueClass,
+ String renderingMethod, Object selectionPojo, String selectionPropertyName, IComboEntryFactory entryFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getEmptySelectionItem() {
+ return emptySelection;
+ }
+
+ // TODO [ev] should method return null when not bound? See ListRidget#getObservableList()
+ public IObservableList getObservableList() {
+ return rowObservables;
+ }
+
+ public Object getSelection() {
+ Object selection = selectionObservable.getValue();
+ return selection == emptySelection ? null : selection;
+ }
+
+ public int getSelectionIndex() {
+ int result = -1;
+ Object selection = selectionObservable.getValue();
+ if (emptySelection != selection) {
+ result = rowObservables.indexOf(selection);
+ }
+ return result;
+ }
+
+ public boolean isAddable() {
+ throw new UnsupportedOperationException(); // TODO implement
+ }
+
+ @Override
+ public boolean isDisableMandatoryMarker() {
+ return hasInput();
+ }
+
+ public boolean isListMutable() {
+ throw new UnsupportedOperationException(); // TODO implement
+ }
+
+ public boolean isReadonly() {
+ throw new UnsupportedOperationException(); // TODO implement
+ }
+
+ public void setAddable(boolean addable) {
+ throw new UnsupportedOperationException(); // TODO implement
+ }
+
+ public void setEmptySelectionItem(Object emptySelectionItem) {
+ this.emptySelection = emptySelectionItem;
+ }
+
+ public void setListMutable(boolean mutable) {
+ throw new UnsupportedOperationException(); // TODO implement
+ }
+
+ public void setReadonly(boolean readonly) {
+ throw new UnsupportedOperationException(); // TODO implement
+ }
+
+ public void setSelection(Object newSelection) {
+ assertIsBoundToModel();
+ Object oldSelection = selectionObservable.getValue();
+ if (oldSelection != newSelection) {
+ if (newSelection == null || !rowObservables.contains(newSelection)) {
+ if (getUIControl() != null) {
+ clearUIControlListSelection();
+ }
+ selectionObservable.setValue(null);
+ } else {
+ selectionObservable.setValue(newSelection);
+ }
+ }
+ }
+
+ public void setSelection(int index) {
+ if (index == -1) {
+ setSelection(null);
+ } else {
+ Object newSelection = rowObservables.get(index);
+ setSelection(newSelection);
+ }
+ }
+
+ // helping methods
+ // ////////////////
+
+ /**
+ * @return Returns an observable observing the items attribute of the
+ * control.
+ */
+ protected abstract IObservableList getUIControlItemsObservable();
+
+ /**
+ * @return Returns an observable observing the selection attribute of the
+ * control.
+ */
+ protected abstract ISWTObservableValue getUIControlSelectionObservable();
+
+ /**
+ * Deselects all selected items in the controls list.
+ */
+ protected abstract void clearUIControlListSelection();
+
+ private void applyEnabled() {
+ if (isEnabled()) {
+ bindControlToSelectionAndUpdate();
+ } else {
+ unbindControlFromSelectionAndClear();
+ }
+ }
+
+ private void assertIsBoundToModel() {
+ if (rowObservablesModel == null) {
+ throw new BindingException("ridget not bound to model"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Restores the list of items / selection in the combo, when the ridget is
+ * enabled.
+ */
+ private void bindControlToSelectionAndUpdate() {
+ if (getUIControl() != null && listBindingInternal != null) {
+ /* update list of items in combo */
+ listBindingInternal.updateModelToTarget();
+ /* re-create selectionBinding */
+ ISWTObservableValue controlSelection = getUIControlSelectionObservable();
+ controlSelection.addValueChangeListener(valueChangeValidator);
+ DataBindingContext dbc = new DataBindingContext();
+ selectionBindingInternal = dbc.bindValue(controlSelection, selectionObservable, new UpdateValueStrategy(
+ UpdateValueStrategy.POLICY_UPDATE).setConverter(strToObjConverter).setAfterGetValidator(
+ selectionValidator), new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
+ .setConverter(objToStrConverter));
+ /* update selection in combo */
+ selectionBindingInternal.updateModelToTarget();
+ }
+ }
+
+ private void disposeBinding(Binding binding) {
+ if (binding != null && !binding.isDisposed()) {
+ binding.dispose();
+ }
+ }
+
+ private String getItemFromValue(Object value) {
+ Object valueObject = value;
+ if (value != null && renderingMethod != null) {
+ valueObject = ReflectionUtils.invoke(value, renderingMethod, (Object[]) null);
+ }
+ return String.valueOf(valueObject);
+ }
+
+ private Object getValueFromItem(String item) {
+ String[] items = getUIControlItems();
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].equals(item)) {
+ return rowObservables.get(i);
+ }
+ }
+ return item;
+ }
+
+ /**
+ * @return The items of the controls list. May be an empty array.
+ */
+ protected abstract String[] getUIControlItems();
+
+ private boolean hasInput() {
+ Object selection = selectionObservable.getValue();
+ return selection != null && selection != emptySelection;
+ }
+
+ /**
+ * Clears the list of items in the combo, when the ridget is disabled.
+ */
+ private void unbindControlFromSelectionAndClear() {
+ if (getUIControl() != null && !isEnabled()) {
+ /* dispose selectionBinding to avoid sync */
+ disposeBinding(selectionBindingInternal);
+ selectionBindingInternal = null;
+ /* clear combo */
+ if (MarkerSupport.HIDE_DISABLED_RIDGET_CONTENT) {
+ removeAllFromUIControl();
+ }
+ }
+ }
+
+ /**
+ * Removes all of the items from the controls list and clears the controls
+ * text field.
+ */
+ protected abstract void removeAllFromUIControl();
+
+ /**
+ * @return The index of the item in the controls list or -1 if no such item
+ * is found.
+ */
+ protected abstract int indexOfInUIControl(String item);
+
+ /**
+ * Selects the item in the controls list.
+ */
+ protected abstract void selectInUIControl(int index);
+
+ // helping classes
+ // ////////////////
+
+ /**
+ * Convert from model object to combo box items (strings).
+ */
+ private final class ObjectToStringConverter extends Converter {
+ public ObjectToStringConverter() {
+ super(Object.class, String.class);
+ }
+
+ public Object convert(Object fromObject) {
+ return getItemFromValue(fromObject);
+ }
+ }
+
+ /**
+ * Convert from combo box items (strings) to model objects.
+ */
+ private final class StringToObjectConverter extends Converter {
+ public StringToObjectConverter() {
+ super(String.class, Object.class);
+ }
+
+ public Object convert(Object fromObject) {
+ return getValueFromItem((String) fromObject);
+ }
+ }
+
+ /**
+ * This validator can be used to interrupt an update request
+ */
+ private final class SelectionBindingValidator implements IValidator {
+
+ private boolean isEnabled = true;
+
+ public IStatus validate(Object value) {
+ IStatus result = Status.OK_STATUS;
+ // disallow control to ridget update, isEnabled == false || output
+ if (!isEnabled || isOutputOnly()) {
+ result = Status.CANCEL_STATUS;
+ }
+ return result;
+ }
+
+ void enableBinding(final boolean isEnabled) {
+ this.isEnabled = isEnabled;
+ }
+ }
+
+ /**
+ * Ensures the user cannot change the Combo when isOutputOnly is enabled.
+ *
+ * @see IMarkableRidget#setOutputOnly(boolean)
+ */
+ private final class ValueChangeValidator implements IValueChangeListener {
+
+ private volatile boolean changing = false;
+
+ public void handleValueChange(ValueChangeEvent event) {
+ if (changing || !isOutputOnly()) {
+ return;
+ }
+ changing = true;
+ try {
+ String oldValue = (String) event.diff.getOldValue();
+ int index = oldValue != null ? indexOfInUIControl(oldValue) : -1;
+ if (index > -1) {
+ selectInUIControl(index);
+ } else {
+ clearUIControlListSelection();
+ }
+ } finally {
+ changing = false;
+ }
+ }
+
+ }
+
+}
diff --git a/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractLabelRidget.java b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractLabelRidget.java
new file mode 100644
index 0000000..da9cce4
--- /dev/null
+++ b/org.eclipse.riena.ui.ridgets.swt/src/org/eclipse/riena/ui/ridgets/swt/AbstractLabelRidget.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 compeople AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.ui.ridgets.swt;
+
+import java.net.URL;
+
+import org.eclipse.core.databinding.beans.BeansObservables;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.riena.internal.ui.ridgets.swt.BasicMarkerSupport;
+import org.eclipse.riena.ui.ridgets.AbstractMarkerSupport;
+import org.eclipse.riena.ui.ridgets.ILabelRidget;
+
+/**
+ * Superclass of LabelRidget that does not depend on the Label SWT control. May
+ * be reused for custom Label controls.
+ */
+public abstract class AbstractLabelRidget extends AbstractValueRidget implements ILabelRidget {
+
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+ private String text;
+ private String icon;
+ private URL iconLocation;
+ private boolean textAlreadyInitialized;
+ private boolean useRidgetIcon;
+
+ public AbstractLabelRidget() {
+ textAlreadyInitialized = false;
+ useRidgetIcon = false;
+ }
+
+ @Override
+ protected AbstractMarkerSupport createMarkerSupport() {
+ return new BasicMarkerSupport(this, propertyChangeSupport);
+ }
+
+ @Override
+ protected IObservableValue getRidgetObservable() {
+ return BeansObservables.observeValue(this, ILabelRidget.PROPERTY_TEXT);
+ }
+
+ @Override
+ protected void bindUIControl() {
+ initText();
+ updateUIText();
+ updateUIIcon();
+ }
+
+ /**
+ * If the text of the ridget has no value, initialize it with the text of
+ * the UI control.
+ */
+ private void initText() {
+ if ((text == null) && (!textAlreadyInitialized)) {
+ if ((getUIControl()) != null && !(getUIControl().isDisposed())) {
+ text = getUIControlText();
+ if (text == null) {
+ text = EMPTY_STRING;
+ }
+ textAlreadyInitialized = true;
+ }
+ }
+ }
+
+ public String getIcon() {
+ return icon;
+ }
+
+ public URL getIconLocation() {
+ return iconLocation;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * Always returns true because mandatory markers do not make sense for this
+ * ridget.
+ */
+ @Override
+ public boolean isDisableMandatoryMarker() {
+ return true;
+ }
+
+ public void setIcon(String icon) {
+ boolean oldUseRidgetIcon = useRidgetIcon;
+ useRidgetIcon = true;
+ String oldIcon = this.icon;
+ this.icon = icon;
+ if (hasChanged(oldIcon, icon) || !oldUseRidgetIcon) {
+ updateUIIcon();
+ }
+ }
+
+ public void setIconLocation(URL location) {
+ useRidgetIcon = true;
+ URL oldUrl = this.iconLocation;
+ this.iconLocation = location;
+ if (hasChanged(oldUrl, location)) {
+ updateUIIcon();
+ }
+ }
+
+ public void setText(String text) {
+ String oldValue = this.text;
+ this.text = text;
+ updateUIText();
+ firePropertyChange(ILabelRidget.PROPERTY_TEXT, oldValue, this.text);
+ }
+
+ // helping methods
+ // ////////////////
+
+ /**
+ * @return The controls text.
+ */
+ protected abstract String getUIControlText();
+
+ private void updateUIText() {
+ if (getUIControl() != null) {
+ setUIControlText(text);
+ }
+ }
+
+ /**
+ * Sets the controls text.
+ */
+ protected abstract void setUIControlText(String text);
+
+ private void updateUIIcon() {
+ if (getUIControl() != null) {
+ Image image = null;
+ if (icon != null) {
+ image = getManagedImage(icon);
+ } else if (iconLocation != null) {
+ String key = iconLocation.toExternalForm();
+ image = getManagedImage(key);
+ }
+ if ((image != null) || useRidgetIcon) {
+ setUIControlImage(image);
+ }
+ }
+ }
+
+ /**
+ * Sets the controls image.
+ */
+ protected abstract void setUIControlImage(Image image);
+
+ private boolean hasChanged(URL oldValue, URL newValue) {
+
+ if (oldValue == null && newValue == null) {
+ return false;
+ }
+ if (oldValue == null || newValue == null) {
+ return true;
+ }
+
+ // avoid URL.equals(...) since it opens a network connection :(
+ String str1 = oldValue.toExternalForm();
+ String str2 = newValue.toExternalForm();
+ return !str1.equals(str2);
+ }
+
+}