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