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

Collapse All | Expand All

(-)ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java (+24 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui.javaeditor;
12
package org.eclipse.jdt.internal.ui.javaeditor;
12
13
Lines 135-140 Link Here
135
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
136
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
136
import org.eclipse.ui.texteditor.TextNavigationAction;
137
import org.eclipse.ui.texteditor.TextNavigationAction;
137
import org.eclipse.ui.texteditor.TextOperationAction;
138
import org.eclipse.ui.texteditor.TextOperationAction;
139
import org.eclipse.ui.texteditor.templates.ITemplatesPage;
138
140
139
import org.eclipse.ui.editors.text.DefaultEncodingSupport;
141
import org.eclipse.ui.editors.text.DefaultEncodingSupport;
140
import org.eclipse.ui.editors.text.EditorsUI;
142
import org.eclipse.ui.editors.text.EditorsUI;
Lines 197-202 Link Here
197
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
199
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
198
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
200
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
199
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
201
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
202
import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage;
200
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
203
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
201
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
204
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
202
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
205
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
Lines 1337-1342 Link Here
1337
	protected JavaOutlinePage fOutlinePage;
1340
	protected JavaOutlinePage fOutlinePage;
1338
	/** Outliner context menu Id */
1341
	/** Outliner context menu Id */
1339
	protected String fOutlinerContextMenuId;
1342
	protected String fOutlinerContextMenuId;
1343
	/** The templates page
1344
     *
1345
     *  @since 3.4
1346
    */
1347
	private JavaTemplatesPage fTemplatesPage;
1348
	
1340
	/**
1349
	/**
1341
	 * The editor selection changed listener.
1350
	 * The editor selection changed listener.
1342
	 *
1351
	 *
Lines 1799-1804 Link Here
1799
			return fOutlinePage;
1808
			return fOutlinePage;
1800
		}
1809
		}
1801
1810
1811
		if (required.equals(ITemplatesPage.class)) {
1812
			return getTemplatesPage();
1813
		}
1814
1802
		if (IEncodingSupport.class.equals(required))
1815
		if (IEncodingSupport.class.equals(required))
1803
			return fEncodingSupport;
1816
			return fEncodingSupport;
1804
1817
Lines 1854-1859 Link Here
1854
	}
1867
	}
1855
1868
1856
	/**
1869
	/**
1870
     *  @since 3.4
1871
     */
1872
	private JavaTemplatesPage getTemplatesPage() {
1873
		if (fTemplatesPage == null) {
1874
			fTemplatesPage= new JavaTemplatesPage(this);
1875
1876
		}
1877
		return fTemplatesPage;
1878
	}
1879
1880
	/**
1857
	 * React to changed selection.
1881
	 * React to changed selection.
1858
	 *
1882
	 *
1859
	 * @since 3.0
1883
	 * @since 3.0
(-)ui/org/eclipse/jdt/internal/ui/JavaPerspectiveFactory.java (-1 / +6 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui;
12
package org.eclipse.jdt.internal.ui;
12
13
Lines 18-23 Link Here
18
import org.eclipse.ui.IPerspectiveFactory;
19
import org.eclipse.ui.IPerspectiveFactory;
19
import org.eclipse.ui.console.IConsoleConstants;
20
import org.eclipse.ui.console.IConsoleConstants;
20
import org.eclipse.ui.progress.IProgressConstants;
21
import org.eclipse.ui.progress.IProgressConstants;
22
import org.eclipse.ui.texteditor.templates.TemplatesView;
21
23
22
public class JavaPerspectiveFactory implements IPerspectiveFactory {
24
public class JavaPerspectiveFactory implements IPerspectiveFactory {
23
	
25
	
Lines 45-51 Link Here
45
		outputfolder.addPlaceholder(IPageLayout.ID_BOOKMARKS);
47
		outputfolder.addPlaceholder(IPageLayout.ID_BOOKMARKS);
46
		outputfolder.addPlaceholder(IProgressConstants.PROGRESS_VIEW_ID);
48
		outputfolder.addPlaceholder(IProgressConstants.PROGRESS_VIEW_ID);
47
		
49
		
48
		layout.addView(IPageLayout.ID_OUTLINE, IPageLayout.RIGHT, (float)0.75, editorArea);
50
		IFolderLayout outlineFolder = layout.createFolder("right", IPageLayout.RIGHT, (float)0.75, editorArea); //$NON-NLS-1$
51
		outlineFolder.addView(IPageLayout.ID_OUTLINE);
52
		outlineFolder.addView(TemplatesView.ID);
49
		
53
		
50
		layout.addActionSet(IDebugUIConstants.LAUNCH_ACTION_SET);
54
		layout.addActionSet(IDebugUIConstants.LAUNCH_ACTION_SET);
51
		layout.addActionSet(JavaUI.ID_ACTION_SET);
55
		layout.addActionSet(JavaUI.ID_ACTION_SET);
Lines 66-71 Link Here
66
70
67
		// views - standard workbench
71
		// views - standard workbench
68
		layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
72
		layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
73
		layout.addShowViewShortcut(TemplatesView.ID);
69
		layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
74
		layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
70
		layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
75
		layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
71
		layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
76
		layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
(-)ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java (+387 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.ui.preferences;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.graphics.Font;
16
import org.eclipse.swt.graphics.Image;
17
import org.eclipse.swt.graphics.Point;
18
import org.eclipse.swt.layout.GridData;
19
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.swt.widgets.Control;
21
22
import org.eclipse.jface.preference.IPreferenceStore;
23
import org.eclipse.jface.resource.JFaceResources;
24
import org.eclipse.jface.window.Window;
25
26
import org.eclipse.jface.text.BadLocationException;
27
import org.eclipse.jface.text.Document;
28
import org.eclipse.jface.text.IDocument;
29
import org.eclipse.jface.text.ITextSelection;
30
import org.eclipse.jface.text.ITextViewerExtension;
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.DocumentTemplateContext;
39
import org.eclipse.jface.text.templates.Template;
40
import org.eclipse.jface.text.templates.TemplateContextType;
41
import org.eclipse.jface.text.templates.persistence.TemplateStore;
42
43
import org.eclipse.ui.texteditor.templates.TemplatesPage;
44
45
import org.eclipse.jdt.core.ICompilationUnit;
46
47
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType;
48
import org.eclipse.jdt.internal.corext.template.java.JavaContext;
49
import org.eclipse.jdt.internal.corext.template.java.JavaContextType;
50
import org.eclipse.jdt.internal.corext.template.java.JavaDocContext;
51
import org.eclipse.jdt.internal.corext.template.java.JavaDocContextType;
52
import org.eclipse.jdt.internal.corext.template.java.SWTContextType;
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.JavaPluginImages;
60
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
61
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
62
import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
63
import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
64
import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal;
65
import org.eclipse.jdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
66
67
/**
68
 * An implementation of TemplatesPage for JavaEditor
69
 */
70
public class JavaTemplatesPage extends TemplatesPage {
71
72
	private static final String PREFERENCE_PAGE_ID= "org.eclipse.jdt.ui.preferences.JavaTemplatePreferencePage"; //$NON-NLS-1$
73
	private static final TemplateStore TEMPLATE_STORE= JavaPlugin.getDefault().getTemplateStore();
74
	private static final IPreferenceStore PREFERENCE_STORE= JavaPlugin.getDefault().getPreferenceStore();
75
	private static final ContextTypeRegistry TEMPLATE_CONTEXT_REGISTRY= JavaPlugin.getDefault().getTemplateContextRegistry();
76
	
77
	private TemplateVariableProcessor fTemplateProcessor;
78
79
	/**
80
	 * Create a new TemplatesPage for the JavaEditor
81
	 * 
82
	 * @param javaEditor
83
	 */
84
	public JavaTemplatesPage(JavaEditor javaEditor) {
85
		super(javaEditor, javaEditor.getViewer());
86
		fTemplateProcessor= new TemplateVariableProcessor();
87
		updateContextTypes(getContextTypes());
88
	}
89
90
	/* (non-Javadoc)
91
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template, org.eclipse.swt.graphics.Point)
92
	 */
93
	protected void insertTemplate(Template template, Point dropPosition) {
94
		if (!getJavaEditor().validateEditorInputState())
95
			return;
96
		ISourceViewer contextViewer= getJavaEditor().getViewer();
97
		ITextSelection textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
98
		IDocument document= getJavaEditor().getDocumentProvider().getDocument(getJavaEditor().getEditorInput());
99
		if (!isValidTemplate(document, template, textSelection.getOffset(), textSelection.getLength()))
100
			return;
101
		beginCompoundChange(contextViewer);
102
		/*
103
		 * The Editor checks whether a completion for a word exists before it allows for the template to be
104
		 * applied. We pickup the current text at the selection position and replace it with the first char
105
		 * of the template name for this to succeed.
106
		 * Another advantage by this method is that the template replaces the selected text provided the
107
		 * selection by itself is not used in the template pattern.
108
		 */
109
		String savedText;
110
		try {
111
			savedText= document.get(textSelection.getOffset(), textSelection.getLength());
112
			if (savedText.length() == 0) {
113
				String prefix= getIdentifierPart(document, template, textSelection.getOffset(), textSelection.getLength());
114
				if (prefix.length() > 0 && !template.getName().startsWith(prefix.toString())) {
115
					return;
116
				}
117
				if (prefix.length() > 0) {
118
					contextViewer.setSelectedRange(textSelection.getOffset() - prefix.length(), prefix.length());
119
					textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
120
				}
121
			}
122
			document.replace(textSelection.getOffset(), textSelection.getLength(), template.getName().substring(0, 1));
123
		} catch (BadLocationException e) {
124
			endCompoundChange(contextViewer);
125
			return;
126
		}
127
		Position position= new Position(textSelection.getOffset() + 1, 0);
128
		Region region= new Region(textSelection.getOffset() + 1, 0);
129
		contextViewer.getSelectionProvider().setSelection(new TextSelection(textSelection.getOffset(), 1));
130
		ICompilationUnit compilationUnit= (ICompilationUnit) EditorUtility.getEditorInputJavaElement(getJavaEditor(), true);
131
	
132
		TemplateContextType type= getContextTypeRegistry().getContextType(template.getContextTypeId());
133
		DocumentTemplateContext context= ((CompilationUnitContextType) type).createContext(document, position, compilationUnit);
134
		context.setVariable("selection", savedText); //$NON-NLS-1$
135
		if (context.getKey().length() == 0) {
136
			try {
137
				document.replace(textSelection.getOffset(), 1, savedText);
138
			} catch (BadLocationException e) {
139
				endCompoundChange(contextViewer);
140
				return;
141
			}
142
		}
143
		TemplateProposal proposal= new TemplateProposal(template, context, region, null);
144
		getJavaEditor().getSite().getPage().activate(getJavaEditor());
145
		proposal.apply(getJavaEditor().getViewer(), ' ', 0, region.getOffset());
146
		endCompoundChange(contextViewer);
147
	}
148
149
	/* (non-Javadoc)
150
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getContextTypeRegistry()
151
	 */
152
	protected ContextTypeRegistry getContextTypeRegistry() {
153
		return TEMPLATE_CONTEXT_REGISTRY;
154
	}
155
156
	/* (non-Javadoc)
157
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getTemplatePreferenceStore()
158
	 */
159
	protected IPreferenceStore getTemplatePreferenceStore() {
160
		return PREFERENCE_STORE;
161
	}
162
163
	/* (non-Javadoc)
164
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getTemplateStore()
165
	 */
166
	protected TemplateStore getTemplateStore() {
167
		return TEMPLATE_STORE;
168
	}
169
170
	/* (non-Javadoc)
171
	 * @see org.eclipse.ui.texteditor.templates.TextEditorTemplatesPage#isValidTemplate(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.templates.Template, int, int)
172
	 */
173
	protected boolean isValidTemplate(IDocument document, Template template, int offset, int length) {
174
		try {
175
			String[] contextIds= getContextIds(document, offset);
176
			for (int i= 0; i < contextIds.length; i++) {
177
				if (contextIds[i].equals(template.getContextTypeId())) {
178
					DocumentTemplateContext context= getContext(document, template, offset, length);
179
					return context.canEvaluate(template) || isTemplateAllowed(context, template);
180
				}
181
			}
182
		} catch (BadLocationException e) {
183
		}
184
		return false;
185
	}
186
187
	/* (non-Javadoc)
188
	 * @see org.eclipse.ui.texteditor.templates.TextEditorTemplatesPage#createPatternViewer(org.eclipse.swt.widgets.Composite)
189
	 */
190
	protected SourceViewer createPatternViewer(Composite parent) {
191
		IDocument document= new Document();
192
		JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools();
193
		tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
194
		IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
195
		JavaSourceViewer viewer= new JavaSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
196
		SimpleJavaSourceViewerConfiguration configuration= new SimpleJavaSourceViewerConfiguration(tools.getColorManager(), store, null, IJavaPartitions.JAVA_PARTITIONING, false);
197
		viewer.configure(configuration);
198
		viewer.setEditable(false);
199
		viewer.setDocument(document);
200
	
201
		Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
202
		viewer.getTextWidget().setFont(font);
203
		new JavaSourcePreviewerUpdater(viewer, configuration, store);
204
	
205
		Control control= viewer.getControl();
206
		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
207
		control.setLayoutData(data);
208
	
209
		viewer.setEditable(false);
210
		return viewer;
211
	}
212
213
	/* (non-Javadoc)
214
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getImageForTemplate(org.eclipse.jface.text.templates.Template)
215
	 */
216
	protected Image getImageForTemplate(Template template) {
217
		if (template.getContextTypeId().equals(SWTContextType.ID))
218
			return JavaPluginImages.get(JavaPluginImages.IMG_OBJS_SWT_TEMPLATE);
219
		return JavaPluginImages.get(JavaPluginImages.IMG_OBJS_TEMPLATE);
220
	}
221
222
	/* (non-Javadoc)
223
	 * @see org.eclipse.ui.texteditor.templates.TextEditorTemplatesPage#editTemplate(org.eclipse.jface.text.templates.Template, boolean, boolean)
224
	 */
225
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
226
		EditTemplateDialog dialog= new EditTemplateDialog(getShell(), template, edit, isNameModifiable, getContextTypeRegistry());
227
		if (dialog.open() == Window.OK) {
228
			return dialog.getTemplate();
229
		}
230
		return null;
231
	}
232
233
	/* (non-Javadoc)
234
	 * @see org.eclipse.ui.texteditor.templates.TextEditorTemplatesPage#getContextTypes()
235
	 */
236
	protected String[] getContextTypes() {
237
		Point selectedRange= getJavaEditor().getViewer().getSelectedRange();
238
		int offset= selectedRange.x + selectedRange.y;
239
		try {
240
			IDocument document= getJavaEditor().getDocumentProvider().getDocument(getJavaEditor().getEditorInput());
241
			return getContextIds(document, offset);
242
		} catch (BadLocationException e) {
243
			return new String[0];
244
		}
245
	}
246
247
	/* (non-Javadoc)
248
	 * @see org.eclipse.ui.texteditor.templates.TextEditorTemplatesPage#updatePatternViewer(org.eclipse.jface.text.templates.Template)
249
	 */
250
	protected void updatePatternViewer(Template template) {
251
		if (template == null) {
252
			getPatternViewer().getDocument().set(""); //$NON-NLS-1$
253
			return ;
254
		}
255
		String contextId= template.getContextTypeId();
256
		TemplateContextType type= getContextTypeRegistry().getContextType(contextId);
257
		fTemplateProcessor.setContextType(type);
258
	
259
		IDocument doc= getPatternViewer().getDocument();
260
	
261
		String start= null;
262
		if ("javadoc".equals(contextId)) { //$NON-NLS-1$
263
			start= "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
264
		} else
265
			start= ""; //$NON-NLS-1$
266
	
267
		doc.set(start + template.getPattern());
268
		int startLen= start.length();
269
		getPatternViewer().setDocument(doc, startLen, doc.getLength() - startLen);
270
	}
271
272
	/* (non-Javadoc)
273
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId()
274
	 */
275
	protected String getPreferencePageId() {
276
		return PREFERENCE_PAGE_ID;
277
	}
278
279
	/**
280
	 * Helper function to return the JavaEditor
281
	 * 
282
	 * @return the editor
283
	 */
284
	private JavaEditor getJavaEditor() {
285
		return (JavaEditor)getEditor() ;
286
	}
287
	
288
	/**
289
	 * Undomanager - end compound change
290
	 * @param viewer
291
	 */
292
	private void endCompoundChange(ISourceViewer viewer) {
293
		if (viewer instanceof ITextViewerExtension)
294
			((ITextViewerExtension) viewer).getRewriteTarget().endCompoundChange();
295
	}
296
297
	/**
298
	 * Undomanager - begin a compound change
299
	 * @param viewer
300
	 */
301
	private void beginCompoundChange(ISourceViewer viewer) {
302
		if (viewer instanceof ITextViewerExtension)
303
			((ITextViewerExtension) viewer).getRewriteTarget().beginCompoundChange();
304
	}
305
306
	/**
307
	 * Check whether the template is allowed eventhough the context can't evaluate it. This is needed because
308
	 * the Dropping of a template is more lenient than ctl-space invoked code assist.
309
	 * 
310
	 * @param context
311
	 * @param template
312
	 * @return true if the template is allowed
313
	 */
314
	private boolean isTemplateAllowed(DocumentTemplateContext context, Template template) {
315
		int offset;
316
		try {
317
			if (template.getContextTypeId().equals(JavaDocContextType.ID)) {
318
				return (offset= context.getCompletionOffset()) > 0 && Character.isWhitespace(context.getDocument().getChar(offset - 1));
319
			} else {
320
				return ((offset= context.getCompletionOffset()) > 0 && !isTemplateNamePart(context.getDocument().getChar(offset - 1)));
321
			}
322
		} catch (BadLocationException e) {
323
		}
324
		return false;
325
	}
326
327
	/**
328
	 * Checks whether the character is a valid character in Java template names
329
	 * 
330
	 * @param ch
331
	 * @return true or false
332
	 */
333
	private boolean isTemplateNamePart(char ch) {
334
		return !Character.isWhitespace(ch) && ch != '(' && ch != ')' && ch != '{' && ch != '}' && ch != ';';
335
	}
336
337
	/**
338
	 * Get context
339
	 * 
340
	 * @param document
341
	 * @param template
342
	 * @param offset
343
	 * @param length
344
	 * @return the context
345
	 */
346
	private DocumentTemplateContext getContext(IDocument document, Template template, final int offset, int length) {
347
		DocumentTemplateContext context;
348
		if (template.getContextTypeId().equals(JavaDocContextType.ID)) {
349
			context= new JavaDocContext(getContextTypeRegistry().getContextType(template.getContextTypeId()), document, new Position(offset, length), (ICompilationUnit) EditorUtility
350
					.getEditorInputJavaElement(getJavaEditor(), true));
351
		} else {
352
			context= new JavaContext(getContextTypeRegistry().getContextType(template.getContextTypeId()), document, new Position(offset, length), (ICompilationUnit) EditorUtility.getEditorInputJavaElement(
353
					getJavaEditor(), true));
354
		}
355
		return context;
356
	}
357
358
	/**
359
	 * Get the active contexts for the given position in the document
360
	 * 
361
	 * @param document
362
	 * @param offset
363
	 * @return an array of valid context id
364
	 * @throws BadLocationException
365
	 */
366
	private String[] getContextIds(IDocument document, int offset) throws BadLocationException {
367
		String partition= TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, offset, true);
368
		String[] ids= new String[] { JavaContextType.ID, SWTContextType.ID };
369
		if (partition.equals(IJavaPartitions.JAVA_DOC))
370
			ids= new String[] { JavaDocContextType.ID };
371
		return ids;
372
	}
