KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > navigator > NavigatorSiteEditor


1 /*******************************************************************************
2  * Copyright (c) 2003, 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.ui.internal.navigator;
12
13 import org.eclipse.jface.viewers.ILabelProvider;
14 import org.eclipse.jface.viewers.IStructuredSelection;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.custom.TreeEditor;
17 import org.eclipse.swt.events.FocusAdapter;
18 import org.eclipse.swt.events.FocusEvent;
19 import org.eclipse.swt.graphics.Point;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Event;
22 import org.eclipse.swt.widgets.Listener;
23 import org.eclipse.swt.widgets.Text;
24 import org.eclipse.swt.widgets.Tree;
25 import org.eclipse.swt.widgets.TreeItem;
26 import org.eclipse.ui.internal.navigator.extensions.INavigatorSiteEditor;
27 import org.eclipse.ui.navigator.CommonViewer;
28
29
30 /**
31  * A NavigatorSiteEditor is used to edit (i.e., rename) elements in a Navigator view. It displays a
32  * text editor box overlay on the Navigator tree widget.
33  *
34  * @since 3.2
35  */

36 public class NavigatorSiteEditor implements INavigatorSiteEditor {
37
38     private Tree navigatorTree;
39     private TreeEditor treeEditor;
40     private Text textEditor;
41     private Composite textEditorParent;
42     private TextActionHandler textActionHandler;
43     private String JavaDoc text; // the text being edited
44
private CommonViewer commonViewer;
45
46
47     /**
48      * Creates an instance of a NavigatorSiteEditor.
49      *
50      * @param aCommonViewer
51      * the viewer this editor applies to
52      * @param navigatorTree
53      * the tree that is being edited
54      */

55     public NavigatorSiteEditor(CommonViewer aCommonViewer, Tree navigatorTree) {
56         commonViewer = aCommonViewer;
57         this.navigatorTree = navigatorTree;
58         treeEditor = new TreeEditor(navigatorTree);
59     }
60
61     /**
62      * Creates the parent composite for the editor overlay.
63      *
64      * @return the parent composite for the editor overlay
65      */

66     Composite createParent() {
67         Composite result = new Composite(navigatorTree, SWT.NONE);
68         TreeItem[] selectedItems = navigatorTree.getSelection();
69         treeEditor.horizontalAlignment = SWT.LEFT;
70         treeEditor.grabHorizontal = true;
71         treeEditor.setEditor(result, selectedItems[0]);
72         return result;
73     }
74
75     /**
76      * Creates the text editor widget.
77      *
78      * @param runnable
79      * the Runnable to execute when editing ends by the user pressing enter or clicking
80      * outside the text editor box.
81      */

82     void createTextEditor(final Runnable JavaDoc runnable) {
83         // Create text editor parent. This draws a nice bounding rect.
84
textEditorParent = createParent();
85         textEditorParent.setVisible(false);
86         textEditorParent.addListener(SWT.Paint, new Listener() {
87             public void handleEvent(Event e) {
88                 Point textSize = textEditor.getSize();
89                 Point parentSize = textEditorParent.getSize();
90                 e.gc.drawRectangle(0, 0, Math.min(textSize.x + 4, parentSize.x - 1), parentSize.y - 1);
91             }
92         });
93
94         // Create inner text editor.
95
textEditor = new Text(textEditorParent, SWT.NONE);
96         textEditorParent.setBackground(textEditor.getBackground());
97         textEditor.addListener(SWT.Modify, new Listener() {
98             public void handleEvent(Event e) {
99                 Point textSize = textEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT);
100                 textSize.x += textSize.y; // Add extra space for new characters.
101
Point parentSize = textEditorParent.getSize();
102                 textEditor.setBounds(2, 1, Math.min(textSize.x, parentSize.x - 4), parentSize.y - 2);
103                 textEditorParent.redraw();
104             }
105         });
106         textEditor.addListener(SWT.Traverse, new Listener() {
107             public void handleEvent(Event event) {
108                 //Workaround for Bug 20214 due to extra
109
//traverse events
110
switch (event.detail) {
111                     case SWT.TRAVERSE_ESCAPE :
112                         //Do nothing in this case
113
disposeTextWidget();
114                         event.doit = true;
115                         event.detail = SWT.TRAVERSE_NONE;
116                         break;
117                     case SWT.TRAVERSE_RETURN :
118                         saveChangesAndDispose(runnable);
119                         event.doit = true;
120                         event.detail = SWT.TRAVERSE_NONE;
121                         break;
122                 }
123             }
124         });
125         textEditor.addFocusListener(new FocusAdapter() {
126             public void focusLost(FocusEvent fe) {
127                 saveChangesAndDispose(runnable);
128             }
129         });
130
131         if (textActionHandler != null) {
132             textActionHandler.addText(textEditor);
133         }
134     }
135
136     /**
137      * Closes the text editor widget.
138      */

