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

Collapse All | Expand All

(-)Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties (+5 lines)
Lines 41-43 Link Here
41
AntAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
41
AntAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
42
42
43
AntEditor.3=Current text selection does not resolve to an Ant reference
43
AntEditor.3=Current text selection does not resolve to an Ant reference
44
45
Editor.Paste.label=&Paste
46
Editor.Paste.tooltip=Paste
47
Editor.Paste.image=
48
Editor.Paste.description=Paste
(-)Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditor.java (-1 / +70 lines)
Lines 34-39 Link Here
34
import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter;
34
import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter;
35
import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction;
35
import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction;
36
import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage;
36
import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage;
37
import org.eclipse.ant.internal.ui.editor.templates.AntTemplatesPage;
37
import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider;
38
import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider;
38
import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider;
39
import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider;
39
import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant;
40
import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant;
Lines 71-76 Link Here
71
import org.eclipse.jface.text.ISelectionValidator;
72
import org.eclipse.jface.text.ISelectionValidator;
72
import org.eclipse.jface.text.ISynchronizable;
73
import org.eclipse.jface.text.ISynchronizable;
73
import org.eclipse.jface.text.ITextInputListener;
74
import org.eclipse.jface.text.ITextInputListener;
75
import org.eclipse.jface.text.ITextOperationTarget;
74
import org.eclipse.jface.text.ITextSelection;
76
import org.eclipse.jface.text.ITextSelection;
75
import org.eclipse.jface.text.ITextViewer;
77
import org.eclipse.jface.text.ITextViewer;
76
import org.eclipse.jface.text.Position;
78
import org.eclipse.jface.text.Position;
Lines 85-90 Link Here
85
import org.eclipse.jface.text.source.projection.IProjectionListener;
87
import org.eclipse.jface.text.source.projection.IProjectionListener;
86
import org.eclipse.jface.text.source.projection.ProjectionSupport;
88
import org.eclipse.jface.text.source.projection.ProjectionSupport;
87
import org.eclipse.jface.text.source.projection.ProjectionViewer;
89
import org.eclipse.jface.text.source.projection.ProjectionViewer;
90
import org.eclipse.jface.text.templates.Template;
88
import org.eclipse.jface.util.PropertyChangeEvent;
91
import org.eclipse.jface.util.PropertyChangeEvent;
89
import org.eclipse.jface.viewers.IPostSelectionProvider;
92
import org.eclipse.jface.viewers.IPostSelectionProvider;
90
import org.eclipse.jface.viewers.ISelection;
93
import org.eclipse.jface.viewers.ISelection;
Lines 93-98 Link Here
93
import org.eclipse.jface.viewers.IStructuredSelection;
96
import org.eclipse.jface.viewers.IStructuredSelection;
94
import org.eclipse.jface.viewers.SelectionChangedEvent;
97
import org.eclipse.jface.viewers.SelectionChangedEvent;
95
import org.eclipse.swt.custom.StyledText;
98
import org.eclipse.swt.custom.StyledText;
99
import org.eclipse.swt.dnd.Clipboard;
96
import org.eclipse.swt.events.ShellAdapter;
100
import org.eclipse.swt.events.ShellAdapter;
97
import org.eclipse.swt.events.ShellEvent;
101
import org.eclipse.swt.events.ShellEvent;
98
import org.eclipse.swt.graphics.Image;
102
import org.eclipse.swt.graphics.Image;
Lines 112-127 Link Here
112
import org.eclipse.ui.texteditor.ContentAssistAction;
116
import org.eclipse.ui.texteditor.ContentAssistAction;
113
import org.eclipse.ui.texteditor.IDocumentProvider;
117
import org.eclipse.ui.texteditor.IDocumentProvider;
114
import org.eclipse.ui.texteditor.IEditorStatusLine;
118
import org.eclipse.ui.texteditor.IEditorStatusLine;
119
import org.eclipse.ui.texteditor.ITextEditor;
115
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
120
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
116
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
121
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
122
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
123
import org.eclipse.ui.texteditor.TextEditorAction;
117
import org.eclipse.ui.texteditor.TextOperationAction;
124
import org.eclipse.ui.texteditor.TextOperationAction;
125
import org.eclipse.ui.texteditor.templates.TemplateTransfer;
118
import org.eclipse.ui.views.contentoutline.ContentOutline;
126
import org.eclipse.ui.views.contentoutline.ContentOutline;
119
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
127
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
128
import org.eclipse.ui.views.templates.ITemplatesPage;
120
129
121
/**
130
/**
122
 * The actual editor implementation for Eclipse's Ant integration.
131
 * The actual editor implementation for Eclipse's Ant integration.
123
 */
132
 */
124
public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener {
133
public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener {
134
135
	class ClipboardPasteOperation extends TextEditorAction {
136
		private ITextOperationTarget fOperationTarget;
137
		private int fOperationCode = -1;
138
139
		protected ClipboardPasteOperation(ResourceBundle bundle, String prefix, ITextEditor editor,
140
				int style) {
141
			super(bundle, prefix, editor, style);
142
		}
143
144
		public void run() {
145
			ITextEditor editor = getTextEditor();
146
			Clipboard clipboard = new Clipboard(getSite().getShell().getDisplay());
147
			Template[] templates = (Template[]) clipboard.getContents(TemplateTransfer
148
					.getInstance());
149
			if (templates != null) {
150
				AntTemplatesPage page = (AntTemplatesPage) editor.getAdapter(ITemplatesPage.class);
151
				page.insertTemplate(templates[0]);
152
			} else
153
				fOperationTarget.doOperation(fOperationCode);
154
		}
155
156
		/*
157
		 * (non-Javadoc)
158
		 * 
159
		 * @see org.eclipse.ui.texteditor.IUpdate#update()
160
		 */
161
		public void update() {
162
			super.update();
163
		}
164
165
	}
166
167
125
	/**
168
	/**
126
	 * Updates the Ant outline page selection and this editor's range indicator.
169
	 * Updates the Ant outline page selection and this editor's range indicator.
127
	 * 
170
	 * 
Lines 461-467 Link Here
461
     * The page that shows the outline.
504
     * The page that shows the outline.
462
     */
505
     */
463
    protected AntEditorContentOutlinePage fOutlinePage;
506
    protected AntEditorContentOutlinePage fOutlinePage;
464
    
507
	/**
508
	 * The templates page
509
	 */
510
	protected AntTemplatesPage fTemplatesPage;
465
	
511
	
466
	private boolean fInitialReconcile= true;
512
	private boolean fInitialReconcile= true;
467
	
513
	
Lines 538-543 Link Here
538
		action= new RenameInFileAction(this);
584
		action= new RenameInFileAction(this);
539
		action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$
585
		action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$
540
		setAction("renameInFile", action); //$NON-NLS-1$
586
		setAction("renameInFile", action); //$NON-NLS-1$
587
		
588
		// Override the TextEditor paste operation to support templates
589
		action = new ClipboardPasteOperation(bundle,
590
				"Editor.Paste.", this, ITextOperationTarget.PASTE); //$NON-NLS-1$
591
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
592
		setAction(ITextEditorActionConstants.PASTE, action);
541
    }
593
    }
542
594
543
	/*
595
	/*
Lines 564-569 Link Here
564
			return getOutlinePage();
616
			return getOutlinePage();
565
        }
617
        }
566
        
618
        
619
		if (key.equals(ITemplatesPage.class)) {
620
			return getTemplatesPage();
621
		}
622
567
        if (fProjectionSupport != null) { 
623
        if (fProjectionSupport != null) { 
568
        	Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key); 
624
        	Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key); 
569
        	if (adapter != null) {
625
        	if (adapter != null) {
Lines 599-604 Link Here
599
		return fOutlinePage;
655
		return fOutlinePage;
600
	}
656
	}
601
657
658
	private AntTemplatesPage getTemplatesPage() {
659
		if (fTemplatesPage == null) {
660
			fTemplatesPage = new AntTemplatesPage(this);
661
		}
662
		return fTemplatesPage;
663
	}
664
665
	protected void handleCursorPositionChanged() {
666
		super.handleCursorPositionChanged();
667
		if (fTemplatesPage != null)
668
			fTemplatesPage.cursorPositionChanged();
669
	}
670
602
    private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) {
671
    private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) {
603
        IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection();
672
        IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection();
604
673
(-)Ant (+186 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2005  John-Mason P. Shackelford 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
 * 	   John-Mason P. Shackelford - initial API and implementation
10
 *     IBM Corporation - bug fixes
11
 *******************************************************************************/
12
package org.eclipse.ant.internal.ui.editor.templates;
13
14
import org.eclipse.ant.internal.ui.AntUIPlugin;
15
import org.eclipse.ant.internal.ui.editor.AntEditor;
16
import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
17
import org.eclipse.ant.internal.ui.editor.formatter.XmlFormatter;
18
import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
19
import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
20
import org.eclipse.jface.resource.JFaceResources;
21
import org.eclipse.jface.text.Document;
22
import org.eclipse.jface.text.IDocument;
23
import org.eclipse.jface.text.IRegion;
24
import org.eclipse.jface.text.ITextSelection;
25
import org.eclipse.jface.text.Position;
26
import org.eclipse.jface.text.Region;
27
import org.eclipse.jface.text.source.ISourceViewer;
28
import org.eclipse.jface.text.source.SourceViewer;
29
import org.eclipse.jface.text.source.SourceViewerConfiguration;
30
import org.eclipse.jface.text.templates.ContextTypeRegistry;
31
import org.eclipse.jface.text.templates.Template;
32
import org.eclipse.jface.text.templates.TemplateContextType;
33
import org.eclipse.swt.SWT;
34
import org.eclipse.swt.graphics.Font;
35
import org.eclipse.swt.graphics.Point;
36
import org.eclipse.swt.widgets.Composite;
37
import org.eclipse.ui.PlatformUI;
38
import org.eclipse.ui.texteditor.templates.TemplatesPage;
39
40
/**
41
 * An implementation of TemplatesPage for AntEditor
42
 * 
43
 * @see TemplatesPage
44
 */
45
public class AntTemplatesPage extends TemplatesPage {
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
		fEditor = editor;
60
		setTemplateStore(AntTemplateAccess.getDefault().getTemplateStore(),
61
				AntUIPlugin.getDefault().getPreferenceStore());
62
		setContextTypeRegistry(CONTEXT_TYPE_REGISTRY);
63
		cursorPositionChanged();
64
		setupEditorDropTarget(fEditor.getSite(), fEditor.getViewer()
65
				.getTextWidget());
66
	}
67
68
	/*
69
	 * (non-Javadoc)
70
	 * 
71
	 * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#createViewer(org.eclipse.swt.widgets.Composite)
72
	 */
73
	protected SourceViewer createViewer(Composite parent) {
74
		SourceViewer viewer = new SourceViewer(parent, null, SWT.BORDER
75
				| SWT.V_SCROLL | SWT.H_SCROLL);
76
77
		SourceViewerConfiguration configuration = new AntTemplateViewerConfiguration();
78
		IDocument document = new Document();
79
		new AntDocumentSetupParticipant().setup(document);
80
		viewer.configure(configuration);
81
		viewer.setDocument(document);
82
		viewer.setEditable(false);
83
		Font font = JFaceResources.getFont(JFaceResources.TEXT_FONT);
84
		viewer.getTextWidget().setFont(font);
85
86
		return viewer;
87
	}
88
89
	/*
90
	 * (non-Javadoc)
91
	 * 
92
	 * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#getFormatterPreferenceKey()
93
	 */
94
	protected String getFormatterPreferenceKey() {
95
		return AntEditorPreferenceConstants.TEMPLATES_USE_CODEFORMATTER;
96
	}
97
98
	/*
99
	 * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#updateViewerInput()
100
	 */
101
	protected void updateViewerInput(Template template) {
102
		SourceViewer viewer = getViewer();
103
104
		if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(
105
				getFormatterPreferenceKey())) {
106
			String formatted = XmlFormatter.format(template.getPattern(),
107
					fFormattingPreferences);
108
			viewer.getDocument().set(formatted);
109
		} else {
110
			viewer.getDocument().set(template.getPattern());
111
		}
112
	}
113
114
	/*
115
	 * (non-Javadoc)
116
	 * 
117
	 * @see org.eclipse.ui.part.Page#setFocus()
118
	 */
119
	public void setFocus() {
120
	}
121
122
	/*
123
	 * (non-Javadoc)
124
	 * 
125
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId()
126
	 */
127
	protected String getPreferencePageId() {
128
		return "org.eclipse.ant.ui.TemplatesPreferencePage"; //$NON-NLS-1$
129
	}
130
131
	/*
132
	 * (non-Javadoc)
133
	 * 
134
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template)
135
	 */
136
	public void insertTemplate(Template template) {
137
		IRegion region;
138
		TemplateContextType type = CONTEXT_TYPE_REGISTRY
139
				.getContextType(template.getContextTypeId());
140
		if (type == null)
141
			return;
142
		ISourceViewer contextViewer = fEditor.getViewer();
143
		ITextSelection textSelection = (ITextSelection) contextViewer
144
				.getSelectionProvider().getSelection();
145
		region = new Region(textSelection.getOffset(), textSelection
146
				.getLength());
147
		Point selection = contextViewer.getSelectedRange();
148
		Position position;
149
		if (selection.y > 0) {
150
			position = new Position(selection.x, selection.y);
151
		} else {
152
			position = new Position(region.getOffset(), region.getLength());
153
		}
154
155
		IDocument document = contextViewer.getDocument();
156
		AntContext context = new AntContext(type, document, fEditor
157
				.getAntModel(), position);
158
		context.setVariable("selection", textSelection.getText()); //$NON-NLS-1$
159
		AntTemplateProposal proposal = new AntTemplateProposal(template,
160
				context, region, null, 100);
161
		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
162
				.activate(fEditor);
163
		proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset());
164
	}
165
166
	/**
167
	 * Invoked by the editor whenever the caret position is updated
168
	 */
169
	public void cursorPositionChanged() {
170
		String id;
171
		if (fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput())
172
				.getLength() == 0)
173
			id = BuildFileContextType.BUILDFILE_CONTEXT_TYPE;
174
		else
175
			id = TargetContextType.TARGET_CONTEXT_TYPE;
176
		if (id.equals(fCurrentId))
177
			return;
178
		fCurrentId = id;
179
		if (fCurrentId.equals(BuildFileContextType.BUILDFILE_CONTEXT_TYPE))
180
			contextTypeChanged(new String[] { BuildFileContextType.BUILDFILE_CONTEXT_TYPE });
181
		else
182
			contextTypeChanged(new String[] {
183
					TargetContextType.TARGET_CONTEXT_TYPE,
184
					TaskContextType.TASK_CONTEXT_TYPE });
185
	}
