View | Details | Raw Unified | Return to bug 69581 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java (-1 / +34 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Dakshinamurthy Karra - TemplatesPage support (bug 69581)
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.ui.texteditor.templates;
12
package org.eclipse.ui.texteditor.templates;
12
13
Lines 20-30 Link Here
20
final class TextEditorTemplateMessages extends NLS {
21
final class TextEditorTemplateMessages extends NLS {
21
22
22
	private static final String BUNDLE_NAME= TextEditorTemplateMessages.class.getName();
23
	private static final String BUNDLE_NAME= TextEditorTemplateMessages.class.getName();
23
24
	private TextEditorTemplateMessages() {
24
	private TextEditorTemplateMessages() {
25
		// Do not instantiate
25
		// Do not instantiate
26
	}
26
	}
27
27
28
	// TemplatesView
29
	public static String TemplatesPage_column_context;
30
	public static String TemplatesPage_column_description;
31
	public static String TemplatesPage_column_name;
32
	public static String TemplatesPage_insert;
33
	public static String TemplatesPage_edit;
34
	public static String TemplatesPage_preference_page;
35
	public static String TemplatesPage_link_to_editor;
36
	public static String TemplatesPage_collapse_expand;
37
	public static String TemplatesPage_new;
38
	public static String TemplatesPage_remove;
39
	public static String TemplatesPage_show_disabled;
40
	public static String TemplatesPage_show_new_dialog;
41
	public static String TemplatesPage_insert_tooltip;
42
	public static String TemplatesPage_edit_tooltip;
43
	public static String TemplatesPage_preference_page_tooltip;
44
	public static String TemplatesPage_link_to_editor_tooltip;
45
	public static String TemplatesPage_collapse_expand_tooltip;
46
	public static String TemplatesPage_new_tooltip;
47
	public static String TemplatesPage_remove_tooltip;
48
	public static String TemplatesPage_show_disabled_tooltip;
49
	public static String TemplatesPage_show_new_dialog_tooltip;
50
	public static String TemplatesPage_preview;
51
	public static String TemplatesPage_question_create_new_message;
52
	public static String TemplatesPage_question_create_new_title;
53
	public static String TemplatesPage_save_error_message;
54
	public static String TemplatesPage_snippet;
55
	public static String TemplatesPage_paste_description;
56
	public static String TemplatesPage_context_description;
57
	public static String TemplatesPage_remove_message;
58
	public static String TemplatesPage_remove_title;
59
60
	// TemplatePreferencePage
28
	public static String TemplatePreferencePage_error_import;
61
	public static String TemplatePreferencePage_error_import;
29
	public static String TemplatePreferencePage_error_export;
62
	public static String TemplatePreferencePage_error_export;
30
	public static String TemplatePreferencePage_error_read_title;
63
	public static String TemplatePreferencePage_error_read_title;
(-)src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties (+33 lines)
Lines 7-14 Link Here
7
#
7
#
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
#     Dakshinamurthy Karra - TemplatesPage support (bug 69581)
10
###############################################################################
11
###############################################################################
11
12
13
# templates page (view)
14
TemplatesPage_collapse_expand=Collapse or Expand
15
TemplatesPage_column_context=Context
16
TemplatesPage_column_description=Description
17
TemplatesPage_save_error_message=Error Saving the Templates
18
TemplatesPage_column_name=Name
19
TemplatesPage_edit=&Edit...
20
TemplatesPage_insert=&Insert...
21
TemplatesPage_preference_page=&Preference Page...
22
TemplatesPage_paste_description=Pasted from editor
23
TemplatesPage_link_to_editor=Link to Editor
24
TemplatesPage_new=&New...
25
TemplatesPage_preview=Preview
26
TemplatesPage_snippet=snippet
27
TemplatesPage_question_create_new_message= The name of the template has been changed. Click 'Yes' to create an additional template with the new name or 'No' to rename the existing one.
28
TemplatesPage_context_description=Context
29
TemplatesPage_remove_title=Removing Templates
30
TemplatesPage_remove_message=Are you sure you want to remove the selected templates?
31
TemplatesPage_question_create_new_title= Edit Template
32
TemplatesPage_remove=&Remove
33
TemplatesPage_show_disabled=&Show Disabled
34
TemplatesPage_show_new_dialog=S&how New Dialog on Drop
35
TemplatesPage_insert_tooltip=Insert into editor
36
TemplatesPage_edit_tooltip=Edit the template
37
TemplatesPage_preference_page_tooltip=Show preference page
38
TemplatesPage_link_to_editor_tooltip=Link with editor
39
TemplatesPage_collapse_expand_tooltip=Collapse or expand groups
40
TemplatesPage_new_tooltip=Create a new template
41
TemplatesPage_remove_tooltip=Remove the template
42
TemplatesPage_show_disabled_tooltip=Show disabled templates
43
TemplatesPage_show_new_dialog_tooltip=Show new dialog
44
12
# preference page
45
# preference page
13
TemplatePreferencePage_error_import=Failed to import templates.
46
TemplatePreferencePage_error_import=Failed to import templates.
14
TemplatePreferencePage_error_export=Failed to export templates.
47
TemplatePreferencePage_error_export=Failed to export templates.
(-)src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java (-1 / +2 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Dakshinamurthy Karra - bug 69581
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.ui.texteditor.templates;
12
package org.eclipse.ui.texteditor.templates;
12
13
Lines 134-140 Link Here
134
	 *
135
	 *
135
	 * @since 3.3
136
	 * @since 3.3
136
	 */
137
	 */
137
	protected static class EditTemplateDialog extends StatusDialog {
138
	public static class EditTemplateDialog extends StatusDialog {
138
139
139
		private class TextViewerAction extends Action implements IUpdate {
140
		private class TextViewerAction extends Action implements IUpdate {
140
141
(-)src/org/eclipse/ui/texteditor/templates/TemplatesPage.java (+1393 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - 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.MessageDialog;
27
import org.eclipse.jface.layout.TreeColumnLayout;
28
import org.eclipse.jface.preference.IPreferenceStore;
29
import org.eclipse.jface.resource.JFaceResources;
30
import org.eclipse.jface.text.Document;
31
import org.eclipse.jface.text.IDocument;
32
import org.eclipse.jface.text.source.SourceViewer;
33
import org.eclipse.jface.text.source.SourceViewerConfiguration;
34
import org.eclipse.jface.text.templates.ContextTypeRegistry;
35
import org.eclipse.jface.text.templates.Template;
36
import org.eclipse.jface.text.templates.TemplateContextType;
37
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
38
import org.eclipse.jface.text.templates.persistence.TemplateStore;
39
import org.eclipse.jface.util.IPropertyChangeListener;
40
import org.eclipse.jface.util.PropertyChangeEvent;
41
import org.eclipse.jface.viewers.ColumnWeightData;
42
import org.eclipse.jface.viewers.DoubleClickEvent;
43
import org.eclipse.jface.viewers.IDoubleClickListener;
44
import org.eclipse.jface.viewers.ISelectionChangedListener;
45
import org.eclipse.jface.viewers.IStructuredSelection;
46
import org.eclipse.jface.viewers.ITableLabelProvider;
47
import org.eclipse.jface.viewers.ITreeContentProvider;
48
import org.eclipse.jface.viewers.LabelProvider;
49
import org.eclipse.jface.viewers.SelectionChangedEvent;
50
import org.eclipse.jface.viewers.StructuredSelection;
51
import org.eclipse.jface.viewers.TreeViewer;
52
import org.eclipse.jface.viewers.Viewer;
53
import org.eclipse.jface.viewers.ViewerComparator;
54
import org.eclipse.jface.window.Window;
55
import org.eclipse.swt.SWT;
56
import org.eclipse.swt.custom.CLabel;
57
import org.eclipse.swt.custom.SashForm;
58
import org.eclipse.swt.custom.ViewForm;
59
import org.eclipse.swt.dnd.Clipboard;
60
import org.eclipse.swt.dnd.DND;
61
import org.eclipse.swt.dnd.DragSourceAdapter;
62
import org.eclipse.swt.dnd.DragSourceEvent;
63
import org.eclipse.swt.dnd.DropTargetAdapter;
64
import org.eclipse.swt.dnd.DropTargetEvent;
65
import org.eclipse.swt.dnd.TextTransfer;
66
import org.eclipse.swt.dnd.Transfer;
67
import org.eclipse.swt.events.ControlEvent;
68
import org.eclipse.swt.events.ControlListener;
69
import org.eclipse.swt.graphics.Color;
70
import org.eclipse.swt.graphics.Font;
71
import org.eclipse.swt.graphics.FontData;
72
import org.eclipse.swt.graphics.GC;
73
import org.eclipse.swt.graphics.Image;
74
import org.eclipse.swt.layout.GridData;
75
import org.eclipse.swt.widgets.Composite;
76
import org.eclipse.swt.widgets.Control;
77
import org.eclipse.swt.widgets.Menu;
78
import org.eclipse.swt.widgets.Shell;
79
import org.eclipse.swt.widgets.Tree;
80
import org.eclipse.swt.widgets.TreeColumn;
81
import org.eclipse.swt.widgets.TreeItem;
82
import org.eclipse.ui.IActionBars;
83
import org.eclipse.ui.IWorkbenchActionConstants;
84
import org.eclipse.ui.IWorkbenchPartSite;
85
import org.eclipse.ui.actions.ActionFactory;
86
import org.eclipse.ui.dialogs.PreferencesUtil;
87
import org.eclipse.ui.dnd.IDragAndDropService;
88
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
89
import org.eclipse.ui.part.Page;
90
import org.eclipse.ui.texteditor.templates.TemplatePreferencePage.EditTemplateDialog;
91
92
/**
93
 * An abstract base class for template pages for use with TextEditor and JFace
94
 * {@link Template}.
95
 * <p>
96
 * Clients who are defining an editor may elect to provide a corresponding
97
 * templates page. This templates page will be presented to the user via the
98
 * Templates View (the user decides whether their workbench window contains this
99
 * view) whenever that editor is active. This class should be subclassed.
100
 * </p>
101
 * <p>
102
 * Internally, a TemplatesPage uses the template store to display different
103
 * categories. A link to editor mode on the templates page allows to filtering
104
 * of the categories to only that are supported in this context.
105
 * </p>
106
 * @since 3.4
107
 */
108
public abstract class TemplatesPage extends Page {
109
110
	/**
111
	 * Sashform size
112
	 */
113
	private static final String SASH_SIZE_PREF_ID = TextEditorPlugin.PLUGIN_ID
114
			+ ".templates.templatesPage.sashSize"; //$NON-NLS-1$
115
	/**
116
	 * Tree columns widths
117
	 */
118
	private static final String COLUMN_NAME_WIDTH_PREF_ID = TextEditorPlugin.PLUGIN_ID
119
			+ ".templates.templatesPage.nameWidth"; //$NON-NLS-1$
120
	private static final String COLUMN_DESCRIPTION_WIDTH_PREF_ID = TextEditorPlugin.PLUGIN_ID
121
			+ ".templates.templatesPage.descriptionWidth"; //$NON-NLS-1$
122
	/**
123
	 * Link to editor action setting
124
	 */
125
	private static final String LINK_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
126
			+ ".templates.templatesPage.linkAction"; //$NON-NLS-1$
127
	/**
128
	 * Show disabled actions setting
129
	 */
130
	private static final String SHOW_DISABLED_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
131
			+ ".templates.templatesPage.showDisabledAction"; //$NON-NLS-1$
132
	/**
133
	 * Show new dialog on drop setting
134
	 */
135
	private static final String SHOW_NEW_DIALOG_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
136
			+ ".templates.templatesPage.showNewDialogAction"; //$NON-NLS-1$;
137
138
	/**
139
	 * The ID for the popup menu for this templates page
140
	 */
141
	private static final String POPUP_MENU_ID = "org.eclipse.ui.texteditor.templates.PopupMenu"; //$NON-NLS-1$
142
143
	/**
144
	 * Drop support for the editor linked to this page. When a user drops a
145
	 * template into the active editor, the template is applied at the drop
146
	 * position.
147
	 */
148
	private final class EditorDropTarget extends DropTargetAdapter {
149
		/*
150
		 * (non-Javadoc)
151
		 * 
152
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
153
		 */
154
		public void dragEnter(DropTargetEvent event) {
155
			if (event.detail == DND.DROP_DEFAULT)
156
				event.detail = DND.DROP_COPY;
157
		}
158
159
		/*
160
		 * (non-Javadoc)
161
		 * 
162
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
163
		 */
164
		public void dragOperationChanged(DropTargetEvent event) {
165
			if (event.detail == DND.DROP_DEFAULT)
166
				event.detail = DND.DROP_COPY;
167
		}
168
169
		/*
170
		 * (non-Javadoc)
171
		 * 
172
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
173
		 */
174
		public void dragOver(DropTargetEvent event) {
175
			event.feedback |= DND.FEEDBACK_SCROLL;
176
			if (!isEditorModifiable()) {
177
				event.detail = DND.DROP_NONE;
178
				return;
179
			}
180
			if (isValidTemplateForPosition(getSelectedTemplate(), event.x, event.y)) {
181
				event.detail = DND.DROP_COPY;
182
				return;
183
			}
184
			event.detail = DND.DROP_NONE;
185
		}
186
187
		/*
188
		 * (non-Javadoc)
189
		 * 
190
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
191
		 */
192
		public void drop(DropTargetEvent event) {
193
			insertTemplate(getSelectedTemplate());
194
		}
195
	}
196
197
	/**
198
	 * Comparator for the viewer. Sorts the templates by name and then
199
	 * description and context types by names.
200
	 */
201
	private static final class TemplateViewerComparator extends ViewerComparator {
202
		/*
203
		 * (non-Javadoc)
204
		 * 
205
		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
206
		 *      java.lang.Object, java.lang.Object)
207
		 */
208
		public int compare(Viewer viewer, Object object1, Object object2) {
209
			if ((object1 instanceof TemplatePersistenceData)
210
					&& (object2 instanceof TemplatePersistenceData)) {
211
				Template left = ((TemplatePersistenceData) object1).getTemplate();
212
				Template right = ((TemplatePersistenceData) object2).getTemplate();
213
				int result = left.getName().compareToIgnoreCase(right.getName());
214
				if (result != 0)
215
					return result;
216
				return left.getDescription().compareToIgnoreCase(right.getDescription());
217
			}
218
			if ((object1 instanceof TemplateContextType)
219
					&& (object2 instanceof TemplateContextType)) {
220
				return ((TemplateContextType) object1).getName().compareToIgnoreCase(
221
						((TemplateContextType) object1).getName());
222
			}
223
			return super.compare(viewer, object1, object2);
224
		}
225
226
		/*
227
		 * (non-Javadoc)
228
		 * 
229
		 * @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object,
230
		 *      java.lang.String)
231
		 */
232
		public boolean isSorterProperty(Object element, String property) {
233
			return true;
234
		}
235
	}
236
237
	/**
238
	 * Label provider for templates.
239
	 */
240
	private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider {
241
242
		/*
243
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
244
		 *      int)
245
		 */
246
		public Image getColumnImage(Object element, int columnIndex) {
247
			return null;
248
		}
249
250
		/*
251
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
252
		 *      int)
253
		 */
254
		public String getColumnText(Object element, int columnIndex) {
255
			if (element instanceof TemplatePersistenceData)
256
				return getTemplateColumnText(((TemplatePersistenceData) element).getTemplate(),
257
						columnIndex);
258
			return getContextColumnText((TemplateContextType) element, columnIndex);
259
		}
260
261
		/**
262
		 * Return the column text for a template
263
		 * 
264
		 * @param template
265
		 * @param columnIndex
266
		 * @return the column text
267
		 */
268
		private String getTemplateColumnText(Template template, int columnIndex) {
269
			switch (columnIndex) {
270
			case 0:
271
				return template.getName();
272
			case 1:
273
				return template.getDescription();
274
			default:
275
				return ""; //$NON-NLS-1$
276
			}
277
		}
278
279
		/**
280
		 * Return the column text for a context
281
		 * 
282
		 * @param contextType
283
		 * @param columnIndex
284
		 * @return the column text
285
		 */
286
		private String getContextColumnText(TemplateContextType contextType, int columnIndex) {
287
			switch (columnIndex) {
288
			case 0:
289
				return contextType.getName();
290
			case 1:
291
				return TextEditorTemplateMessages.TemplatesPage_context_description;
292
			default:
293
				return ""; //$NON-NLS-1$
294
			}
295
		}
296
297
	}
298
299
	/**
300
	 * Content provider for templates. Provides all the templates defined for
301
	 * this editor and optionally the disabled ones.
302
	 */
303
	private class TemplatesContentProvider implements ITreeContentProvider {
304
		/*
305
		 * (non-Javadoc)
306
		 * 
307
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
308
		 */
309
		public Object[] getChildren(Object parentElement) {
310
			if (parentElement instanceof TemplatePersistenceData)
311
				return new Object[0];
312
			else if (parentElement instanceof TemplateContextType) {
313
				TemplateContextType contextType = (TemplateContextType) parentElement;
314
				return getTemplates(contextType.getId());
315
			}
316
			return null;
317
		}
318
319
		/**
320
		 * Get the templates for a given contextId. if ShowDisabled is selected
321
		 * the disabled templates are also included.
322
		 * 
323
		 * @param contextId
324
		 * @return the templates
325
		 */
326
		private TemplatePersistenceData[] getTemplates(String contextId) {
327
			List templateList = new ArrayList();
328
			TemplatePersistenceData[] datas = fTemplateStore.getTemplateData(false);
329
			for (int i = 0; i < datas.length; i++) {
330
				if ((fShowDisabled || datas[i].isEnabled())
331
						&& datas[i].getTemplate().getContextTypeId().equals(contextId))
332
					templateList.add(datas[i]);
333
			}
334
			return (TemplatePersistenceData[]) templateList
335
					.toArray(new TemplatePersistenceData[templateList.size()]);
336
		}
337
338
		/*
339
		 * (non-Javadoc)
340
		 * 
341
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
342
		 */
343
		public Object getParent(Object element) {
344
			if (element instanceof TemplatePersistenceData) {
345
				TemplatePersistenceData templateData = (TemplatePersistenceData) element;
346
				return fContextTypeRegistry.getContextType(templateData.getTemplate()
347
						.getContextTypeId());
348
			}
349
			return null;
350
		}
351
352
		/*
353
		 * (non-Javadoc)
354
		 * 
355
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
356
		 */
357
		public boolean hasChildren(Object element) {
358
			if (element instanceof TemplateContextType)
359
				return true;
360
			return false;
361
		}
362
363
		/*
364
		 * (non-Javadoc)
365
		 * 
366
		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
367
		 */
368
		public Object[] getElements(Object inputElement) {
369
			List contextTypes = new ArrayList();
370
371
			for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) {
372
				TemplateContextType contextType = (TemplateContextType) iterator.next();
373
				if (isActiveContext(contextType) || !fLinkWithEditor)
374
					contextTypes.add(contextType);
375
			}
376
			return contextTypes.toArray(new TemplateContextType[contextTypes.size()]);
377
		}
378
379
		/**
380
		 * Checks whether given context type is active for displaying the
381
		 * templates
382
		 * 
383
		 * @param contextType
384
		 * @return true if context is active
385
		 */
386
		private boolean isActiveContext(TemplateContextType contextType) {
387
			return fActiveTypes == null || fActiveTypes.contains(contextType.getId());
388
		}
389
390
		/*
391
		 * (non-Javadoc)
392
		 * 
393
		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
394
		 */
395
		public void dispose() {
396
		}
397
398
		/*
399
		 * (non-Javadoc)
400
		 * 
401
		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
402
		 *      java.lang.Object, java.lang.Object)
403
		 */
404
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
405
		}
406
	}
407
408
	/**
409
	 * Show/Hide new dialog
410
	 */
411
	private static final int SHOW_DIALOG = 0;
412
	private static final int MAY_HIDE_DIALOG = 1;
413
414
	/** The viewer displays the pattern of selected template. */
415
	private SourceViewer fPatternViewer;
416
	/** The store for our templates. */
417
	private TemplateStore fTemplateStore;
418
	/**
419
	 * The template stores preference page. Used to listen to the changes and
420
	 * update the view. Needed when the user selects Preferences and updates the
421
	 * templates.
422
	 */
423
	private IPreferenceStore fTemplatePreferenceStore;
424
	private IPropertyChangeListener fTemplateChangeListener;
425
	/** The context type registry. */
426
	private ContextTypeRegistry fContextTypeRegistry;
427
428
	/** The control for this page book view */
429
	private SashForm fControl;
430
431
	/* Actions */
432
	private Action fInsertAction;
433
	private Action fAddAction;
434
	private Action fEditAction;
435
	private Action fRemoveAction;
436
	private Action fLinkWithEditorAction;
437
	private Action fExpandCollapseAction;
438
	private Action fPreferencePageAction;
439
	private Action fShowDisabledAction;
440
	private Action fShowNewDialogOnDropAction;
441
442
	/* Clipboard actions */
443
	private Action fPasteAction;
444
	private Action fCopyAction;
445
446
	/* Options and values saved in preference store */
447
	private boolean fLinkWithEditor ;
448
	private boolean fShowDisabled ;
449
	private boolean fShowNewDialogOnDrop ;
450
	private int fSashSize;
451
	private int fNameWidth;
452
	private int fDescriptionWidth ;
453
	
454
	/** Currently selected templates and type */
455
	private ArrayList fSelectedTemplateList = new ArrayList();
456
	private TemplateContextType fSelectedType;
457
458
	/** Current active context types for the editor */
459
	private List fActiveTypes;
460
461
	/* Preference stores */
462
	/**
463
	 * Preference store to store the dialog setting for this page
464
	 */
465
	private IPreferenceStore fPreferenceStore;
466
467
	/* Controls */
468
	private Tree fTemplatesTree;
469
	private TreeViewer fTreeViewer;
470
	private Menu fContextMenu;
471
472
	/**
473
	 * Creates a new template view page.
474
	 * 
475
	 * @param templateStore
476
	 * @param templatePreferenceStore
477
	 * @param registry
478
	 */
479
	protected TemplatesPage(TemplateStore templateStore, IPreferenceStore templatePreferenceStore,
480
			ContextTypeRegistry registry) {
481
		super();
482
		setupPreferenceStore();
483
		fTemplateStore = templateStore;
484
		fTemplatePreferenceStore = templatePreferenceStore;
485
		if (fTemplatePreferenceStore != null) {
486
			fTemplateChangeListener = new IPropertyChangeListener() {
487
				public void propertyChange(PropertyChangeEvent event) {
488
					refresh();
489
				}
490
			};
491
			fTemplatePreferenceStore.addPropertyChangeListener(fTemplateChangeListener);
492
		}
493
		fContextTypeRegistry = registry;
494
	}
495
496
	private void setupPreferenceStore() {
497
		fPreferenceStore = TextEditorPlugin.getDefault().getPreferenceStore();
498
		fPreferenceStore.setDefault(LINK_ACTION_PREF_ID, true);
499
		fPreferenceStore.setDefault(SHOW_DISABLED_ACTION_PREF_ID, false);
500
		fPreferenceStore.setDefault(SHOW_NEW_DIALOG_ACTION_PREF_ID, true);
501
		fPreferenceStore.setDefault(SASH_SIZE_PREF_ID, 80);
502
		fLinkWithEditor = fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID);
503
		fShowDisabled = fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID);
504
		fShowNewDialogOnDrop = fPreferenceStore.getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID);
505
		fSashSize = fPreferenceStore.getInt(SASH_SIZE_PREF_ID);
506
	}
507
508
	/**
509
	 * Check whether the linked editor is modifiable
510
	 * 
511
	 * @return true if the editor is modifiable
512
	 */
513
	protected boolean isEditorModifiable() {
514
		return true;
515
	}
516
517
	/**
518
	 * Check whether the template is valid for the current drop position
519
	 * 
520
	 * @param template
521
	 * @param x
522
	 * @param y
523
	 * @return true if the template is valid
524
	 */
525
	protected boolean isValidTemplateForPosition(Template template, int x, int y) {
526
		return true;
527
	}
528
529
	/*
530
	 * (non-Javadoc)
531
	 * 
532
	 * @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite)
533
	 */
534
	public void createControl(Composite ancestor) {
535
		setupActions();
536
537
		fControl = new SashForm(ancestor, SWT.VERTICAL);
538
539
		createTemplateTree();
540
		createPatternViewer(fControl);
541
542
		hookContextMenu();
543
		initializeDND();
544
		updateButtons();
545
546
		fControl.setWeights(new int[] { fSashSize, 100 - fSashSize });
547
	}
548
549
	/**
550
	 * Setup the actions
551
	 */
552
	private void setupActions() {
553
		createActions();
554
		IActionBars actionBars = getSite().getActionBars();
555
	
556
		actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction);
557
		actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction);
558
	
559
		fillToolbar(actionBars);
560
		fillMenu(actionBars);
561
	}
562
563
	/**
564
	 * Create actions for this view
565
	 */
566
	private void createActions() {
567
		fInsertAction = new Action(TextEditorTemplateMessages.TemplatesPage_insert) {
568
			public void run() {
569
				insertTemplate(getSelectedTemplate());
570
			}
571
		};
572
		fInsertAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_insert_tooltip);
573
	
574
		fAddAction = new Action(TextEditorTemplateMessages.TemplatesPage_new) {
575
			public void run() {
576
				addTemplate();
577
			}
578
		};
579
		fAddAction.setImageDescriptor(TemplatesViewImages
580
				.getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_NEW));
581
		fAddAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_new_tooltip);
582
	
583
		fEditAction = new Action(TextEditorTemplateMessages.TemplatesPage_edit) {
584
			public void run() {
585
				editTemplate();
586
			}
587
		};
588
		fEditAction.setImageDescriptor(TemplatesViewImages
589
				.getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_EDIT));
