### Eclipse Workspace Patch 1.0 #P org.eclipse.ant.ui Index: Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties,v retrieving revision 1.22 diff -u -r1.22 AntEditorMessages.properties --- Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties 27 Mar 2006 19:08:01 -0000 1.22 +++ Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties 31 Jul 2007 18:04:27 -0000 @@ -41,3 +41,8 @@ AntAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line AntEditor.3=Current text selection does not resolve to an Ant reference + +Editor.Paste.label=&Paste +Editor.Paste.tooltip=Paste +Editor.Paste.image= +Editor.Paste.description=Paste Index: Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditor.java,v retrieving revision 1.109 diff -u -r1.109 AntEditor.java --- Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditor.java 20 Mar 2007 22:09:34 -0000 1.109 +++ Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditor.java 31 Jul 2007 18:04:27 -0000 @@ -34,6 +34,7 @@ import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter; import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction; import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage; +import org.eclipse.ant.internal.ui.editor.templates.AntTemplatesPage; import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider; import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider; import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant; @@ -71,6 +72,7 @@ import org.eclipse.jface.text.ISelectionValidator; import org.eclipse.jface.text.ISynchronizable; import org.eclipse.jface.text.ITextInputListener; +import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Position; @@ -85,6 +87,7 @@ import org.eclipse.jface.text.source.projection.IProjectionListener; import org.eclipse.jface.text.source.projection.ProjectionSupport; import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.jface.viewers.ISelection; @@ -93,6 +96,7 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Image; @@ -112,16 +116,55 @@ import org.eclipse.ui.texteditor.ContentAssistAction; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IEditorStatusLine; +import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; +import org.eclipse.ui.texteditor.TextEditorAction; import org.eclipse.ui.texteditor.TextOperationAction; +import org.eclipse.ui.texteditor.templates.TemplateTransfer; import org.eclipse.ui.views.contentoutline.ContentOutline; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.templates.ITemplatesPage; /** * The actual editor implementation for Eclipse's Ant integration. */ public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener { + + class ClipboardPasteOperation extends TextEditorAction { + private ITextOperationTarget fOperationTarget; + private int fOperationCode = -1; + + protected ClipboardPasteOperation(ResourceBundle bundle, String prefix, ITextEditor editor, + int style) { + super(bundle, prefix, editor, style); + } + + public void run() { + ITextEditor editor = getTextEditor(); + Clipboard clipboard = new Clipboard(getSite().getShell().getDisplay()); + Template[] templates = (Template[]) clipboard.getContents(TemplateTransfer + .getInstance()); + if (templates != null) { + AntTemplatesPage page = (AntTemplatesPage) editor.getAdapter(ITemplatesPage.class); + page.insertTemplate(templates[0]); + } else + fOperationTarget.doOperation(fOperationCode); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + super.update(); + } + + } + + /** * Updates the Ant outline page selection and this editor's range indicator. * @@ -461,7 +504,10 @@ * The page that shows the outline. */ protected AntEditorContentOutlinePage fOutlinePage; - + /** + * The templates page + */ + protected AntTemplatesPage fTemplatesPage; private boolean fInitialReconcile= true; @@ -538,6 +584,12 @@ action= new RenameInFileAction(this); action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$ setAction("renameInFile", action); //$NON-NLS-1$ + + // Override the TextEditor paste operation to support templates + action = new ClipboardPasteOperation(bundle, + "Editor.Paste.", this, ITextOperationTarget.PASTE); //$NON-NLS-1$ + action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE); + setAction(ITextEditorActionConstants.PASTE, action); } /* @@ -564,6 +616,10 @@ return getOutlinePage(); } + if (key.equals(ITemplatesPage.class)) { + return getTemplatesPage(); + } + if (fProjectionSupport != null) { Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key); if (adapter != null) { @@ -599,6 +655,19 @@ return fOutlinePage; } + private AntTemplatesPage getTemplatesPage() { + if (fTemplatesPage == null) { + fTemplatesPage = new AntTemplatesPage(this); + } + return fTemplatesPage; + } + + protected void handleCursorPositionChanged() { + super.handleCursorPositionChanged(); + if (fTemplatesPage != null) + fTemplatesPage.cursorPositionChanged(); + } + private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) { IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection(); Index: Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplatesPage.java =================================================================== RCS file: Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplatesPage.java diff -N Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplatesPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplatesPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 John-Mason P. Shackelford and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * John-Mason P. Shackelford - initial API and implementation + * IBM Corporation - bug fixes + *******************************************************************************/ +package org.eclipse.ant.internal.ui.editor.templates; + +import org.eclipse.ant.internal.ui.AntUIPlugin; +import org.eclipse.ant.internal.ui.editor.AntEditor; +import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences; +import org.eclipse.ant.internal.ui.editor.formatter.XmlFormatter; +import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant; +import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.templates.ContextTypeRegistry; +import org.eclipse.jface.text.templates.Template; +import org.eclipse.jface.text.templates.TemplateContextType; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.texteditor.templates.TemplatesPage; + +/** + * An implementation of TemplatesPage for AntEditor + * + * @see TemplatesPage + */ +public class AntTemplatesPage extends TemplatesPage { + + private static final ContextTypeRegistry CONTEXT_TYPE_REGISTRY = AntTemplateAccess + .getDefault().getContextTypeRegistry(); + private FormattingPreferences fFormattingPreferences = new FormattingPreferences(); + private final AntEditor fEditor; + private String fCurrentId; + + /** + * Constructor + * + * @param editor + */ + public AntTemplatesPage(AntEditor editor) { + fEditor = editor; + setTemplateStore(AntTemplateAccess.getDefault().getTemplateStore(), + AntUIPlugin.getDefault().getPreferenceStore()); + setContextTypeRegistry(CONTEXT_TYPE_REGISTRY); + cursorPositionChanged(); + setupEditorDropTarget(fEditor.getSite(), fEditor.getViewer() + .getTextWidget()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#createViewer(org.eclipse.swt.widgets.Composite) + */ + protected SourceViewer createViewer(Composite parent) { + SourceViewer viewer = new SourceViewer(parent, null, SWT.BORDER + | SWT.V_SCROLL | SWT.H_SCROLL); + + SourceViewerConfiguration configuration = new AntTemplateViewerConfiguration(); + IDocument document = new Document(); + new AntDocumentSetupParticipant().setup(document); + viewer.configure(configuration); + viewer.setDocument(document); + viewer.setEditable(false); + Font font = JFaceResources.getFont(JFaceResources.TEXT_FONT); + viewer.getTextWidget().setFont(font); + + return viewer; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#getFormatterPreferenceKey() + */ + protected String getFormatterPreferenceKey() { + return AntEditorPreferenceConstants.TEMPLATES_USE_CODEFORMATTER; + } + + /* + * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#updateViewerInput() + */ + protected void updateViewerInput(Template template) { + SourceViewer viewer = getViewer(); + + if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean( + getFormatterPreferenceKey())) { + String formatted = XmlFormatter.format(template.getPattern(), + fFormattingPreferences); + viewer.getDocument().set(formatted); + } else { + viewer.getDocument().set(template.getPattern()); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.Page#setFocus() + */ + public void setFocus() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId() + */ + protected String getPreferencePageId() { + return "org.eclipse.ant.ui.TemplatesPreferencePage"; //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template) + */ + public void insertTemplate(Template template) { + IRegion region; + TemplateContextType type = CONTEXT_TYPE_REGISTRY + .getContextType(template.getContextTypeId()); + if (type == null) + return; + ISourceViewer contextViewer = fEditor.getViewer(); + ITextSelection textSelection = (ITextSelection) contextViewer + .getSelectionProvider().getSelection(); + region = new Region(textSelection.getOffset(), textSelection + .getLength()); + Point selection = contextViewer.getSelectedRange(); + Position position; + if (selection.y > 0) { + position = new Position(selection.x, selection.y); + } else { + position = new Position(region.getOffset(), region.getLength()); + } + + IDocument document = contextViewer.getDocument(); + AntContext context = new AntContext(type, document, fEditor + .getAntModel(), position); + context.setVariable("selection", textSelection.getText()); //$NON-NLS-1$ + AntTemplateProposal proposal = new AntTemplateProposal(template, + context, region, null, 100); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .activate(fEditor); + proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset()); + } + + /** + * Invoked by the editor whenever the caret position is updated + */ + public void cursorPositionChanged() { + String id; + if (fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()) + .getLength() == 0) + id = BuildFileContextType.BUILDFILE_CONTEXT_TYPE; + else + id = TargetContextType.TARGET_CONTEXT_TYPE; + if (id.equals(fCurrentId)) + return; + fCurrentId = id; + if (fCurrentId.equals(BuildFileContextType.BUILDFILE_CONTEXT_TYPE)) + contextTypeChanged(new String[] { BuildFileContextType.BUILDFILE_CONTEXT_TYPE }); + else + contextTypeChanged(new String[] { + TargetContextType.TARGET_CONTEXT_TYPE, + TaskContextType.TASK_CONTEXT_TYPE }); + } +} #P org.eclipse.ui.views Index: META-INF/MANIFEST.MF =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views/META-INF/MANIFEST.MF,v retrieving revision 1.9 diff -u -r1.9 MANIFEST.MF --- META-INF/MANIFEST.MF 7 Sep 2006 19:17:20 -0000 1.9 +++ META-INF/MANIFEST.MF 31 Jul 2007 18:04:29 -0000 @@ -11,7 +11,8 @@ org.eclipse.ui.internal.views.contentoutline;x-internal:=true, org.eclipse.ui.internal.views.properties;x-internal:=true, org.eclipse.ui.views.contentoutline, - org.eclipse.ui.views.properties + org.eclipse.ui.views.properties, + org.eclipse.ui.views.templates Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", org.eclipse.help;bundle-version="[3.2.0,4.0.0)", org.eclipse.ui;bundle-version="[3.2.0,4.0.0)" Index: plugin.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views/plugin.properties,v retrieving revision 1.13 diff -u -r1.13 plugin.properties --- plugin.properties 8 May 2006 20:53:18 -0000 1.13 +++ plugin.properties 31 Jul 2007 18:04:29 -0000 @@ -13,4 +13,4 @@ Views.PropertySheet = Properties Views.ContentOutline = Outline - +Views.Templates = Templates Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views/plugin.xml,v retrieving revision 1.26 diff -u -r1.26 plugin.xml --- plugin.xml 23 Feb 2006 19:35:46 -0000 1.26 +++ plugin.xml 31 Jul 2007 18:04:29 -0000 @@ -18,6 +18,13 @@ class="org.eclipse.ui.views.contentoutline.ContentOutline" id="org.eclipse.ui.views.ContentOutline"> + + Index: icons/full/eview16/templates.gif =================================================================== RCS file: icons/full/eview16/templates.gif diff -N icons/full/eview16/templates.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ icons/full/eview16/templates.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,2 @@ +GIF89awymqU_`gNY2]ohh\]P}P}BvCw+k+j,j,k,j,k6p7q+kS1^TozǑҝԹ!P,PKKLLI11IJ 2" JM%3 +%%%MG**HF!ǃE$O͑#A'"N &=),ϑ-.0">DCB@? /(:  +;2qG6h ,L! i4; Index: src/org/eclipse/ui/internal/views/templates/TemplatesMessages.java =================================================================== RCS file: src/org/eclipse/ui/internal/views/templates/TemplatesMessages.java diff -N src/org/eclipse/ui/internal/views/templates/TemplatesMessages.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/internal/views/templates/TemplatesMessages.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,21 @@ +package org.eclipse.ui.internal.views.templates; + +import org.eclipse.osgi.util.NLS; + +/** + * TemplatesMessages is the message class for the messages used in the templates view. + * + */ +public class TemplatesMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.ui.internal.views.templates.TemplatesMessages"; //$NON-NLS-1$ + + // Default message for an empty templates view + public static String Templates_defaultMessage; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, TemplatesMessages.class); + } + + private TemplatesMessages() { + } +} Index: src/org/eclipse/ui/internal/views/templates/TemplatesMessages.properties =================================================================== RCS file: src/org/eclipse/ui/internal/views/templates/TemplatesMessages.properties diff -N src/org/eclipse/ui/internal/views/templates/TemplatesMessages.properties --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/internal/views/templates/TemplatesMessages.properties 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,1 @@ +Templates_defaultMessage=No templates available for this editor Index: src/org/eclipse/ui/views/templates/Templates.java =================================================================== RCS file: src/org/eclipse/ui/views/templates/Templates.java diff -N src/org/eclipse/ui/views/templates/Templates.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/views/templates/Templates.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.ui.views.templates; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.views.ViewsPlugin; +import org.eclipse.ui.internal.views.templates.TemplatesMessages; +import org.eclipse.ui.part.IContributedContentsView; +import org.eclipse.ui.part.IPage; +import org.eclipse.ui.part.MessagePage; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.part.PageBookView; + +/** + * Main class for the Templates View. + *

+ * This standard view has id "org.eclipse.ui.views.TemplatesView". + *