186
}
(-)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)"
(-)plugin.properties (-1 / +1 lines)
Lines 13-16 Link Here
13
13
14
Views.PropertySheet = Properties
14
Views.PropertySheet = Properties
15
Views.ContentOutline = Outline
15
Views.ContentOutline = Outline
16
16
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>
(-)icons/full/eview16/templates.gif (+2 lines)
Added Link Here
1
GIF89aæûwyômqåU_ì`gàNY÷øüö÷ûøùüôöû‰•­‰•¬òõûöøüûüþúûýùúüøùûˆ•­‰–­ˆ•¬ìñú2]ˆ–­ˆ–¬‰–¬Œ˜«çîùíòúòõúo¹™§ÅÑããìùðôúöøûh‰·hŠ¶ô÷û\„´]ƒ³äíøéðùòöûñõúP}°P}¯”œ¥Bv«Cw«øúüüýþûüý+k¤+j£,j¤,k¤,j£,k£6p§7q§+k£˜Ÿ¢‹S1•^T¦o¢žz·‚Ç‘´Ò£¥›¨¨—­«”ÞÝÔ¹³‹µ°Ž¿¶ˆ¼´‰²­’ÿÿÿÿÿÿÿ!ùP,¡€P‚ƒ„…ƒKˆ‰ŠK…LL…I1—1™I…J—2"¤J…M%3
2
%%%M…G*¶¶*H…F!ÁǃE$O͑#ƒA'"N&ƒ=),ϑ-ƒ.0">DCB@?/ƒ(:ûù+;ƒ2€ÀqƒG6hðà‘£Æ 	,L˜!‚‹i4;
(-)src/org/eclipse/ui/internal/views/templates/TemplatesMessages.java (+21 lines)
Added Link Here
1
package org.eclipse.ui.internal.views.templates;
2
3
import org.eclipse.osgi.util.NLS;
4
5
/**
6
 * TemplatesMessages is the message class for the messages used in the templates view.
7
 *
8
 */
9
public class TemplatesMessages extends NLS {
10
	private static final String BUNDLE_NAME = "org.eclipse.ui.internal.views.templates.TemplatesMessages"; //$NON-NLS-1$
11
	
12
	// Default message for an empty templates view
13
	public static String Templates_defaultMessage;
14
	static {
15
		// initialize resource bundle
16
		NLS.initializeMessages(BUNDLE_NAME, TemplatesMessages.class);
17
	}
18
19
	private TemplatesMessages() {
20
	}
21
}
(-)src/org/eclipse/ui/internal/views/templates/TemplatesMessages.properties (+1 lines)
Added Link Here
1
Templates_defaultMessage=No templates available for this editor
(-)src/org/eclipse/ui/views/templates/Templates.java (+183 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation 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
 *     IBM Corporation - 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
public class Templates extends PageBookView {
60
    /**
61
     * The plugin prefix.
62
     */
63
    public static final String PREFIX = PlatformUI.PLUGIN_ID + "."; //$NON-NLS-1$
64
65
    /**
66
     * Help context id used for the content outline view
67
     * (value <code>"org.eclipse.ui.content_outline_context"</code>).
68
     */
69
    public static final String TEMPLATES_VIEW_HELP_CONTEXT_ID = PREFIX
70
            + "templates_view_context";//$NON-NLS-1$
71
72
    /**
73
     * Message to show on the default page.
74
     */
75
    private String defaultText = TemplatesMessages.Templates_defaultMessage; 
76
77
    /**
78
     * Creates a content outline view with no content outline pages.
79
     */
80
    public Templates() {
81
        super();
82
    }
83
84
    /* (non-Javadoc)
85
     * Method declared on PageBookView.
86
     */
87
    protected IPage createDefaultPage(PageBook book) {
88
        MessagePage page = new MessagePage();
89
        initPage(page);
90
        page.createControl(book);
91
        page.setMessage(defaultText);
92
        return page;
93
    }
94
95
    /**
96
     * The <code>PageBookView</code> implementation of this <code>IWorkbenchPart</code>
97
     * method creates a <code>PageBook</code> control with its default page showing.
98
     */
99
    public void createPartControl(Composite parent) {
100
        super.createPartControl(parent);
101
        PlatformUI.getWorkbench().getHelpSystem().setHelp(getPageBook(),
102
                TEMPLATES_VIEW_HELP_CONTEXT_ID);
103
    }
104
105
    /* (non-Javadoc)
106
     * Method declared on PageBookView.
107
     */
108
    protected PageRec doCreatePage(IWorkbenchPart part) {
109
        // Try to get template page.
110
        Object obj = ViewsPlugin.getAdapter(part, ITemplatesPage.class, false);
111
        if (obj instanceof ITemplatesPage) {
112
            ITemplatesPage page = (ITemplatesPage) obj;
113
			initPage(page);
114
            page.createControl(getPageBook());
115
            return new PageRec(part, page);
116
        }
117
        // There is no template page
118
        return null;
119
    }
120
121
    /* (non-Javadoc)
122
     * Method declared on PageBookView.
123
     */
124
    protected void doDestroyPage(IWorkbenchPart part, PageRec rec) {
125
        ITemplatesPage page = (ITemplatesPage) rec.page;
126
        page.dispose();
127
        rec.dispose();
128
    }
129
130
    /* (non-Javadoc)
131
     * Method declared on IAdaptable.
132
     */
133
    public Object getAdapter(Class key) {
134
        if (key == IContributedContentsView.class) {
135
			return new IContributedContentsView() {
136
                public IWorkbenchPart getContributingPart() {
137
                    return getContributingEditor();
138
                }
139
            };
140
		}
141
        return super.getAdapter(key);
142
    }
143
144
    /* (non-Javadoc)
145
     * Method declared on PageBookView.
146
     */
147
    protected IWorkbenchPart getBootstrapPart() {
148
        IWorkbenchPage page = getSite().getPage();
149
        if (page != null) {
150
			return page.getActiveEditor();
151
		}
152
153
        return null;
154
    }
155
156
    /**
157
     * Returns the editor which contributed the current 
158
     * page to this view.
159
     *
160
     * @return the editor which contributed the current page
161
     * or <code>null</code> if no editor contributed the current page
162
     */
163
    private IWorkbenchPart getContributingEditor() {
164
        return getCurrentContributingPart();
165
    }
166
167
    /* (non-Javadoc)
168
     * Method declared on PageBookView.
169
     * We only want to track editors.
170
     */
171
    protected boolean isImportant(IWorkbenchPart part) {
172
        //We only care about editors
173
        return (part instanceof IEditorPart);
174
    }
175
176
    /* (non-Javadoc)
177
     * Method declared on IViewPart.
178
     * Treat this the same as part activation.
179
     */
180
    public void partBroughtToTop(IWorkbenchPart part) {
181
        partActivated(part);
182
    }
183
}
(-)src/org/eclipse/ui/views/templates/ITemplatesPage.java (+13 lines)
Added Link Here
1
package org.eclipse.ui.views.templates;
2
3
import org.eclipse.ui.part.IPageBookViewPage;
4
5
/**
6
 * Interface for a template page. This interface defines
7
 * the minimum requirement for pages within the templates view, namely
8
 * they must be pages (implement <code>IPageBookViewPage</code>).
9
 *
10
 * @see TemplatesView
11
 */
12
public interface ITemplatesPage extends IPageBookViewPage {
13
}
(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 25-31 Link Here
25
 org.eclipse.core.expressions;bundle-version="[3.2.0,4.0.0)",
25
 org.eclipse.core.expressions;bundle-version="[3.2.0,4.0.0)",
26
 org.eclipse.jface.text;bundle-version="[3.4.0,4.0.0)",
26
 org.eclipse.jface.text;bundle-version="[3.4.0,4.0.0)",
27
 org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)",
27
 org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)",
28
 org.eclipse.ui;bundle-version="[3.3.0,4.0.0)"
28
 org.eclipse.ui;bundle-version="[3.3.0,4.0.0)",
29
 org.eclipse.ui.views
29
Eclipse-LazyStart: true
30
Eclipse-LazyStart: true
30
Bundle-RequiredExecutionEnvironment: J2SE-1.4
31
Bundle-RequiredExecutionEnvironment: J2SE-1.4
31
Import-Package: com.ibm.icu.text
32
Import-Package: com.ibm.icu.text
(-)src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java (-1 / +24 lines)
Lines 20-30 Link Here
20
final class TextEditorTemplateMessages extends NLS {
20
final class TextEditorTemplateMessages extends NLS {
21
21
22
	private static final String BUNDLE_NAME= TextEditorTemplateMessages.class.getName();
22
	private static final String BUNDLE_NAME= TextEditorTemplateMessages.class.getName();
23
24
	private TextEditorTemplateMessages() {
23
	private TextEditorTemplateMessages() {
25
		// Do not instantiate
24
		// Do not instantiate
26
	}
25
	}
27
26
27
	// TemplatesView
28
	public static String TemplatesPage_collapse_expand;
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_paste_description;
35
	public static String TemplatesPage_preference_page;
36
	public static String TemplatesPage_link_to_editor;
37
	public static String TemplatesPage_new;
38
	public static String TemplatesPage_preview;
39
	public static String TemplatesPage_question_create_new_message;
40
	public static String TemplatesPage_question_create_new_title;
41
	public static String TemplatesPage_remove;
42
	public static String TemplatesPage_save_error_message;
43
	public static String TemplatesPage_snippet;
44
	public static String TemplatesPage_show_disabled;
45
	public static String TemplatesPage_show_new_dialog;
46
	public static String TemplatesPage_context_description;
47
	public static String TemplatesPage_remove_message;
48
	public static String TemplatesPage_remove_title;
49
50
	// TemplatePreferencePage
28
	public static String TemplatePreferencePage_error_import;
51
	public static String TemplatePreferencePage_error_import;
29
	public static String TemplatePreferencePage_error_export;
52
	public static String TemplatePreferencePage_error_export;
30
	public static String TemplatePreferencePage_error_read_title;
53
	public static String TemplatePreferencePage_error_read_title;
(-)src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties (+23 lines)
Lines 9-14 Link Here
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
###############################################################################
10
###############################################################################
11
11
12
# templates page (view)
13
TemplatesPage_collapse_expand=Collapse or Expand
14
TemplatesPage_column_context=Context
15
TemplatesPage_column_description=Description
16
TemplatesPage_save_error_message=Error Saving the Templates
17
TemplatesPage_column_name=Name
18
TemplatesPage_edit=&Edit...
19
TemplatesPage_insert=&Insert...
20
TemplatesPage_preference_page=&Preference Page...
21
TemplatesPage_paste_description=Pasted from editor
22
TemplatesPage_link_to_editor=Link to Editor
23
TemplatesPage_new=&New...
24
TemplatesPage_preview=Previe&w:
25
TemplatesPage_snippet=snippet
26
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.
27
TemplatesPage_context_description=Context
28
TemplatesPage_remove_title=Removing Templates
29
TemplatesPage_remove_message=Are you sure you want to remove the selected templates?
30
TemplatesPage_question_create_new_title= Edit Template
31
TemplatesPage_remove=&Remove
32
TemplatesPage_show_disabled=&Show Disabled
33
TemplatesPage_show_new_dialog=S&how New Dialog on Drop
34
12
# preference page
35
# preference page
13
TemplatePreferencePage_error_import=Failed to import templates.
36
TemplatePreferencePage_error_import=Failed to import templates.
14
TemplatePreferencePage_error_export=Failed to export templates.
37
TemplatePreferencePage_error_export=Failed to export templates.
(-)src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java (-577 lines)
Lines 16-54 Link Here
16
import java.io.InputStream;
16
import java.io.InputStream;
17
import java.io.OutputStream;
17
import java.io.OutputStream;
18
import java.util.ArrayList;
18
import java.util.ArrayList;
19
import java.util.HashMap;
20
import java.util.Iterator;
19
import java.util.Iterator;
21
import java.util.List;
20
import java.util.List;
22
import java.util.Map;
23
21
24
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.SWT;
25
import org.eclipse.swt.custom.StyledText;
26
import org.eclipse.swt.custom.VerifyKeyListener;
27
import org.eclipse.swt.events.FocusEvent;
28
import org.eclipse.swt.events.FocusListener;
29
import org.eclipse.swt.events.ModifyEvent;
30
import org.eclipse.swt.events.ModifyListener;
31
import org.eclipse.swt.events.SelectionEvent;
32
import org.eclipse.swt.events.SelectionListener;
33
import org.eclipse.swt.events.VerifyEvent;
34
import org.eclipse.swt.graphics.GC;
23
import org.eclipse.swt.graphics.GC;
35
import org.eclipse.swt.graphics.Image;
24
import org.eclipse.swt.graphics.Image;
36
import org.eclipse.swt.layout.GridData;
25
import org.eclipse.swt.layout.GridData;
37
import org.eclipse.swt.layout.GridLayout;
26
import org.eclipse.swt.layout.GridLayout;
38
import org.eclipse.swt.widgets.Button;
27
import org.eclipse.swt.widgets.Button;
39
import org.eclipse.swt.widgets.Combo;
40
import org.eclipse.swt.widgets.Composite;
28
import org.eclipse.swt.widgets.Composite;
41
import org.eclipse.swt.widgets.Control;
29
import org.eclipse.swt.widgets.Control;
42
import org.eclipse.swt.widgets.Event;
30
import org.eclipse.swt.widgets.Event;
43
import org.eclipse.swt.widgets.FileDialog;
31
import org.eclipse.swt.widgets.FileDialog;
44
import org.eclipse.swt.widgets.Label;
32
import org.eclipse.swt.widgets.Label;
45
import org.eclipse.swt.widgets.Listener;
33
import org.eclipse.swt.widgets.Listener;
46
import org.eclipse.swt.widgets.Menu;
47
import org.eclipse.swt.widgets.Shell;
48
import org.eclipse.swt.widgets.Table;
34
import org.eclipse.swt.widgets.Table;
49
import org.eclipse.swt.widgets.TableColumn;
35
import org.eclipse.swt.widgets.TableColumn;
50
import org.eclipse.swt.widgets.Text;
51
import org.eclipse.swt.widgets.Widget;
52
36
53
import org.eclipse.core.filesystem.EFS;
37
import org.eclipse.core.filesystem.EFS;
54
import org.eclipse.core.filesystem.IFileInfo;
38
import org.eclipse.core.filesystem.IFileInfo;
Lines 57-73 Link Here
57
import org.eclipse.core.runtime.CoreException;
41
import org.eclipse.core.runtime.CoreException;
58
import org.eclipse.core.runtime.Path;
42
import org.eclipse.core.runtime.Path;
59
43
60
import org.eclipse.jface.action.Action;
61
import org.eclipse.jface.action.GroupMarker;
62
import org.eclipse.jface.action.IAction;
63
import org.eclipse.jface.action.IMenuListener;
64
import org.eclipse.jface.action.IMenuManager;
65
import org.eclipse.jface.action.MenuManager;
66
import org.eclipse.jface.action.Separator;
67
import org.eclipse.jface.dialogs.Dialog;
44
import org.eclipse.jface.dialogs.Dialog;
68
import org.eclipse.jface.dialogs.IDialogSettings;
69
import org.eclipse.jface.dialogs.MessageDialog;
45
import org.eclipse.jface.dialogs.MessageDialog;
70
import org.eclipse.jface.dialogs.StatusDialog;
71
import org.eclipse.jface.preference.IPreferenceStore;
46
import org.eclipse.jface.preference.IPreferenceStore;
72
import org.eclipse.jface.preference.PreferencePage;
47
import org.eclipse.jface.preference.PreferencePage;
73
import org.eclipse.jface.resource.JFaceResources;
48
import org.eclipse.jface.resource.JFaceResources;
Lines 91-110 Link Here
91
66
92
import org.eclipse.jface.text.Document;
67
import org.eclipse.jface.text.Document;
93
import org.eclipse.jface.text.IDocument;
68
import org.eclipse.jface.text.IDocument;
94
import org.eclipse.jface.text.ITextListener;
95
import org.eclipse.jface.text.ITextOperationTarget;
96
import org.eclipse.jface.text.ITextViewer;
97
import org.eclipse.jface.text.TextEvent;
98
import org.eclipse.jface.text.contentassist.ContentAssistant;
99
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
100
import org.eclipse.jface.text.contentassist.IContentAssistant;
101
import org.eclipse.jface.text.source.ISourceViewer;
102
import org.eclipse.jface.text.source.SourceViewer;
69
import org.eclipse.jface.text.source.SourceViewer;
103
import org.eclipse.jface.text.source.SourceViewerConfiguration;
70
import org.eclipse.jface.text.source.SourceViewerConfiguration;
104
import org.eclipse.jface.text.templates.ContextTypeRegistry;
71
import org.eclipse.jface.text.templates.ContextTypeRegistry;
105
import org.eclipse.jface.text.templates.Template;
72
import org.eclipse.jface.text.templates.Template;
106
import org.eclipse.jface.text.templates.TemplateContextType;
73
import org.eclipse.jface.text.templates.TemplateContextType;
107
import org.eclipse.jface.text.templates.TemplateException;
108
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
74
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
109
import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
75
import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
110
import org.eclipse.jface.text.templates.persistence.TemplateStore;
76
import org.eclipse.jface.text.templates.persistence.TemplateStore;
Lines 112-120 Link Here
112
import org.eclipse.ui.IWorkbench;
78
import org.eclipse.ui.IWorkbench;
113
import org.eclipse.ui.IWorkbenchPreferencePage;
79
import org.eclipse.ui.IWorkbenchPreferencePage;
114
import org.eclipse.ui.internal.texteditor.NLSUtility;
80
import org.eclipse.ui.internal.texteditor.NLSUtility;
115
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
116
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
117
import org.eclipse.ui.texteditor.IUpdate;
118
81
119
/**
82
/**
120
 * A template preference page allows configuration of the templates for an
83
 * A template preference page allows configuration of the templates for an
Lines 132-677 Link Here
132
95
133
	
96
	
134
	/**
97
	/**
135
	 * Dialog to edit a template. Clients will usually instantiate, but
136
	 * may also extend.
137
	 *
138
	 * @since 3.3
139
	 */
140
	protected static class EditTemplateDialog extends StatusDialog {
141
142
		private class TextViewerAction extends Action implements IUpdate {
143
144
			private int fOperationCode= -1;
145
			private ITextOperationTarget fOperationTarget;
146
147
			/**
148
			 * Creates a new action.
149
			 *
150
			 * @param viewer the viewer
151
			 * @param operationCode the opcode
152
			 */
153
			public TextViewerAction(ITextViewer viewer, int operationCode) {
154
				fOperationCode= operationCode;
155
				fOperationTarget= viewer.getTextOperationTarget();
156
				update();
157
			}
158
159
			/**
160
			 * Updates the enabled state of the action.
161
			 * Fires a property change if the enabled state changes.
162
			 *
163
			 * @see Action#firePropertyChange(String, Object, Object)
164
			 */
165
			public void update() {
166
167
				boolean wasEnabled= isEnabled();
168
				boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
169
				setEnabled(isEnabled);
170
171
				if (wasEnabled != isEnabled) {
172
					firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE);
173
				}
174
			}
175
176
			/**
177
			 * @see Action#run()
178
			 */
179
			public void run() {
180
				if (fOperationCode != -1 && fOperationTarget != null) {
181
					fOperationTarget.doOperation(fOperationCode);
182
				}
183
			}
184
		}
185
186
		private final Template fOriginalTemplate;
187
188
		private Text fNameText;
189
		private Text fDescriptionText;
190
		private Combo fContextCombo;
191
		private SourceViewer fPatternEditor;
192
		private Button fInsertVariableButton;
193
		private Button fAutoInsertCheckbox;
194
		private boolean fIsNameModifiable;
195
196
		private StatusInfo fValidationStatus;
197
		private boolean fSuppressError= true; // #4354
198
		private Map fGlobalActions= new HashMap(10);
199
		private List fSelectionActions = new ArrayList(3);
200
		private String[][] fContextTypes;
201
202
		private ContextTypeRegistry fContextTypeRegistry;
203
204
		private final TemplateVariableProcessor fTemplateProcessor= new TemplateVariableProcessor();
205
206
		private Template fNewTemplate;
207
208
		/**
209
		 * Creates a new dialog.
210
		 *
211
		 * @param parent the shell parent of the dialog
212
		 * @param template the template to edit
213
		 * @param edit whether this is a new template or an existing being edited
214
		 * @param isNameModifiable whether the name of the template may be modified
215
		 * @param registry the context type registry to use
216
		 */
217
		public EditTemplateDialog(Shell parent, Template template, boolean edit, boolean isNameModifiable, ContextTypeRegistry registry) {
218
			super(parent);
219
220
			setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
221
222
			String title= edit
223
				? TextEditorTemplateMessages.EditTemplateDialog_title_edit
224
				: TextEditorTemplateMessages.EditTemplateDialog_title_new;
225
			setTitle(title);
226
227
			fOriginalTemplate= template;
228
			fIsNameModifiable= isNameModifiable;
229
230
			List contexts= new ArrayList();
231
			for (Iterator it= registry.contextTypes(); it.hasNext();) {
232
				TemplateContextType type= (TemplateContextType) it.next();
233
				contexts.add(new String[] { type.getId(), type.getName() });
234
			}
235
			fContextTypes= (String[][]) contexts.toArray(new String[contexts.size()][]);
236
237
			fValidationStatus= new StatusInfo();
238
239
			fContextTypeRegistry= registry;
240
241
			TemplateContextType type= fContextTypeRegistry.getContextType(template.getContextTypeId());
242
			fTemplateProcessor.setContextType(type);
243
		}
244
245
		/*
246
		 * @see org.eclipse.ui.texteditor.templates.StatusDialog#create()
247
		 */
248
		public void create() {
249
			super.create();
250
			// update initial OK button to be disabled for new templates
251
			boolean valid= fNameText == null || fNameText.getText().trim().length() != 0;
252
			if (!valid) {
253
				StatusInfo status = new StatusInfo();
254
				status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname);
255
				updateButtonsEnableState(status);
256
	 		}
257
		}
258
259
		/*
260
		 * @see Dialog#createDialogArea(Composite)
261
		 */
262
		protected Control createDialogArea(Composite ancestor) {
263
			Composite parent= new Composite(ancestor, SWT.NONE);
264
			GridLayout layout= new GridLayout();
265
			layout.numColumns= 2;
266
			parent.setLayout(layout);
267
			parent.setLayoutData(new GridData(GridData.FILL_BOTH));
268
269
			ModifyListener listener= new ModifyListener() {
270
				public void modifyText(ModifyEvent e) {
271
					doTextWidgetChanged(e.widget);
272
				}
273
			};
274
275
			if (fIsNameModifiable) {
276
				createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_name);
277
278
				Composite composite= new Composite(parent, SWT.NONE);
279
				composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
280
				layout= new GridLayout();
281
				layout.numColumns= 4;
282
				layout.marginWidth= 0;
283
				layout.marginHeight= 0;
284
				composite.setLayout(layout);
285
286
				fNameText= createText(composite);
287
				fNameText.addModifyListener(listener);
288
				fNameText.addFocusListener(new FocusListener() {
289
290
					public void focusGained(FocusEvent e) {
291
					}
292
293
					public void focusLost(FocusEvent e) {
294
						if (fSuppressError) {
295
							fSuppressError= false;
296
							updateButtons();
297
						}
298
					}
299
				});
300
301
				createLabel(composite, TextEditorTemplateMessages.EditTemplateDialog_context);
302
				fContextCombo= new Combo(composite, SWT.READ_ONLY);
303
304
				for (int i= 0; i < fContextTypes.length; i++) {
305
					fContextCombo.add(fContextTypes[i][1]);
306
				}
307
308
				fContextCombo.addModifyListener(listener);
309
				
310
				fAutoInsertCheckbox= createCheckbox(composite, TextEditorTemplateMessages.EditTemplateDialog_autoinsert);
311
				fAutoInsertCheckbox.setSelection(fOriginalTemplate.isAutoInsertable());
312
			}
313
314
			createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_description);
315
316
			int descFlags= fIsNameModifiable ? SWT.BORDER : SWT.BORDER | SWT.READ_ONLY;
317
			fDescriptionText= new Text(parent, descFlags );
318
			fDescriptionText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
319
320
			fDescriptionText.addModifyListener(listener);
321
322
			Label patternLabel= createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_pattern);
323
			patternLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
324
			fPatternEditor= createEditor(parent, fOriginalTemplate.getPattern());
325
326
			Label filler= new Label(parent, SWT.NONE);
327
			filler.setLayoutData(new GridData());
328
329
			Composite composite= new Composite(parent, SWT.NONE);
330
			layout= new GridLayout();
331
			layout.marginWidth= 0;
332
			layout.marginHeight= 0;
333
			composite.setLayout(layout);
334
			composite.setLayoutData(new GridData());
335
336
			fInsertVariableButton= new Button(composite, SWT.NONE);
337
			fInsertVariableButton.setLayoutData(getButtonGridData(fInsertVariableButton));
338
			fInsertVariableButton.setText(TextEditorTemplateMessages.EditTemplateDialog_insert_variable);
339
			fInsertVariableButton.addSelectionListener(new SelectionListener() {
340
				public void widgetSelected(SelectionEvent e) {
341
					fPatternEditor.getTextWidget().setFocus();
342
					fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
343
				}
344
345
				public void widgetDefaultSelected(SelectionEvent e) {}
346
			});
347
348
			fDescriptionText.setText(fOriginalTemplate.getDescription());
349
			if (fIsNameModifiable) {
350
				fNameText.setText(fOriginalTemplate.getName());
351
				fNameText.addModifyListener(listener);
352
				fContextCombo.select(getIndex(fOriginalTemplate.getContextTypeId()));
353
			} else {
354
				fPatternEditor.getControl().setFocus();
355
			}
356
			initializeActions();
357
358
			applyDialogFont(parent);
359
			return composite;
360
		}
361
362
		private void doTextWidgetChanged(Widget w) {
363
			if (w == fNameText) {
364
				fSuppressError= false;
365
				updateButtons();
366
			} else if (w == fContextCombo) {
367
				String contextId= getContextId();
368
				fTemplateProcessor.setContextType(fContextTypeRegistry.getContextType(contextId));
369
			} else if (w == fDescriptionText) {
370
				// oh, nothing
371
			}
372
		}
373
374
		private String getContextId() {
375
			if (fContextCombo != null && !fContextCombo.isDisposed()) {
376
				String name= fContextCombo.getText();
377
				for (int i= 0; i < fContextTypes.length; i++) {
378
					if (name.equals(fContextTypes[i][1])) {
379
						return fContextTypes[i][0];
380
					}
381
				}
382
			}
383
384
			return fOriginalTemplate.getContextTypeId();
385
		}
386
387
		private void doSourceChanged(IDocument document) {
388
			String text= document.get();
389
			fValidationStatus.setOK();
390
			TemplateContextType contextType= fContextTypeRegistry.getContextType(getContextId());
391
			if (contextType != null) {
392
				try {
393
					contextType.validate(text);
394
				} catch (TemplateException e) {
395
					fValidationStatus.setError(e.getLocalizedMessage());
396
				}
397
			}
398
399
			updateUndoAction();
400
			updateButtons();
401
		}
402
403
		private static GridData getButtonGridData(Button button) {
404
			GridData data= new GridData(GridData.FILL_HORIZONTAL);
405
			// TODO get some button hints.
406
//			data.heightHint= SWTUtil.getButtonHeightHint(button);
407
408
			return data;
409
		}
410
411
		private static Label createLabel(Composite parent, String name) {
412
			Label label= new Label(parent, SWT.NULL);
413
			label.setText(name);
414
			label.setLayoutData(new GridData());
415
416
			return label;
417
		}
418
419
		private static Text createText(Composite parent) {
420
			Text text= new Text(parent, SWT.BORDER);
421
			text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
422
423
			return text;
424
		}
425
426
		private static Button createCheckbox(Composite parent, String name) {
427
			Button button= new Button(parent, SWT.CHECK);
428
			button.setText(name);
429
			button.setLayoutData(new GridData());
430
			
431
			return button;
432
		}
433
		
434
		private SourceViewer createEditor(Composite parent, String pattern) {
435
			SourceViewer viewer= createViewer(parent);
436
			viewer.setEditable(true);
437
			
438
			IDocument document= viewer.getDocument();
439
			if (document != null)
440
				document.set(pattern);
441
			else {
442
				document= new Document(pattern);
443
				viewer.setDocument(document);
444
			}
445
446
			int nLines= document.getNumberOfLines();
447
			if (nLines < 5) {
448
				nLines= 5;
449
			} else if (nLines > 12) {
450
				nLines= 12;
451
			}
452
453
			Control control= viewer.getControl();
454
			GridData data= new GridData(GridData.FILL_BOTH);
455
			data.widthHint= convertWidthInCharsToPixels(80);
456
			data.heightHint= convertHeightInCharsToPixels(nLines);
457
			control.setLayoutData(data);
458
459
			viewer.addTextListener(new ITextListener() {
460
				public void textChanged(TextEvent event) {
461
					if (event .getDocumentEvent() != null)
462
						doSourceChanged(event.getDocumentEvent().getDocument());
463
				}
464
			});
465
466
			viewer.addSelectionChangedListener(new ISelectionChangedListener() {
467
				public void selectionChanged(SelectionChangedEvent event) {
468
					updateSelectionDependentActions();
469
				}
470
			});
471
472
		 	viewer.prependVerifyKeyListener(new VerifyKeyListener() {
473
				public void verifyKey(VerifyEvent event) {
474
					handleVerifyKeyPressed(event);
475
				}
476
			});
477
478
			return viewer;
479
		}
480
481
		/**
482
		 * Creates the viewer to be used to display the pattern. Subclasses may override.
483
		 *
484
		 * @param parent the parent composite of the viewer
485
		 * @return a configured <code>SourceViewer</code>
486
		 */
487
		protected SourceViewer createViewer(Composite parent) {
488
			SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
489
			SourceViewerConfiguration configuration= new SourceViewerConfiguration() {
490
				public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
491
492
					ContentAssistant assistant= new ContentAssistant();
493
					assistant.enableAutoActivation(true);
494
					assistant.enableAutoInsert(true);
495
					assistant.setContentAssistProcessor(fTemplateProcessor, IDocument.DEFAULT_CONTENT_TYPE);
496
					return assistant;
497
				}
498
			};
499
			viewer.configure(configuration);
500
			return viewer;
501
		}
502
503
		private void handleVerifyKeyPressed(VerifyEvent event) {
504
			if (!event.doit)
505
				return;
506
507
			if (event.stateMask != SWT.MOD1)
508
				return;
509
510
			switch (event.character) {
511
				case ' ':
512
					fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
513
					event.doit= false;
514
					break;
515
516
				// CTRL-Z
517
				case 'z' - 'a' + 1:
518
					fPatternEditor.doOperation(ITextOperationTarget.UNDO);
519
					event.doit= false;
520
					break;
521
			}
522
		}
523
524
		private void initializeActions() {
525
			TextViewerAction action= new TextViewerAction(fPatternEditor, ITextOperationTarget.UNDO);
526
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_undo);
527
			fGlobalActions.put(ITextEditorActionConstants.UNDO, action);
528
529
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.CUT);
530
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_cut);
531
			fGlobalActions.put(ITextEditorActionConstants.CUT, action);
532
533
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.COPY);
534
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_copy);
535
			fGlobalActions.put(ITextEditorActionConstants.COPY, action);
536
537
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.PASTE);
538
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_paste);
539
			fGlobalActions.put(ITextEditorActionConstants.PASTE, action);
540
541
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.SELECT_ALL);
542
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_select_all);
543
			fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action);
544
545
			action= new TextViewerAction(fPatternEditor, ISourceViewer.CONTENTASSIST_PROPOSALS);
546
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_content_assist);
547
			fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$
548
549
			fSelectionActions.add(ITextEditorActionConstants.CUT);
550
			fSelectionActions.add(ITextEditorActionConstants.COPY);
551
			fSelectionActions.add(ITextEditorActionConstants.PASTE);
552
553
			// create context menu
554
			MenuManager manager= new MenuManager(null, null);
555
			manager.setRemoveAllWhenShown(true);
556
			manager.addMenuListener(new IMenuListener() {
557
				public void menuAboutToShow(IMenuManager mgr) {
558
					fillContextMenu(mgr);
559
				}
560
			});
561
562
			StyledText text= fPatternEditor.getTextWidget();
563
			Menu menu= manager.createContextMenu(text);
564
			text.setMenu(menu);
565
		}
566
567
		private void fillContextMenu(IMenuManager menu) {
568
			menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO));
569
			menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO));
570
571
			menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
572
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT));
573
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY));
574
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE));
575
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL));
576
577
			menu.add(new Separator("templates")); //$NON-NLS-1$
578
			menu.appendToGroup("templates", (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$ //$NON-NLS-2$
579
		}
580
581
		private void updateSelectionDependentActions() {
582
			Iterator iterator= fSelectionActions.iterator();
583
			while (iterator.hasNext())
584
				updateAction((String)iterator.next());
585
		}
586
587
		private void updateUndoAction() {
588
			IAction action= (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO);
589
			if (action instanceof IUpdate)
590
				((IUpdate) action).update();
591
		}
592
593
		private void updateAction(String actionId) {
594
			IAction action= (IAction) fGlobalActions.get(actionId);
595
			if (action instanceof IUpdate)
596
				((IUpdate) action).update();
597
		}
598
599
		private int getIndex(String contextid) {
600
601
			if (contextid == null)
602
				return -1;
603
604
			for (int i= 0; i < fContextTypes.length; i++) {
605
				if (contextid.equals(fContextTypes[i][0])) {
606
					return i;
607
				}
608
			}
609
			return -1;
610
		}
611
612
		private void updateButtons() {
613
			StatusInfo status;
614
615
			boolean valid= fNameText == null || fNameText.getText().trim().length() != 0;
616
			if (!valid) {
617
				status = new StatusInfo();
618
				if (!fSuppressError) {
619
					status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname);
620
				}
621
	 		} else {
622
	 			status= fValidationStatus;
623
	 		}
624
			updateStatus(status);
625
		}
626
627
		/*
628
		 * @since 3.1
629
		 */
630
		protected void okPressed() {
631
			String name= fNameText == null ? fOriginalTemplate.getName() : fNameText.getText();
632
			boolean isAutoInsertable= fAutoInsertCheckbox != null && fAutoInsertCheckbox.getSelection();
633
			fNewTemplate= new Template(name, fDescriptionText.getText(), getContextId(), fPatternEditor.getDocument().get(), isAutoInsertable);
634
			super.okPressed();
635
		}
636
637
		/**
638
		 * Returns the created template.
639
		 *
640
		 * @return the created template
641
		 * @since 3.1
642
		 */
643
		public Template getTemplate() {
644
			return fNewTemplate;
645
		}
646
		
647
		/**
648
		 * Returns the content assist processor that
649
		 * suggests template variables.
650
		 * 
651
		 * @return the processor to suggest variables
652
		 * @since 3.3
653
		 */
654
		protected IContentAssistProcessor getTemplateProcessor() {
655
			return fTemplateProcessor;
656
		}
657
658
		/*
659
		 * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
660
		 * @since 3.2
661
		 */
662
		protected IDialogSettings getDialogBoundsSettings() {
663
			String sectionName= getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
664
			IDialogSettings settings= TextEditorPlugin.getDefault().getDialogSettings();
665
			IDialogSettings section= settings.getSection(sectionName);
666
			if (section == null)
667
				section= settings.addNewSection(sectionName);
668
			return section;
669
		}
670
671
	}
672
	
673
	
674
	/**
675
	 * Label provider for templates.
98
	 * Label provider for templates.
676
	 */
99
	 */
677
	private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider {
100
	private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider {
(-)src/org/eclipse/ui/texteditor/templates/TemplatesPage.java (+1228 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 IBM Corporation 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
 *     IBM Corporation - 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.Dialog;
27
import org.eclipse.jface.dialogs.MessageDialog;
28
import org.eclipse.jface.layout.TreeColumnLayout;
29
import org.eclipse.jface.preference.IPreferenceStore;
30
import org.eclipse.jface.resource.JFaceResources;
31
import org.eclipse.jface.text.Document;
32
import org.eclipse.jface.text.IDocument;
33
import org.eclipse.jface.text.source.SourceViewer;
34
import org.eclipse.jface.text.source.SourceViewerConfiguration;
35
import org.eclipse.jface.text.templates.ContextTypeRegistry;
36
import org.eclipse.jface.text.templates.Template;
37
import org.eclipse.jface.text.templates.TemplateContextType;
38
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
39
import org.eclipse.jface.text.templates.persistence.TemplateStore;
40
import org.eclipse.jface.util.IPropertyChangeListener;
41
import org.eclipse.jface.util.PropertyChangeEvent;
42
import org.eclipse.jface.viewers.ColumnWeightData;
43
import org.eclipse.jface.viewers.DoubleClickEvent;
44
import org.eclipse.jface.viewers.IDoubleClickListener;
45
import org.eclipse.jface.viewers.ISelectionChangedListener;
46
import org.eclipse.jface.viewers.IStructuredSelection;
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.dnd.Clipboard;
58
import org.eclipse.swt.dnd.DND;
59
import org.eclipse.swt.dnd.DragSourceAdapter;
60
import org.eclipse.swt.dnd.DragSourceEvent;
61
import org.eclipse.swt.dnd.DropTargetAdapter;
62
import org.eclipse.swt.dnd.DropTargetEvent;
63
import org.eclipse.swt.dnd.TextTransfer;
64
import org.eclipse.swt.dnd.Transfer;
65
import org.eclipse.swt.graphics.Color;
66
import org.eclipse.swt.graphics.FontMetrics;
67
import org.eclipse.swt.graphics.GC;
68
import org.eclipse.swt.graphics.Image;
69
import org.eclipse.swt.layout.GridData;
70
import org.eclipse.swt.layout.GridLayout;
71
import org.eclipse.swt.widgets.Composite;
72
import org.eclipse.swt.widgets.Control;
73
import org.eclipse.swt.widgets.Label;
74
import org.eclipse.swt.widgets.Menu;
75
import org.eclipse.swt.widgets.Shell;
76
import org.eclipse.swt.widgets.Tree;
77
import org.eclipse.swt.widgets.TreeColumn;
78
import org.eclipse.swt.widgets.TreeItem;
79
import org.eclipse.ui.IActionBars;
80
import org.eclipse.ui.IWorkbenchActionConstants;
81
import org.eclipse.ui.IWorkbenchPartSite;
82
import org.eclipse.ui.actions.ActionFactory;
83
import org.eclipse.ui.dialogs.PreferencesUtil;
84
import org.eclipse.ui.dnd.IDragAndDropService;
85
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
86
import org.eclipse.ui.part.Page;
87
import org.eclipse.ui.views.templates.ITemplatesPage;
88
89
/**
90
 * An abstract base class for template pages for use with TextEditor.
91
 * <p>
92
 * Clients who are defining an editor may elect to provide a corresponding
93
 * templates page. This templates page will be presented to the user via the
94
 * Templates View (the user decides whether their workbench window contains this
95
 * view) whenever that editor is active. This class should be subclassed.
96
 * </p>
97
 * <p>
98
 * Internally, a TemplatesPage uses the template store to display different
99
 * categories. A link to editor mode on the templates page allows to filtering
100
 * of the categories to only that are supported in this context.
101
 * </p>
102
 * Since: 3.4
103
 */
104
public abstract class TemplatesPage extends Page implements ITemplatesPage {
105
106
	/**
107
	 * Link to editor action setting
108
	 */
109
	private static final String LINK_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
110
			+ ".templates.templatesPage.linkAction"; //$NON-NLS-1$
111
	/**
112
	 * Show disabled actions setting
113
	 */
114
	private static final String SHOW_DISABLED_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
115
			+ ".templates.templatesPage.showDisabledAction"; //$NON-NLS-1$
116
	/**
117
	 * Show new dialog on drop setting
118
	 */
119
	private static final String SHOW_NEW_DIALOG_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID
120
			+ ".templates.templatesPage.showNewDialogAction"; //$NON-NLS-1$;
121
122
	/**
123
	 * The ID for the popup menu for this templates page
124
	 */
125
	private static final String POPUP_MENU_ID = "org.eclipse.ui.texteditor.templates.PopupMenu"; //$NON-NLS-1$
126
127
	/**
128
	 * Drop support for the editor linked to this page. When a user drops a
129
	 * template into the active editor, the template is applied at the drop
130
	 * position.
131
	 */
132
	private final class EditorDropTarget extends DropTargetAdapter {
133
		/*
134
		 * (non-Javadoc)
135
		 * 
136
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
137
		 */
138
		public void dragEnter(DropTargetEvent event) {
139
			super.dragEnter(event);
140
			if (event.detail == DND.DROP_DEFAULT)
141
				event.detail = DND.DROP_COPY;
142
		}
143
144
		/*
145
		 * (non-Javadoc)
146
		 * 
147
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
148
		 */
149
		public void dragOperationChanged(DropTargetEvent event) {
150
			if (event.detail == DND.DROP_DEFAULT)
151
				event.detail = DND.DROP_COPY;
152
		}
153
154
		/*
155
		 * (non-Javadoc)
156
		 * 
157
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
158
		 */
159
		public void dragOver(DropTargetEvent event) {
160
			event.feedback |= DND.FEEDBACK_SCROLL;
161
		}
162
163
		/*
164
		 * (non-Javadoc)
165
		 * 
166
		 * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
167
		 */
168
		public void drop(DropTargetEvent event) {
169
			insertTemplate(getSelectedTemplate());
170
		}
171
	}
172
173
	/**
174
	 * Comparator for the viewer. Sorts the templates by name and then
175
	 * description and context types by names.
176
	 */
177
	private static final class TemplateViewerComparator extends ViewerComparator {
178
		/*
179
		 * (non-Javadoc)
180
		 * 
181
		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
182
		 *      java.lang.Object, java.lang.Object)
183
		 */
184
		public int compare(Viewer viewer, Object object1, Object object2) {
185
			if ((object1 instanceof TemplatePersistenceData)
186
					&& (object2 instanceof TemplatePersistenceData)) {
187
				Template left = ((TemplatePersistenceData) object1).getTemplate();
188
				Template right = ((TemplatePersistenceData) object2).getTemplate();
189
				int result = left.getName().compareToIgnoreCase(right.getName());
190
				if (result != 0)
191
					return result;
192
				return left.getDescription().compareToIgnoreCase(right.getDescription());
193
			}
194
			if ((object1 instanceof TemplateContextType)
195
					&& (object2 instanceof TemplateContextType)) {
196
				return ((TemplateContextType) object1).getName().compareToIgnoreCase(
197
						((TemplateContextType) object1).getName());
198
			}
199
			return super.compare(viewer, object1, object2);
200
		}
201
202
		/*
203
		 * (non-Javadoc)
204
		 * 
205
		 * @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object,
206
		 *      java.lang.String)
207
		 */
208
		public boolean isSorterProperty(Object element, String property) {
209
			return true;
210
		}
211
	}
212
213
	/**
214
	 * Label provider for templates.
215
	 */
216
	private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider {
217
218
		/*
219
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
220
		 *      int)
221
		 */
222
		public Image getColumnImage(Object element, int columnIndex) {
223
			return null;
224
		}
225
226
		/*
227
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
228
		 *      int)
229
		 */
230
		public String getColumnText(Object element, int columnIndex) {
231
			if (element instanceof TemplatePersistenceData)
232
				return getTemplateColumnText(((TemplatePersistenceData) element).getTemplate(),
233
						columnIndex);
234
			return getContextColumnText((TemplateContextType) element, columnIndex);
235
		}
236
237
		/**
238
		 * Return the column text for a template
239
		 * 
240
		 * @param template
241
		 * @param columnIndex
242
		 * @return the column text
243
		 */
244
		private String getTemplateColumnText(Template template, int columnIndex) {
245
			switch (columnIndex) {
246
			case 0:
247
				return template.getName();
248
			case 1:
249
				return template.getDescription();
250
			default:
251
				return ""; //$NON-NLS-1$
252
			}
253
		}
254
255
		/**
256
		 * Return the column text for a context
257
		 * 
258
		 * @param contextType
259
		 * @param columnIndex
260
		 * @return the column text
261
		 */
262
		private String getContextColumnText(TemplateContextType contextType, int columnIndex) {
263
			switch (columnIndex) {
264
			case 0:
265
				return contextType.getName();
266
			case 1:
267
				return TextEditorTemplateMessages.TemplatesPage_context_description;
268
			default:
269
				return ""; //$NON-NLS-1$
270
			}
271
		}
272
273
	}
274
275
	/**
276
	 * Content provider for templates. Provides all the templates defined for
277
	 * this editor and optionally the disabled ones.
278
	 */
279
	private class TemplatesContentProvider implements ITreeContentProvider {
280
		/*
281
		 * (non-Javadoc)
282
		 * 
283
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
284
		 */
285
		public Object[] getChildren(Object parentElement) {
286
			if (parentElement instanceof TemplatePersistenceData)
287
				return new Object[0];
288
			else if (parentElement instanceof TemplateContextType) {
289
				TemplateContextType contextType = (TemplateContextType) parentElement;
290
				return getTemplates(contextType.getId());
291
			}
292
			return null;
293
		}
294
295
		/**
296
		 * Get the templates for a given contextId. if ShowDisabled is selected
297
		 * the disabled templates are also included.
298
		 * 
299
		 * @param contextId
300
		 * @return the templates
301
		 */
302
		private TemplatePersistenceData[] getTemplates(String contextId) {
303
			List templateList = new ArrayList();
304
			TemplatePersistenceData[] datas = fTemplateStore.getTemplateData(false);
305
			boolean showDisabled = fShowDisabledAction.isChecked();
306
			for (int i = 0; i < datas.length; i++) {
307
				if ((showDisabled || datas[i].isEnabled())
308
						&& datas[i].getTemplate().getContextTypeId().equals(contextId))
309
					templateList.add(datas[i]);
310
			}
311
			return (TemplatePersistenceData[]) templateList
312
					.toArray(new TemplatePersistenceData[templateList.size()]);
313
		}
314
315
		/*
316
		 * (non-Javadoc)
317
		 * 
318
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
319
		 */
320
		public Object getParent(Object element) {
321
			if (element instanceof TemplatePersistenceData) {
322
				TemplatePersistenceData templateData = (TemplatePersistenceData) element;
323
				return fContextTypeRegistry.getContextType(templateData.getTemplate()
324
						.getContextTypeId());
325
			}
326
			return null;
327
		}
328
329
		/*
330
		 * (non-Javadoc)
331
		 * 
332
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
333
		 */
334
		public boolean hasChildren(Object element) {
335
			if (element instanceof TemplateContextType)
336
				return true;
337
			return false;
338
		}
339
340
		/*
341
		 * (non-Javadoc)
342
		 * 
343
		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
344
		 */
345
		public Object[] getElements(Object inputElement) {
346
			List contextTypes = new ArrayList();
347
348
			for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) {
349
				TemplateContextType contextType = (TemplateContextType) iterator.next();
350
				if (isActiveContext(contextType) || !fLinkAction.isChecked())
351
					contextTypes.add(contextType);
352
			}
353
			return contextTypes.toArray(new TemplateContextType[contextTypes.size()]);
354
		}
355
356
		/**
357
		 * Checks whether given context type is active for displaying the
358
		 * templates
359
		 * 
360
		 * @param contextType
361
		 * @return true if context is active
362
		 */
363
		private boolean isActiveContext(TemplateContextType contextType) {
364
			return fActiveTypes == null || fActiveTypes.contains(contextType.getId());
365
		}
366
367
		/*
368
		 * (non-Javadoc)
369
		 * 
370
		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
371
		 */
372
		public void dispose() {
373
		}
374
375
		/*
376
		 * (non-Javadoc)
377
		 * 
378
		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
379
		 *      java.lang.Object, java.lang.Object)
380
		 */
381
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
382
		}
383
	}
384
385
	/**
386
	 * Show/Hide new dialog
387
	 */
388
	private static final int SHOW_DIALOG = 0;
389
	private static final int HIDE_DIALOG = 1;
390
391
	/** The viewer displays the pattern of selected template. */
392
	private SourceViewer fPatternViewer;
393
	/** The store for our templates. */
394
	private TemplateStore fTemplateStore;
395
	/** The context type registry. */
396
	private ContextTypeRegistry fContextTypeRegistry;
397
398
	/** The control for this page book view */
399
	private Composite fControl;
400
401
	/* Actions */
402
	private Action fInsertAction;
403
	private Action fAddAction;
404
	private Action fEditAction;
405
	private Action fRemoveAction;
406
	private Action fLinkAction;
407
	private Action fExpandCollapseAction;
408
	private Action fPreferencePageAction;
409
	private Action fShowDisabledAction;
410
	private Action fShowNewDialogOnDropAction;
411
412
	/* Clipboard actions */
413
	private Action fPasteAction;
414
	private Action fCopyAction;
415
416
	/** Currently selected templates */
417
	private ArrayList fSelectedTemplateList = new ArrayList();
418
419
	/** Current active context types for the editor */
420
	private List fActiveTypes;
421
422
	/* Preference stores */
423
	/**
424
	 * Preference store to store the dialog setting for this page
425
	 */
426
	private IPreferenceStore fPreferenceStore;
427
	/**
428
	 * The template stores preference page. Used to listen to the changes and
429
	 * update the view. Needed when the user selects Preferences and updates the
430
	 * templates.
431
	 */
432
	private IPreferenceStore fTemplatePreferenceStore;
433
434
	/* Controls */
435
	private Tree fTemplatesTree;
436
	private TreeViewer fTreeViewer;
437
438
	/**
439
	 * Creates a new template preference page.
440
	 */
441
	protected TemplatesPage() {
442
		super();
443
		fPreferenceStore = TextEditorPlugin.getDefault().getPreferenceStore();
444
	}
445
446
	/**
447
	 * Returns the template store.
448
	 * 
449
	 * @return the template store
450
	 */
451
	public TemplateStore getTemplateStore() {
452
		return fTemplateStore;
453
	}
454
455
	/**
456
	 * Returns the context type registry.
457
	 * 
458
	 * @return the context type registry
459
	 */
460
	public ContextTypeRegistry getContextTypeRegistry() {
461
		return fContextTypeRegistry;
462
	}
463
464
	/**
465
	 * Sets the template store.
466
	 * 
467
	 * @param store
468
	 *            the template store
469
	 * @param templatePreferenceStore
470
	 *            the preference store used for this template store
471
	 */
472
	public void setTemplateStore(TemplateStore store, IPreferenceStore templatePreferenceStore) {
473
		fTemplateStore = store;
474
		fTemplatePreferenceStore = templatePreferenceStore;
475
		if (fTemplatePreferenceStore != null)
476
			fTemplatePreferenceStore.addPropertyChangeListener(new IPropertyChangeListener() {
477
				public void propertyChange(PropertyChangeEvent event) {
478
					refresh();
479
				}
480
			});
481
	}
482
483
	/**
484
	 * Sets the context type registry.
485
	 * 
486
	 * @param registry
487
	 *            the new context type registry
488
	 */
489
	public void setContextTypeRegistry(ContextTypeRegistry registry) {
490
		fContextTypeRegistry = registry;
491
	}
492
493
	/*
494
	 * (non-Javadoc)
495
	 * 
496
	 * @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite)
497
	 */
498
	public void createControl(Composite ancestor) {
499
		setupActions();
500
501
		fControl = new Composite(ancestor, SWT.NONE);
502
		GridLayout layout = new GridLayout();
503
		layout.numColumns = 2;
504
		layout.marginHeight = 0;
505
		layout.marginWidth = 0;
506
		fControl.setLayout(layout);
507
		Dialog.applyDialogFont(fControl);
508
509
		createTemplateTree();
510
		createPatternViewer(fControl);
511
512
		hookContextMenu();
513
		initializeDND();
514
		updateButtons();
515
516
		fControl.layout(true, true);
517
	}
518
519
	/**
520
	 * Create the tree control to display template information
521
	 */
522
	private void createTemplateTree() {
523
		Composite treeComposite = new Composite(fControl, SWT.NONE);
524
		GridData data = new GridData(GridData.FILL_BOTH);
525
		treeComposite.setLayoutData(data);
526
527
		TreeColumnLayout columnLayout = new TreeColumnLayout();
528
		treeComposite.setLayout(columnLayout);
529
		fTemplatesTree = new Tree(treeComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
530
				| SWT.FULL_SELECTION);
531
		fTemplatesTree.setHeaderVisible(true);
532
		fTemplatesTree.setLinesVisible(true);
533
534
		GC gc = new GC(getShell());
535
		gc.setFont(JFaceResources.getDialogFont());
536
537
		TreeColumn columnName = new TreeColumn(fTemplatesTree, SWT.NONE);
538
		columnName.setText(TextEditorTemplateMessages.TemplatesPage_column_name);
539
		int minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_name).x + 10;
540
		columnLayout.setColumnData(columnName, new ColumnWeightData(2, minWidth, true));
541
542
		TreeColumn columnDescription = new TreeColumn(fTemplatesTree, SWT.NONE);
543
		columnDescription.setText(TextEditorTemplateMessages.TemplatesPage_column_description);
544
		minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_description).x + 10;
545
		columnLayout.setColumnData(columnDescription, new ColumnWeightData(3, minWidth, true));
546
547
		gc.dispose();
548
549
		data = new GridData(GridData.FILL_BOTH);
550
		data.grabExcessHorizontalSpace = true;
551
		data.grabExcessVerticalSpace = true;
552
		/*
553
		 * these hints should not be zero. the grabExcess will ensure that the
554
		 * tree is sized appropriately the the pattern viewer is displayed below
555
		 * it.
556
		 */
557
		data.heightHint = 5;
558
		data.widthHint = 5;
559
		fTemplatesTree.setLayoutData(data);
560
		createTreeViewer();
561
	}
562
563
	/**
564
	 * Create the viewer for the tree control and configure it.
565
	 */
566
	private void createTreeViewer() {
567
		fTreeViewer = new TreeViewer(fTemplatesTree);
568
		fTreeViewer.setLabelProvider(new TemplateLabelProvider());
569
		fTreeViewer.setContentProvider(new TemplatesContentProvider());
570
571
		fTreeViewer.setComparator(new TemplateViewerComparator());
572
		fTreeViewer.setInput(fTemplateStore);
573
		fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
574
			public void doubleClick(DoubleClickEvent e) {
575
				updateSelectedTemplate();
576
				insertTemplate(getSelectedTemplate());
577
			}
578
		});
579
580
		fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
581
			public void selectionChanged(SelectionChangedEvent e) {
582
				updateSelectedTemplate();
583
				updateButtons();
584
			}
585
		});
586
		fTreeViewer.expandAll();
587
		setDisableItemColors();
588
	}
589
590
	/**
591
	 * Sets all templates in the tree that are disabled to grey.
592
	 */
593
	private void setDisableItemColors() {
594
		TreeItem[] items = fTemplatesTree.getItems();
595
		Color fgcDisabled = getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY);
596
		Color fgcEnabled = getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
597
		for (int i = 0; i < items.length; i++) {
598
			TreeItem[] items2 = items[i].getItems();
599
			for (int j = 0; j < items2.length; j++) {
600
				TemplatePersistenceData templateData = (TemplatePersistenceData) items2[j]
601
						.getData();
602
				if (!templateData.isEnabled() && items2[j].getForeground() != fgcDisabled)
603
					items2[j].setForeground(fgcDisabled);
604
				else if (templateData.isEnabled() && items2[j].getForeground() != fgcEnabled)
605
					items2[j].setForeground(fgcEnabled);
606
			}
607
		}
608
	}
609
610
	/**
611
	 * Update the selected template list and update the pattern viewer
612
	 */
613
	private void updateSelectedTemplate() {
614
		IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection();
615
616
		fSelectedTemplateList.clear();
617
		for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
618
			Object item = iterator.next();
619
			if (item instanceof TemplateContextType) {
620
				fSelectedTemplateList.clear();
621
				break;
622
			}
623
			fSelectedTemplateList.add(item);
624
625
		}
626
		if (isSingleTemplateSelected())
627
			updateViewerInput(getSelectedTemplate());
628
		else
629
			fPatternViewer.getDocument().set(""); //$NON-NLS-1$
630
	}
631
632
	/**
633
	 * Checks whether only one template is selected in the tree
634
	 * 
635
	 * @return true if only single template is selected
636
	 */
637
	private boolean isSingleTemplateSelected() {
638
		return fSelectedTemplateList.size() == 1;
639
	}
640
641
	/**
642
	 * Get the selected template. Note: should always precede with a check for
643
	 * isSingleTemplateSelected
644
	 * 
645
	 * @return the template (Not the data)
646
	 */
647
	private Template getSelectedTemplate() {
648
		return ((TemplatePersistenceData) fSelectedTemplateList.get(0)).getTemplate();
649
	}
650
651
	/**
652
	 * Create a viewer to display the pattern
653
	 * 
654
	 * @param parent
655
	 */
656
	private void createPatternViewer(Composite parent) {
657
		Label previewLabel = new Label(parent, SWT.NONE);
658
		previewLabel.setText(TextEditorTemplateMessages.TemplatesPage_preview);
659
		GridData data = new GridData();
660
		data.horizontalSpan = 2;
661
		previewLabel.setLayoutData(data);
662
663
		fPatternViewer = createViewer(parent);
664
		fPatternViewer.setEditable(false);
665
666
		Control control = fPatternViewer.getControl();
667
		data = new GridData(GridData.FILL_BOTH);
668
		data.horizontalSpan = 2;
669
670
		Dialog.applyDialogFont(control);
671
		GC gc = new GC(control);
672
		data.heightHint = convertHeightInCharsToPixels(gc, 5);
673
		data.grabExcessVerticalSpace = false;
674
		data.verticalAlignment = SWT.FILL;
675
		gc.dispose();
676
677
		control.setLayoutData(data);
678
	}
679
680
	/**
681
	 * Setup the actions
682
	 */
683
	private void setupActions() {
684
		IActionBars actionBars = getSite().getActionBars();
685
		IToolBarManager toolBarManager = actionBars.getToolBarManager();
686
		IMenuManager menuManager = actionBars.getMenuManager();
687
688
		fInsertAction = new Action(TextEditorTemplateMessages.TemplatesPage_insert) {
689
			public void run() {
690
				insertTemplate(getSelectedTemplate());
691
			}
692
		};
693
694
		fAddAction = new Action() {
695
			public void run() {
696
				addTemplate();
697
			}
698
		};
699
		fAddAction.setText(TextEditorTemplateMessages.TemplatesPage_new);
700
		fAddAction.setImageDescriptor(TemplateViewImages
701
				.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_NEW));
702
		toolBarManager.add(fAddAction);
703
704
		fEditAction = new Action() {
705
			public void run() {
706
				editTemplate();
707
			}
708
		};
709
		fEditAction.setText(TextEditorTemplateMessages.TemplatesPage_edit);
710
		fEditAction.setImageDescriptor(TemplateViewImages
711
				.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_EDIT));
712
		toolBarManager.add(fEditAction);
713
714
		fRemoveAction = new Action() {
715
			public void run() {
716
				removeTemplate();
717
			}
718
		};
719
		fRemoveAction.setText(TextEditorTemplateMessages.TemplatesPage_remove);
720
		fRemoveAction.setImageDescriptor(TemplateViewImages
721
				.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_DELETE));
722
		toolBarManager.add(fRemoveAction);
723
724
		toolBarManager.add(new Separator());
725
726
		fLinkAction = new Action(TextEditorTemplateMessages.TemplatesPage_link_to_editor,
727
				IAction.AS_CHECK_BOX) {
728
			public void run() {
729
				fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkAction.isChecked());
730
				refresh();
731
			}
732
		};
733
		fLinkAction.setImageDescriptor(TemplateViewImages
734
				.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_LINK));
735
		fLinkAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID));
736
		toolBarManager.add(fLinkAction);
737
738
		fExpandCollapseAction = new Action(TextEditorTemplateMessages.TemplatesPage_collapse_expand) {
739
			public void run() {
740
				Object[] vee = fTreeViewer.getVisibleExpandedElements();
741
				boolean collapse = vee.length != 0;
742
				if (collapse)
743
					fTreeViewer.collapseAll();
744
				else
745
					fTreeViewer.expandAll();
746
			}
747
		};
748
		fExpandCollapseAction.setImageDescriptor(TemplateViewImages
749
				.getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_COLLAPSE_EXPAND));
750
		toolBarManager.add(fExpandCollapseAction);
751
752
		if (getPreferencePageId() != null) {
753
			fPreferencePageAction = new Action() {
754
				public void run() {
755
					showPreferencePage();
756
				}
757
			};
758
			fPreferencePageAction.setText(TextEditorTemplateMessages.TemplatesPage_preference_page);
759
			menuManager.add(fPreferencePageAction);
760
		}
761
		menuManager.add(new Separator());
762
763
		fShowDisabledAction = new Action(TextEditorTemplateMessages.TemplatesPage_show_disabled,
764
				IAction.AS_CHECK_BOX) {
765
			public void run() {
766
				fPreferenceStore.setValue(SHOW_DISABLED_ACTION_PREF_ID, fShowDisabledAction
767
						.isChecked());
768
				refresh();
769
			}
770
		};
771
		fPreferenceStore.setDefault(SHOW_DISABLED_ACTION_PREF_ID, false);
772
		fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID));
773
		menuManager.add(fShowDisabledAction);
774
775
		fShowNewDialogOnDropAction = new Action(
776
				TextEditorTemplateMessages.TemplatesPage_show_new_dialog, IAction.AS_CHECK_BOX) {
777
			public void run() {
778
				fPreferenceStore.setValue(SHOW_NEW_DIALOG_ACTION_PREF_ID,
779
						fShowNewDialogOnDropAction.isChecked());
780
			}
781
		};
782
		fPreferenceStore.setDefault(SHOW_NEW_DIALOG_ACTION_PREF_ID, true);
783
		fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID));
784
		menuManager.add(fShowNewDialogOnDropAction);
785
786
		menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
787
788
		fPasteAction = new Action() {
789
			public void run() {
790
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
791
				Object contents = clipBoard.getContents(TextTransfer.getInstance());
792
				if (contents == null)
793
					return;
794
				final String text = (String) contents;
795
				String contextId = getContextId();
796
				final Template template = new Template(
797
						TextEditorTemplateMessages.TemplatesPage_snippet,
798
						TextEditorTemplateMessages.TemplatesPage_paste_description, contextId,
799
						text, true);
800
				getShell().getDisplay().asyncExec(new Runnable() {
801
					public void run() {
802
						addTemplate(template, HIDE_DIALOG);
803
					}
804
				});
805
806
			}
807
808
			private String getContextId() {
809
				if (isSingleTemplateSelected())
810
					return getSelectedTemplate().getContextTypeId();
811
				IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection();
812
				if (selection.isEmpty())
813
					return getFirstContextTypeId();
814
				Object element = selection.getFirstElement();
815
				if (element instanceof TemplateContextType)
816
					return ((TemplateContextType) element).getId();
817
				return ((TemplatePersistenceData) element).getTemplate().getContextTypeId();
818
			}
819
		};
820
		actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction);
821
822
		fCopyAction = new Action() {
823
			public void run() {
824
				if (!isSingleTemplateSelected())
825
					return;
826
				Template[] templates = new Template[] { getSelectedTemplate() };
827
				Clipboard clipBoard = new Clipboard(getShell().getDisplay());
828
				clipBoard.setContents(new Object[] { templates }, new Transfer[] { TemplateTransfer
829
						.getInstance() });
830
			}
831
		};
832
		actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction);
833
	}
834
835
	/**
836
	 * Setup the context menu for the viewer.
837
	 */
838
	private void hookContextMenu() {
839
		MenuManager menuMgr = new MenuManager(POPUP_MENU_ID);
840
		menuMgr.setRemoveAllWhenShown(true);
841
		menuMgr.addMenuListener(new IMenuListener() {
842
			public void menuAboutToShow(IMenuManager manager) {
843
				fillContextMenu(manager);
844
			}
845
		});
846
		Menu menu = menuMgr.createContextMenu(fTreeViewer.getControl());
847
		fTreeViewer.getControl().setMenu(menu);
848
		getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer);
849
	}
850
851
	/**
852
	 * Fill up the context menu
853
	 * 
854
	 * @param manager
855
	 */
856
	protected void fillContextMenu(IMenuManager manager) {
857
		manager.add(fInsertAction);
858
		manager.add(new Separator());
859
		manager.add(fAddAction);
860
		manager.add(fEditAction);
861
		manager.add(fRemoveAction);
862
		// Other plug-ins can contribute there actions here
863
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
864
	}
865
866
	/**
867
	 * Show the preference templates preference page
868
	 */
869
	private void showPreferencePage() {
870
		PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageId(), null, null)
871
				.open();
872
	}
873
874
	/**
875
	 * Get the preference page ID for the templates for the given editor.
876
	 * Subclasses should override.
877
	 * 
878
	 * @return id of the preference page
879
	 */
880
	protected String getPreferencePageId() {
881
		return null;
882
	}
883
884
	/**
885
	 * Helper to find the size for pattern viewer
886
	 * 
887
	 * @param gc
888
	 * @param chars
889
	 * @return the hieght in pixels
890
	 */
891
	private int convertHeightInCharsToPixels(GC gc, int chars) {
892
		FontMetrics fontMetrics = gc.getFontMetrics();
893
		return fontMetrics.getHeight() * chars;
894
	}
895
896
	/**
897
	 * Get the shell
898
	 * 
899
	 * @return the shell for this view site
900
	 */
901
	protected Shell getShell() {
902
		return getSite().getShell();
903
	}
904
905
	/**
906
	 * Creates, configures and returns a source viewer to present the template
907
	 * pattern on the preference page. Clients may override to provide a custom
908
	 * source viewer featuring e.g. syntax coloring.
909
	 * 
910
	 * @param parent
911
	 *            the parent control
912
	 * @return a configured source viewer
913
	 */
914
	protected SourceViewer createViewer(Composite parent) {
915
		SourceViewer viewer = new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL
916
				| SWT.H_SCROLL);
917
		SourceViewerConfiguration configuration = new SourceViewerConfiguration();
918
		viewer.configure(configuration);
919
		IDocument document = new Document();
920
		viewer.setDocument(document);
921
		return viewer;
922
	}
923
924
	/**
925
	 * Updates the pattern viewer.
926
	 * 
927
	 * @param template
928
	 */
929
	protected void updateViewerInput(Template template) {
930
		if (template != null)
931
			fPatternViewer.getDocument().set(template.getPattern());
932
		else
933
			fPatternViewer.getDocument().set(""); //$NON-NLS-1$
934
	}
935
936
	/**
937
	 * Updates the buttons.
938
	 */
939
	private void updateButtons() {
940
		fCopyAction.setEnabled(isSingleTemplateSelected());
941
		fInsertAction.setEnabled(isSingleTemplateSelected());
942
		fEditAction.setEnabled(isSingleTemplateSelected());
943
		fRemoveAction.setEnabled(fSelectedTemplateList.size() != 0);
944
	}
945
946
	/**
947
	 * Add a template
948
	 */
949
	private void addTemplate() {
950
		String id = getFirstContextTypeId();
951
		if (id != null) {
952
			Template template = new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
953
954
			addTemplate(template, SHOW_DIALOG);
955
		}
956
	}
957
958
	/**
959
	 * Get the first context type from the registry.
960
	 * 
961
	 * @return id of the context type
962
	 */
963
	private String getFirstContextTypeId() {
964
		Iterator it = fContextTypeRegistry.contextTypes();
965
		if (it.hasNext())
966
			return ((TemplateContextType) it.next()).getId();
967
		return null;
968
	}
969
970
	/**
971
	 * Add a template
972
	 * 
973
	 * Setting ui to SHOW_DIALOG will force a New dialog. Setting it to
974
	 * MAY_HIDE_DIALOG will respect the show new dialog on drop option.
975
	 * 
976
	 * @param template
977
	 * @param ui
978
	 */
979
	private void addTemplate(Template template, int ui) {
980
		Template newTemplate;
981
		if (ui == SHOW_DIALOG || fShowNewDialogOnDropAction.isChecked())
982
			newTemplate = editTemplate(template, false, true);
983
		else
984
			newTemplate = template;
985
		if (newTemplate != null) {
986
			TemplatePersistenceData data = new TemplatePersistenceData(newTemplate, true);
987
			fTemplateStore.add(data);
988
			saveTemplateStore();
989
			fSelectedTemplateList.clear();
990
			fSelectedTemplateList.add(data);
991
			changeSelection();
992
		}
993
	}
994
995
	/**
996
	 * Save the template store
997
	 */
998
	private void saveTemplateStore() {
999
		try {
1000
			fTemplateStore.save();
1001
		} catch (IOException e) {
1002
			e.printStackTrace();
1003
			MessageDialog.openError(getShell(),
1004
					TextEditorTemplateMessages.TemplatesPage_save_error_message, e.getMessage());
1005
		}
1006
	}
1007
1008
	/**
1009
	 * Change selection in the viewer. oldData will contain the earlier selected
1010
	 * template and fCurrentTemplateData will hold the current selection. Either
1011
	 * can be null.
1012
	 * 
1013
	 */
1014
	private void changeSelection() {
1015
		fTreeViewer.refresh();
1016
		if (isSingleTemplateSelected())
1017
			fTreeViewer.setSelection(new StructuredSelection(fSelectedTemplateList.get(0)), true);
1018
		else
1019
			fTreeViewer.setSelection(new StructuredSelection());
1020
		updateSelectedTemplate();
1021
	}
1022
1023
	/**
1024
	 * Creates the edit dialog. Subclasses may override this method to provide a
1025
	 * custom dialog.
1026
	 * 
1027
	 * @param template
1028
	 *            the template being edited
1029
	 * @param edit
1030
	 *            whether the dialog should be editable
1031
	 * @param isNameModifiable
1032
	 *            whether the template name may be modified
1033
	 * @return the created or modified template, or <code>null</code> if the
1034
	 *         edition failed
1035
	 * @since 3.1
1036
	 */
1037
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
1038
		EditTemplateDialog dialog = new EditTemplateDialog(getShell(), template, edit,
1039
				isNameModifiable, fContextTypeRegistry);
1040
		if (dialog.open() == Window.OK) {
1041
			return dialog.getTemplate();
1042
		}
1043
		return null;
1044
	}
1045
1046
	/**
1047
	 * Edit the current template
1048
	 */
1049
	private void editTemplate() {
1050
		Template oldTemplate = getSelectedTemplate();
1051
		Template newTemplate = editTemplate(new Template(oldTemplate), true, true);
1052
		if (newTemplate != null) {
1053
			if (!newTemplate.getName().equals(oldTemplate.getName())
1054
					&& MessageDialog.openQuestion(getShell(),
1055
							TextEditorTemplateMessages.TemplatesPage_question_create_new_title,
1056
							TextEditorTemplateMessages.TemplatesPage_question_create_new_message)) {
1057
				fSelectedTemplateList.clear();
1058
				TemplatePersistenceData templateData = new TemplatePersistenceData(newTemplate,
1059
						true);
1060
				fSelectedTemplateList.add(templateData);
1061
				fTemplateStore.add(templateData);
1062
			} else {
1063
				((TemplatePersistenceData) fSelectedTemplateList.get(0)).setTemplate(newTemplate);
1064
			}
1065
			changeSelection();
1066
		}
1067
		saveTemplateStore();
1068
	}
1069
1070
	/**
1071
	 * Remove the currently selected templates
1072
	 */
1073
	private void removeTemplate() {
1074
		if (!MessageDialog.openQuestion(getShell(),
1075
				TextEditorTemplateMessages.TemplatesPage_remove_title,
1076
				TextEditorTemplateMessages.TemplatesPage_remove_message))
1077
			return;
1078
		for (Iterator iterator = fSelectedTemplateList.iterator(); iterator.hasNext();) {
1079
			TemplatePersistenceData data = (TemplatePersistenceData) iterator.next();
1080
			fTemplateStore.delete(data);
1081
		}
1082
		saveTemplateStore();
1083
		fSelectedTemplateList.clear();
1084
		changeSelection();
1085
	}
1086
1087
	/**
1088
	 * Get the pattern viewer. Subclass can override
1089
	 * 
1090
	 * @return the viewer
1091
	 */
1092
	protected SourceViewer getViewer() {
1093
		return fPatternViewer;
1094
	}
1095
1096
	/*
1097
	 * (non-Javadoc)
1098
	 * 
1099
	 * @see org.eclipse.ui.part.Page#getControl()
1100
	 */
1101
	public Control getControl() {
1102
		return fControl;
1103
	}
1104
1105
	/**
1106
	 * Subclasses should override and facilitate inserting the template code
1107
	 * into the active editor.
1108
	 * 
1109
	 * @param template
1110
	 */
1111
	public void insertTemplate(Template template) {
1112
	}
1113
1114
	/**
1115
	 * The caret position in the editor has moved into a new context type. It is
1116
	 * the subclasses responsibility to see that this is called only when needed
1117
	 * by keeping track of editor contents (eg. partitions).
1118
	 * 
1119
	 * @param ids
1120
	 */
1121
	protected void contextTypeChanged(String[] ids) {
1122
		fActiveTypes = Arrays.asList(ids);
1123
		if (fLinkAction != null && fLinkAction.isChecked())
1124
			refresh();
1125
	}
1126
1127
	/**
1128
	 * Setup the drop target for the table
1129
	 */
1130
	private void initializeDND() {
1131
		DragSourceAdapter dragListener = new DragSourceAdapter() {
1132
			public void dragSetData(DragSourceEvent event) {
1133
				if (isSingleTemplateSelected()
1134
						&& TemplateTransfer.getInstance().isSupportedType(event.dataType)) {
1135
					event.data = new Template[] { getSelectedTemplate() };
1136
				}
1137
			}
1138
		};
1139
		fTreeViewer.addDragSupport(DND.DROP_COPY,
1140
				new Transfer[] { TemplateTransfer.getInstance() }, dragListener);
1141
		DropTargetAdapter dropListener = new DropTargetAdapter() {
1142
			TextTransfer textTransfer = TextTransfer.getInstance();
1143
1144
			public void dragEnter(DropTargetEvent event) {
1145
				if (event.detail == DND.DROP_DEFAULT)
1146
					event.detail = DND.DROP_COPY;
1147
			}
1148
1149
			public void dragOperationChanged(DropTargetEvent event) {
1150
				if (event.detail == DND.DROP_DEFAULT)
1151
					event.detail = DND.DROP_COPY;
1152
			}
1153
1154
			public void dragOver(DropTargetEvent event) {
1155
				event.detail = DND.DROP_NONE;
1156
				if (event.item == null)
1157
					return;
1158
				int index = 0;
1159
				while (index < event.dataTypes.length) {
1160
					if (textTransfer.isSupportedType(event.dataTypes[index]))
1161
						break;
1162
					index++;
1163
				}
1164
				if (index < event.dataTypes.length) {
1165
					event.currentDataType = event.dataTypes[index];
1166
					event.detail = DND.DROP_COPY;
1167
					return;
1168
				}
1169
			}
1170
1171
			public void drop(DropTargetEvent event) {
1172
				if (event.item == null)
1173
					return;
1174
				Object object = ((TreeItem) event.item).getData();
1175
				String contextId;
1176
				if (object instanceof TemplateContextType)
1177
					contextId = findContextIdByName(((TemplateContextType) object).getId());
1178
				else
1179
					contextId = findContextIdByName(((TemplatePersistenceData) object)
1180
							.getTemplate().getContextTypeId());
1181
				if (textTransfer.isSupportedType(event.currentDataType)) {
1182
					String text = (String) event.data;
1183
					final Template template = new Template(
1184
							TextEditorTemplateMessages.TemplatesPage_snippet,
1185
							TextEditorTemplateMessages.TemplatesPage_paste_description, contextId,
1186
							text, true);
1187
					getShell().getDisplay().asyncExec(new Runnable() {
1188
						public void run() {
1189
							addTemplate(template, HIDE_DIALOG);
1190
						}
1191
					});
1192
				}
1193
			}
1194
1195
			private String findContextIdByName(String contextName) {
1196
				String contextId = null;
1197
				for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) {
1198
					TemplateContextType contextType = (TemplateContextType) iterator.next();
1199
					if (contextType.getName().equals(contextName))
1200
						contextId = contextType.getId();
1201
				}
1202
				return contextId;
1203
			}
1204
		};
1205
		fTreeViewer.addDropSupport(DND.DROP_COPY, new Transfer[] { TextTransfer.getInstance() },
1206
				dropListener);
1207
	}
1208
1209
	/**
1210
	 * Setup the editor site as a drop target. Should be invoked by the
1211
	 * subclasses for the D&D to work with the editor.
1212
	 * 
1213
	 * @param site
1214
	 * @param viewer
1215
	 */
1216
	protected void setupEditorDropTarget(IWorkbenchPartSite site, Control viewer) {
1217
		IDragAndDropService dndService = (IDragAndDropService) site
1218
				.getService(IDragAndDropService.class);
1219
		EditorDropTarget editorDropTarget = new EditorDropTarget();
1220
		dndService.addMergedDropTarget(viewer, DND.DROP_COPY, new Transfer[] { TemplateTransfer
1221
				.getInstance() }, editorDropTarget);
1222
	}
1223
1224
	private void refresh() {
1225
		fTreeViewer.refresh();
1226
		setDisableItemColors();
1227
	}
1228
}
(-)src/org/eclipse/ui/texteditor/templates/EditTemplateDialog.java (+598 lines)
Added Link Here
1
package org.eclipse.ui.texteditor.templates;
2
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.Map;
8
9
import org.eclipse.jface.action.Action;
10
import org.eclipse.jface.action.GroupMarker;
11
import org.eclipse.jface.action.IAction;
12
import org.eclipse.jface.action.IMenuListener;
13
import org.eclipse.jface.action.IMenuManager;
14
import org.eclipse.jface.action.MenuManager;
15
import org.eclipse.jface.action.Separator;
16
import org.eclipse.jface.dialogs.IDialogSettings;
17
import org.eclipse.jface.dialogs.StatusDialog;
18
import org.eclipse.jface.text.Document;
19
import org.eclipse.jface.text.IDocument;
20
import org.eclipse.jface.text.ITextListener;
21
import org.eclipse.jface.text.ITextOperationTarget;
22
import org.eclipse.jface.text.ITextViewer;
23
import org.eclipse.jface.text.TextEvent;
24
import org.eclipse.jface.text.contentassist.ContentAssistant;
25
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
26
import org.eclipse.jface.text.contentassist.IContentAssistant;
27
import org.eclipse.jface.text.source.ISourceViewer;
28
import org.eclipse.jface.text.source.SourceViewer;
29
import org.eclipse.jface.text.source.SourceViewerConfiguration;
30
import org.eclipse.jface.text.templates.ContextTypeRegistry;
31
import org.eclipse.jface.text.templates.Template;
32
import org.eclipse.jface.text.templates.TemplateContextType;
33
import org.eclipse.jface.text.templates.TemplateException;
34
import org.eclipse.jface.viewers.ISelectionChangedListener;
35
import org.eclipse.jface.viewers.SelectionChangedEvent;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.custom.StyledText;
38
import org.eclipse.swt.custom.VerifyKeyListener;
39
import org.eclipse.swt.events.FocusEvent;
40
import org.eclipse.swt.events.FocusListener;
41
import org.eclipse.swt.events.ModifyEvent;
42
import org.eclipse.swt.events.ModifyListener;
43
import org.eclipse.swt.events.SelectionEvent;
44
import org.eclipse.swt.events.SelectionListener;
45
import org.eclipse.swt.events.VerifyEvent;
46
import org.eclipse.swt.layout.GridData;
47
import org.eclipse.swt.layout.GridLayout;
48
import org.eclipse.swt.widgets.Button;
49
import org.eclipse.swt.widgets.Combo;
50
import org.eclipse.swt.widgets.Composite;
51
import org.eclipse.swt.widgets.Control;
52
import org.eclipse.swt.widgets.Label;
53
import org.eclipse.swt.widgets.Menu;
54
import org.eclipse.swt.widgets.Shell;
55
import org.eclipse.swt.widgets.Text;
56
import org.eclipse.swt.widgets.Widget;
57
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
58
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
59
import org.eclipse.ui.texteditor.IUpdate;
60
61
/**
62
	 * Dialog to edit a template. Clients will usually instantiate, but
63
	 * may also extend.
64
	 *
65
	 * @since 3.3
66
	 */
67
	public class EditTemplateDialog extends StatusDialog {
68
69
		private class TextViewerAction extends Action implements IUpdate {
70
71
			private int fOperationCode= -1;
72
			private ITextOperationTarget fOperationTarget;
73
74
			/**
75
			 * Creates a new action.
76
			 *
77
			 * @param viewer the viewer
78
			 * @param operationCode the opcode
79
			 */
80
			public TextViewerAction(ITextViewer viewer, int operationCode) {
81
				fOperationCode= operationCode;
82
				fOperationTarget= viewer.getTextOperationTarget();
83
				update();
84
			}
85
86
			/**
87
			 * Updates the enabled state of the action.
88
			 * Fires a property change if the enabled state changes.
89
			 *
90
			 * @see Action#firePropertyChange(String, Object, Object)
91
			 */
92
			public void update() {
93
94
				boolean wasEnabled= isEnabled();
95
				boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
96
				setEnabled(isEnabled);
97
98
				if (wasEnabled != isEnabled) {
99
					firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE);
100
				}
101
			}
102
103
			/**
104
			 * @see Action#run()
105
			 */
106
			public void run() {
107
				if (fOperationCode != -1 && fOperationTarget != null) {
108
					fOperationTarget.doOperation(fOperationCode);
109
				}
110
			}
111
		}
112
113
		private final Template fOriginalTemplate;
114
115
		private Text fNameText;
116
		private Text fDescriptionText;
117
		private Combo fContextCombo;
118
		private SourceViewer fPatternEditor;
119
		private Button fInsertVariableButton;
120
		private Button fAutoInsertCheckbox;
121
		private boolean fIsNameModifiable;
122
123
		private StatusInfo fValidationStatus;
124
		private boolean fSuppressError= true; // #4354
125
		private Map fGlobalActions= new HashMap(10);
126
		private List fSelectionActions = new ArrayList(3);
127
		private String[][] fContextTypes;
128
129
		private ContextTypeRegistry fContextTypeRegistry;
130
131
		private final TemplateVariableProcessor fTemplateProcessor= new TemplateVariableProcessor();
132
133
		private Template fNewTemplate;
134
135
		/**
136
		 * Creates a new dialog.
137
		 *
138
		 * @param parent the shell parent of the dialog
139
		 * @param template the template to edit
140
		 * @param edit whether this is a new template or an existing being edited
141
		 * @param isNameModifiable whether the name of the template may be modified
142
		 * @param registry the context type registry to use
143
		 */
144
		public EditTemplateDialog(Shell parent, Template template, boolean edit, boolean isNameModifiable, ContextTypeRegistry registry) {
145
			super(parent);
146
147
			setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
148
149
			String title= edit
150
				? TextEditorTemplateMessages.EditTemplateDialog_title_edit
151
				: TextEditorTemplateMessages.EditTemplateDialog_title_new;
152
			setTitle(title);
153
154
			fOriginalTemplate= template;
155
			fIsNameModifiable= isNameModifiable;
156
157
			List contexts= new ArrayList();
158
			for (Iterator it= registry.contextTypes(); it.hasNext();) {
159
				TemplateContextType type= (TemplateContextType) it.next();
160
				contexts.add(new String[] { type.getId(), type.getName() });
161
			}
162
			fContextTypes= (String[][]) contexts.toArray(new String[contexts.size()][]);
163
164
			fValidationStatus= new StatusInfo();
165
166
			fContextTypeRegistry= registry;
167
168
			TemplateContextType type= fContextTypeRegistry.getContextType(template.getContextTypeId());
169
			fTemplateProcessor.setContextType(type);
170
		}
171
172
		/*
173
		 * @see org.eclipse.ui.texteditor.templates.StatusDialog#create()
174
		 */
175
		public void create() {
176
			super.create();
177
			// update initial OK button to be disabled for new templates
178
			boolean valid= fNameText == null || fNameText.getText().trim().length() != 0;
179
			if (!valid) {
180
				StatusInfo status = new StatusInfo();
181
				status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname);
182
				updateButtonsEnableState(status);
183
	 		}
184
		}
185
186
		/*
187
		 * @see Dialog#createDialogArea(Composite)
188
		 */
189
		protected Control createDialogArea(Composite ancestor) {
190
			Composite parent= new Composite(ancestor, SWT.NONE);
191
			GridLayout layout= new GridLayout();
192
			layout.numColumns= 2;
193
			parent.setLayout(layout);
194
			parent.setLayoutData(new GridData(GridData.FILL_BOTH));
195
196
			ModifyListener listener= new ModifyListener() {
197
				public void modifyText(ModifyEvent e) {
198
					doTextWidgetChanged(e.widget);
199
				}
200
			};
201
202
			if (fIsNameModifiable) {
203
				createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_name);
204
205
				Composite composite= new Composite(parent, SWT.NONE);
206
				composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
207
				layout= new GridLayout();
208
				layout.numColumns= 4;
209
				layout.marginWidth= 0;
210
				layout.marginHeight= 0;
211
				composite.setLayout(layout);
212
213
				fNameText= createText(composite);
214
				fNameText.addModifyListener(listener);
215
				fNameText.addFocusListener(new FocusListener() {
216
217
					public void focusGained(FocusEvent e) {
218
					}
219
220
					public void focusLost(FocusEvent e) {
221
						if (fSuppressError) {
222
							fSuppressError= false;
223
							updateButtons();
224
						}
225
					}
226
				});
227
228
				createLabel(composite, TextEditorTemplateMessages.EditTemplateDialog_context);
229
				fContextCombo= new Combo(composite, SWT.READ_ONLY);
230
231
				for (int i= 0; i < fContextTypes.length; i++) {
232
					fContextCombo.add(fContextTypes[i][1]);
233
				}
234
235
				fContextCombo.addModifyListener(listener);
236
				
237
				fAutoInsertCheckbox= createCheckbox(composite, TextEditorTemplateMessages.EditTemplateDialog_autoinsert);
238
				fAutoInsertCheckbox.setSelection(fOriginalTemplate.isAutoInsertable());
239
			}
240
241
			createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_description);
242
243
			int descFlags= fIsNameModifiable ? SWT.BORDER : SWT.BORDER | SWT.READ_ONLY;
244
			fDescriptionText= new Text(parent, descFlags );
245
			fDescriptionText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
246
247
			fDescriptionText.addModifyListener(listener);
248
249
			Label patternLabel= createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_pattern);
250
			patternLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
251
			fPatternEditor= createEditor(parent, fOriginalTemplate.getPattern());
252
253
			Label filler= new Label(parent, SWT.NONE);
254
			filler.setLayoutData(new GridData());
255
256
			Composite composite= new Composite(parent, SWT.NONE);
257
			layout= new GridLayout();
258
			layout.marginWidth= 0;
259
			layout.marginHeight= 0;
260
			composite.setLayout(layout);
261
			composite.setLayoutData(new GridData());
262
263
			fInsertVariableButton= new Button(composite, SWT.NONE);
264
			fInsertVariableButton.setLayoutData(getButtonGridData(fInsertVariableButton));
265
			fInsertVariableButton.setText(TextEditorTemplateMessages.EditTemplateDialog_insert_variable);
266
			fInsertVariableButton.addSelectionListener(new SelectionListener() {
267
				public void widgetSelected(SelectionEvent e) {
268
					fPatternEditor.getTextWidget().setFocus();
269
					fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
270
				}
271
272
				public void widgetDefaultSelected(SelectionEvent e) {}
273
			});
274
275
			fDescriptionText.setText(fOriginalTemplate.getDescription());
276
			if (fIsNameModifiable) {
277
				fNameText.setText(fOriginalTemplate.getName());
278
				fNameText.addModifyListener(listener);
279
				fContextCombo.select(getIndex(fOriginalTemplate.getContextTypeId()));
280
			} else {
281
				fPatternEditor.getControl().setFocus();
282
			}
283
			initializeActions();
284
285
			applyDialogFont(parent);
286
			return composite;
287
		}
288
289
		private void doTextWidgetChanged(Widget w) {
290
			if (w == fNameText) {
291
				fSuppressError= false;
292
				updateButtons();
293
			} else if (w == fContextCombo) {
294
				String contextId= getContextId();
295
				fTemplateProcessor.setContextType(fContextTypeRegistry.getContextType(contextId));
296
			} else if (w == fDescriptionText) {
297
				// oh, nothing
298
			}
299
		}
300
301
		private String getContextId() {
302
			if (fContextCombo != null && !fContextCombo.isDisposed()) {
303
				String name= fContextCombo.getText();
304
				for (int i= 0; i < fContextTypes.length; i++) {
305
					if (name.equals(fContextTypes[i][1])) {
306
						return fContextTypes[i][0];
307
					}
308
				}
309
			}
310
311
			return fOriginalTemplate.getContextTypeId();
312
		}
313
314
		private void doSourceChanged(IDocument document) {
315
			String text= document.get();
316
			fValidationStatus.setOK();
317
			TemplateContextType contextType= fContextTypeRegistry.getContextType(getContextId());
318
			if (contextType != null) {
319
				try {
320
					contextType.validate(text);
321
				} catch (TemplateException e) {
322
					fValidationStatus.setError(e.getLocalizedMessage());
323
				}
324
			}
325
326
			updateUndoAction();
327
			updateButtons();
328
		}
329
330
		private static GridData getButtonGridData(Button button) {
331
			GridData data= new GridData(GridData.FILL_HORIZONTAL);
332
			// TODO get some button hints.
333
//			data.heightHint= SWTUtil.getButtonHeightHint(button);
334
335
			return data;
336
		}
337
338
		private static Label createLabel(Composite parent, String name) {
339
			Label label= new Label(parent, SWT.NULL);
340
			label.setText(name);
341
			label.setLayoutData(new GridData());
342
343
			return label;
344
		}
345
346
		private static Text createText(Composite parent) {
347
			Text text= new Text(parent, SWT.BORDER);
348
			text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
349
350
			return text;
351
		}
352
353
		private static Button createCheckbox(Composite parent, String name) {
354
			Button button= new Button(parent, SWT.CHECK);
355
			button.setText(name);
356
			button.setLayoutData(new GridData());
357
			
358
			return button;
359
		}
360
		
361
		private SourceViewer createEditor(Composite parent, String pattern) {
362
			SourceViewer viewer= createViewer(parent);
363
			viewer.setEditable(true);
364
			
365
			IDocument document= viewer.getDocument();
366
			if (document != null)
367
				document.set(pattern);
368
			else {
369
				document= new Document(pattern);
370
				viewer.setDocument(document);
371
			}
372
373
			int nLines= document.getNumberOfLines();
374
			if (nLines < 5) {
375
				nLines= 5;
376
			} else if (nLines > 12) {
377
				nLines= 12;
378
			}
379
380
			Control control= viewer.getControl();
381
			GridData data= new GridData(GridData.FILL_BOTH);
382
			data.widthHint= convertWidthInCharsToPixels(80);
383
			data.heightHint= convertHeightInCharsToPixels(nLines);
384
			control.setLayoutData(data);
385
386
			viewer.addTextListener(new ITextListener() {
387
				public void textChanged(TextEvent event) {
388
					if (event .getDocumentEvent() != null)
389
						doSourceChanged(event.getDocumentEvent().getDocument());
390
				}
391
			});
392
393
			viewer.addSelectionChangedListener(new ISelectionChangedListener() {
394
				public void selectionChanged(SelectionChangedEvent event) {
395
					updateSelectionDependentActions();
396
				}
397
			});
398
399
		 	viewer.prependVerifyKeyListener(new VerifyKeyListener() {
400
				public void verifyKey(VerifyEvent event) {
401
					handleVerifyKeyPressed(event);
402
				}
403
			});
404
405
			return viewer;
406
		}
407
408
		/**
409
		 * Creates the viewer to be used to display the pattern. Subclasses may override.
410
		 *
411
		 * @param parent the parent composite of the viewer
412
		 * @return a configured <code>SourceViewer</code>
413
		 */
414
		protected SourceViewer createViewer(Composite parent) {
415
			SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
416
			SourceViewerConfiguration configuration= new SourceViewerConfiguration() {
417
				public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
418
419
					ContentAssistant assistant= new ContentAssistant();
420
					assistant.enableAutoActivation(true);
421
					assistant.enableAutoInsert(true);
422
					assistant.setContentAssistProcessor(fTemplateProcessor, IDocument.DEFAULT_CONTENT_TYPE);
423
					return assistant;
424
				}
425
			};
426
			viewer.configure(configuration);
427
			return viewer;
428
		}
429
430
		private void handleVerifyKeyPressed(VerifyEvent event) {
431
			if (!event.doit)
432
				return;
433
434
			if (event.stateMask != SWT.MOD1)
435
				return;
436
437
			switch (event.character) {
438
				case ' ':
439
					fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
440
					event.doit= false;
441
					break;
442
443
				// CTRL-Z
444
				case 'z' - 'a' + 1:
445
					fPatternEditor.doOperation(ITextOperationTarget.UNDO);
446
					event.doit= false;
447
					break;
448
			}
449
		}
450
451
		private void initializeActions() {
452
			TextViewerAction action= new TextViewerAction(fPatternEditor, ITextOperationTarget.UNDO);
453
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_undo);
454
			fGlobalActions.put(ITextEditorActionConstants.UNDO, action);
455
456
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.CUT);
457
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_cut);
458
			fGlobalActions.put(ITextEditorActionConstants.CUT, action);
459
460
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.COPY);
461
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_copy);
462
			fGlobalActions.put(ITextEditorActionConstants.COPY, action);
463
464
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.PASTE);
465
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_paste);
466
			fGlobalActions.put(ITextEditorActionConstants.PASTE, action);
467
468
			action= new TextViewerAction(fPatternEditor, ITextOperationTarget.SELECT_ALL);
469
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_select_all);
470
			fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action);
471
472
			action= new TextViewerAction(fPatternEditor, ISourceViewer.CONTENTASSIST_PROPOSALS);
473
			action.setText(TextEditorTemplateMessages.EditTemplateDialog_content_assist);
474
			fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$
475
476
			fSelectionActions.add(ITextEditorActionConstants.CUT);
477
			fSelectionActions.add(ITextEditorActionConstants.COPY);
478
			fSelectionActions.add(ITextEditorActionConstants.PASTE);
479
480
			// create context menu
481
			MenuManager manager= new MenuManager(null, null);
482
			manager.setRemoveAllWhenShown(true);
483
			manager.addMenuListener(new IMenuListener() {
484
				public void menuAboutToShow(IMenuManager mgr) {
485
					fillContextMenu(mgr);
486
				}
487
			});
488
489
			StyledText text= fPatternEditor.getTextWidget();
490
			Menu menu= manager.createContextMenu(text);
491
			text.setMenu(menu);
492
		}
493
494
		private void fillContextMenu(IMenuManager menu) {
495
			menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO));
496
			menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO));
497
498
			menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
499
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT));
500
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY));
501
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE));
502
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL));
503
504
			menu.add(new Separator("templates")); //$NON-NLS-1$
505
			menu.appendToGroup("templates", (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$ //$NON-NLS-2$
506
		}
507
508
		private void updateSelectionDependentActions() {
509
			Iterator iterator= fSelectionActions.iterator();
510
			while (iterator.hasNext())
511
				updateAction((String)iterator.next());
512
		}
513
514
		private void updateUndoAction() {
515
			IAction action= (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO);
516
			if (action instanceof IUpdate)
517
				((IUpdate) action).update();
518
		}
519
520
		private void updateAction(String actionId) {
521
			IAction action= (IAction) fGlobalActions.get(actionId);
522
			if (action instanceof IUpdate)
523
				((IUpdate) action).update();
524
		}
525
526
		private int getIndex(String contextid) {
527
528
			if (contextid == null)
529
				return -1;
530
531
			for (int i= 0; i < fContextTypes.length; i++) {
532
				if (contextid.equals(fContextTypes[i][0])) {
533
					return i;
534
				}
535
			}
536
			return -1;
537
		}
538
539
		private void updateButtons() {
540
			StatusInfo status;
541
542
			boolean valid= fNameText == null || fNameText.getText().trim().length() != 0;
543
			if (!valid) {
544
				status = new StatusInfo();
545
				if (!fSuppressError) {
546
					status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname);
547
				}
548
	 		} else {
549
	 			status= fValidationStatus;
550
	 		}
551
			updateStatus(status);
552
		}
553
554
		/*
555
		 * @since 3.1
556
		 */
557
		protected void okPressed() {
558
			String name= fNameText == null ? fOriginalTemplate.getName() : fNameText.getText();
559
			boolean isAutoInsertable= fAutoInsertCheckbox != null && fAutoInsertCheckbox.getSelection();
560
			fNewTemplate= new Template(name, fDescriptionText.getText(), getContextId(), fPatternEditor.getDocument().get(), isAutoInsertable);
561
			super.okPressed();
562
		}
563
564
		/**
565
		 * Returns the created template.
566
		 *
567
		 * @return the created template
568
		 * @since 3.1
569
		 */
570
		public Template getTemplate() {
571
			return fNewTemplate;
572
		}
573
		
574
		/**
575
		 * Returns the content assist processor that
576
		 * suggests template variables.
577
		 * 
578
		 * @return the processor to suggest variables
579
		 * @since 3.3
580
		 */
581
		protected IContentAssistProcessor getTemplateProcessor() {
582
			return fTemplateProcessor;
583
		}
584
585
		/*
586
		 * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
587
		 * @since 3.2
588
		 */
589
		protected IDialogSettings getDialogBoundsSettings() {
590
			String sectionName= this.getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
591
			IDialogSettings settings= TextEditorPlugin.getDefault().getDialogSettings();
592
			IDialogSettings section= settings.getSection(sectionName);
593
			if (section == null)
594
				section= settings.addNewSection(sectionName);
595
			return section;
596
		}
597
598
	}
(-)icons/full/elcl16/edit_template.gif (+7 lines)
Added Link Here
1
GIF89aæôöüõ÷üôöûêïúðóúg}©ùúümƒ­tŠ³s‰²€•»–»ŠžÂáé÷äëø‡œÀ¢Ä‘¥Ç³ÀÖ·ÄÙ½ÉÝÞèøßè÷éïùóöûðôúöøûïôûõøüô÷ûéðù"Cgìòùõøû÷ùûÛÓ¡»´Š|p>{o>{p>†v<ƒs<q=|o>~Bš7y9Œw:©I–|8ܵVÄ£Oàȏ²Š0¯‰1¬‡2¨…3Ú=Û±NÔ²hÔ²iÚ½|Õ²iðبéÄ~öæȓ|W”]•`“xQi8Ži8l>m>pCpD’tJi9ÿÿÿ!ùN,ž€N‚ƒ„…„5ˆ‰ˆ†‚5<5Œ9=>“ƒAD:"
2
4=;6ƒ?AC®!7ƒ@ªB	8ƒE·AEÉ-„LÅL½¿ 1…K·#J.…2I$$H¾ /…3FGMõ(…0
3
 