373
374
	/**
375
	 * Get the java identifier terminated at the given offset
376
	 * 
377
	 * @param document 
378
	 * @param template 
379
	 * @param offset
380
	 * @param length 
381
	 * @return the identifier part
382
	 * @throws BadLocationException
383
	 */
384
	private String getIdentifierPart(IDocument document, Template template, int offset, int length) throws BadLocationException {
385
		return getContext(document, template, offset, length).getKey();
386
	}
387
}
(-)plugin.xml (+11 lines)
Lines 1102-1105 Link Here
1102
        </action>
1102
        </action>
1103
      </actionSet>
1103
      </actionSet>
1104
   </extension>
1104
   </extension>
1105
   <extension
1106
         point="org.eclipse.ui.views">
1107
      <view
1108
            name="%Views.Templates"
1109
            icon="$nl$/icons/full/eview16/templates.gif"
1110
            category="org.eclipse.ui"
1111
            class="org.eclipse.ui.texteditor.templates.TemplatesView"
1112
            id="org.eclipse.ui.texteditor.templates.view.TemplatesView">
1113
      </view>
1114
   </extension>
1115
1105
</plugin>
1116
</plugin>
(-)plugin.properties (+3 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
###############################################################################
11
###############################################################################
11
pluginName= Text Editor Framework
12
pluginName= Text Editor Framework
12
providerName= Eclipse.org
13
providerName= Eclipse.org
Lines 169-171 Link Here
169
170
170
SpellingEngine= Spelling Engine
171
SpellingEngine= Spelling Engine
171
172
173
Views.Templates = Templates
174
(-)src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java (+6 lines)
Lines 9-14 Link Here
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Genady Beryozkin, me@genady.org - https://bugs.eclipse.org/bugs/show_bug.cgi?id=11668
10
 *     Genady Beryozkin, me@genady.org - https://bugs.eclipse.org/bugs/show_bug.cgi?id=11668
11
 *     Benjamin Muskalla <b.muskalla@gmx.net> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=41573
11
 *     Benjamin Muskalla <b.muskalla@gmx.net> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=41573
12
 *     Dakshinamurthy Karra (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
12
 *******************************************************************************/
13
 *******************************************************************************/
13
14
14
package org.eclipse.ui.texteditor;
15
package org.eclipse.ui.texteditor;
Lines 364-367 Link Here
364
	 * @since 3.3
365
	 * @since 3.3
365
	 */
366
	 */
366
	String SHOW_INFORMATION_ACTION=PREFIX + "show_information" + ACTION_POSTFIX; //$NON-NLS-1$
367
	String SHOW_INFORMATION_ACTION=PREFIX + "show_information" + ACTION_POSTFIX; //$NON-NLS-1$
368
369
	/**
370
	 * Help context id used for the templates view
371
	 */
372
	public static final String TEMPLATES_VIEW_HELP_CONTEXT_ID =PREFIX + "templates_view_context";//$NON-NLS-1$
367
}
373
}
(-)META-INF/MANIFEST.MF (+1 lines)
Lines 14-19 Link Here
14
 org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer;x-internal:=true,
14
 org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer;x-internal:=true,
15
 org.eclipse.ui.internal.texteditor.rulers;x-internal:=true,
15
 org.eclipse.ui.internal.texteditor.rulers;x-internal:=true,
16
 org.eclipse.ui.internal.texteditor.spelling;x-internal:=true,
16
 org.eclipse.ui.internal.texteditor.spelling;x-internal:=true,
17
 org.eclipse.ui.internal.texteditor.templates,
17
 org.eclipse.ui.texteditor,
18
 org.eclipse.ui.texteditor,
18
 org.eclipse.ui.texteditor.link,
19
 org.eclipse.ui.texteditor.link,
19
 org.eclipse.ui.texteditor.quickdiff,
20
 org.eclipse.ui.texteditor.quickdiff,