139     void disposeTextWidget() {
140         if (textActionHandler != null) {
141             textActionHandler.removeText(textEditor);
142         }
143         if (textEditorParent != null) {
144             textEditorParent.dispose();
145             textEditorParent = null;
146             textEditor = null;
147             treeEditor.setEditor(null, null);
148         }
149     }
150
151     /**
152      * Displays a text editor overlay on the tree widget.
153      *
154      * @param runnable
155      * Runnable to execute when editing ends either by the user pressing enter or
156      * clicking outside the editor box.
157      */

158     public void edit(Runnable JavaDoc runnable) {
159         IStructuredSelection selection = (IStructuredSelection) commonViewer.getSelection();
160
161         if (selection.size() != 1) {
162             return;
163         }
164         text = getLabel(selection.getFirstElement());
165         if (text == null) {
166             return;
167         }
168         // Make sure text editor is created only once. Simply reset text
169
// editor when action is executed more than once. Fixes bug 22269.
170
if (textEditorParent == null) {
171             createTextEditor(runnable);
172         }
173         textEditor.setText(text);
174         // Open text editor with initial size.
175
textEditorParent.setVisible(true);
176         Point textSize = textEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT);
177         textSize.x += textSize.y; // Add extra space for new characters.
178
Point parentSize = textEditorParent.getSize();
179         textEditor.setBounds(2, 1, Math.min(textSize.x, parentSize.x - 4), parentSize.y - 2);
180         textEditorParent.redraw();
181         textEditor.selectAll();
182         textEditor.setFocus();
183     }
184
185     /**
186      * Returns the displayed label of the given element.
187      *
188      * @param element
189      * the element that is displayed in the navigator
190      * @return the displayed label of the given element.
191      */

192     String JavaDoc getLabel(Object JavaDoc element) {
193         return ((ILabelProvider) commonViewer.getLabelProvider()).getText(element);
194     }
195
196  
197     public String JavaDoc getText() {
198         return text;
199     }
200
201     /**
202      * Saves the changes and disposes of the text widget.
203      *
204      * @param runnable
205      * Runnable to execute
206      */

207     void saveChangesAndDispose(final Runnable JavaDoc runnable) {
208         final String JavaDoc newText = textEditor.getText();
209         // Run this in an async to make sure that the operation that triggered
210
// this action is completed. Otherwise this leads to problems when the
211
// icon of the item being renamed is clicked (i.e., which causes the rename
212
// text widget to lose focus and trigger this method).
213
Runnable JavaDoc editRunnable = new Runnable JavaDoc() {
214             public void run() {
215                 disposeTextWidget();
216                 if (newText.length() > 0 && newText.equals(text) == false) {
217                     text = newText;
218                     runnable.run();
219                 }
220                 text = null;
221             }
222         };
223         navigatorTree.getShell().getDisplay().asyncExec(editRunnable);
224     }
225
226  
227     public void setTextActionHandler(TextActionHandler actionHandler) {
228         textActionHandler = actionHandler;
229     }
230
231 }
232
Popular Tags