View | Details | Raw Unified | Return to bug 144260 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/ViewersObservableFactory.java (-2 / +29 lines)
Lines 8-33 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Brad Reynolds - bug 137877
10
 *     Brad Reynolds - bug 137877
11
 *     Brad Reynolds - bug 144260
11
 *******************************************************************************/
12
 *******************************************************************************/
12
13
13
package org.eclipse.jface.internal.databinding.provisional.viewers;
14
package org.eclipse.jface.internal.databinding.provisional.viewers;
14
15
16
import org.eclipse.jface.internal.databinding.internal.swt.TextObservableValue;
15
import org.eclipse.jface.internal.databinding.internal.viewers.AbstractListViewerObservableCollectionWithLabels;
17
import org.eclipse.jface.internal.databinding.internal.viewers.AbstractListViewerObservableCollectionWithLabels;
16
import org.eclipse.jface.internal.databinding.internal.viewers.SelectionProviderSingleSelectionObservableValue;
18
import org.eclipse.jface.internal.databinding.internal.viewers.SelectionProviderSingleSelectionObservableValue;
17
import org.eclipse.jface.internal.databinding.internal.viewers.TableViewerObservableCollectionWithLabels;
19
import org.eclipse.jface.internal.databinding.internal.viewers.TableViewerObservableCollectionWithLabels;
18
import org.eclipse.jface.internal.databinding.provisional.description.Property;
20
import org.eclipse.jface.internal.databinding.provisional.description.Property;
21
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
19
import org.eclipse.jface.internal.databinding.provisional.factories.IObservableFactory;
22
import org.eclipse.jface.internal.databinding.provisional.factories.IObservableFactory;
20
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
23
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
21
import org.eclipse.jface.viewers.AbstractListViewer;
24
import org.eclipse.jface.viewers.AbstractListViewer;
25
import org.eclipse.jface.viewers.CellEditor;
26
import org.eclipse.jface.viewers.CheckboxCellEditor;
22
import org.eclipse.jface.viewers.ISelectionProvider;
27
import org.eclipse.jface.viewers.ISelectionProvider;
23
import org.eclipse.jface.viewers.TableViewer;
28
import org.eclipse.jface.viewers.TableViewer;
29
import org.eclipse.jface.viewers.TextCellEditor;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.widgets.Text;
24
32
25
/**
33
/**
26
 * A factory that supports binding to JFace viewers. This factory supports the
34
 * A factory that supports binding to JFace viewers. This factory supports the
27
 * following description objects:
35
 * following description objects:
28
 * <ul>
36
 * <ul>
29
 * <li>{@link AbstractListViewer} - denotes the viewer's collection of elements</li>
37
 * <li>{@link AbstractListViewer} - denotes the viewer's collection of elements</li>
30
 * <li>{@link TableViewerDescription} - TODO describe</li>
38
 * <li>{@link TableModelDescription} - TODO describe</li>
31
 * <li>org.eclipse.jface.databinding.PropertyDescription - depending on the
39
 * <li>org.eclipse.jface.databinding.PropertyDescription - depending on the
32
 * property description's object and property ID:
40
 * property description's object and property ID:
33
 * <ul>
41
 * <ul>
Lines 37-42 Link Here
37
 * {@link ViewersProperties#CONTENT}</li>
45
 * {@link ViewersProperties#CONTENT}</li>
38
 * <li>object instanceof AbstractListViewer, property ID is
46
 * <li>object instanceof AbstractListViewer, property ID is
39
 * {@link ViewersProperties#CONTENT}</li>
47
 * {@link ViewersProperties#CONTENT}</li>
48
 * <li>object instanceof <code>TextCellEditor</code></li>
49
 * <li>object instanceof <code>CheckboxCellEditor</code></li>
40
 * </ul>
50
 * </ul>
41
 * </li>
51
 * </li>
42
 * </ul>
52
 * </ul>
Lines 54-60 Link Here
54
	}
64
	}
55
65
56
	/**
66
	/**
57
	 * @param updateTime.
67
	 * @param updateTime
58
	 *            Update policy of DataBindingContext.TIME_EARLY or TIME_LATE.
68
	 *            Update policy of DataBindingContext.TIME_EARLY or TIME_LATE.
59
	 *            This is only a hint that some editable viewers may support
69
	 *            This is only a hint that some editable viewers may support
60
	 */
70
	 */
Lines 84-90 Link Here
84
		} else if (description instanceof TableViewer) {
94
		} else if (description instanceof TableViewer) {
85
			return new TableViewerObservableCollectionWithLabels(
95
			return new TableViewerObservableCollectionWithLabels(
86
					(TableViewer) description);
96
					(TableViewer) description);
97
		} else if (description instanceof CellEditor) {
98
			if (description instanceof TextCellEditor) {
99
				TextCellEditor editor = (TextCellEditor) description;
100
101
				if (editor.getControl() == null) {
102
					throw new IllegalArgumentException(
103
							"The TextCellEditor control must be created before creating the observable."); //$NON-NLS-1$
104
				}
105
106
				//Updating of the model will need to be done manually, hence the SWT.NONE.
107
				return new TextObservableValue((Text) editor.getControl(),
108
						SWT.NONE);
109
			} else if (description instanceof CheckboxCellEditor) {
110
				return new BooleanCellEditorObservableValue(
111
						(CheckboxCellEditor) description);
112
			}
87
		}
113
		}
114
88
		return null;
115
		return null;
89
	}
116
	}