(-)src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java (+37 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.ui.texteditor.templates;
12
package org.eclipse.ui.texteditor.templates;
12
13
Lines 90-95 Link Here
90
	public static String TemplatePreferencePage_column_autoinsert;
91
	public static String TemplatePreferencePage_column_autoinsert;
91
	public static String EditTemplateDialog_autoinsert;
92
	public static String EditTemplateDialog_autoinsert;
92
93
94
	// TemplatesView
95
	public static String TemplatesPage_column_context;
96
	public static String TemplatesPage_column_description;
97
	public static String TemplatesPage_column_name;
98
	public static String TemplatesPage_insert;
99
	public static String TemplatesPage_edit;
100
	public static String TemplatesPage_copy;
101
	public static String TemplatesPage_paste;
102
	public static String TemplatesPage_preference_page;
103
	public static String TemplatesPage_link_to_editor;
104
	public static String TemplatesPage_collapse_all;
105
	public static String TemplatesPage_new;
106
	public static String TemplatesPage_remove;
107
	public static String TemplatesPage_insert_tooltip;
108
	public static String TemplatesPage_edit_tooltip;
109
	public static String TemplatesPage_preference_page_tooltip;
110
	public static String TemplatesPage_link_to_editor_tooltip;
111
	public static String TemplatesPage_collapse_all_tooltip;
112
	public static String TemplatesPage_new_tooltip;
113
	public static String TemplatesPage_remove_tooltip;
114
	public static String TemplatesPage_preview;
115
	public static String TemplatesPage_question_create_new_message;
116
	public static String TemplatesPage_question_create_new_title;
117
	public static String TemplatesPage_save_error_message;
118
	public static String TemplatesPage_snippet;
119
	public static String TemplatesPage_paste_description;
120
	public static String TemplatesPage_remove_message_single;
121
	public static String TemplatesPage_remove_message_multi;
122
	public static String TemplatesPage_remove_title_single;
123
	public static String TemplatesPage_remove_title_multi;
124
125
	/**
126
	 * Default message for an empty templates view 
127
	 */
128
	public static String Templates_defaultMessage;
129
93
	static {
130
	static {
94
		NLS.initializeMessages(BUNDLE_NAME, TextEditorTemplateMessages.class);
131
		NLS.initializeMessages(BUNDLE_NAME, TextEditorTemplateMessages.class);
95
	}
132
	}
(-)src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties (+35 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
###############################################################################
11
###############################################################################
11
12
12
# preference page
13
# preference page
Lines 93-95 Link Here
93
GlobalVariables_variable_description_selectedWord= The selected word
94
GlobalVariables_variable_description_selectedWord= The selected word
94
GlobalVariables_variable_description_selectedLines= The selected lines
95
GlobalVariables_variable_description_selectedLines= The selected lines
95
96
97
# templates page (view)
98
TemplatesPage_collapse_all=Collapse All
99
TemplatesPage_column_context=Context
100
TemplatesPage_column_description=Description
101
TemplatesPage_save_error_message=Error Saving the Templates
102
TemplatesPage_column_name=Name
103
TemplatesPage_edit=&Edit...
104
TemplatesPage_insert=&Insert...
105
TemplatesPage_copy=Copy
106
TemplatesPage_paste=Paste
107
TemplatesPage_preference_page=&Preferences...
108
TemplatesPage_paste_description=Pasted from editor
109
TemplatesPage_link_to_editor=Link with Editor
110
TemplatesPage_new=&New...
111
TemplatesPage_preview=Preview
112
TemplatesPage_snippet=snippet
113
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.
114
TemplatesPage_remove_title_single=Removing Template
115
TemplatesPage_remove_title_multi=Removing Templates
116
TemplatesPage_remove_message_single=Are you sure you want to remove the selected template?
117
TemplatesPage_remove_message_multi=Are you sure you want to remove {0} selected templates?
118
TemplatesPage_question_create_new_title= Edit Template
119
TemplatesPage_remove=&Remove
120
TemplatesPage_insert_tooltip=Insert into Editor
121
TemplatesPage_edit_tooltip=Edit the Template
122
TemplatesPage_preference_page_tooltip=Show Preference Page
123
TemplatesPage_link_to_editor_tooltip=Link with Editor
124
TemplatesPage_collapse_all_tooltip=Collapse All
125
TemplatesPage_new_tooltip=Create a New Template
126
TemplatesPage_remove_tooltip=Remove the Template
127
128
# templates view
129
Templates_defaultMessage=Templates are not available.
130
(-)src/org/eclipse/ui/texteditor/templates/TemplatesPage.java (+1609 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
12
package org.eclipse.ui.texteditor.templates;
13
14
import java.io.IOException;
15
import java.util.ArrayList;
16
import java.util.Arrays;
17
import java.util.Iterator;
18
import java.util.List;
19
20
import org.eclipse.jface.action.Action;
21
import org.eclipse.jface.action.IAction;
22
import org.eclipse.jface.action.IMenuListener;
23
import org.eclipse.jface.action.IMenuManager;
24
import org.eclipse.jface.action.IToolBarManager;
25
import org.eclipse.jface.action.MenuManager;
26
import org.eclipse.jface.action.Separator;
27
import org.eclipse.jface.dialogs.MessageDialog;
28
import org.eclipse.jface.layout.TreeColumnLayout;
29
import org.eclipse.jface.preference.IPreferenceStore;
30
import org.eclipse.jface.text.BadLocationException;
31
import org.eclipse.jface.text.Document;
32
import org.eclipse.jface.text.IDocument;
33
import org.eclipse.jface.text.IRegion;
34
import org.eclipse.jface.text.ITextViewerExtension5;
35
import org.eclipse.jface.text.source.ISourceViewer;
36
import org.eclipse.jface.text.source.SourceViewer;
37
import org.eclipse.jface.text.source.SourceViewerConfiguration;
38
import org.eclipse.jface.text.templates.ContextTypeRegistry;
39
import org.eclipse.jface.text.templates.Template;
40
import org.eclipse.jface.text.templates.TemplateContextType;
41
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
42
import org.eclipse.jface.text.templates.persistence.TemplateStore;
43
import org.eclipse.jface.util.IPropertyChangeListener;
44
import org.eclipse.jface.util.PropertyChangeEvent;
45
import org.eclipse.jface.viewers.AbstractTreeViewer;
46
import org.eclipse.jface.viewers.ColumnPixelData;
47
import org.eclipse.jface.viewers.DoubleClickEvent;
48
import org.eclipse.jface.viewers.IDoubleClickListener;
49
import org.eclipse.jface.viewers.IPostSelectionProvider;
50
import org.eclipse.jface.viewers.ISelectionChangedListener;
51
import org.eclipse.jface.viewers.ISelectionProvider;
52
import org.eclipse.jface.viewers.IStructuredSelection;
53
import org.eclipse.jface.viewers.ITableLabelProvider;
54
import org.eclipse.jface.viewers.ITreeContentProvider;
55
import org.eclipse.jface.viewers.LabelProvider;
56
import org.eclipse.jface.viewers.SelectionChangedEvent;
57
import org.eclipse.jface.viewers.StructuredSelection;
58
import org.eclipse.jface.viewers.TreeViewer;
59
import org.eclipse.jface.viewers.Viewer;
60
import org.eclipse.jface.viewers.ViewerComparator;
61
import org.eclipse.jface.window.Window;
62
import org.eclipse.swt.SWT;
63
import org.eclipse.swt.custom.CLabel;
64
import org.eclipse.swt.custom.SashForm;
65
import org.eclipse.swt.custom.StyledText;
66
import org.eclipse.swt.custom.ViewForm;
67
import org.eclipse.swt.dnd.Clipboard;
68
import org.eclipse.swt.dnd.DND;
69
import org.eclipse.swt.dnd.DragSourceAdapter;
70
import org.eclipse.swt.dnd.DragSourceEvent;
71
import org.eclipse.swt.dnd.DropTargetAdapter;
72
import org.eclipse.swt.dnd.DropTargetEvent;
73
import org.eclipse.swt.dnd.TextTransfer;
74
import org.eclipse.swt.dnd.Transfer;
75
import org.eclipse.swt.events.ControlEvent;
76
import org.eclipse.swt.events.ControlListener;
77
import org.eclipse.swt.graphics.Image;
78
import org.eclipse.swt.graphics.Point;
79
import org.eclipse.swt.layout.GridData;
80
import org.eclipse.swt.widgets.Composite;
81
import org.eclipse.swt.widgets.Control;
82
import org.eclipse.swt.widgets.Event;
83
import org.eclipse.swt.widgets.Menu;
84
import org.eclipse.swt.widgets.Shell;
85
import org.eclipse.swt.widgets.Tree;
86
import org.eclipse.swt.widgets.TreeColumn;
87
import org.eclipse.swt.widgets.TreeItem;
88
import org.eclipse.ui.IActionBars;
89
import org.eclipse.ui.IWorkbenchActionConstants;
90
import org.eclipse.ui.actions.ActionFactory;
91
import org.eclipse.ui.dialogs.PreferencesUtil;
92
import org.eclipse.ui.dnd.IDragAndDropService;
93
import org.eclipse.ui.internal.texteditor.NLSUtility;
94
import org.eclipse.ui.internal.texteditor.PixelConverter;
95
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
96
import org.eclipse.ui.internal.texteditor.templates.TemplateTransfer;
97
import org.eclipse.ui.internal.texteditor.templates.TemplatesPageImages;
98
import org.eclipse.ui.part.Page;
99
import org.eclipse.ui.texteditor.AbstractTextEditor;
100
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
101
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
102
import org.eclipse.ui.texteditor.templates.TemplatePreferencePage.EditTemplateDialog;
103
104
import com.ibm.icu.text.Collator;
105
106
/**
107
 * An abstract base class for template pages.
108
 * <p>
109
 * Clients who are defining an editor may elect to provide a corresponding
110
 * templates page. This templates page will be presented to the user via the
111
 * Templates View (the user decides whether their workbench window contains this
112
 * view) whenever that editor is active. This class should be subclassed by
113
 * clients.
114
 * </p>
115
 * <p>
116
 * Internally, a TemplatesPage uses the template store to display different
117
 * categories. A link to editor mode on the templates page allows to filtering
118
 * of the categories to only that are supported in this context.
119
 * </p>
120
 * 
121
 * @since 3.4
122
 */
123
public abstract class TemplatesPage extends Page implements ITemplatesPage {
124
125
	/**
126
	 * Sashform size
127
	 */
128
	private static final String SASH_SIZE_PREF_ID = TextEditorPlugin.PLUGIN_ID
129
			+ ".templates.templatesPage.sashSize"; //$NON-NLS-1$
130
	/**
131
	 * Tree columns widths
132
	 */
133
	private static final String COLUMN_NAME_WIDTH_PREF_ID = TextEditorPlugin.PLUGIN_ID
134
			+ ".templates.templatesPage.nameWidth"; //$NON-NLS-1$
135
	private static final String COLUMN_DESCRIPTION_WIDTH_PREF_ID = TextEditorPlugin.PLUGIN_ID
136
			+ ".templates.templatesPage.descriptionWidth"; //$NON-NLS-1$
137
	/**
138
	 * Link to editor action setting
139
	 */
140
	private static final String LINK_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
141
			+ ".templates.templatesPage.linkAction"; //$NON-NLS-1$
142
143
	/**
144
	 * Context expand/collapse setting prefix
145
	 */
146
	private static final String CONTEXT_COLLAPSE_PREF_ID = TextEditorPlugin.PLUGIN_ID
147
			+ "templates.templatesPage.context.expand."; //$NON-NLS-1$
148
149
	/**
150
	 * The ID for the popup menu for this templates page
151
	 */
152
	private static final String POPUP_MENU_ID = "org.eclipse.ui.texteditor.templates.PopupMenu"; //$NON-NLS-1$
153
154
	/**
155
	 * Default image for a template
156
	 */
157
	private static final Image DEFAULT_TEMPLATE_IMAGE = TemplatesPageImages
158
			.getImage(TemplatesPageImages.IMG_OBJ_TEMPLATE);
159
	/**
160
	 * Image for the context
161
	 */
162
	private static final Image CONTEXT_IMAGE = TemplatesPageImages
163
			.getImage(TemplatesPageImages.IMG_OBJ_CONTEXT);
164
165
	/**
166
	 * A post selection changed listener for the editor. Depending on the caret
167
	 * position updates the templates
168
	 */
169
	private final class SelectionChangedListener implements ISelectionChangedListener {
170
		/*
171
		 * (non-Javadoc)
172
		 * 
173
		 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
174
		 */
175
		public void selectionChanged(SelectionChangedEvent event) {
176
			String[] contextTypes = getContextTypes();
177
			if (needUpdate(contextTypes)) {
178
				fCurrentContextTypes = contextTypes;
179
				updateContextTypes(fCurrentContextTypes);
180
				return;
181
			}
182
		}
183
184
		/**
185
		 * Check whether an update of the TemplatesPage is needed
186
		 * 
187
		 * @param contextTypes
188
		 * @return true if update is needed
189
		 */
190
		private boolean needUpdate(String[] contextTypes) {
191
			return fCurrentContextTypes == null
192
					|| fCurrentContextTypes.length != contextTypes.length
193
					|| contextTypeChanged(contextTypes);
194
		}
195
196
		/**
197
		 * Check whether there is any change in the context types needed
198
		 * 
199
		 * @param contextTypes
200
		 * @return true if any of the context types changed
201
		 */
202
		private boolean contextTypeChanged(String[] contextTypes) {
203
			for (int i = 0; i < contextTypes.length; i++) {
204
				if (!contextTypes[i].equals(fCurrentContextTypes[i]))
205
					return false;
206
			}
207
			return true;
208
		}
209
	}
210
211
	/**
212
	 * Drop support for the editor linked to this page. When a user drops a
213
	 * template into the active editor, the template is applied at the drop
214
	 * position.
215
	 */
216
	private final class EditorDropTarget extends DropTargetAdapter {
217
		/*
218
		 * (non-Javadoc)
219
		 * 
220
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
221
		 */
222
		public void dragEnter(DropTargetEvent event) {
223
			event.detail = DND.DROP_COPY;
224
		}
225
226
		/*
227
		 * (non-Javadoc)
228
		 * 
229
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
230
		 */
231
		public void dragOperationChanged(DropTargetEvent event) {
232
			event.detail = DND.DROP_COPY;
233
		}
234
235
		/*
236
		 * (non-Javadoc)
237
		 * 
238
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
239
		 */
240
		public void dragOver(DropTargetEvent event) {
241
			event.feedback |= DND.FEEDBACK_SCROLL;
242
			event.detail = DND.DROP_NONE;
243
			TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
244
			if (fEditor.isEditorInputModifiable()
245
					&& selectedTemplates.length == 1
246
					&& isValidTemplateForPosition(selectedTemplates[0].getTemplate(), new Point(
247
							event.x, event.y)))
248
				event.detail = DND.DROP_COPY;
249
		}
250
251
		/*
252
		 * (non-Javadoc)
253
		 * 
254
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
255
		 */
256
		public void drop(DropTargetEvent event) {
257
			TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
258
			insertTemplate(selectedTemplates[0].getTemplate(), new Point(event.x, event.y));
259
			// The highlight of the item is removed once the drop happens -
260
			// restore it
261
			fTreeViewer.setSelection(new StructuredSelection(selectedTemplates), true);
262
		}
263
	}
264
265
	/**
266
	 * Comparator for the viewer. Sorts the templates by name and then
267
	 * description and context types by names.
268
	 */
269
	private static final class TemplateViewerComparator extends ViewerComparator {
270
		/*
271
		 * (non-Javadoc)
272
		 * 
273
		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
274
		 *      java.lang.Object, java.lang.Object)
275
		 */
276
		public int compare(Viewer viewer, Object object1, Object object2) {
277
			if ((object1 instanceof TemplatePersistenceData)
278
					&& (object2 instanceof TemplatePersistenceData)) {
279
				Template left = ((TemplatePersistenceData) object1).getTemplate();
280
				Template right = ((TemplatePersistenceData) object2).getTemplate();
281
				int result = Collator.getInstance().compare(left.getName(), right.getName());
282
				if (result != 0)
283
					return result;
284
				return Collator.getInstance()
285
						.compare(left.getDescription(), right.getDescription());
286
			}
287
			if ((object1 instanceof TemplateContextType)
288
					&& (object2 instanceof TemplateContextType)) {
289
				return Collator.getInstance().compare(((TemplateContextType) object1).getName(),
290
						((TemplateContextType) object1).getName());
291
			}
292
			return super.compare(viewer, object1, object2);
293
		}
294
295
		/*
296
		 * (non-Javadoc)
297
		 * 
298
		 * @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object,
299
		 *      java.lang.String)
300
		 */
301
		public boolean isSorterProperty(Object element, String property) {
302
			return false;
303
		}
304
	}
305
306
	/**
307
	 * Label provider for templates.
308
	 */
309
	private final class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider {
310
		/*
311
		 * (non-Javadoc)
312
		 * 
313
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
314
		 *      int)
315
		 */
316
		public Image getColumnImage(Object element, int columnIndex) {
317
			if (columnIndex != 0)
318
				return null;
319
			if (element instanceof TemplateContextType)
320
				return CONTEXT_IMAGE;
321
			return getImageForTemplate(((TemplatePersistenceData) element).getTemplate());
322
		}
323
324
		/*
325
		 * (non-Javadoc)
326
		 * 
327
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
328
		 *      int)
329
		 */
330
		public String getColumnText(Object element, int columnIndex) {
331
			if (element instanceof TemplatePersistenceData)
332
				return getTemplateColumnText((TemplatePersistenceData) element, columnIndex);
333
			return getContextColumnText((TemplateContextType) element, columnIndex);
334
		}
335
336
		private String getTemplateColumnText(TemplatePersistenceData data, int columnIndex) {
337
			switch (columnIndex) {
338
			case 0:
339
				return data.getTemplate().getName();
340
			case 1:
341
				return data.getTemplate().getDescription();
342
			default:
343
				return ""; //$NON-NLS-1$
344
			}
345
		}
346
347
		private String getContextColumnText(TemplateContextType contextType, int columnIndex) {
348
			switch (columnIndex) {
349
			case 0:
350
				return contextType.getName();
351
			default:
352
				return ""; //$NON-NLS-1$
353
			}
354
		}
355
	}
356
357
	/**
358
	 * Content provider for templates. Provides all the enabled templates
359
	 * defined for this editor.
360
	 */
361
	private final class TemplatesContentProvider implements ITreeContentProvider {
362
		/*
363
		 * (non-Javadoc)
364
		 * 
365
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
366
		 */
367
		public Object[] getChildren(Object parentElement) {
368
			if (parentElement instanceof TemplatePersistenceData)
369
				return new Object[0];
370
			else if (parentElement instanceof TemplateContextType) {
371
				TemplateContextType contextType = (TemplateContextType) parentElement;
372
				return getTemplates(contextType.getId());
373
			}
374
			return null;
375
		}
376
377
		private TemplatePersistenceData[] getTemplates(String contextId) {
378
			List templateList = new ArrayList();
379
			TemplatePersistenceData[] datas = getTemplateStore().getTemplateData(false);
380
			for (int i = 0; i < datas.length; i++) {
381
				if (datas[i].isEnabled()
382
						&& datas[i].getTemplate().getContextTypeId().equals(contextId))
383
					templateList.add(datas[i]);
384
			}
385
			return (TemplatePersistenceData[]) templateList
386
					.toArray(new TemplatePersistenceData[templateList.size()]);
387
		}
388
389
		/*
390
		 * (non-Javadoc)
391
		 * 
392
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
393
		 */
394
		public Object getParent(Object element) {
395
			if (element instanceof TemplatePersistenceData) {
396
				TemplatePersistenceData templateData = (TemplatePersistenceData) element;
397
				return getContextTypeRegistry().getContextType(
398
						templateData.getTemplate().getContextTypeId());
399
			}
400
			return null;
401
		}
402
403
		/*
404
		 * (non-Javadoc)
405
		 * 
406
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
407
		 */
408
		public boolean hasChildren(Object element) {
409
			if (element instanceof TemplateContextType)
410
				return true;
411
			return false;
412
		}
413
414
		/*
415
		 * (non-Javadoc)
416
		 * 
417
		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
418
		 */
419
		public Object[] getElements(Object inputElement) {
420
			List contextTypes = new ArrayList();
421
422
			for (Iterator iterator = getContextTypeRegistry().contextTypes(); iterator.hasNext();) {
423
				TemplateContextType contextType = (TemplateContextType) iterator.next();
424
				if (!fLinkWithEditorAction.isChecked() || isActiveContext(contextType))
425
					contextTypes.add(contextType);
426
			}
427
			return contextTypes.toArray(new TemplateContextType[contextTypes.size()]);
428
		}
429
430
		private boolean isActiveContext(TemplateContextType contextType) {
431
			return fActiveTypes == null || fActiveTypes.contains(contextType.getId());
432
		}
433
434
		/*
435
		 * (non-Javadoc)
436
		 * 
437
		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
438
		 */
439
		public void dispose() {
440
		}
441
442
		/*
443
		 * (non-Javadoc)
444
		 * 
445
		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
446
		 *      java.lang.Object, java.lang.Object)
447
		 */
448
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
449
		}
450
	}
451
452
	/* The editor */
453
	private final AbstractTextEditor fEditor;
454
	/* The SourceViewer attached to this editor */
455
	private final ISourceViewer fViewer;
456
457
	/* Listener to monitor changes to template store */
458
	private IPropertyChangeListener fTemplateChangeListener;
459
460
	/* Control for this pagebook view */
461
	private SashForm fControl;
462
463
	/* Actions */
464
	private Action fInsertAction;
465
	private Action fAddAction;
466
	private Action fEditAction;
467
	private Action fRemoveAction;
468
	private Action fLinkWithEditorAction;
469
	private Action fCollapseAllAction;
470
	private Action fPreferencePageAction;
471
472
	/* Clipboard actions */
473
	private Action fPasteAction;
474
	private Action fCopyAction;
475
476
	/* Current active context types for the editor */
477
	private List fActiveTypes;
478
479
	/* Preference stores */
480
	private IPreferenceStore fPreferenceStore;
481
482
	/* Controls */
483
	private Tree fTemplatesTree;
484
	private TreeViewer fTreeViewer;
485
	private Menu fContextMenu;
486
487
	/* Current selection */
488
	private TemplatePersistenceData[] fSelectedTemplates = new TemplatePersistenceData[0];
489
490
	/* The pattern viewer to be used with this view */
491
	private SourceViewer fPatternViewer;
492
493
	/* Cached results for avoiding processing while drag-over the editor */
494
	private int fCachedOffset;
495
	private boolean fCachedResult;
496
	private Point fCachedPosition;
497
498
	/* The current context types */
499
	protected String[] fCurrentContextTypes;
500
501
	/* The selection changed listener to monitor the editor selections */
502
	private SelectionChangedListener fSelectionChangedListener;
503
504
	/* Paste action support for the editor */
505
	private IAction fEditorOldPasteAction;
506
	private IAction fEditorPasteAction;
507
508
	/**
509
	 * Creates a new template view page.
510
	 * 
511
	 * @param editor
512
	 * @param viewer
513
	 */
514
	protected TemplatesPage(AbstractTextEditor editor, ISourceViewer viewer) {
515
		super();
516
		fEditor = editor;
517
		fViewer = viewer;
518
		setupPreferenceStore();
519
		setupEditorDropTarget();
520
		setupSelectionProvider();
521
		setupPasteOperation();
522
	}
523
524
	/*
525
	 * (non-Javadoc)
526
	 * 
527
	 * @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite)
528
	 */
529
	public void createControl(Composite ancestor) {
530
		setupActions();
531
532
		fControl = new SashForm(ancestor, SWT.VERTICAL);
533
534
		createTemplateTree(fControl);
535
		createPatternForm(fControl);
536
537
		hookContextMenu();
538
		initializeDND();
539
		updateButtons();
540
541
		int sashSize = fPreferenceStore.getInt(SASH_SIZE_PREF_ID);
542
		fControl.setWeights(new int[] { sashSize, 100 - sashSize });
543
		fTemplateChangeListener = new IPropertyChangeListener() {
544
			public void propertyChange(PropertyChangeEvent event) {
545
				getShell().getDisplay().asyncExec(new Runnable() {
546
					public void run() {
547
						refresh();
548
					}
549
				});
550
			}
551
		};
552
		getTemplatePreferenceStore().addPropertyChangeListener(fTemplateChangeListener);
553
	}
554
555
	/*
556
	 * (non-Javadoc)
557
	 * 
558
	 * @see org.eclipse.ui.part.Page#setFocus()
559
	 */
560
	public void setFocus() {
561
	}
562
563
	/*
564
	 * (non-Javadoc)
565
	 * 
566
	 * @see org.eclipse.ui.part.Page#getControl()
567
	 */
568
	public Control getControl() {
569
		return fControl;
570
	}
571
572
	/*
573
	 * (non-Javadoc)
574
	 * 
575
	 * @see org.eclipse.ui.part.Page#dispose()
576
	 */
577
	public void dispose() {
578
		ISelectionProvider selectionProvider = fViewer.getSelectionProvider();
579
		if (selectionProvider instanceof IPostSelectionProvider)
580
			((IPostSelectionProvider) selectionProvider)
581
					.removePostSelectionChangedListener(fSelectionChangedListener);
582
		else
583
			selectionProvider.removeSelectionChangedListener(fSelectionChangedListener);
584
		fEditor.setAction(ITextEditorActionConstants.PASTE, fEditorOldPasteAction);
585
		if (fContextMenu != null && !fContextMenu.isDisposed())
586
			fContextMenu.dispose();
587
		if (fTemplateChangeListener != null)
588
			getTemplatePreferenceStore().removePropertyChangeListener(fTemplateChangeListener);
589
		super.dispose();
590
	}
591
592
	/**
593
	 * Get the shell
594
	 * 
595
	 * @return the shell for this view site
596
	 */
597
	protected Shell getShell() {
598
		return getSite().getShell();
599
	}
600
601
	/**
602
	 * Get the image to be used for the given template. Clients can override to
603
	 * provide a different image.
604
	 * 
605
	 * @param template
606
	 * @return handle to the image
607
	 */
608
	protected Image getImageForTemplate(Template template) {
609
		return DEFAULT_TEMPLATE_IMAGE;
610
	}
611
612
	/**
613
	 * Creates the edit dialog. Subclasses may override this method to provide a
614
	 * custom dialog.
615
	 * 
616
	 * @param template
617
	 *            the template being edited
618
	 * @param edit
619
	 *            whether the dialog should be editable
620
	 * @param isNameModifiable
621
	 *            whether the template name may be modified
622
	 * @return the created or modified template, or <code>null</code> if the
623
	 *         editing failed
624
	 */
625
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
626
		EditTemplateDialog dialog = new EditTemplateDialog(getShell(), template, edit,
627
				isNameModifiable, getContextTypeRegistry());
628
		if (dialog.open() == Window.OK) {
629
			return dialog.getTemplate();
630
		}
631
		return null;
632
	}
633
634
	/**
635
	 * Update the pattern viewer to show the current template.
636
	 * 
637
	 * @param template
638
	 */
639
	protected void updatePatternViewer(Template template) {
640
		if (template != null)
641
			fPatternViewer.getDocument().set(template.getPattern());
642
		else
643
			fPatternViewer.getDocument().set(""); //$NON-NLS-1$
644
	}
645
646
	/**
647
	 * Creates, configures and returns a source viewer to present the template
648
	 * pattern on the templates page. Clients may override to provide a custom
649
	 * source viewer featuring e.g. syntax coloring.
650
	 * 
651
	 * @param parent
652
	 *            the parent control
653
	 * @return a configured source viewer
654
	 */
655
	protected SourceViewer createPatternViewer(Composite parent) {
656
		SourceViewer viewer = new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL
657
				| SWT.H_SCROLL);
658
		SourceViewerConfiguration configuration = new SourceViewerConfiguration();
659
		viewer.configure(configuration);
660
		IDocument document = new Document();
661
		viewer.setDocument(document);
662
		viewer.setEditable(false);
663
		return viewer;
664
	}
665
666
	/**
667
	 * Get the pattern viewer created by createPatternViewer()
668
	 * 
669
	 * @return the pattern viewer
670
	 */
671
	protected final SourceViewer getPatternViewer() {
672
		return fPatternViewer;
673
	}
674
675
	/**
676
	 * Get the editor associated with this view
677
	 * 
678
	 * @return the editor
679
	 */
680
	protected final AbstractTextEditor getEditor() {
681
		return fEditor;
682
	}
683
684
	/**
685
	 * The caret position in the editor has moved into a new context type. It is
686
	 * the subclasses responsibility to see that this is called only when needed
687
	 * by keeping track of editor contents (eg. partitions).
688
	 * 
689
	 * @param ids
690
	 */
691
	protected final void updateContextTypes(String[] ids) {
692
		fActiveTypes = Arrays.asList(ids);
693
		if (fLinkWithEditorAction != null && fLinkWithEditorAction.isChecked())
694
			refresh();
695
	}
696
697
	/**
698
	 * Subclasses should override and facilitate inserting the template code
699
	 * into the active editor.
700
	 * 
701
	 * @param template
702
	 * @param position
703
	 */
704
	abstract protected void insertTemplate(Template template, Point position);
705
706
	/**
707
	 * Get the context type registry for the associated editor.
708
	 * 
709
	 * @return the contextTypeRegistry
710
	 */
711
	abstract protected ContextTypeRegistry getContextTypeRegistry();
712
713
	/**
714
	 * Get the template store for the associated editor
715
	 * 
716
	 * @return the template store
717
	 */
718
	abstract protected TemplateStore getTemplateStore();
719
720
	/**
721
	 * Get the preference store used to create the template store returned by
722
	 * {@link TemplatesPage#getTemplateStore()}.
723
	 * 
724
	 * @return the preference store
725
	 */
726
	abstract protected IPreferenceStore getTemplatePreferenceStore();
727
728
	/**
729
	 * Get the preference page ID for the templates for the given editor.
730
	 * 
731
	 * @return id of the preference page, null if none exists
732
	 */
733
	abstract protected String getPreferencePageId();
734
735
	/**
736
	 * Get the context types supported at the current caret position of the
737
	 * editor
738
	 * 
739
	 * @return the ids of the context types
740
	 */
741
	protected abstract String[] getContextTypes();
742
743
	/**
744
	 * Check whether the given template is valid for the document at the given
745
	 * position
746
	 * 
747
	 * @param document
748
	 * @param template
749
	 * @param offset
750
	 * @param length
751
	 * @return true if the template is valid
752
	 */
753
	protected abstract boolean isValidTemplate(IDocument document, Template template, int offset,
754
			int length);
755
756
	/**
757
	 * Setup the preference store
758
	 */
759
	private void setupPreferenceStore() {
760
		fPreferenceStore = TextEditorPlugin.getDefault().getPreferenceStore();
761
		fPreferenceStore.setDefault(LINK_ACTION_PREF_ID, true);
762
		fPreferenceStore.setDefault(SASH_SIZE_PREF_ID, 80);
763
	}
764
765
	/**
766
	 * Setup the paste operation
767
	 * 
768
	 * We get the editors Paste operation and sets up a new operation that
769
	 * checks for the clipboard contents for TemplateTransfer data.
770
	 */
771
	private void setupPasteOperation() {
772
		fEditorOldPasteAction = fEditor.getAction(ITextEditorActionConstants.PASTE);
773
		fEditorPasteAction = new Action(TextEditorTemplateMessages.TemplatesPage_paste) {
774
			public void run() {
775
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
776
				Template template = getTemplateFromClipboard(clipBoard);
777
				if (template != null)
778
					insertTemplate(template, null);
779
				else
780
					fEditorOldPasteAction.run();
781
			}
782
783
			public void runWithEvent(Event event) {
784
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
785
				Template template = getTemplateFromClipboard(clipBoard);
786
				if (template != null)
787
					insertTemplate(template, null);
788
				else
789
					fEditorOldPasteAction.runWithEvent(event);
790
			}
791
792
			/**
793
			 * Convert the clipboard contents into a template
794
			 * 
795
			 * @param clipBoard
796
			 * @return the template or null if contents are not valid
797
			 */
798
			private Template getTemplateFromClipboard(Clipboard clipBoard) {
799
				TemplatePersistenceData[] contents = (TemplatePersistenceData[]) clipBoard
800
						.getContents(TemplateTransfer.getInstance());
801
				if (contents != null && contents.length == 1)
802
					return contents[0].getTemplate();
803
				return null;
804
			}
805
		};
806
		fEditorPasteAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
807
		fEditor.setAction(ITextEditorActionConstants.PASTE, fEditorPasteAction);
808
	}
809
810
	/**
811
	 * Setup a selection listener to monitor the editor
812
	 */
813
	private void setupSelectionProvider() {
814
		ISelectionProvider selectionProvider = fViewer.getSelectionProvider();
815
		fSelectionChangedListener = new SelectionChangedListener();
816
		if (selectionProvider instanceof IPostSelectionProvider)
817
			((IPostSelectionProvider) selectionProvider)
818
					.addPostSelectionChangedListener(fSelectionChangedListener);
819
		else
820
			selectionProvider.addSelectionChangedListener(fSelectionChangedListener);
821
	}
822
823
	/**
824
	 * Setup the editor site as a drop target.
825
	 */
826
	private void setupEditorDropTarget() {
827
		IDragAndDropService dndService = (IDragAndDropService) fEditor.getSite().getService(
828
				IDragAndDropService.class);
829
		EditorDropTarget editorDropTarget = new EditorDropTarget();
830
		dndService.addMergedDropTarget((Control) fEditor.getAdapter(Control.class), DND.DROP_COPY,
831
				new Transfer[] { TemplateTransfer.getInstance() }, editorDropTarget);
832
	}
833
834
	/**
835
	 * Setup the menu, context menu and toolbar actions.
836
	 */
837
	private void setupActions() {
838
		createActions();
839
		IActionBars actionBars = getSite().getActionBars();
840
841
		actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction);
842
		fPasteAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
843
		fPasteAction.setText(TextEditorTemplateMessages.TemplatesPage_paste);
844
		actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction);