+ * When a templates view notices an editor being activated, it + * asks the editor whether it has a template page to include + * in the templates view. This is done using getAdapter: + *
+ * IEditorPart editor = ...;
+ * ITemplatePage templatePage = (ITemplatePage) editor.getAdapter(ITemplatePage.class);
+ * if (templatePage != null) {
+ *    // editor wishes to contribute templatePage to templates view
+ * }
+ * 
+ * If the editor supports a templates page, the editor instantiates + * and configures the page, and returns it. This page is then added to the + * templates view (a pagebook which presents one page at a time) and + * immediately made the current page (the templates view need not be + * visible). If the editor does not support a template page, the templates + * view shows a special default page which makes it clear to the user + * that the templates view is disengaged. When the templates view notices a + * different editor being activated, it flips to the editor's corresponding + * template page. When the templates view notices an editor being + * closed, it may destroy the editor's corresponding content outline page. + *

+ *

+ * The workbench will automatically instantiate this class when a templates + * view is needed for a workbench window. This class was not intended + * to be instantiated or subclassed by clients. + *

+ */ +public class Templates extends PageBookView { + /** + * The plugin prefix. + */ + public static final String PREFIX = PlatformUI.PLUGIN_ID + "."; //$NON-NLS-1$ + + /** + * Help context id used for the content outline view + * (value "org.eclipse.ui.content_outline_context"). + */ + public static final String TEMPLATES_VIEW_HELP_CONTEXT_ID = PREFIX + + "templates_view_context";//$NON-NLS-1$ + + /** + * Message to show on the default page. + */ + private String defaultText = TemplatesMessages.Templates_defaultMessage; + + /** + * Creates a content outline view with no content outline pages. + */ + public Templates() { + super(); + } + + /* (non-Javadoc) + * Method declared on PageBookView. + */ + protected IPage createDefaultPage(PageBook book) { + MessagePage page = new MessagePage(); + initPage(page); + page.createControl(book); + page.setMessage(defaultText); + return page; + } + + /** + * The PageBookView implementation of this IWorkbenchPart + * method creates a PageBook control with its default page showing. + */ + public void createPartControl(Composite parent) { + super.createPartControl(parent); + PlatformUI.getWorkbench().getHelpSystem().setHelp(getPageBook(), + TEMPLATES_VIEW_HELP_CONTEXT_ID); + } + + /* (non-Javadoc) + * Method declared on PageBookView. + */ + protected PageRec doCreatePage(IWorkbenchPart part) { + // Try to get template page. + Object obj = ViewsPlugin.getAdapter(part, ITemplatesPage.class, false); + if (obj instanceof ITemplatesPage) { + ITemplatesPage page = (ITemplatesPage) obj; + initPage(page); + page.createControl(getPageBook()); + return new PageRec(part, page); + } + // There is no template page + return null; + } + + /* (non-Javadoc) + * Method declared on PageBookView. + */ + protected void doDestroyPage(IWorkbenchPart part, PageRec rec) { + ITemplatesPage page = (ITemplatesPage) rec.page; + page.dispose(); + rec.dispose(); + } + + /* (non-Javadoc) + * Method declared on IAdaptable. + */ + public Object getAdapter(Class key) { + if (key == IContributedContentsView.class) { + return new IContributedContentsView() { + public IWorkbenchPart getContributingPart() { + return getContributingEditor(); + } + }; + } + return super.getAdapter(key); + } + + /* (non-Javadoc) + * Method declared on PageBookView. + */ + protected IWorkbenchPart getBootstrapPart() { + IWorkbenchPage page = getSite().getPage(); + if (page != null) { + return page.getActiveEditor(); + } + + return null; + } + + /** + * Returns the editor which contributed the current + * page to this view. + * + * @return the editor which contributed the current page + * or null if no editor contributed the current page + */ + private IWorkbenchPart getContributingEditor() { + return getCurrentContributingPart(); + } + + /* (non-Javadoc) + * Method declared on PageBookView. + * We only want to track editors. + */ + protected boolean isImportant(IWorkbenchPart part) { + //We only care about editors + return (part instanceof IEditorPart); + } + + /* (non-Javadoc) + * Method declared on IViewPart. + * Treat this the same as part activation. + */ + public void partBroughtToTop(IWorkbenchPart part) { + partActivated(part); + } +} Index: src/org/eclipse/ui/views/templates/ITemplatesPage.java =================================================================== RCS file: src/org/eclipse/ui/views/templates/ITemplatesPage.java diff -N src/org/eclipse/ui/views/templates/ITemplatesPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/views/templates/ITemplatesPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,13 @@ +package org.eclipse.ui.views.templates; + +import org.eclipse.ui.part.IPageBookViewPage; + +/** + * Interface for a template page. This interface defines + * the minimum requirement for pages within the templates view, namely + * they must be pages (implement IPageBookViewPage). + * + * @see TemplatesView + */ +public interface ITemplatesPage extends IPageBookViewPage { +} #P org.eclipse.ui.workbench.texteditor Index: META-INF/MANIFEST.MF =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF,v retrieving revision 1.18 diff -u -r1.18 MANIFEST.MF --- META-INF/MANIFEST.MF 26 Jun 2007 15:08:06 -0000 1.18 +++ META-INF/MANIFEST.MF 31 Jul 2007 18:04:31 -0000 @@ -25,7 +25,8 @@ org.eclipse.core.expressions;bundle-version="[3.2.0,4.0.0)", org.eclipse.jface.text;bundle-version="[3.4.0,4.0.0)", org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)", - org.eclipse.ui;bundle-version="[3.3.0,4.0.0)" + org.eclipse.ui;bundle-version="[3.3.0,4.0.0)", + org.eclipse.ui.views Eclipse-LazyStart: true Bundle-RequiredExecutionEnvironment: J2SE-1.4 Import-Package: com.ibm.icu.text Index: src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java,v retrieving revision 1.10 diff -u -r1.10 TextEditorTemplateMessages.java --- src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java 25 May 2005 13:15:37 -0000 1.10 +++ src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.java 31 Jul 2007 18:04:33 -0000 @@ -20,11 +20,34 @@ final class TextEditorTemplateMessages extends NLS { private static final String BUNDLE_NAME= TextEditorTemplateMessages.class.getName(); - private TextEditorTemplateMessages() { // Do not instantiate } + // TemplatesView + public static String TemplatesPage_collapse_expand; + public static String TemplatesPage_column_context; + public static String TemplatesPage_column_description; + public static String TemplatesPage_column_name; + public static String TemplatesPage_insert; + public static String TemplatesPage_edit; + public static String TemplatesPage_paste_description; + public static String TemplatesPage_preference_page; + public static String TemplatesPage_link_to_editor; + public static String TemplatesPage_new; + public static String TemplatesPage_preview; + public static String TemplatesPage_question_create_new_message; + public static String TemplatesPage_question_create_new_title; + public static String TemplatesPage_remove; + public static String TemplatesPage_save_error_message; + public static String TemplatesPage_snippet; + public static String TemplatesPage_show_disabled; + public static String TemplatesPage_show_new_dialog; + public static String TemplatesPage_context_description; + public static String TemplatesPage_remove_message; + public static String TemplatesPage_remove_title; + + // TemplatePreferencePage public static String TemplatePreferencePage_error_import; public static String TemplatePreferencePage_error_export; public static String TemplatePreferencePage_error_read_title; Index: src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties,v retrieving revision 1.13 diff -u -r1.13 TextEditorTemplateMessages.properties --- src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties 28 Mar 2006 16:36:54 -0000 1.13 +++ src/org/eclipse/ui/texteditor/templates/TextEditorTemplateMessages.properties 31 Jul 2007 18:04:35 -0000 @@ -9,6 +9,29 @@ # IBM Corporation - initial API and implementation ############################################################################### +# templates page (view) +TemplatesPage_collapse_expand=Collapse or Expand +TemplatesPage_column_context=Context +TemplatesPage_column_description=Description +TemplatesPage_save_error_message=Error Saving the Templates +TemplatesPage_column_name=Name +TemplatesPage_edit=&Edit... +TemplatesPage_insert=&Insert... +TemplatesPage_preference_page=&Preference Page... +TemplatesPage_paste_description=Pasted from editor +TemplatesPage_link_to_editor=Link to Editor +TemplatesPage_new=&New... +TemplatesPage_preview=Previe&w: +TemplatesPage_snippet=snippet +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. +TemplatesPage_context_description=Context +TemplatesPage_remove_title=Removing Templates +TemplatesPage_remove_message=Are you sure you want to remove the selected templates? +TemplatesPage_question_create_new_title= Edit Template +TemplatesPage_remove=&Remove +TemplatesPage_show_disabled=&Show Disabled +TemplatesPage_show_new_dialog=S&how New Dialog on Drop + # preference page TemplatePreferencePage_error_import=Failed to import templates. TemplatePreferencePage_error_export=Failed to export templates. Index: src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java,v retrieving revision 1.54 diff -u -r1.54 TemplatePreferencePage.java --- src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java 28 Jun 2007 15:50:39 -0000 1.54 +++ src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java 31 Jul 2007 18:04:32 -0000 @@ -16,39 +16,23 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.custom.VerifyKeyListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Widget; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; @@ -57,17 +41,8 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.GroupMarker; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.StatusDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.resource.JFaceResources; @@ -91,20 +66,11 @@ import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextListener; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.TextEvent; -import org.eclipse.jface.text.contentassist.ContentAssistant; -import org.eclipse.jface.text.contentassist.IContentAssistProcessor; -import org.eclipse.jface.text.contentassist.IContentAssistant; -import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.text.templates.ContextTypeRegistry; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.text.templates.TemplateContextType; -import org.eclipse.jface.text.templates.TemplateException; import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData; import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter; import org.eclipse.jface.text.templates.persistence.TemplateStore; @@ -112,9 +78,6 @@ import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.internal.texteditor.NLSUtility; -import org.eclipse.ui.internal.texteditor.TextEditorPlugin; -import org.eclipse.ui.texteditor.ITextEditorActionConstants; -import org.eclipse.ui.texteditor.IUpdate; /** * A template preference page allows configuration of the templates for an @@ -132,546 +95,6 @@ /** - * Dialog to edit a template. Clients will usually instantiate, but - * may also extend. - * - * @since 3.3 - */ - protected static class EditTemplateDialog extends StatusDialog { - - private class TextViewerAction extends Action implements IUpdate { - - private int fOperationCode= -1; - private ITextOperationTarget fOperationTarget; - - /** - * Creates a new action. - * - * @param viewer the viewer - * @param operationCode the opcode - */ - public TextViewerAction(ITextViewer viewer, int operationCode) { - fOperationCode= operationCode; - fOperationTarget= viewer.getTextOperationTarget(); - update(); - } - - /** - * Updates the enabled state of the action. - * Fires a property change if the enabled state changes. - * - * @see Action#firePropertyChange(String, Object, Object) - */ - public void update() { - - boolean wasEnabled= isEnabled(); - boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode)); - setEnabled(isEnabled); - - if (wasEnabled != isEnabled) { - firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE); - } - } - - /** - * @see Action#run() - */ - public void run() { - if (fOperationCode != -1 && fOperationTarget != null) { - fOperationTarget.doOperation(fOperationCode); - } - } - } - - private final Template fOriginalTemplate; - - private Text fNameText; - private Text fDescriptionText; - private Combo fContextCombo; - private SourceViewer fPatternEditor; - private Button fInsertVariableButton; - private Button fAutoInsertCheckbox; - private boolean fIsNameModifiable; - - private StatusInfo fValidationStatus; - private boolean fSuppressError= true; // #4354 - private Map fGlobalActions= new HashMap(10); - private List fSelectionActions = new ArrayList(3); - private String[][] fContextTypes; - - private ContextTypeRegistry fContextTypeRegistry; - - private final TemplateVariableProcessor fTemplateProcessor= new TemplateVariableProcessor(); - - private Template fNewTemplate; - - /** - * Creates a new dialog. - * - * @param parent the shell parent of the dialog - * @param template the template to edit - * @param edit whether this is a new template or an existing being edited - * @param isNameModifiable whether the name of the template may be modified - * @param registry the context type registry to use - */ - public EditTemplateDialog(Shell parent, Template template, boolean edit, boolean isNameModifiable, ContextTypeRegistry registry) { - super(parent); - - setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE); - - String title= edit - ? TextEditorTemplateMessages.EditTemplateDialog_title_edit - : TextEditorTemplateMessages.EditTemplateDialog_title_new; - setTitle(title); - - fOriginalTemplate= template; - fIsNameModifiable= isNameModifiable; - - List contexts= new ArrayList(); - for (Iterator it= registry.contextTypes(); it.hasNext();) { - TemplateContextType type= (TemplateContextType) it.next(); - contexts.add(new String[] { type.getId(), type.getName() }); - } - fContextTypes= (String[][]) contexts.toArray(new String[contexts.size()][]); - - fValidationStatus= new StatusInfo(); - - fContextTypeRegistry= registry; - - TemplateContextType type= fContextTypeRegistry.getContextType(template.getContextTypeId()); - fTemplateProcessor.setContextType(type); - } - - /* - * @see org.eclipse.ui.texteditor.templates.StatusDialog#create() - */ - public void create() { - super.create(); - // update initial OK button to be disabled for new templates - boolean valid= fNameText == null || fNameText.getText().trim().length() != 0; - if (!valid) { - StatusInfo status = new StatusInfo(); - status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname); - updateButtonsEnableState(status); - } - } - - /* - * @see Dialog#createDialogArea(Composite) - */ - protected Control createDialogArea(Composite ancestor) { - Composite parent= new Composite(ancestor, SWT.NONE); - GridLayout layout= new GridLayout(); - layout.numColumns= 2; - parent.setLayout(layout); - parent.setLayoutData(new GridData(GridData.FILL_BOTH)); - - ModifyListener listener= new ModifyListener() { - public void modifyText(ModifyEvent e) { - doTextWidgetChanged(e.widget); - } - }; - - if (fIsNameModifiable) { - createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_name); - - Composite composite= new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - layout= new GridLayout(); - layout.numColumns= 4; - layout.marginWidth= 0; - layout.marginHeight= 0; - composite.setLayout(layout); - - fNameText= createText(composite); - fNameText.addModifyListener(listener); - fNameText.addFocusListener(new FocusListener() { - - public void focusGained(FocusEvent e) { - } - - public void focusLost(FocusEvent e) { - if (fSuppressError) { - fSuppressError= false; - updateButtons(); - } - } - }); - - createLabel(composite, TextEditorTemplateMessages.EditTemplateDialog_context); - fContextCombo= new Combo(composite, SWT.READ_ONLY); - - for (int i= 0; i < fContextTypes.length; i++) { - fContextCombo.add(fContextTypes[i][1]); - } - - fContextCombo.addModifyListener(listener); - - fAutoInsertCheckbox= createCheckbox(composite, TextEditorTemplateMessages.EditTemplateDialog_autoinsert); - fAutoInsertCheckbox.setSelection(fOriginalTemplate.isAutoInsertable()); - } - - createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_description); - - int descFlags= fIsNameModifiable ? SWT.BORDER : SWT.BORDER | SWT.READ_ONLY; - fDescriptionText= new Text(parent, descFlags ); - fDescriptionText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - fDescriptionText.addModifyListener(listener); - - Label patternLabel= createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_pattern); - patternLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); - fPatternEditor= createEditor(parent, fOriginalTemplate.getPattern()); - - Label filler= new Label(parent, SWT.NONE); - filler.setLayoutData(new GridData()); - - Composite composite= new Composite(parent, SWT.NONE); - layout= new GridLayout(); - layout.marginWidth= 0; - layout.marginHeight= 0; - composite.setLayout(layout); - composite.setLayoutData(new GridData()); - - fInsertVariableButton= new Button(composite, SWT.NONE); - fInsertVariableButton.setLayoutData(getButtonGridData(fInsertVariableButton)); - fInsertVariableButton.setText(TextEditorTemplateMessages.EditTemplateDialog_insert_variable); - fInsertVariableButton.addSelectionListener(new SelectionListener() { - public void widgetSelected(SelectionEvent e) { - fPatternEditor.getTextWidget().setFocus(); - fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); - } - - public void widgetDefaultSelected(SelectionEvent e) {} - }); - - fDescriptionText.setText(fOriginalTemplate.getDescription()); - if (fIsNameModifiable) { - fNameText.setText(fOriginalTemplate.getName()); - fNameText.addModifyListener(listener); - fContextCombo.select(getIndex(fOriginalTemplate.getContextTypeId())); - } else { - fPatternEditor.getControl().setFocus(); - } - initializeActions(); - - applyDialogFont(parent); - return composite; - } - - private void doTextWidgetChanged(Widget w) { - if (w == fNameText) { - fSuppressError= false; - updateButtons(); - } else if (w == fContextCombo) { - String contextId= getContextId(); - fTemplateProcessor.setContextType(fContextTypeRegistry.getContextType(contextId)); - } else if (w == fDescriptionText) { - // oh, nothing - } - } - - private String getContextId() { - if (fContextCombo != null && !fContextCombo.isDisposed()) { - String name= fContextCombo.getText(); - for (int i= 0; i < fContextTypes.length; i++) { - if (name.equals(fContextTypes[i][1])) { - return fContextTypes[i][0]; - } - } - } - - return fOriginalTemplate.getContextTypeId(); - } - - private void doSourceChanged(IDocument document) { - String text= document.get(); - fValidationStatus.setOK(); - TemplateContextType contextType= fContextTypeRegistry.getContextType(getContextId()); - if (contextType != null) { - try { - contextType.validate(text); - } catch (TemplateException e) { - fValidationStatus.setError(e.getLocalizedMessage()); - } - } - - updateUndoAction(); - updateButtons(); - } - - private static GridData getButtonGridData(Button button) { - GridData data= new GridData(GridData.FILL_HORIZONTAL); - // TODO get some button hints. -// data.heightHint= SWTUtil.getButtonHeightHint(button); - - return data; - } - - private static Label createLabel(Composite parent, String name) { - Label label= new Label(parent, SWT.NULL); - label.setText(name); - label.setLayoutData(new GridData()); - - return label; - } - - private static Text createText(Composite parent) { - Text text= new Text(parent, SWT.BORDER); - text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - return text; - } - - private static Button createCheckbox(Composite parent, String name) { - Button button= new Button(parent, SWT.CHECK); - button.setText(name); - button.setLayoutData(new GridData()); - - return button; - } - - private SourceViewer createEditor(Composite parent, String pattern) { - SourceViewer viewer= createViewer(parent); - viewer.setEditable(true); - - IDocument document= viewer.getDocument(); - if (document != null) - document.set(pattern); - else { - document= new Document(pattern); - viewer.setDocument(document); - } - - int nLines= document.getNumberOfLines(); - if (nLines < 5) { - nLines= 5; - } else if (nLines > 12) { - nLines= 12; - } - - Control control= viewer.getControl(); - GridData data= new GridData(GridData.FILL_BOTH); - data.widthHint= convertWidthInCharsToPixels(80); - data.heightHint= convertHeightInCharsToPixels(nLines); - control.setLayoutData(data); - - viewer.addTextListener(new ITextListener() { - public void textChanged(TextEvent event) { - if (event .getDocumentEvent() != null) - doSourceChanged(event.getDocumentEvent().getDocument()); - } - }); - - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - updateSelectionDependentActions(); - } - }); - - viewer.prependVerifyKeyListener(new VerifyKeyListener() { - public void verifyKey(VerifyEvent event) { - handleVerifyKeyPressed(event); - } - }); - - return viewer; - } - - /** - * Creates the viewer to be used to display the pattern. Subclasses may override. - * - * @param parent the parent composite of the viewer - * @return a configured SourceViewer - */ - protected SourceViewer createViewer(Composite parent) { - SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - SourceViewerConfiguration configuration= new SourceViewerConfiguration() { - public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { - - ContentAssistant assistant= new ContentAssistant(); - assistant.enableAutoActivation(true); - assistant.enableAutoInsert(true); - assistant.setContentAssistProcessor(fTemplateProcessor, IDocument.DEFAULT_CONTENT_TYPE); - return assistant; - } - }; - viewer.configure(configuration); - return viewer; - } - - private void handleVerifyKeyPressed(VerifyEvent event) { - if (!event.doit) - return; - - if (event.stateMask != SWT.MOD1) - return; - - switch (event.character) { - case ' ': - fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); - event.doit= false; - break; - - // CTRL-Z - case 'z' - 'a' + 1: - fPatternEditor.doOperation(ITextOperationTarget.UNDO); - event.doit= false; - break; - } - } - - private void initializeActions() { - TextViewerAction action= new TextViewerAction(fPatternEditor, ITextOperationTarget.UNDO); - action.setText(TextEditorTemplateMessages.EditTemplateDialog_undo); - fGlobalActions.put(ITextEditorActionConstants.UNDO, action); - - action= new TextViewerAction(fPatternEditor, ITextOperationTarget.CUT); - action.setText(TextEditorTemplateMessages.EditTemplateDialog_cut); - fGlobalActions.put(ITextEditorActionConstants.CUT, action); - - action= new TextViewerAction(fPatternEditor, ITextOperationTarget.COPY); - action.setText(TextEditorTemplateMessages.EditTemplateDialog_copy); - fGlobalActions.put(ITextEditorActionConstants.COPY, action); - - action= new TextViewerAction(fPatternEditor, ITextOperationTarget.PASTE); - action.setText(TextEditorTemplateMessages.EditTemplateDialog_paste); - fGlobalActions.put(ITextEditorActionConstants.PASTE, action); - - action= new TextViewerAction(fPatternEditor, ITextOperationTarget.SELECT_ALL); - action.setText(TextEditorTemplateMessages.EditTemplateDialog_select_all); - fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action); - - action= new TextViewerAction(fPatternEditor, ISourceViewer.CONTENTASSIST_PROPOSALS); - action.setText(TextEditorTemplateMessages.EditTemplateDialog_content_assist); - fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$ - - fSelectionActions.add(ITextEditorActionConstants.CUT); - fSelectionActions.add(ITextEditorActionConstants.COPY); - fSelectionActions.add(ITextEditorActionConstants.PASTE); - - // create context menu - MenuManager manager= new MenuManager(null, null); - manager.setRemoveAllWhenShown(true); - manager.addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager mgr) { - fillContextMenu(mgr); - } - }); - - StyledText text= fPatternEditor.getTextWidget(); - Menu menu= manager.createContextMenu(text); - text.setMenu(menu); - } - - private void fillContextMenu(IMenuManager menu) { - menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO)); - menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO)); - - menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); - menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT)); - menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY)); - menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE)); - menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL)); - - menu.add(new Separator("templates")); //$NON-NLS-1$ - menu.appendToGroup("templates", (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$ //$NON-NLS-2$ - } - - private void updateSelectionDependentActions() { - Iterator iterator= fSelectionActions.iterator(); - while (iterator.hasNext()) - updateAction((String)iterator.next()); - } - - private void updateUndoAction() { - IAction action= (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO); - if (action instanceof IUpdate) - ((IUpdate) action).update(); - } - - private void updateAction(String actionId) { - IAction action= (IAction) fGlobalActions.get(actionId); - if (action instanceof IUpdate) - ((IUpdate) action).update(); - } - - private int getIndex(String contextid) { - - if (contextid == null) - return -1; - - for (int i= 0; i < fContextTypes.length; i++) { - if (contextid.equals(fContextTypes[i][0])) { - return i; - } - } - return -1; - } - - private void updateButtons() { - StatusInfo status; - - boolean valid= fNameText == null || fNameText.getText().trim().length() != 0; - if (!valid) { - status = new StatusInfo(); - if (!fSuppressError) { - status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname); - } - } else { - status= fValidationStatus; - } - updateStatus(status); - } - - /* - * @since 3.1 - */ - protected void okPressed() { - String name= fNameText == null ? fOriginalTemplate.getName() : fNameText.getText(); - boolean isAutoInsertable= fAutoInsertCheckbox != null && fAutoInsertCheckbox.getSelection(); - fNewTemplate= new Template(name, fDescriptionText.getText(), getContextId(), fPatternEditor.getDocument().get(), isAutoInsertable); - super.okPressed(); - } - - /** - * Returns the created template. - * - * @return the created template - * @since 3.1 - */ - public Template getTemplate() { - return fNewTemplate; - } - - /** - * Returns the content assist processor that - * suggests template variables. - * - * @return the processor to suggest variables - * @since 3.3 - */ - protected IContentAssistProcessor getTemplateProcessor() { - return fTemplateProcessor; - } - - /* - * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings() - * @since 3.2 - */ - protected IDialogSettings getDialogBoundsSettings() { - String sectionName= getClass().getName() + "_dialogBounds"; //$NON-NLS-1$ - IDialogSettings settings= TextEditorPlugin.getDefault().getDialogSettings(); - IDialogSettings section= settings.getSection(sectionName); - if (section == null) - section= settings.addNewSection(sectionName); - return section; - } - - } - - - /** * Label provider for templates. */ private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider { Index: src/org/eclipse/ui/texteditor/templates/TemplatesPage.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/templates/TemplatesPage.java diff -N src/org/eclipse/ui/texteditor/templates/TemplatesPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/templates/TemplatesPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,1228 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.texteditor.templates; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.TreeColumnLayout; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.templates.ContextTypeRegistry; +import org.eclipse.jface.text.templates.Template; +import org.eclipse.jface.text.templates.TemplateContextType; +import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData; +import org.eclipse.jface.text.templates.persistence.TemplateStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.dialogs.PreferencesUtil; +import org.eclipse.ui.dnd.IDragAndDropService; +import org.eclipse.ui.internal.texteditor.TextEditorPlugin; +import org.eclipse.ui.part.Page; +import org.eclipse.ui.views.templates.ITemplatesPage; + +/** + * An abstract base class for template pages for use with TextEditor. + *

+ * Clients who are defining an editor may elect to provide a corresponding + * templates page. This templates page will be presented to the user via the + * Templates View (the user decides whether their workbench window contains this + * view) whenever that editor is active. This class should be subclassed. + *

+ *

+ * Internally, a TemplatesPage uses the template store to display different + * categories. A link to editor mode on the templates page allows to filtering + * of the categories to only that are supported in this context. + *

+ * Since: 3.4 + */ +public abstract class TemplatesPage extends Page implements ITemplatesPage { + + /** + * Link to editor action setting + */ + private static final String LINK_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID + + ".templates.templatesPage.linkAction"; //$NON-NLS-1$ + /** + * Show disabled actions setting + */ + private static final String SHOW_DISABLED_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID + + ".templates.templatesPage.showDisabledAction"; //$NON-NLS-1$ + /** + * Show new dialog on drop setting + */ + private static final String SHOW_NEW_DIALOG_ACTION_PREF_ID = TextEditorPlugin.PLUGIN_ID + + ".templates.templatesPage.showNewDialogAction"; //$NON-NLS-1$; + + /** + * The ID for the popup menu for this templates page + */ + private static final String POPUP_MENU_ID = "org.eclipse.ui.texteditor.templates.PopupMenu"; //$NON-NLS-1$ + + /** + * Drop support for the editor linked to this page. When a user drops a + * template into the active editor, the template is applied at the drop + * position. + */ + private final class EditorDropTarget extends DropTargetAdapter { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent) + */ + public void dragEnter(DropTargetEvent event) { + super.dragEnter(event); + if (event.detail == DND.DROP_DEFAULT) + event.detail = DND.DROP_COPY; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent) + */ + public void dragOperationChanged(DropTargetEvent event) { + if (event.detail == DND.DROP_DEFAULT) + event.detail = DND.DROP_COPY; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent) + */ + public void dragOver(DropTargetEvent event) { + event.feedback |= DND.FEEDBACK_SCROLL; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent) + */ + public void drop(DropTargetEvent event) { + insertTemplate(getSelectedTemplate()); + } + } + + /** + * Comparator for the viewer. Sorts the templates by name and then + * description and context types by names. + */ + private static final class TemplateViewerComparator extends ViewerComparator { + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public int compare(Viewer viewer, Object object1, Object object2) { + if ((object1 instanceof TemplatePersistenceData) + && (object2 instanceof TemplatePersistenceData)) { + Template left = ((TemplatePersistenceData) object1).getTemplate(); + Template right = ((TemplatePersistenceData) object2).getTemplate(); + int result = left.getName().compareToIgnoreCase(right.getName()); + if (result != 0) + return result; + return left.getDescription().compareToIgnoreCase(right.getDescription()); + } + if ((object1 instanceof TemplateContextType) + && (object2 instanceof TemplateContextType)) { + return ((TemplateContextType) object1).getName().compareToIgnoreCase( + ((TemplateContextType) object1).getName()); + } + return super.compare(viewer, object1, object2); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object, + * java.lang.String) + */ + public boolean isSorterProperty(Object element, String property) { + return true; + } + } + + /** + * Label provider for templates. + */ + private class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider { + + /* + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, + * int) + */ + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + /* + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, + * int) + */ + public String getColumnText(Object element, int columnIndex) { + if (element instanceof TemplatePersistenceData) + return getTemplateColumnText(((TemplatePersistenceData) element).getTemplate(), + columnIndex); + return getContextColumnText((TemplateContextType) element, columnIndex); + } + + /** + * Return the column text for a template + * + * @param template + * @param columnIndex + * @return the column text + */ + private String getTemplateColumnText(Template template, int columnIndex) { + switch (columnIndex) { + case 0: + return template.getName(); + case 1: + return template.getDescription(); + default: + return ""; //$NON-NLS-1$ + } + } + + /** + * Return the column text for a context + * + * @param contextType + * @param columnIndex + * @return the column text + */ + private String getContextColumnText(TemplateContextType contextType, int columnIndex) { + switch (columnIndex) { + case 0: + return contextType.getName(); + case 1: + return TextEditorTemplateMessages.TemplatesPage_context_description; + default: + return ""; //$NON-NLS-1$ + } + } + + } + + /** + * Content provider for templates. Provides all the templates defined for + * this editor and optionally the disabled ones. + */ + private class TemplatesContentProvider implements ITreeContentProvider { + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof TemplatePersistenceData) + return new Object[0]; + else if (parentElement instanceof TemplateContextType) { + TemplateContextType contextType = (TemplateContextType) parentElement; + return getTemplates(contextType.getId()); + } + return null; + } + + /** + * Get the templates for a given contextId. if ShowDisabled is selected + * the disabled templates are also included. + * + * @param contextId + * @return the templates + */ + private TemplatePersistenceData[] getTemplates(String contextId) { + List templateList = new ArrayList(); + TemplatePersistenceData[] datas = fTemplateStore.getTemplateData(false); + boolean showDisabled = fShowDisabledAction.isChecked(); + for (int i = 0; i < datas.length; i++) { + if ((showDisabled || datas[i].isEnabled()) + && datas[i].getTemplate().getContextTypeId().equals(contextId)) + templateList.add(datas[i]); + } + return (TemplatePersistenceData[]) templateList + .toArray(new TemplatePersistenceData[templateList.size()]); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element instanceof TemplatePersistenceData) { + TemplatePersistenceData templateData = (TemplatePersistenceData) element; + return fContextTypeRegistry.getContextType(templateData.getTemplate() + .getContextTypeId()); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element instanceof TemplateContextType) + return true; + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + List contextTypes = new ArrayList(); + + for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) { + TemplateContextType contextType = (TemplateContextType) iterator.next(); + if (isActiveContext(contextType) || !fLinkAction.isChecked()) + contextTypes.add(contextType); + } + return contextTypes.toArray(new TemplateContextType[contextTypes.size()]); + } + + /** + * Checks whether given context type is active for displaying the + * templates + * + * @param contextType + * @return true if context is active + */ + private boolean isActiveContext(TemplateContextType contextType) { + return fActiveTypes == null || fActiveTypes.contains(contextType.getId()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + /** + * Show/Hide new dialog + */ + private static final int SHOW_DIALOG = 0; + private static final int HIDE_DIALOG = 1; + + /** The viewer displays the pattern of selected template. */ + private SourceViewer fPatternViewer; + /** The store for our templates. */ + private TemplateStore fTemplateStore; + /** The context type registry. */ + private ContextTypeRegistry fContextTypeRegistry; + + /** The control for this page book view */ + private Composite fControl; + + /* Actions */ + private Action fInsertAction; + private Action fAddAction; + private Action fEditAction; + private Action fRemoveAction; + private Action fLinkAction; + private Action fExpandCollapseAction; + private Action fPreferencePageAction; + private Action fShowDisabledAction; + private Action fShowNewDialogOnDropAction; + + /* Clipboard actions */ + private Action fPasteAction; + private Action fCopyAction; + + /** Currently selected templates */ + private ArrayList fSelectedTemplateList = new ArrayList(); + + /** Current active context types for the editor */ + private List fActiveTypes; + + /* Preference stores */ + /** + * Preference store to store the dialog setting for this page + */ + private IPreferenceStore fPreferenceStore; + /** + * The template stores preference page. Used to listen to the changes and + * update the view. Needed when the user selects Preferences and updates the + * templates. + */ + private IPreferenceStore fTemplatePreferenceStore; + + /* Controls */ + private Tree fTemplatesTree; + private TreeViewer fTreeViewer; + + /** + * Creates a new template preference page. + */ + protected TemplatesPage() { + super(); + fPreferenceStore = TextEditorPlugin.getDefault().getPreferenceStore(); + } + + /** + * Returns the template store. + * + * @return the template store + */ + public TemplateStore getTemplateStore() { + return fTemplateStore; + } + + /** + * Returns the context type registry. + * + * @return the context type registry + */ + public ContextTypeRegistry getContextTypeRegistry() { + return fContextTypeRegistry; + } + + /** + * Sets the template store. + * + * @param store + * the template store + * @param templatePreferenceStore + * the preference store used for this template store + */ + public void setTemplateStore(TemplateStore store, IPreferenceStore templatePreferenceStore) { + fTemplateStore = store; + fTemplatePreferenceStore = templatePreferenceStore; + if (fTemplatePreferenceStore != null) + fTemplatePreferenceStore.addPropertyChangeListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + refresh(); + } + }); + } + + /** + * Sets the context type registry. + * + * @param registry + * the new context type registry + */ + public void setContextTypeRegistry(ContextTypeRegistry registry) { + fContextTypeRegistry = registry; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite ancestor) { + setupActions(); + + fControl = new Composite(ancestor, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.marginHeight = 0; + layout.marginWidth = 0; + fControl.setLayout(layout); + Dialog.applyDialogFont(fControl); + + createTemplateTree(); + createPatternViewer(fControl); + + hookContextMenu(); + initializeDND(); + updateButtons(); + + fControl.layout(true, true); + } + + /** + * Create the tree control to display template information + */ + private void createTemplateTree() { + Composite treeComposite = new Composite(fControl, SWT.NONE); + GridData data = new GridData(GridData.FILL_BOTH); + treeComposite.setLayoutData(data); + + TreeColumnLayout columnLayout = new TreeColumnLayout(); + treeComposite.setLayout(columnLayout); + fTemplatesTree = new Tree(treeComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI + | SWT.FULL_SELECTION); + fTemplatesTree.setHeaderVisible(true); + fTemplatesTree.setLinesVisible(true); + + GC gc = new GC(getShell()); + gc.setFont(JFaceResources.getDialogFont()); + + TreeColumn columnName = new TreeColumn(fTemplatesTree, SWT.NONE); + columnName.setText(TextEditorTemplateMessages.TemplatesPage_column_name); + int minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_name).x + 10; + columnLayout.setColumnData(columnName, new ColumnWeightData(2, minWidth, true)); + + TreeColumn columnDescription = new TreeColumn(fTemplatesTree, SWT.NONE); + columnDescription.setText(TextEditorTemplateMessages.TemplatesPage_column_description); + minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_description).x + 10; + columnLayout.setColumnData(columnDescription, new ColumnWeightData(3, minWidth, true)); + + gc.dispose(); + + data = new GridData(GridData.FILL_BOTH); + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + /* + * these hints should not be zero. the grabExcess will ensure that the + * tree is sized appropriately the the pattern viewer is displayed below + * it. + */ + data.heightHint = 5; + data.widthHint = 5; + fTemplatesTree.setLayoutData(data); + createTreeViewer(); + } + + /** + * Create the viewer for the tree control and configure it. + */ + private void createTreeViewer() { + fTreeViewer = new TreeViewer(fTemplatesTree); + fTreeViewer.setLabelProvider(new TemplateLabelProvider()); + fTreeViewer.setContentProvider(new TemplatesContentProvider()); + + fTreeViewer.setComparator(new TemplateViewerComparator()); + fTreeViewer.setInput(fTemplateStore); + fTreeViewer.addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent e) { + updateSelectedTemplate(); + insertTemplate(getSelectedTemplate()); + } + }); + + fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent e) { + updateSelectedTemplate(); + updateButtons(); + } + }); + fTreeViewer.expandAll(); + setDisableItemColors(); + } + + /** + * Sets all templates in the tree that are disabled to grey. + */ + private void setDisableItemColors() { + TreeItem[] items = fTemplatesTree.getItems(); + Color fgcDisabled = getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY); + Color fgcEnabled = getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); + for (int i = 0; i < items.length; i++) { + TreeItem[] items2 = items[i].getItems(); + for (int j = 0; j < items2.length; j++) { + TemplatePersistenceData templateData = (TemplatePersistenceData) items2[j] + .getData(); + if (!templateData.isEnabled() && items2[j].getForeground() != fgcDisabled) + items2[j].setForeground(fgcDisabled); + else if (templateData.isEnabled() && items2[j].getForeground() != fgcEnabled) + items2[j].setForeground(fgcEnabled); + } + } + } + + /** + * Update the selected template list and update the pattern viewer + */ + private void updateSelectedTemplate() { + IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection(); + + fSelectedTemplateList.clear(); + for (Iterator iterator = selection.iterator(); iterator.hasNext();) { + Object item = iterator.next(); + if (item instanceof TemplateContextType) { + fSelectedTemplateList.clear(); + break; + } + fSelectedTemplateList.add(item); + + } + if (isSingleTemplateSelected()) + updateViewerInput(getSelectedTemplate()); + else + fPatternViewer.getDocument().set(""); //$NON-NLS-1$ + } + + /** + * Checks whether only one template is selected in the tree + * + * @return true if only single template is selected + */ + private boolean isSingleTemplateSelected() { + return fSelectedTemplateList.size() == 1; + } + + /** + * Get the selected template. Note: should always precede with a check for + * isSingleTemplateSelected + * + * @return the template (Not the data) + */ + private Template getSelectedTemplate() { + return ((TemplatePersistenceData) fSelectedTemplateList.get(0)).getTemplate(); + } + + /** + * Create a viewer to display the pattern + * + * @param parent + */ + private void createPatternViewer(Composite parent) { + Label previewLabel = new Label(parent, SWT.NONE); + previewLabel.setText(TextEditorTemplateMessages.TemplatesPage_preview); + GridData data = new GridData(); + data.horizontalSpan = 2; + previewLabel.setLayoutData(data); + + fPatternViewer = createViewer(parent); + fPatternViewer.setEditable(false); + + Control control = fPatternViewer.getControl(); + data = new GridData(GridData.FILL_BOTH); + data.horizontalSpan = 2; + + Dialog.applyDialogFont(control); + GC gc = new GC(control); + data.heightHint = convertHeightInCharsToPixels(gc, 5); + data.grabExcessVerticalSpace = false; + data.verticalAlignment = SWT.FILL; + gc.dispose(); + + control.setLayoutData(data); + } + + /** + * Setup the actions + */ + private void setupActions() { + IActionBars actionBars = getSite().getActionBars(); + IToolBarManager toolBarManager = actionBars.getToolBarManager(); + IMenuManager menuManager = actionBars.getMenuManager(); + + fInsertAction = new Action(TextEditorTemplateMessages.TemplatesPage_insert) { + public void run() { + insertTemplate(getSelectedTemplate()); + } + }; + + fAddAction = new Action() { + public void run() { + addTemplate(); + } + }; + fAddAction.setText(TextEditorTemplateMessages.TemplatesPage_new); + fAddAction.setImageDescriptor(TemplateViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_NEW)); + toolBarManager.add(fAddAction); + + fEditAction = new Action() { + public void run() { + editTemplate(); + } + }; + fEditAction.setText(TextEditorTemplateMessages.TemplatesPage_edit); + fEditAction.setImageDescriptor(TemplateViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_EDIT)); + toolBarManager.add(fEditAction); + + fRemoveAction = new Action() { + public void run() { + removeTemplate(); + } + }; + fRemoveAction.setText(TextEditorTemplateMessages.TemplatesPage_remove); + fRemoveAction.setImageDescriptor(TemplateViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_DELETE)); + toolBarManager.add(fRemoveAction); + + toolBarManager.add(new Separator()); + + fLinkAction = new Action(TextEditorTemplateMessages.TemplatesPage_link_to_editor, + IAction.AS_CHECK_BOX) { + public void run() { + fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkAction.isChecked()); + refresh(); + } + }; + fLinkAction.setImageDescriptor(TemplateViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_LINK)); + fLinkAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID)); + toolBarManager.add(fLinkAction); + + fExpandCollapseAction = new Action(TextEditorTemplateMessages.TemplatesPage_collapse_expand) { + public void run() { + Object[] vee = fTreeViewer.getVisibleExpandedElements(); + boolean collapse = vee.length != 0; + if (collapse) + fTreeViewer.collapseAll(); + else + fTreeViewer.expandAll(); + } + }; + fExpandCollapseAction.setImageDescriptor(TemplateViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_TEMPLATE_COLLAPSE_EXPAND)); + toolBarManager.add(fExpandCollapseAction); + + if (getPreferencePageId() != null) { + fPreferencePageAction = new Action() { + public void run() { + showPreferencePage(); + } + }; + fPreferencePageAction.setText(TextEditorTemplateMessages.TemplatesPage_preference_page); + menuManager.add(fPreferencePageAction); + } + menuManager.add(new Separator()); + + fShowDisabledAction = new Action(TextEditorTemplateMessages.TemplatesPage_show_disabled, + IAction.AS_CHECK_BOX) { + public void run() { + fPreferenceStore.setValue(SHOW_DISABLED_ACTION_PREF_ID, fShowDisabledAction + .isChecked()); + refresh(); + } + }; + fPreferenceStore.setDefault(SHOW_DISABLED_ACTION_PREF_ID, false); + fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID)); + menuManager.add(fShowDisabledAction); + + fShowNewDialogOnDropAction = new Action( + TextEditorTemplateMessages.TemplatesPage_show_new_dialog, IAction.AS_CHECK_BOX) { + public void run() { + fPreferenceStore.setValue(SHOW_NEW_DIALOG_ACTION_PREF_ID, + fShowNewDialogOnDropAction.isChecked()); + } + }; + fPreferenceStore.setDefault(SHOW_NEW_DIALOG_ACTION_PREF_ID, true); + fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID)); + menuManager.add(fShowNewDialogOnDropAction); + + menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + + fPasteAction = new Action() { + public void run() { + Clipboard clipBoard = new Clipboard(getShell().getDisplay()); + Object contents = clipBoard.getContents(TextTransfer.getInstance()); + if (contents == null) + return; + final String text = (String) contents; + String contextId = getContextId(); + final Template template = new Template( + TextEditorTemplateMessages.TemplatesPage_snippet, + TextEditorTemplateMessages.TemplatesPage_paste_description, contextId, + text, true); + getShell().getDisplay().asyncExec(new Runnable() { + public void run() { + addTemplate(template, HIDE_DIALOG); + } + }); + + } + + private String getContextId() { + if (isSingleTemplateSelected()) + return getSelectedTemplate().getContextTypeId(); + IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection(); + if (selection.isEmpty()) + return getFirstContextTypeId(); + Object element = selection.getFirstElement(); + if (element instanceof TemplateContextType) + return ((TemplateContextType) element).getId(); + return ((TemplatePersistenceData) element).getTemplate().getContextTypeId(); + } + }; + actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction); + + fCopyAction = new Action() { + public void run() { + if (!isSingleTemplateSelected()) + return; + Template[] templates = new Template[] { getSelectedTemplate() }; + Clipboard clipBoard = new Clipboard(getShell().getDisplay()); + clipBoard.setContents(new Object[] { templates }, new Transfer[] { TemplateTransfer + .getInstance() }); + } + }; + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction); + } + + /** + * Setup the context menu for the viewer. + */ + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager(POPUP_MENU_ID); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(fTreeViewer.getControl()); + fTreeViewer.getControl().setMenu(menu); + getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer); + } + + /** + * Fill up the context menu + * + * @param manager + */ + protected void fillContextMenu(IMenuManager manager) { + manager.add(fInsertAction); + manager.add(new Separator()); + manager.add(fAddAction); + manager.add(fEditAction); + manager.add(fRemoveAction); + // Other plug-ins can contribute there actions here + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + /** + * Show the preference templates preference page + */ + private void showPreferencePage() { + PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageId(), null, null) + .open(); + } + + /** + * Get the preference page ID for the templates for the given editor. + * Subclasses should override. + * + * @return id of the preference page + */ + protected String getPreferencePageId() { + return null; + } + + /** + * Helper to find the size for pattern viewer + * + * @param gc + * @param chars + * @return the hieght in pixels + */ + private int convertHeightInCharsToPixels(GC gc, int chars) { + FontMetrics fontMetrics = gc.getFontMetrics(); + return fontMetrics.getHeight() * chars; + } + + /** + * Get the shell + * + * @return the shell for this view site + */ + protected Shell getShell() { + return getSite().getShell(); + } + + /** + * Creates, configures and returns a source viewer to present the template + * pattern on the preference page. Clients may override to provide a custom + * source viewer featuring e.g. syntax coloring. + * + * @param parent + * the parent control + * @return a configured source viewer + */ + protected SourceViewer createViewer(Composite parent) { + SourceViewer viewer = new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL + | SWT.H_SCROLL); + SourceViewerConfiguration configuration = new SourceViewerConfiguration(); + viewer.configure(configuration); + IDocument document = new Document(); + viewer.setDocument(document); + return viewer; + } + + /** + * Updates the pattern viewer. + * + * @param template + */ + protected void updateViewerInput(Template template) { + if (template != null) + fPatternViewer.getDocument().set(template.getPattern()); + else + fPatternViewer.getDocument().set(""); //$NON-NLS-1$ + } + + /** + * Updates the buttons. + */ + private void updateButtons() { + fCopyAction.setEnabled(isSingleTemplateSelected()); + fInsertAction.setEnabled(isSingleTemplateSelected()); + fEditAction.setEnabled(isSingleTemplateSelected()); + fRemoveAction.setEnabled(fSelectedTemplateList.size() != 0); + } + + /** + * Add a template + */ + private void addTemplate() { + String id = getFirstContextTypeId(); + if (id != null) { + Template template = new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + addTemplate(template, SHOW_DIALOG); + } + } + + /** + * Get the first context type from the registry. + * + * @return id of the context type + */ + private String getFirstContextTypeId() { + Iterator it = fContextTypeRegistry.contextTypes(); + if (it.hasNext()) + return ((TemplateContextType) it.next()).getId(); + return null; + } + + /** + * Add a template + * + * Setting ui to SHOW_DIALOG will force a New dialog. Setting it to + * MAY_HIDE_DIALOG will respect the show new dialog on drop option. + * + * @param template + * @param ui + */ + private void addTemplate(Template template, int ui) { + Template newTemplate; + if (ui == SHOW_DIALOG || fShowNewDialogOnDropAction.isChecked()) + newTemplate = editTemplate(template, false, true); + else + newTemplate = template; + if (newTemplate != null) { + TemplatePersistenceData data = new TemplatePersistenceData(newTemplate, true); + fTemplateStore.add(data); + saveTemplateStore(); + fSelectedTemplateList.clear(); + fSelectedTemplateList.add(data); + changeSelection(); + } + } + + /** + * Save the template store + */ + private void saveTemplateStore() { + try { + fTemplateStore.save(); + } catch (IOException e) { + e.printStackTrace(); + MessageDialog.openError(getShell(), + TextEditorTemplateMessages.TemplatesPage_save_error_message, e.getMessage()); + } + } + + /** + * Change selection in the viewer. oldData will contain the earlier selected + * template and fCurrentTemplateData will hold the current selection. Either + * can be null. + * + */ + private void changeSelection() { + fTreeViewer.refresh(); + if (isSingleTemplateSelected()) + fTreeViewer.setSelection(new StructuredSelection(fSelectedTemplateList.get(0)), true); + else + fTreeViewer.setSelection(new StructuredSelection()); + updateSelectedTemplate(); + } + + /** + * Creates the edit dialog. Subclasses may override this method to provide a + * custom dialog. + * + * @param template + * the template being edited + * @param edit + * whether the dialog should be editable + * @param isNameModifiable + * whether the template name may be modified + * @return the created or modified template, or null if the + * edition failed + * @since 3.1 + */ + protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) { + EditTemplateDialog dialog = new EditTemplateDialog(getShell(), template, edit, + isNameModifiable, fContextTypeRegistry); + if (dialog.open() == Window.OK) { + return dialog.getTemplate(); + } + return null; + } + + /** + * Edit the current template + */ + private void editTemplate() { + Template oldTemplate = getSelectedTemplate(); + Template newTemplate = editTemplate(new Template(oldTemplate), true, true); + if (newTemplate != null) { + if (!newTemplate.getName().equals(oldTemplate.getName()) + && MessageDialog.openQuestion(getShell(), + TextEditorTemplateMessages.TemplatesPage_question_create_new_title, + TextEditorTemplateMessages.TemplatesPage_question_create_new_message)) { + fSelectedTemplateList.clear(); + TemplatePersistenceData templateData = new TemplatePersistenceData(newTemplate, + true); + fSelectedTemplateList.add(templateData); + fTemplateStore.add(templateData); + } else { + ((TemplatePersistenceData) fSelectedTemplateList.get(0)).setTemplate(newTemplate); + } + changeSelection(); + } + saveTemplateStore(); + } + + /** + * Remove the currently selected templates + */ + private void removeTemplate() { + if (!MessageDialog.openQuestion(getShell(), + TextEditorTemplateMessages.TemplatesPage_remove_title, + TextEditorTemplateMessages.TemplatesPage_remove_message)) + return; + for (Iterator iterator = fSelectedTemplateList.iterator(); iterator.hasNext();) { + TemplatePersistenceData data = (TemplatePersistenceData) iterator.next(); + fTemplateStore.delete(data); + } + saveTemplateStore(); + fSelectedTemplateList.clear(); + changeSelection(); + } + + /** + * Get the pattern viewer. Subclass can override + * + * @return the viewer + */ + protected SourceViewer getViewer() { + return fPatternViewer; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.Page#getControl() + */ + public Control getControl() { + return fControl; + } + + /** + * Subclasses should override and facilitate inserting the template code + * into the active editor. + * + * @param template + */ + public void insertTemplate(Template template) { + } + + /** + * The caret position in the editor has moved into a new context type. It is + * the subclasses responsibility to see that this is called only when needed + * by keeping track of editor contents (eg. partitions). + * + * @param ids + */ + protected void contextTypeChanged(String[] ids) { + fActiveTypes = Arrays.asList(ids); + if (fLinkAction != null && fLinkAction.isChecked()) + refresh(); + } + + /** + * Setup the drop target for the table + */ + private void initializeDND() { + DragSourceAdapter dragListener = new DragSourceAdapter() { + public void dragSetData(DragSourceEvent event) { + if (isSingleTemplateSelected() + && TemplateTransfer.getInstance().isSupportedType(event.dataType)) { + event.data = new Template[] { getSelectedTemplate() }; + } + } + }; + fTreeViewer.addDragSupport(DND.DROP_COPY, + new Transfer[] { TemplateTransfer.getInstance() }, dragListener); + DropTargetAdapter dropListener = new DropTargetAdapter() { + TextTransfer textTransfer = TextTransfer.getInstance(); + + public void dragEnter(DropTargetEvent event) { + if (event.detail == DND.DROP_DEFAULT) + event.detail = DND.DROP_COPY; + } + + public void dragOperationChanged(DropTargetEvent event) { + if (event.detail == DND.DROP_DEFAULT) + event.detail = DND.DROP_COPY; + } + + public void dragOver(DropTargetEvent event) { + event.detail = DND.DROP_NONE; + if (event.item == null) + return; + int index = 0; + while (index < event.dataTypes.length) { + if (textTransfer.isSupportedType(event.dataTypes[index])) + break; + index++; + } + if (index < event.dataTypes.length) { + event.currentDataType = event.dataTypes[index]; + event.detail = DND.DROP_COPY; + return; + } + } + + public void drop(DropTargetEvent event) { + if (event.item == null) + return; + Object object = ((TreeItem) event.item).getData(); + String contextId; + if (object instanceof TemplateContextType) + contextId = findContextIdByName(((TemplateContextType) object).getId()); + else + contextId = findContextIdByName(((TemplatePersistenceData) object) + .getTemplate().getContextTypeId()); + if (textTransfer.isSupportedType(event.currentDataType)) { + String text = (String) event.data; + final Template template = new Template( + TextEditorTemplateMessages.TemplatesPage_snippet, + TextEditorTemplateMessages.TemplatesPage_paste_description, contextId, + text, true); + getShell().getDisplay().asyncExec(new Runnable() { + public void run() { + addTemplate(template, HIDE_DIALOG); + } + }); + } + } + + private String findContextIdByName(String contextName) { + String contextId = null; + for (Iterator iterator = fContextTypeRegistry.contextTypes(); iterator.hasNext();) { + TemplateContextType contextType = (TemplateContextType) iterator.next(); + if (contextType.getName().equals(contextName)) + contextId = contextType.getId(); + } + return contextId; + } + }; + fTreeViewer.addDropSupport(DND.DROP_COPY, new Transfer[] { TextTransfer.getInstance() }, + dropListener); + } + + /** + * Setup the editor site as a drop target. Should be invoked by the + * subclasses for the D&D to work with the editor. + * + * @param site + * @param viewer + */ + protected void setupEditorDropTarget(IWorkbenchPartSite site, Control viewer) { + IDragAndDropService dndService = (IDragAndDropService) site + .getService(IDragAndDropService.class); + EditorDropTarget editorDropTarget = new EditorDropTarget(); + dndService.addMergedDropTarget(viewer, DND.DROP_COPY, new Transfer[] { TemplateTransfer + .getInstance() }, editorDropTarget); + } + + private void refresh() { + fTreeViewer.refresh(); + setDisableItemColors(); + } +} Index: src/org/eclipse/ui/texteditor/templates/EditTemplateDialog.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/templates/EditTemplateDialog.java diff -N src/org/eclipse/ui/texteditor/templates/EditTemplateDialog.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/templates/EditTemplateDialog.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,598 @@ +package org.eclipse.ui.texteditor.templates; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.StatusDialog; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.templates.ContextTypeRegistry; +import org.eclipse.jface.text.templates.Template; +import org.eclipse.jface.text.templates.TemplateContextType; +import org.eclipse.jface.text.templates.TemplateException; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.internal.texteditor.TextEditorPlugin; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * Dialog to edit a template. Clients will usually instantiate, but + * may also extend. + * + * @since 3.3 + */ + public class EditTemplateDialog extends StatusDialog { + + private class TextViewerAction extends Action implements IUpdate { + + private int fOperationCode= -1; + private ITextOperationTarget fOperationTarget; + + /** + * Creates a new action. + * + * @param viewer the viewer + * @param operationCode the opcode + */ + public TextViewerAction(ITextViewer viewer, int operationCode) { + fOperationCode= operationCode; + fOperationTarget= viewer.getTextOperationTarget(); + update(); + } + + /** + * Updates the enabled state of the action. + * Fires a property change if the enabled state changes. + * + * @see Action#firePropertyChange(String, Object, Object) + */ + public void update() { + + boolean wasEnabled= isEnabled(); + boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode)); + setEnabled(isEnabled); + + if (wasEnabled != isEnabled) { + firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE); + } + } + + /** + * @see Action#run() + */ + public void run() { + if (fOperationCode != -1 && fOperationTarget != null) { + fOperationTarget.doOperation(fOperationCode); + } + } + } + + private final Template fOriginalTemplate; + + private Text fNameText; + private Text fDescriptionText; + private Combo fContextCombo; + private SourceViewer fPatternEditor; + private Button fInsertVariableButton; + private Button fAutoInsertCheckbox; + private boolean fIsNameModifiable; + + private StatusInfo fValidationStatus; + private boolean fSuppressError= true; // #4354 + private Map fGlobalActions= new HashMap(10); + private List fSelectionActions = new ArrayList(3); + private String[][] fContextTypes; + + private ContextTypeRegistry fContextTypeRegistry; + + private final TemplateVariableProcessor fTemplateProcessor= new TemplateVariableProcessor(); + + private Template fNewTemplate; + + /** + * Creates a new dialog. + * + * @param parent the shell parent of the dialog + * @param template the template to edit + * @param edit whether this is a new template or an existing being edited + * @param isNameModifiable whether the name of the template may be modified + * @param registry the context type registry to use + */ + public EditTemplateDialog(Shell parent, Template template, boolean edit, boolean isNameModifiable, ContextTypeRegistry registry) { + super(parent); + + setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE); + + String title= edit + ? TextEditorTemplateMessages.EditTemplateDialog_title_edit + : TextEditorTemplateMessages.EditTemplateDialog_title_new; + setTitle(title); + + fOriginalTemplate= template; + fIsNameModifiable= isNameModifiable; + + List contexts= new ArrayList(); + for (Iterator it= registry.contextTypes(); it.hasNext();) { + TemplateContextType type= (TemplateContextType) it.next(); + contexts.add(new String[] { type.getId(), type.getName() }); + } + fContextTypes= (String[][]) contexts.toArray(new String[contexts.size()][]); + + fValidationStatus= new StatusInfo(); + + fContextTypeRegistry= registry; + + TemplateContextType type= fContextTypeRegistry.getContextType(template.getContextTypeId()); + fTemplateProcessor.setContextType(type); + } + + /* + * @see org.eclipse.ui.texteditor.templates.StatusDialog#create() + */ + public void create() { + super.create(); + // update initial OK button to be disabled for new templates + boolean valid= fNameText == null || fNameText.getText().trim().length() != 0; + if (!valid) { + StatusInfo status = new StatusInfo(); + status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname); + updateButtonsEnableState(status); + } + } + + /* + * @see Dialog#createDialogArea(Composite) + */ + protected Control createDialogArea(Composite ancestor) { + Composite parent= new Composite(ancestor, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + parent.setLayout(layout); + parent.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ModifyListener listener= new ModifyListener() { + public void modifyText(ModifyEvent e) { + doTextWidgetChanged(e.widget); + } + }; + + if (fIsNameModifiable) { + createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_name); + + Composite composite= new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + layout= new GridLayout(); + layout.numColumns= 4; + layout.marginWidth= 0; + layout.marginHeight= 0; + composite.setLayout(layout); + + fNameText= createText(composite); + fNameText.addModifyListener(listener); + fNameText.addFocusListener(new FocusListener() { + + public void focusGained(FocusEvent e) { + } + + public void focusLost(FocusEvent e) { + if (fSuppressError) { + fSuppressError= false; + updateButtons(); + } + } + }); + + createLabel(composite, TextEditorTemplateMessages.EditTemplateDialog_context); + fContextCombo= new Combo(composite, SWT.READ_ONLY); + + for (int i= 0; i < fContextTypes.length; i++) { + fContextCombo.add(fContextTypes[i][1]); + } + + fContextCombo.addModifyListener(listener); + + fAutoInsertCheckbox= createCheckbox(composite, TextEditorTemplateMessages.EditTemplateDialog_autoinsert); + fAutoInsertCheckbox.setSelection(fOriginalTemplate.isAutoInsertable()); + } + + createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_description); + + int descFlags= fIsNameModifiable ? SWT.BORDER : SWT.BORDER | SWT.READ_ONLY; + fDescriptionText= new Text(parent, descFlags ); + fDescriptionText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + fDescriptionText.addModifyListener(listener); + + Label patternLabel= createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_pattern); + patternLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + fPatternEditor= createEditor(parent, fOriginalTemplate.getPattern()); + + Label filler= new Label(parent, SWT.NONE); + filler.setLayoutData(new GridData()); + + Composite composite= new Composite(parent, SWT.NONE); + layout= new GridLayout(); + layout.marginWidth= 0; + layout.marginHeight= 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData()); + + fInsertVariableButton= new Button(composite, SWT.NONE); + fInsertVariableButton.setLayoutData(getButtonGridData(fInsertVariableButton)); + fInsertVariableButton.setText(TextEditorTemplateMessages.EditTemplateDialog_insert_variable); + fInsertVariableButton.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + fPatternEditor.getTextWidget().setFocus(); + fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); + } + + public void widgetDefaultSelected(SelectionEvent e) {} + }); + + fDescriptionText.setText(fOriginalTemplate.getDescription()); + if (fIsNameModifiable) { + fNameText.setText(fOriginalTemplate.getName()); + fNameText.addModifyListener(listener); + fContextCombo.select(getIndex(fOriginalTemplate.getContextTypeId())); + } else { + fPatternEditor.getControl().setFocus(); + } + initializeActions(); + + applyDialogFont(parent); + return composite; + } + + private void doTextWidgetChanged(Widget w) { + if (w == fNameText) { + fSuppressError= false; + updateButtons(); + } else if (w == fContextCombo) { + String contextId= getContextId(); + fTemplateProcessor.setContextType(fContextTypeRegistry.getContextType(contextId)); + } else if (w == fDescriptionText) { + // oh, nothing + } + } + + private String getContextId() { + if (fContextCombo != null && !fContextCombo.isDisposed()) { + String name= fContextCombo.getText(); + for (int i= 0; i < fContextTypes.length; i++) { + if (name.equals(fContextTypes[i][1])) { + return fContextTypes[i][0]; + } + } + } + + return fOriginalTemplate.getContextTypeId(); + } + + private void doSourceChanged(IDocument document) { + String text= document.get(); + fValidationStatus.setOK(); + TemplateContextType contextType= fContextTypeRegistry.getContextType(getContextId()); + if (contextType != null) { + try { + contextType.validate(text); + } catch (TemplateException e) { + fValidationStatus.setError(e.getLocalizedMessage()); + } + } + + updateUndoAction(); + updateButtons(); + } + + private static GridData getButtonGridData(Button button) { + GridData data= new GridData(GridData.FILL_HORIZONTAL); + // TODO get some button hints. +// data.heightHint= SWTUtil.getButtonHeightHint(button); + + return data; + } + + private static Label createLabel(Composite parent, String name) { + Label label= new Label(parent, SWT.NULL); + label.setText(name); + label.setLayoutData(new GridData()); + + return label; + } + + private static Text createText(Composite parent) { + Text text= new Text(parent, SWT.BORDER); + text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + return text; + } + + private static Button createCheckbox(Composite parent, String name) { + Button button= new Button(parent, SWT.CHECK); + button.setText(name); + button.setLayoutData(new GridData()); + + return button; + } + + private SourceViewer createEditor(Composite parent, String pattern) { + SourceViewer viewer= createViewer(parent); + viewer.setEditable(true); + + IDocument document= viewer.getDocument(); + if (document != null) + document.set(pattern); + else { + document= new Document(pattern); + viewer.setDocument(document); + } + + int nLines= document.getNumberOfLines(); + if (nLines < 5) { + nLines= 5; + } else if (nLines > 12) { + nLines= 12; + } + + Control control= viewer.getControl(); + GridData data= new GridData(GridData.FILL_BOTH); + data.widthHint= convertWidthInCharsToPixels(80); + data.heightHint= convertHeightInCharsToPixels(nLines); + control.setLayoutData(data); + + viewer.addTextListener(new ITextListener() { + public void textChanged(TextEvent event) { + if (event .getDocumentEvent() != null) + doSourceChanged(event.getDocumentEvent().getDocument()); + } + }); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateSelectionDependentActions(); + } + }); + + viewer.prependVerifyKeyListener(new VerifyKeyListener() { + public void verifyKey(VerifyEvent event) { + handleVerifyKeyPressed(event); + } + }); + + return viewer; + } + + /** + * Creates the viewer to be used to display the pattern. Subclasses may override. + * + * @param parent the parent composite of the viewer + * @return a configured SourceViewer + */ + protected SourceViewer createViewer(Composite parent) { + SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + SourceViewerConfiguration configuration= new SourceViewerConfiguration() { + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + + ContentAssistant assistant= new ContentAssistant(); + assistant.enableAutoActivation(true); + assistant.enableAutoInsert(true); + assistant.setContentAssistProcessor(fTemplateProcessor, IDocument.DEFAULT_CONTENT_TYPE); + return assistant; + } + }; + viewer.configure(configuration); + return viewer; + } + + private void handleVerifyKeyPressed(VerifyEvent event) { + if (!event.doit) + return; + + if (event.stateMask != SWT.MOD1) + return; + + switch (event.character) { + case ' ': + fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); + event.doit= false; + break; + + // CTRL-Z + case 'z' - 'a' + 1: + fPatternEditor.doOperation(ITextOperationTarget.UNDO); + event.doit= false; + break; + } + } + + private void initializeActions() { + TextViewerAction action= new TextViewerAction(fPatternEditor, ITextOperationTarget.UNDO); + action.setText(TextEditorTemplateMessages.EditTemplateDialog_undo); + fGlobalActions.put(ITextEditorActionConstants.UNDO, action); + + action= new TextViewerAction(fPatternEditor, ITextOperationTarget.CUT); + action.setText(TextEditorTemplateMessages.EditTemplateDialog_cut); + fGlobalActions.put(ITextEditorActionConstants.CUT, action); + + action= new TextViewerAction(fPatternEditor, ITextOperationTarget.COPY); + action.setText(TextEditorTemplateMessages.EditTemplateDialog_copy); + fGlobalActions.put(ITextEditorActionConstants.COPY, action); + + action= new TextViewerAction(fPatternEditor, ITextOperationTarget.PASTE); + action.setText(TextEditorTemplateMessages.EditTemplateDialog_paste); + fGlobalActions.put(ITextEditorActionConstants.PASTE, action); + + action= new TextViewerAction(fPatternEditor, ITextOperationTarget.SELECT_ALL); + action.setText(TextEditorTemplateMessages.EditTemplateDialog_select_all); + fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action); + + action= new TextViewerAction(fPatternEditor, ISourceViewer.CONTENTASSIST_PROPOSALS); + action.setText(TextEditorTemplateMessages.EditTemplateDialog_content_assist); + fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$ + + fSelectionActions.add(ITextEditorActionConstants.CUT); + fSelectionActions.add(ITextEditorActionConstants.COPY); + fSelectionActions.add(ITextEditorActionConstants.PASTE); + + // create context menu + MenuManager manager= new MenuManager(null, null); + manager.setRemoveAllWhenShown(true); + manager.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager mgr) { + fillContextMenu(mgr); + } + }); + + StyledText text= fPatternEditor.getTextWidget(); + Menu menu= manager.createContextMenu(text); + text.setMenu(menu); + } + + private void fillContextMenu(IMenuManager menu) { + menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO)); + menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO)); + + menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); + menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT)); + menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY)); + menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE)); + menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL)); + + menu.add(new Separator("templates")); //$NON-NLS-1$ + menu.appendToGroup("templates", (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void updateSelectionDependentActions() { + Iterator iterator= fSelectionActions.iterator(); + while (iterator.hasNext()) + updateAction((String)iterator.next()); + } + + private void updateUndoAction() { + IAction action= (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO); + if (action instanceof IUpdate) + ((IUpdate) action).update(); + } + + private void updateAction(String actionId) { + IAction action= (IAction) fGlobalActions.get(actionId); + if (action instanceof IUpdate) + ((IUpdate) action).update(); + } + + private int getIndex(String contextid) { + + if (contextid == null) + return -1; + + for (int i= 0; i < fContextTypes.length; i++) { + if (contextid.equals(fContextTypes[i][0])) { + return i; + } + } + return -1; + } + + private void updateButtons() { + StatusInfo status; + + boolean valid= fNameText == null || fNameText.getText().trim().length() != 0; + if (!valid) { + status = new StatusInfo(); + if (!fSuppressError) { + status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname); + } + } else { + status= fValidationStatus; + } + updateStatus(status); + } + + /* + * @since 3.1 + */ + protected void okPressed() { + String name= fNameText == null ? fOriginalTemplate.getName() : fNameText.getText(); + boolean isAutoInsertable= fAutoInsertCheckbox != null && fAutoInsertCheckbox.getSelection(); + fNewTemplate= new Template(name, fDescriptionText.getText(), getContextId(), fPatternEditor.getDocument().get(), isAutoInsertable); + super.okPressed(); + } + + /** + * Returns the created template. + * + * @return the created template + * @since 3.1 + */ + public Template getTemplate() { + return fNewTemplate; + } + + /** + * Returns the content assist processor that + * suggests template variables. + * + * @return the processor to suggest variables + * @since 3.3 + */ + protected IContentAssistProcessor getTemplateProcessor() { + return fTemplateProcessor; + } + + /* + * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings() + * @since 3.2 + */ + protected IDialogSettings getDialogBoundsSettings() { + String sectionName= this.getClass().getName() + "_dialogBounds"; //$NON-NLS-1$ + IDialogSettings settings= TextEditorPlugin.getDefault().getDialogSettings(); + IDialogSettings section= settings.getSection(sectionName); + if (section == null) + section= settings.addNewSection(sectionName); + return section; + } + + } Index: icons/full/elcl16/edit_template.gif =================================================================== RCS file: icons/full/elcl16/edit_template.gif diff -N icons/full/elcl16/edit_template.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ icons/full/elcl16/edit_template.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,7 @@ +GIF89ag}mtsđdzַٽ"Cgӡ|p>{o>{p>v~B7y9w:I|8ܵVģOȏ0123Ú=۱NԲhԲiڽ|ղiب~ȓ|W]`xQi8i8l>m>pCpDtJi9!N,N55<59=>AD:" +4=;6?AC!7@B 8EAE-LL 1K#J.2I$$H /3FGM(0 + + +Rba` + +(db%N(!; Index: icons/full/elcl16/collapse_expand_all.gif =================================================================== RCS file: icons/full/elcl16/collapse_expand_all.gif diff -N icons/full/elcl16/collapse_expand_all.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ icons/full/elcl16/collapse_expand_all.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +GIF89a">r2]z9135452w90}q=~p=|7pismkwu~q=(b!",p@P$ šp. X(E' Tĵi݅!DWCBW!!W{~|!WvW +v +WutJJ + +W"A; Index: src/org/eclipse/ui/texteditor/templates/ITemplateViewImageConstants.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/templates/ITemplateViewImageConstants.java diff -N src/org/eclipse/ui/texteditor/templates/ITemplateViewImageConstants.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/templates/ITemplateViewImageConstants.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,19 @@ +package org.eclipse.ui.texteditor.templates; + +import org.eclipse.ui.internal.texteditor.TextEditorPlugin; + +/** + * Image constants for the template page + * + * @author kd + * + */ +public interface ITemplateViewImageConstants { + public static final String PREFIX = TextEditorPlugin.PLUGIN_ID + "."; //$NON-NLS-1$ + + public final static String IMG_TEMPLATE_NEW = PREFIX + "new_template.gif"; //$NON-NLS-1$ + public static final String IMG_TEMPLATE_DELETE = "delete_template.gif"; //$NON-NLS-1$ + public final static String IMG_TEMPLATE_EDIT = PREFIX + "edit_template.gif"; //$NON-NLS-1$ + public static final String IMG_TEMPLATE_LINK = "link_to_editor.gif"; //$NON-NLS-1$ + public static final String IMG_TEMPLATE_COLLAPSE_EXPAND = "collapse_expand_all.gif"; //$NON-NLS-1$ +} Index: icons/full/elcl16/link_to_editor.gif =================================================================== RCS file: icons/full/elcl16/link_to_editor.gif diff -N icons/full/elcl16/link_to_editor.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ icons/full/elcl16/link_to_editor.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,1 @@ +GIF89aokպ&!,M18[wLTh5/\bx>cAIHQp#18G0>y^; Index: src/org/eclipse/ui/texteditor/templates/TemplateTransfer.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/templates/TemplateTransfer.java diff -N src/org/eclipse/ui/texteditor/templates/TemplateTransfer.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/templates/TemplateTransfer.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2004, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.texteditor.templates; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.jface.text.templates.Template; +import org.eclipse.swt.dnd.ByteArrayTransfer; +import org.eclipse.swt.dnd.TransferData; + +/** + * Transfer type used for clip board and DnD operations for template objects + * + * @see TemplatesPage + * + */ +public class TemplateTransfer extends ByteArrayTransfer { + + private static TemplateTransfer instance; + + private static final String LOCAL_NAME = TemplateTransfer.class.getName() + + System.currentTimeMillis(); + private static final int LOCAL_TYPE = registerType(LOCAL_NAME); + + private static String[] names = null; + private static int types[] = null; + + /** + * @return the registered Transfer instance + */ + public static TemplateTransfer getInstance() { + if (instance == null) { + instance = new TemplateTransfer(); + types = new int[] { LOCAL_TYPE }; + names = new String[] { LOCAL_NAME }; + } + return instance; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.Transfer#getTypeIds() + */ + protected int[] getTypeIds() { + return types; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.Transfer#getTypeNames() + */ + protected String[] getTypeNames() { + return names; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(java.lang.Object, + * org.eclipse.swt.dnd.TransferData) + */ + protected void javaToNative(Object object, TransferData transferData) { + if (object == null || !(object instanceof Template[]) + || !isSupportedType(transferData)) + return; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + DataOutputStream dataOut = new DataOutputStream(out); + Template[] templates = (Template[]) object; + for (int i = 0; i < templates.length; i++) { + writeTemplate(dataOut, templates[i]); + } + byte[] byteArray = out.toByteArray(); + try { + dataOut.close(); + } catch (IOException e) { + } + super.javaToNative(byteArray, transferData); + } + + /** + * Write a template to the output stream + * + * @param dataOut + * @param template + */ + private void writeTemplate(DataOutputStream dataOut, Template template) { + try { + writeString(dataOut, template.getName()); + writeString(dataOut, template.getDescription()); + writeString(dataOut, template.getContextTypeId()); + writeString(dataOut, template.getPattern()); + dataOut.writeBoolean(template.isAutoInsertable()); + } catch (IOException e) { + } + } + + /** + * Write a string to the output stream + * + * @param dataOut + * @param name + * @throws IOException + */ + private void writeString(DataOutputStream dataOut, String name) + throws IOException { + byte[] bytes = name.getBytes(); + dataOut.writeInt(bytes.length); + dataOut.write(bytes); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(org.eclipse.swt.dnd.TransferData) + */ + protected Object nativeToJava(TransferData transferData) { + byte[] bytes = (byte[]) super.nativeToJava(transferData); + if (bytes == null) + return null; + ArrayList listTemplates = new ArrayList(); + ByteArrayInputStream in = new ByteArrayInputStream(bytes); + DataInputStream dataIn = new DataInputStream(in); + try { + while (dataIn.available() > 0) { + Template template = readTempate(dataIn); + if (template == null) + break; + listTemplates.add(template); + } + } catch (IOException e) { + } finally { + try { + dataIn.close(); + } catch (IOException e) { + } + } + return listTemplates.toArray(new Template[listTemplates.size()]); + } + + /** + * Read a template from the data input stream. + * + * @param dataIn + * @return the template + * @throws IOException + */ + private Template readTempate(DataInputStream dataIn) throws IOException { + return new Template(readString(dataIn), readString(dataIn), + readString(dataIn), readString(dataIn), dataIn.readBoolean()); + } + + /** + * Read a string from the data input stream + * + * @param dataIn + * @return the string + * @throws IOException + */ + private String readString(DataInputStream dataIn) throws IOException { + byte[] bytes = new byte[dataIn.readInt()]; + dataIn.read(bytes); + return new String(bytes); + } +} Index: icons/full/elcl16/new_template.gif =================================================================== RCS file: icons/full/elcl16/new_template.gif diff -N icons/full/elcl16/new_template.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ icons/full/elcl16/new_template.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,4 @@ +GIF89a¿Ǹ¾ǸǹȏԲiڽ|!\,\F\B--TF<3UT<=%[RC>%ZXZZ%>:/YWQQ,?92SNPVVN/974 OK$85* +ILIM*6#"EDDJJE1+ );HHA ' ! +@@<@Ç!:ʀ(Lp 4P 4 +; Index: icons/full/elcl16/delete_template.gif =================================================================== RCS file: icons/full/elcl16/delete_template.gif diff -N icons/full/elcl16/delete_template.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ icons/full/elcl16/delete_template.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +GIF89a35qtstrtsu*/,4,3)06>6> +09U`ckcjckdk'(' ,T`%?R?QHXHXetߜ]In^WFXFXFՈ|PCܦG>G?G?=9a[}=:RO~~!1,|pH,FgTy`DXb +G*,\+ҧ!%ELAd%rXHq + + + H1  H EBC0C\BBBA; Index: src/org/eclipse/ui/texteditor/templates/TemplateViewImages.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/templates/TemplateViewImages.java diff -N src/org/eclipse/ui/texteditor/templates/TemplateViewImages.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/templates/TemplateViewImages.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49380, 49445, 53547 + *******************************************************************************/ +package org.eclipse.ui.texteditor.templates; + +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.internal.texteditor.TextEditorPlugin; +import org.osgi.framework.Bundle; + +/** + * The images provided by the texteditor plugin + */ +public class TemplateViewImages { + + /** + * The image registry containing Images. + */ + private static ImageRegistry imageRegistry; + + private static String ICONS_PATH = "$nl$/icons/full/"; //$NON-NLS-1$ + + // Use IPath and toOSString to build the names to ensure they have the + // slashes correct + private final static String LOCALTOOL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$ + + /** + * Declare all images + */ + private static void declareImages() { + // Ant Editor images + declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_NEW, + LOCALTOOL + "new_template.gif"); //$NON-NLS-1$ + declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_DELETE, + LOCALTOOL + "delete_template.gif"); //$NON-NLS-1$ + declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_EDIT, + LOCALTOOL + "edit_template.gif"); //$NON-NLS-1$ + declareRegistryImage(ITemplateViewImageConstants.IMG_TEMPLATE_LINK, + LOCALTOOL + "link_to_editor.gif"); //$NON-NLS-1$ + declareRegistryImage( + ITemplateViewImageConstants.IMG_TEMPLATE_COLLAPSE_EXPAND, + LOCALTOOL + "collapse_expand_all.gif"); //$NON-NLS-1$ + } + + /** + * Declare an Image in the registry table. + * + * @param key + * The key to use when registering the image + * @param path + * The path where the image can be found. This path is relative + * to where this plugin class is found (i.e. typically the + * packages directory) + */ + private final static void declareRegistryImage(String key, String path) { + ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor(); + Bundle bundle = Platform.getBundle(TextEditorPlugin.PLUGIN_ID); + URL url = null; + if (bundle != null) { + url = FileLocator.find(bundle, new Path(path), null); + desc = ImageDescriptor.createFromURL(url); + } + imageRegistry.put(key, desc); + } + + /** + * Returns the ImageRegistry. + * + * @return image registry + */ + public static ImageRegistry getImageRegistry() { + if (imageRegistry == null) { + initializeImageRegistry(); + } + return imageRegistry; + } + + /** + * Initialize the image registry by declaring all of the required graphics. + * This involves creating JFace image descriptors describing how to + * create/find the image should it be needed. The image is not actually + * allocated until requested. + * + * Prefix conventions Wizard Banners WIZBAN_ Preference Banners PREF_BAN_ + * Property Page Banners PROPBAN_ Color toolbar CTOOL_ Enable toolbar ETOOL_ + * Disable toolbar DTOOL_ Local enabled toolbar ELCL_ Local Disable toolbar + * DLCL_ Object large OBJL_ Object small OBJS_ View VIEW_ Product images + * PROD_ Misc images MISC_ + * + * Where are the images? The images (typically gifs) are found in the same + * location as this plugin class. This may mean the same package directory + * as the package holding this class. The images are declared using + * this.getClass() to ensure they are looked up via this plugin class. + * + * @return the image registry + * @see org.eclipse.jface.resource.ImageRegistry + */ + public static ImageRegistry initializeImageRegistry() { + imageRegistry = new ImageRegistry(getStandardDisplay()); + declareImages(); + return imageRegistry; + } + + /** + * Returns the standard display to be used. The method first checks, if the + * thread calling this method has an associated display. If so, this display + * is returned. Otherwise the method returns the default display. + * + * @return the display + */ + public static Display getStandardDisplay() { + Display display = Display.getCurrent(); + if (display == null) { + display = Display.getDefault(); + } + return display; + } + + /** + * Returns the Image identified by the given key, + * or null if it does not exist. + * @param key + * @return the image + */ + public static Image getImage(String key) { + return getImageRegistry().get(key); + } + + /** + * Returns the ImageDescriptor identified by the given key, + * or null if it does not exist. + * @param key + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String key) { + return getImageRegistry().getDescriptor(key); + } + +} #P org.eclipse.jdt.ui Index: ui/org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.java,v retrieving revision 1.25 diff -u -r1.25 ClipboardOperationAction.java --- ui/org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.java 31 Aug 2006 08:52:18 -0000 1.25 +++ ui/org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.java 31 Jul 2007 18:04:39 -0000 @@ -41,12 +41,16 @@ import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.templates.Template; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; import org.eclipse.ui.texteditor.TextEditorAction; +import org.eclipse.ui.texteditor.templates.TemplateTransfer; + +import org.eclipse.ui.views.templates.ITemplatesPage; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; @@ -66,6 +70,7 @@ import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage; /** @@ -489,7 +494,12 @@ } } } else { - fOperationTarget.doOperation(fOperationCode); + Template[] templates= (Template[]) clipboard.getContents(TemplateTransfer.getInstance()); + if (templates != null) { + JavaTemplatesPage page= (JavaTemplatesPage) editor.getAdapter(ITemplatesPage.class); + page.insertTemplate(templates[0]); + } else + fOperationTarget.doOperation(fOperationCode); } } Index: ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java,v retrieving revision 1.430 diff -u -r1.430 JavaEditor.java --- ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java 25 Jul 2007 15:56:17 -0000 1.430 +++ ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java 31 Jul 2007 18:04:55 -0000 @@ -141,6 +141,7 @@ import org.eclipse.ui.views.contentoutline.ContentOutline; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.templates.ITemplatesPage; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; @@ -194,6 +195,7 @@ import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction; import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction; import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction; +import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage; import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder; import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder; import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder; @@ -1333,6 +1335,9 @@ protected JavaOutlinePage fOutlinePage; /** Outliner context menu Id */ protected String fOutlinerContextMenuId; + /** The templates page */ + private JavaTemplatesPage fTemplatesPage; + /** * The editor selection changed listener. * @@ -1778,6 +1783,10 @@ return fOutlinePage; } + if (required.equals(ITemplatesPage.class)) { + return getTemplatesPage(); + } + if (IEncodingSupport.class.equals(required)) return fEncodingSupport; @@ -1832,6 +1841,14 @@ return super.getAdapter(required); } + private JavaTemplatesPage getTemplatesPage() { + if (fTemplatesPage == null) { + fTemplatesPage= new JavaTemplatesPage(this); + + } + return fTemplatesPage; + } + /** * React to changed selection. * @@ -3225,6 +3242,8 @@ protected void handleCursorPositionChanged() { super.handleCursorPositionChanged(); fCachedSelectedRange= getViewer().getSelectedRange(); + if (fTemplatesPage != null) + fTemplatesPage.cursorPositionChanged(); } private static boolean isBracket(char character) { Index: ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java diff -N ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/preferences/JavaTemplatesPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.preferences; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.window.Window; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.TextUtilities; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.templates.ContextTypeRegistry; +import org.eclipse.jface.text.templates.Template; +import org.eclipse.jface.text.templates.TemplateContextType; + +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.templates.TemplatesPage; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.JavaCore; + +import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext; +import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType; +import org.eclipse.jdt.internal.corext.template.java.JavaContextType; +import org.eclipse.jdt.internal.corext.template.java.JavaDocContextType; + +import org.eclipse.jdt.ui.PreferenceConstants; +import org.eclipse.jdt.ui.text.IJavaPartitions; +import org.eclipse.jdt.ui.text.JavaTextTools; + +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; +import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer; +import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration; +import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal; +import org.eclipse.jdt.internal.ui.text.template.preferences.TemplateVariableProcessor; + +/** + * A TemplatesPage implementation for Java CompilationUnitEditor + * + * @author kd + */ +public class JavaTemplatesPage extends TemplatesPage { + + private static final ContextTypeRegistry TEMPLATE_CONTEXT_REGISTRY= JavaPlugin.getDefault().getTemplateContextRegistry(); + private TemplateVariableProcessor fTemplateProcessor; + private ScrolledPageContent fScrolled; + private final JavaEditor fEditor; + private IDocument fDocument; + private String fJavaDocId; + private String fJavaId; + private String fCurrentId; + + /** + * @param javaEditor + */ + public JavaTemplatesPage(JavaEditor javaEditor) { + fEditor= javaEditor; + setTemplateStore(JavaPlugin.getDefault().getTemplateStore(), JavaPlugin.getDefault().getPreferenceStore()); + setContextTypeRegistry(TEMPLATE_CONTEXT_REGISTRY); + fJavaDocId= new JavaDocContextType().getId(); + fJavaId= new JavaContextType().getId(); + fTemplateProcessor= new TemplateVariableProcessor(); + fDocument= fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()); + cursorPositionChanged(); + setupEditorDropTarget(fEditor.getSite(), fEditor.getViewer().getTextWidget()); + } + + public void dispose() { + super.dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite ancestor) { + fScrolled= new ScrolledPageContent(ancestor, SWT.H_SCROLL | SWT.V_SCROLL); + fScrolled.setExpandHorizontal(true); + fScrolled.setExpandVertical(true); + + super.createControl(fScrolled); + Control control= super.getControl(); + + fScrolled.setContent(control); + final Point size= control.computeSize(SWT.DEFAULT, SWT.DEFAULT); + fScrolled.setMinSize(size.x, size.y); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#editTemplate(org.eclipse.jface.text.templates.Template, boolean, boolean) + */ + protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) { + EditTemplateDialog dialog= new EditTemplateDialog(getShell(), template, edit, isNameModifiable, getContextTypeRegistry()); + if (dialog.open() == Window.OK) { + return dialog.getTemplate(); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#createViewer(org.eclipse.swt.widgets.Composite) + */ + protected SourceViewer createViewer(Composite parent) { + IDocument document= new Document(); + JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools(); + tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING); + IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore(); + SourceViewer viewer= new JavaSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store); + SimpleJavaSourceViewerConfiguration configuration= new SimpleJavaSourceViewerConfiguration(tools.getColorManager(), store, null, IJavaPartitions.JAVA_PARTITIONING, false); + viewer.configure(configuration); + viewer.setEditable(false); + viewer.setDocument(document); + + Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT); + viewer.getTextWidget().setFont(font); + new JavaSourcePreviewerUpdater(viewer, configuration, store); + + Control control= viewer.getControl(); + GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL); + control.setLayoutData(data); + + return viewer; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#updateViewerInput(org.eclipse.jface.text.templates.Template) + */ + protected void updateViewerInput(Template template) { + SourceViewer viewer= getViewer(); + + String contextId= template.getContextTypeId(); + TemplateContextType type= TEMPLATE_CONTEXT_REGISTRY.getContextType(contextId); + fTemplateProcessor.setContextType(type); + + IDocument doc= viewer.getDocument(); + + String start= null; + if ("javadoc".equals(contextId)) { //$NON-NLS-1$ + start= "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$ + } else + start= ""; //$NON-NLS-1$ + + doc.set(start + template.getPattern()); + int startLen= start.length(); + viewer.setDocument(doc, startLen, doc.getLength() - startLen); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getControl() + */ + public Control getControl() { + return fScrolled; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.Page#setFocus() + */ + public void setFocus() { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#getPreferencePageId() + */ + protected String getPreferencePageId() { + return "org.eclipse.jdt.ui.preferences.JavaTemplatePreferencePage"; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.templates.TemplatesPage#insertTemplate(org.eclipse.jface.text.templates.Template) + */ + public void insertTemplate(Template template) { + if (!fEditor.isEditorInputModifiable()) + return; + TemplateContextType type= TEMPLATE_CONTEXT_REGISTRY.getContextType(template.getContextTypeId()); + if (type == null) + return; + ISourceViewer contextViewer= fEditor.getViewer(); + ITextSelection textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection(); + IDocument document= contextViewer.getDocument(); + /* + * The Editor checks whether a completion for a word exists before it allows for the template to be + * applied. We pickup the current text at the selection position and replace it with the first char + * of the template name for this to succeed. + * We don't need to go through this, if the editors simply support applyTemplate(Template). + */ + String savedText; + try { + savedText= document.get(textSelection.getOffset(), textSelection.getLength()); + document.replace(textSelection.getOffset(), textSelection.getLength(), template.getName().substring(0, 1)); + } catch (BadLocationException e) { + e.printStackTrace(); + return; + } + Position position= new Position(textSelection.getOffset() + 1, 0); + Region region= new Region(textSelection.getOffset() + 1, 0); + contextViewer.getSelectionProvider().setSelection(new TextSelection(textSelection.getOffset(), 1)); + ICompilationUnit compilationUnit= JavaCore.createCompilationUnitFrom(((FileEditorInput) fEditor.getEditorInput()).getFile()); + + CompilationUnitContext context= ((CompilationUnitContextType) type).createContext(document, position, compilationUnit); + context.setVariable("selection", savedText); //$NON-NLS-1$ + if (context.getKey().length() == 0) { + try { + document.replace(textSelection.getOffset(), 1, savedText); + } catch (BadLocationException e) { + e.printStackTrace(); + return; + } + } + TemplateProposal proposal= new TemplateProposal(template, context, region, null); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(fEditor); + proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset()); + } + + /** + * Invoked by the editor whenever the caret position is updated + */ + public void cursorPositionChanged() { + Point selectedRange= fEditor.getViewer().getSelectedRange(); + int cursor= selectedRange.x + selectedRange.y; + String partition; + try { + partition= TextUtilities.getContentType(fDocument, IJavaPartitions.JAVA_PARTITIONING, cursor, true); + } catch (BadLocationException e) { + return; + } + String id= fJavaId; + if (partition.equals(IJavaPartitions.JAVA_DOC)) + id= fJavaDocId; + if (!id.equals(fCurrentId)) { + fCurrentId= id; + contextTypeChanged(new String[] { id }); + } + } +}