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

Return to bug 69581