845
		fCopyAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
846
		fCopyAction.setText(TextEditorTemplateMessages.TemplatesPage_copy);
847
		fillToolbar(actionBars);
848
		fillMenu(actionBars);
849
	}
850
851
	/**
852
	 * Create all the actions
853
	 */
854
	private void createActions() {
855
		fInsertAction = new Action(TextEditorTemplateMessages.TemplatesPage_insert) {
856
			public void run() {
857
				TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
858
				insertTemplate(selectedTemplates[0].getTemplate(), null);
859
			}
860
		};
861
		fInsertAction.setImageDescriptor(TemplatesPageImages
862
				.getImageDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_INSERT));
863
		fInsertAction.setDisabledImageDescriptor(TemplatesPageImages
864
				.getImageDescriptor(TemplatesPageImages.IMG_DLCL_TEMPLATE_INSERT));
865
		fInsertAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_insert_tooltip);
866
867
		fAddAction = new Action(TextEditorTemplateMessages.TemplatesPage_new) {
868
			public void run() {
869
				addTemplate();
870
			}
871
		};
872
		fAddAction.setImageDescriptor(TemplatesPageImages
873
				.getImageDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_NEW));
874
		fAddAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_new_tooltip);
875
876
		fEditAction = new Action(TextEditorTemplateMessages.TemplatesPage_edit) {
877
			public void run() {
878
				editTemplate();
879
			}
880
		};
