KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > viewers > TreeEditorImpl


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation 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  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jface.viewers;
13
14 import org.eclipse.swt.events.FocusAdapter;
15 import org.eclipse.swt.events.FocusEvent;
16 import org.eclipse.swt.events.FocusListener;
17 import org.eclipse.swt.events.MouseAdapter;
18 import org.eclipse.swt.events.MouseEvent;
19 import org.eclipse.swt.events.MouseListener;
20 import org.eclipse.swt.graphics.Rectangle;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Display;
23 import org.eclipse.swt.widgets.Item;
24
25 /**
26  * Internal tree viewer implementation.
27  *
28  * @since 3.1
29  */

30 /* package */abstract class TreeEditorImpl {
31
32     private CellEditor cellEditor;
33
34     private CellEditor[] cellEditors;
35
36     private ICellModifier cellModifier;
37
38     private String JavaDoc[] columnProperties;
39
40     private Item treeItem;
41
42     private int columnNumber;
43
44     private ICellEditorListener cellEditorListener;
45
46     private FocusListener focusListener;
47
48     private MouseListener mouseListener;
49
50     private int doubleClickExpirationTime;
51
52     private StructuredViewer viewer;
53
54     TreeEditorImpl(StructuredViewer viewer) {
55         this.viewer = viewer;
56         initCellEditorListener();
57     }
58
59     /**
60      * Returns this <code>TreeViewerImpl</code> viewer
61      *
62      * @return the viewer
63      */

64     public StructuredViewer getViewer() {
65         return viewer;
66     }
67
68     private void activateCellEditor() {
69         if (cellEditors != null) {
70             if (cellEditors[columnNumber] != null && cellModifier != null) {
71                 Object JavaDoc element = treeItem.getData();
72                 String JavaDoc property = columnProperties[columnNumber];
73                 if (cellModifier.canModify(element, property)) {
74                     cellEditor = cellEditors[columnNumber];
75                     //tree.showSelection();
76
cellEditor.addListener(cellEditorListener);
77                     Object JavaDoc value = cellModifier.getValue(element, property);
78                     cellEditor.setValue(value);
79                     // Tricky flow of control here:
80
// activate() can trigger callback to cellEditorListener which will clear cellEditor
81
// so must get control first, but must still call activate() even if there is no control.
82
final Control control = cellEditor.getControl();
83                     cellEditor.activate();
84                     if (control == null) {
85                         return;
86                     }
87                     setLayoutData(cellEditor.getLayoutData());
88                     setEditor(control, treeItem, columnNumber);
89                     cellEditor.setFocus();
90                     if (focusListener == null) {
91                         focusListener = new FocusAdapter() {
92                             public void focusLost(FocusEvent e) {
93                                 applyEditorValue();
94                             }
95                         };
96                     }
97                     control.addFocusListener(focusListener);
98                     mouseListener = new MouseAdapter() {
99                         public void mouseDown(MouseEvent e) {
100                             // time wrap?
101
// check for expiration of doubleClickTime
102
if (e.time <= doubleClickExpirationTime) {
103                                 control.removeMouseListener(mouseListener);
104                                 cancelEditing();
105                                 handleDoubleClickEvent();
106                             } else if (mouseListener != null) {
107                                 control.removeMouseListener(mouseListener);
108                             }
109                         }
110                     };
111                     control.addMouseListener(mouseListener);
112                 }
113             }
114         }
115     }
116
117     /**
118      * Activate a cell editor for the given mouse position.
119      */

120     private void activateCellEditor(MouseEvent event) {
121         if (treeItem == null || treeItem.isDisposed()) {
122             //item no longer exists
123
return;
124         }
125         int columnToEdit;
126         int columns = getColumnCount();
127         if (columns == 0) {
128             // If no TreeColumn, Tree acts as if it has a single column
129
// which takes the whole width.
130
columnToEdit = 0;
131         } else {
132             columnToEdit = -1;
133             for (int i = 0; i < columns; i++) {
134                 Rectangle bounds = getBounds(treeItem, i);
135                 if (bounds.contains(event.x, event.y)) {
136                     columnToEdit = i;
137                     break;
138                 }
139             }
140             if (columnToEdit == -1) {
141                 return;
142             }
143         }
144
145         columnNumber = columnToEdit;
146         activateCellEditor();
147     }
148
149     /**
150      * Deactivates the currently active cell editor.
151      */

152     public void applyEditorValue() {
153         CellEditor c = this.cellEditor;
154         if (c != null) {
155             // null out cell editor before calling save
156
// in case save results in applyEditorValue being re-entered
157
// see 1GAHI8Z: ITPUI:ALL - How to code event notification when using cell editor ?
158
this.cellEditor = null;
159             Item t = this.treeItem;
160             // don't null out tree item -- same item is still selected
161
if (t != null && !t.isDisposed()) {
162                 saveEditorValue(c, t);
163             }
164             setEditor(null, null, 0);
165             c.removeListener(cellEditorListener);
166             Control control = c.getControl();
167             if (control != null) {
168                 if (mouseListener != null) {
169                     control.removeMouseListener(mouseListener);
170                 }
171                 if (focusListener != null) {
172                     control.removeFocusListener(focusListener);
173                 }
174             }
175             c.deactivate();
176         }
177     }
178
179     /**
180      * Cancels the active cell editor, without saving the value
181      * back to the domain model.
182      */

183     public void cancelEditing() {
184         if (cellEditor != null) {
185             setEditor(null, null, 0);
186             cellEditor.removeListener(cellEditorListener);
187             CellEditor oldEditor = cellEditor;
188             cellEditor = null;
189             oldEditor.deactivate();
190         }
191     }
192
193     /**
194      * Start editing the given element.
195      * @param element
196      * @param column
197      */

198     public void editElement(Object JavaDoc element, int column) {
199         if (cellEditor != null) {
200             applyEditorValue();
201         }
202
203         IStructuredSelection structuredSelection;
204         if(element instanceof TreePath) {
205             structuredSelection = new TreeSelection((TreePath)element, viewer.getComparer());
206         } else {
207             structuredSelection = new StructuredSelection(element);
208         }
209         setSelection(structuredSelection, true);
210         Item[] selection = getSelection();
211         if (selection.length != 1) {
212             return;
213         }
214
215         treeItem = selection[0];
216
217         // Make sure selection is visible
218
showSelection();
219         columnNumber = column;
220         activateCellEditor();
221
222     }
223
224     abstract Rectangle getBounds(Item item, int columnNumber);
225
226     /**
227      * Get the Cell Editors for the receiver.
228      * @return CellEditor[]
229      */

230     public CellEditor[] getCellEditors() {
231         return cellEditors;
232     }
233
234     /**
235      * Get the cell modifier for the receiver.
236      * @return ICellModifier
237      */

238     public ICellModifier getCellModifier() {
239         return cellModifier;
240     }
241
242     abstract int getColumnCount();
243
244     /**
245      * Get the column properties for the receiver.
246      * @return Object[]
247      */

248     public Object JavaDoc[] getColumnProperties() {
249         return columnProperties;
250     }
251
252     abstract Item[] getSelection();
253
254     /**
255      * Handles the mouse down event; activates the cell editor.
256      * @param event
257      */

258     public void handleMouseDown(MouseEvent event) {
259         if (event.button != 1) {
260             return;
261         }
262
263         if (cellEditor != null) {
264             applyEditorValue();
265         }
266
267         // activate the cell editor immediately. If a second mouseDown
268
// is received prior to the expiration of the doubleClick time then
269
// the cell editor will be deactivated and a doubleClick event will
270
// be processed.
271
//
272
doubleClickExpirationTime = event.time
273                 + Display.getCurrent().getDoubleClickTime();
274
275         Item[] items = getSelection();
276         // Do not edit if more than one row is selected.
277
if (items.length != 1) {
278             treeItem = null;
279             return;
280         }
281         treeItem = items[0];
282         activateCellEditor(event);
283     }
284
285     private void initCellEditorListener() {
286         cellEditorListener = new ICellEditorListener() {
287             public void editorValueChanged(boolean oldValidState,
288                     boolean newValidState) {
289                 // Ignore.
290
}
291
292             public void cancelEditor() {
293                 TreeEditorImpl.this.cancelEditing();
294             }
295
296             public void applyEditorValue() {
297                 TreeEditorImpl.this.applyEditorValue();
298             }
299         };
300     }
301
302     /**
303      * Return whether or not there is an active cell editor.
304      * @return boolean <code>true</code> if there is an active cell editor; otherwise
305      * <code>false</code> is returned.
306      */

307     public boolean isCellEditorActive() {
308         return cellEditor != null;
309     }
310
311     /**
312      * Saves the value of the currently active cell editor,
313      * by delegating to the cell modifier.
314      */

315     private void saveEditorValue(CellEditor cellEditor, Item treeItem) {
316         if (cellModifier != null) {
317             String JavaDoc property = null;
318             if (columnProperties != null
319                     && columnNumber < columnProperties.length) {
320                 property = columnProperties[columnNumber];
321             }
322             cellModifier.modify(treeItem, property, cellEditor.getValue());
323         }
324     }
325
326     /**
327      * Set the cell editors for the receiver.
328      * @param editors
329      */

330     public void setCellEditors(CellEditor[] editors) {
331         this.cellEditors = editors;
332     }
333
334     /**
335      * Set the cell modifier for the receiver.
336      * @param modifier
337      */

338     public void setCellModifier(ICellModifier modifier) {
339         this.cellModifier = modifier;
340     }
341
342     /**
343      * Set the column properties for the receiver.
344      * @param columnProperties
345      */

346     public void setColumnProperties(String JavaDoc[] columnProperties) {
347         this.columnProperties = columnProperties;
348     }
349
350     abstract void setEditor(Control w, Item item, int fColumnNumber);
351
352     abstract void setLayoutData(CellEditor.LayoutData layoutData);
353
354     abstract void setSelection(IStructuredSelection selection, boolean b);
355
356     abstract void showSelection();
357
358     abstract void handleDoubleClickEvent();
359 }
360
Popular Tags