KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > dialogs > TableTextCellEditor


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 package org.eclipse.jdt.internal.ui.dialogs;
12
13 import org.eclipse.core.runtime.Assert;
14
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.events.FocusAdapter;
17 import org.eclipse.swt.events.FocusEvent;
18 import org.eclipse.swt.events.KeyAdapter;
19 import org.eclipse.swt.events.KeyEvent;
20 import org.eclipse.swt.events.ModifyEvent;
21 import org.eclipse.swt.events.ModifyListener;
22 import org.eclipse.swt.events.MouseAdapter;
23 import org.eclipse.swt.events.MouseEvent;
24 import org.eclipse.swt.events.SelectionAdapter;
25 import org.eclipse.swt.events.SelectionEvent;
26 import org.eclipse.swt.events.TraverseEvent;
27 import org.eclipse.swt.events.TraverseListener;
28 import org.eclipse.swt.layout.FillLayout;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Listener;
32 import org.eclipse.swt.widgets.Text;
33
34 import org.eclipse.jface.contentassist.SubjectControlContentAssistant;
35 import org.eclipse.jface.viewers.CellEditor;
36 import org.eclipse.jface.viewers.IStructuredSelection;
37 import org.eclipse.jface.viewers.TableViewer;
38
39 import org.eclipse.jdt.internal.corext.util.Messages;
40
41 /**
42  * <code>TableTextCellEditor</code> is a copy of TextCellEditor, with the
43  * following changes:
44  *
45  * <ul>
46  * <li> modify events are sent out as the text is changed, and not only after
47  * editing is done </li>
48  *
49  * <li>a content assistant is supported</li>
50  *
51  * <li>the <code>Control</code> from <code>getControl(Composite)</code>
52  * does not notify registered FocusListeners. This is a workaround for bug
53  * 58777. </li>
54  *
55  * <li>the user can go to the next/previous row with up and down keys</li>
56  * </ul>
57  */

