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

Collapse All | Expand All

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

Return to bug 69581