4
ÿ
5
Rba¡`Á
6
7
ª(db…‰%Nœ(±Â!£‹ƒ;
(-)icons/full/elcl16/collapse_expand_all.gif (+5 lines)
Added Link Here
1
GIF89aÕ"·Òä>r§2]’z9¯‰1©…3 5¤ƒ4œ5¬‡2w9²Š0}q=~p=–|7p†°iªs‰²mƒ®k¬ôüÿøýÿþþÿüÿÿùýÿöüÿwŒ´uŠ²úþÿüþÿýþÿ~q=(b–ùþÿÿÿÿ!ù",p@‘P$ ‹Å¡p°. X(E„€'À	T”ášð˜ÏçĵÐi»Ý…ë!D¯×WCÄïƒBW!!W{~|!Wv—W
2
—v
3
WœuŸ¡t£J ¥§J
4
5
±±W´µ"A;
(-)src/org/eclipse/ui/texteditor/templates/ITemplateViewImageConstants.java (+19 lines)
Added Link Here
1
package org.eclipse.ui.texteditor.templates;
2
3
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
4
5
/**
6
 * Image constants for the template page
7
 * 
8
 * @author kd
9
 * 
10
 */
11
public interface ITemplateViewImageConstants {
12
	public static final String PREFIX = TextEditorPlugin.PLUGIN_ID + "."; //$NON-NLS-1$
13
14
	public final static String IMG_TEMPLATE_NEW = PREFIX + "new_template.gif"; //$NON-NLS-1$
15
	public static final String IMG_TEMPLATE_DELETE = "delete_template.gif"; //$NON-NLS-1$
16
	public final static String IMG_TEMPLATE_EDIT = PREFIX + "edit_template.gif"; //$NON-NLS-1$
17
	public static final String IMG_TEMPLATE_LINK = "link_to_editor.gif"; //$NON-NLS-1$
18
	public static final String IMG_TEMPLATE_COLLAPSE_EXPAND = "collapse_expand_all.gif"; //$NON-NLS-1$
19
}
(-)icons/full/elcl16/link_to_editor.gif (+1 lines)
Added Link Here
1
GIF89a³½„ªo¦küì±ûå—üñÃýñÃþýïüê©ýöÕº—&þøÞþøÝýøÝûì±ÿÿÿ!ù,MðÉÀ¼˜›18[wL³Th5†Á/\bx>cAì¢IHQˆp#€18ù¨<©JbʑŽv»­>à°ÀG0¿>óy¬^·;
(-)src/org/eclipse/ui/texteditor/templates/TemplateTransfer.java (+179 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2005 IBM Corporation 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
 *     IBM Corporation - 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
 */
30
public class TemplateTransfer extends ByteArrayTransfer {
31
32
	private static TemplateTransfer instance;
33
34
	private static final String LOCAL_NAME = TemplateTransfer.class.getName()
35
			+ System.currentTimeMillis();
36
	private static final int LOCAL_TYPE = registerType(LOCAL_NAME);
37
38
	private static String[] names = null;
39
	private static int types[] = null;
40
41
	/**
42
	 * @return the registered Transfer instance
43
	 */
44
	public static TemplateTransfer getInstance() {
45
		if (instance == null) {
46
			instance = new TemplateTransfer();
47
			types = new int[] { LOCAL_TYPE };
48
			names = new String[] { LOCAL_NAME };
49
		}
50
		return instance;
51
	}
52
53
	/*
54
	 * (non-Javadoc)
55
	 * 
56
	 * @see org.eclipse.swt.dnd.Transfer#getTypeIds()
57
	 */
58
	protected int[] getTypeIds() {
59
		return types;
60
	}
61
62
	/*
63
	 * (non-Javadoc)
64
	 * 
65
	 * @see org.eclipse.swt.dnd.Transfer#getTypeNames()
66
	 */
67
	protected String[] getTypeNames() {
68
		return names;
69
	}
70
71
	/*
72
	 * (non-Javadoc)
73
	 * 
74
	 * @see org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(java.lang.Object,
75
	 *      org.eclipse.swt.dnd.TransferData)
76
	 */
77
	protected void javaToNative(Object object, TransferData transferData) {
78
		if (object == null || !(object instanceof Template[])
79
				|| !isSupportedType(transferData))
80
			return;
81
		ByteArrayOutputStream out = new ByteArrayOutputStream();
82
		DataOutputStream dataOut = new DataOutputStream(out);
83
		Template[] templates = (Template[]) object;
84
		for (int i = 0; i < templates.length; i++) {
85
			writeTemplate(dataOut, templates[i]);
86
		}
87
		byte[] byteArray = out.toByteArray();
88
		try {
89
			dataOut.close();
90
		} catch (IOException e) {
91
		}
92
		super.javaToNative(byteArray, transferData);
93
	}
94
95
	/**
96
	 * Write a template to the output stream
97
	 * 
98
	 * @param dataOut
99
	 * @param template
100
	 */
101
	private void writeTemplate(DataOutputStream dataOut, Template template) {
102
		try {
103
			writeString(dataOut, template.getName());
104
			writeString(dataOut, template.getDescription());
105
			writeString(dataOut, template.getContextTypeId());
106
			writeString(dataOut, template.getPattern());
107
			dataOut.writeBoolean(template.isAutoInsertable());
108
		} catch (IOException e) {
109
		}
110
	}
111
112
	/**
113
	 * Write a string to the output stream
114
	 * 
115
	 * @param dataOut
116
	 * @param name
117
	 * @throws IOException
118
	 */
119
	private void writeString(DataOutputStream dataOut, String name)
120
			throws IOException {
121
		byte[] bytes = name.getBytes();
122
		dataOut.writeInt(bytes.length);
123
		dataOut.write(bytes);
124
	}
125
126
	/*
127
	 * (non-Javadoc)
128
	 * 
129
	 * @see org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(org.eclipse.swt.dnd.TransferData)
130
	 */
131
	protected Object nativeToJava(TransferData transferData) {
132
		byte[] bytes = (byte[]) super.nativeToJava(transferData);
133
		if (bytes == null)
134
			return null;
135
		ArrayList listTemplates = new ArrayList();
136
		ByteArrayInputStream in = new ByteArrayInputStream(bytes);
137
		DataInputStream dataIn = new DataInputStream(in);
138
		try {
139
			while (dataIn.available() > 0) {
140
				Template template = readTempate(dataIn);
141
				if (template == null)
142
					break;
143
				listTemplates.add(template);
144
			}
145
		} catch (IOException e) {
146
		} finally {
147
			try {
148
				dataIn.close();
149
			} catch (IOException e) {
150
			}
151
		}
152
		return listTemplates.toArray(new Template[listTemplates.size()]);
153
	}
154
155
	/**
156
	 * Read a template from the data input stream.
157
	 * 
158
	 * @param dataIn
159
	 * @return the template
160
	 * @throws IOException
161
	 */
162
	private Template readTempate(DataInputStream dataIn) throws IOException {
163
		return new Template(readString(dataIn), readString(dataIn),
164
				readString(dataIn), readString(dataIn), dataIn.readBoolean());
165
	}
166
167
	/**
168
	 * Read a string from the data input stream
169
	 * 
170
	 * @param dataIn
171
	 * @return the string
172
	 * @throws IOException
173
	 */
174
	private String readString(DataInputStream dataIn) throws IOException {
175
		byte[] bytes = new byte[dataIn.readInt()];
176
		dataIn.read(bytes);
177
		return new String(bytes);
178
	}
179
}
(-)icons/full/elcl16/new_template.gif (+4 lines)
Added Link Here
1
GIF89a櫤©ª£¨ª¢¨¶°µ´®³²¬±°ª¯®¨­¬¦«¬¥««¤ªª¢©²¬²°ª°·²·µ±µ³¯´¹µº¸´¹†“°†“¯…“°†”°…“¯†”¯ˆ•®…”°…”¯ˆ•­Œ—«˜«š¨•¥íùÿðúÿ™Ÿ¢óûÿöüÿìùÿïúÿëùÿîúÿñûÿšŸ¡õüÿøýÿìúÿôüÿëúÿïûÿóüÿ÷ýÿòüÿŸ£Ÿž¢ž£¦›£¥›¨¨˜­¬”¹·£¹³‹¶±Ž²®‘®«”³°šº·¢¼µŠ¶°Â¿­Á¾­¿¶ˆ³¯šº¶£ÊǸ¾­ÓÐÃËǸËǹÜÙÏÔÐÄÜÙÐäáÙàȏÝÙÏÔ²iÚ½|ÜØÏåáÙëèâåàÙëçâðìèÿÿÿ!ù\,²€\‚ƒ„…ƒFˆ‰‰†\B--TF†<3˜™UT<…=%[¢¢R›C„>%ZXZ¬Z%>„:/YWQ¹Q,?„92SNPVVN/9„74OÑKÑ$8„5*
2
IÜLIM*6„#"EDDJJE1+„ );HHõA	' „!
3
@Ž@Š„<¸°@€Ã‡!:ʀŒŠ(L¸p‚¡	4P¸€ä†4
4
;
(-)icons/full/elcl16/delete_template.gif (+5 lines)
Added Link Here
1
GIF89aÕÇ35ôqtôstórtósuØ*/à,4ß,3Ç)0æ6>å6>Å +å09òU`ôckócjóckódkÅ'Æ(Å'Æ ,òT`Å%ñ?Rð?QòHXñHXÔetߜ¨Ê]IÎn^ÊWFÊXFÉXFՈ|ÉPCܦ ÉG>ÉG?ÈG?Ç=9àa[õ}Ç=:ãROõ€~ô€~ãÄÄÿÿÿ!ù1,|À˜pH,F˜gTy`DX¨b
2
G¢*,‘\+Ò§ô!½Â%âE¨LªAàd%rXÈÃñHq
3
4
5
	H1H””E”˜B ¦C0¨C«\B±£B«¹ˆÀÁBA;
