KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > viewers > TreeEditorImpl


1 /*******************************************************************************
2  * Copyright (c) 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.debug.internal.ui.viewers;
13
14 import org.eclipse.jface.viewers.CellEditor;
15 import org.eclipse.jface.viewers.ICellEditorListener;
16 import org.eclipse.jface.viewers.ICellModifier;
17 import org.eclipse.jface.viewers.IStructuredSelection;
18 import org.eclipse.jface.viewers.StructuredSelection;
19 import org.eclipse.jface.viewers.StructuredViewer;
20 import org.eclipse.jface.viewers.TreePath;
21 import org.eclipse.jface.viewers.TreeSelection;
22 import org.eclipse.swt.events.FocusAdapter;
23 import org.eclipse.swt.events.FocusEvent;
24 import org.eclipse.swt.events.FocusListener;
25 import org.eclipse.swt.events.MouseAdapter;
26 import org.eclipse.swt.events.MouseEvent;
27 import org.eclipse.swt.events.MouseListener;
28 import org.eclipse.swt.graphics.Rectangle;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.swt.widgets.Display;
31 import org.eclipse.swt.widgets.Item;
32
33 /**
34  * Internal tree viewer implementation.
35  *
36  * TODO: Copied from JFace. Should attempt to reduce code duplication in future
37  */

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

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

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

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

191     public void cancelEditing() {
192         if (cellEditor != null) {
193             setEditor(null, null, 0);
194             cellEditor.removeListener(cellEditorListener);
195             CellEditor oldEditor = cellEditor;
196             cellEditor = null;
197             oldEditor.deactivate();
198         }
199     }
200
201     /**
202      * Start editing the given element.
203      * @param element
204      * @param column
205      */

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

238     public CellEditor[] getCellEditors() {
239         return cellEditors;
240     }
241
242     /**
243      * Get the cell modifier for the receiver.
244      * @return ICellModifier
245      */

246     public ICellModifier getCellModifier() {
247         return cellModifier;
248     }
249
250     abstract int getColumnCount();
251
252     /**
253      * Get the column properties for the receiver.
254      * @return Object[]
255      */

256     public Object JavaDoc[] getColumnProperties() {
257         return columnProperties;
258     }
259
260     abstract Item[] getSelection();
261
262     /**
263      * Handles the mouse down event; activates the cell editor.
264      * @param event
265      */

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

315     public boolean isCellEditorActive() {
316         return cellEditor != null;
317     }
318
319     /**
320      * Saves the value of the currently active cell editor,
321      * by delegating to the cell modifier.
322      */

323     private void saveEditorValue(CellEditor editor, Item item) {
324         if (cellModifier != null) {
325             String JavaDoc property = null;
326             if (columnProperties != null
327                     && columnNumber < columnProperties.length) {
328                 property = columnProperties[columnNumber];
329             }
330             cellModifier.modify(item.getData(), property, editor.getValue());
331         }
332     }
333
334     /**
335      * Set the cell editors for the receiver.
336      * @param editors
337      */

338     public void setCellEditors(CellEditor[] editors) {
339         this.cellEditors = editors;
340     }
341
342     /**
343      * Set the cell modifier for the receiver.
344      * @param modifier
345      */

346     public void setCellModifier(ICellModifier modifier) {
347         this.cellModifier = modifier;
348     }
349
350     /**
351      * Set the column properties for the receiver.
352      * @param columnProperties
353      */

354     public void setColumnProperties(String JavaDoc[] columnProperties) {
355         this.columnProperties = columnProperties;
356     }
357
358     abstract void setEditor(Control w, Item item, int fColumnNumber);
359
360     abstract void setLayoutData(CellEditor.LayoutData layoutData);
361
362     abstract void setSelection(IStructuredSelection selection, boolean b);
363
364     abstract void showSelection();
365
366     abstract void handleDoubleClickEvent();
367 }
368
Popular Tags