90
}
117
}
(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/TableViewerBindingManagerFactory.java (+243 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.provisional.viewers;
13
14
import java.util.ArrayList;
15
import java.util.HashMap;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.Map;
19
20
import org.eclipse.jface.internal.databinding.provisional.BindSpec;
21
import org.eclipse.jface.internal.databinding.provisional.Binding;
22
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
23
import org.eclipse.jface.internal.databinding.provisional.description.Property;
24
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
25
import org.eclipse.jface.internal.databinding.provisional.observable.list.IObservableList;
26
import org.eclipse.jface.viewers.CellEditor;
27
import org.eclipse.jface.viewers.TableViewer;
28
29
/**
30
 * Builds a binding for a <code>TableViewer</code>.
31
 * 
32
 * @since 3.2
33
 */
34
public class TableViewerBindingManagerFactory {
35
	/**
36
	 * Empty array to represent no column IDs.
37
	 */
38
	private static final Object[] NO_COLUMN_IDS = new Object[0];
39
40
	/**
41
	 * Maintains the order of columns.
42
	 */
43
	private List columnIDs;
44
45
	/**
46
	 * Maintains columnData instances keyed by column ID.
47
	 */
48
	private Map columnDatas;
49
50
	/**
51
	 * Constructs a new instance.
52
	 */
53
	public TableViewerBindingManagerFactory() {
54
	}
55
56
	/**
57
	 * Adds a column to the binding.
58
	 * 
59
	 * @param columnID
60
	 */
61
	public void addColumn(Object columnID) {
62
		addColumn(columnID, null, null, null);
63
	}
64
65
	/**
66
	 * Adds a column that is to be edited with the provided editor data.
67
	 * 
68
	 * @param columnID
69
	 * @param cellEditor
70
	 * @param propertyType
71
	 * @param bindSpec
72
	 */
73
	private void addColumn(Object columnID, CellEditor cellEditor,
74
			Class propertyType, BindSpec bindSpec) {
75
		if (columnID == null) {
76
			throw new IllegalArgumentException(
77
					"Parameter " + columnID + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
78
		}
79
80
		if (columnDatas == null) {
81
			columnIDs = new ArrayList();
82
			columnDatas = new HashMap();
83
		}
84
85
		columnIDs.add(columnID);
86
		columnDatas.put(columnID, new ColumnData(cellEditor, propertyType,
87
				bindSpec));
88
	}
89
90
	/**
91
	 * Adds a column that is to be edited using the editor data.
92
	 * 
93
	 * @param columnID
94
	 * @param cellEditor
95
	 * @param propertyType
96
	 * @param bindSpec
97
	 *            can be <code>null</code>
98
	 */
99
	public void addEditableColumn(Object columnID, CellEditor cellEditor,
100
			Class propertyType, BindSpec bindSpec) {
101
		if (columnID == null) {
102
			throw new IllegalArgumentException(
103
					"Parameter " + columnID + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
104
		}
105
		if (cellEditor == null) {
106
			throw new IllegalArgumentException(
107
					"Parameter " + cellEditor + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
108
		}
109
		if (propertyType == null) {
110
			throw new IllegalArgumentException(
111
					"Parameter " + propertyType + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
112
		}
113
114
		addColumn(columnID, cellEditor, propertyType, bindSpec);
115
	}
116
117
	/**
118
	 * Returns the columnID for the column index.
119
	 * 
120
	 * @param columnIndex
121
	 * @return column ID
122
	 */
123
	public Object getColumnID(int columnIndex) {
124
		if (columnIDs == null || columnIndex >= columnIDs.size()
125
				|| columnIndex < 0) {
126
			throw new IllegalArgumentException(
127
					"Parameter columnIndex [" + columnIndex + "] is out of bounds."); //$NON-NLS-1$//$NON-NLS-2$
128
		}
129
130
		return columnIDs.get(columnIndex);
131
	}
132
133
	/**
134
	 * @return Number of columns added to the factory.
135
	 */
136
	public int getColumnCount() {
137
		return (columnDatas != null) ? columnDatas.size() : 0;
138
	}
139
140
	/**
141
	 * Binds a viewer to the provided <code>propertyName</code> of the
142
	 * <code>model</code> which contains objects of the provided
143
	 * <code>propertyType</code>.
144
	 * 
145
	 * @param viewer
146
	 * @param model
147
	 * @param propertyName
148
	 * @param propertyType
149
	 * @param context
150
	 * @param bindSpec
151
	 * @return binding manager
152
	 */
153
	public TableViewerBindingManager bind(TableViewer viewer, Object model,
154
			String propertyName, Class propertyType,
155
			DataBindingContext context, BindSpec bindSpec) {
156
		TableModelDescription description = new TableModelDescription(
157
				new Property(model, propertyName, propertyType, Boolean.TRUE),
158
				getColumnIDs());
159
		return bind(viewer, description, context, bindSpec);
160
	}
161
162
	/**
163
	 * Binds a viewer to the provided <code>observableList</code>.
164
	 * 
165
	 * @param viewer
166
	 * @param observableList
167
	 * @param context
168
	 * @param bindSpec
169
	 * 
170
	 * @return binding manager
171
	 */
172
	public TableViewerBindingManager bind(TableViewer viewer,
173
			IObservableList observableList, DataBindingContext context,
174
			BindSpec bindSpec) {
175
		TableModelDescription description = new TableModelDescription(
176
				observableList, getColumnIDs());
177
178
		return bind(viewer, description, context, bindSpec);
179
	}
180
181
	private TableViewerBindingManager bind(TableViewer viewer,
182
			TableModelDescription description, DataBindingContext context,
183
			BindSpec bindSpec) {
184
		// Perform the binding.
185
		Binding binding = context.bind(viewer, description, bindSpec);
186
187
		// Setup editing.
188
		TableViewerEditorManager editorManager = new TableViewerEditorManager(
189
				viewer, description.getColumnIDs(), context);
190
		if (columnDatas != null) {
191
			for (Iterator it = columnIDs.iterator(); it.hasNext();) {
192
				Object columnID = it.next();
193
				ColumnData data = (ColumnData) columnDatas.get(columnID);
194
				if (data.editor != null) {
195
					editorManager.setEditor(data.editor, columnID,
196
							data.propertyType, data.bindSpec);
197
				}
198
			}
199
		}
200
201
		return new TableViewerBindingManager(description, binding,
202
				editorManager);
203
	}
204
205
	/**
206
	 * @return columnIDs, empty array if none
207
	 */
208
	public Object[] getColumnIDs() {
209
		Object[] result = NO_COLUMN_IDS;
210
211
		if (columnIDs != null) {
212
			result = columnIDs.toArray();
213
		}
214
		return result;
215
	}
216
217
	/**
218
	 * Manages relationship between columnID and the editor data.
219
	 * 
220
	 * @since 3.2
221
	 */
222
	private class ColumnData {
223
		private final CellEditor editor;
224
225
		private final Class propertyType;
226
227
		private final BindSpec bindSpec;
228
229
		/**
230
		 * Constructs a new instance.
231
		 * 
232
		 * @param editor
233
		 * @param propertyType
234
		 * @param bindSpec
235
		 */
236
		public ColumnData(CellEditor editor, Class propertyType,
237
				BindSpec bindSpec) {
238
			this.editor = editor;
239
			this.propertyType = propertyType;
240
			this.bindSpec = bindSpec;
241
		}
242
	}
243
}
(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/TableViewerEditorManager.java (+320 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.provisional.viewers;
13
14
import org.eclipse.jface.internal.databinding.provisional.BindSpec;
15
import org.eclipse.jface.internal.databinding.provisional.Binding;
16
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
17
import org.eclipse.jface.internal.databinding.provisional.description.Property;
18
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
19
import org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue;
20
import org.eclipse.jface.internal.databinding.provisional.observable.value.ValueDiff;
21
import org.eclipse.jface.util.Assert;
22
import org.eclipse.jface.viewers.CellEditor;
23
import org.eclipse.jface.viewers.ICellModifier;
24
import org.eclipse.jface.viewers.TableViewer;
25
import org.eclipse.swt.widgets.Item;
26
27
/**
28
 * Manages the editing of a bound <code>TableViewer</code>.
29
 * <p>
30
 * The <code>CellEditor</code> must not propagate changes to the model on its
31
 * own. This is facilitated by this manager and if the editor was to propagate
32
 * changes on its own the behavior is undefined.
33
 * </p>
34
 * 
35
 * @since 3.2
36
 */
37
public class TableViewerEditorManager {
38
	private final Object[] columnIDs;
39
40
	/**
41
	 * Viewer to associate editors with.
42
	 */
43
	private final TableViewer viewer;
44
45
	/**
46
	 * Bindings that have been created for editors.
47
	 */
48
	private Binding[] bindings;
49
50
	/**
51
	 * DBC to use for creating editor bindings.
52
	 */
53
	private final DataBindingContext context;
54
55
	/**
56
	 * Observable that represents the element being edited. This is set in
57
	 * CellModifer getValue as this is the only place that we have access to
58
	 * this.
59
	 */
60
	private EditableElement editableElement;
61
62
	/**
63
	 * Constructs a new instance.
64
	 * 
65
	 * @param viewer
66
	 * @param columnIDs
67
	 * @param context
68
	 */
69
	public TableViewerEditorManager(TableViewer viewer, Object[] columnIDs,
70
			DataBindingContext context) {
71
		if (viewer == null) {
72
			throw new IllegalArgumentException(
73
					"Parameter " + viewer + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
74
		}
75
		if (columnIDs == null) {
76
			throw new IllegalArgumentException(
77
					"Parameter " + columnIDs + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
78
		}
79
		if (context == null) {
80
			throw new IllegalArgumentException(
81
					"Parameter " + context + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
82
		}
83
84
		this.viewer = viewer;
85
		this.context = context;
86
		this.columnIDs = columnIDs;
87
88
		int columnCount = (columnIDs != null) ? columnIDs.length : 0;
89
90
		viewer.setCellEditors(new CellEditor[columnCount]);
91
92
		String[] properties = new String[columnCount];
93
		viewer.setColumnProperties(properties);
94
95
		for (int i = 0; i < columnCount; i++) {
96
			properties[i] = columnIDs[i].toString();
97
		}
98
99
		editableElement = new EditableElement();
100
		bindings = new Binding[columnCount];
101
102
		viewer.setCellModifier(new CellModifier());
103
	}
104
105
	/**
106
	 * Returns the index for the column ID.
107
	 * 
108
	 * @param columnID
109
	 * @return column index, -1 if not found
110
	 */
111
	private int getColumnIndex(Object columnID) {
112
		int columnIndex = -1;
113
		for (int i = 0; columnIndex == -1 && i < columnIDs.length; i++) {
114
			if (columnID.equals(columnIDs[i])) {
115
				columnIndex = i;
116
			}
117
		}
118
119
		return columnIndex;
120
	}
121
122
	/**
123
	 * Returns the column index of the provided <code>columnID</code>.
124
	 * 
125
	 * @param columnID
126
	 * @return index
127
	 * @throws IllegalArgumentException
128
	 *             if columnID is invalid.
129
	 */
130
	private int getValidColumnIndex(Object columnID) {
131
		int index = getColumnIndex(columnID);
132
133
		if (index <= -1) {
134
			throw new IllegalArgumentException(
135
					"ColumnID [" + columnID + "] is an invalid columnID."); //$NON-NLS-1$//$NON-NLS-2$
136
		}
137
138
		return index;
139
	}
140
141
	/**
142
	 * Returns the binding for the columnID.
143
	 * 
144
	 * @param columnID 
145
	 * @return binding, <code>null</code> if a binding doesn't exist because there is no editor.
146
	 */
147
	public Binding getBinding(Object columnID) {
148
		int columnIndex = getValidColumnIndex(columnID);
149
150
		return bindings[columnIndex];
151
	}
152
153
	/**
154
	 * Retuns the editor for the columnID.
155
	 * 
156
	 * @param columnID 
157
	 * @return editor, <code>null</code> if an editor was not set
158
	 */
159
	public CellEditor getEditor(Object columnID) {
160
		int columnIndex = getValidColumnIndex(columnID);
161
162
		return viewer.getCellEditors()[columnIndex];
163
	}
164
165
	/**
166
	 * Sets a <code>editor</code> as the editor for the provided
167
	 * <code>columnID</code>.
168
	 * 
169
	 * @param editor
170
	 *            if <code>null</code> removes the current editor
171
	 * @param columnID
172
	 * @param propertyType
173
	 *            type of the attribute to be edited
174
	 * @param bindSpec
175
	 *            can be <code>null</code>
176
	 * @return binding for the editor
177
	 */
178
	public Binding setEditor(CellEditor editor, Object columnID,
179
			Class propertyType, BindSpec bindSpec) {
180
		if (columnID == null) {
181
			throw new IllegalArgumentException(
182
					"Parameter " + columnID + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
183
		}
184
		if (propertyType == null) {
185
			throw new IllegalArgumentException(
186
					"Parameter " + propertyType + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
187
		}
188
189
		int columnIndex = getValidColumnIndex(columnID);
190
		viewer.getCellEditors()[columnIndex] = editor;
191
		Binding existingBinding = bindings[columnIndex];
192
193
		if (existingBinding != null) {
194
			// Remove the existing editor.
195
			existingBinding.dispose();
196
			bindings[columnIndex] = null;
197
		}
198
199
		Binding result = null;
200
201
		if (editor != null) {
202
			if (editor.getControl() == null) {
203
				editor.create(viewer.getTable());
204
			}
205
206
			IObservable observable = context.createObservable(new Property(
207
					editableElement, columnID, propertyType, Boolean.FALSE));
208
209
			result = context.bind(editor, observable, bindSpec);
210
			bindings[columnIndex] = result;
211
		}
212
213
		return result;
214
	}
215
216
	/**
217
	 * Observable for the element being edited.
218
	 * 
219
	 * @since 3.2
220
	 */
221
	private class EditableElement extends AbstractObservableValue {
222
		private Object element;
223
224
		/*
225
		 * (non-Javadoc)
226
		 * 
227
		 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue#setValue(java.lang.Object)
228
		 */
229
		public void setValue(Object value) {
230
			final Object old = element;
231
			element = value;
232
			fireValueChange(new ValueDiff() {
233
				public Object getNewValue() {
234
					return element;
235
				}
236
237
				public Object getOldValue() {
238
					return old;
239
				}
240
			});
241
		}
242
243
		/*
244
		 * (non-Javadoc)
245
		 * 
246
		 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue#doGetValue()
247
		 */
248
		protected Object doGetValue() {
249
			return element;
250
		}
251
252
		/*
253
		 * (non-Javadoc)
254
		 * 
255
		 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue#getValueType()
256
		 */
257
		public Object getValueType() {
258
			return Object.class;
259
		}
260
	}
261
262
	/**
263
	 * <code>ICellModifier</code> implementation to be used in data binding
264
	 * that when requested retrieves the values from the model and sets the
265
	 * value in the model. The observables should not automatically update the
266
	 * model, the cell modifier handles this.
267
	 * 
268
	 * @since 3.2
269
	 */
270
	private class CellModifier implements ICellModifier {
271
		public boolean canModify(Object element, String property) {
272
			int columnIndex = getColumnIndex(property);
273
			Assert.isTrue(columnIndex > -1);
274
275
			return bindings[columnIndex] != null;
276
		}
277
278
		/*
279
		 * (non-Javadoc)
280
		 * 
281
		 * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object,
282
		 *      java.lang.String)
283
		 */
284
		public Object getValue(Object element, String property) {
285
			if (editableElement.getValue() != element) {
286
				editableElement.setValue(element);
287
			}
288
289
			Binding binding = getBinding(property);
290
			Assert.isNotNull(binding);
291
			binding.updateTargetFromModel();
292
293
			/*
294
			 * Something has to be returned so just pass the value of the
295
			 * editor, it's the correct value at this point. This will end up
296
			 * setting the value twice but the observable shouldn't fire 2
297
			 * change events as the value didn't change on the second set.
298
			 */
299
			return getEditor(property).getValue();
300
		}
301
302
		/*
303
		 * (non-Javadoc)
304
		 * 
305
		 * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object,
306
		 *      java.lang.String, java.lang.Object)
307
		 */
308
		public void modify(Object element, String property, Object value) {
309
			element = ((Item) element).getData();
310
			Assert.isTrue(editableElement.getValue().equals(element));
311
312
			Binding binding = getBinding(property);
313
			Assert.isNotNull(binding);
314
			binding.updateModelFromTarget();
315
316
			editableElement.setValue(null);
317
		}
318
	}
319
320
}
(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/TableViewerBindingManager.java (+64 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.provisional.viewers;
13
14
import org.eclipse.jface.internal.databinding.provisional.Binding;
15
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
16
17
/**
18
 * Manages the binding created by {@link TableViewerBindingManagerFactory}
19
 * providing access to all artifacts of the binding.
20
 * 
21
 * @since 3.2
22
 */
23
public class TableViewerBindingManager {
24
	private final TableModelDescription description;
25
26
	private final Binding binding;
27
28
	private final TableViewerEditorManager editorManager;
29
30
	/**
31
	 * Constructs a new instance.
32
	 * 
33
	 * @param description
34
	 * @param binding
35
	 * @param editorManager
36
	 */
37
	public TableViewerBindingManager(TableModelDescription description,
38
			Binding binding, TableViewerEditorManager editorManager) {
39
		this.description = description;
40
		this.binding = binding;
41
		this.editorManager = editorManager;
42
	}
43
44
	/**
45
	 * @return table model description
46
	 */
47
	public TableModelDescription getTableModelDescription() {
48
		return description;
49
	}
50
51
	/**
52
	 * @return binding
53
	 */
54
	public Binding getBinding() {
55
		return binding;
56
	}
57
58
	/**
59
	 * @return table viewer editor manager
60
	 */
61
	public TableViewerEditorManager getTableViewerEditorManager() {
62
		return editorManager;
63
	}
64
}
(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/BooleanCellEditorObservableValue.java (+113 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.provisional.viewers;
13
14
import org.eclipse.jface.internal.databinding.provisional.observable.Diffs;
15
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
16
import org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue;
17
import org.eclipse.jface.viewers.CellEditor;
18
import org.eclipse.jface.viewers.ICellEditorListener;
19
20
/**
21
 * {@link IObservable} implementation for a <code>CellEditor</code> that has
22
 * no control and its value is of type boolean.
23
 * 
24
 * @since 3.2
25
 */
26
public class BooleanCellEditorObservableValue extends AbstractObservableValue {
27
	private final CellEditor editor;
28
29
	private CellEditorListener listener;
30
31
	/**
32
	 * Constructs a new instance.
33
	 * 
34
	 * @param cellEditor
35
	 */
36
	public BooleanCellEditorObservableValue(final CellEditor cellEditor) {
37
		if (cellEditor == null) {
38
			throw new IllegalArgumentException(
39
					"Parameter " + cellEditor + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
40
		}
41
42
		this.editor = cellEditor;
43
44
		listener = new CellEditorListener(this);
45
		editor.addListener(listener);
46
	}
47
48
	public void dispose() {
49
		super.dispose();
50
51
		if (listener != null) {
52
			editor.removeListener(listener);
53
			listener = null;
54
		}
55
	}
56
57
	/**
58
	 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue#doGetValue()
59
	 */
60
	protected Object doGetValue() {
61
		return editor.getValue();
62
	}
63
64
	/**
65
	 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue#getValueType()
66
	 */
67
	public Object getValueType() {
68
		return Boolean.class;
69
	}
70
71
	/**
72
	 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue#setValue(java.lang.Object)
73
	 */
74
	public void setValue(Object value) {
75
		Boolean oldValue = (Boolean) editor.getValue();
76
		Boolean newValue = (value == null) ? Boolean.FALSE : (Boolean) value;
77
		
78
		if (!newValue.equals(oldValue)) {
79
			editor.setValue(newValue); // does not fire an event
80
			fireValueChange(Diffs.createValueDiff(oldValue, newValue));
81
		}
82
	}
83
84
	private static class CellEditorListener implements ICellEditorListener {
85
		private final BooleanCellEditorObservableValue observable;
86
87
		private CellEditorListener(BooleanCellEditorObservableValue observable) {
88
			this.observable = observable;
89
		}
90
91
		public void applyEditorValue() {
92
			/*
93
			 * When applyEditorValue() is invoked the value has changed. Because
94
			 * of the nature of a boolean we know the old is the opposite of the
95
			 * current value.
96
			 */
97
			boolean value = ((Boolean) observable.editor.getValue())
98
					.booleanValue();
99
100
			observable.fireValueChange(Diffs.createValueDiff(Boolean
101
					.valueOf(!value), Boolean.valueOf(value)));
102
		}
103
104
		public void cancelEditor() {
105
			// not needed
106
		}
107
108
		public void editorValueChanged(boolean oldValidState,
109
				boolean newValidState) {
110
			// not needed
111
		}
112
	}
113
}
(-)src/org/eclipse/jface/tests/internal/databinding/provisional/viewers/ViewersObservableFactoryTest.java (-2 / +25 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds.
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 18-34 Link Here
18
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
18
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
19
import org.eclipse.jface.internal.databinding.provisional.viewers.ViewersObservableFactory;
19
import org.eclipse.jface.internal.databinding.provisional.viewers.ViewersObservableFactory;
20
import org.eclipse.jface.internal.databinding.provisional.viewers.ViewersProperties;
20
import org.eclipse.jface.internal.databinding.provisional.viewers.ViewersProperties;
21
import org.eclipse.jface.viewers.CheckboxCellEditor;
21
import org.eclipse.jface.viewers.ISelection;
22
import org.eclipse.jface.viewers.ISelection;
22
import org.eclipse.jface.viewers.ISelectionChangedListener;
23
import org.eclipse.jface.viewers.ISelectionChangedListener;
23
import org.eclipse.jface.viewers.ISelectionProvider;
24
import org.eclipse.jface.viewers.ISelectionProvider;
24
import org.eclipse.jface.viewers.ListViewer;
25
import org.eclipse.jface.viewers.ListViewer;
25
import org.eclipse.jface.viewers.TableViewer;
26
import org.eclipse.jface.viewers.TableViewer;
27
import org.eclipse.jface.viewers.TextCellEditor;
26
import org.eclipse.swt.widgets.Shell;
28
import org.eclipse.swt.widgets.Shell;
27
29
28
/**
30
/**
29
 * Tests for ViewerObservableFactory.
31
 * Tests for ViewerObservableFactory.
30
 * 
32
 * 
31
 * @since 1.1
33
 * @since 3.2
32
 */
34
 */
33
public class ViewersObservableFactoryTest extends TestCase {
35
public class ViewersObservableFactoryTest extends TestCase {
34
	private Shell shell;
36
	private Shell shell;
Lines 72-77 Link Here
72
		assertTrue(observable instanceof SelectionProviderSingleSelectionObservableValue);
74
		assertTrue(observable instanceof SelectionProviderSingleSelectionObservableValue);
73
	}
75
	}
74
	
76
	
77
	public void testGetObservableForTextCellEditor() throws Exception {
78
		TextCellEditor editor = new TextCellEditor(shell);
79
		IObservable observable = factory.createObservable(editor);
80
		assertNotNull(observable);
81
	}
82
	
83
	public void testThrowsIAEIfTextCellEditorControlIsNotCreated() throws Exception {
84
		TextCellEditor editor = new TextCellEditor();
85
		try {
86
			factory.createObservable(editor);
87
			fail("exception should have been thrown");
88
		} catch (IllegalArgumentException e) {
89
		}
90
	}
91
	
92
	public void testGetObservableForCheckboxCellEditor() throws Exception {
93
		CheckboxCellEditor editor = new CheckboxCellEditor();
94
		IObservable observable = factory.createObservable(editor);
95
		assertNotNull(observable);
96
	}
97
	
75
	/**
98
	/**
76
	 * Empty stub to satisfy the requirement that we have a type of ISelectionProvider that is not a viewer.
99
	 * Empty stub to satisfy the requirement that we have a type of ISelectionProvider that is not a viewer.
77
	 */
100
	 */
(-)src/org/eclipse/jface/tests/databinding/BindingTestSuite.java (+8 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Brad Reynolds - bug 137877
10
 *     Brad Reynolds - bug 137877
11
 *     Brad Reynolds - bug 144260
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.jface.tests.databinding;
13
package org.eclipse.jface.tests.databinding;
13
14
Lines 32-37 Link Here
32
import org.eclipse.jface.tests.internal.databinding.internal.viewers.SVOCWLTest;
33
import org.eclipse.jface.tests.internal.databinding.internal.viewers.SVOCWLTest;
33
import org.eclipse.jface.tests.internal.databinding.internal.viewers.SelectionProviderSingleSelectionObservableValueTest;
34
import org.eclipse.jface.tests.internal.databinding.internal.viewers.SelectionProviderSingleSelectionObservableValueTest;
34
import org.eclipse.jface.tests.internal.databinding.provisional.observable.AbstractObservableTest;
35
import org.eclipse.jface.tests.internal.databinding.provisional.observable.AbstractObservableTest;
36
import org.eclipse.jface.tests.internal.databinding.provisional.viewers.BooleanCellEditorObservableValueTest;
37
import org.eclipse.jface.tests.internal.databinding.provisional.viewers.TableViewerBindingManagerFactoryTest;
38
import org.eclipse.jface.tests.internal.databinding.provisional.viewers.TableViewerEditorManagerTest;
35
import org.eclipse.jface.tests.internal.databinding.provisional.viewers.ViewersObservableFactoryTest;
39
import org.eclipse.jface.tests.internal.databinding.provisional.viewers.ViewersObservableFactoryTest;
36
40
37
public class BindingTestSuite extends TestSuite {
41
public class BindingTestSuite extends TestSuite {
Lines 72-77 Link Here
72
		addTestSuite(AbstractObservableTest.class);
76
		addTestSuite(AbstractObservableTest.class);
73
		addTestSuite(MocksTest.class);
77
		addTestSuite(MocksTest.class);
74
		addTestSuite(PersonTests.class);
78
		addTestSuite(PersonTests.class);
79
		addTestSuite(BooleanCellEditorObservableValueTest.class);
80
		addTestSuite(TableViewerBindingManagerFactoryTest.class);
81
		addTestSuite(TableViewerEditorManagerTest.class);
82
		addTestSuite(ViewersObservableFactoryTest.class);
75
	}
83
	}
76
84
77
	/**
85
	/**
(-)src/org/eclipse/jface/tests/internal/databinding/provisional/viewers/TableViewerEditorManagerTest.java (+282 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.tests.internal.databinding.provisional.viewers;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.jface.examples.databinding.model.Adventure;
17
import org.eclipse.jface.examples.databinding.model.Catalog;
18
import org.eclipse.jface.examples.databinding.model.Category;
19
import org.eclipse.jface.examples.databinding.model.Lodging;
20
import org.eclipse.jface.examples.databinding.model.SampleData;
21
import org.eclipse.jface.internal.databinding.provisional.Binding;
22
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
23
import org.eclipse.jface.internal.databinding.provisional.description.Property;
24
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
25
import org.eclipse.jface.internal.databinding.provisional.viewers.TableViewerEditorManager;
26
import org.eclipse.jface.viewers.CellEditor;
27
import org.eclipse.jface.viewers.CheckboxCellEditor;
28
import org.eclipse.jface.viewers.ICellModifier;
29
import org.eclipse.jface.viewers.TableViewer;
30
import org.eclipse.jface.viewers.TextCellEditor;
31
import org.eclipse.swt.SWT;
32
import org.eclipse.swt.layout.RowLayout;
33
import org.eclipse.swt.widgets.Shell;
34
35
/**
36
 * @since 3.2
37
 */
38
public class TableViewerEditorManagerTest extends TestCase {
39
	private Shell shell;
40
41
	private TableViewer viewer;
42
43
	private DataBindingContext context;
44
45
	private TableModelDescription description;
46
47
	private TableViewerEditorManager manager;
48
49
	private Catalog model;
50
51
	protected void setUp() throws Exception {
52
		shell = new Shell();
53
		shell.setLayout(new RowLayout());
54
55
		viewer = new TableViewer(shell, SWT.NONE);
56
		context = SampleData.getDatabindingContext(shell);
57
		model = SampleData.CATALOG_2005;
58
59
		description = new TableModelDescription(new Property(model,
60
				"lodgings", Lodging.class, Boolean.TRUE),
61
				new String[] { "name", "description" });
62
63
		context.bind(viewer, description, null);
64
65
		manager = new TableViewerEditorManager(viewer, description.getColumnIDs(), context);
66
	}
67
68
	/*
69
	 * (non-Javadoc)
70
	 * 
71
	 * @see junit.framework.TestCase#tearDown()
72
	 */
73
	protected void tearDown() throws Exception {
74
		if (shell != null && !shell.isDisposed()) {
75
			shell.dispose();
76
			shell = null;
77
		}
78
	}
79
80
	public void testCreateControlIfItDoesntExist() throws Exception {
81
		TextCellEditor editor = new TextCellEditor();
82
83
		manager.setEditor(editor, "name", String.class, null);
84
		assertNotNull(viewer.getCellEditors()[0]);
85
	}
86
87
	public void testSetupViewerForEditing() throws Exception {
88
		assertNotNull(viewer.getCellModifier());
89
90
		assertNotNull(viewer.getColumnProperties());
91
		assertEquals(2, viewer.getColumnProperties().length);
92
		assertNotNull(viewer.getColumnProperties()[0]);
93
		assertEquals("name", viewer.getColumnProperties()[0]);
94
		
95
		assertNotNull(viewer.getCellEditors());
96
		assertEquals(2, viewer.getCellEditors().length);
97
		assertNull(viewer.getCellEditors()[0]);
98
		
99
		TextCellEditor editor = new TextCellEditor();
100
		manager.setEditor(editor, "name", String.class, null);
101
		
102
		assertEquals(editor, viewer.getCellEditors()[0]);
103
	}
104
105
	public void testSetValueInTextCellEditorOnEdit() throws Exception {
106
		TextCellEditor editor = new TextCellEditor();
107
		manager.setEditor(editor, "name", String.class, null);
108
109
		viewer.editElement(model.getLodgings()[0], 0);
110
111
		Lodging lodging = model.getLodgings()[0];
112
		assertEquals(lodging.getName(), editor.getValue());
113
	}
114
115
	public void testUpdateModelFromTextCellEditorAfterEdit() throws Exception {
116
		TextCellEditor editor = new TextCellEditor();
117
		manager.setEditor(editor, "name", String.class, null);
118
		
119
		Lodging lodging = model.getLodgings()[0];
120
		viewer.editElement(lodging, 0);
121
		
122
		assertTrue(editor.isActivated());
123
		
124
		String newValue = lodging.getName() + " new";
125
		editor.setValue(newValue);
126
		
127
		editor.getControl().notifyListeners(SWT.FocusOut, null);
128
		
129
		assertFalse(editor.isActivated());
130
		assertEquals(newValue, lodging.getName());
131
	}
132
133
	public void testToggleCheckboxCellEditorValueOnEdit() throws Exception {
134
		Category model = SampleData.WINTER_CATEGORY;
135
		description = new TableModelDescription(new Property(model,
136
				"adventures", Adventure.class, Boolean.TRUE),
137
				new String[] { "petsAllowed" });
138
139
		context.bind(viewer, description, null);
140
141
		manager = new TableViewerEditorManager(viewer, description.getColumnIDs(), context);
142
143
		CheckboxCellEditor editor = new CheckboxCellEditor();
144
		manager.setEditor(editor, "petsAllowed", boolean.class, null);
145
146
		Adventure adventure = model.getAdventures()[0];
147
		boolean old = adventure.isPetsAllowed();
148
		
149
		viewer.editElement(adventure, 0);
150
		
151
		assertEquals(!old, adventure.isPetsAllowed());
152
	}
153
	
154
	public void testRemoveEditor() throws Exception {
155
		TextCellEditor editor = new TextCellEditor();
156
		Binding binding = manager.setEditor(editor, "name", String.class, null);
157
		assertNotNull(binding);
158
		assertFalse(binding.isDisposed());
159
		
160
		ICellModifier cellModifier = viewer.getCellModifier();
161
		Lodging lodging = model.getLodgings()[0];
162
		assertTrue(cellModifier.canModify(lodging, "name"));
163
		
164
		manager.setEditor(null, "name", String.class, null);
165
		
166
		assertTrue(binding.isDisposed());
167
		assertFalse(cellModifier.canModify(lodging, "name"));
168
	}
169
	
170
	public void testSetEditorForExistingEditableColumn() throws Exception {
171
		TextCellEditor firstEditor = new TextCellEditor();
172
		Binding firstBinding = manager.setEditor(firstEditor, "name", String.class, null);
173
		assertFalse(firstBinding.isDisposed());
174
		
175
		TextCellEditor secondEditor = new TextCellEditor();
176
		Binding secondBinding = manager.setEditor(secondEditor, "name", String.class, null);
177
		assertTrue(firstBinding.isDisposed());
178
		assertFalse(secondBinding.isDisposed());
179
		
180
		ICellModifier cellModifier = viewer.getCellModifier();
181
		Lodging lodging = model.getLodgings()[0];
182
		assertTrue(cellModifier.canModify(lodging, "name"));
183
	}
184
	
185
	public void testSetEditorForInvalidColumnID() throws Exception {
186
		try {
187
			TextCellEditor editor = new TextCellEditor();
188
			manager.setEditor(editor, "bogus ID", String.class, null);
189
			fail("exception should have been thrown");
190
		} catch (IllegalArgumentException e) {
191
		}
192
	}
193
194
	public void testSetNullColumnID() throws Exception {
195
		try {
196
			TextCellEditor editor = new TextCellEditor();
197
			manager.setEditor(editor, null, String.class, null);
198
		} catch (IllegalArgumentException e) {
199
		}
200
	}
201
	
202
	public void testSetNullPropertyType() throws Exception {
203
		try {
204
			TextCellEditor editor = new TextCellEditor();
205
			manager.setEditor(editor, "name", null, null);
206
		} catch (IllegalArgumentException e) {
207
		}
208
	}
209
	
210
	public void testCellModifierOnlyAllowsEditingForColumnsWithAnEditor() throws Exception {
211
		ICellModifier modifier = viewer.getCellModifier();
212
		Lodging lodging = model.getLodgings()[0];
213
		
214
		TextCellEditor editor = new TextCellEditor();
215
		manager.setEditor(editor, "name", String.class, null);
216
		
217
		assertTrue(modifier.canModify(lodging, "name"));
218
		assertFalse(modifier.canModify(lodging, "description"));
219
	}
220
	
221
	public void testConstructWithNullTableViewer() throws Exception {
222
		try {
223
			manager = new TableViewerEditorManager(null, description.getColumnIDs(), context);
224
			fail("exception should have been thrown");
225
		} catch (IllegalArgumentException e) {
226
		}
227
	}
228
	
229
	public void testConstructWithNullTableModelDescription() throws Exception {
230
		try {
231
			manager = new TableViewerEditorManager(viewer, null, context);
232
			fail("exception should have been thrown");
233
		} catch (IllegalArgumentException e) {
234
		}
235
	}
236
	
237
	public void testConstructWithNullDataBindingContext() throws Exception {
238
		try {
239
			manager = new TableViewerEditorManager(viewer, description.getColumnIDs(), null);
240
			fail("exception should have been thrown");
241
		} catch (IllegalArgumentException e) {
242
		}
243
	}
244
	
245
	public void testGetEditor() throws Exception {
246
		assertNull(manager.getEditor("name"));
247
		
248
		TextCellEditor editor = new TextCellEditor();
249
		manager.setEditor(editor, "name", String.class, null);
250
		
251
		CellEditor nameEditor = manager.getEditor("name");
252
		assertNotNull(nameEditor);
253
		assertEquals(editor, nameEditor);
254
	}
255
	
256
	public void testGetInvalidEditor() throws Exception {
257
		try {
258
			manager.getEditor("column ID that does not exist");
259
			fail("exception should have been thrown");			
260
		} catch (IllegalArgumentException e) {
261
		}
262
	}
263
	
264
	public void testGetBinding() throws Exception {
265
		assertNull(manager.getBinding("name"));
266
		
267
		TextCellEditor editor = new TextCellEditor();
268
		Binding binding = manager.setEditor(editor, "name", String.class, null);
269
		
270
		Binding nameBinding = manager.getBinding("name");
271
		assertNotNull(nameBinding);
272
		assertEquals(binding, nameBinding);
273
	}
274
	
275
	public void testGetInvalidBinding() throws Exception {
276
		try {
277
			manager.getBinding("column ID that does not exist");
278
			fail("exception should have been thrown");
279
		} catch (IllegalArgumentException e) {
280
		}
281
	}
282
}
(-)src/org/eclipse/jface/tests/internal/databinding/provisional/viewers/BooleanCellEditorObservableValueTest.java (+162 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.tests.internal.databinding.provisional.viewers;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue;
17
import org.eclipse.jface.internal.databinding.provisional.observable.value.IValueChangeListener;
18
import org.eclipse.jface.internal.databinding.provisional.observable.value.ValueDiff;
19
import org.eclipse.jface.internal.databinding.provisional.viewers.BooleanCellEditorObservableValue;
20
import org.eclipse.jface.viewers.CheckboxCellEditor;
21
22
/**
23
 * @since 3.2
24
 */
25
public class BooleanCellEditorObservableValueTest extends TestCase {
26
	private BooleanCellEditorObservableValue observable;
27
28
	private MyCheckboxCellEditor cellEditor;
29
30
	protected void setUp() throws Exception {
31
		cellEditor = new MyCheckboxCellEditor();
32
		cellEditor.setValue(Boolean.FALSE);
33
		observable = new BooleanCellEditorObservableValue(cellEditor);
34
	}
35
36
	private class MyCheckboxCellEditor extends CheckboxCellEditor {
37
		protected void setValueValid(boolean valid) {
38
			// TODO Auto-generated method stub
39
			super.setValueValid(valid);
40
		}
41
	}
42
43
	public void testConstructionIllegalArgumentExceptions() throws Exception {
44
		try {
45
			new BooleanCellEditorObservableValue(null);
46
			fail("Exception should have been thrown.");
47
		} catch (IllegalArgumentException e) {
48
		}
49
	}
50
51
	public void testGetValueType() throws Exception {
52
		assertEquals(Boolean.class, observable.getValueType());
53
	}
54
55
	public void testGetValue() throws Exception {
56
		cellEditor.setValue(Boolean.TRUE);
57
		assertEquals(Boolean.TRUE, observable.getValue());
58
		cellEditor.setValue(Boolean.FALSE);
59
		assertEquals(Boolean.FALSE, observable.getValue());
60
	}
61
62
	public void testSetFalseWhenCellEditorValueIsNull() throws Exception {
63
		cellEditor.setValueValid(false);
64
		assertNull(cellEditor.getValue());
65
		observable.setValue(Boolean.FALSE);
66
		Boolean editorValue = (Boolean) cellEditor.getValue();
67
		assertNotNull(editorValue);
68
		assertEquals(Boolean.FALSE, editorValue);
69
	}
70
71
	public void testObservableSetValueSame() throws Exception {
72
		ValueChangeCounter listener = new ValueChangeCounter();
73
		observable.addValueChangeListener(listener);
74
		assertEquals(0, listener.count);
75
		assertEquals(Boolean.FALSE, observable.getValue());
76
		assertEquals(Boolean.FALSE, cellEditor.getValue());
77
78
		observable.setValue(Boolean.FALSE);
79
80
		assertEquals(0, listener.count);
81
		assertEquals(Boolean.FALSE, observable.getValue());
82
		assertEquals(Boolean.FALSE, cellEditor.getValue());
83
	}
84
85
	public void testObservableSetValueDifferent() throws Exception {
86
		ValueChangeCounter listener = new ValueChangeCounter();
87
		observable.addValueChangeListener(listener);
88
		assertEquals(0, listener.count);
89
		assertEquals(Boolean.FALSE, observable.getValue());
90
		assertEquals(Boolean.FALSE, cellEditor.getValue());
91
92
		observable.setValue(Boolean.TRUE);
93
94
		assertEquals(1, listener.count);
95
		assertEquals(Boolean.TRUE, observable.getValue());
96
		assertEquals(Boolean.TRUE, cellEditor.getValue());
97
98
		assertEquals(observable, listener.source);
99
		assertEquals(Boolean.FALSE, listener.diff.getOldValue());
100
		assertEquals(Boolean.TRUE, listener.diff.getNewValue());
101
	}
102
103
	public void testCellEditorChangeValue() throws Exception {
104
		ValueChangeCounter listener = new ValueChangeCounter();
105
		observable.addValueChangeListener(listener);
106
		assertEquals(0, listener.count);
107
		assertEquals(Boolean.FALSE, observable.getValue());
108
		assertEquals(Boolean.FALSE, cellEditor.getValue());
109
110
		cellEditor.activate();
111
112
		assertEquals(1, listener.count);
113
		assertEquals(Boolean.TRUE, observable.getValue());
114
		assertEquals(Boolean.TRUE, cellEditor.getValue());
115
116
		assertEquals(observable, listener.source);
117
		assertEquals(Boolean.FALSE, listener.diff.getOldValue());
118
		assertEquals(Boolean.TRUE, listener.diff.getNewValue());
119
	}
120
121
	public void testCellEditorSetValueDifferent() throws Exception {
122
		ValueChangeCounter listener = new ValueChangeCounter();
123
		observable.addValueChangeListener(listener);
124
		assertEquals(0, listener.count);
125
		assertEquals(Boolean.FALSE, observable.getValue());
126
		assertEquals(Boolean.FALSE, cellEditor.getValue());
127
128
		cellEditor.setValue(Boolean.TRUE);
129
130
		assertEquals(0, listener.count);
131
		assertEquals(Boolean.TRUE, observable.getValue());
132
		assertEquals(Boolean.TRUE, cellEditor.getValue());
133
	}
134
135
	public void testSetObservableNullValue() throws Exception {
136
		ValueChangeCounter listener = new ValueChangeCounter();
137
		observable.addValueChangeListener(listener);
138
		assertEquals(0, listener.count);
139
		assertEquals(Boolean.FALSE, observable.getValue());
140
		assertEquals(Boolean.FALSE, cellEditor.getValue());
141
142
		observable.setValue(null);
143
144
		assertEquals(0, listener.count);
145
		assertEquals(Boolean.FALSE, observable.getValue());
146
		assertEquals(Boolean.FALSE, cellEditor.getValue());
147
	}
148
149
	private class ValueChangeCounter implements IValueChangeListener {
150
		private int count;
151
152
		private IObservableValue source;
153
154
		private ValueDiff diff;
155
156
		public void handleValueChange(IObservableValue source, ValueDiff diff) {
157
			count++;
158
			this.source = source;
159
			this.diff = diff;
160
		}
161
	}
162
}
(-)src/org/eclipse/jface/tests/internal/databinding/provisional/viewers/TableViewerBindingManagerFactoryTest.java (+191 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.tests.internal.databinding.provisional.viewers;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.jface.examples.databinding.model.Catalog;
17
import org.eclipse.jface.examples.databinding.model.Lodging;
18
import org.eclipse.jface.examples.databinding.model.SampleData;
19
import org.eclipse.jface.internal.databinding.provisional.Binding;
20
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
21
import org.eclipse.jface.internal.databinding.provisional.description.Property;
22
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
23
import org.eclipse.jface.internal.databinding.provisional.observable.list.WritableList;
24
import org.eclipse.jface.internal.databinding.provisional.viewers.TableViewerBindingManager;
25
import org.eclipse.jface.internal.databinding.provisional.viewers.TableViewerBindingManagerFactory;
26
import org.eclipse.jface.internal.databinding.provisional.viewers.TableViewerEditorManager;
27
import org.eclipse.jface.viewers.TableViewer;
28
import org.eclipse.jface.viewers.TextCellEditor;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.layout.RowLayout;
31
import org.eclipse.swt.widgets.Shell;
32
import org.eclipse.swt.widgets.Table;
33
import org.eclipse.swt.widgets.TableColumn;
34
import org.eclipse.swt.widgets.TableItem;
35
36
/**
37
 * @since 3.2
38
 *
39
 */
40
public class TableViewerBindingManagerFactoryTest extends TestCase {
41
	private Shell shell;
42
43
	private TableViewer viewer;
44
45
	private DataBindingContext context;
46
47
	private Catalog model;
48
	
49
	private TableViewerBindingManagerFactory factory;
50
	
51
	/* (non-Javadoc)
52
	 * @see junit.framework.TestCase#setUp()
53
	 */
54
	protected void setUp() throws Exception {
55
		shell = new Shell();
56
		shell.setLayout(new RowLayout());
57
58
		viewer = new TableViewer(shell, SWT.NONE);
59
		context = SampleData.getDatabindingContext(shell);
60
		model = SampleData.CATALOG_2005;
61
		factory = new TableViewerBindingManagerFactory();
62
	}
63
	
64
	/* (non-Javadoc)
65
	 * @see junit.framework.TestCase#tearDown()
66
	 */
67
	protected void tearDown() throws Exception {
68
		if (shell != null && !shell.isDisposed()) {
69
			shell.dispose();
70
			shell = null;
71
		}
72
	}
73
	
74
	public void testAddAndGetFactoryColumnIDs() throws Exception {
75
		TableViewerBindingManagerFactory factory = new TableViewerBindingManagerFactory();
76
		Object[] columnIDs = factory.getColumnIDs();
77
		assertNotNull(columnIDs);
78
		assertEquals(0, columnIDs.length);
79
		
80
		factory.addColumn("name");
81
		columnIDs = factory.getColumnIDs();
82
		assertNotNull(columnIDs);
83
		assertEquals(1, columnIDs.length);
84
		assertEquals("name", columnIDs[0]);
85
		
86
		factory.addColumn("description");
87
		columnIDs = factory.getColumnIDs();
88
		assertEquals(2, columnIDs.length);
89
		assertEquals("name", columnIDs[0]);
90
		assertEquals("description", columnIDs[1]);
91
		
92
		assertEquals("name", factory.getColumnID(0));
93
		assertEquals("description", factory.getColumnID(1));
94
	}
95
	
96
	public void testTableModelDescriptionConstruction() throws Exception {
97
		TableViewerBindingManagerFactory factory = new TableViewerBindingManagerFactory();
98
		factory.addColumn("name");
99
		factory.addColumn("description");
100
101
		TableViewerBindingManager tvb = factory.bind(viewer, model, "lodgings", Lodging.class, context, null);
102
		TableModelDescription description = tvb.getTableModelDescription();
103
		Object[] columnIDs = description.getColumnIDs();
104
		assertNotNull(columnIDs);
105
		assertEquals(2, columnIDs.length);
106
		assertEquals("name", columnIDs[0]);
107
		assertEquals("description", columnIDs[1]);
108
		
109
		Property property = description.getCollectionProperty();
110
		assertEquals(model, property.getObject());
111
		assertEquals("lodgings", property.getPropertyID());
112
		assertEquals(Lodging.class, property.getPropertyType());
113
	}
114
	
115
	public void testBindProperty() throws Exception {
116
		Table table = viewer.getTable();
117
		for (int i = 0; i < 2; i++) {
118
			new TableColumn(table, SWT.NONE);
119
		}
120
				
121
		factory.addColumn("name");
122
		factory.addColumn("description");
123
		
124
		TableViewerBindingManager tvb = factory.bind(viewer, model, "lodgings", Lodging.class, context, null);
125
		Binding binding = tvb.getBinding();
126
		assertNotNull(binding);
127
		
128
		//Assert the binding worked
129
		TableItem item = table.getItem(0);
130
		Lodging lodging = model.getLodgings()[0];
131
		assertEquals(lodging, item.getData());
132
		assertEquals(lodging.getName(), item.getText(0));
133
		assertEquals(lodging.getDescription(), item.getText(1));		
134
	}
135
	
136
	public void testAddEditableColumn() throws Exception {
137
		TextCellEditor nameEditor = new TextCellEditor();
138
		
139
		factory.addEditableColumn("name", nameEditor, String.class, null);
140
		factory.addColumn("description");
141
		
142
		TableViewerBindingManager tvb = factory.bind(viewer, model, "lodgings", Lodging.class, context, null);
143
		TableViewerEditorManager editorManager = tvb.getTableViewerEditorManager();
144
		assertNotNull(editorManager);
145
		assertEquals(nameEditor, editorManager.getEditor("name"));
146
		
147
		assertNull(editorManager.getEditor("description"));
148
	}
149
	
150
	public void testAddEditableColumnWithNullEditor() throws Exception {
151
		try {
152
			factory.addEditableColumn("name", null, String.class, null);
153
			fail("exception should have been thrown");
154
		} catch (IllegalArgumentException e) {
155
		}		
156
	}
157
	
158
	public void testAddEditableColumnWithNullPropertyType() throws Exception {
159
		try {
160
			factory.addEditableColumn("name", new TextCellEditor(), null, null);
161
			fail("exception should have been thrown");
162
		} catch (IllegalArgumentException e) {
163
		}
164
	}
165
	
166
	public void testBindObservableList() throws Exception {
167
		WritableList list = new WritableList(Lodging.class);
168
		Lodging lodging = new Lodging();
169
		lodging.setName("lodging name");
170
		list.add(lodging);
171
		
172
		factory.addColumn("name");
173
		
174
		TableViewerBindingManager tvb = factory.bind(viewer, list, context, null);
175
		assertNotNull(tvb.getBinding());
176
		
177
		//Assert the binding worked
178
		Table table = viewer.getTable();
179
		TableItem item = table.getItem(0);
180
		assertEquals(lodging, item.getData());
181
		assertEquals(lodging.getName(), item.getText(0));
182
	}
183
	
184
	public void testAddNullColumnID() throws Exception {
185
		try {
186
			factory.addColumn(null);
187
			fail("exception should have been thrown");
188
		} catch (IllegalArgumentException e) {
189
		}
190
	}
191
}

Return to bug 144260