58 public class TableTextCellEditor extends CellEditor {
59     public interface IActivationListener {
60         public void activate();
61     }
62     
63     private final TableViewer fTableViewer;
64     private final int fColumn;
65     private final String JavaDoc fProperty;
66     /**
67      * The editor's value on activation. This value is reset to the
68      * cell when the editor is left via ESC key.
69      */

70     String JavaDoc fOriginalValue;
71     SubjectControlContentAssistant fContentAssistant;
72     private IActivationListener fActivationListener;
73     
74     protected Text text;
75
76     private boolean isSelection = false;
77     private boolean isDeleteable = false;
78     private boolean isSelectable = false;
79
80     private static final int defaultStyle = SWT.SINGLE;
81     private ModifyListener fModifyListener;
82     
83     public TableTextCellEditor(TableViewer tableViewer, int column) {
84         super(tableViewer.getTable(), defaultStyle);
85         fTableViewer= tableViewer;
86         fColumn= column;
87         fProperty= (String JavaDoc) tableViewer.getColumnProperties()[column];
88     }
89     
90     public void activate() {
91         super.activate();
92         if (fActivationListener != null)
93             fActivationListener.activate();
94         fOriginalValue= text.getText();
95     }
96     
97     private void fireModifyEvent(Object JavaDoc newValue) {
98         fTableViewer.getCellModifier().modify(
99                 ((IStructuredSelection) fTableViewer.getSelection()).getFirstElement(),
100                 fProperty, newValue);
101     }
102     
103     protected void focusLost() {
104         if (fContentAssistant != null && fContentAssistant.hasProposalPopupFocus()) {
105             // skip focus lost if it went to the content assist popup
106
} else {
107             super.focusLost();
108         }
109     }
110     
111     public void setContentAssistant(SubjectControlContentAssistant assistant) {
112         fContentAssistant= assistant;
113     }
114     
115     public void setActivationListener(IActivationListener listener) {
116         fActivationListener= listener;
117     }
118     
119     public Text getText() {
120         return text;
121     }
122     
123     protected void checkDeleteable() {
124         boolean oldIsDeleteable = isDeleteable;
125         isDeleteable = isDeleteEnabled();
126         if (oldIsDeleteable != isDeleteable) {
127             fireEnablementChanged(DELETE);
128         }
129     }
130
131     protected void checkSelectable() {
132         boolean oldIsSelectable = isSelectable;
133         isSelectable = isSelectAllEnabled();
134         if (oldIsSelectable != isSelectable) {
135             fireEnablementChanged(SELECT_ALL);
136         }
137     }
138
139     protected void checkSelection() {
140         boolean oldIsSelection = isSelection;
141         isSelection = text.getSelectionCount() > 0;
142         if (oldIsSelection != isSelection) {
143             fireEnablementChanged(COPY);
144             fireEnablementChanged(CUT);
145         }
146     }
147
148     private ModifyListener getModifyListener() {
149         if (fModifyListener == null) {
150             fModifyListener = new ModifyListener() {
151                 public void modifyText(ModifyEvent e) {
152                     editOccured(e);
153                 }
154             };
155         }
156         return fModifyListener;
157     }
158
159     /* (non-Javadoc)
160      * Method declared on CellEditor.
161      */

162     protected Control createControl(Composite parent) {
163         //workaround for bug 58777: don't accept focus listeners on the text control
164
final Control[] textControl= new Control[1];
165         Composite result= new Composite(parent, SWT.NONE) {
166             public void addListener(int eventType, final Listener listener) {
167                 if (eventType != SWT.FocusIn && eventType != SWT.FocusOut) {
168                     textControl[0].addListener(eventType, listener);
169                 }
170             }
171         };
172         result.setFont(parent.getFont());
173         result.setBackground(parent.getBackground());
174         result.setLayout(new FillLayout());
175         
176         text = new Text(result, getStyle());
177         textControl[0]= text;
178         text.addSelectionListener(new SelectionAdapter() {
179             public void widgetDefaultSelected(SelectionEvent e) {
180                 handleDefaultSelection(e);
181             }
182         });
183         text.addKeyListener(new KeyAdapter() {
184             public void keyPressed(KeyEvent e) {
185                 // support switching rows while editing:
186
if (e.stateMask == SWT.MOD1 || e.stateMask == SWT.MOD2) {
187                     if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) {
188                         // allow starting multi-selection even if in edit mode
189
deactivate();
190                         e.doit= false;
191                         return;
192                     }
193                 }
194                 
195                 if (e.stateMask != SWT.NONE)
196                     return;
197                 
198                 switch (e.keyCode) {
199                 case SWT.ARROW_DOWN :
200                     e.doit= false;
201                     int nextRow= fTableViewer.getTable().getSelectionIndex() + 1;
202                     if (nextRow >= fTableViewer.getTable().getItemCount())
203                         break;
204                     editRow(nextRow);
205                     break;
206                     
207                 case SWT.ARROW_UP :
208                     e.doit= false;
209                     int prevRow= fTableViewer.getTable().getSelectionIndex() - 1;
210                     if (prevRow < 0)
211                         break;
212                     editRow(prevRow);
213                     break;
214                     
215                 case SWT.F2 :
216                     e.doit= false;
217                     deactivate();
218                     break;
219                 }
220             }
221
222             private void editRow(int row) {
223                 fTableViewer.getTable().setSelection(row);
224                 IStructuredSelection newSelection= (IStructuredSelection) fTableViewer.getSelection();
225                 if (newSelection.size() == 1)
226                     fTableViewer.editElement(newSelection.getFirstElement(), fColumn);
227             }
228         });
229         text.addKeyListener(new KeyAdapter() {
230             // hook key pressed - see PR 14201
231
public void keyPressed(KeyEvent e) {
232                 keyReleaseOccured(e);
233
234                 // as a result of processing the above call, clients may have
235
// disposed this cell editor
236
if ((getControl() == null) || getControl().isDisposed())
237                     return;
238                 checkSelection(); // see explaination below
239
checkDeleteable();
240                 checkSelectable();
241             }
242         });
243         text.addTraverseListener(new TraverseListener() {
244             public void keyTraversed(TraverseEvent e) {
245                 if (e.detail == SWT.TRAVERSE_ESCAPE
246                         || e.detail == SWT.TRAVERSE_RETURN) {
247                     e.doit = false;
248                 }
249             }
250         });
251         // We really want a selection listener but it is not supported so we
252
// use a key listener and a mouse listener to know when selection changes
253
// may have occured
254
text.addMouseListener(new MouseAdapter() {
255             public void mouseUp(MouseEvent e) {
256                 checkSelection();
257                 checkDeleteable();
258                 checkSelectable();
259             }
260         });
261         text.addFocusListener(new FocusAdapter() {
262             public void focusLost(FocusEvent e) {
263                 TableTextCellEditor.this.focusLost();
264             }
265         });
266         text.setFont(parent.getFont());
267         text.setBackground(parent.getBackground());
268         text.setText("");//$NON-NLS-1$
269
text.addModifyListener(getModifyListener());
270         
271         return result;
272     }
273
274     protected void fireCancelEditor() {
275         /* bug 58540: change signature refactoring interaction: validate as you type [refactoring] */
276         text.setText(fOriginalValue);
277         super.fireApplyEditorValue();
278     }
279         
280     /**
281      * The <code>TextCellEditor</code> implementation of
282      * this <code>CellEditor</code> framework method returns
283      * the text string.
284      *
285      * @return the text string
286      */