881
		fEditAction.setImageDescriptor(TemplatesPageImages
882
				.getImageDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_EDIT));
883
		fEditAction.setDisabledImageDescriptor(TemplatesPageImages
884
				.getImageDescriptor(TemplatesPageImages.IMG_DLCL_TEMPLATE_EDIT));
885
		fEditAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_edit_tooltip);
886
887
		fRemoveAction = new Action(TextEditorTemplateMessages.TemplatesPage_remove) {
888
			public void run() {
889
				removeTemplates();
890
			}
891
		};
892
		fRemoveAction.setImageDescriptor(TemplatesPageImages
893
				.getImageDescriptor(TemplatesPageImages.IMG_DLCL_TEMPLATE_DELETE));
894
		fRemoveAction.setImageDescriptor(TemplatesPageImages
895
				.getImageDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_DELETE));
896
		fRemoveAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_remove_tooltip);
897
898
		fLinkWithEditorAction = new Action(TextEditorTemplateMessages.TemplatesPage_link_to_editor,
899
				IAction.AS_CHECK_BOX) {
900
			public void run() {
901
				fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkWithEditorAction.isChecked());
902
				refresh();
903
			}
904
		};
905
		fLinkWithEditorAction.setImageDescriptor(TemplatesPageImages
906
				.getImageDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_LINK));
907
		fLinkWithEditorAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID));
908
		fLinkWithEditorAction
909
				.setToolTipText(TextEditorTemplateMessages.TemplatesPage_link_to_editor_tooltip);
910
		fCollapseAllAction = new Action(TextEditorTemplateMessages.TemplatesPage_collapse_all) {
911
			public void run() {
912
				fTreeViewer.collapseAll();
913
			}
914
		};
915
		fCollapseAllAction.setImageDescriptor(TemplatesPageImages
916
				.getImageDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_COLLAPSE_ALL));
917
		fCollapseAllAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_collapse_all_tooltip);
918
919
		if (getPreferencePageId() != null) {
920
			fPreferencePageAction = new Action(TextEditorTemplateMessages.TemplatesPage_preference_page) {
921
				public void run() {
922
					showPreferencePage();
923
				}
924
			};
925
			fPreferencePageAction
926
					.setToolTipText(TextEditorTemplateMessages.TemplatesPage_preference_page_tooltip);
927
		}
928
929
		fPasteAction = new Action() {
930
			public void run() {
931
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
932
				String pattern = ((String) clipBoard.getContents(TextTransfer.getInstance()));
933
				if (pattern != null) {
934
					final Template template = new Template(createTemplateName(),
935
							TextEditorTemplateMessages.TemplatesPage_paste_description,
936
							getContextTypeId(), pattern.replaceAll("\\$", "\\$\\$"), true); //$NON-NLS-1$//$NON-NLS-2$
937
					if (template != null)
938
						getShell().getDisplay().asyncExec(new Runnable() {
939
							public void run() {
940
								addTemplate(template);
941
							}
942
						});
943
					return ;
944
				}
945
				TemplatePersistenceData[] templates = (TemplatePersistenceData[]) clipBoard
946
						.getContents(TemplateTransfer.getInstance());
947
				if (templates != null)
948
					copyTemplates(templates, getContextTypeId());
949
			}
950
		};
951
952
		fCopyAction = new Action() {
953
			public void run() {
954
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
955
				clipBoard.setContents(new Object[] { getSelectedTemplates() },
956
						new Transfer[] { TemplateTransfer.getInstance() });
957
			}
958
		};
959
	}
960
961
	/**
962
	 * Fill the toolbar
963
	 * 
964
	 * @param actionBars
965
	 */
966
	private void fillToolbar(IActionBars actionBars) {
967
		IToolBarManager toolBarManager = actionBars.getToolBarManager();
968
		toolBarManager.add(fInsertAction);
969
		toolBarManager.add(fAddAction);
970
		toolBarManager.add(fEditAction);
971
		toolBarManager.add(fRemoveAction);
972
973
		toolBarManager.add(new Separator());
974
975
		toolBarManager.add(fLinkWithEditorAction);
976
		toolBarManager.add(fCollapseAllAction);
977
	}
978
979
	/**
980
	 * Fill the view menu
981
	 * 
982
	 * @param actionBars
983
	 */
984
	private void fillMenu(IActionBars actionBars) {
985
		IMenuManager menuManager = actionBars.getMenuManager();
986
987
		if (fPreferencePageAction != null) {
988
			menuManager.add(fPreferencePageAction);
989
			menuManager.add(new Separator());
990
		}
991
992
		menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
993
	}
994
995
	/**
996
	 * Fill the context menu items
997
	 * 
998
	 * @param manager
999
	 */
1000
	private void fillContextMenu(IMenuManager manager) {
1001
		manager.add(fInsertAction);
1002
		manager.add(new Separator());
1003
		manager.add(fAddAction);
1004
		manager.add(fEditAction);
1005
		manager.add(fRemoveAction);
1006
		manager.add(new Separator());
1007
		manager.add(fCopyAction);
1008
		manager.add(fPasteAction);
1009
		// Other plug-ins can contribute there actions here
1010
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
1011
	}
1012
1013
	/**
1014
	 * Create the tree to display templates
1015
	 * 
1016
	 * @param parent
1017
	 */
1018
	private void createTemplateTree(Composite parent) {
1019
		Composite treeComposite = new Composite(parent, SWT.NONE);
1020
		GridData data = new GridData(GridData.FILL_BOTH);
1021
		treeComposite.setLayoutData(data);
1022
1023
		TreeColumnLayout columnLayout = new TreeColumnLayout();
1024
		treeComposite.setLayout(columnLayout);
1025
		fTemplatesTree = new Tree(treeComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
1026
				| SWT.FULL_SELECTION);
1027
		fTemplatesTree.setHeaderVisible(true);
1028
		fTemplatesTree.setLinesVisible(true);
1029
1030
		PixelConverter pixelConverter = new PixelConverter(fTemplatesTree);
1031
1032
		TreeColumn columnName = new TreeColumn(fTemplatesTree, SWT.NONE);
1033
		columnName.setText(TextEditorTemplateMessages.TemplatesPage_column_name);
1034
		int minWidth = fPreferenceStore.getInt(COLUMN_NAME_WIDTH_PREF_ID);
1035
		if (minWidth == 0) {
1036
			minWidth = pixelConverter.convertWidthInCharsToPixels(30);
1037
		}
1038
		columnLayout.setColumnData(columnName, new ColumnPixelData(minWidth, true));
1039
		columnName.addControlListener(new ControlListener() {
1040
			public void controlMoved(ControlEvent e) {
1041
			}
1042
1043
			public void controlResized(ControlEvent e) {
1044
				int nameWidth = ((TreeColumn) e.getSource()).getWidth();
1045
				fPreferenceStore.setValue(COLUMN_NAME_WIDTH_PREF_ID, nameWidth);
1046
			}
1047
		});
1048
1049
		TreeColumn columnDescription = new TreeColumn(fTemplatesTree, SWT.NONE);
1050
		columnDescription.setText(TextEditorTemplateMessages.TemplatesPage_column_description);
1051
		minWidth = fPreferenceStore.getInt(COLUMN_DESCRIPTION_WIDTH_PREF_ID);
1052
		if (minWidth == 0) {
1053
			minWidth = pixelConverter.convertWidthInCharsToPixels(45);
1054
		}
1055
		columnLayout.setColumnData(columnDescription, new ColumnPixelData(minWidth, false));
1056
		columnDescription.addControlListener(new ControlListener() {
1057
			public void controlMoved(ControlEvent e) {
1058
			}
1059
1060
			public void controlResized(ControlEvent e) {
1061
				int descriptionWidth = ((TreeColumn) e.getSource()).getWidth();
1062
				fPreferenceStore.setValue(COLUMN_DESCRIPTION_WIDTH_PREF_ID, descriptionWidth);
1063
			}
1064
		});
1065
1066
		createTreeViewer(fTemplatesTree);
1067
	}
1068
1069
	/**
1070
	 * Create the tree viewer and setup the providers
1071
	 * 
1072
	 * @param templatesTree
1073
	 */
1074
	private void createTreeViewer(Tree templatesTree) {
1075
		fTreeViewer = new TreeViewer(fTemplatesTree);
1076
		fTreeViewer.setLabelProvider(new TemplateLabelProvider());
1077
		fTreeViewer.setContentProvider(new TemplatesContentProvider());
1078
1079
		fTreeViewer.setComparator(new TemplateViewerComparator());
1080
		fTreeViewer.setInput(getTemplatePreferenceStore());
1081
		fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
1082
			public void doubleClick(DoubleClickEvent e) {
1083
				updateSelectedItems();
1084
				TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
1085
				insertTemplate(selectedTemplates[0].getTemplate(), null);
1086
			}
1087
		});