590
		fEditAction.setDisabledImageDescriptor(TemplatesViewImages
591
				.getImageDescriptor(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_EDIT));
592
		fEditAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_edit_tooltip);
593
	
594
		fRemoveAction = new Action(TextEditorTemplateMessages.TemplatesPage_remove) {
595
			public void run() {
596
				removeTemplate();
597
			}
598
		};
599
		fRemoveAction.setImageDescriptor(TemplatesViewImages
600
				.getImageDescriptor(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_DELETE));
601
		fRemoveAction.setImageDescriptor(TemplatesViewImages
602
				.getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_DELETE));
603
		fRemoveAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_remove_tooltip);
604
	
605
		fLinkWithEditorAction = new Action(TextEditorTemplateMessages.TemplatesPage_link_to_editor,
606
				IAction.AS_CHECK_BOX) {
607
			public void run() {
608
				fLinkWithEditor = fLinkWithEditorAction.isChecked();
609
				refresh();
610
			}
611
		};
612
		fLinkWithEditorAction.setImageDescriptor(TemplatesViewImages
613
				.getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_LINK));
614
		fLinkWithEditorAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID));
615
		fLinkWithEditorAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_link_to_editor_tooltip);
616
		fExpandCollapseAction = new Action(TextEditorTemplateMessages.TemplatesPage_collapse_expand) {
617
			public void run() {
618
				Object[] vee = fTreeViewer.getVisibleExpandedElements();
619
				boolean collapse = vee.length != 0;
620
				if (collapse)
621
					fTreeViewer.collapseAll();
622
				else
623
					fTreeViewer.expandAll();
624
			}
625
		};
626
		fExpandCollapseAction.setImageDescriptor(TemplatesViewImages
627
				.getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_COLLAPSE_EXPAND));
628
		fExpandCollapseAction
629
				.setToolTipText(TextEditorTemplateMessages.TemplatesPage_collapse_expand_tooltip);
630
	
631
		if (getPreferencePageId() != null) {
632
			fPreferencePageAction = new Action(
633
					TextEditorTemplateMessages.TemplatesPage_preference_page) {
634
				public void run() {
635
					showPreferencePage();
636
				}
637
			};
638
			fPreferencePageAction
639
					.setToolTipText(TextEditorTemplateMessages.TemplatesPage_preference_page_tooltip);
640
		}
641
	
642
		fShowDisabledAction = new Action(TextEditorTemplateMessages.TemplatesPage_show_disabled,
643
				IAction.AS_CHECK_BOX) {
644
			public void run() {
645
				fShowDisabled = fShowDisabledAction.isChecked();
646
				refresh();
647
			}
648
		};
649
		fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID));
650
		fShowDisabledAction
651
				.setToolTipText(TextEditorTemplateMessages.TemplatesPage_show_disabled_tooltip);
652
	
653
		fShowNewDialogOnDropAction = new Action(
654
				TextEditorTemplateMessages.TemplatesPage_show_new_dialog, IAction.AS_CHECK_BOX) {
655
			public void run() {
656
				fShowNewDialogOnDrop = fShowNewDialogOnDropAction.isChecked();
657
			}
658
		};
659
		fShowNewDialogOnDropAction.setChecked(fPreferenceStore
660
				.getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID));
