Added
Link Here
|
1 |
package org.eclipse.ui.views.bookmarkexplorer; |
2 |
|
3 |
/********************************************************************** |
4 |
Copyright (c) 2000, 2002 IBM Corp. and others. |
5 |
All rights reserved. This program and the accompanying materials |
6 |
are made available under the terms of the Common Public License v1.0 |
7 |
which accompanies this distribution, and is available at |
8 |
http://www.eclipse.org/legal/cpl-v10.html |
9 |
|
10 |
Contributors: |
11 |
Sebastian Davids <sdavids@gmx.de> - initial version |
12 |
*********************************************************************/ |
13 |
|
14 |
import org.eclipse.core.resources.IMarker; |
15 |
import org.eclipse.core.runtime.CoreException; |
16 |
import org.eclipse.jface.dialogs.ErrorDialog; |
17 |
import org.eclipse.jface.dialogs.IInputValidator; |
18 |
import org.eclipse.jface.dialogs.InputDialog; |
19 |
import org.eclipse.jface.viewers.IStructuredSelection; |
20 |
import org.eclipse.jface.viewers.TreeViewer; |
21 |
import org.eclipse.jface.window.Window; |
22 |
import org.eclipse.swt.SWT; |
23 |
import org.eclipse.swt.custom.TreeEditor; |
24 |
import org.eclipse.swt.events.FocusAdapter; |
25 |
import org.eclipse.swt.events.FocusEvent; |
26 |
import org.eclipse.swt.graphics.Point; |
27 |
import org.eclipse.swt.widgets.Composite; |
28 |
import org.eclipse.swt.widgets.Event; |
29 |
import org.eclipse.swt.widgets.Listener; |
30 |
import org.eclipse.swt.widgets.Text; |
31 |
import org.eclipse.swt.widgets.Tree; |
32 |
import org.eclipse.ui.help.WorkbenchHelp; |
33 |
|
34 |
/** |
35 |
* Action to rename the selected bookmarks. |
36 |
*/ |
37 |
/* package */ class RenameBookmarkAction extends BookmarkAction { |
38 |
|
39 |
/* The tree editing widgets. If treeEditor is null then edit using the |
40 |
dialog. We keep the editorText around so that we can close it if |
41 |
a new selection is made. */ |
42 |
private TreeEditor fTreeEditor; |
43 |
private Text fTextEditor; |
44 |
private Composite fTextEditorParent; |
45 |
|
46 |
//The bookmark being edited if this is being done inline |
47 |
private IMarker fInlinedBookmark; |
48 |
|
49 |
/** |
50 |
* Create a new action for the given view. Using this constructor will |
51 |
* rename using a dialog rather than the inline editor of a |
52 |
* BookmarkNavigator. |
53 |
* |
54 |
* @param view the view showing bookmarks |
55 |
* @since 2.1 |
56 |
*/ |
57 |
public RenameBookmarkAction(BookmarkNavigator view) { |
58 |
this(view, null); |
59 |
} |
60 |
|
61 |
/** |
62 |
* Create a new action for the given view; an inline editor will be used to |
63 |
* change the bookmarks name. |
64 |
* |
65 |
* @param view the view showing bookmarks |
66 |
* @param tree the tree we want to use an inline editor on. |
67 |
* |
68 |
* @since 2.1 |
69 |
*/ |
70 |
public RenameBookmarkAction(BookmarkNavigator view, Tree tree) { |
71 |
super(view, BookmarkMessages.getString("RenameBookmark.text")); //$NON-NLS-1$ |
72 |
|
73 |
setToolTipText(BookmarkMessages.getString("RenameBookmark.toolTip")); //$NON-NLS-1$ |
74 |
WorkbenchHelp.setHelp(this, IBookmarkHelpContextIds.REMOVE_BOOKMARK_ACTION); |
75 |
setEnabled(false); |
76 |
|
77 |
if (tree != null) |
78 |
fTreeEditor = new TreeEditor(tree); |
79 |
} |
80 |
|
81 |
/** |
82 |
* Rename the marker selection. |
83 |
*/ |
84 |
public void run() { |
85 |
IStructuredSelection sel = getStructuredSelection(); |
86 |
|
87 |
if (sel.isEmpty()) |
88 |
return; |
89 |
|
90 |
Object o = sel.getFirstElement(); |
91 |
|
92 |
if (!(o instanceof IMarker)) |
93 |
return; |
94 |
|
95 |
IMarker marker = (IMarker) o; |
96 |
|
97 |
try { |
98 |
if (!IMarker.BOOKMARK.equals(marker.getType())) |
99 |
return; |
100 |
|
101 |
String oldName = getOldName(marker); |
102 |
|
103 |
if (oldName == null) |
104 |
return; |
105 |
|
106 |
if (fTreeEditor == null) { |
107 |
String newName = queryNewBookmarkNameDialog(oldName); |
108 |
|
109 |
if (newName != null) |
110 |
marker.setAttribute(IMarker.MESSAGE, newName); |
111 |
} else |
112 |
queryNewBookmarkNameInline(marker, oldName); |
113 |
} catch (CoreException e) { |
114 |
ErrorDialog.openError(getView().getShell(), BookmarkMessages.getString("RenameBookmark.errorTitle"), null, e.getStatus()); //$NON-NLS-1$ |
115 |
} |
116 |
} |
117 |
|
118 |
/** |
119 |
* Disables this action if the selection is empty. |
120 |
*/ |
121 |
public void selectionChanged(IStructuredSelection selection) { |
122 |
disposeTextWidget(); |
123 |
|
124 |
setEnabled(!selection.isEmpty()); |
125 |
} |
126 |
|
127 |
private Composite createParent() { |
128 |
Tree tree = ((TreeViewer) getView().getViewer()).getTree(); |
129 |
|
130 |
Composite result = new Composite(tree, SWT.NONE); |
131 |
|
132 |
fTreeEditor.horizontalAlignment = SWT.LEFT; |
133 |
fTreeEditor.grabHorizontal = true; |
134 |
fTreeEditor.setEditor(result, tree.getSelection()[0]); |
135 |
|
136 |
return result; |
137 |
} |
138 |
|
139 |
/** |
140 |
* Create the text editor widget. |
141 |
* |
142 |
* @param bookmark the bookmark to rename |
143 |
*/ |
144 |
private void createTextEditor(final IMarker bookmark) { |
145 |
// Create text editor parent. This draws a nice bounding rect. |
146 |
fTextEditorParent = createParent(); |
147 |
fTextEditorParent.setVisible(false); |
148 |
fTextEditorParent.addListener(SWT.Paint, new Listener() { |
149 |
public void handleEvent (Event e) { |
150 |
Point textSize = fTextEditor.getSize(); |
151 |
Point parentSize = fTextEditorParent.getSize(); |
152 |
e.gc.drawRectangle(0, 0, Math.min(textSize.x + 4, parentSize.x - 1), parentSize.y - 1); |
153 |
} |
154 |
}); |
155 |
|
156 |
// Create inner text editor. |
157 |
fTextEditor = new Text(fTextEditorParent, SWT.NONE); |
158 |
fTextEditorParent.setBackground(fTextEditor.getBackground()); |
159 |
fTextEditor.addListener(SWT.Modify, new Listener() { |
160 |
public void handleEvent (Event e) { |
161 |
Point textSize = fTextEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
162 |
textSize.x += textSize.y; // Add extra space for new characters. |
163 |
Point parentSize = fTextEditorParent.getSize(); |
164 |
fTextEditor.setBounds(2, 1, Math.min(textSize.x, parentSize.x - 4), parentSize.y - 2); |
165 |
fTextEditorParent.redraw(); |
166 |
} |
167 |
}); |
168 |
|
169 |
fTextEditor.addListener(SWT.Traverse, new Listener() { |
170 |
public void handleEvent(Event event) { |
171 |
//Workaround for Bug 20214 due to extra |
172 |
//traverse events |
173 |
switch (event.detail) { |
174 |
case SWT.TRAVERSE_ESCAPE: |
175 |
//Do nothing in this case |
176 |
disposeTextWidget(); |
177 |
event.doit = true; |
178 |
event.detail = SWT.TRAVERSE_NONE; |
179 |
break; |
180 |
case SWT.TRAVERSE_RETURN: |
181 |
saveChangesAndDispose(bookmark); |
182 |
event.doit = true; |
183 |
event.detail = SWT.TRAVERSE_NONE; |
184 |
break; |
185 |
} |
186 |
} |
187 |
}); |
188 |
|
189 |
fTextEditor.addFocusListener(new FocusAdapter() { |
190 |
public void focusLost(FocusEvent fe) { |
191 |
saveChangesAndDispose(bookmark); |
192 |
} |
193 |
}); |
194 |
} |
195 |
|
196 |
/** |
197 |
* Close the text widget and reset the editorText field. |
198 |
*/ |
199 |
private void disposeTextWidget() { |
200 |
if (fTextEditorParent == null) |
201 |
return; |
202 |
|
203 |
fTextEditorParent.dispose(); |
204 |
fTextEditorParent = null; |
205 |
fTextEditor = null; |
206 |
fTreeEditor.setEditor(null,null); |
207 |
} |
208 |
/** |
209 |
* Return the old name of the target bookmark or <code>null</code> if an |
210 |
* error occurred. |
211 |
*/ |
212 |
private String getOldName(IMarker bookmark) { |
213 |
try { |
214 |
return (String) bookmark.getAttribute(IMarker.MESSAGE); |
215 |
} catch (CoreException e) { |
216 |
ErrorDialog.openError(getView().getShell(), BookmarkMessages.getString("RenameBookmark.errorTitle"), null, e.getStatus()); //$NON-NLS-1$ |
217 |
return null; |
218 |
} |
219 |
} |
220 |
|
221 |
/** |
222 |
* Return the new name to be given to the target bookmarkor |
223 |
* <code>null</code> if an error occurred; uses an Dialog. |
224 |
*/ |
225 |
private String queryNewBookmarkNameDialog(String oldName) { |
226 |
String title = BookmarkMessages.getString("RenameBookmarkDialog.title"); //$NON-NLS-1$ |
227 |
String message = BookmarkMessages.getString("RenameBookmarkDialog.message"); //$NON-NLS-1$ |
228 |
|
229 |
IInputValidator inputValidator = new IInputValidator() { |
230 |
public String isValid(String newText) { |
231 |
return (newText == null || newText.length() == 0) ? " " : null; //$NON-NLS-1$ |
232 |
} |
233 |
}; |
234 |
|
235 |
InputDialog dialog = new InputDialog(getView().getShell(), title, message, oldName, inputValidator); |
236 |
|
237 |
if (dialog.open() != Window.CANCEL) { |
238 |
String name = dialog.getValue(); |
239 |
|
240 |
if (name == null) |
241 |
return null; |
242 |
|
243 |
name = name.trim(); |
244 |
|
245 |
return (name.length() == 0) ? null : name; |
246 |
} else |
247 |
return null; |
248 |
} |
249 |
|
250 |
/** |
251 |
* Inline editing of the bookmarks name. |
252 |
*/ |
253 |
private void queryNewBookmarkNameInline(IMarker bookmark, String oldName) { |
254 |
// Make sure text editor is created only once. Simply reset text |
255 |
// editor when action is executed more than once. Fixes bug 22269. |
256 |
if (fTextEditorParent == null) |
257 |
createTextEditor(bookmark); |
258 |
|
259 |
fTextEditor.setText(oldName); |
260 |
|
261 |
// Open text editor with initial size. |
262 |
fTextEditorParent.setVisible(true); |
263 |
|
264 |
Point textSize = fTextEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
265 |
textSize.x += textSize.y; // Add extra space for new characters. |
266 |
Point parentSize = fTextEditorParent.getSize(); |
267 |
|
268 |
fTextEditor.setBounds(2, 1, Math.min(textSize.x, parentSize.x - 4), parentSize.y - 2); |
269 |
fTextEditorParent.redraw(); |
270 |
fTextEditor.selectAll (); |
271 |
fTextEditor.setFocus (); |
272 |
} |
273 |
|
274 |
/** |
275 |
* Save the changes and dispose of the text widget. |
276 |
* @param bookmark the bookmark to be renamed. |
277 |
*/ |
278 |
private void saveChangesAndDispose(IMarker bookmark) { |
279 |
// Cache the bookmark to avoid selection loss since a selection of |
280 |
// another item can trigger this method |
281 |
fInlinedBookmark = bookmark; |
282 |
|
283 |
final String newLabel = fTextEditor.getText().trim(); |
284 |
|
285 |
// Run this in an async to make sure that the operation that triggered |
286 |
// this action is completed. Otherwise this leads to problems when the |
287 |
// icon of the item being renamed is clicked (i.e., which causes the rename |
288 |
// text widget to lose focus and trigger this method). |
289 |
Runnable query = new Runnable() { |
290 |
public void run() { |
291 |
//Dispose the text widget regardless |
292 |
disposeTextWidget(); |
293 |
|
294 |
try { |
295 |
if ("".equals(newLabel)) //$NON-NLS-1$ |
296 |
return; |
297 |
|
298 |
fInlinedBookmark.setAttribute(IMarker.MESSAGE, newLabel); |
299 |
} catch (CoreException e) { |
300 |
ErrorDialog.openError(getView().getShell(), BookmarkMessages.getString("RenameBookmark.errorTitle"), null, e.getStatus()); //$NON-NLS-1$ |
301 |
} |
302 |
|
303 |
fInlinedBookmark = null; |
304 |
} |
305 |
}; |
306 |
|
307 |
getView().getShell().getDisplay().asyncExec(query); |
308 |
} |
309 |
} |