1088
1089
		fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
1090
			public void selectionChanged(SelectionChangedEvent e) {
1091
				updateSelectedItems();
1092
				updateButtons();
1093
			}
1094
		});
1095
		fTreeViewer.expandAll();
1096
	}
1097
1098
	/**
1099
	 * Setup the pattern viewer
1100
	 * 
1101
	 * @param parent
1102
	 */
1103
	private void createPatternForm(Composite parent) {
1104
		ViewForm viewForm = new ViewForm(parent, SWT.NONE);
1105
		viewForm.setBorderVisible(false);
1106
		CLabel previewLabel = new CLabel(viewForm, SWT.NONE);
1107
		previewLabel.setText(TextEditorTemplateMessages.TemplatesPage_preview);
1108
		previewLabel.setImage(TemplatesPageImages.getImage(TemplatesPageImages.IMG_OBJ_PREVIEW));
1109
		viewForm.setTopLeft(previewLabel);
1110
1111
		fPatternViewer = createPatternViewer(viewForm);
1112
		viewForm.setContent(fPatternViewer.getControl());
1113
		viewForm.addControlListener(new ControlListener() {
1114
			public void controlMoved(ControlEvent e) {
1115
			}
1116
1117
			public void controlResized(ControlEvent e) {
1118
				int[] weights = fControl.getWeights();
1119
				int sashSize = (int) (weights[0] * 100.0 / (weights[0] + weights[1]));
1120
				fPreferenceStore.setValue(SASH_SIZE_PREF_ID, sashSize);
1121
			}
1122
		});
1123
	}
1124
1125
	/**
1126
	 * Hookup the context menu
1127
	 */
1128
	private void hookContextMenu() {
1129
		MenuManager menuMgr = new MenuManager(POPUP_MENU_ID);
1130
		menuMgr.setRemoveAllWhenShown(true);
1131
		menuMgr.addMenuListener(new IMenuListener() {
1132
			public void menuAboutToShow(IMenuManager manager) {
1133
				fillContextMenu(manager);
1134
			}
1135
		});
1136
		fContextMenu = menuMgr.createContextMenu(fTreeViewer.getControl());
1137
		fTreeViewer.getControl().setMenu(fContextMenu);
1138
		getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer);
1139
	}
1140
1141
	/**
1142
	 * Check whether the template is valid for the given drop position
1143
	 * 
1144
	 * @param template
1145
	 * @param position
1146
	 * @return true if the template is valid
1147
	 */
1148
	private boolean isValidTemplateForPosition(Template template, Point position) {
1149
		StyledText textWidget = (StyledText) fEditor.getAdapter(Control.class);
1150
		IDocument document = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
1151
		try {
1152
			if (position.equals(fCachedPosition))
1153
				return fCachedResult;
1154
			fCachedPosition = position;
1155
			int offset = getOffset(document, textWidget, textWidget.toControl(position.x,
1156
					position.y));
1157
			if (fCachedOffset == offset)
1158
				return fCachedResult;
1159
			fCachedOffset = offset;
1160
			if (isValidTemplate(document, template, offset, 0))
1161
				return fCachedResult = true;
1162
		} catch (BadLocationException e) {
1163
		}
1164
		return fCachedResult = false;
1165
	}
1166
1167
	/**
1168
	 * Update the selected items.
1169
	 */
1170
	private void updateSelectedItems() {
1171
		setSelectedTemplates();
1172
		TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
1173
1174
		if (selectedTemplates.length == 1)
1175
			updatePatternViewer(selectedTemplates[0].getTemplate());
1176
		else
1177
			updatePatternViewer(null);
1178
	}
1179
1180
	/**
1181
	 * Show the preference page. The action is enabled only if
1182
	 * getPreferencePageId() returns non-null.
1183
	 */
1184
	private void showPreferencePage() {
1185
		PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageId(), null, null)
1186
				.open();
1187
	}
1188
1189
	/**
1190
	 * Update the state of the buttons
1191
	 */
1192
	private void updateButtons() {
1193
		TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
1194
		fCopyAction.setEnabled(selectedTemplates.length > 0);
1195
		fInsertAction.setEnabled(selectedTemplates.length == 1);
1196
		fEditAction.setEnabled(selectedTemplates.length == 1);
1197
		fRemoveAction.setEnabled(selectedTemplates.length > 0);
1198
	}
1199
1200
	/**
1201
	 * Set the selected templates
1202
	 */
1203
	private void setSelectedTemplates() {
1204
		IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection();
1205
1206
		Iterator it = selection.iterator();
1207
		TemplatePersistenceData[] data = new TemplatePersistenceData[selection.size()];
1208
		int i = 0;
1209
		while (it.hasNext()) {
1210
			Object o = it.next();
1211
			if (o instanceof TemplatePersistenceData)
1212
				data[i++] = (TemplatePersistenceData) o;
1213
			else {
1214
				fSelectedTemplates = new TemplatePersistenceData[0];
1215
				return;
1216
			}
1217
		}
1218
		fSelectedTemplates = data;
1219
	}
1220
1221
	/**
1222
	 * Get the currently selected templates
1223
	 * 
1224
	 * @return selected tempaltes
1225
	 */
1226
	private TemplatePersistenceData[] getSelectedTemplates() {
1227
		return fSelectedTemplates;
1228
	}
1229
1230
	/**
1231
	 * Add a template
1232
	 */
1233
	private void addTemplate() {
1234
		String id = getContextTypeId();
1235
		if (id != null) {
1236
			Template template = new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1237
1238
			addTemplate(template);
1239
		}
1240
	}
1241
1242
	/**
1243
	 * Get contextType of the selected template
1244
	 * 
1245
	 * @return contextType of the selected template or the first from the
1246
	 *         registry if no templates are selected
1247
	 */
1248
	private String getContextTypeId() {
1249
		IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection();
1250
		Object item;
1251
1252
		if (selection.size() == 0)
1253
			return ((TemplateContextType) getContextTypeRegistry().contextTypes().next()).getId();
1254
1255
		if (selection.size() == 1) {
1256
			item = selection.getFirstElement();
1257
			if (item instanceof TemplatePersistenceData)
1258
				return ((TemplatePersistenceData) item).getTemplate().getContextTypeId();
1259
			return ((TemplateContextType) item).getId();
1260
		}
1261
		Iterator it = selection.iterator();
1262
		String contextId = null;
1263
		while (it.hasNext()) {
1264
			item = it.next();
1265
			if (contextId == null)
1266
				contextId = getContextId(item);
1267
			else if (!contextId.equals(getContextId(item)))
1268
				return ((TemplateContextType) getContextTypeRegistry().contextTypes().next())
1269
						.getId();
1270
		}
1271
		return contextId;
1272
	}
1273
1274
	/**
1275
	 * Get the context id for the given item which is either a template or a
1276
	 * context type.
1277
	 * 
1278
	 * @param item
1279
	 * @return the context type id
1280
	 */
1281
	private String getContextId(Object item) {
1282
		String contextId;
1283
		if (item instanceof TemplatePersistenceData)
1284
			contextId = ((TemplatePersistenceData) item).getTemplate().getContextTypeId();
1285
		else
1286
			contextId = ((TemplateContextType) item).getId();
1287
		return contextId;
1288
	}
1289
1290
	/**
1291
	 * Add a template. The dialog is filled with the values from the given
1292
	 * template.
1293
	 * 
1294
	 * @param template
1295
	 */
1296
	private void addTemplate(Template template) {
1297
		Template newTemplate;
1298
		newTemplate = editTemplate(template, false, true);
1299
		if (newTemplate != null) {
1300
			TemplatePersistenceData data = new TemplatePersistenceData(newTemplate, true);
1301
			getTemplateStore().add(data);
1302
			saveTemplateStore();
1303
			refresh();
1304
			fTreeViewer.setSelection(new StructuredSelection(data), true);
1305
		}
1306
	}
1307
1308
	/**
1309
	 * Save the template store
1310
	 */
1311
	private void saveTemplateStore() {
1312
		try {
1313
			getTemplateStore().save();
1314
		} catch (IOException e) {
1315
			e.printStackTrace();
1316
			MessageDialog.openError(getShell(),
1317
					TextEditorTemplateMessages.TemplatesPage_save_error_message, e.getMessage());
1318
		}
1319
	}
1320
1321
	/**
1322
	 * Edit the selected template
1323
	 */
1324
	private void editTemplate() {
1325
		Template oldTemplate = getSelectedTemplates()[0].getTemplate();
1326
		Template newTemplate = editTemplate(new Template(oldTemplate), true, true);
1327
		if (newTemplate != null) {
1328
			if (!newTemplate.getName().equals(oldTemplate.getName())
1329
					&& MessageDialog.openQuestion(getShell(),
1330
							TextEditorTemplateMessages.TemplatesPage_question_create_new_title,
1331
							TextEditorTemplateMessages.TemplatesPage_question_create_new_message)) {
1332
				TemplatePersistenceData templateData = new TemplatePersistenceData(newTemplate,
1333
						true);
1334
				getTemplateStore().add(templateData);
1335
				refresh();
1336
				fTreeViewer.setSelection(new StructuredSelection(templateData), true);
1337
			} else {
1338
				getSelectedTemplates()[0].setTemplate(newTemplate);
1339
			}
1340
		}
1341
		saveTemplateStore();
1342
	}
1343
1344
	/**
1345
	 * Move the selected template from one context to another
1346
	 * 
1347
	 * @param templates
1348
	 * @param contextId
1349
	 * 
1350
	 */
1351
	private void moveTemplates(TemplatePersistenceData[] templates, String contextId) {
1352
		for (int i = 0; i < templates.length; i++) {
1353
			Template t = templates[i].getTemplate();
1354
			templates[i].setTemplate(new Template(t.getName(), t.getDescription(), contextId, t
1355
					.getPattern(), t.isAutoInsertable()));
1356
		}
1357
		saveTemplateStore();
1358
		fTreeViewer.setSelection(new StructuredSelection(templates), true);
1359
	}
1360
1361
	/**
1362
	 * Copy the selected templates to another context
1363
	 * 
1364
	 * @param templates
1365
	 * @param contextId
1366
	 * 
1367
	 */
1368
	private void copyTemplates(TemplatePersistenceData[] templates, String contextId) {
1369
		TemplatePersistenceData[] newTemplates = new TemplatePersistenceData[templates.length];
1370
		for (int i = 0; i < templates.length; i++) {
1371
			Template t = templates[i].getTemplate();
1372
			newTemplates[i] = new TemplatePersistenceData(new Template(t.getName(), t
1373
					.getDescription(), contextId, t.getPattern(), t.isAutoInsertable()), true);
1374
			getTemplateStore().add(newTemplates[i]);
1375
		}
1376
		saveTemplateStore();
1377
		refresh();
1378
		fTreeViewer.setSelection(new StructuredSelection(newTemplates), true);
1379
	}
1380
1381
	/**
1382
	 * Remove one or more selected templates
1383
	 */
1384
	private void removeTemplates() {
1385
		String title;
1386
		TemplatePersistenceData[] selectedTemplates = getSelectedTemplates();
1387
		if (selectedTemplates.length == 1)
1388
			title = TextEditorTemplateMessages.TemplatesPage_remove_title_single;
1389
		else
1390
			title = TextEditorTemplateMessages.TemplatesPage_remove_title_multi;
1391
		String message;
1392
		if (selectedTemplates.length == 1)
1393
			message = TextEditorTemplateMessages.TemplatesPage_remove_message_single;
1394
		else
1395
			message = NLSUtility.format(TextEditorTemplateMessages.TemplatesPage_remove_message_multi,
1396
					new Object[] { new Integer(selectedTemplates.length) });
1397
		if (!MessageDialog.openQuestion(getShell(), title, message))
1398
			return;
1399
		for (int i = 0; i < selectedTemplates.length; i++) {
1400
			getTemplateStore().delete(selectedTemplates[i]);
1401
		}
1402
		saveTemplateStore();
1403
		fTreeViewer.setSelection(new StructuredSelection(new Object[] {}), true);
1404
	}
1405
1406
	/**
1407
	 * Initialize drag and drop the template items
1408
	 */
1409
	private void initializeDND() {
1410
		DragSourceAdapter dragListener = new DragSourceAdapter() {
1411
			/*
1412
			 * (non-Javadoc)
1413
			 * 
1414
			 * @see org.eclipse.swt.dnd.DragSourceAdapter#dragStart(org.eclipse.swt.dnd.DragSourceEvent)
1415
			 */
1416
			public void dragStart(DragSourceEvent event) {
1417
				if (getSelectedTemplates().length == 0) {
1418
					event.doit = false;
1419
				}
1420
			}
1421
1422
			/*
1423
			 * (non-Javadoc)
1424
			 * 
1425
			 * @see org.eclipse.swt.dnd.DragSourceAdapter#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
1426
			 */
1427
			public void dragSetData(DragSourceEvent event) {
1428
				if (TemplateTransfer.getInstance().isSupportedType(event.dataType)) {
1429
					event.data = getSelectedTemplates();
1430
				}
1431
			}
1432
		};
1433
		fTreeViewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, new Transfer[] { TemplateTransfer
1434
				.getInstance() }, dragListener);