661
		fShowNewDialogOnDropAction
662
				.setToolTipText(TextEditorTemplateMessages.TemplatesPage_show_new_dialog_tooltip);
663
	
664
		fPasteAction = new Action() {
665
			public void run() {
666
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
667
				final Template template = getTemplateFromCB(clipBoard);
668
				if (template == null)
669
					return;
670
				getShell().getDisplay().asyncExec(new Runnable() {
671
					public void run() {
672
						addTemplate(template, MAY_HIDE_DIALOG);
673
					}
674
				});
675
			}
676
	
677
			private Template getTemplateFromCB(Clipboard clipBoard) {
678
				String text = (String) clipBoard.getContents(TextTransfer.getInstance());
679
				if (text == null)
680
					return getTemplateFromTemplate(clipBoard);
681
				return new Template(TextEditorTemplateMessages.TemplatesPage_snippet,
682
						TextEditorTemplateMessages.TemplatesPage_paste_description,
683
						getContextTypeId(), text.replaceAll("\\$", "\\$\\$"), true); //$NON-NLS-1$ //$NON-NLS-2$
684
			}
685
	
686
			private Template getTemplateFromTemplate(Clipboard clipBoard) {
687
				Object contents = clipBoard.getContents(TemplateTransfer.getInstance());
688
				if (contents == null)
689
					return null;
690
				Template t = ((Template[]) contents)[0];
691
				return new Template(t.getName(), t.getDescription(), getContextTypeId(), t
692
						.getPattern(), true);
693
			}
694
		};
695
	
696
		fCopyAction = new Action() {
697
			public void run() {
698
				if (!isSingleTemplateSelected())
699
					return;
700
				Template[] templates = new Template[] { getSelectedTemplate() };
701
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
702
				clipBoard.setContents(new Object[] { templates }, new Transfer[] { TemplateTransfer
703
						.getInstance() });
704
			}
705
		};
706
	}
707
708
	/**
709
	 * Fill the menu items
710
	 * 
711
	 * @param actionBars
712
	 */
713
	private void fillMenu(IActionBars actionBars) {
714
		IMenuManager menuManager = actionBars.getMenuManager();
715
	
716
		if (fPreferencePageAction != null) {
717
			menuManager.add(fPreferencePageAction);
718
			menuManager.add(new Separator());
719
		}
720
		menuManager.add(fShowDisabledAction);
721
		menuManager.add(fShowNewDialogOnDropAction);
722
	
723
		menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
724
	}
725
726
	/**
727
	 * Fill items into the toolbar
728
	 * 
729
	 * @param actionBars
730
	 */
731
	private void fillToolbar(IActionBars actionBars) {
732
		IToolBarManager toolBarManager = actionBars.getToolBarManager();
733
		toolBarManager.add(fAddAction);
734
		toolBarManager.add(fEditAction);
735
		toolBarManager.add(fRemoveAction);
736
	
737
		toolBarManager.add(new Separator());
738
	
739
		toolBarManager.add(fLinkWithEditorAction);
740
		toolBarManager.add(fExpandCollapseAction);
741
	}
742
743
	/**
744
	 * Setup the context menu for the viewer.
745
	 */
746
	private void hookContextMenu() {
747
		MenuManager menuMgr = new MenuManager(POPUP_MENU_ID);
748
		menuMgr.setRemoveAllWhenShown(true);
749
		menuMgr.addMenuListener(new IMenuListener() {
750
			public void menuAboutToShow(IMenuManager manager) {
751
				fillContextMenu(manager);
752
			}
753
		});
754
		fContextMenu = menuMgr.createContextMenu(fTreeViewer.getControl());
755
		fTreeViewer.getControl().setMenu(fContextMenu);
756
		getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer);
757
	}
758
759
	/**
760
	 * Fill up the context menu
761
	 * 
762
	 * @param manager
763
	 */
764
	private void fillContextMenu(IMenuManager manager) {
765
		manager.add(fInsertAction);
766
		manager.add(new Separator());
767
		manager.add(fAddAction);
768
		manager.add(fEditAction);
769
		manager.add(fRemoveAction);
770
		// Other plug-ins can contribute there actions here
771
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
772
	}
773
774
	/**
775
	 * Create the tree control to display template information
776
	 */
777
	private void createTemplateTree() {
778
		Composite treeComposite = new Composite(fControl, SWT.NONE);
779
		GridData data = new GridData(GridData.FILL_BOTH);
780
		treeComposite.setLayoutData(data);
781
782
		TreeColumnLayout columnLayout = new TreeColumnLayout();
783
		treeComposite.setLayout(columnLayout);
784
		fTemplatesTree = new Tree(treeComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
785
				| SWT.FULL_SELECTION);
786
		fTemplatesTree.setHeaderVisible(true);
787
		fTemplatesTree.setLinesVisible(true);
788
789
		GC gc = new GC(getShell());
790
		gc.setFont(JFaceResources.getDialogFont());
791
792
		TreeColumn columnName = new TreeColumn(fTemplatesTree, SWT.NONE);
793
		columnName.setText(TextEditorTemplateMessages.TemplatesPage_column_name);
794
		int minWidth = fPreferenceStore.getInt(COLUMN_NAME_WIDTH_PREF_ID);
795
		if (minWidth == 0)
796
			minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_name).x + 10;
797
		columnLayout.setColumnData(columnName, new ColumnWeightData(2, minWidth, true));
798
		columnName.addControlListener(new ControlListener() {
799
			public void controlMoved(ControlEvent e) {
800
			}
801
802
			public void controlResized(ControlEvent e) {
803
				fNameWidth = ((TreeColumn)e.getSource()).getWidth();
804
			}
805
		});
806
807
		TreeColumn columnDescription = new TreeColumn(fTemplatesTree, SWT.NONE);
808
		columnDescription.setText(TextEditorTemplateMessages.TemplatesPage_column_description);
809
		minWidth = fPreferenceStore.getInt(COLUMN_DESCRIPTION_WIDTH_PREF_ID);
810
		if (minWidth == 0)
811
			minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_description).x + 10;
812
		columnLayout.setColumnData(columnDescription, new ColumnWeightData(3, minWidth, true));
813
		columnDescription.addControlListener(new ControlListener() {
814
			public void controlMoved(ControlEvent e) {
815
			}
816
817
			public void controlResized(ControlEvent e) {
818
				fDescriptionWidth = ((TreeColumn)e.getSource()).getWidth();
819
			}
820
		});
821
822
823
		gc.dispose();
824
825
		createTreeViewer();
826
	}
827
828
	/**
829
	 * Create the viewer for the tree control and configure it.
830
	 */
831
	private void createTreeViewer() {
832
		fTreeViewer = new TreeViewer(fTemplatesTree);
833
		fTreeViewer.setLabelProvider(new TemplateLabelProvider());
834
		fTreeViewer.setContentProvider(new TemplatesContentProvider());
835
836
		fTreeViewer.setComparator(new TemplateViewerComparator());
837
		fTreeViewer.setInput(fTemplateStore);
838
		fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
839
			public void doubleClick(DoubleClickEvent e) {
840
				updateSelectedItems();
841
				insertTemplate(getSelectedTemplate());
842
			}
843
		});
844
845
		fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
846
			public void selectionChanged(SelectionChangedEvent e) {
847
				updateSelectedItems();
848
				updateButtons();
849
			}
850
		});
851
		fTreeViewer.expandAll();
852
		decorateTemplates();
853
	}
854
855
	/**
856
	 * Create a viewer to display the pattern
857
	 * 
858
	 * @param parent
859
	 */
860
	private void createPatternViewer(Composite parent) {
861
		ViewForm viewForm = new ViewForm(parent, SWT.NONE);
862
		viewForm.setBorderVisible(false);
863
		CLabel previewLabel = new CLabel(viewForm, SWT.NONE);
864
		previewLabel.setText(TextEditorTemplateMessages.TemplatesPage_preview);
865
		previewLabel.setImage(TemplatesViewImages
866
				.getImage(ITemplateViewImageConstants.IMG_OBJ_PREVIEW));
867
		viewForm.setTopLeft(previewLabel);
868
	
869
		fPatternViewer = createViewer(viewForm);
870
		fPatternViewer.setEditable(false);
871
		viewForm.setContent(fPatternViewer.getControl());
872
		viewForm.addControlListener(new ControlListener() {
873
			public void controlMoved(ControlEvent e) {
874
			}
875
	
876
			public void controlResized(ControlEvent e) {
877
				int[] weights = fControl.getWeights();
878
				fSashSize = (int) (weights[0] * 100.0 / (weights[0] + weights[1]));
879
			}
880
		});
881
	}
882
883
	/**
884
	 * Sets all templates in the tree that are disabled to grey.
885
	 */
886
	private void decorateTemplates() {
887
		TreeItem[] contextItems = fTemplatesTree.getItems();
888
		Color fgcDisabled = getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY);
889
		Color fgcEnabled = getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
890
		for (int i = 0; i < contextItems.length; i++) {
891
			contextItems[i].setFont(getBoldFont(contextItems[i].getFont()));
892
			TreeItem[] templateItems = contextItems[i].getItems();
893
			for (int j = 0; j < templateItems.length; j++) {
894
				TemplatePersistenceData templateData = (TemplatePersistenceData) templateItems[j]
895
						.getData();
896
				if (templateData == null)
897
					continue;
898
				if (!templateData.isEnabled() && templateItems[j].getForeground() != fgcDisabled)
899
					templateItems[j].setForeground(fgcDisabled);
900
				else if (templateData.isEnabled() && templateItems[j].getForeground() != fgcEnabled)
901
					templateItems[j].setForeground(fgcEnabled);
902
			}
903
		}
904
	}
905
906
	private Font getBoldFont(Font font) {
907
		FontData[] fontData = font.getFontData();
908
		for (int i = 0; i < fontData.length; i++) {
909
			fontData[i].setStyle(fontData[i].getStyle() | SWT.BOLD | SWT.ITALIC);
910
		}
911
		return new Font(font.getDevice(), fontData);
912
	}
913
914
	/**
915
	 * Update the selected template list, type and pattern viewer
916
	 */
917
	private void updateSelectedItems() {
918
		IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection();
919
920
		fSelectedTemplateList.clear();
921
		fSelectedType = null;
922
923
		if (selection.size() == 1) {
924
			Object item = selection.getFirstElement();
925
			if (item instanceof TemplateContextType)
926
				fSelectedType = (TemplateContextType) item;
927
			else
928
				fSelectedTemplateList.add(item);
929
		} else if (selection.size() > 1) {
930
			for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
931
				Object item = iterator.next();
932
				if (item instanceof TemplateContextType) {
933
					fSelectedTemplateList.clear();
934
					break;
935
				}
936
				fSelectedTemplateList.add(item);
937
			}
938
		}
939
		if (!fSelectedTemplateList.isEmpty()) {
940
			String contextTypeId = ((TemplatePersistenceData) fSelectedTemplateList.get(0))
941
					.getTemplate().getContextTypeId();
942
			fSelectedType = fContextTypeRegistry.getContextType(contextTypeId);
943
			for (Iterator iterator = fSelectedTemplateList.iterator(); iterator.hasNext();) {
944
				TemplatePersistenceData template = (TemplatePersistenceData) iterator.next();
945
				if (!contextTypeId.equals(template.getTemplate().getContextTypeId())) {
946
					fSelectedType = null;
947
					break;
948
				}
949
			}
950
		}
951
		if (isSingleTemplateSelected()) {
952
			updateViewerInput(getSelectedTemplate());
953
		} else
954
			fPatternViewer.getDocument().set(""); //$NON-NLS-1$
955
	}
956
957
	/**
958
	 * Checks whether only one template is selected in the tree
959
	 * 
960
	 * @return true if only single template is selected
961
	 */
962
	private boolean isSingleTemplateSelected() {
963
		return fSelectedTemplateList.size() == 1;
964
	}
965
966
	/**
967
	 * Get the selected template. Note: should always precede with a check for
968
	 * isSingleTemplateSelected
969
	 * 
970
	 * @return the template (Not the data)
971
	 */
972
	private Template getSelectedTemplate() {
973
		return ((TemplatePersistenceData) fSelectedTemplateList.get(0)).getTemplate();
974
	}
975
976
	/**
977
	 * Show the preference templates preference page
978
	 */
979
	private void showPreferencePage() {
980
		PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageId(), null, null)
981
				.open();
982
	}
983
984
	/**
985
	 * Get the preference page ID for the templates for the given editor.
986
	 * Subclasses should override.
987
	 * 
988
	 * @return id of the preference page
989
	 */
990
	protected String getPreferencePageId() {
991
		return null;
992
	}
993
994
	/**
995
	 * Get the shell
996
	 * 
997
	 * @return the shell for this view site
998
	 */
999
	protected Shell getShell() {
1000
		return getSite().getShell();
1001
	}
1002
1003
	/**
1004
	 * Creates, configures and returns a source viewer to present the template
1005
	 * pattern on the preference page. Clients may override to provide a custom
1006
	 * source viewer featuring e.g. syntax coloring.
1007
	 * 
1008
	 * @param parent
1009
	 *            the parent control
1010
	 * @return a configured source viewer
1011
	 */
1012
	protected SourceViewer createViewer(Composite parent) {
1013
		SourceViewer viewer = new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL
1014
				| SWT.H_SCROLL);
1015
		SourceViewerConfiguration configuration = new SourceViewerConfiguration();
1016
		viewer.configure(configuration);
1017
		IDocument document = new Document();
1018
		viewer.setDocument(document);
1019
		return viewer;
1020
	}
1021
1022
	/**
1023
	 * Updates the pattern viewer.
1024
	 * 
1025
	 * @param template
1026
	 */
1027
	protected void updateViewerInput(Template template) {
1028
		if (template != null)
1029
			fPatternViewer.getDocument().set(template.getPattern());
1030
		else
1031
			fPatternViewer.getDocument().set(""); //$NON-NLS-1$
1032
	}
1033
1034
	/**
1035
	 * Updates the buttons.
1036
	 */
1037
	private void updateButtons() {
1038
		fCopyAction.setEnabled(isSingleTemplateSelected());
1039
		fInsertAction.setEnabled(isSingleTemplateSelected());
1040
		fEditAction.setEnabled(isSingleTemplateSelected());
1041
		fRemoveAction.setEnabled(fSelectedTemplateList.size() != 0);
1042
	}
1043
1044
	/**
1045
	 * Add a template
1046
	 */
1047
	private void addTemplate() {
1048
		String id = getContextTypeId();
1049
		if (id != null) {
1050
			Template template = new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1051
1052
			addTemplate(template, SHOW_DIALOG);
1053
		}
1054
	}
