diff org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableValueEditingSupport.d @ 78:0a55d2d5a946

Added file for databinding
author Frank Benoit <benoit@tionex.de>
date Tue, 14 Apr 2009 11:35:29 +0200
parents
children 6be48cf9f95c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableValueEditingSupport.d	Tue Apr 14 11:35:29 2009 +0200
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+module org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport;
+
+import java.lang.all;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener;
+import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.ViewerCell;
+
+/**
+ * {@link EditingSupport} using the JFace Data Binding concepts to handle the
+ * updating of an element from a {@link CellEditor}.
+ * 
+ * @since 1.2
+ */
+public abstract class ObservableValueEditingSupport : EditingSupport {
+    /**
+     * Maintains references to the instances currently imployed while editing.
+     * Will be <code>null</code> when not editing.
+     */
+    private EditingState editingState;
+
+    private final ColumnViewerEditorActivationListenerHelper activationListener = new ColumnViewerEditorActivationListenerHelper();
+
+    private ColumnViewer viewer;
+
+    private DataBindingContext dbc;
+
+    /**
+     * Constructs a new instance with the provided <code>viewer</code> and
+     * <code>dbc</code>.
+     * 
+     * @param viewer
+     *            viewer to edit
+     * @param dbc
+     *            dbc to create <code>Bindings</code>
+     */
+    public this(ColumnViewer viewer,
+            DataBindingContext dbc) {
+        super(viewer);
+
+        if (dbc is null) {
+            throw new IllegalArgumentException("Parameter dbc was null."); //$NON-NLS-1$
+        }
+
+        this.viewer = viewer;
+        this.dbc = dbc;
+    }
+
+    /**
+     * Default implementation always returns <code>true</code>.
+     * 
+     * @see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
+     */
+    protected bool canEdit(Object element) {
+        return true;
+    }
+
+    /**
+     * Default implementation always returns <code>null</code> as this will be
+     * handled by the Binding.
+     * 
+     * @see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
+     */
+    protected Object getValue(Object element) {
+        // no op
+        return null;
+    }
+
+    /**
+     * Default implementation does nothing as this will be handled by the
+     * Binding.
+     * 
+     * @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object,
+     *      java.lang.Object)
+     */
+    protected void setValue(Object element, Object value) {
+        // no op
+    }
+
+    /**
+     * Creates a {@link Binding} between the editor and the element to be
+     * edited. Invokes {@link #doCreateCellEditorObservable(CellEditor)},
+     * {@link #doCreateElementObservable(Object, ViewerCell)}, and then
+     * {@link #createBinding(IObservableValue, IObservableValue)}.
+     */
+    final protected void initializeCellEditorValue(CellEditor cellEditor,
+            ViewerCell cell) {
+        IObservableValue target = doCreateCellEditorObservable(cellEditor);
+        Assert
+                .isNotNull(target,
+                        "doCreateCellEditorObservable(...) did not return an observable"); //$NON-NLS-1$
+
+        IObservableValue model = doCreateElementObservable(cell.getElement(),
+                cell);
+        Assert.isNotNull(model,
+                "doCreateElementObservable(...) did not return an observable"); //$NON-NLS-1$
+
+        Binding binding = createBinding(target, model);
+        Assert
+                .isNotNull(binding,
+                        "createBinding(...) did not return a binding"); //$NON-NLS-1$
+
+        editingState = new EditingState(binding, target, model);
+
+        getViewer().getColumnViewerEditor().addEditorActivationListener(
+                activationListener);
+    }
+
+    /**
+     * Creates the observable value for the CellEditor.
+     * 
+     * @param cellEditor
+     * @return observable value
+     */
+    protected abstract IObservableValue doCreateCellEditorObservable(
+            CellEditor cellEditor);
+
+    /**
+     * Creates the observable value for the element.
+     * 
+     * @param element
+     * @param cell
+     * @return observable value
+     */
+    protected abstract IObservableValue doCreateElementObservable(
+            Object element, ViewerCell cell);
+
+    /**
+     * Creates a new binding for the provided <code>target</code> and
+     * <code>model</code>. Default
+     * {@link UpdateValueStrategy value update strategies} are used with the
+     * target to model updating on {@link UpdateValueStrategy#POLICY_CONVERT}.
+     * 
+     * @param target
+     * @param model
+     * @return binding
+     */
+    protected Binding createBinding(IObservableValue target,
+            IObservableValue model) {
+        return dbc.bindValue(target, model, new UpdateValueStrategy(
+                UpdateValueStrategy.POLICY_CONVERT), null);
+    }
+
+    /**
+     * Updates the model from the target.
+     */
+    final protected void saveCellEditorValue(CellEditor cellEditor,
+            ViewerCell cell) {
+        editingState.binding.updateTargetToModel();
+    }
+
+    private class ColumnViewerEditorActivationListenerHelper :
+            ColumnViewerEditorActivationListener {
+
+        public void afterEditorActivated(ColumnViewerEditorActivationEvent event) {
+            // do nothing
+        }
+
+        public void afterEditorDeactivated(
+                ColumnViewerEditorDeactivationEvent event) {
+            editingState.dispose();
+            editingState = null;
+
+            viewer.getColumnViewerEditor().removeEditorActivationListener(this);
+        }
+
+        public void beforeEditorActivated(
+                ColumnViewerEditorActivationEvent event) {
+            // do nothing
+        }
+
+        public void beforeEditorDeactivated(
+                ColumnViewerEditorDeactivationEvent event) {
+            // do nothing
+        }
+    }
+
+    /**
+     * Maintains references to objects that only live for the length of the edit
+     * cycle.
+     */
+    private static class EditingState {
+        IObservableValue target;
+
+        IObservableValue model;
+
+        Binding binding;
+
+        this(Binding binding, IObservableValue target,
+                IObservableValue model) {
+            this.binding = binding;
+            this.target = target;
+            this.model = model;
+        }
+
+        void dispose() {
+            target.dispose();
+            model.dispose();
+            binding.dispose();
+        }
+    }
+}