1435
		DropTargetAdapter dropListener = new DropTargetAdapter() {
1436
			Transfer textTransfer = TextTransfer.getInstance();
1437
			Transfer templateTransfer = TemplateTransfer.getInstance();
1438
1439
			/*
1440
			 * (non-Javadoc)
1441
			 * 
1442
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
1443
			 */
1444
			public void dragEnter(DropTargetEvent event) {
1445
				if (event.detail == DND.DROP_DEFAULT)
1446
					event.detail = DND.DROP_COPY;
1447
			}
1448
1449
			/*
1450
			 * (non-Javadoc)
1451
			 * 
1452
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
1453
			 */
1454
			public void dragOperationChanged(DropTargetEvent event) {
1455
				if (event.detail == DND.DROP_DEFAULT)
1456
					event.detail = DND.DROP_COPY;
1457
			}
1458
1459
			/*
1460
			 * (non-Javadoc)
1461
			 * 
1462
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
1463
			 */
1464
			public void dragOver(DropTargetEvent event) {
1465
				event.feedback |= DND.FEEDBACK_SCROLL;
1466
				if (event.item == null) {
1467
					event.detail = DND.DROP_NONE;
1468
					return;
1469
				}
1470
				int index = 0;
1471
				boolean isTemplateTransfer = false;
1472
				while (index < event.dataTypes.length) {
1473
					if (textTransfer.isSupportedType(event.dataTypes[index])) {
1474
						break;
1475
					}
1476
					if (templateTransfer.isSupportedType(event.dataTypes[index])) {
1477
						isTemplateTransfer = true;
1478
						break;
1479
					}
1480
					index++;
1481
				}
1482
				if (index < event.dataTypes.length) {
1483
					event.currentDataType = event.dataTypes[index];
1484
					if (event.detail == DND.DROP_DEFAULT || !isTemplateTransfer)
1485
						event.detail = DND.DROP_COPY;
1486
					return;
1487
				}
1488
			}
1489
1490
			/*
1491
			 * (non-Javadoc)
1492
			 * 
1493
			 * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
1494
			 */
1495
			public void drop(DropTargetEvent event) {
1496
				if (event.item == null)
1497
					return;
1498
				Object object = ((TreeItem) event.item).getData();
1499
				final String contextId;
1500
				if (object instanceof TemplateContextType)
1501
					contextId = ((TemplateContextType) object).getId();
1502
				else
1503
					contextId = ((TemplatePersistenceData) object).getTemplate().getContextTypeId();
1504
				if (textTransfer.isSupportedType(event.currentDataType)) {
1505
					String text = ((String) event.data).replaceAll("\\$", "\\$\\$"); //$NON-NLS-1$ //$NON-NLS-2$
1506
					final Template template = new Template(createTemplateName(),
1507
							TextEditorTemplateMessages.TemplatesPage_paste_description, contextId, text,
1508
							true);
1509
					getShell().getDisplay().asyncExec(new Runnable() {
1510
						public void run() {
1511
							addTemplate(template);
1512
						}
1513
					});
1514
					return;
1515
				}
1516
				if (templateTransfer.isSupportedType(event.currentDataType)) {
1517
					final TemplatePersistenceData[] templates = (TemplatePersistenceData[]) event.data;
1518
					final int dropType = event.detail;
1519
					getShell().getDisplay().asyncExec(new Runnable() {
1520
						public void run() {
1521
							if (dropType == DND.DROP_COPY)
1522
								copyTemplates(templates, contextId);
1523
							else
1524
								moveTemplates(templates, contextId);
1525
						}
1526
					});
1527
				}
1528
			}
1529
		};
1530
		Transfer[] transfers = new Transfer[] { TextTransfer.getInstance(),
1531
				TemplateTransfer.getInstance() };
1532
		fTreeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, dropListener);
1533
	}
1534
1535
	/**
1536
	 * Create a template name
1537
	 * 
1538
	 * @return a new template name
1539
	 */
1540
	private String createTemplateName() {
1541
		for (int i = 1; i < Integer.MAX_VALUE; i++) {
1542
			String name = TextEditorTemplateMessages.TemplatesPage_snippet + i;
1543
			if (getTemplateStore().findTemplate(name) == null)
1544
				return name;
1545
		}
1546
		return null;
1547
	}
1548
1549
	/**
1550
	 * Store the collapse state of a context
1551
	 */
1552
	private void storeCollapseState() {
1553
		TreeItem[] items = fTreeViewer.getTree().getItems();
1554
		for (int i = 0; i < items.length; i++) {
1555
			fPreferenceStore.setValue(CONTEXT_COLLAPSE_PREF_ID
1556
					+ ((TemplateContextType) items[i].getData()).getId(), !items[i].getExpanded());
1557
		}
1558
	}
1559
1560
	/**
1561
	 * Refresh the template tree contents
1562
	 */
1563
	private void refresh() {
1564
		storeCollapseState();
1565
		fTreeViewer.getTree().setRedraw(false);
1566
		try {
1567
			fTreeViewer.refresh();
1568
			TreeItem[] items = fTreeViewer.getTree().getItems();
1569
			for (int i = 0; i < items.length; i++) {
1570
				boolean isExpanded = !fPreferenceStore.getBoolean(CONTEXT_COLLAPSE_PREF_ID
1571
						+ ((TemplateContextType) items[i].getData()).getId());
1572
				if (isExpanded)
1573
					fTreeViewer.expandToLevel(items[i].getData(), AbstractTreeViewer.ALL_LEVELS);
1574
				else
1575
					fTreeViewer.collapseToLevel(items[i].getData(), AbstractTreeViewer.ALL_LEVELS);
1576
			}
1577
		} finally {
1578
			fTreeViewer.getTree().setRedraw(true);
1579
		}
1580
	}
1581
1582
	/**
1583
	 * Get the document relative offset from the textwidget relative point
1584
	 * 
1585
	 * @param document
1586
	 * @param textWidget
1587
	 * @param point
1588
	 * @return the offset
1589
	 * @throws BadLocationException
1590
	 */
1591
	private int getOffset(IDocument document, StyledText textWidget, Point point)
1592
			throws BadLocationException {
1593
		int widgetCaret = fViewer.getTextWidget().getCaretOffset();
1594
		if (fViewer instanceof ITextViewerExtension5) {
1595
			ITextViewerExtension5 ext = (ITextViewerExtension5) fViewer;
1596
			try {
1597
				return ext.widgetOffset2ModelOffset(textWidget.getOffsetAtLocation(point));
1598
			} catch (IllegalArgumentException e) {
1599
				int docLineIndex = ext.widgetLine2ModelLine(textWidget.getLineIndex(point.y));
1600
				String lineDelimiter = document.getLineDelimiter(docLineIndex);
1601
				int delimLength = lineDelimiter == null ? 0 : lineDelimiter.length();
1602
				return document.getLineOffset(docLineIndex) + document.getLineLength(docLineIndex)
1603
						- delimLength;
1604
			}
1605
		}
1606
		IRegion visible = fViewer.getVisibleRegion();
1607
		return widgetCaret + visible.getOffset();
1608
	}
