Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2007 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.texteditor.templates; |
12 |
|
13 |
import java.io.IOException; |
14 |
import java.util.ArrayList; |
15 |
import java.util.Arrays; |
16 |
import java.util.Iterator; |
17 |
import java.util.List; |
18 |
|
19 |
import org.eclipse.jface.action.Action; |
20 |
import org.eclipse.jface.action.IAction; |
21 |
import org.eclipse.jface.action.IMenuListener; |
22 |
import org.eclipse.jface.action.IMenuManager; |
23 |
import org.eclipse.jface.action.IToolBarManager; |
24 |
import org.eclipse.jface.action.MenuManager; |
25 |
import org.eclipse.jface.action.Separator; |
26 |
import org.eclipse.jface.dialogs.Dialog; |
27 |
import org.eclipse.jface.dialogs.MessageDialog; |
28 |
import org.eclipse.jface.layout.TreeColumnLayout; |
29 |
import org.eclipse.jface.preference.IPreferenceStore; |
30 |
import org.eclipse.jface.resource.JFaceResources; |
31 |
import org.eclipse.jface.text.Document; |
32 |
import org.eclipse.jface.text.IDocument; |
33 |
import org.eclipse.jface.text.source.SourceViewer; |
34 |
import org.eclipse.jface.text.source.SourceViewerConfiguration; |
35 |
import org.eclipse.jface.text.templates.ContextTypeRegistry; |
36 |
import org.eclipse.jface.text.templates.Template; |
37 |
import org.eclipse.jface.text.templates.TemplateContextType; |
38 |
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData; |
39 |
import org.eclipse.jface.text.templates.persistence.TemplateStore; |
40 |
import org.eclipse.jface.util.IPropertyChangeListener; |
41 |
import org.eclipse.jface.util.PropertyChangeEvent; |
42 |
import org.eclipse.jface.viewers.ColumnWeightData; |
43 |
import org.eclipse.jface.viewers.DoubleClickEvent; |
44 |
import org.eclipse.jface.viewers.IDoubleClickListener; |
45 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
46 |
import org.eclipse.jface.viewers.IStructuredSelection; |
47 |
import org.eclipse.jface.viewers.ITableLabelProvider; |
48 |
import org.eclipse.jface.viewers.ITreeContentProvider; |
49 |
import org.eclipse.jface.viewers.LabelProvider; |
50 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
51 |
import org.eclipse.jface.viewers.StructuredSelection; |
52 |
import org.eclipse.jface.viewers.TreeViewer; |
53 |
import org.eclipse.jface.viewers.Viewer; |
54 |
import org.eclipse.jface.viewers.ViewerComparator; |
55 |
import org.eclipse.jface.window.Window; |
56 |
import org.eclipse.swt.SWT; |
57 |
import org.eclipse.swt.dnd.Clipboard; |
58 |
import org.eclipse.swt.dnd.DND; |
59 |
import org.eclipse.swt.dnd.DragSourceAdapter; |
60 |
import org.eclipse.swt.dnd.DragSourceEvent; |
61 |
import org.eclipse.swt.dnd.DropTargetAdapter; |
62 |
import org.eclipse.swt.dnd.DropTargetEvent; |
63 |
import org.eclipse.swt.dnd.TextTransfer; |
64 |
import org.eclipse.swt.dnd.Transfer; |
65 |
import org.eclipse.swt.graphics.Color; |
66 |
import org.eclipse.swt.graphics.FontMetrics; |
67 |
import org.eclipse.swt.graphics.GC; |
68 |
import org.eclipse.swt.graphics.Image; |
69 |
import org.eclipse.swt.layout.GridData; |
70 |
import org.eclipse.swt.layout.GridLayout; |
71 |
import org.eclipse.swt.widgets.Composite; |
72 |
import org.eclipse.swt.widgets.Control; |
73 |
import org.eclipse.swt.widgets.Label; |
74 |
import org.eclipse.swt.widgets.Menu; |
75 |
import org.eclipse.swt.widgets.Shell; |
76 |
import org.eclipse.swt.widgets.Tree; |
77 |
import org.eclipse.swt.widgets.TreeColumn; |
78 |
import org.eclipse.swt.widgets.TreeItem; |
79 |
import org.eclipse.ui.IActionBars; |
80 |
import org.eclipse.ui.IWorkbenchActionConstants; |
81 |
import org.eclipse.ui.IWorkbenchPartSite; |
82 |
import org.eclipse.ui.actions.ActionFactory; |
83 |
import org.eclipse.ui.dialogs.PreferencesUtil; |
84 |
import org.eclipse.ui.dnd.IDragAndDropService; |
85 |
import org.eclipse.ui.internal.texteditor.TextEditorPlugin; |
86 |
import org.eclipse.ui.part.Page; |
87 |
import org.eclipse.ui.views.templates.ITemplatesPage; |
88 |
|
89 |
/** |
90 |
* An abstract base class for template pages for use with TextEditor. |
91 |
* <p> |
92 |
* Clients who are defining an editor may elect to provide a corresponding |
93 |
* templates page. This templates page will be presented to the user via the |
94 |
* Templates View (the user decides whether their workbench window contains this |
95 |
* view) whenever that editor is active. This class should be subclassed. |
96 |
* </p> |
97 |
* <p> |
98 |
* Internally, a TemplatesPage uses the template store to display different |
99 |
* categories. A link to editor mode on the templates page allows to filtering |
100 |
* of the categories to only that are supported in this context. |
101 |
* </p> |
102 |
* Since: 3.4 |
103 |
*/ |
104 |
public abstract class TemplatesPage extends Page implements ITemplatesPage { |
105 |
|
106 |
/** |
107 |
* Link to editor action setting |
108 |
*/ |
109 |
private static final String LINK_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID |
110 |
+ ".templates.templatesPage.linkAction"; //$NON-NLS-1$ |
111 |
/** |
112 |
* Show disabled actions setting |
113 |
*/ |
114 |
private static final String SHOW_DISABLED_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID |
115 |
+ ".templates.templatesPage.showDisabledAction"; //$NON-NLS-1$ |
116 |
/** |
117 |
* Show new dialog on drop setting |
118 |
*/ |
119 |
private static final String SHOW_NEW_DIALOG_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID |
120 |
+ ".templates.templatesPage.showNewDialogAction"; //$NON-NLS-1$; |
121 |
|
122 |
/** |
123 |
* The ID for the popup menu for this templates page |
124 |
*/ |
125 |
private static final String POPUP_MENU_ID = "org.eclipse.ui.texteditor.templates.PopupMenu"; //$NON-NLS-1$ |
126 |
|
127 |
/** |
128 |
* Drop support for the editor linked to this page. When a user drops a |
129 |
* template into the active editor, the template is applied at the drop |
130 |
* position. |
131 |
*/ |
132 |
private final class EditorDropTarget extends DropTargetAdapter { |
133 |
/* |
134 |
* (non-Javadoc) |
135 |
* |
136 |
* @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent) |
137 |
*/ |
138 |
public void dragEnter(DropTargetEvent event) { |
139 |
super.dragEnter(event); |
140 |
if (event.detail == DND.DROP_DEFAULT) |
141 |
event.detail = DND.DROP_COPY; |
142 |
} |
143 |
|
144 |
/* |
145 |
* (non-Javadoc) |
146 |
* |
147 |
* @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent) |
148 |
*/ |
149 |
public void dragOperationChanged(DropTargetEvent event) { |
150 |
if (event.detail == DND.DROP_DEFAULT) |
151 |
event.detail = DND.DROP_COPY; |
152 |
} |
153 |
|
154 |
/* |
155 |
* (non-Javadoc) |
156 |
* |
157 |
* @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent) |
158 |
*/ |
159 |
public void dragOver(DropTargetEvent event) { |
160 |
event.feedback |= DND.FEEDBACK_SCROLL; |
161 |
} |
162 |
|
163 |
/* |
164 |
* (non-Javadoc) |
165 |
* |
166 |
* @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent) |
167 |
*/ |
168 |
public void drop(DropTargetEvent event) { |
169 |
insertTemplate(getSelectedTemplate()); |
170 |
} |
171 |
} |
172 |
|
173 |
/** |
174 |
* Comparator for the viewer. Sorts the templates by name and then |
175 |
* description and context types by names. |
176 |
*/ |
177 |
private static final class TemplateViewerComparator extends ViewerComparator { |
178 |
/* |
179 |
* (non-Javadoc) |
180 |
* |
181 |
* @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, |
182 |
* java.lang.Object, java.lang.Object) |
183 |
*/ |
184 |
public int compare(Viewer viewer, Object object1, Object object2) { |
185 |
if ((object1 instanceof TemplatePersistenceData) |
186 |
&& (object2 instanceof TemplatePersistenceData)) { |
187 |
Template left = ((TemplatePersistenceData) object1).getTemplate(); |
188 |
Template right = ((TemplatePersistenceData) object2).getTemplate(); |
189 |
int result = left.getName().compareToIgnoreCase(right.getName()); |
190 |
if (result != 0) |
191 |
return result; |
192 |
return left.getDescription().compareToIgnoreCase(right.getDescription()); |
193 |
} |
194 |
if ((object1 instanceof TemplateContextType) |
195 |
&& (object2 instanceof TemplateContextType)) { |
196 |
return ((TemplateContextType) object1).getName().compareToIgnoreCase( |
197 |
((TemplateContextType) object1).getName()); |
198 |
} |
199 |
return super.compare(viewer, object1, object2); |
200 |
} |
201 |
|
202 |
/* |
203 |
* (non-Javadoc) |
204 |
* |
205 |
* @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object, |
206 |
* java.lang.String) |
207 |
*/ |
208 |
public boolean isSorterProperty(Object element, String property) { |
209 |
return true; |
210 |
} |
211 |
} |
212 |
|
213 |
/** |
214 |
* Label provider for templates. |
215 |
*/ |
216 |
private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider { |
217 |
|
218 |
/* |
219 |
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, |
220 |
* int) |
221 |
*/ |
222 |
public Image getColumnImage(Object element, int columnIndex) { |
223 |
return null; |
224 |
} |
225 |
|
226 |
/* |
227 |
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, |
228 |
* int) |
229 |
*/ |
230 |
public String getColumnText(Object element, int columnIndex) { |
231 |
if (element instanceof TemplatePersistenceData) |
232 |
return getTemplateColumnText(((TemplatePersistenceData) element).getTemplate(), |
233 |
columnIndex); |
234 |
return getContextColumnText((TemplateContextType) element, columnIndex); |
235 |
} |
236 |
|
237 |
/** |
238 |
* Return the column text for a template |
239 |
* |
240 |
* @param template |
241 |
* @param columnIndex |
242 |
* @return the column text |
243 |
*/ |
244 |
private String getTemplateColumnText(Template template, int columnIndex) { |
245 |
switch (columnIndex) { |
246 |
case 0: |
247 |
return template.getName(); |
248 |
case 1: |
249 |
return template.getDescription(); |
250 |
default: |
251 |
return ""; //$NON-NLS-1$ |
252 |
} |
253 |
} |
254 |
|
255 |
/** |
256 |
* Return the column text for a context |
257 |
* |
258 |
* @param contextType |
259 |
* @param columnIndex |
260 |
* @return the column text |
261 |
*/ |
262 |
private String getContextColumnText(TemplateContextType contextType, int columnIndex) { |
263 |
switch (columnIndex) { |
264 |
case 0: |
265 |
return contextType.getName(); |
266 |
case 1: |
267 |
return TextEditorTemplateMessages.TemplatesPage_context_description; |
268 |
default: |
269 |
return ""; //$NON-NLS-1$ |
270 |
} |
271 |
} |
272 |
|
273 |
} |
274 |
|
275 |
/** |
276 |
* Content provider for templates. Provides all the templates defined for |
277 |
* this editor and optionally the disabled ones. |
278 |
*/ |
279 |
private class TemplatesContentProvider implements ITreeContentProvider { |
280 |
/* |
281 |
* (non-Javadoc) |
282 |
* |
283 |
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) |
284 |
*/ |
285 |
public Object[] getChildren(Object parentElement) { |
286 |
if (parentElement instanceof TemplatePersistenceData) |
287 |
return new Object[0]; |
288 |
else if (parentElement instanceof TemplateContextType) { |
289 |
TemplateContextType contextType = (TemplateContextType) parentElement; |
290 |
return getTemplates(contextType.getId()); |
291 |
} |
292 |
return null; |
293 |
} |
294 |
|
295 |
/** |
296 |
* Get the templates for a given contextId. if ShowDisabled is selected |
297 |
* the disabled templates are also included. |
298 |
* |
299 |
* @param contextId |
300 |
* @return the templates |
301 |
*/ |
302 |
private TemplatePersistenceData[] getTemplates(String contextId) { |
303 |
List templateList = new ArrayList(); |
304 |
TemplatePersistenceData[] datas = fTemplateStore.getTemplateData(false); |
305 |
boolean showDisabled = fShowDisabledAction.isChecked(); |
306 |
for (int i = 0; i < datas.length; i++) { |
307 |
if ((showDisabled || datas[i].isEnabled()) |
308 |
&& datas[i].getTemplate().getContextTypeId().equals(contextId)) |
309 |
templateList.add(datas[i]); |
310 |
} |
311 |
return (TemplatePersistenceData[]) templateList |
312 |
.toArray(new TemplatePersistenceData[templateList.size()]); |
313 |
} |
314 |
|
315 |
/* |
316 |
* (non-Javadoc) |
317 |
* |
318 |
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) |
319 |
*/ |
320 |
public Object getParent(Object element) { |
321 |
if (element instanceof TemplatePersistenceData) { |
322 |
TemplatePersistenceData templateData = (TemplatePersistenceData) element; |
323 |
return fContextTypeRegistry.getContextType(templateData.getTemplate() |
324 |
.getContextTypeId()); |
325 |
} |
326 |
return null; |
327 |
} |
328 |
|
329 |
/* |
330 |
* (non-Javadoc) |
331 |
* |
332 |
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) |
333 |
*/ |
334 |
public boolean hasChildren(Object element) { |
335 |
if (element instanceof TemplateContextType) |
336 |
return true; |
337 |
return false; |
338 |
} |
339 |
|
340 |
/* |
341 |
* (non-Javadoc) |
342 |
* |
343 |
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) |
344 |
*/ |
345 |
public Object[] getElements(Object inputElement) { |
346 |
List contextTypes = new ArrayList(); |
347 |
|
348 |
for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) { |
349 |
TemplateContextType contextType = (TemplateContextType) iterator.next(); |
350 |
if (isActiveContext(contextType) || !fLinkAction.isChecked()) |
351 |
contextTypes.add(contextType); |
352 |
} |
353 |
return contextTypes.toArray(new TemplateContextType[contextTypes.size()]); |
354 |
} |
355 |
|
356 |
/** |
357 |
* Checks whether given context type is active for displaying the |
358 |
* templates |
359 |
* |
360 |
* @param contextType |
361 |
* @return true if context is active |
362 |
*/ |
363 |
private boolean isActiveContext(TemplateContextType contextType) { |
364 |
return fActiveTypes == null || fActiveTypes.contains(contextType.getId()); |
365 |
} |
366 |
|
367 |
/* |
368 |
* (non-Javadoc) |
369 |
* |
370 |
* @see org.eclipse.jface.viewers.IContentProvider#dispose() |
371 |
*/ |
372 |
public void dispose() { |
373 |
} |
374 |
|
375 |
/* |
376 |
* (non-Javadoc) |
377 |
* |
378 |
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, |
379 |
* java.lang.Object, java.lang.Object) |
380 |
*/ |
381 |
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
382 |
} |
383 |
} |
384 |
|
385 |
/** |
386 |
* Show/Hide new dialog |
387 |
*/ |
388 |
private static final int SHOW_DIALOG = 0; |
389 |
private static final int HIDE_DIALOG = 1; |
390 |
|
391 |
/** The viewer displays the pattern of selected template. */ |
392 |
private SourceViewer fPatternViewer; |
393 |
/** The store for our templates. */ |
394 |
private TemplateStore fTemplateStore; |
395 |
/** The context type registry. */ |
396 |
private ContextTypeRegistry fContextTypeRegistry; |
397 |
|
398 |
/** The control for this page book view */ |
399 |
private Composite fControl; |
400 |
|
401 |
/* Actions */ |
402 |
private Action fInsertAction; |
403 |
private Action fAddAction; |
404 |
private Action fEditAction; |
405 |
private Action fRemoveAction; |
406 |
private Action fLinkAction; |
407 |
private Action fExpandCollapseAction; |
408 |
private Action fPreferencePageAction; |
409 |
private Action fShowDisabledAction; |
410 |
private Action fShowNewDialogOnDropAction; |
411 |
|
412 |
/* Clipboard actions */ |
413 |
private Action fPasteAction; |
414 |
private Action fCopyAction; |
415 |
|
416 |
/** Currently selected templates */ |
417 |
private ArrayList fSelectedTemplateList = new ArrayList(); |
418 |
|
419 |
/** Current active context types for the editor */ |
420 |
private List fActiveTypes; |
421 |
|
422 |
/* Preference stores */ |
423 |
/** |
424 |
* Preference store to store the dialog setting for this page |
425 |
*/ |
426 |
private IPreferenceStore fPreferenceStore; |
427 |
/** |
428 |
* The template stores preference page. Used to listen to the changes and |
429 |
* update the view. Needed when the user selects Preferences and updates the |
430 |
* templates. |
431 |
*/ |
432 |
private IPreferenceStore fTemplatePreferenceStore; |
433 |
|
434 |
/* Controls */ |
435 |
private Tree fTemplatesTree; |
436 |
private TreeViewer fTreeViewer; |
437 |
|
438 |
/** |
439 |
* Creates a new template preference page. |
440 |
*/ |
441 |
protected TemplatesPage() { |
442 |
super(); |
443 |
fPreferenceStore = TextEditorPlugin.getDefault().getPreferenceStore(); |
444 |
} |
445 |
|
446 |
/** |
447 |
* Returns the template store. |
448 |
* |
449 |
* @return the template store |
450 |
*/ |
451 |
public TemplateStore getTemplateStore() { |
452 |
return fTemplateStore; |
453 |
} |
454 |
|
455 |
/** |
456 |
* Returns the context type registry. |
457 |
* |
458 |
* @return the context type registry |
459 |
*/ |
460 |
public ContextTypeRegistry getContextTypeRegistry() { |
461 |
return fContextTypeRegistry; |
462 |
} |
463 |
|
464 |
/** |
465 |
* Sets the template store. |
466 |
* |
467 |
* @param store |
468 |
* the template store |
469 |
* @param templatePreferenceStore |
470 |
* the preference store used for this template store |
471 |
*/ |
472 |
public void setTemplateStore(TemplateStore store, IPreferenceStore templatePreferenceStore) { |
473 |
fTemplateStore = store; |
474 |
fTemplatePreferenceStore = templatePreferenceStore; |
475 |
if (fTemplatePreferenceStore != null) |
476 |
fTemplatePreferenceStore.addPropertyChangeListener(new IPropertyChangeListener() { |
477 |
public void propertyChange(PropertyChangeEvent event) { |
478 |
refresh(); |
479 |
} |
480 |
}); |
481 |
} |
482 |
|
483 |
/** |
484 |
* Sets the context type registry. |
485 |
* |
486 |
* @param registry |
487 |
* the new context type registry |
488 |
*/ |
489 |
public void setContextTypeRegistry(ContextTypeRegistry registry) { |
490 |
fContextTypeRegistry = registry; |
491 |
} |
492 |
|
493 |
/* |
494 |
* (non-Javadoc) |
495 |
* |
496 |
* @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite) |
497 |
*/ |
498 |
public void createControl(Composite ancestor) { |
499 |
setupActions(); |
500 |
|
501 |
fControl = new Composite(ancestor, SWT.NONE); |
502 |
GridLayout layout = new GridLayout(); |
503 |
layout.numColumns = 2; |
504 |
layout.marginHeight = 0; |
505 |
layout.marginWidth = 0; |
506 |
fControl.setLayout(layout); |
507 |
Dialog.applyDialogFont(fControl); |
508 |
|
509 |
createTemplateTree(); |
510 |
createPatternViewer(fControl); |
511 |
|
512 |
hookContextMenu(); |
513 |
initializeDND(); |
514 |
updateButtons(); |
515 |
|
516 |
fControl.layout(true, true); |
517 |
} |
518 |
|
519 |
/** |
520 |
* Create the tree control to display template information |
521 |
*/ |
522 |
private void createTemplateTree() { |
523 |
Composite treeComposite = new Composite(fControl, SWT.NONE); |
524 |
GridData data = new GridData(GridData.FILL_BOTH); |
525 |
treeComposite.setLayoutData(data); |
526 |
|
527 |
TreeColumnLayout columnLayout = new TreeColumnLayout(); |
528 |
treeComposite.setLayout(columnLayout); |
529 |
fTemplatesTree = new Tree(treeComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI |
530 |
| SWT.FULL_SELECTION); |
531 |
fTemplatesTree.setHeaderVisible(true); |
532 |
fTemplatesTree.setLinesVisible(true); |
533 |
|
534 |
GC gc = new GC(getShell()); |
535 |
gc.setFont(JFaceResources.getDialogFont()); |
536 |
|
537 |
TreeColumn columnName = new TreeColumn(fTemplatesTree, SWT.NONE); |
538 |
columnName.setText(TextEditorTemplateMessages.TemplatesPage_column_name); |
539 |
int minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_name).x + 10; |
540 |
columnLayout.setColumnData(columnName, new ColumnWeightData(2, minWidth, true)); |
541 |
|
542 |
TreeColumn columnDescription = new TreeColumn(fTemplatesTree, SWT.NONE); |
543 |
columnDescription.setText(TextEditorTemplateMessages.TemplatesPage_column_description); |
544 |
minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_description).x + 10; |
545 |
columnLayout.setColumnData(columnDescription, new ColumnWeightData(3, minWidth, true)); |
546 |
|
547 |
gc.dispose(); |
548 |
|
549 |
data = new GridData(GridData.FILL_BOTH); |
550 |
data.grabExcessHorizontalSpace = true; |
551 |
data.grabExcessVerticalSpace = true; |
552 |
/* |
553 |
* these hints should not be zero. the grabExcess will ensure that the |
554 |
* tree is sized appropriately the the pattern viewer is displayed below |
555 |
* it. |
556 |
*/ |
557 |
data.heightHint = 5; |
558 |
data.widthHint = 5; |
559 |
fTemplatesTree.setLayoutData(data); |
560 |
createTreeViewer(); |
561 |
} |
562 |
|
563 |
/** |
564 |
* Create the viewer for the tree control and configure it. |
565 |
*/ |
566 |
private void createTreeViewer() { |
567 |
fTreeViewer = new TreeViewer(fTemplatesTree); |
568 |
fTreeViewer.setLabelProvider(new TemplateLabelProvider()); |
569 |
fTreeViewer.setContentProvider(new TemplatesContentProvider()); |
570 |
|
571 |
fTreeViewer.setComparator(new TemplateViewerComparator()); |
572 |
fTreeViewer.setInput(fTemplateStore); |
573 |
fTreeViewer.addDoubleClickListener(new IDoubleClickListener() { |
574 |
public void doubleClick(DoubleClickEvent e) { |
575 |
updateSelectedTemplate(); |
576 |
insertTemplate(getSelectedTemplate()); |
577 |
} |
578 |
}); |
579 |
|
580 |
fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
581 |
public void selectionChanged(SelectionChangedEvent e) { |
582 |
updateSelectedTemplate(); |
583 |
updateButtons(); |
584 |
} |
585 |
}); |
586 |
fTreeViewer.expandAll(); |
587 |
setDisableItemColors(); |
588 |
} |
589 |
|
590 |
/** |
591 |
* Sets all templates in the tree that are disabled to grey. |
592 |
*/ |
593 |
private void setDisableItemColors() { |
594 |
TreeItem[] items = fTemplatesTree.getItems(); |
595 |
Color fgcDisabled = getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY); |
596 |
Color fgcEnabled = getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); |
597 |
for (int i = 0; i < items.length; i++) { |
598 |
TreeItem[] items2 = items[i].getItems(); |
599 |
for (int j = 0; j < items2.length; j++) { |
600 |
TemplatePersistenceData templateData = (TemplatePersistenceData) items2[j] |
601 |
.getData(); |
602 |
if (!templateData.isEnabled() && items2[j].getForeground() != fgcDisabled) |
603 |
items2[j].setForeground(fgcDisabled); |
604 |
else if (templateData.isEnabled() && items2[j].getForeground() != fgcEnabled) |
605 |
items2[j].setForeground(fgcEnabled); |
606 |
} |
607 |
} |
608 |
} |
609 |
|
610 |
/** |
611 |
* Update the selected template list and update the pattern viewer |
612 |
*/ |
613 |
private void updateSelectedTemplate() { |
614 |
IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection(); |
615 |
|
616 |
fSelectedTemplateList.clear(); |
617 |
for (Iterator iterator = selection.iterator(); iterator.hasNext();) { |
618 |
Object item = iterator.next(); |
619 |
if (item instanceof TemplateContextType) { |
620 |
fSelectedTemplateList.clear(); |
621 |
break; |
622 |
} |
623 |
fSelectedTemplateList.add(item); |
624 |
|
625 |
} |
626 |
if (isSingleTemplateSelected()) |
627 |
updateViewerInput(getSelectedTemplate()); |
628 |
else |
629 |
fPatternViewer.getDocument().set(""); //$NON-NLS-1$ |
630 |
} |
631 |
|
632 |
/** |
633 |
* Checks whether only one template is selected in the tree |
634 |
* |
635 |
* @return true if only single template is selected |
636 |
*/ |
637 |
private boolean isSingleTemplateSelected() { |
638 |
return fSelectedTemplateList.size() == 1; |
639 |
} |
640 |
|
641 |
/** |
642 |
* Get the selected template. Note: should always precede with a check for |
643 |
* isSingleTemplateSelected |
644 |
* |
645 |
* @return the template (Not the data) |
646 |
*/ |
647 |
private Template getSelectedTemplate() { |
648 |
return ((TemplatePersistenceData) fSelectedTemplateList.get(0)).getTemplate(); |
649 |
} |
650 |
|
651 |
/** |
652 |
* Create a viewer to display the pattern |
653 |
* |
654 |
* @param parent |
655 |
*/ |
656 |
private void createPatternViewer(Composite parent) { |
657 |
Label previewLabel = new Label(parent, SWT.NONE); |
658 |
previewLabel.setText(TextEditorTemplateMessages.TemplatesPage_preview); |
659 |
GridData data = new GridData(); |
660 |
data.horizontalSpan = 2; |
661 |
previewLabel.setLayoutData(data); |
662 |
|
663 |
fPatternViewer = createViewer(parent); |
664 |
fPatternViewer.setEditable(false); |
665 |
|
666 |
Control control = fPatternViewer.getControl(); |
667 |
data = new GridData(GridData.FILL_BOTH); |
668 |
data.horizontalSpan = 2; |
669 |
|
670 |
Dialog.applyDialogFont(control); |
671 |
GC gc = new GC(control); |
672 |
data.heightHint = convertHeightInCharsToPixels(gc, 5); |
673 |
data.grabExcessVerticalSpace = false; |
674 |
data.verticalAlignment = SWT.FILL; |
675 |
gc.dispose(); |
676 |
|
677 |
control.setLayoutData(data); |
678 |
} |
679 |
|
680 |
/** |
681 |
* Setup the actions |
682 |
*/ |
683 |
private void setupActions() { |
684 |
IActionBars actionBars = getSite().getActionBars(); |
685 |
IToolBarManager toolBarManager = actionBars.getToolBarManager(); |
686 |
IMenuManager menuManager = actionBars.getMenuManager(); |
687 |
|
688 |
fInsertAction = new Action(TextEditorTemplateMessages.TemplatesPage_insert) { |
689 |
public void run() { |
690 |
insertTemplate(getSelectedTemplate()); |
691 |
} |
692 |
}; |
693 |
|
694 |
fAddAction = new Action() { |
695 |
public void run() { |
696 |
addTemplate(); |
697 |
} |
698 |
}; |
699 |
fAddAction.setText(TextEditorTemplateMessages.TemplatesPage_new); |
700 |
fAddAction.setImageDescriptor(TemplateViewImages |
701 |
.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_NEW)); |
702 |
toolBarManager.add(fAddAction); |
703 |
|
704 |
fEditAction = new Action() { |
705 |
public void run() { |
706 |
editTemplate(); |
707 |
} |
708 |
}; |
709 |
fEditAction.setText(TextEditorTemplateMessages.TemplatesPage_edit); |
710 |
fEditAction.setImageDescriptor(TemplateViewImages |
711 |
.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_EDIT)); |
712 |
toolBarManager.add(fEditAction); |
713 |
|
714 |
fRemoveAction = new Action() { |
715 |
public void run() { |
716 |
removeTemplate(); |
717 |
} |
718 |
}; |
719 |
fRemoveAction.setText(TextEditorTemplateMessages.TemplatesPage_remove); |
720 |
fRemoveAction.setImageDescriptor(TemplateViewImages |
721 |
.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_DELETE)); |
722 |
toolBarManager.add(fRemoveAction); |
723 |
|
724 |
toolBarManager.add(new Separator()); |
725 |
|
726 |
fLinkAction = new Action(TextEditorTemplateMessages.TemplatesPage_link_to_editor, |
727 |
IAction.AS_CHECK_BOX) { |
728 |
public void run() { |
729 |
fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkAction.isChecked()); |
730 |
refresh(); |
731 |
} |
732 |
}; |
733 |
fLinkAction.setImageDescriptor(TemplateViewImages |
734 |
.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_LINK)); |
735 |
fLinkAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID)); |
736 |
toolBarManager.add(fLinkAction); |
737 |
|
738 |
fExpandCollapseAction = new Action(TextEditorTemplateMessages.TemplatesPage_collapse_expand) { |
739 |
public void run() { |
740 |
Object[] vee = fTreeViewer.getVisibleExpandedElements(); |
741 |
boolean collapse = vee.length != 0; |
742 |
if (collapse) |
743 |
fTreeViewer.collapseAll(); |
744 |
else |
745 |
fTreeViewer.expandAll(); |
746 |
} |
747 |
}; |
748 |
fExpandCollapseAction.setImageDescriptor(TemplateViewImages |
749 |
.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_COLLAPSE_EXPAND)); |
750 |
toolBarManager.add(fExpandCollapseAction); |
751 |
|
752 |
if (getPreferencePageId() != null) { |
753 |
fPreferencePageAction = new Action() { |
754 |
public void run() { |
755 |
showPreferencePage(); |
756 |
} |
757 |
}; |
758 |
fPreferencePageAction.setText(TextEditorTemplateMessages.TemplatesPage_preference_page); |
759 |
menuManager.add(fPreferencePageAction); |
760 |
} |
761 |
menuManager.add(new Separator()); |
762 |
|
763 |
fShowDisabledAction = new Action(TextEditorTemplateMessages.TemplatesPage_show_disabled, |
764 |
IAction.AS_CHECK_BOX) { |
765 |
public void run() { |
766 |
fPreferenceStore.setValue(SHOW_DISABLED_ACTION_PREF_ID, fShowDisabledAction |
767 |
.isChecked()); |
768 |
refresh(); |
769 |
} |
770 |
}; |
771 |
fPreferenceStore.setDefault(SHOW_DISABLED_ACTION_PREF_ID, false); |
772 |
fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID)); |
773 |
menuManager.add(fShowDisabledAction); |
774 |
|
775 |
fShowNewDialogOnDropAction = new Action( |
776 |
TextEditorTemplateMessages.TemplatesPage_show_new_dialog, IAction.AS_CHECK_BOX) { |
777 |
public void run() { |
778 |
fPreferenceStore.setValue(SHOW_NEW_DIALOG_ACTION_PREF_ID, |
779 |
fShowNewDialogOnDropAction.isChecked()); |
780 |
} |
781 |
}; |
782 |
fPreferenceStore.setDefault(SHOW_NEW_DIALOG_ACTION_PREF_ID, true); |
783 |
fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID)); |
784 |
menuManager.add(fShowNewDialogOnDropAction); |
785 |
|
786 |
menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
787 |
|
788 |
fPasteAction = new Action() { |
789 |
public void run() { |
790 |
Clipboard clipBoard = new Clipboard(getShell().getDisplay()); |
791 |
Object contents = clipBoard.getContents(TextTransfer.getInstance()); |
792 |
if (contents == null) |
793 |
return; |
794 |
final String text = (String) contents; |
795 |
String contextId = getContextId(); |
796 |
final Template template = new Template( |
797 |
TextEditorTemplateMessages.TemplatesPage_snippet, |
798 |
TextEditorTemplateMessages.TemplatesPage_paste_description, contextId, |
799 |
text, true); |
800 |
getShell().getDisplay().asyncExec(new Runnable() { |
801 |
public void run() { |
802 |
addTemplate(template, HIDE_DIALOG); |
803 |
} |
804 |
}); |
805 |
|
806 |
} |
807 |
|
808 |
private String getContextId() { |
809 |
if (isSingleTemplateSelected()) |
810 |
return getSelectedTemplate().getContextTypeId(); |
811 |
IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection(); |
812 |
if (selection.isEmpty()) |
813 |
return getFirstContextTypeId(); |
814 |
Object element = selection.getFirstElement(); |
815 |
if (element instanceof TemplateContextType) |
816 |
return ((TemplateContextType) element).getId(); |
817 |
return ((TemplatePersistenceData) element).getTemplate().getContextTypeId(); |
818 |
} |
819 |
}; |
820 |
actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction); |
821 |
|
822 |
fCopyAction = new Action() { |
823 |
public void run() { |
824 |
if (!isSingleTemplateSelected()) |
825 |
return; |
826 |
Template[] templates = new Template[] { getSelectedTemplate() }; |
827 |
Clipboard clipBoard = new Clipboard(getShell().getDisplay()); |
828 |
clipBoard.setContents(new Object[] { templates }, new Transfer[] { TemplateTransfer |
829 |
.getInstance() }); |
830 |
} |
831 |
}; |
832 |
actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction); |
833 |
} |
834 |
|
835 |
/** |
836 |
* Setup the context menu for the viewer. |
837 |
*/ |
838 |
private void hookContextMenu() { |
839 |
MenuManager menuMgr = new MenuManager(POPUP_MENU_ID); |
840 |
menuMgr.setRemoveAllWhenShown(true); |
841 |
menuMgr.addMenuListener(new IMenuListener() { |
842 |
public void menuAboutToShow(IMenuManager manager) { |
843 |
fillContextMenu(manager); |
844 |
} |
845 |
}); |
846 |
Menu menu = menuMgr.createContextMenu(fTreeViewer.getControl()); |
847 |
fTreeViewer.getControl().setMenu(menu); |
848 |
getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer); |
849 |
} |
850 |
|
851 |
/** |
852 |
* Fill up the context menu |
853 |
* |
854 |
* @param manager |
855 |
*/ |
856 |
protected void fillContextMenu(IMenuManager manager) { |
857 |
manager.add(fInsertAction); |
858 |
manager.add(new Separator()); |
859 |
manager.add(fAddAction); |
860 |
manager.add(fEditAction); |
861 |
manager.add(fRemoveAction); |
862 |
// Other plug-ins can contribute there actions here |
863 |
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
864 |
} |
865 |
|
866 |
/** |
867 |
* Show the preference templates preference page |
868 |
*/ |
869 |
private void showPreferencePage() { |
870 |
PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageId(), null, null) |
871 |
.open(); |
872 |
} |
873 |
|
874 |
/** |
875 |
* Get the preference page ID for the templates for the given editor. |
876 |
* Subclasses should override. |
877 |
* |
878 |
* @return id of the preference page |
879 |
*/ |
880 |
protected String getPreferencePageId() { |
881 |
return null; |
882 |
} |
883 |
|
884 |
/** |
885 |
* Helper to find the size for pattern viewer |
886 |
* |
887 |
* @param gc |
888 |
* @param chars |
889 |
* @return the hieght in pixels |
890 |
*/ |
891 |
private int convertHeightInCharsToPixels(GC gc, int chars) { |
892 |
FontMetrics fontMetrics = gc.getFontMetrics(); |
893 |
return fontMetrics.getHeight() * chars; |
894 |
} |
895 |
|
896 |
/** |
897 |
* Get the shell |
898 |
* |
899 |
* @return the shell for this view site |
900 |
*/ |
901 |
protected Shell getShell() { |
902 |
return getSite().getShell(); |
903 |
} |
904 |
|
905 |
/** |
906 |
* Creates, configures and returns a source viewer to present the template |
907 |
* pattern on the preference page. Clients may override to provide a custom |
908 |
* source viewer featuring e.g. syntax coloring. |
909 |
* |
910 |
* @param parent |
911 |
* the parent control |
912 |
* @return a configured source viewer |
913 |
*/ |
914 |
protected SourceViewer createViewer(Composite parent) { |
915 |
SourceViewer viewer = new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL |
916 |
| SWT.H_SCROLL); |
917 |
SourceViewerConfiguration configuration = new SourceViewerConfiguration(); |
918 |
viewer.configure(configuration); |
919 |
IDocument document = new Document(); |
920 |
viewer.setDocument(document); |
921 |
return viewer; |
922 |
} |
923 |
|
924 |
/** |
925 |
* Updates the pattern viewer. |
926 |
* |
927 |
* @param template |
928 |
*/ |
929 |
protected void updateViewerInput(Template template) { |
930 |
if (template != null) |
931 |
fPatternViewer.getDocument().set(template.getPattern()); |
932 |
else |
933 |
fPatternViewer.getDocument().set(""); //$NON-NLS-1$ |
934 |
} |
935 |
|
936 |
/** |
937 |
* Updates the buttons. |
938 |
*/ |
939 |
private void updateButtons() { |
940 |
fCopyAction.setEnabled(isSingleTemplateSelected()); |
941 |
fInsertAction.setEnabled(isSingleTemplateSelected()); |
942 |
fEditAction.setEnabled(isSingleTemplateSelected()); |
943 |
fRemoveAction.setEnabled(fSelectedTemplateList.size() != 0); |
944 |
} |
945 |
|
946 |
/** |
947 |
* Add a template |
948 |
*/ |
949 |
private void addTemplate() { |
950 |
String id = getFirstContextTypeId(); |
951 |
if (id != null) { |
952 |
Template template = new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
953 |
|
954 |
addTemplate(template, SHOW_DIALOG); |
955 |
} |
956 |
} |
957 |
|
958 |
/** |
959 |
* Get the first context type from the registry. |
960 |
* |
961 |
* @return id of the context type |
962 |
*/ |
963 |
private String getFirstContextTypeId() { |
964 |
Iterator it = fContextTypeRegistry.contextTypes(); |
965 |
if (it.hasNext()) |
966 |
return ((TemplateContextType) it.next()).getId(); |
967 |
return null; |
968 |
} |
969 |
|
970 |
/** |
971 |
* Add a template |
972 |
* |
973 |
* Setting ui to SHOW_DIALOG will force a New dialog. Setting it to |
974 |
* MAY_HIDE_DIALOG will respect the show new dialog on drop option. |
975 |
* |
976 |
* @param template |
977 |
* @param ui |
978 |
*/ |
979 |
private void addTemplate(Template template, int ui) { |
980 |
Template newTemplate; |
981 |
if (ui == SHOW_DIALOG || fShowNewDialogOnDropAction.isChecked()) |
982 |
newTemplate = editTemplate(template, false, true); |
983 |
else |
984 |
newTemplate = template; |
985 |
if (newTemplate != null) { |
986 |
TemplatePersistenceData data = new TemplatePersistenceData(newTemplate, true); |
987 |
fTemplateStore.add(data); |
988 |
saveTemplateStore(); |
989 |
fSelectedTemplateList.clear(); |
990 |
fSelectedTemplateList.add(data); |
991 |
changeSelection(); |
992 |
} |
993 |
} |
994 |
|
995 |
/** |
996 |
* Save the template store |
997 |
*/ |
998 |
private void saveTemplateStore() { |
999 |
try { |
1000 |
fTemplateStore.save(); |
1001 |
} catch (IOException e) { |
1002 |
e.printStackTrace(); |
1003 |
MessageDialog.openError(getShell(), |
1004 |
TextEditorTemplateMessages.TemplatesPage_save_error_message, e.getMessage()); |
1005 |
} |
1006 |
} |
1007 |
|
1008 |
/** |
1009 |
* Change selection in the viewer. oldData will contain the earlier selected |
1010 |
* template and fCurrentTemplateData will hold the current selection. Either |
1011 |
* can be null. |
1012 |
* |
1013 |
*/ |
1014 |
private void changeSelection() { |
1015 |
fTreeViewer.refresh(); |
1016 |
if (isSingleTemplateSelected()) |
1017 |
fTreeViewer.setSelection(new StructuredSelection(fSelectedTemplateList.get(0)), true); |
1018 |
else |
1019 |
fTreeViewer.setSelection(new StructuredSelection()); |
1020 |
updateSelectedTemplate(); |
1021 |
} |
1022 |
|
1023 |
/** |
1024 |
* Creates the edit dialog. Subclasses may override this method to provide a |
1025 |
* custom dialog. |
1026 |
* |
1027 |
* @param template |
1028 |
* the template being edited |
1029 |
* @param edit |
1030 |
* whether the dialog should be editable |
1031 |
* @param isNameModifiable |
1032 |
* whether the template name may be modified |
1033 |
* @return the created or modified template, or <code>null</code> if the |
1034 |
* edition failed |
1035 |
* @since 3.1 |
1036 |
*/ |
1037 |
protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) { |
1038 |
EditTemplateDialog dialog = new EditTemplateDialog(getShell(), template, edit, |
1039 |
isNameModifiable, fContextTypeRegistry); |
1040 |
if (dialog.open() == Window.OK) { |
1041 |
return dialog.getTemplate(); |
1042 |
} |
1043 |
return null; |
1044 |
} |
1045 |
|
1046 |
/** |
1047 |
* Edit the current template |
1048 |
*/ |
1049 |
private void editTemplate() { |
1050 |
Template oldTemplate = getSelectedTemplate(); |
1051 |
Template newTemplate = editTemplate(new Template(oldTemplate), true, true); |
1052 |
if (newTemplate != null) { |
1053 |
if (!newTemplate.getName().equals(oldTemplate.getName()) |
1054 |
&& MessageDialog.openQuestion(getShell(), |
1055 |
TextEditorTemplateMessages.TemplatesPage_question_create_new_title, |
1056 |
TextEditorTemplateMessages.TemplatesPage_question_create_new_message)) { |
1057 |
fSelectedTemplateList.clear(); |
1058 |
TemplatePersistenceData templateData = new TemplatePersistenceData(newTemplate, |
1059 |
true); |
1060 |
fSelectedTemplateList.add(templateData); |
1061 |
fTemplateStore.add(templateData); |
1062 |
} else { |
1063 |
((TemplatePersistenceData) fSelectedTemplateList.get(0)).setTemplate(newTemplate); |
1064 |
} |
1065 |
changeSelection(); |
1066 |
} |
1067 |
saveTemplateStore(); |
1068 |
} |
1069 |
|
1070 |
/** |
1071 |
* Remove the currently selected templates |
1072 |
*/ |
1073 |
private void removeTemplate() { |
1074 |
if (!MessageDialog.openQuestion(getShell(), |
1075 |
TextEditorTemplateMessages.TemplatesPage_remove_title, |
1076 |
TextEditorTemplateMessages.TemplatesPage_remove_message)) |
1077 |
return; |
1078 |
for (Iterator iterator = fSelectedTemplateList.iterator(); iterator.hasNext();) { |
1079 |
TemplatePersistenceData data = (TemplatePersistenceData) iterator.next(); |
1080 |
fTemplateStore.delete(data); |
1081 |
} |
1082 |
saveTemplateStore(); |
1083 |
fSelectedTemplateList.clear(); |
1084 |
changeSelection(); |
1085 |
} |
1086 |
|
1087 |
/** |
1088 |
* Get the pattern viewer. Subclass can override |
1089 |
* |
1090 |
* @return the viewer |
1091 |
*/ |
1092 |
protected SourceViewer getViewer() { |
1093 |
return fPatternViewer; |
1094 |
} |
1095 |
|
1096 |
/* |
1097 |
* (non-Javadoc) |
1098 |
* |
1099 |
* @see org.eclipse.ui.part.Page#getControl() |
1100 |
*/ |
1101 |
public Control getControl() { |
1102 |
return fControl; |
1103 |
} |
1104 |
|
1105 |
/** |
1106 |
* Subclasses should override and facilitate inserting the template code |
1107 |
* into the active editor. |
1108 |
* |
1109 |
* @param template |
1110 |
*/ |
1111 |
public void insertTemplate(Template template) { |
1112 |
} |
1113 |
|
1114 |
/** |
1115 |
* The caret position in the editor has moved into a new context type. It is |
1116 |
* the subclasses responsibility to see that this is called only when needed |
1117 |
* by keeping track of editor contents (eg. partitions). |
1118 |
* |
1119 |
* @param ids |
1120 |
*/ |
1121 |
protected void contextTypeChanged(String[] ids) { |
1122 |
fActiveTypes = Arrays.asList(ids); |
1123 |
if (fLinkAction != null && fLinkAction.isChecked()) |
1124 |
refresh(); |
1125 |
} |
1126 |
|
1127 |
/** |
1128 |
* Setup the drop target for the table |
1129 |
*/ |
1130 |
private void initializeDND() { |
1131 |
DragSourceAdapter dragListener = new DragSourceAdapter() { |
1132 |
public void dragSetData(DragSourceEvent event) { |
1133 |
if (isSingleTemplateSelected() |
1134 |
&& TemplateTransfer.getInstance().isSupportedType(event.dataType)) { |
1135 |
event.data = new Template[] { getSelectedTemplate() }; |
1136 |
} |
1137 |
} |
1138 |
}; |
1139 |
fTreeViewer.addDragSupport(DND.DROP_COPY, |
1140 |
new Transfer[] { TemplateTransfer.getInstance() }, dragListener); |
1141 |
DropTargetAdapter dropListener = new DropTargetAdapter() { |
1142 |
TextTransfer textTransfer = TextTransfer.getInstance(); |
1143 |
|
1144 |
public void dragEnter(DropTargetEvent event) { |
1145 |
if (event.detail == DND.DROP_DEFAULT) |
1146 |
event.detail = DND.DROP_COPY; |
1147 |
} |
1148 |
|
1149 |
public void dragOperationChanged(DropTargetEvent event) { |
1150 |
if (event.detail == DND.DROP_DEFAULT) |
1151 |
event.detail = DND.DROP_COPY; |
1152 |
} |
1153 |
|
1154 |
public void dragOver(DropTargetEvent event) { |
1155 |
event.detail = DND.DROP_NONE; |
1156 |
if (event.item == null) |
1157 |
return; |
1158 |
int index = 0; |
1159 |
while (index < event.dataTypes.length) { |
1160 |
if (textTransfer.isSupportedType(event.dataTypes[index])) |
1161 |
break; |
1162 |
index++; |
1163 |
} |
1164 |
if (index < event.dataTypes.length) { |
1165 |
event.currentDataType = event.dataTypes[index]; |
1166 |
event.detail = DND.DROP_COPY; |
1167 |
return; |
1168 |
} |
1169 |
} |
1170 |
|
1171 |
public void drop(DropTargetEvent event) { |
1172 |
if (event.item == null) |
1173 |
return; |
1174 |
Object object = ((TreeItem) event.item).getData(); |
1175 |
String contextId; |
1176 |
if (object instanceof TemplateContextType) |
1177 |
contextId = findContextIdByName(((TemplateContextType) object).getId()); |
1178 |
else |
1179 |
contextId = findContextIdByName(((TemplatePersistenceData) object) |
1180 |
.getTemplate().getContextTypeId()); |
1181 |
if (textTransfer.isSupportedType(event.currentDataType)) { |
1182 |
String text = (String) event.data; |
1183 |
final Template template = new Template( |
1184 |
TextEditorTemplateMessages.TemplatesPage_snippet, |
1185 |
TextEditorTemplateMessages.TemplatesPage_paste_description, contextId, |
1186 |
text, true); |
1187 |
getShell().getDisplay().asyncExec(new Runnable() { |
1188 |
public void run() { |
1189 |
addTemplate(template, HIDE_DIALOG); |
1190 |
} |
1191 |
}); |
1192 |
} |
1193 |
} |
1194 |
|
1195 |
private String findContextIdByName(String contextName) { |
1196 |
String contextId = null; |
1197 |
for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) { |
1198 |
TemplateContextType contextType = (TemplateContextType) iterator.next(); |
1199 |
if (contextType.getName().equals(contextName)) |
1200 |
contextId = contextType.getId(); |
1201 |
} |
1202 |
return contextId; |
1203 |
} |
1204 |
}; |
1205 |
fTreeViewer.addDropSupport(DND.DROP_COPY, new Transfer[] { TextTransfer.getInstance() }, |
1206 |
dropListener); |
1207 |
} |
1208 |
|
1209 |
/** |
1210 |
* Setup the editor site as a drop target. Should be invoked by the |
1211 |
* subclasses for the D&D to work with the editor. |
1212 |
* |
1213 |
* @param site |
1214 |
* @param viewer |
1215 |
*/ |
1216 |
protected void setupEditorDropTarget(IWorkbenchPartSite site, Control viewer) { |
1217 |
IDragAndDropService dndService = (IDragAndDropService) site |
1218 |
.getService(IDragAndDropService.class); |
1219 |
EditorDropTarget editorDropTarget = new EditorDropTarget(); |
1220 |
dndService.addMergedDropTarget(viewer, DND.DROP_COPY, new Transfer[] { TemplateTransfer |
1221 |
.getInstance() }, editorDropTarget); |
1222 |
} |
1223 |
|
1224 |
private void refresh() { |
1225 |
fTreeViewer.refresh(); |
1226 |
setDisableItemColors(); |
1227 |
} |
1228 |
} |