(-)src/org/eclipse/ui/texteditor/templates/TemplateViewImages.java (+154 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation 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
 *     IBM Corporation - initial API and implementation
10
 *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49380, 49445, 53547
11
 *******************************************************************************/
12
package org.eclipse.ui.texteditor.templates;
13
14
import java.net.URL;
15
16
import org.eclipse.core.runtime.FileLocator;
17
import org.eclipse.core.runtime.Path;
18
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.jface.resource.ImageDescriptor;
20
import org.eclipse.jface.resource.ImageRegistry;
21
import org.eclipse.swt.graphics.Image;
22
import org.eclipse.swt.widgets.Display;
23
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
24
import org.osgi.framework.Bundle;
25
26
/**
27
 * The images provided by the texteditor plugin
28
 */
29
public class TemplateViewImages {
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 LOCALTOOL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$
41
42
	/**
43
	 * Declare all images
44
	 */
45
	private static void declareImages() {
46
		// Ant Editor images
47
		declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_NEW,
48
				LOCALTOOL + "new_template.gif"); //$NON-NLS-1$
49
		declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_DELETE,
50
				LOCALTOOL + "delete_template.gif"); //$NON-NLS-1$
51
		declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_EDIT,
52
				LOCALTOOL + "edit_template.gif"); //$NON-NLS-1$