1609
}
(-)src/org/eclipse/ui/texteditor/templates/ITemplatesPage.java (+25 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
12
package org.eclipse.ui.texteditor.templates;
13
14
import org.eclipse.ui.part.IPageBookViewPage;
15
16
/**
17
 * Interface for a template page. This interface defines the minimum requirement
18
 * for pages within the templates view, namely they must be pages in a pagebook
19
 * view. (implement <code>IPageBookViewPage</code>).
20
 * 
21
 * @see TemplatesView
22
 * @since 3.4
23
 */
24
public interface ITemplatesPage extends IPageBookViewPage {
25
}
(-)src/org/eclipse/ui/texteditor/templates/TemplatesView.java (+246 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
12
package org.eclipse.ui.texteditor.templates;
13
14
import org.eclipse.core.runtime.Assert;
15
import org.eclipse.core.runtime.IAdaptable;
16
import org.eclipse.core.runtime.Platform;
17
import org.eclipse.core.runtime.PlatformObject;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.ui.IEditorPart;
20
import org.eclipse.ui.IWorkbenchPage;
21
import org.eclipse.ui.IWorkbenchPart;
22
import org.eclipse.ui.PlatformUI;
23
import org.eclipse.ui.part.IContributedContentsView;
24
import org.eclipse.ui.part.IPage;
25
import org.eclipse.ui.part.MessagePage;
26
import org.eclipse.ui.part.PageBook;
27
import org.eclipse.ui.part.PageBookView;
28
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
29
30
/**
31
 * Main class for the Templates View.
32
 * <p>
33
 * This standard view has id <code>"org.eclipse.ui.views.TemplatesView"</code>.
34
 * </p>
35
 * When a <b>templates view</b> notices an editor being activated, it 
36
 * asks the editor whether it has a <b>template page</b> to include
37
 * in the templates view. This is done using <code>getAdapter</code>:
38
 * <pre>
39
 * IEditorPart editor = ...;
40
 * ITemplatePage templatePage = (ITemplatePage) editor.getAdapter(ITemplatePage.class);
41
 * if (templatePage != null) {
42
 *    // editor wishes to contribute templatePage to templates view
43
 * }
44
 * </pre>
45
 * If the editor supports a templates page, the editor instantiates
46
 * and configures the page, and returns it. This page is then added to the 
47
 * templates view (a pagebook which presents one page at a time) and 
48
 * immediately made the current page (the templates view need not be
49
 * visible). If the editor does not support a template page, the templates
50
 * view shows a special default page which makes it clear to the user
51
 * that the templates are not available. When the templates view notices a
52
 * different editor being activated, it flips to the editor's corresponding
53
 * template page. When the templates view notices an editor being
54
 * closed, it may destroy the editor's corresponding templates page.
55
 * </p>
56
 * <p>
57
 * The workbench will automatically instantiate this class when a templates
58
 * view is needed for a workbench window. This class was not intended
59
 * to be instantiated or subclassed by clients.
60
 * </p>
61
 *
62
 * @since 3.4
63
 */
64
public class TemplatesView extends PageBookView {
65
    /**
66
     * The view id for the workbench's Templates standard component.
67
     */
68
    public static String ID = "org.eclipse.ui.texteditor.templates.view.TemplatesView"; //$NON-NLS-1$
69
70
    /**
71
     * The plugin prefix.
72
     */
73
    public static final String PREFIX = PlatformUI.PLUGIN_ID + "."; //$NON-NLS-1$
74
75
    /**
76
     * Message to show on the default page.
77
     */
78
    private static final String DEFAULT_TEXT = TextEditorTemplateMessages.Templates_defaultMessage; 
79
80
    /**
81
     * Creates a templates view
82
     */
83
    public TemplatesView() {
84
        super();
85
    }
86
87
    /* (non-Javadoc)
88
     * Method declared on PageBookView.
89
     */
90
    protected IPage createDefaultPage(PageBook book) {
91
        MessagePage page = new MessagePage();
92
        initPage(page);
93
        page.createControl(book);
94
        page.setMessage(DEFAULT_TEXT);
95
        return page;
96
    }
97
98
    /**
99
     * The <code>PageBookView</code> implementation of this <code>IWorkbenchPart</code>
100
     * method creates a <code>PageBook</code> control with its default page showing.
101
     * @param parent 
102
     */
103
    public void createPartControl(Composite parent) {
104
        super.createPartControl(parent);
105
        PlatformUI.getWorkbench().getHelpSystem().setHelp(getPageBook(),
106
                IAbstractTextEditorHelpContextIds.TEMPLATES_VIEW_HELP_CONTEXT_ID);
107
    }
108
109
    /* (non-Javadoc)
110
     * Method declared on PageBookView.
111
     */
112
    protected PageRec doCreatePage(IWorkbenchPart part) {
113
        // Try to get template page.
114
        Object obj = getAdapter(part, ITemplatesPage.class, false);
115
        if (obj instanceof ITemplatesPage) {
116
            ITemplatesPage page = (ITemplatesPage) obj;
117
			initPage(page);
118
            page.createControl(getPageBook());
119
            return new PageRec(part, page);
120
        }
121
        // There is no template page
122
        return null;
123
    }
124
125
    /* (non-Javadoc)
126
     * Method declared on PageBookView.
127
     */
128
    protected void doDestroyPage(IWorkbenchPart part, PageRec rec) {
129
        ITemplatesPage page = (ITemplatesPage) rec.page;
130
        page.dispose();
131
        rec.dispose();
132
    }
133
134
    /* (non-Javadoc)
135
     * Method declared on IAdaptable.
136
     */
137
    public Object getAdapter(Class key) {
138
        if (key == IContributedContentsView.class) {
139
			return new IContributedContentsView() {
140
                public IWorkbenchPart getContributingPart() {
141
                    return getContributingEditor();
142
                }
143
            };
144
		}
145
        return super.getAdapter(key);
146
    }
147
148
    /* (non-Javadoc)
149
     * Method declared on PageBookView.
150
     */
151
    protected IWorkbenchPart getBootstrapPart() {
152
        IWorkbenchPage page = getSite().getPage();
153
        if (page != null) {
154
			return page.getActiveEditor();
155
		}
156
157
        return null;
158
    }
159
160
    /**
161
     * Returns the editor which contributed the current 
162
     * page to this view.
163
     *
164
     * @return the editor which contributed the current page
165
     * or <code>null</code> if no editor contributed the current page
166
     */
167
    private IWorkbenchPart getContributingEditor() {
168
        return getCurrentContributingPart();
169
    }
170
171
    /* (non-Javadoc)
172
     * Method declared on PageBookView.
173
     * We only want to track editors.
174
     */
175
    protected boolean isImportant(IWorkbenchPart part) {
176
        //We only care about editors
177
        return (part instanceof IEditorPart);
178
    }
179
180
    /* (non-Javadoc)
181
     * Method declared on IViewPart.
182
     * Treat this the same as part activation.
183
     */
184
    public void partBroughtToTop(IWorkbenchPart part) {
185
        partActivated(part);
186
    }
187
    
188
    /**
189
     * If it is possible to adapt the given object to the given type, this
190
     * returns the adapter. Performs the following checks:
191
     * 
192
     * <ol>
193
     * <li>Returns <code>sourceObject</code> if it is an instance of the
194
     * adapter type.</li>
195
     * <li>If sourceObject implements IAdaptable, it is queried for adapters.</li>
196
     * <li>If sourceObject is not an instance of PlatformObject (which would have
197
     * already done so), the adapter manager is queried for adapters</li>
198
     * </ol>
199
     * 
200
     * Otherwise returns null.
201
     * 
202
     * @param sourceObject
203
     *            object to adapt, or null
204
     * @param adapter
205
     *            type to adapt to
206
     * @param activatePlugins 
207
     *            true if IAdapterManager.loadAdapter should be used (may trigger plugin activation)
208
     * @return a representation of sourceObject that is assignable to the
209
     *         adapter type, or null if no such representation exists
210
     */
211
    private Object getAdapter(Object sourceObject, Class adapter, boolean activatePlugins) {
212
    	Assert.isNotNull(adapter);
213
        if (sourceObject == null) {
214
            return null;
215
        }
216
        if (adapter.isInstance(sourceObject)) {
217
            return sourceObject;
218
        }
219
220
        if (sourceObject instanceof IAdaptable) {
221
            IAdaptable adaptable = (IAdaptable) sourceObject;
222
223
            Object result = adaptable.getAdapter(adapter);
224
            if (result != null) {
225
                // Sanity-check
226
                Assert.isTrue(adapter.isInstance(result));
227
                return result;
228
            }
229
        } 
230
        
231
        if (!(sourceObject instanceof PlatformObject)) {
232
        	Object result;
233
        	if (activatePlugins) {
234
        		result = Platform.getAdapterManager().loadAdapter(sourceObject, adapter.getName());
235
        	} else {
236
        		result = Platform.getAdapterManager().getAdapter(sourceObject, adapter);
237
        	}
238
            if (result != null) {
239
                return result;
240
            }
241
        }
242
243
        return null;
244
    }
245
246
}
(-)src/org/eclipse/ui/internal/texteditor/templates/TemplatesPageImages.java (+161 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
12
package org.eclipse.ui.internal.texteditor.templates;
13
14
import java.net.URL;
15
16
import org.eclipse.core.runtime.FileLocator;
17
import org.eclipse.core.runtime.Path;
18
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.jface.resource.ImageDescriptor;
20
import org.eclipse.jface.resource.ImageRegistry;
21
import org.eclipse.swt.graphics.Image;
22
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
23
import org.osgi.framework.Bundle;
24
25
/**
26
 * The images used by TemplatesPage
27
 * 
28
 * @since 3.4
29
 */
30
public class TemplatesPageImages {
31
32
	static final String PREFIX_ELCL = TextEditorPlugin.PLUGIN_ID + ".elcl."; //$NON-NLS-1$
33
	static final String PREFIX_DLCL = TextEditorPlugin.PLUGIN_ID + ".dlcl."; //$NON-NLS-1$
34
	static final String PREFIX_OBJ = TextEditorPlugin.PLUGIN_ID + ".obj."; //$NON-NLS-1$
35
36
	public static final String IMG_ELCL_TEMPLATE_NEW = PREFIX_ELCL + "new_template.gif"; //$NON-NLS-1$
37
	public static final String IMG_ELCL_TEMPLATE_DELETE = PREFIX_ELCL + "delete_template.gif"; //$NON-NLS-1$
38
	public static final String IMG_ELCL_TEMPLATE_EDIT = PREFIX_ELCL + "edit_template.gif"; //$NON-NLS-1$
39
	public static final String IMG_ELCL_TEMPLATE_INSERT = PREFIX_ELCL + "insert_template.gif"; //$NON-NLS-1$
40
	public static final String IMG_ELCL_TEMPLATE_LINK = PREFIX_ELCL + "link_to_editor.gif"; //$NON-NLS-1$
41
	public static final String IMG_ELCL_TEMPLATE_COLLAPSE_ALL = PREFIX_ELCL + "collapseall.gif"; //$NON-NLS-1$
42
	public static final String IMG_DLCL_TEMPLATE_DELETE = PREFIX_DLCL + "delete_template.gif"; //$NON-NLS-1$
43
	public static final String IMG_DLCL_TEMPLATE_EDIT = PREFIX_DLCL + "edit_template.gif"; //$NON-NLS-1$
44
	public static final String IMG_DLCL_TEMPLATE_INSERT = PREFIX_DLCL + "insert_template.gif"; //$NON-NLS-1$
45
46
	public static final String IMG_OBJ_PREVIEW = PREFIX_OBJ + "preview.gif"; //$NON-NLS-1$
47
	public static final String IMG_OBJ_CONTEXT = PREFIX_OBJ + "context.gif"; //$NON-NLS-1$
48
	public static final String IMG_OBJ_TEMPLATE = PREFIX_OBJ + "template_obj.gif"; //$NON-NLS-1$
49
50
	/**
51
	 * The image registry containing <code>Image</code>s.
52
	 */
53
	private static ImageRegistry imageRegistry;
54
55
	private static String ICONS_PATH = "$nl$/icons/full/"; //$NON-NLS-1$
56
57
	// Use IPath and toOSString to build the names to ensure they have the
58
	// slashes correct
59
	private final static String ELCL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$
60
	private final static String DLCL = ICONS_PATH + "dlcl16/"; //$NON-NLS-1$
61
	private final static String OBJ = ICONS_PATH + "obj16/"; //$NON-NLS-1$
62
63
	/**
64
	 * Declare all images
65
	 */
66
	private static void declareImages() {
67
		// Ant Editor images
68
		declareRegistryImage(IMG_ELCL_TEMPLATE_NEW, ELCL + "new_template.gif"); //$NON-NLS-1$
69
		declareRegistryImage(IMG_ELCL_TEMPLATE_INSERT, ELCL + "insert_template.gif"); //$NON-NLS-1$
70
		declareRegistryImage(IMG_DLCL_TEMPLATE_INSERT, DLCL + "insert_template.gif"); //$NON-NLS-1$
71
		declareRegistryImage(IMG_ELCL_TEMPLATE_DELETE, ELCL + "delete_template.gif"); //$NON-NLS-1$
72
		declareRegistryImage(IMG_DLCL_TEMPLATE_DELETE, DLCL + "delete_template.gif"); //$NON-NLS-1$
73
		declareRegistryImage(IMG_ELCL_TEMPLATE_EDIT, ELCL + "edit_template.gif"); //$NON-NLS-1$
74
		declareRegistryImage(IMG_DLCL_TEMPLATE_EDIT, DLCL + "edit_template.gif"); //$NON-NLS-1$
75
		declareRegistryImage(IMG_ELCL_TEMPLATE_LINK, ELCL + "link_to_editor.gif"); //$NON-NLS-1$
76
		declareRegistryImage(IMG_ELCL_TEMPLATE_COLLAPSE_ALL, ELCL + "collapseall.gif"); //$NON-NLS-1$
77
78
		declareRegistryImage(IMG_OBJ_PREVIEW, OBJ + "preview.gif"); //$NON-NLS-1$
79
		declareRegistryImage(IMG_OBJ_CONTEXT, OBJ + "context.gif"); //$NON-NLS-1$
80
		declareRegistryImage(IMG_OBJ_TEMPLATE, OBJ + "template_obj.gif"); //$NON-NLS-1$
81
	}
82
83
	/**
84
	 * Declare an Image in the registry table.
85
	 * 
86
	 * @param key
87
	 *            The key to use when registering the image
88
	 * @param path
89
	 *            The path where the image can be found. This path is relative
90
	 *            to where this plugin class is found (i.e. typically the
91
	 *            packages directory)
92
	 */
93
	private final static void declareRegistryImage(String key, String path) {
94
		ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor();
95
		Bundle bundle = Platform.getBundle(TextEditorPlugin.PLUGIN_ID);
96
		URL url = null;
97
		if (bundle != null) {
98
			url = FileLocator.find(bundle, new Path(path), null);
99
			desc = ImageDescriptor.createFromURL(url);
100
		}
101
		imageRegistry.put(key, desc);
102
	}
103
104
	/**
105
	 * Returns the ImageRegistry.
106
	 * 
107
	 * @return image registry
108
	 */
109
	public static ImageRegistry getImageRegistry() {
110
		if (imageRegistry == null) {
111
			initializeImageRegistry();
112
		}
113
		return imageRegistry;
114
	}
115
116
	/**
117
	 * Initialize the image registry by declaring all of the required graphics.
118
	 * This involves creating JFace image descriptors describing how to
119
	 * create/find the image should it be needed. The image is not actually
120
	 * allocated until requested.
121
	 * 
122
	 * Prefix conventions Wizard Banners WIZBAN_ Preference Banners PREF_BAN_
123
	 * Property Page Banners PROPBAN_ Color toolbar CTOOL_ Enable toolbar ETOOL_
124
	 * Disable toolbar DTOOL_ Local enabled toolbar ELCL_ Local Disable toolbar
125
	 * DLCL_ Object large OBJL_ Object small OBJS_ View VIEW_ Product images
126
	 * PROD_ Misc images MISC_
127
	 * 
128
	 * Where are the images? The images (typically gifs) are found in the same
129
	 * location as this plugin class. This may mean the same package directory
130
	 * as the package holding this class. The images are declared using
131
	 * this.getClass() to ensure they are looked up via this plugin class.
132
	 * 
133
	 * @return the image registry
134
	 * @see org.eclipse.jface.resource.ImageRegistry
135
	 */
136
	public static ImageRegistry initializeImageRegistry() {
137
		imageRegistry = TextEditorPlugin.getDefault().getImageRegistry();
138
		declareImages();
139
		return imageRegistry;
140
	}
141
142
	/**
143
	 * Returns the <code>Image<code> identified by the given key,
144
	 * or <code>null</code> if it does not exist.
145
	 * @param key 
146
	 * @return the image
147
	 */
148
	public static Image getImage(String key) {
149
		return getImageRegistry().get(key);
150
	}
151
152
	/**
153
	 * Returns the <code>ImageDescriptor<code> identified by the given key,
154
	 * or <code>null</code> if it does not exist.
155
	 * @param key 
156
	 * @return the image descriptor
157
	 */
158
	public static ImageDescriptor getImageDescriptor(String key) {
159
		return getImageRegistry().getDescriptor(key);
160
	}
161
}
(-)src/org/eclipse/ui/internal/texteditor/templates/TemplateTransfer.java (+97 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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 (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
10
 *******************************************************************************/
11
12
package org.eclipse.ui.internal.texteditor.templates;
13
14
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
15
import org.eclipse.swt.dnd.ByteArrayTransfer;
16
import org.eclipse.swt.dnd.TransferData;
17
import org.eclipse.ui.texteditor.templates.TemplatesPage;
18
19
/**
20
 * Transfer type used for clip board and DnD operations for template objects
21
 * 
22
 * @see TemplatesPage
23
 *
24
 * @since 3.4
25
 */
26
public class TemplateTransfer extends ByteArrayTransfer {
27
28
	private static TemplateTransfer instance;
29
30
	private static final String LOCAL_NAME = TemplateTransfer.class.getName()
31
			+ System.currentTimeMillis();
32
	private static final int LOCAL_TYPE = registerType(LOCAL_NAME);
33
34
	private static String[] names = null;
35
	private static int types[] = null;
36
37
	private TemplatePersistenceData[] fObject ;
38
	
39
	/**
40
	 * @return the registered Transfer instance
41
	 */
42
	public static TemplateTransfer getInstance() {
43
		if (instance == null) {
44
			instance = new TemplateTransfer();
45
			types = new int[] { LOCAL_TYPE };
46
			names = new String[] { LOCAL_NAME };
47
		}
48
		return instance;
49
	}
50
51
	/*
52
	 * (non-Javadoc)
53
	 * 
54
	 * @see org.eclipse.swt.dnd.Transfer#getTypeIds()
55
	 */
56
	protected int[] getTypeIds() {
57
		return types;
58
	}
59
60
	/*
61
	 * (non-Javadoc)
62
	 * 
63
	 * @see org.eclipse.swt.dnd.Transfer#getTypeNames()
64
	 */
65
	protected String[] getTypeNames() {
66
		return names;
67
	}
68
69
	/*
70
	 * (non-Javadoc)
71
	 * 
72
	 * @see org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(java.lang.Object,
73
	 *      org.eclipse.swt.dnd.TransferData)
74
	 */
75
	protected void javaToNative(Object object, TransferData transferData) {
76
		if (object == null || !(object instanceof TemplatePersistenceData[])
77
				|| !isSupportedType(transferData)) {
78
			fObject = null ;
79
			return;
80
		}
81
		fObject = (TemplatePersistenceData[]) object ;
82
		super.javaToNative(LOCAL_NAME.getBytes(), transferData);
83
	}
84
85
	/*
86
	 * (non-Javadoc)
87
	 * 
88
	 * @see org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(org.eclipse.swt.dnd.TransferData)
89
	 */
90
	protected Object nativeToJava(TransferData transferData) {
91
        Object result = super.nativeToJava(transferData);
92
        if (!(result instanceof byte[])
93
                || !LOCAL_NAME.equals(new String((byte[]) result)))
94
        	return null ;
95
		return fObject ;
96
	}
97
}

Return to bug 69581