1055
1056
	/**
1057
	 * Get the selected or the first context type from the registry.
1058
	 * 
1059
	 * @return id of the context type
1060
	 */
1061
	private String getContextTypeId() {
1062
		if (fSelectedType != null)
1063
			return fSelectedType.getId();
1064
		Iterator it = fContextTypeRegistry.contextTypes();
1065
		if (it.hasNext())
1066
			return ((TemplateContextType) it.next()).getId();
1067
		return null;
1068
	}
1069
1070
	/**
1071
	 * Add a template
1072
	 * 
1073
	 * Setting ui to SHOW_DIALOG will force a New dialog. Setting it to
1074
	 * MAY_HIDE_DIALOG will respect the show new dialog on drop option.
1075
	 * 
1076
	 * @param template
1077
	 * @param ui
1078
	 */
1079
	private void addTemplate(Template template, int ui) {
1080
		Template newTemplate;
1081
		if (ui == SHOW_DIALOG || fShowNewDialogOnDrop)
1082
			newTemplate = editTemplate(template, false, true);
1083
		else
1084
			newTemplate = template;
1085
		if (newTemplate != null) {
1086
			TemplatePersistenceData data = new TemplatePersistenceData(newTemplate, true);
1087
			fTemplateStore.add(data);
1088
			saveTemplateStore();
1089
			fSelectedTemplateList.clear();
1090
			fSelectedTemplateList.add(data);
1091
			changeSelection();
1092
		}
1093
	}
1094
1095
	/**
1096
	 * Save the template store
1097
	 */
1098
	private void saveTemplateStore() {
1099
		try {
1100
			fTemplateStore.save();
1101
		} catch (IOException e) {
1102
			e.printStackTrace();
1103
			MessageDialog.openError(getShell(),
1104
					TextEditorTemplateMessages.TemplatesPage_save_error_message, e.getMessage());
1105
		}
1106
	}
1107
1108
	/**
1109
	 * Change selection in the viewer. oldData will contain the earlier selected
1110
	 * template and fCurrentTemplateData will hold the current selection. Either
1111
	 * can be null.
1112
	 * 
1113
	 */
1114
	private void changeSelection() {
1115
		fTreeViewer.refresh();
1116
		if (isSingleTemplateSelected())
1117
			fTreeViewer.setSelection(new StructuredSelection(fSelectedTemplateList.get(0)), true);
1118
		else
1119
			fTreeViewer.setSelection(new StructuredSelection());
1120
		updateSelectedItems();
1121
	}
1122
1123
	/**
1124
	 * Creates the edit dialog. Subclasses may override this method to provide a
1125
	 * custom dialog.
1126
	 * 
1127
	 * @param template
1128
	 *            the template being edited
1129
	 * @param edit
1130
	 *            whether the dialog should be editable
1131
	 * @param isNameModifiable
1132
	 *            whether the template name may be modified
1133
	 * @return the created or modified template, or <code>null</code> if the
1134
	 *         edition failed
1135
	 * @since 3.1
1136
	 */
1137
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
1138
		EditTemplateDialog dialog = new EditTemplateDialog(getShell(), template, edit,
1139
				isNameModifiable, fContextTypeRegistry);
1140
		if (dialog.open() == Window.OK) {
1141
			return dialog.getTemplate();
1142
		}
1143
		return null;
1144
	}
1145
1146
	/**
1147
	 * Edit the current template
1148
	 */
1149
	private void editTemplate() {
1150
		Template oldTemplate = getSelectedTemplate();
1151
		Template newTemplate = editTemplate(new Template(oldTemplate), true, true);
1152
		if (newTemplate != null) {
1153
			if (!newTemplate.getName().equals(oldTemplate.getName())
1154
					&& MessageDialog.openQuestion(getShell(),
1155
							TextEditorTemplateMessages.TemplatesPage_question_create_new_title,
1156
							TextEditorTemplateMessages.TemplatesPage_question_create_new_message)) {
1157
				fSelectedTemplateList.clear();
1158
				TemplatePersistenceData templateData = new TemplatePersistenceData(newTemplate,
1159
						true);
1160
				fSelectedTemplateList.add(templateData);
1161
				fTemplateStore.add(templateData);
1162
			} else {
1163
				((TemplatePersistenceData) fSelectedTemplateList.get(0)).setTemplate(newTemplate);
1164
			}
1165
			changeSelection();
1166
		}
1167
		saveTemplateStore();
1168
	}
1169
1170
	/**
1171
	 * Remove the currently selected templates
1172
	 */
1173
	private void removeTemplate() {
1174
		if (!MessageDialog.openQuestion(getShell(),
1175
				TextEditorTemplateMessages.TemplatesPage_remove_title,
1176
				TextEditorTemplateMessages.TemplatesPage_remove_message))
1177
			return;
1178
		for (Iterator iterator = fSelectedTemplateList.iterator(); iterator.hasNext();) {
1179
			TemplatePersistenceData data = (TemplatePersistenceData) iterator.next();
1180
			fTemplateStore.delete(data);
1181
		}
1182
		saveTemplateStore();
1183
		fSelectedTemplateList.clear();
1184
		changeSelection();
1185
	}
1186
1187
	/**
1188
	 * Get the pattern viewer. Subclass can override
1189
	 * 
1190
	 * @return the viewer
1191
	 */
1192
	protected SourceViewer getViewer() {
1193
		return fPatternViewer;
1194
	}
1195
1196
	/*
1197
	 * (non-Javadoc)
1198
	 * 
1199
	 * @see org.eclipse.ui.part.Page#getControl()
1200
	 */
1201
	public Control getControl() {
1202
		return fControl;
1203
	}
1204
1205
	/**
1206
	 * Subclasses should override and facilitate inserting the template code
1207
	 * into the active editor.
1208
	 * 
1209
	 * @param template
1210
	 */
1211
	public void insertTemplate(Template template) {
1212
	}
1213
1214
	/**
1215
	 * The caret position in the editor has moved into a new context type. It is
1216
	 * the subclasses responsibility to see that this is called only when needed
1217
	 * by keeping track of editor contents (eg. partitions).
1218
	 * 
1219
	 * @param ids
1220
	 */
1221
	protected void contextTypeChanged(String[] ids) {
1222
		fActiveTypes = Arrays.asList(ids);
1223
		if (fLinkWithEditorAction != null && fLinkWithEditor)
1224
			refresh();
1225
	}
1226
1227
	/**
1228
	 * Initialize drag and drop the the template items
1229
	 */
1230
	private void initializeDND() {
1231
		DragSourceAdapter dragListener = new DragSourceAdapter() {
1232
			/*
1233
			 * (non-Javadoc)
1234
			 * 
1235
			 * @see org.eclipse.swt.dnd.DragSourceAdapter#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
1236
			 */
1237
			public void dragSetData(DragSourceEvent event) {
1238
				if (isSingleTemplateSelected()
1239
						&& TemplateTransfer.getInstance().isSupportedType(event.dataType)) {
1240
					event.data = new Template[] { getSelectedTemplate() };
1241
				}
1242
			}
1243
		};
1244
		fTreeViewer.addDragSupport(DND.DROP_COPY,
1245
				new Transfer[] { TemplateTransfer.getInstance() }, dragListener);
1246
		DropTargetAdapter dropListener = new DropTargetAdapter() {
1247
			TextTransfer textTransfer = TextTransfer.getInstance();
1248
			TemplateTransfer templateTransfer = TemplateTransfer.getInstance();
1249
1250
			/*
1251
			 * (non-Javadoc)
1252
			 * 
1253
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
1254
			 */
1255
			public void dragEnter(DropTargetEvent event) {
1256
				if (event.detail == DND.DROP_DEFAULT)
1257
					event.detail = DND.DROP_COPY;
1258
			}
1259
1260
			/*
1261
			 * (non-Javadoc)
1262
			 * 
1263
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
1264
			 */
1265
			public void dragOperationChanged(DropTargetEvent event) {
1266
				if (event.detail == DND.DROP_DEFAULT)
1267
					event.detail = DND.DROP_COPY;
1268
			}
1269
1270
			/*
1271
			 * (non-Javadoc)
1272
			 * 
1273
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
1274
			 */
1275
			public void dragOver(DropTargetEvent event) {
1276
				event.detail = DND.DROP_NONE;
1277
				if (event.item == null)
1278
					return;
1279
				int index = 0;
1280
				while (index < event.dataTypes.length) {
1281
					if (textTransfer.isSupportedType(event.dataTypes[index]))
1282
						break;
1283
					if (templateTransfer.isSupportedType(event.dataTypes[index]))
1284
						break;
1285
					index++;
1286
				}
1287
				if (index < event.dataTypes.length) {
1288
					event.currentDataType = event.dataTypes[index];
1289
					event.detail = DND.DROP_COPY;
1290
					return;
1291
				}
1292
			}
1293
1294
			/*
1295
			 * (non-Javadoc)
1296
			 * 
1297
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
1298
			 */
1299
			public void drop(DropTargetEvent event) {
1300
				if (event.item == null)
1301
					return;
1302
				Object object = ((TreeItem) event.item).getData();
1303
				String contextId;
1304
				if (object instanceof TemplateContextType)
1305
					contextId = ((TemplateContextType) object).getId();
1306
				else
1307
					contextId = ((TemplatePersistenceData) object).getTemplate().getContextTypeId();
1308
				if (textTransfer.isSupportedType(event.currentDataType)) {
1309
					String text = (String) event.data;
1310
					final Template template = new Template(
1311
							TextEditorTemplateMessages.TemplatesPage_snippet,
1312
							TextEditorTemplateMessages.TemplatesPage_paste_description, contextId,
1313
							text.replaceAll("\\$", "\\$\\$"), true); //$NON-NLS-1$//$NON-NLS-2$
1314
					getShell().getDisplay().asyncExec(new Runnable() {
1315
						public void run() {
1316
							addTemplate(template, MAY_HIDE_DIALOG);
1317
						}
1318
					});
1319
				} else if (templateTransfer.isSupportedType(event.currentDataType)) {
1320
					Template[] templates = (Template[]) event.data;
1321
					Template t = templates[0];
1322
					final Template template = new Template(t.getName(), t.getDescription(),
1323
							contextId, t.getPattern(), true);
1324
					getShell().getDisplay().asyncExec(new Runnable() {
1325
						public void run() {
1326
							addTemplate(template, MAY_HIDE_DIALOG);
1327
						}
1328
					});
1329
				}
1330
			}
1331
1332
		};
1333
		fTreeViewer.addDropSupport(DND.DROP_COPY, new Transfer[] { TemplateTransfer.getInstance(),
1334
				TextTransfer.getInstance() }, dropListener);
1335
	}
1336
1337
	/**
1338
	 * Setup the editor site as a drop target. Should be invoked by the
1339
	 * subclasses for the D&D to work with the editor.
1340
	 * 
1341
	 * @param site
1342
	 * @param viewer
1343
	 */
1344
	protected void setupEditorDropTarget(IWorkbenchPartSite site, Control viewer) {
1345
		IDragAndDropService dndService = (IDragAndDropService) site
1346
				.getService(IDragAndDropService.class);
1347
		EditorDropTarget editorDropTarget = new EditorDropTarget();
1348
		dndService.addMergedDropTarget(viewer, DND.DROP_COPY, new Transfer[] { TemplateTransfer
1349
				.getInstance() }, editorDropTarget);
1350
	}
1351
1352
	/**
1353
	 * Refresh the template tree contents
1354
	 */
1355
	private void refresh() {
1356
		fTreeViewer.refresh();
1357
		fTreeViewer.expandAll();
1358
		decorateTemplates();
1359
	}
1360
1361
	/*
1362
	 * (non-Javadoc)
1363
	 * 
1364
	 * @see org.eclipse.ui.part.Page#setFocus()
1365
	 */
1366
	public void setFocus() {
1367
	}
1368
1369
	/*
1370
	 * (non-Javadoc)
1371
	 * 
1372
	 * @see org.eclipse.ui.part.Page#dispose()
1373
	 */
1374
	public void dispose() {
1375
		if (fContextMenu != null && !fContextMenu.isDisposed())
1376
			fContextMenu.dispose();
1377
		fTemplatePreferenceStore.removePropertyChangeListener(fTemplateChangeListener);
1378
		savePreferences();
1379
		super.dispose();
1380
	}
1381
1382
	/**
1383
	 * Save the preferences
1384
	 */
1385
	private void savePreferences() {
1386
		fPreferenceStore.setValue(SASH_SIZE_PREF_ID, fSashSize);
1387
		fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkWithEditor);
1388
		fPreferenceStore.setValue(SHOW_DISABLED_ACTION_PREF_ID, fShowDisabled);
1389
		fPreferenceStore.setValue(SHOW_NEW_DIALOG_ACTION_PREF_ID, fShowNewDialogOnDrop);
1390
		fPreferenceStore.setValue(COLUMN_NAME_WIDTH_PREF_ID, fNameWidth);
1391
		fPreferenceStore.setValue(COLUMN_DESCRIPTION_WIDTH_PREF_ID, fDescriptionWidth);
1392
	}