53
		declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_LINK,
54
				LOCALTOOL + "link_to_editor.gif"); //$NON-NLS-1$
55
		declareRegistryImage(
56
				ITemplateViewImageConstants.IMG_TEMPLATE_COLLAPSE_EXPAND,
57
				LOCALTOOL + "collapse_expand_all.gif"); //$NON-NLS-1$
58
	}
59
60
	/**
61
	 * Declare an Image in the registry table.
62
	 * 
63
	 * @param key
64
	 *            The key to use when registering the image
65
	 * @param path
66
	 *            The path where the image can be found. This path is relative
67
	 *            to where this plugin class is found (i.e. typically the
68
	 *            packages directory)
69
	 */
70
	private final static void declareRegistryImage(String key, String path) {
71
		ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor();
72
		Bundle bundle = Platform.getBundle(TextEditorPlugin.PLUGIN_ID);
73
		URL url = null;
74
		if (bundle != null) {
75
			url = FileLocator.find(bundle, new Path(path), null);
76
			desc = ImageDescriptor.createFromURL(url);
77
		}
78
		imageRegistry.put(key, desc);
79
	}
80
81
	/**
82
	 * Returns the ImageRegistry.
83
	 * 
84
	 * @return image registry
85
	 */
86
	public static ImageRegistry getImageRegistry() {
87
		if (imageRegistry == null) {
88
			initializeImageRegistry();
89
		}
90
		return imageRegistry;
91
	}