287     protected Object JavaDoc doGetValue() {
288         return text.getText();
289     }
290
291     protected void doSetFocus() {
292         if (text != null) {
293             text.selectAll();
294             text.setFocus();
295             checkSelection();
296             checkDeleteable();
297             checkSelectable();
298         }
299     }
300
301     /**
302      * The <code>TextCellEditor2</code> implementation of
303      * this <code>CellEditor</code> framework method accepts
304      * a text string (type <code>String</code>).
305      *
306      * @param value a text string (type <code>String</code>)
307      */

308     protected void doSetValue(Object JavaDoc value) {
309         Assert.isTrue(text != null && (value instanceof String JavaDoc));
310         text.removeModifyListener(getModifyListener());
311         text.setText((String JavaDoc) value);
312         text.addModifyListener(getModifyListener());
313     }
314
315     /**
316      * Processes a modify event that occurred in this text cell editor.
317      * This framework method performs validation and sets the error message
318      * accordingly, and then reports a change via <code>fireEditorValueChanged</code>.
319      * Subclasses should call this method at appropriate times. Subclasses
320      * may extend or reimplement.
321      *
322      * @param e the SWT modify event
323      */

324     protected void editOccured(ModifyEvent e) {
325         String JavaDoc value = text.getText();
326         boolean oldValidState = isValueValid();
327         boolean newValidState = isCorrect(value);
328         if (!newValidState) {
329             // try to insert the current value into the error message.
330
setErrorMessage(Messages.format(getErrorMessage(),
331                     new Object JavaDoc[] { value }));
332         }
333         valueChanged(oldValidState, newValidState);
334         fireModifyEvent(text.getText()); // update model on-the-fly
335
}
336
337     public LayoutData getLayoutData() {
338         return new LayoutData();
339     }
340
341     protected void handleDefaultSelection(SelectionEvent event) {
342         // same with enter-key handling code in keyReleaseOccured(e);
343
fireApplyEditorValue();
344         deactivate();
345     }
346
347     public boolean isCopyEnabled() {
348         if (text == null || text.isDisposed())
349             return false;
350         return text.getSelectionCount() > 0;
351     }
352
353     public boolean isCutEnabled() {
354         if (text == null || text.isDisposed())
355             return false;
356         return text.getSelectionCount() > 0;
357     }
358
359     public boolean isDeleteEnabled() {
360         if (text == null || text.isDisposed())
361             return false;
362         return text.getSelectionCount() > 0
363                 || text.getCaretPosition() < text.getCharCount();
364     }
365
366     public boolean isPasteEnabled() {
367         if (text == null || text.isDisposed())
368             return false;
369         return true;
370     }
371
372     public boolean isSelectAllEnabled() {
373         if (text == null || text.isDisposed())
374             return false;
375         return text.getCharCount() > 0;
376     }
377
378     protected void keyReleaseOccured(KeyEvent keyEvent) {
379         if (keyEvent.character == '\r') { // Return key
380
// Enter is handled in handleDefaultSelection.
381
// Do not apply the editor value in response to an Enter key event
382
// since this can be received from the IME when the intent is -not-
383
// to apply the value.
384
// See bug 39074 [CellEditors] [DBCS] canna input mode fires bogus event from Text Control
385
//
386
// An exception is made for Ctrl+Enter for multi-line texts, since
387
// a default selection event is not sent in this case.
388
if (text != null && !text.isDisposed()
389                     && (text.getStyle() & SWT.MULTI) != 0) {
390                 if ((keyEvent.stateMask & SWT.CTRL) != 0) {
391                     super.keyReleaseOccured(keyEvent);
392                 }
393             }
394             return;
395         }
396         super.keyReleaseOccured(keyEvent);
397     }
398
399     public void performCopy() {
400         text.copy();
401     }
402
403     public void performCut() {
404         text.cut();
405         checkSelection();
406         checkDeleteable();
407         checkSelectable();
408     }
409
410     public void performDelete() {
411         if (text.getSelectionCount() > 0)
412             // remove the contents of the current selection
413
text.insert(""); //$NON-NLS-1$
414
else {
415             // remove the next character
416
int pos = text.getCaretPosition();
417             if (pos < text.getCharCount()) {
418                 text.setSelection(pos, pos + 1);
419                 text.insert(""); //$NON-NLS-1$
420
}
421         }
422         checkSelection();
423         checkDeleteable();
424         checkSelectable();
425     }
426
427     public void performPaste() {
428         text.paste();
429         checkSelection();
430         checkDeleteable();
431         checkSelectable();
432     }
433
434     public void performSelectAll() {
435         text.selectAll();
436         checkSelection();
437         checkDeleteable();
438     }
439
440 }
441
Popular Tags