1393
}
(-)src/org/eclipse/ui/texteditor/templates/ITemplateViewImageConstants.java (+36 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.texteditor.templates;
12
13
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
14
15
/**
16
 * Image constants for the template page
17
 * 
18
 * @author kd
19
 * 
20
 * @since 3.4
21
 */
22
public interface ITemplateViewImageConstants {
23
	public static final String PREFIX_ELCL = TextEditorPlugin.PLUGIN_ID + ".elcl."; //$NON-NLS-1$
24
	public static final String PREFIX_DLCL = TextEditorPlugin.PLUGIN_ID + ".dlcl."; //$NON-NLS-1$
25
	public static final String PREFIX_OBJ  = TextEditorPlugin.PLUGIN_ID + ".obj."; //$NON-NLS-1$
26
	
27
	public final static String IMG_ELCL_TEMPLATE_NEW = PREFIX_ELCL + "new_template.gif"; //$NON-NLS-1$
28
	public static final String IMG_ELCL_TEMPLATE_DELETE = PREFIX_ELCL + "delete_template.gif"; //$NON-NLS-1$
29
	public final static String IMG_ELCL_TEMPLATE_EDIT = PREFIX_ELCL + "edit_template.gif"; //$NON-NLS-1$
30
	public static final String IMG_ELCL_TEMPLATE_LINK = PREFIX_ELCL + "link_to_editor.gif"; //$NON-NLS-1$
31
	public static final String IMG_ELCL_TEMPLATE_COLLAPSE_EXPAND = PREFIX_ELCL + "collapse_expand_all.gif"; //$NON-NLS-1$
32
	public static final String IMG_DLCL_TEMPLATE_DELETE = PREFIX_DLCL + "delete_template.gif"; //$NON-NLS-1$
33
	public final static String IMG_DLCL_TEMPLATE_EDIT = PREFIX_DLCL + "edit_template.gif"; //$NON-NLS-1$
34
	
35
	public final static String IMG_OBJ_PREVIEW = PREFIX_OBJ + "preview.gif"; //$NON-NLS-1$
36
}
(-)src/org/eclipse/ui/texteditor/templates/TemplatesViewImages.java (+161 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.texteditor.templates;
12
13
import java.net.URL;
14
15
import org.eclipse.core.runtime.FileLocator;
16
import org.eclipse.core.runtime.Path;
17
import org.eclipse.core.runtime.Platform;
18
import org.eclipse.jface.resource.ImageDescriptor;
19
import org.eclipse.jface.resource.ImageRegistry;
20
import org.eclipse.swt.graphics.Image;
21
import org.eclipse.swt.widgets.Display;
22
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
23
import org.osgi.framework.Bundle;
24
25
/**
26
 * The images provided by the texteditor plugin
27
 * @since 3.4
28
 */
29
public class TemplatesViewImages {
30
31
	/**
32
	 * The image registry containing <code>Image</code>s.
33
	 */
34
	private static ImageRegistry imageRegistry;
35
36
	private static String ICONS_PATH = "$nl$/icons/full/"; //$NON-NLS-1$
37
38
	// Use IPath and toOSString to build the names to ensure they have the
39
	// slashes correct
40
	private final static String ELCL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$
41
	private final static String DLCL = ICONS_PATH + "dlcl16/"; //$NON-NLS-1$
42
	private final static String OBJ = ICONS_PATH + "obj16/"; //$NON-NLS-1$
43
44
	/**
45
	 * Declare all images
46
	 */
47
	private static void declareImages() {
48
		// Ant Editor images
49
		declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_NEW, ELCL
50
				+ "new_template.gif"); //$NON-NLS-1$
51
		declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_DELETE, ELCL
52
				+ "delete_template.gif"); //$NON-NLS-1$
53
		declareRegistryImage(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_DELETE, DLCL
54
				+ "delete_template.gif"); //$NON-NLS-1$
55
		declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_EDIT, ELCL
56
				+ "edit_template.gif"); //$NON-NLS-1$
57
		declareRegistryImage(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_EDIT, DLCL
58
				+ "edit_template.gif"); //$NON-NLS-1$
59
		declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_LINK, ELCL
60
				+ "link_to_editor.gif"); //$NON-NLS-1$
61
		declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_COLLAPSE_EXPAND, ELCL
62
				+ "collapse_expand_all.gif"); //$NON-NLS-1$
63
64
		declareRegistryImage(ITemplateViewImageConstants.IMG_OBJ_PREVIEW, OBJ + "preview.gif"); //$NON-NLS-1$
65
	}
66
67
	/**
68
	 * Declare an Image in the registry table.
69
	 * 
70
	 * @param key
71
	 *            The key to use when registering the image
72
	 * @param path
73
	 *            The path where the image can be found. This path is relative
74
	 *            to where this plugin class is found (i.e. typically the
75
	 *            packages directory)
76
	 */
77
	private final static void declareRegistryImage(String key, String path) {
78
		ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor();
79
		Bundle bundle = Platform.getBundle(TextEditorPlugin.PLUGIN_ID);
80
		URL url = null;
81
		if (bundle != null) {
82
			url = FileLocator.find(bundle, new Path(path), null);
83
			desc = ImageDescriptor.createFromURL(url);
84
		}
85
		imageRegistry.put(key, desc);
86
	}
87
88
	/**
89
	 * Returns the ImageRegistry.
90
	 * 
91
	 * @return image registry
92
	 */
93
	public static ImageRegistry getImageRegistry() {
94
		if (imageRegistry == null) {
95
			initializeImageRegistry();
96
		}
97
		return imageRegistry;
98
	}
99
100
	/**
101
	 * Initialize the image registry by declaring all of the required graphics.
102
	 * This involves creating JFace image descriptors describing how to
103
	 * create/find the image should it be needed. The image is not actually
104
	 * allocated until requested.
105
	 * 
106
	 * Prefix conventions Wizard Banners WIZBAN_ Preference Banners PREF_BAN_
107
	 * Property Page Banners PROPBAN_ Color toolbar CTOOL_ Enable toolbar ETOOL_
108
	 * Disable toolbar DTOOL_ Local enabled toolbar ELCL_ Local Disable toolbar
109
	 * DLCL_ Object large OBJL_ Object small OBJS_ View VIEW_ Product images
110
	 * PROD_ Misc images MISC_
111
	 * 
112
	 * Where are the images? The images (typically gifs) are found in the same
113
	 * location as this plugin class. This may mean the same package directory
114
	 * as the package holding this class. The images are declared using
115
	 * this.getClass() to ensure they are looked up via this plugin class.
116
	 * 
117
	 * @return the image registry
118
	 * @see org.eclipse.jface.resource.ImageRegistry
119
	 */
120
	public static ImageRegistry initializeImageRegistry() {
121
		imageRegistry = new ImageRegistry(getStandardDisplay());
122
		declareImages();
123
		return imageRegistry;
124
	}
125
126
	/**
127
	 * Returns the standard display to be used. The method first checks, if the
128
	 * thread calling this method has an associated display. If so, this display
129
	 * is returned. Otherwise the method returns the default display.
130
	 * 
131
	 * @return the display
132
	 */
133
	public static Display getStandardDisplay() {
134
		Display display = Display.getCurrent();
135
		if (display == null) {
136
			display = Display.getDefault();
137
		}
138
		return display;
139
	}
140
141
	/**
142
	 * Returns the <code>Image<code> identified by the given key,
143
	 * or <code>null</code> if it does not exist.
144
	 * @param key 
145
	 * @return the image
146
	 */
147
	public static Image getImage(String key) {
148
		return getImageRegistry().get(key);
149
	}
150
151
	/**
152
	 * Returns the <code>ImageDescriptor<code> identified by the given key,
153
	 * or <code>null</code> if it does not exist.
154
	 * @param key 
155
	 * @return the image descriptor
156
	 */
157
	public static ImageDescriptor getImageDescriptor(String key) {
158
		return getImageRegistry().getDescriptor(key);
159
	}