92
93
	/**
94
	 * Initialize the image registry by declaring all of the required graphics.
95
	 * This involves creating JFace image descriptors describing how to
96
	 * create/find the image should it be needed. The image is not actually
97
	 * allocated until requested.
98
	 * 
99
	 * Prefix conventions Wizard Banners WIZBAN_ Preference Banners PREF_BAN_
100
	 * Property Page Banners PROPBAN_ Color toolbar CTOOL_ Enable toolbar ETOOL_
101
	 * Disable toolbar DTOOL_ Local enabled toolbar ELCL_ Local Disable toolbar
102
	 * DLCL_ Object large OBJL_ Object small OBJS_ View VIEW_ Product images
103
	 * PROD_ Misc images MISC_
104
	 * 
105
	 * Where are the images? The images (typically gifs) are found in the same
106
	 * location as this plugin class. This may mean the same package directory
107
	 * as the package holding this class. The images are declared using
108
	 * this.getClass() to ensure they are looked up via this plugin class.
109
	 * 
110
	 * @return the image registry
111
	 * @see org.eclipse.jface.resource.ImageRegistry
112
	 */
113
	public static ImageRegistry initializeImageRegistry() {
114
		imageRegistry = new ImageRegistry(getStandardDisplay());
115
		declareImages();
116
		return imageRegistry;
117
	}
