Project

General

Profile

Download (7.25 KB) Statistics
| Branch: | Tag: | Revision:
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 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 runnable) {
83
		// Create text editor parent. This draws a nice bounding rect.
84
		textEditorParent = createParent();
85
		textEditorParent.setVisible(false);
86
// RAP [bmichalik]: unsupported event type handler removed  
87
//		textEditorParent.addListener(SWT.Paint, new Listener() {
88
//			public void handleEvent(Event e) {
89
//				Point textSize = textEditor.getSize();
90
//				Point parentSize = textEditorParent.getSize();
91
//				e.gc.drawRectangle(0, 0, Math.min(textSize.x + 4, parentSize.x - 1), parentSize.y - 1);
92
//			}
93
//		});
94

    
95
		// Create inner text editor.
96
		textEditor = new Text(textEditorParent, SWT.NONE);
97
		textEditorParent.setBackground(textEditor.getBackground());
98
		textEditor.addListener(SWT.Modify, new Listener() {
99
			public void handleEvent(Event e) {
100
				Point textSize = textEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT);
101
				textSize.x += textSize.y; // Add extra space for new characters.
102
				Point parentSize = textEditorParent.getSize();
103
				textEditor.setBounds(2, 1, Math.min(textSize.x, parentSize.x - 4), parentSize.y - 2);
104
				textEditorParent.redraw();
105
			}
106
		});
107
		textEditor.addListener(SWT.Traverse, new Listener() {
108
			public void handleEvent(Event event) {
109
				//Workaround for Bug 20214 due to extra
110
				//traverse events
111
				switch (event.detail) {
112
					case SWT.TRAVERSE_ESCAPE :
113
						//Do nothing in this case
114
						disposeTextWidget();
115
						event.doit = true;
116
						event.detail = SWT.TRAVERSE_NONE;
117
						break;
118
					case SWT.TRAVERSE_RETURN :
119
						saveChangesAndDispose(runnable);
120
						event.doit = true;
121
						event.detail = SWT.TRAVERSE_NONE;
122
						break;
123
				}
124
			}
125
		});
126
		textEditor.addFocusListener(new FocusAdapter() {
127
			public void focusLost(FocusEvent fe) {
128
				saveChangesAndDispose(runnable);
129
			}
130
		});
131

    
132
		if (textActionHandler != null) {
133
			textActionHandler.addText(textEditor);
134
		}
135
	}
136

    
137
	/**
138
	 * Closes the text editor widget.
139
	 */
140
	void disposeTextWidget() {
141
		if (textActionHandler != null) {
142
			textActionHandler.removeText(textEditor);
143
		}
144
		if (textEditorParent != null) {
145
			textEditorParent.dispose();
146
			textEditorParent = null;
147
			textEditor = null;
148
			treeEditor.setEditor(null, null);
149
		}
150
	}
151

    
152
	/**
153
	 * Displays a text editor overlay on the tree widget.
154
	 * 
155
	 * @param runnable
156
	 *            Runnable to execute when editing ends either by the user pressing enter or
157
	 *            clicking outside the editor box.
158
	 */
159
	public void edit(Runnable runnable) {
160
		IStructuredSelection selection = (IStructuredSelection) commonViewer.getSelection();
161

    
162
		if (selection.size() != 1) {
163
			return;
164
		}
165
		text = getLabel(selection.getFirstElement());
166
		if (text == null) {
167
			return;
168
		}
169
		// Make sure text editor is created only once. Simply reset text
170
		// editor when action is executed more than once. Fixes bug 22269.
171
		if (textEditorParent == null) {
172
			createTextEditor(runnable);
173
		}
174
		textEditor.setText(text);
175
		// Open text editor with initial size.
176
		textEditorParent.setVisible(true);
177
		Point textSize = textEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT);
178
		textSize.x += textSize.y; // Add extra space for new characters.
179
		Point parentSize = textEditorParent.getSize();
180
		textEditor.setBounds(2, 1, Math.min(textSize.x, parentSize.x - 4), parentSize.y - 2);
181
		textEditorParent.redraw();
182
		textEditor.selectAll();
183
		textEditor.setFocus();
184
	}
185

    
186
	/**
187
	 * Returns the displayed label of the given element.
188
	 * 
189
	 * @param element
190
	 *            the element that is displayed in the navigator
191
	 * @return the displayed label of the given element.
192
	 */
193
	String getLabel(Object element) {
194
		return ((ILabelProvider) commonViewer.getLabelProvider()).getText(element);
195
	}
196

    
197
 
198
	public String getText() {
199
		return text;
200
	}
201

    
202
	/**
203
	 * Saves the changes and disposes of the text widget.
204
	 * 
205
	 * @param runnable
206
	 *            Runnable to execute
207
	 */
208
	void saveChangesAndDispose(final Runnable runnable) {
209
		final String newText = textEditor.getText();
210
		// Run this in an async to make sure that the operation that triggered
211
		// this action is completed. Otherwise this leads to problems when the
212
		// icon of the item being renamed is clicked (i.e., which causes the rename
213
		// text widget to lose focus and trigger this method).
214
		Runnable editRunnable = new Runnable() {
215
			public void run() {
216
				disposeTextWidget();
217
				if (newText.length() > 0 && newText.equals(text) == false) {
218
					text = newText;
219
					runnable.run();
220
				}
221
				text = null;
222
			}
223
		};
224
		navigatorTree.getShell().getDisplay().asyncExec(editRunnable);
225
	}
226

    
227
 
228
	public void setTextActionHandler(TextActionHandler actionHandler) {
229
		textActionHandler = actionHandler;
230
	}
231

    
232
}
(25-25/31)