160
161
}
(-)src/org/eclipse/ui/texteditor/templates/TemplateTransfer.java (+180 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.texteditor.templates;
12
13
import java.io.ByteArrayInputStream;
14
import java.io.ByteArrayOutputStream;
15
import java.io.DataInputStream;
16
import java.io.DataOutputStream;
17
import java.io.IOException;
18
import java.util.ArrayList;
19
20
import org.eclipse.jface.text.templates.Template;
21
import org.eclipse.swt.dnd.ByteArrayTransfer;
22
import org.eclipse.swt.dnd.TransferData;
23
24
/**
25
 * Transfer type used for clip board and DnD operations for template objects
26
 * 
27
 * @see TemplatesPage
28
 *
29
 * @since 3.4
30
 */
31
public class TemplateTransfer extends ByteArrayTransfer {
32
33
	private static TemplateTransfer instance;
34
35
	private static final String LOCAL_NAME = TemplateTransfer.class.getName()
36
			+ System.currentTimeMillis();
37
	private static final int LOCAL_TYPE = registerType(LOCAL_NAME);
38
39
	private static String[] names = null;
40
	private static int types[] = null;
41
42
	/**
43
	 * @return the registered Transfer instance
44
	 */
45
	public static TemplateTransfer getInstance() {
46
		if (instance == null) {
47
			instance = new TemplateTransfer();
48
			types = new int[] { LOCAL_TYPE };
49
			names = new String[] { LOCAL_NAME };
50
		}
51
		return instance;
52
	}
53
54
	/*
55
	 * (non-Javadoc)
56
	 * 
57
	 * @see org.eclipse.swt.dnd.Transfer#getTypeIds()
58
	 */
59
	protected int[] getTypeIds() {
60
		return types;
61
	}
62
63
	/*
64
	 * (non-Javadoc)
65
	 * 
66
	 * @see org.eclipse.swt.dnd.Transfer#getTypeNames()
67
	 */
68
	protected String[] getTypeNames() {
69
		return names;
70
	}
71
72
	/*
73
	 * (non-Javadoc)
74
	 * 
75
	 * @see org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(java.lang.Object,
76
	 *      org.eclipse.swt.dnd.TransferData)
77
	 */
78
	protected void javaToNative(Object object, TransferData transferData) {
79
		if (object == null || !(object instanceof Template[])
80
				|| !isSupportedType(transferData))
81
			return;
82
		ByteArrayOutputStream out = new ByteArrayOutputStream();
83
		DataOutputStream dataOut = new DataOutputStream(out);
84
		Template[] templates = (Template[]) object;
85
		for (int i = 0; i < templates.length; i++) {
86
			writeTemplate(dataOut, templates[i]);
87
		}
88
		byte[] byteArray = out.toByteArray();
89
		try {
90
			dataOut.close();
91
		} catch (IOException e) {
92
		}
93
		super.javaToNative(byteArray, transferData);
94
	}
95
96
	/**
97
	 * Write a template to the output stream
98
	 * 
99
	 * @param dataOut
100
	 * @param template
101
	 */
102
	private void writeTemplate(DataOutputStream dataOut, Template template) {
103
		try {
104
			writeString(dataOut, template.getName());
105
			writeString(dataOut, template.getDescription());
106
			writeString(dataOut, template.getContextTypeId());
107
			writeString(dataOut, template.getPattern());
108
			dataOut.writeBoolean(template.isAutoInsertable());
109
		} catch (IOException e) {
110
		}
111
	}
112
113
	/**
114
	 * Write a string to the output stream
115
	 * 
116
	 * @param dataOut
117
	 * @param name
118
	 * @throws IOException
119
	 */
120
	private void writeString(DataOutputStream dataOut, String name)
121
			throws IOException {
122
		byte[] bytes = name.getBytes();
123
		dataOut.writeInt(bytes.length);
124
		dataOut.write(bytes);
125
	}
126
127
	/*
128
	 * (non-Javadoc)
129
	 * 
130
	 * @see org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(org.eclipse.swt.dnd.TransferData)
131
	 */
132
	protected Object nativeToJava(TransferData transferData) {
133
		byte[] bytes = (byte[]) super.nativeToJava(transferData);
134
		if (bytes == null)
135
			return null;
136
		ArrayList listTemplates = new ArrayList();
137
		ByteArrayInputStream in = new ByteArrayInputStream(bytes);
138
		DataInputStream dataIn = new DataInputStream(in);
139
		try {
140
			while (dataIn.available() > 0) {
141
				Template template = readTempate(dataIn);
142
				if (template == null)
143
					break;
144
				listTemplates.add(template);
145
			}
146
		} catch (IOException e) {
147
		} finally {
148
			try {
149
				dataIn.close();
150
			} catch (IOException e) {
151
			}
152
		}
153
		return listTemplates.toArray(new Template[listTemplates.size()]);
154
	}
155
156
	/**
157
	 * Read a template from the data input stream.
158
	 * 
159
	 * @param dataIn
160
	 * @return the template
161
	 * @throws IOException
162
	 */
163
	private Template readTempate(DataInputStream dataIn) throws IOException {
164
		return new Template(readString(dataIn), readString(dataIn),
165
				readString(dataIn), readString(dataIn), dataIn.readBoolean());
166
	}
167
168
	/**
169
	 * Read a string from the data input stream
170
	 * 
171
	 * @param dataIn
172
	 * @return the string
173
	 * @throws IOException
174
	 */
175
	private String readString(DataInputStream dataIn) throws IOException {
176
		byte[] bytes = new byte[dataIn.readInt()];
177
		dataIn.read(bytes);
178
		return new String(bytes);
179
	}
180
}
(-)Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties (+6 lines)
Lines 8-13 Link Here
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
#     John-Mason P. Shackelford - bug 40255
10
#     John-Mason P. Shackelford - bug 40255
11
#     Dakshinamurthy Karra - TemplatesPage support
11
###############################################################################
12
###############################################################################
12
13
13
ContentAssistProposal.label=Content &Assist@Ctrl+Space
14
ContentAssistProposal.label=Content &Assist@Ctrl+Space
Lines 41-43 Link Here
41
AntAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
42
AntAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
42
43
43
AntEditor.3=Current text selection does not resolve to an Ant reference
44
AntEditor.3=Current text selection does not resolve to an Ant reference
45
46
Editor.Paste.label=&Paste
47
Editor.Paste.tooltip=Paste
48
Editor.Paste.image=
49
Editor.Paste.description=Paste
(-)Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditor.java (-1 / +81 lines)
Lines 12-17 Link Here
12
 * 	   IBM Corporation - bug fixes
12
 * 	   IBM Corporation - bug fixes
13
 * 	   John-Mason P. Shackelford - bug 40255
13
 * 	   John-Mason P. Shackelford - bug 40255
14
 *     Mark Melvin - bug 93378
14
 *     Mark Melvin - bug 93378
15
 *     Dakshinamurthy Karra - TemplatesView support
15
 *******************************************************************************/
16
 *******************************************************************************/
16
17
17
package org.eclipse.ant.internal.ui.editor;
18
package org.eclipse.ant.internal.ui.editor;
Lines 34-39 Link Here
34
import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter;
35
import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter;
35
import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction;
36
import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction;
36
import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage;
37
import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage;
38
import org.eclipse.ant.internal.ui.editor.templates.AntTemplatesPage;
37
import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider;
39
import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider;
38
import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider;
40
import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider;
39
import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant;
41
import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant;
Lines 71-76 Link Here
71
import org.eclipse.jface.text.ISelectionValidator;
73
import org.eclipse.jface.text.ISelectionValidator;
72
import org.eclipse.jface.text.ISynchronizable;
74
import org.eclipse.jface.text.ISynchronizable;
73
import org.eclipse.jface.text.ITextInputListener;
75
import org.eclipse.jface.text.ITextInputListener;
76
import org.eclipse.jface.text.ITextOperationTarget;
74
import org.eclipse.jface.text.ITextSelection;
77
import org.eclipse.jface.text.ITextSelection;
75
import org.eclipse.jface.text.ITextViewer;
78
import org.eclipse.jface.text.ITextViewer;
76
import org.eclipse.jface.text.Position;
79
import org.eclipse.jface.text.Position;
Lines 85-90 Link Here
85
import org.eclipse.jface.text.source.projection.IProjectionListener;
88
import org.eclipse.jface.text.source.projection.IProjectionListener;
86
import org.eclipse.jface.text.source.projection.ProjectionSupport;
89
import org.eclipse.jface.text.source.projection.ProjectionSupport;
87
import org.eclipse.jface.text.source.projection.ProjectionViewer;
90
import org.eclipse.jface.text.source.projection.ProjectionViewer;
91
import org.eclipse.jface.text.templates.Template;
88
import org.eclipse.jface.util.PropertyChangeEvent;
92
import org.eclipse.jface.util.PropertyChangeEvent;
89
import org.eclipse.jface.viewers.IPostSelectionProvider;
93
import org.eclipse.jface.viewers.IPostSelectionProvider;
90
import org.eclipse.jface.viewers.ISelection;
94
import org.eclipse.jface.viewers.ISelection;
Lines 93-98 Link Here
93
import org.eclipse.jface.viewers.IStructuredSelection;
97
import org.eclipse.jface.viewers.IStructuredSelection;
94
import org.eclipse.jface.viewers.SelectionChangedEvent;
98
import org.eclipse.jface.viewers.SelectionChangedEvent;
95
import org.eclipse.swt.custom.StyledText;
99
import org.eclipse.swt.custom.StyledText;
100
import org.eclipse.swt.dnd.Clipboard;
96
import org.eclipse.swt.events.ShellAdapter;
101
import org.eclipse.swt.events.ShellAdapter;
97
import org.eclipse.swt.events.ShellEvent;
102
import org.eclipse.swt.events.ShellEvent;
98
import org.eclipse.swt.graphics.Image;
103
import org.eclipse.swt.graphics.Image;
Lines 112-127 Link Here
112
import org.eclipse.ui.texteditor.ContentAssistAction;
117
import org.eclipse.ui.texteditor.ContentAssistAction;
113
import org.eclipse.ui.texteditor.IDocumentProvider;
118
import org.eclipse.ui.texteditor.IDocumentProvider;
114
import org.eclipse.ui.texteditor.IEditorStatusLine;
119
import org.eclipse.ui.texteditor.IEditorStatusLine;
120
import org.eclipse.ui.texteditor.ITextEditor;
115
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
121
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
116
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
122
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
123
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
124
import org.eclipse.ui.texteditor.TextEditorAction;
117
import org.eclipse.ui.texteditor.TextOperationAction;
125
import org.eclipse.ui.texteditor.TextOperationAction;
126
import org.eclipse.ui.texteditor.templates.TemplateTransfer;
118
import org.eclipse.ui.views.contentoutline.ContentOutline;
127
import org.eclipse.ui.views.contentoutline.ContentOutline;
119
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
128
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
129
import org.eclipse.ui.views.templates.ITemplatesPage;
120
130
121
/**
131
/**
122
 * The actual editor implementation for Eclipse's Ant integration.
132
 * The actual editor implementation for Eclipse's Ant integration.
123
 */
133
 */
124
public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener {
134
public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener {
135
136
	/**
137
	 * Clipboard paste operation support for templates
138
	 * 
139
	 * @since 3.4
140
	 */
141
	class ClipboardPasteOperation extends TextEditorAction {
142
		private ITextOperationTarget fOperationTarget;
143
		private int fOperationCode = -1;
144
145
		protected ClipboardPasteOperation(ResourceBundle bundle, String prefix, ITextEditor editor,
146
				int style) {
147
			super(bundle, prefix, editor, style);
148
		}
149
150
		/* (non-Javadoc)
151
		 * @see org.eclipse.jface.action.Action#run()
152
		 */
153
		public void run() {
154
			ITextEditor editor = getTextEditor();
155
			Clipboard clipboard = new Clipboard(getSite().getShell().getDisplay());
156
			Template[] templates = (Template[]) clipboard.getContents(TemplateTransfer
157
					.getInstance());
158
			if (templates != null) {
159
				AntTemplatesPage page = (AntTemplatesPage) editor.getAdapter(ITemplatesPage.class);
160
				page.insertTemplate(templates[0]);
161
			} else
162
				fOperationTarget.doOperation(fOperationCode);
163
		}
164
	}
165
166
125
	/**
167
	/**
126
	 * Updates the Ant outline page selection and this editor's range indicator.
168
	 * Updates the Ant outline page selection and this editor's range indicator.
127
	 * 
169
	 * 
Lines 461-467 Link Here
461
     * The page that shows the outline.
503
     * The page that shows the outline.
462
     */
504
     */
463
    protected AntEditorContentOutlinePage fOutlinePage;
505
    protected AntEditorContentOutlinePage fOutlinePage;
464
    
506
	/**
507
	 * The templates page
508
     *
509
	 * @since 3.4
510
	 */
511
	protected AntTemplatesPage fTemplatesPage;
465
	
512
	
466
	private boolean fInitialReconcile= true;
513
	private boolean fInitialReconcile= true;
467
	
514
	
Lines 538-543 Link Here
538
		action= new RenameInFileAction(this);
585
		action= new RenameInFileAction(this);
539
		action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$
586
		action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$
540
		setAction("renameInFile", action); //$NON-NLS-1$
587
		setAction("renameInFile", action); //$NON-NLS-1$
588
		
589
		// Override the TextEditor paste operation to support templates
590
		action = new ClipboardPasteOperation(bundle,
591
				"Editor.Paste.", this, ITextOperationTarget.PASTE); //$NON-NLS-1$
592
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
593
		setAction(ITextEditorActionConstants.PASTE, action);
541
    }
594
    }
542
595
543
	/*
596
	/*
Lines 564-569 Link Here
564
			return getOutlinePage();
617
			return getOutlinePage();
565
        }
618
        }
566
        
619
        
620
		if (key.equals(ITemplatesPage.class)) {
621
			return getTemplatesPage();
622
		}
623
567
        if (fProjectionSupport != null) { 
624
        if (fProjectionSupport != null) { 
568
        	Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key); 
625
        	Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key); 
569
        	if (adapter != null) {
626
        	if (adapter != null) {
Lines 599-604 Link Here
599
		return fOutlinePage;
656
		return fOutlinePage;
600
	}
657
	}
601
658
659
	/**
660
	 * @since 3.4
661
	 * 
662
	 * @return the templatespage for this editor
663
	 */
664
	private AntTemplatesPage getTemplatesPage() {
665
		if (fTemplatesPage == null) {
666
			fTemplatesPage = new AntTemplatesPage(this);
667
		}
668
		return fTemplatesPage;
669
	}
670
671
	/* (non-Javadoc)
672
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleCursorPositionChanged()
673
	 * 
674
	 * @since 3.4
675
	 */
676
	protected void handleCursorPositionChanged() {
677
		super.handleCursorPositionChanged();
678
		if (fTemplatesPage != null)
679
			fTemplatesPage.cursorPositionChanged();
680
	}
681
602
    private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) {
682
    private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) {
603
        IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection();
683
        IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection();
604
684
(-)Ant (+197 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007  Dakshinamurthy Karra 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
 * 	   Dakshinamurthy Karra - Initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ant.internal.ui.editor.templates;
12
13
import org.eclipse.ant.internal.ui.AntUIPlugin;
14
import org.eclipse.ant.internal.ui.editor.AntEditor;
15
import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
16
import org.eclipse.ant.internal.ui.editor.formatter.XmlFormatter;
17
import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
18
import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
19
import org.eclipse.jface.resource.JFaceResources;
20
import org.eclipse.jface.text.Document;
21
import org.eclipse.jface.text.IDocument;
22
import org.eclipse.jface.text.IRegion;
23
import org.eclipse.jface.text.ITextSelection;
24
import org.eclipse.jface.text.Position;
25
import org.eclipse.jface.text.Region;
26
import org.eclipse.jface.text.source.ISourceViewer;
27
import org.eclipse.jface.text.source.SourceViewer;
28
import org.eclipse.jface.text.source.SourceViewerConfiguration;
29
import org.eclipse.jface.text.templates.ContextTypeRegistry;
30
import org.eclipse.jface.text.templates.Template;
31
import org.eclipse.jface.text.templates.TemplateContextType;
32
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.graphics.Font;
34
import org.eclipse.swt.graphics.Point;
35
import org.eclipse.swt.widgets.Composite;
36
import org.eclipse.ui.texteditor.templates.TemplatesPage;
37
import org.eclipse.ui.views.templates.ITemplatesPage;
38
39
/**
40
 * An implementation of TemplatesPage for AntEditor
41
 * 
42
 * @see TemplatesPage
43
 * @since 3.4
44
 */
45
public class AntTemplatesPage extends TemplatesPage implements ITemplatesPage {
46
47
	private static final ContextTypeRegistry CONTEXT_TYPE_REGISTRY = AntTemplateAccess
48
			.getDefault().getContextTypeRegistry();
49
	private FormattingPreferences fFormattingPreferences = new FormattingPreferences();
50
	private final AntEditor fEditor;
51
	private String fCurrentId;
52
53
	/**
54
	 * Constructor
55
	 * 
56
	 * @param editor
57
	 */
58
	public AntTemplatesPage(AntEditor editor) {
59
		super(AntTemplateAccess.getDefault().getTemplateStore(),
60
				AntUIPlugin.getDefault().getPreferenceStore(), CONTEXT_TYPE_REGISTRY);
61
		fEditor = editor;
62
		cursorPositionChanged();
63
		setupEditorDropTarget(fEditor.getSite(), fEditor.getViewer()
64
				.getTextWidget());
65
	}
66
67
	/*
68
	 * (non-Javadoc)
69
	 * 
70
	 * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#createViewer(org.eclipse.swt.widgets.Composite)
71
	 */
72
	protected SourceViewer createViewer(Composite parent) {
73
		SourceViewer viewer = new SourceViewer(parent, null, SWT.BORDER
74
				| SWT.V_SCROLL | SWT.H_SCROLL);
75
76
		SourceViewerConfiguration configuration = new AntTemplateViewerConfiguration();
77
		IDocument document = new Document();
78
		new AntDocumentSetupParticipant().setup(document);
79
		viewer.configure(configuration);
80
		viewer.setDocument(document);
81
		viewer.setEditable(false);
82
		Font font = JFaceResources.getFont(JFaceResources.TEXT_FONT);
83
		viewer.getTextWidget().setFont(font);
84
85
		return viewer;
86
	}
87
88
	/*
89
	 * (non-Javadoc)
90
	 * 
91
	 * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#getFormatterPreferenceKey()
92
	 */
93
	protected String getFormatterPreferenceKey() {
94
		return AntEditorPreferenceConstants.TEMPLATES_USE_CODEFORMATTER;
95
	}
96
97
	/*
98
	 * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#updateViewerInput()
99
	 */
100
	protected void updateViewerInput(Template template) {
101
		SourceViewer viewer = getViewer();
102
103
		if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(
104
				getFormatterPreferenceKey())) {
105
			String formatted = XmlFormatter.format(template.getPattern(),
106
					fFormattingPreferences);
107
			viewer.getDocument().set(formatted);
108
		} else {
109
			viewer.getDocument().set(template.getPattern());
110
		}
111
	}
112
113
	/*
114
	 * (non-Javadoc)
115
	 * 
116
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId()
117
	 */
118
	protected String getPreferencePageId() {
119
		return "org.eclipse.ant.ui.TemplatesPreferencePage"; //$NON-NLS-1$
120
	}
121
122
	/*
123
	 * (non-Javadoc)
124
	 * 
125
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template)
126
	 */
127
	public void insertTemplate(Template template) {
128
		IRegion region;
129
		TemplateContextType type = CONTEXT_TYPE_REGISTRY
130
				.getContextType(template.getContextTypeId());
131
		if (type == null)
132
			return;
133
		ISourceViewer contextViewer = fEditor.getViewer();
134
		ITextSelection textSelection = (ITextSelection) contextViewer
135
				.getSelectionProvider().getSelection();
136
		region = new Region(textSelection.getOffset(), textSelection
137
				.getLength());
138
		Point selection = contextViewer.getSelectedRange();
139
		Position position;
140
		if (selection.y > 0) {
141
			position = new Position(selection.x, selection.y);
142
		} else {
143
			position = new Position(region.getOffset(), region.getLength());
144
		}
145
146
		IDocument document = contextViewer.getDocument();
147
		AntContext context = new AntContext(type, document, fEditor
148
				.getAntModel(), position);
149
		context.setVariable("selection", textSelection.getText()); //$NON-NLS-1$
150
		AntTemplateProposal proposal = new AntTemplateProposal(template,
151
				context, region, null, 100);
152
		fEditor.getSite().getPage().activate(fEditor);
153
		proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset());
154
	}
155
156
	/**
157
	 * Invoked by the editor whenever the caret position is updated
158
	 */
159
	public void cursorPositionChanged() {
160
		String id= getContextId();
161
		if (id.equals(fCurrentId))
162
			return;
163
		fCurrentId = id;
164
		if (fCurrentId.equals(BuildFileContextType.BUILDFILE_CONTEXT_TYPE))
165
			contextTypeChanged(new String[] { BuildFileContextType.BUILDFILE_CONTEXT_TYPE });
166
		else
167
			contextTypeChanged(new String[] {
168
					TargetContextType.TARGET_CONTEXT_TYPE,
169
					TaskContextType.TASK_CONTEXT_TYPE });
170
	}
171
172
	/**
173
	 * Get the contextid for the editor
174
	 * 
175
	 * @return contextId
176
	 */
177
	private String getContextId() {
178
		if (fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput())
179
				.getLength() == 0)
180
			return BuildFileContextType.BUILDFILE_CONTEXT_TYPE;
181
		return TargetContextType.TARGET_CONTEXT_TYPE;
182
	}
183
	
184
	/* (non-Javadoc)
185
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isValidTempalteForPosition(org.eclipse.jface.text.templates.Template, int, int)
186
	 */
187
	protected boolean isValidTemplateForPosition(Template template, int x, int y) {
188
		return getContextId().equals(template.getContextTypeId());
189
	}
190
	
191
	/* (non-Javadoc)
192
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isEditorModifiable()
193
	 */
194
	protected boolean isEditorModifiable() {
195
		return fEditor.isEditable() ;
196
	}