118
119
	/**
120
	 * Returns the standard display to be used. The method first checks, if the
121
	 * thread calling this method has an associated display. If so, this display
122
	 * is returned. Otherwise the method returns the default display.
123
	 * 
124
	 * @return the display
125
	 */
126
	public static Display getStandardDisplay() {
127
		Display display = Display.getCurrent();
128
		if (display == null) {
129
			display = Display.getDefault();
130
		}
131
		return display;
132
	}
133
134
	/**
135
	 * Returns the <code>Image<code> identified by the given key,
136
	 * or <code>null</code> if it does not exist.
137
	 * @param key 
138
	 * @return the image
139
	 */
140
	public static Image getImage(String key) {
141
		return getImageRegistry().get(key);
142
	}
143
144
	/**
145
	 * Returns the <code>ImageDescriptor<code> identified by the given key,
146
	 * or <code>null</code> if it does not exist.
147
	 * @param key 
148
	 * @return the image descriptor
149
	 */
150
	public static ImageDescriptor getImageDescriptor(String key) {
151
		return getImageRegistry().getDescriptor(key);
152
	}
153
154
}
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.java (-1 / +11 lines)
Lines 41-52 Link Here
41
import org.eclipse.jface.text.ITextOperationTarget;
41
import org.eclipse.jface.text.ITextOperationTarget;
42
import org.eclipse.jface.text.ITextSelection;
42
import org.eclipse.jface.text.ITextSelection;
43
import org.eclipse.jface.text.Region;
43
import org.eclipse.jface.text.Region;
44
import org.eclipse.jface.text.templates.Template;
44
45
45
import org.eclipse.ui.IWorkbenchPartSite;
46
import org.eclipse.ui.IWorkbenchPartSite;
46
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
47
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
47
import org.eclipse.ui.texteditor.ITextEditor;
48
import org.eclipse.ui.texteditor.ITextEditor;
48
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
49
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
49
import org.eclipse.ui.texteditor.TextEditorAction;
50
import org.eclipse.ui.texteditor.TextEditorAction;
51
import org.eclipse.ui.texteditor.templates.TemplateTransfer;
52
53
import org.eclipse.ui.views.templates.ITemplatesPage;
50
54
51
import org.eclipse.jdt.core.ICompilationUnit;
55
import org.eclipse.jdt.core.ICompilationUnit;
52
import org.eclipse.jdt.core.IJavaElement;
56
import org.eclipse.jdt.core.IJavaElement;
Lines 66-71 Link Here
66
import org.eclipse.jdt.ui.PreferenceConstants;
70
import org.eclipse.jdt.ui.PreferenceConstants;
67
71
68
import org.eclipse.jdt.internal.ui.JavaPlugin;
72
import org.eclipse.jdt.internal.ui.JavaPlugin;
73
import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage;
69
74
70
75
71
/**
76
/**
Lines 489-495 Link Here
489
				}
494
				}
490
			}
495
			}
491
		} else {
496
		} else {
492
			fOperationTarget.doOperation(fOperationCode);
497
			Template[] templates= (Template[]) clipboard.getContents(TemplateTransfer.getInstance());
498
			if (templates != null) {
499
				JavaTemplatesPage page= (JavaTemplatesPage) editor.getAdapter(ITemplatesPage.class);
500
				page.insertTemplate(templates[0]);
501
			} else
502
				fOperationTarget.doOperation(fOperationCode);
493
		}
503
		}
494
	}
504
	}
495
505
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java (+19 lines)
Lines 141-146 Link Here
141
141
142
import org.eclipse.ui.views.contentoutline.ContentOutline;
142
import org.eclipse.ui.views.contentoutline.ContentOutline;
143
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
143
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
144
import org.eclipse.ui.views.templates.ITemplatesPage;
144
145
145
import org.eclipse.jdt.core.IClassFile;
146
import org.eclipse.jdt.core.IClassFile;
146
import org.eclipse.jdt.core.ICompilationUnit;
147
import org.eclipse.jdt.core.ICompilationUnit;
Lines 194-199 Link Here
194
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
195
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
195
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
196
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
196
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
197
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
198
import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage;
197
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
199
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
198
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
200
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
199
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
201
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
Lines 1333-1338 Link Here
1333
	protected JavaOutlinePage fOutlinePage;
1335
	protected JavaOutlinePage fOutlinePage;
1334
	/** Outliner context menu Id */
