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

Collapse All | Expand All

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

Return to bug 69581