197
}
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.java (-1 / +12 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Dakshinamurthy Karra - TemplatesPage support (bug 69581)
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui.javaeditor;
12
package org.eclipse.jdt.internal.ui.javaeditor;
12
13
Lines 41-52 Link Here
41
import org.eclipse.jface.text.ITextOperationTarget;
42
import org.eclipse.jface.text.ITextOperationTarget;
42
import org.eclipse.jface.text.ITextSelection;
43
import org.eclipse.jface.text.ITextSelection;
43
import org.eclipse.jface.text.Region;
44
import org.eclipse.jface.text.Region;
45
import org.eclipse.jface.text.templates.Template;
44
46
45
import org.eclipse.ui.IWorkbenchPartSite;
47
import org.eclipse.ui.IWorkbenchPartSite;
46
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
48
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
47
import org.eclipse.ui.texteditor.ITextEditor;
49
import org.eclipse.ui.texteditor.ITextEditor;
48
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
50
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
49
import org.eclipse.ui.texteditor.TextEditorAction;
51
import org.eclipse.ui.texteditor.TextEditorAction;
52
import org.eclipse.ui.texteditor.templates.TemplateTransfer;
53
54
import org.eclipse.ui.views.templates.ITemplatesPage;
50
55
51
import org.eclipse.jdt.core.ICompilationUnit;
56
import org.eclipse.jdt.core.ICompilationUnit;
52
import org.eclipse.jdt.core.IJavaElement;
57
import org.eclipse.jdt.core.IJavaElement;
Lines 66-71 Link Here
66
import org.eclipse.jdt.ui.PreferenceConstants;
71
import org.eclipse.jdt.ui.PreferenceConstants;
67
72
68
import org.eclipse.jdt.internal.ui.JavaPlugin;
73
import org.eclipse.jdt.internal.ui.JavaPlugin;
74
import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage;
69
75
70
76
71
/**
77
/**
Lines 489-495 Link Here
489
				}
495
				}
490
			}
496
			}
491
		} else {
497
		} else {
492
			fOperationTarget.doOperation(fOperationCode);
498
			Template[] templates= (Template[]) clipboard.getContents(TemplateTransfer.getInstance());
499
			if (templates != null) {
500
				JavaTemplatesPage page= (JavaTemplatesPage) editor.getAdapter(ITemplatesPage.class);
501
				page.insertTemplate(templates[0]);
502
			} else
503
				fOperationTarget.doOperation(fOperationCode);
493
		}
504
		}
494
	}
505
	}
495
506
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java (+26 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Dakshinamurthy Karra - TemplatesPage support (bug 69581)
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui.javaeditor;
12
package org.eclipse.jdt.internal.ui.javaeditor;
12
13
Lines 141-146 Link Here
141
142
142
import org.eclipse.ui.views.contentoutline.ContentOutline;
143
import org.eclipse.ui.views.contentoutline.ContentOutline;
143
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
144
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
145
import org.eclipse.ui.views.templates.ITemplatesPage;
144
146
145
import org.eclipse.jdt.core.IClassFile;
147
import org.eclipse.jdt.core.IClassFile;
146
import org.eclipse.jdt.core.ICompilationUnit;
148
import org.eclipse.jdt.core.ICompilationUnit;
Lines 194-199 Link Here
194
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
196
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
195
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
197
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
196
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
198
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
199
import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage;
197
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
200
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
198
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
201
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
199
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
202
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
Lines 1333-1338 Link Here
1333
	protected JavaOutlinePage fOutlinePage;
1336
	protected JavaOutlinePage fOutlinePage;
1334
	/** Outliner context menu Id */
1337
	/** Outliner context menu Id */
1335
	protected String fOutlinerContextMenuId;
1338
	protected String fOutlinerContextMenuId;
1339
	/** The templates page
1340
     *
1341
     *  @since 3.4
1342
    */
1343
	private JavaTemplatesPage fTemplatesPage;
1344
	
1336
	/**
1345
	/**
1337
	 * The editor selection changed listener.
1346
	 * The editor selection changed listener.
1338
	 *
1347
	 *
Lines 1778-1783 Link Here
1778
			return fOutlinePage;
1787
			return fOutlinePage;
1779
		}
1788
		}
1780
1789
1790
		if (required.equals(ITemplatesPage.class)) {
1791
			return getTemplatesPage();
1792
		}
1793
1781
		if (IEncodingSupport.class.equals(required))
1794
		if (IEncodingSupport.class.equals(required))
1782
			return fEncodingSupport;
1795
			return fEncodingSupport;
1783
1796
Lines 1833-1838 Link Here
1833
	}
1846
	}
1834
1847
1835
	/**
1848
	/**
1849
     *  @since 3.4
1850
     */
1851
	private JavaTemplatesPage getTemplatesPage() {
1852
		if (fTemplatesPage == null) {
1853
			fTemplatesPage= new JavaTemplatesPage(this);
1854
1855
		}
1856
		return fTemplatesPage;
1857
	}
1858
1859
	/**
1836
	 * React to changed selection.
1860
	 * React to changed selection.
1837
	 *
1861
	 *
1838
	 * @since 3.0
1862
	 * @since 3.0
Lines 3225-3230 Link Here
3225
	protected void handleCursorPositionChanged() {
3249
	protected void handleCursorPositionChanged() {
3226
		super.handleCursorPositionChanged();
3250
		super.handleCursorPositionChanged();
3227
		fCachedSelectedRange= getViewer().getSelectedRange();
3251
		fCachedSelectedRange= getViewer().getSelectedRange();
3252
		if (fTemplatesPage != null)
3253
			fTemplatesPage.cursorPositionChanged();
3228
	}
3254
	}
3229
3255
3230
	private static boolean isBracket(char character) {
3256
	private static boolean isBracket(char character) {
(-)ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java (+353 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui.preferences;
12
13
import org.eclipse.swt.SWT;
14
import org.eclipse.swt.custom.StyledText;
15
import org.eclipse.swt.graphics.Font;
16
import org.eclipse.swt.graphics.Point;
17
import org.eclipse.swt.layout.GridData;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Control;
20
21
import org.eclipse.jface.preference.IPreferenceStore;
22
import org.eclipse.jface.resource.JFaceResources;
23
import org.eclipse.jface.window.Window;
24
25
import org.eclipse.jface.text.BadLocationException;
26
import org.eclipse.jface.text.Document;
27
import org.eclipse.jface.text.IDocument;
28
import org.eclipse.jface.text.ITextSelection;
29
import org.eclipse.jface.text.ITextViewerExtension5;
30
import org.eclipse.jface.text.IUndoManager;
31
import org.eclipse.jface.text.Position;
32
import org.eclipse.jface.text.Region;
33
import org.eclipse.jface.text.TextSelection;
34
import org.eclipse.jface.text.TextUtilities;
35
import org.eclipse.jface.text.source.ISourceViewer;
36
import org.eclipse.jface.text.source.SourceViewer;
37
import org.eclipse.jface.text.templates.ContextTypeRegistry;
38
import org.eclipse.jface.text.templates.Template;
39
import org.eclipse.jface.text.templates.TemplateContextType;
40
41
import org.eclipse.ui.part.FileEditorInput;
42
import org.eclipse.ui.texteditor.templates.TemplatesPage;
43
44
import org.eclipse.ui.views.templates.ITemplatesPage;
45
46
import org.eclipse.jdt.core.ICompilationUnit;
47
import org.eclipse.jdt.core.JavaCore;
48
49
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext;
50
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType;
51
import org.eclipse.jdt.internal.corext.template.java.JavaContextType;
52
import org.eclipse.jdt.internal.corext.template.java.JavaDocContextType;
53
54
import org.eclipse.jdt.ui.PreferenceConstants;
55
import org.eclipse.jdt.ui.text.IJavaPartitions;
56
import org.eclipse.jdt.ui.text.JavaTextTools;
57
58
import org.eclipse.jdt.internal.ui.JavaPlugin;
59
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
60
import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
61
import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
62
import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal;
63
import org.eclipse.jdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
64
65
/**
66
 * A TemplatesPage implementation for JavaEditor
67
 * 
68
 * @since 3.4
69
 */
70
public class JavaTemplatesPage extends TemplatesPage implements ITemplatesPage {
71
72
	private static final ContextTypeRegistry TEMPLATE_CONTEXT_REGISTRY= JavaPlugin.getDefault().getTemplateContextRegistry();
73
	private TemplateVariableProcessor fTemplateProcessor;
74
	private final JavaEditor fEditor;
75
	private IDocument fDocument;
76
	private String fJavaDocId;
77
	private String fJavaId;
78
	private String fCurrentId;
79
	private int fCachedOffset;
80
	private boolean fCachedResult;
81
	private Point fCachedPosition;
82
83
	/**
84
	 * @param javaEditor
85
	 */
86
	public JavaTemplatesPage(JavaEditor javaEditor) {
87
		super(JavaPlugin.getDefault().getTemplateStore(), JavaPlugin.getDefault().getPreferenceStore(), TEMPLATE_CONTEXT_REGISTRY);
88
		fEditor= javaEditor;
89
		fJavaDocId= new JavaDocContextType().getId();
90
		fJavaId= new JavaContextType().getId();
91
		fTemplateProcessor= new TemplateVariableProcessor();
92
		fDocument= fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
93
		cursorPositionChanged();
94
		setupEditorDropTarget(fEditor.getSite(), fEditor.getViewer().getTextWidget());
95
	}
96
97
	public void dispose() {
98
		super.dispose();
99
	}
100
101
	/* (non-Javadoc)
102
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#editTemplate(org.eclipse.jface.text.templates.Template, boolean, boolean)
103
	 */
104
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
105
		EditTemplateDialog dialog= new EditTemplateDialog(getShell(), template, edit, isNameModifiable, TEMPLATE_CONTEXT_REGISTRY);
106
		if (dialog.open() == Window.OK) {
107
			return dialog.getTemplate();
108
		}
109
		return null;
110
	}
111
112
	/* (non-Javadoc)
113
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#createViewer(org.eclipse.swt.widgets.Composite)
114
	 */
115
	protected SourceViewer createViewer(Composite parent) {
116
		IDocument document= new Document();
117
		JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools();
118
		tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
119
		IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
120
		SourceViewer viewer= new JavaSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
121
		SimpleJavaSourceViewerConfiguration configuration= new SimpleJavaSourceViewerConfiguration(tools.getColorManager(), store, null, IJavaPartitions.JAVA_PARTITIONING, false);
122
		viewer.configure(configuration);
123
		viewer.setEditable(false);
124
		viewer.setDocument(document);
125
126
		Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
127
		viewer.getTextWidget().setFont(font);
128
		new JavaSourcePreviewerUpdater(viewer, configuration, store);
129
130
		Control control= viewer.getControl();
131
		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
132
		control.setLayoutData(data);
133
134
		return viewer;
135
	}
136
137
138
	/* (non-Javadoc)
139
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#updateViewerInput(org.eclipse.jface.text.templates.Template)
140
	 */
141
	protected void updateViewerInput(Template template) {
142
		SourceViewer viewer= getViewer();
143
144
		String contextId= template.getContextTypeId();
145
		TemplateContextType type= TEMPLATE_CONTEXT_REGISTRY.getContextType(contextId);
146
		fTemplateProcessor.setContextType(type);
147
148
		IDocument doc= viewer.getDocument();
149
150
		String start= null;
151
		if ("javadoc".equals(contextId)) { //$NON-NLS-1$
152
			start= "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
153
		} else
154
			start= ""; //$NON-NLS-1$
155
156
		doc.set(start + template.getPattern());
157
		int startLen= start.length();
158
		viewer.setDocument(doc, startLen, doc.getLength() - startLen);
159
	}
160
161
	/* (non-Javadoc)
162
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId()
163
	 */
164
	protected String getPreferencePageId() {
165
		return "org.eclipse.jdt.ui.preferences.JavaTemplatePreferencePage"; //$NON-NLS-1$
166
	}
167
168
	/* (non-Javadoc)
169
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template)
170
	 */
171
	public void insertTemplate(Template template) {
172
		if (!fEditor.isEditorInputModifiable())
173
			return;
174
		TemplateContextType type= TEMPLATE_CONTEXT_REGISTRY.getContextType(template.getContextTypeId());
175
		ISourceViewer contextViewer= fEditor.getViewer();
176
		ITextSelection textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
177
		if ( !isValidTemplate(template, textSelection.getOffset(), textSelection.getLength()))
178
			return;
179
		IUndoManager undoManager= ((JavaSourceViewer) fEditor.getViewer()).getUndoManager();
180
		undoManager.beginCompoundChange();
181
182
		/*
183
		 * The Editor checks whether a completion for a word exists before it allows for the template to be
184
		 * applied. We pickup the current text at the selection position and replace it with the first char
185
		 * of the template name for this to succeed.
186
		 * We don't need to go through this, if the editors simply support applyTemplate(Template).
187
		 */
188
		String savedText;
189
		try {
190
			savedText= fDocument.get(textSelection.getOffset(), textSelection.getLength());
191
			if (savedText.length() == 0) {
192
				String prefix= getIdentifierPart(textSelection.getOffset());
193
				if (prefix.length() > 0 && !template.getName().startsWith(prefix.toString())) {
194
					return;
195
				}
196
				if (prefix.length() > 0) {
197
					contextViewer.setSelectedRange(textSelection.getOffset() - prefix.length(), prefix.length());
198
					textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
199
				}
200
			}
201
			fDocument.replace(textSelection.getOffset(), textSelection.getLength(), template.getName().substring(0, 1));
202
		} catch (BadLocationException e) {
203
			undoManager.endCompoundChange();
204
			e.printStackTrace();
205
			return;
206
		}
207
		Position position= new Position(textSelection.getOffset() + 1, 0);
208
		Region region= new Region(textSelection.getOffset() + 1, 0);
209
		contextViewer.getSelectionProvider().setSelection(new TextSelection(textSelection.getOffset(), 1));
210
		ICompilationUnit compilationUnit= JavaCore.createCompilationUnitFrom(((FileEditorInput) fEditor.getEditorInput()).getFile());
211
212
		CompilationUnitContext context= ((CompilationUnitContextType) type).createContext(fDocument, position, compilationUnit);
213
		context.setVariable("selection", savedText); //$NON-NLS-1$
214
		if (context.getKey().length() == 0) {
215
			try {
216
				fDocument.replace(textSelection.getOffset(), 1, savedText);
217
			} catch (BadLocationException e) {
218
				e.printStackTrace();
219
				undoManager.endCompoundChange();
220
				return;
221
			}
222
		}
223
		TemplateProposal proposal= new TemplateProposal(template, context, region, null);
224
		fEditor.getSite().getPage().activate(fEditor);
225
		proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset());
226
		undoManager.endCompoundChange();
227
	}
228
229
	/**
230
	 * Invoked by the editor whenever the caret position is updated
231
	 */