1336
	/** Outliner context menu Id */
1335
	protected String fOutlinerContextMenuId;
1337
	protected String fOutlinerContextMenuId;
1338
	/** The templates page */
1339
	private JavaTemplatesPage fTemplatesPage;
1340
	
1336
	/**
1341
	/**
1337
	 * The editor selection changed listener.
1342
	 * The editor selection changed listener.
1338
	 *
1343
	 *
Lines 1778-1783 Link Here
1778
			return fOutlinePage;
1783
			return fOutlinePage;
1779
		}
1784
		}
1780
1785
1786
		if (required.equals(ITemplatesPage.class)) {
1787
			return getTemplatesPage();
1788
		}
1789
1781
		if (IEncodingSupport.class.equals(required))
1790
		if (IEncodingSupport.class.equals(required))
1782
			return fEncodingSupport;
1791
			return fEncodingSupport;
1783
1792
Lines 1832-1837 Link Here
1832
		return super.getAdapter(required);
1841
		return super.getAdapter(required);
1833
	}
1842
	}
1834
1843
1844
	private JavaTemplatesPage getTemplatesPage() {
1845
		if (fTemplatesPage == null) {
1846
			fTemplatesPage= new JavaTemplatesPage(this);
1847
1848
		}
1849
		return fTemplatesPage;
1850
	}
1851
1835
	/**
1852
	/**
1836
	 * React to changed selection.
1853
	 * React to changed selection.
1837
	 *
1854
	 *
Lines 3225-3230 Link Here
3225
	protected void handleCursorPositionChanged() {
3242
	protected void handleCursorPositionChanged() {
3226
		super.handleCursorPositionChanged();
3243
		super.handleCursorPositionChanged();
3227
		fCachedSelectedRange= getViewer().getSelectedRange();
3244
		fCachedSelectedRange= getViewer().getSelectedRange();
3245
		if (fTemplatesPage != null)
3246
			fTemplatesPage.cursorPositionChanged();
3228
	}
3247
	}
3229
3248
3230
	private static boolean isBracket(char character) {
3249
	private static boolean isBracket(char character) {
(-)ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java (+258 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation 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
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui.preferences;
12
13
import org.eclipse.swt.SWT;
14
import org.eclipse.swt.graphics.Font;
15
import org.eclipse.swt.graphics.Point;
16
import org.eclipse.swt.layout.GridData;
17
import org.eclipse.swt.widgets.Composite;
18
import org.eclipse.swt.widgets.Control;
19
20
import org.eclipse.jface.preference.IPreferenceStore;
21
import org.eclipse.jface.resource.JFaceResources;
22
import org.eclipse.jface.window.Window;
23
24
import org.eclipse.jface.text.BadLocationException;
25
import org.eclipse.jface.text.Document;
26
import org.eclipse.jface.text.IDocument;
27
import org.eclipse.jface.text.ITextSelection;
28
import org.eclipse.jface.text.Position;
29
import org.eclipse.jface.text.Region;
30
import org.eclipse.jface.text.TextSelection;
31
import org.eclipse.jface.text.TextUtilities;
32
import org.eclipse.jface.text.source.ISourceViewer;
33
import org.eclipse.jface.text.source.SourceViewer;
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
38
import org.eclipse.ui.PlatformUI;
39
import org.eclipse.ui.part.FileEditorInput;
40
import org.eclipse.ui.texteditor.templates.TemplatesPage;
41
42
import org.eclipse.jdt.core.ICompilationUnit;
43
import org.eclipse.jdt.core.JavaCore;
44
45
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext;
46
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType;
47
import org.eclipse.jdt.internal.corext.template.java.JavaContextType;
48
import org.eclipse.jdt.internal.corext.template.java.JavaDocContextType;
49
50
import org.eclipse.jdt.ui.PreferenceConstants;
51
import org.eclipse.jdt.ui.text.IJavaPartitions;
52
import org.eclipse.jdt.ui.text.JavaTextTools;
53
54
import org.eclipse.jdt.internal.ui.JavaPlugin;
55
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
56
import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
57
import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
58
import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal;
59
import org.eclipse.jdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
60
61
/**
62
 * A TemplatesPage implementation for Java CompilationUnitEditor
63
 * 
64
 * @author kd
65
 */
66
public class JavaTemplatesPage extends TemplatesPage {
67
68
	private static final ContextTypeRegistry TEMPLATE_CONTEXT_REGISTRY= JavaPlugin.getDefault().getTemplateContextRegistry();
69
	private TemplateVariableProcessor fTemplateProcessor;
70
	private ScrolledPageContent fScrolled;
71
	private final JavaEditor fEditor;
72
	private IDocument fDocument;
73
	private String fJavaDocId;
74
	private String fJavaId;
75
	private String fCurrentId;
76
77
	/**
78
	 * @param javaEditor
79
	 */
80
	public JavaTemplatesPage(JavaEditor javaEditor) {
81
		fEditor= javaEditor;
82
		setTemplateStore(JavaPlugin.getDefault().getTemplateStore(), JavaPlugin.getDefault().getPreferenceStore());
83
		setContextTypeRegistry(TEMPLATE_CONTEXT_REGISTRY);
84
		fJavaDocId= new JavaDocContextType().getId();
85
		fJavaId= new JavaContextType().getId();
86
		fTemplateProcessor= new TemplateVariableProcessor();
87
		fDocument= fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
88
		cursorPositionChanged();
89
		setupEditorDropTarget(fEditor.getSite(), fEditor.getViewer().getTextWidget());
90
	}
91
92
	public void dispose() {
93
		super.dispose();
94
	}
95
96
	/* (non-Javadoc)
97
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#createControl(org.eclipse.swt.widgets.Composite)
98
	 */
99
	public void createControl(Composite ancestor) {
100
		fScrolled= new ScrolledPageContent(ancestor, SWT.H_SCROLL | SWT.V_SCROLL);
101
		fScrolled.setExpandHorizontal(true);
102
		fScrolled.setExpandVertical(true);
103
104
		super.createControl(fScrolled);
105
		Control control= super.getControl();
106
107
		fScrolled.setContent(control);
108
		final Point size= control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
109
		fScrolled.setMinSize(size.x, size.y);
110
	}
111
112
	/* (non-Javadoc)
113
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#editTemplate(org.eclipse.jface.text.templates.Template, boolean, boolean)
114
	 */
115
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
116
		EditTemplateDialog dialog= new EditTemplateDialog(getShell(), template, edit, isNameModifiable, getContextTypeRegistry());
117
		if (dialog.open() == Window.OK) {
118
			return dialog.getTemplate();
119
		}
120
		return null;
121
	}
122
123
	/* (non-Javadoc)
124
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#createViewer(org.eclipse.swt.widgets.Composite)
125
	 */
126
	protected SourceViewer createViewer(Composite parent) {
127
		IDocument document= new Document();
128
		JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools();
129
		tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
130
		IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
131
		SourceViewer viewer= new JavaSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
132
		SimpleJavaSourceViewerConfiguration configuration= new SimpleJavaSourceViewerConfiguration(tools.getColorManager(), store, null, IJavaPartitions.JAVA_PARTITIONING, false);
133
		viewer.configure(configuration);
134
		viewer.setEditable(false);
135
		viewer.setDocument(document);
136
137
		Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
138
		viewer.getTextWidget().setFont(font);
139
		new JavaSourcePreviewerUpdater(viewer, configuration, store);
140
141
		Control control= viewer.getControl();
142
		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
143
		control.setLayoutData(data);
144
145
		return viewer;
146
	}
147
148
149
	/* (non-Javadoc)
150
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#updateViewerInput(org.eclipse.jface.text.templates.Template)
151
	 */
152
	protected void updateViewerInput(Template template) {
153
		SourceViewer viewer= getViewer();
154
155
		String contextId= template.getContextTypeId();
156
		TemplateContextType type= TEMPLATE_CONTEXT_REGISTRY.getContextType(contextId);
157
		fTemplateProcessor.setContextType(type);
158
159
		IDocument doc= viewer.getDocument();
160
161
		String start= null;
162
		if ("javadoc".equals(contextId)) { //$NON-NLS-1$
163
			start= "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
164
		} else
165
			start= ""; //$NON-NLS-1$
166
167
		doc.set(start + template.getPattern());
168
		int startLen= start.length();
169
		viewer.setDocument(doc, startLen, doc.getLength() - startLen);
170
	}
171
172
	/* (non-Javadoc)
173
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getControl()
174
	 */
175
	public Control getControl() {
176
		return fScrolled;
177
	}
178
179
	/* (non-Javadoc)
180
	 * @see org.eclipse.ui.part.Page#setFocus()
181
	 */
182
	public void setFocus() {
183
	}
184
185
	/* (non-Javadoc)
186
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId()
187
	 */
188
	protected String getPreferencePageId() {
189
		return "org.eclipse.jdt.ui.preferences.JavaTemplatePreferencePage"; //$NON-NLS-1$
190
	}
191
192
	/* (non-Javadoc)
193
	 * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template)
194
	 */
195
	public void insertTemplate(Template template) {
196
		if (!fEditor.isEditorInputModifiable())
197
			return;
198
		TemplateContextType type= TEMPLATE_CONTEXT_REGISTRY.getContextType(template.getContextTypeId());
199
		if (type == null)
200
			return;
201
		ISourceViewer contextViewer= fEditor.getViewer();
202
		ITextSelection textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
203
		IDocument document= contextViewer.getDocument();
204
		/*
205
		 * The Editor checks whether a completion for a word exists before it allows for the template to be
206
		 * applied. We pickup the current text at the selection position and replace it with the first char
207
		 * of the template name for this to succeed.
208
		 * We don't need to go through this, if the editors simply support applyTemplate(Template).
209
		 */
210
		String savedText;
211
		try {
212
			savedText= document.get(textSelection.getOffset(), textSelection.getLength());
213
			document.replace(textSelection.getOffset(), textSelection.getLength(), template.getName().substring(0, 1));
214
		} catch (BadLocationException e) {
215
			e.printStackTrace();
216
			return;
217
		}
218
		Position position= new Position(textSelection.getOffset() + 1, 0);
219
		Region region= new Region(textSelection.getOffset() + 1, 0);
220
		contextViewer.getSelectionProvider().setSelection(new TextSelection(textSelection.getOffset(), 1));
221
		ICompilationUnit compilationUnit= JavaCore.createCompilationUnitFrom(((FileEditorInput) fEditor.getEditorInput()).getFile());
222
223
		CompilationUnitContext context= ((CompilationUnitContextType) type).createContext(document, position, compilationUnit);
224
		context.setVariable("selection", savedText); //$NON-NLS-1$
225
		if (context.getKey().length() == 0) {
226
			try {
227
				document.replace(textSelection.getOffset(), 1, savedText);
228
			} catch (BadLocationException e) {
229
				e.printStackTrace();
230
				return;
231
			}
232
		}
233
		TemplateProposal proposal= new TemplateProposal(template, context, region, null);
234
		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(fEditor);
235
		proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset());
236
	}
237
238
	/**
239
	 * Invoked by the editor whenever the caret position is updated
240
	 */
241
	public void cursorPositionChanged() {
242
		Point selectedRange= fEditor.getViewer().getSelectedRange();
243
		int cursor= selectedRange.x + selectedRange.y;
244
		String partition;
245
		try {
246
			partition= TextUtilities.getContentType(fDocument, IJavaPartitions.JAVA_PARTITIONING, cursor, true);
247
		} catch (BadLocationException e) {
248
			return;
249
		}
250
		String id= fJavaId;
251
		if (partition.equals(IJavaPartitions.JAVA_DOC))
252
			id= fJavaDocId;
253
		if (!id.equals(fCurrentId)) {
254
			fCurrentId= id;
255
			contextTypeChanged(new String[] { id });
256
		}
257
	}
258
}

Return to bug 69581