232
	public void cursorPositionChanged() {
233
		Point selectedRange= fEditor.getViewer().getSelectedRange();
234
		int cursor= selectedRange.x + selectedRange.y;
235
		String partition;
236
		try {
237
			partition= TextUtilities.getContentType(fDocument, IJavaPartitions.JAVA_PARTITIONING, cursor, true);
238
		} catch (BadLocationException e) {
239
			return;
240
		}
241
		String id= fJavaId;
242
		if (partition.equals(IJavaPartitions.JAVA_DOC))
243
			id= fJavaDocId;
244
		if (!id.equals(fCurrentId)) {
245
			fCurrentId= id;
246
			contextTypeChanged(new String[] { id });
247
		}
248
	}
249
250
	/* (non-Javadoc)
251
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isValidTempalteForPosition(org.eclipse.jface.text.templates.Template, int, int)
252
	 */
253
	protected boolean isValidTemplateForPosition(Template template, int x, int y) {
254
		StyledText textWidget= fEditor.getViewer().getTextWidget();
255
		try {
256
			Point point= new Point(x,y);
257
			if (point.equals(fCachedPosition))
258
				return fCachedResult;
259
			fCachedPosition = point ;
260
			int offset= getOffset(textWidget, textWidget.toControl(x, y));
261
			if (fCachedOffset == offset)
262
				return fCachedResult;
263
			fCachedOffset= offset;
264
			if (isValidTemplate(template, offset, 0))
265
				return fCachedResult= true;
266
		} catch (BadLocationException e) {
267
		}
268
		return fCachedResult= false;
269
	}
270
271
	/**
272
	 * Get the document relative offset from the textwidget relative point
273
	 * 
274
	 * @param textWidget
275
	 * @param point
276
	 * @return offset
277
	 * @throws BadLocationException
278
	 */
279
	private int getOffset(StyledText textWidget, Point point) throws BadLocationException {
280
		ITextViewerExtension5 ext= (ITextViewerExtension5) fEditor.getViewer();
281
		try {
282
			return ext.widgetOffset2ModelOffset(textWidget.getOffsetAtLocation(point));
283
		} catch (IllegalArgumentException e) {
284
			int docLineIndex= ext.widgetLine2ModelLine(textWidget.getLineIndex(point.y));
285
			String lineDelimiter= fDocument.getLineDelimiter(docLineIndex);
286
			int delimLength= lineDelimiter == null ? 0 : lineDelimiter.length();
287
			return fDocument.getLineOffset(docLineIndex) + fDocument.getLineLength(docLineIndex) - delimLength;
288
		}
289
	}
290
291
	/**
292
	 * Check whether the template is valid for the given offset
293
	 *
294
	 * @param template
295
	 * @param offset
296
	 * @param length 
297
	 * @return true if the template is valid
298
	 */
299
	private boolean isValidTemplate(Template template, int offset, int length) {
300
		try {
301
			if (!getContextId(offset).equals(template.getContextTypeId()))
302
				return false ;
303
			if (length > 0) // length > 0 iff no selection in editor or DnD operation
304
				return true ;
305
			String identifierPart= getIdentifierPart(offset);
306
			return ((identifierPart.length() > 0 && template.getName().startsWith(identifierPart.toString())) ||
307
					(offset == fDocument.getLineInformationOfOffset(offset).getOffset()) ||
308
					(Character.isWhitespace(fDocument.getChar(offset - 1))));
309
		} catch (BadLocationException e) {
310
		}
311
		return false;
312
	}
313
314
	/**
315
	 * Get the context id for at the given offset
316
	 * 
317
	 * @param offset
318
	 * @return the context id
319
	 * @throws BadLocationException
320
	 */
321
	private String getContextId(int offset) throws BadLocationException {
322
		String partition= TextUtilities.getContentType(fDocument, IJavaPartitions.JAVA_PARTITIONING, offset, true);
323
		String id= fJavaId;
324
		if (partition.equals(IJavaPartitions.JAVA_DOC))
325
			id= fJavaDocId;
326
		return id;
327
	}
328
329
	/**
330
	 * Get the java identifier terminated at the given offset
331
	 * 
332
	 * @param offset
333
	 * @return the identifier part
334
	 * @throws BadLocationException
335
	 */
336
	private String getIdentifierPart(int offset) throws BadLocationException {
337
		int end= offset;
338
		int start= end;
339
		while (--start >= 0) {
340
			if (!Character.isJavaIdentifierPart(fDocument.getChar(start)))
341
				break;
342
		}
343
		start++;
344
		return fDocument.get(start, end - start);
345
	}
346
347
	/* (non-Javadoc)
348
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isEditorModifiable()
349
	 */
350
	protected boolean isEditorModifiable() {
351
		return fEditor.isEditorInputModifiable();
352
	}
353
}
(-)plugin.properties (-1 / +2 lines)
Lines 7-16 Link Here
7
#
7
#
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
#     Dakshinamurthy Karra - Templates support (bug 69581)
10
###############################################################################
11
###############################################################################
11
pluginName= Views
12
pluginName= Views
12
providerName= Eclipse.org
13
providerName= Eclipse.org
13
14
14
Views.PropertySheet = Properties
15
Views.PropertySheet = Properties
15
Views.ContentOutline = Outline
16
Views.ContentOutline = Outline
16
17
Views.Templates = Templates
(-)plugin.xml (+7 lines)
Lines 18-23 Link Here
18
            class="org.eclipse.ui.views.contentoutline.ContentOutline"
18
            class="org.eclipse.ui.views.contentoutline.ContentOutline"
19
            id="org.eclipse.ui.views.ContentOutline">
19
            id="org.eclipse.ui.views.ContentOutline">
20
      </view>
20
      </view>
21
      <view
22
            name="%Views.Templates"
23
            icon="$nl$/icons/full/eview16/templates.gif"
24
            category="org.eclipse.ui"
25
            class="org.eclipse.ui.views.templates.Templates"
26
            id="org.eclipse.ui.views.Templates">
27
      </view>
21
   </extension>
28
   </extension>
22
   
29
   
23
</plugin>
30
</plugin>
(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 11-17 Link Here
11
 org.eclipse.ui.internal.views.contentoutline;x-internal:=true,
11
 org.eclipse.ui.internal.views.contentoutline;x-internal:=true,
12
 org.eclipse.ui.internal.views.properties;x-internal:=true,
12
 org.eclipse.ui.internal.views.properties;x-internal:=true,
13
 org.eclipse.ui.views.contentoutline,
13
 org.eclipse.ui.views.contentoutline,
14
 org.eclipse.ui.views.properties
14
 org.eclipse.ui.views.properties,
15
 org.eclipse.ui.views.templates
15
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
16
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
16
 org.eclipse.help;bundle-version="[3.2.0,4.0.0)",
17
 org.eclipse.help;bundle-version="[3.2.0,4.0.0)",
17
 org.eclipse.ui;bundle-version="[3.2.0,4.0.0)"
18
 org.eclipse.ui;bundle-version="[3.2.0,4.0.0)"
(-)src/org/eclipse/ui/internal/views/templates/TemplatesMessages.java (+31 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.views.templates;
12
13
import org.eclipse.osgi.util.NLS;
14
15
/**
16
 * TemplatesMessages is the message class for the messages used in the templates view.
17
 *
18
 */
19
public class TemplatesMessages extends NLS {
20
	private static final String BUNDLE_NAME = "org.eclipse.ui.internal.views.templates.TemplatesMessages"; //$NON-NLS-1$
21
	
22
	// Default message for an empty templates view
23
	public static String Templates_defaultMessage;
24
	static {
25
		// initialize resource bundle
26
		NLS.initializeMessages(BUNDLE_NAME, TemplatesMessages.class);
27
	}
28
29
	private TemplatesMessages() {
30
	}
31
}
(-)src/org/eclipse/ui/internal/views/templates/TemplatesMessages.properties (+11 lines)
Added Link Here
1
###############################################################################
2
# Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
#     Dakshinamurthy Karra - initial API and implementation
10
###############################################################################
11
Templates_defaultMessage=No templates available for this editor
(-)src/org/eclipse/ui/views/templates/Templates.java (+185 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.ui.views.templates;
13
14
import org.eclipse.swt.widgets.Composite;
15
import org.eclipse.ui.IEditorPart;
16
import org.eclipse.ui.IWorkbenchPage;
17
import org.eclipse.ui.IWorkbenchPart;
18
import org.eclipse.ui.PlatformUI;
19
import org.eclipse.ui.internal.views.ViewsPlugin;
20
import org.eclipse.ui.internal.views.templates.TemplatesMessages;
21
import org.eclipse.ui.part.IContributedContentsView;
22
import org.eclipse.ui.part.IPage;
23
import org.eclipse.ui.part.MessagePage;
24
import org.eclipse.ui.part.PageBook;
25
import org.eclipse.ui.part.PageBookView;
26
27
/**
28
 * Main class for the Templates View.
29
 * <p>
30
 * This standard view has id <code>"org.eclipse.ui.views.TemplatesView"</code>.
31
 * </p>
32
 * When a <b>templates view</b> notices an editor being activated, it 
33
 * asks the editor whether it has a <b>template page</b> to include
34
 * in the templates view. This is done using <code>getAdapter</code>:
35
 * <pre>
36
 * IEditorPart editor = ...;
37
 * ITemplatePage templatePage = (ITemplatePage) editor.getAdapter(ITemplatePage.class);
38
 * if (templatePage != null) {
39
 *    // editor wishes to contribute templatePage to templates view
40
 * }
41
 * </pre>
42
 * If the editor supports a templates page, the editor instantiates
43
 * and configures the page, and returns it. This page is then added to the 
44
 * templates view (a pagebook which presents one page at a time) and 
45
 * immediately made the current page (the templates view need not be
46
 * visible). If the editor does not support a template page, the templates
47
 * view shows a special default page which makes it clear to the user
48
 * that the templates view is disengaged. When the templates view notices a
49
 * different editor being activated, it flips to the editor's corresponding
50
 * template page. When the templates view notices an editor being
51
 * closed, it may destroy the editor's corresponding content outline page.
52
 * </p>
53
 * <p>
54
 * The workbench will automatically instantiate this class when a templates
55
 * view is needed for a workbench window. This class was not intended
56
 * to be instantiated or subclassed by clients.
57
 * </p>
58
 *
59
 * @since 3.4
60
 */
61
public class Templates extends PageBookView {
62
    /**
63
     * The plugin prefix.
64
     */
65
    public static final String PREFIX = PlatformUI.PLUGIN_ID + "."; //$NON-NLS-1$
66
67
    /**
68
     * Help context id used for the content outline view
69
     * (value <code>"org.eclipse.ui.content_outline_context"</code>).
70
     */
71
    public static final String TEMPLATES_VIEW_HELP_CONTEXT_ID = PREFIX
72
            + "templates_view_context";//$NON-NLS-1$
73
74
    /**
75
     * Message to show on the default page.
76
     */
77
    private String defaultText = TemplatesMessages.Templates_defaultMessage; 
78
79
    /**
80
     * Creates a content outline view with no content outline pages.
81
     */
82
    public Templates() {
83
        super();
84
    }
85
86
    /* (non-Javadoc)
87
     * Method declared on PageBookView.
88
     */
89
    protected IPage createDefaultPage(PageBook book) {
90
        MessagePage page = new MessagePage();
91
        initPage(page);
92
        page.createControl(book);
93
        page.setMessage(defaultText);
94
        return page;
95
    }
96
97
    /**
98
     * The <code>PageBookView</code> implementation of this <code>IWorkbenchPart</code>
99
     * method creates a <code>PageBook</code> control with its default page showing.
100
     */
101
    public void createPartControl(Composite parent) {
102
        super.createPartControl(parent);
103
        PlatformUI.getWorkbench().getHelpSystem().setHelp(getPageBook(),
104
                TEMPLATES_VIEW_HELP_CONTEXT_ID);
105
    }
106
107
    /* (non-Javadoc)
108
     * Method declared on PageBookView.
109
     */
110
    protected PageRec doCreatePage(IWorkbenchPart part) {
111
        // Try to get template page.
112
        Object obj = ViewsPlugin.getAdapter(part, ITemplatesPage.class, false);
113
        if (obj instanceof ITemplatesPage) {
114
            ITemplatesPage page = (ITemplatesPage) obj;
115
			initPage(page);
116
            page.createControl(getPageBook());
117
            return new PageRec(part, page);
118
        }
119
        // There is no template page
120
        return null;
121
    }
122
123
    /* (non-Javadoc)
124
     * Method declared on PageBookView.
125
     */
126
    protected void doDestroyPage(IWorkbenchPart part, PageRec rec) {
127
        ITemplatesPage page = (ITemplatesPage) rec.page;
128
        page.dispose();
129
        rec.dispose();
130
    }
131
132
    /* (non-Javadoc)
133
     * Method declared on IAdaptable.
134
     */
135
    public Object getAdapter(Class key) {
136
        if (key == IContributedContentsView.class) {
137
			return new IContributedContentsView() {
138
                public IWorkbenchPart getContributingPart() {
139
                    return getContributingEditor();
140
                }
141
            };
142
		}
143
        return super.getAdapter(key);
144
    }
145
146
    /* (non-Javadoc)
147
     * Method declared on PageBookView.
148
     */
149
    protected IWorkbenchPart getBootstrapPart() {
150
        IWorkbenchPage page = getSite().getPage();
151
        if (page != null) {
152
			return page.getActiveEditor();
153
		}
154
155
        return null;
156
    }
157
158
    /**
159
     * Returns the editor which contributed the current 
160
     * page to this view.
161
     *
162
     * @return the editor which contributed the current page
163
     * or <code>null</code> if no editor contributed the current page
164
     */
165
    private IWorkbenchPart getContributingEditor() {
166
        return getCurrentContributingPart();
167
    }
168
169
    /* (non-Javadoc)
170
     * Method declared on PageBookView.
171
     * We only want to track editors.
172
     */
173
    protected boolean isImportant(IWorkbenchPart part) {
174
        //We only care about editors
175
        return (part instanceof IEditorPart);
176
    }
177
178
    /* (non-Javadoc)
179
     * Method declared on IViewPart.
180
     * Treat this the same as part activation.
181
     */
182
    public void partBroughtToTop(IWorkbenchPart part) {
183
        partActivated(part);
184
    }
185
}
(-)src/org/eclipse/ui/views/templates/ITemplatesPage.java (+24 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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
 *     Dakshinamurthy Karra - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.views.templates;
12
13
import org.eclipse.ui.part.IPageBookViewPage;
14
15
/**
16
 * Interface for a template page. This interface defines
17
 * the minimum requirement for pages within the templates view, namely
18
 * they must be pages (implement <code>IPageBookViewPage</code>).
19
 *
20
 * @see TemplatesView
21
 * @since 3.4
22
 */
23
public interface ITemplatesPage extends IPageBookViewPage {
24
}

Return to bug 69581