### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.workbench.texteditor 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 6 Aug 2007 15:32:03 -0000 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Dakshinamurthy Karra - TemplatesPage support (bug 69581) *******************************************************************************/ package org.eclipse.ui.texteditor.templates; @@ -20,11 +21,43 @@ final class TextEditorTemplateMessages extends NLS { private static final String BUNDLE_NAME= TextEditorTemplateMessages.class.getName(); - private TextEditorTemplateMessages() { // Do not instantiate } + // TemplatesView + 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_preference_page; + public static String TemplatesPage_link_to_editor; + public static String TemplatesPage_collapse_expand; + public static String TemplatesPage_new; + public static String TemplatesPage_remove; + public static String TemplatesPage_show_disabled; + public static String TemplatesPage_show_new_dialog; + public static String TemplatesPage_insert_tooltip; + public static String TemplatesPage_edit_tooltip; + public static String TemplatesPage_preference_page_tooltip; + public static String TemplatesPage_link_to_editor_tooltip; + public static String TemplatesPage_collapse_expand_tooltip; + public static String TemplatesPage_new_tooltip; + public static String TemplatesPage_remove_tooltip; + public static String TemplatesPage_show_disabled_tooltip; + public static String TemplatesPage_show_new_dialog_tooltip; + 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_save_error_message; + public static String TemplatesPage_snippet; + public static String TemplatesPage_paste_description; + 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 6 Aug 2007 15:32:03 -0000 @@ -7,8 +7,41 @@ # # Contributors: # IBM Corporation - initial API and implementation +# Dakshinamurthy Karra - TemplatesPage support (bug 69581) ############################################################################### +# 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=Preview +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 +TemplatesPage_insert_tooltip=Insert into editor +TemplatesPage_edit_tooltip=Edit the template +TemplatesPage_preference_page_tooltip=Show preference page +TemplatesPage_link_to_editor_tooltip=Link with editor +TemplatesPage_collapse_expand_tooltip=Collapse or expand groups +TemplatesPage_new_tooltip=Create a new template +TemplatesPage_remove_tooltip=Remove the template +TemplatesPage_show_disabled_tooltip=Show disabled templates +TemplatesPage_show_new_dialog_tooltip=Show new dialog + # 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.55 diff -u -r1.55 TemplatePreferencePage.java --- src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java 6 Aug 2007 13:19:01 -0000 1.55 +++ src/org/eclipse/ui/texteditor/templates/TemplatePreferencePage.java 6 Aug 2007 15:32:03 -0000 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Dakshinamurthy Karra - bug 69581 *******************************************************************************/ package org.eclipse.ui.texteditor.templates; @@ -134,7 +135,7 @@ * * @since 3.3 */ - protected static class EditTemplateDialog extends StatusDialog { + public static class EditTemplateDialog extends StatusDialog { private class TextViewerAction extends Action implements IUpdate { 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,1393 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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: + * Dakshinamurthy Karra - 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.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.custom.CLabel; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.ViewForm; +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.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +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.texteditor.templates.TemplatePreferencePage.EditTemplateDialog; + +/** + * An abstract base class for template pages for use with TextEditor and JFace + * {@link Template}. + *
+ * 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 { + + /** + * Sashform size + */ + private static final String SASH_SIZE_PREF_ID = TextEditorPlugin.PLUGIN_ID + + ".templates.templatesPage.sashSize"; //$NON-NLS-1$ + /** + * Tree columns widths + */ + private static final String COLUMN_NAME_WIDTH_PREF_ID = TextEditorPlugin.PLUGIN_ID + + ".templates.templatesPage.nameWidth"; //$NON-NLS-1$ + private static final String COLUMN_DESCRIPTION_WIDTH_PREF_ID = TextEditorPlugin.PLUGIN_ID + + ".templates.templatesPage.descriptionWidth"; //$NON-NLS-1$ + /** + * 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) { + 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; + if (!isEditorModifiable()) { + event.detail = DND.DROP_NONE; + return; + } + if (isValidTemplateForPosition(getSelectedTemplate(), event.x, event.y)) { + event.detail = DND.DROP_COPY; + return; + } + event.detail = DND.DROP_NONE; + } + + /* + * (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); + for (int i = 0; i < datas.length; i++) { + if ((fShowDisabled || 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) || !fLinkWithEditor) + 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 MAY_HIDE_DIALOG = 1; + + /** The viewer displays the pattern of selected template. */ + private SourceViewer fPatternViewer; + /** The store for our templates. */ + private TemplateStore fTemplateStore; + /** + * 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; + private IPropertyChangeListener fTemplateChangeListener; + /** The context type registry. */ + private ContextTypeRegistry fContextTypeRegistry; + + /** The control for this page book view */ + private SashForm fControl; + + /* Actions */ + private Action fInsertAction; + private Action fAddAction; + private Action fEditAction; + private Action fRemoveAction; + private Action fLinkWithEditorAction; + private Action fExpandCollapseAction; + private Action fPreferencePageAction; + private Action fShowDisabledAction; + private Action fShowNewDialogOnDropAction; + + /* Clipboard actions */ + private Action fPasteAction; + private Action fCopyAction; + + /* Options and values saved in preference store */ + private boolean fLinkWithEditor ; + private boolean fShowDisabled ; + private boolean fShowNewDialogOnDrop ; + private int fSashSize; + private int fNameWidth; + private int fDescriptionWidth ; + + /** Currently selected templates and type */ + private ArrayList fSelectedTemplateList = new ArrayList(); + private TemplateContextType fSelectedType; + + /** 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; + + /* Controls */ + private Tree fTemplatesTree; + private TreeViewer fTreeViewer; + private Menu fContextMenu; + + /** + * Creates a new template view page. + * + * @param templateStore + * @param templatePreferenceStore + * @param registry + */ + protected TemplatesPage(TemplateStore templateStore, IPreferenceStore templatePreferenceStore, + ContextTypeRegistry registry) { + super(); + setupPreferenceStore(); + fTemplateStore = templateStore; + fTemplatePreferenceStore = templatePreferenceStore; + if (fTemplatePreferenceStore != null) { + fTemplateChangeListener = new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + refresh(); + } + }; + fTemplatePreferenceStore.addPropertyChangeListener(fTemplateChangeListener); + } + fContextTypeRegistry = registry; + } + + private void setupPreferenceStore() { + fPreferenceStore = TextEditorPlugin.getDefault().getPreferenceStore(); + fPreferenceStore.setDefault(LINK_ACTION_PREF_ID, true); + fPreferenceStore.setDefault(SHOW_DISABLED_ACTION_PREF_ID, false); + fPreferenceStore.setDefault(SHOW_NEW_DIALOG_ACTION_PREF_ID, true); + fPreferenceStore.setDefault(SASH_SIZE_PREF_ID, 80); + fLinkWithEditor = fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID); + fShowDisabled = fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID); + fShowNewDialogOnDrop = fPreferenceStore.getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID); + fSashSize = fPreferenceStore.getInt(SASH_SIZE_PREF_ID); + } + + /** + * Check whether the linked editor is modifiable + * + * @return true if the editor is modifiable + */ + protected boolean isEditorModifiable() { + return true; + } + + /** + * Check whether the template is valid for the current drop position + * + * @param template + * @param x + * @param y + * @return true if the template is valid + */ + protected boolean isValidTemplateForPosition(Template template, int x, int y) { + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite ancestor) { + setupActions(); + + fControl = new SashForm(ancestor, SWT.VERTICAL); + + createTemplateTree(); + createPatternViewer(fControl); + + hookContextMenu(); + initializeDND(); + updateButtons(); + + fControl.setWeights(new int[] { fSashSize, 100 - fSashSize }); + } + + /** + * Setup the actions + */ + private void setupActions() { + createActions(); + IActionBars actionBars = getSite().getActionBars(); + + actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction); + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction); + + fillToolbar(actionBars); + fillMenu(actionBars); + } + + /** + * Create actions for this view + */ + private void createActions() { + fInsertAction = new Action(TextEditorTemplateMessages.TemplatesPage_insert) { + public void run() { + insertTemplate(getSelectedTemplate()); + } + }; + fInsertAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_insert_tooltip); + + fAddAction = new Action(TextEditorTemplateMessages.TemplatesPage_new) { + public void run() { + addTemplate(); + } + }; + fAddAction.setImageDescriptor(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_NEW)); + fAddAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_new_tooltip); + + fEditAction = new Action(TextEditorTemplateMessages.TemplatesPage_edit) { + public void run() { + editTemplate(); + } + }; + fEditAction.setImageDescriptor(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_EDIT)); + fEditAction.setDisabledImageDescriptor(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_EDIT)); + fEditAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_edit_tooltip); + + fRemoveAction = new Action(TextEditorTemplateMessages.TemplatesPage_remove) { + public void run() { + removeTemplate(); + } + }; + fRemoveAction.setImageDescriptor(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_DELETE)); + fRemoveAction.setImageDescriptor(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_DELETE)); + fRemoveAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_remove_tooltip); + + fLinkWithEditorAction = new Action(TextEditorTemplateMessages.TemplatesPage_link_to_editor, + IAction.AS_CHECK_BOX) { + public void run() { + fLinkWithEditor = fLinkWithEditorAction.isChecked(); + refresh(); + } + }; + fLinkWithEditorAction.setImageDescriptor(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_LINK)); + fLinkWithEditorAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID)); + fLinkWithEditorAction.setToolTipText(TextEditorTemplateMessages.TemplatesPage_link_to_editor_tooltip); + 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(TemplatesViewImages + .getImageDescriptor(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_COLLAPSE_EXPAND)); + fExpandCollapseAction + .setToolTipText(TextEditorTemplateMessages.TemplatesPage_collapse_expand_tooltip); + + if (getPreferencePageId() != null) { + fPreferencePageAction = new Action( + TextEditorTemplateMessages.TemplatesPage_preference_page) { + public void run() { + showPreferencePage(); + } + }; + fPreferencePageAction + .setToolTipText(TextEditorTemplateMessages.TemplatesPage_preference_page_tooltip); + } + + fShowDisabledAction = new Action(TextEditorTemplateMessages.TemplatesPage_show_disabled, + IAction.AS_CHECK_BOX) { + public void run() { + fShowDisabled = fShowDisabledAction.isChecked(); + refresh(); + } + }; + fShowDisabledAction.setChecked(fPreferenceStore.getBoolean(SHOW_DISABLED_ACTION_PREF_ID)); + fShowDisabledAction + .setToolTipText(TextEditorTemplateMessages.TemplatesPage_show_disabled_tooltip); + + fShowNewDialogOnDropAction = new Action( + TextEditorTemplateMessages.TemplatesPage_show_new_dialog, IAction.AS_CHECK_BOX) { + public void run() { + fShowNewDialogOnDrop = fShowNewDialogOnDropAction.isChecked(); + } + }; + fShowNewDialogOnDropAction.setChecked(fPreferenceStore + .getBoolean(SHOW_NEW_DIALOG_ACTION_PREF_ID)); + fShowNewDialogOnDropAction + .setToolTipText(TextEditorTemplateMessages.TemplatesPage_show_new_dialog_tooltip); + + fPasteAction = new Action() { + public void run() { + Clipboard clipBoard = new Clipboard(getShell().getDisplay()); + final Template template = getTemplateFromCB(clipBoard); + if (template == null) + return; + getShell().getDisplay().asyncExec(new Runnable() { + public void run() { + addTemplate(template, MAY_HIDE_DIALOG); + } + }); + } + + private Template getTemplateFromCB(Clipboard clipBoard) { + String text = (String) clipBoard.getContents(TextTransfer.getInstance()); + if (text == null) + return getTemplateFromTemplate(clipBoard); + return new Template(TextEditorTemplateMessages.TemplatesPage_snippet, + TextEditorTemplateMessages.TemplatesPage_paste_description, + getContextTypeId(), text.replaceAll("\\$", "\\$\\$"), true); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private Template getTemplateFromTemplate(Clipboard clipBoard) { + Object contents = clipBoard.getContents(TemplateTransfer.getInstance()); + if (contents == null) + return null; + Template t = ((Template[]) contents)[0]; + return new Template(t.getName(), t.getDescription(), getContextTypeId(), t + .getPattern(), true); + } + }; + + 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() }); + } + }; + } + + /** + * Fill the menu items + * + * @param actionBars + */ + private void fillMenu(IActionBars actionBars) { + IMenuManager menuManager = actionBars.getMenuManager(); + + if (fPreferencePageAction != null) { + menuManager.add(fPreferencePageAction); + menuManager.add(new Separator()); + } + menuManager.add(fShowDisabledAction); + menuManager.add(fShowNewDialogOnDropAction); + + menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + /** + * Fill items into the toolbar + * + * @param actionBars + */ + private void fillToolbar(IActionBars actionBars) { + IToolBarManager toolBarManager = actionBars.getToolBarManager(); + toolBarManager.add(fAddAction); + toolBarManager.add(fEditAction); + toolBarManager.add(fRemoveAction); + + toolBarManager.add(new Separator()); + + toolBarManager.add(fLinkWithEditorAction); + toolBarManager.add(fExpandCollapseAction); + } + + /** + * 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); + } + }); + fContextMenu = menuMgr.createContextMenu(fTreeViewer.getControl()); + fTreeViewer.getControl().setMenu(fContextMenu); + getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer); + } + + /** + * Fill up the context menu + * + * @param manager + */ + private 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)); + } + + /** + * 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 = fPreferenceStore.getInt(COLUMN_NAME_WIDTH_PREF_ID); + if (minWidth == 0) + minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_name).x + 10; + columnLayout.setColumnData(columnName, new ColumnWeightData(2, minWidth, true)); + columnName.addControlListener(new ControlListener() { + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + fNameWidth = ((TreeColumn)e.getSource()).getWidth(); + } + }); + + TreeColumn columnDescription = new TreeColumn(fTemplatesTree, SWT.NONE); + columnDescription.setText(TextEditorTemplateMessages.TemplatesPage_column_description); + minWidth = fPreferenceStore.getInt(COLUMN_DESCRIPTION_WIDTH_PREF_ID); + if (minWidth == 0) + minWidth = gc.stringExtent(TextEditorTemplateMessages.TemplatesPage_column_description).x + 10; + columnLayout.setColumnData(columnDescription, new ColumnWeightData(3, minWidth, true)); + columnDescription.addControlListener(new ControlListener() { + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + fDescriptionWidth = ((TreeColumn)e.getSource()).getWidth(); + } + }); + + + gc.dispose(); + + 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) { + updateSelectedItems(); + insertTemplate(getSelectedTemplate()); + } + }); + + fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent e) { + updateSelectedItems(); + updateButtons(); + } + }); + fTreeViewer.expandAll(); + decorateTemplates(); + } + + /** + * Create a viewer to display the pattern + * + * @param parent + */ + private void createPatternViewer(Composite parent) { + ViewForm viewForm = new ViewForm(parent, SWT.NONE); + viewForm.setBorderVisible(false); + CLabel previewLabel = new CLabel(viewForm, SWT.NONE); + previewLabel.setText(TextEditorTemplateMessages.TemplatesPage_preview); + previewLabel.setImage(TemplatesViewImages + .getImage(ITemplateViewImageConstants.IMG_OBJ_PREVIEW)); + viewForm.setTopLeft(previewLabel); + + fPatternViewer = createViewer(viewForm); + fPatternViewer.setEditable(false); + viewForm.setContent(fPatternViewer.getControl()); + viewForm.addControlListener(new ControlListener() { + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + int[] weights = fControl.getWeights(); + fSashSize = (int) (weights[0] * 100.0 / (weights[0] + weights[1])); + } + }); + } + + /** + * Sets all templates in the tree that are disabled to grey. + */ + private void decorateTemplates() { + TreeItem[] contextItems = fTemplatesTree.getItems(); + Color fgcDisabled = getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY); + Color fgcEnabled = getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); + for (int i = 0; i < contextItems.length; i++) { + contextItems[i].setFont(getBoldFont(contextItems[i].getFont())); + TreeItem[] templateItems = contextItems[i].getItems(); + for (int j = 0; j < templateItems.length; j++) { + TemplatePersistenceData templateData = (TemplatePersistenceData) templateItems[j] + .getData(); + if (templateData == null) + continue; + if (!templateData.isEnabled() && templateItems[j].getForeground() != fgcDisabled) + templateItems[j].setForeground(fgcDisabled); + else if (templateData.isEnabled() && templateItems[j].getForeground() != fgcEnabled) + templateItems[j].setForeground(fgcEnabled); + } + } + } + + private Font getBoldFont(Font font) { + FontData[] fontData = font.getFontData(); + for (int i = 0; i < fontData.length; i++) { + fontData[i].setStyle(fontData[i].getStyle() | SWT.BOLD | SWT.ITALIC); + } + return new Font(font.getDevice(), fontData); + } + + /** + * Update the selected template list, type and pattern viewer + */ + private void updateSelectedItems() { + IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection(); + + fSelectedTemplateList.clear(); + fSelectedType = null; + + if (selection.size() == 1) { + Object item = selection.getFirstElement(); + if (item instanceof TemplateContextType) + fSelectedType = (TemplateContextType) item; + else + fSelectedTemplateList.add(item); + } else if (selection.size() > 1) { + for (Iterator iterator = selection.iterator(); iterator.hasNext();) { + Object item = iterator.next(); + if (item instanceof TemplateContextType) { + fSelectedTemplateList.clear(); + break; + } + fSelectedTemplateList.add(item); + } + } + if (!fSelectedTemplateList.isEmpty()) { + String contextTypeId = ((TemplatePersistenceData) fSelectedTemplateList.get(0)) + .getTemplate().getContextTypeId(); + fSelectedType = fContextTypeRegistry.getContextType(contextTypeId); + for (Iterator iterator = fSelectedTemplateList.iterator(); iterator.hasNext();) { + TemplatePersistenceData template = (TemplatePersistenceData) iterator.next(); + if (!contextTypeId.equals(template.getTemplate().getContextTypeId())) { + fSelectedType = null; + break; + } + } + } + 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(); + } + + /** + * 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; + } + + /** + * 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 = getContextTypeId(); + if (id != null) { + Template template = new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + addTemplate(template, SHOW_DIALOG); + } + } + + /** + * Get the selected or the first context type from the registry. + * + * @return id of the context type + */ + private String getContextTypeId() { + if (fSelectedType != null) + return fSelectedType.getId(); + 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 || fShowNewDialogOnDrop) + 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()); + updateSelectedItems(); + } + + /** + * 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, ornull
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 (fLinkWithEditorAction != null && fLinkWithEditor)
+ refresh();
+ }
+
+ /**
+ * Initialize drag and drop the the template items
+ */
+ private void initializeDND() {
+ DragSourceAdapter dragListener = new DragSourceAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DragSourceAdapter#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ 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();
+ TemplateTransfer templateTransfer = TemplateTransfer.getInstance();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void dragEnter(DropTargetEvent 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.detail = DND.DROP_NONE;
+ if (event.item == null)
+ return;
+ int index = 0;
+ while (index < event.dataTypes.length) {
+ if (textTransfer.isSupportedType(event.dataTypes[index]))
+ break;
+ if (templateTransfer.isSupportedType(event.dataTypes[index]))
+ break;
+ index++;
+ }
+ if (index < event.dataTypes.length) {
+ event.currentDataType = event.dataTypes[index];
+ event.detail = DND.DROP_COPY;
+ return;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void drop(DropTargetEvent event) {
+ if (event.item == null)
+ return;
+ Object object = ((TreeItem) event.item).getData();
+ String contextId;
+ if (object instanceof TemplateContextType)
+ contextId = ((TemplateContextType) object).getId();
+ else
+ contextId = ((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.replaceAll("\\$", "\\$\\$"), true); //$NON-NLS-1$//$NON-NLS-2$
+ getShell().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ addTemplate(template, MAY_HIDE_DIALOG);
+ }
+ });
+ } else if (templateTransfer.isSupportedType(event.currentDataType)) {
+ Template[] templates = (Template[]) event.data;
+ Template t = templates[0];
+ final Template template = new Template(t.getName(), t.getDescription(),
+ contextId, t.getPattern(), true);
+ getShell().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ addTemplate(template, MAY_HIDE_DIALOG);
+ }
+ });
+ }
+ }
+
+ };
+ fTreeViewer.addDropSupport(DND.DROP_COPY, new Transfer[] { TemplateTransfer.getInstance(),
+ 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);
+ }
+
+ /**
+ * Refresh the template tree contents
+ */
+ private void refresh() {
+ fTreeViewer.refresh();
+ fTreeViewer.expandAll();
+ decorateTemplates();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.Page#setFocus()
+ */
+ public void setFocus() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.Page#dispose()
+ */
+ public void dispose() {
+ if (fContextMenu != null && !fContextMenu.isDisposed())
+ fContextMenu.dispose();
+ fTemplatePreferenceStore.removePropertyChangeListener(fTemplateChangeListener);
+ savePreferences();
+ super.dispose();
+ }
+
+ /**
+ * Save the preferences
+ */
+ private void savePreferences() {
+ fPreferenceStore.setValue(SASH_SIZE_PREF_ID, fSashSize);
+ fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkWithEditor);
+ fPreferenceStore.setValue(SHOW_DISABLED_ACTION_PREF_ID, fShowDisabled);
+ fPreferenceStore.setValue(SHOW_NEW_DIALOG_ACTION_PREF_ID, fShowNewDialogOnDrop);
+ fPreferenceStore.setValue(COLUMN_NAME_WIDTH_PREF_ID, fNameWidth);
+ fPreferenceStore.setValue(COLUMN_DESCRIPTION_WIDTH_PREF_ID, fDescriptionWidth);
+ }
+}
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,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.texteditor.templates;
+
+import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
+
+/**
+ * Image constants for the template page
+ *
+ * @author kd
+ *
+ * @since 3.4
+ */
+public interface ITemplateViewImageConstants {
+ public static final String PREFIX_ELCL = TextEditorPlugin.PLUGIN_ID + ".elcl."; //$NON-NLS-1$
+ public static final String PREFIX_DLCL = TextEditorPlugin.PLUGIN_ID + ".dlcl."; //$NON-NLS-1$
+ public static final String PREFIX_OBJ = TextEditorPlugin.PLUGIN_ID + ".obj."; //$NON-NLS-1$
+
+ public final static String IMG_ELCL_TEMPLATE_NEW = PREFIX_ELCL + "new_template.gif"; //$NON-NLS-1$
+ public static final String IMG_ELCL_TEMPLATE_DELETE = PREFIX_ELCL + "delete_template.gif"; //$NON-NLS-1$
+ public final static String IMG_ELCL_TEMPLATE_EDIT = PREFIX_ELCL + "edit_template.gif"; //$NON-NLS-1$
+ public static final String IMG_ELCL_TEMPLATE_LINK = PREFIX_ELCL + "link_to_editor.gif"; //$NON-NLS-1$
+ public static final String IMG_ELCL_TEMPLATE_COLLAPSE_EXPAND = PREFIX_ELCL + "collapse_expand_all.gif"; //$NON-NLS-1$
+ public static final String IMG_DLCL_TEMPLATE_DELETE = PREFIX_DLCL + "delete_template.gif"; //$NON-NLS-1$
+ public final static String IMG_DLCL_TEMPLATE_EDIT = PREFIX_DLCL + "edit_template.gif"; //$NON-NLS-1$
+
+ public final static String IMG_OBJ_PREVIEW = PREFIX_OBJ + "preview.gif"; //$NON-NLS-1$
+}
Index: src/org/eclipse/ui/texteditor/templates/TemplatesViewImages.java
===================================================================
RCS file: src/org/eclipse/ui/texteditor/templates/TemplatesViewImages.java
diff -N src/org/eclipse/ui/texteditor/templates/TemplatesViewImages.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/ui/texteditor/templates/TemplatesViewImages.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - initial API and implementation
+ *******************************************************************************/
+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
+ * @since 3.4
+ */
+public class TemplatesViewImages {
+
+ /**
+ * The image registry containing Image
s.
+ */
+ 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 ELCL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$
+ private final static String DLCL = ICONS_PATH + "dlcl16/"; //$NON-NLS-1$
+ private final static String OBJ = ICONS_PATH + "obj16/"; //$NON-NLS-1$
+
+ /**
+ * Declare all images
+ */
+ private static void declareImages() {
+ // Ant Editor images
+ declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_NEW, ELCL
+ + "new_template.gif"); //$NON-NLS-1$
+ declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_DELETE, ELCL
+ + "delete_template.gif"); //$NON-NLS-1$
+ declareRegistryImage(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_DELETE, DLCL
+ + "delete_template.gif"); //$NON-NLS-1$
+ declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_EDIT, ELCL
+ + "edit_template.gif"); //$NON-NLS-1$
+ declareRegistryImage(ITemplateViewImageConstants.IMG_DLCL_TEMPLATE_EDIT, DLCL
+ + "edit_template.gif"); //$NON-NLS-1$
+ declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_LINK, ELCL
+ + "link_to_editor.gif"); //$NON-NLS-1$
+ declareRegistryImage(ITemplateViewImageConstants.IMG_ELCL_TEMPLATE_COLLAPSE_EXPAND, ELCL
+ + "collapse_expand_all.gif"); //$NON-NLS-1$
+
+ declareRegistryImage(ITemplateViewImageConstants.IMG_OBJ_PREVIEW, OBJ + "preview.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);
+ }
+
+}
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,180 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - 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
+ *
+ * @since 3.4
+ */
+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);
+ }
+}
#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 6 Aug 2007 15:32:32 -0000
@@ -8,6 +8,7 @@
# Contributors:
# IBM Corporation - initial API and implementation
# John-Mason P. Shackelford - bug 40255
+# Dakshinamurthy Karra - TemplatesPage support
###############################################################################
ContentAssistProposal.label=Content &Assist@Ctrl+Space
@@ -41,3 +42,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 6 Aug 2007 15:32:30 -0000
@@ -12,6 +12,7 @@
* IBM Corporation - bug fixes
* John-Mason P. Shackelford - bug 40255
* Mark Melvin - bug 93378
+ * Dakshinamurthy Karra - TemplatesView support
*******************************************************************************/
package org.eclipse.ant.internal.ui.editor;
@@ -34,6 +35,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 +73,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 +88,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 +97,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 +117,53 @@
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 {
+
+ /**
+ * Clipboard paste operation support for templates
+ *
+ * @since 3.4
+ */
+ 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);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ 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);
+ }
+ }
+
+
/**
* Updates the Ant outline page selection and this editor's range indicator.
*
@@ -461,7 +503,12 @@
* The page that shows the outline.
*/
protected AntEditorContentOutlinePage fOutlinePage;
-
+ /**
+ * The templates page
+ *
+ * @since 3.4
+ */
+ protected AntTemplatesPage fTemplatesPage;
private boolean fInitialReconcile= true;
@@ -538,6 +585,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 +617,10 @@
return getOutlinePage();
}
+ if (key.equals(ITemplatesPage.class)) {
+ return getTemplatesPage();
+ }
+
if (fProjectionSupport != null) {
Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key);
if (adapter != null) {
@@ -599,6 +656,29 @@
return fOutlinePage;
}
+ /**
+ * @since 3.4
+ *
+ * @return the templatespage for this editor
+ */
+ private AntTemplatesPage getTemplatesPage() {
+ if (fTemplatesPage == null) {
+ fTemplatesPage = new AntTemplatesPage(this);
+ }
+ return fTemplatesPage;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleCursorPositionChanged()
+ *
+ * @since 3.4
+ */
+ 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,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - Initial API and implementation
+ *******************************************************************************/
+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.texteditor.templates.TemplatesPage;
+import org.eclipse.ui.views.templates.ITemplatesPage;
+
+/**
+ * An implementation of TemplatesPage for AntEditor
+ *
+ * @see TemplatesPage
+ * @since 3.4
+ */
+public class AntTemplatesPage extends TemplatesPage implements ITemplatesPage {
+
+ 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) {
+ super(AntTemplateAccess.getDefault().getTemplateStore(),
+ AntUIPlugin.getDefault().getPreferenceStore(), CONTEXT_TYPE_REGISTRY);
+ fEditor = editor;
+ 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.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);
+ fEditor.getSite().getPage().activate(fEditor);
+ proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset());
+ }
+
+ /**
+ * Invoked by the editor whenever the caret position is updated
+ */
+ public void cursorPositionChanged() {
+ String id= getContextId();
+ 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 });
+ }
+
+ /**
+ * Get the contextid for the editor
+ *
+ * @return contextId
+ */
+ private String getContextId() {
+ if (fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput())
+ .getLength() == 0)
+ return BuildFileContextType.BUILDFILE_CONTEXT_TYPE;
+ return TargetContextType.TARGET_CONTEXT_TYPE;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isValidTempalteForPosition(org.eclipse.jface.text.templates.Template, int, int)
+ */
+ protected boolean isValidTemplateForPosition(Template template, int x, int y) {
+ return getContextId().equals(template.getContextTypeId());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isEditorModifiable()
+ */
+ protected boolean isEditorModifiable() {
+ return fEditor.isEditable() ;
+ }
+}
#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 6 Aug 2007 15:32:56 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Dakshinamurthy Karra - TemplatesPage support (bug 69581)
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor;
@@ -41,12 +42,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 +71,7 @@
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.preferences.JavaTemplatesPage;
/**
@@ -489,7 +495,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 6 Aug 2007 15:33:09 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Dakshinamurthy Karra - TemplatesPage support (bug 69581)
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor;
@@ -141,6 +142,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 +196,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 +1336,12 @@
protected JavaOutlinePage fOutlinePage;
/** Outliner context menu Id */
protected String fOutlinerContextMenuId;
+ /** The templates page
+ *
+ * @since 3.4
+ */
+ private JavaTemplatesPage fTemplatesPage;
+
/**
* The editor selection changed listener.
*
@@ -1778,6 +1787,10 @@
return fOutlinePage;
}
+ if (required.equals(ITemplatesPage.class)) {
+ return getTemplatesPage();
+ }
+
if (IEncodingSupport.class.equals(required))
return fEncodingSupport;
@@ -1833,6 +1846,17 @@
}
/**
+ * @since 3.4
+ */
+ private JavaTemplatesPage getTemplatesPage() {
+ if (fTemplatesPage == null) {
+ fTemplatesPage= new JavaTemplatesPage(this);
+
+ }
+ return fTemplatesPage;
+ }
+
+ /**
* React to changed selection.
*
* @since 3.0
@@ -3225,6 +3249,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,353 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+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.ITextViewerExtension5;
+import org.eclipse.jface.text.IUndoManager;
+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.part.FileEditorInput;
+import org.eclipse.ui.texteditor.templates.TemplatesPage;
+
+import org.eclipse.ui.views.templates.ITemplatesPage;
+
+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 JavaEditor
+ *
+ * @since 3.4
+ */
+public class JavaTemplatesPage extends TemplatesPage implements ITemplatesPage {
+
+ private static final ContextTypeRegistry TEMPLATE_CONTEXT_REGISTRY= JavaPlugin.getDefault().getTemplateContextRegistry();
+ private TemplateVariableProcessor fTemplateProcessor;
+ private final JavaEditor fEditor;
+ private IDocument fDocument;
+ private String fJavaDocId;
+ private String fJavaId;
+ private String fCurrentId;
+ private int fCachedOffset;
+ private boolean fCachedResult;
+ private Point fCachedPosition;
+
+ /**
+ * @param javaEditor
+ */
+ public JavaTemplatesPage(JavaEditor javaEditor) {
+ super(JavaPlugin.getDefault().getTemplateStore(), JavaPlugin.getDefault().getPreferenceStore(), TEMPLATE_CONTEXT_REGISTRY);
+ fEditor= javaEditor;
+ 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#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, TEMPLATE_CONTEXT_REGISTRY);
+ 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#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());
+ ISourceViewer contextViewer= fEditor.getViewer();
+ ITextSelection textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
+ if ( !isValidTemplate(template, textSelection.getOffset(), textSelection.getLength()))
+ return;
+ IUndoManager undoManager= ((JavaSourceViewer) fEditor.getViewer()).getUndoManager();
+ undoManager.beginCompoundChange();
+
+ /*
+ * 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= fDocument.get(textSelection.getOffset(), textSelection.getLength());
+ if (savedText.length() == 0) {
+ String prefix= getIdentifierPart(textSelection.getOffset());
+ if (prefix.length() > 0 && !template.getName().startsWith(prefix.toString())) {
+ return;
+ }
+ if (prefix.length() > 0) {
+ contextViewer.setSelectedRange(textSelection.getOffset() - prefix.length(), prefix.length());
+ textSelection= (ITextSelection) contextViewer.getSelectionProvider().getSelection();
+ }
+ }
+ fDocument.replace(textSelection.getOffset(), textSelection.getLength(), template.getName().substring(0, 1));
+ } catch (BadLocationException e) {
+ undoManager.endCompoundChange();
+ 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(fDocument, position, compilationUnit);
+ context.setVariable("selection", savedText); //$NON-NLS-1$
+ if (context.getKey().length() == 0) {
+ try {
+ fDocument.replace(textSelection.getOffset(), 1, savedText);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ undoManager.endCompoundChange();
+ return;
+ }
+ }
+ TemplateProposal proposal= new TemplateProposal(template, context, region, null);
+ fEditor.getSite().getPage().activate(fEditor);
+ proposal.apply(fEditor.getViewer(), ' ', 0, region.getOffset());
+ undoManager.endCompoundChange();
+ }
+
+ /**
+ * 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 });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isValidTempalteForPosition(org.eclipse.jface.text.templates.Template, int, int)
+ */
+ protected boolean isValidTemplateForPosition(Template template, int x, int y) {
+ StyledText textWidget= fEditor.getViewer().getTextWidget();
+ try {
+ Point point= new Point(x,y);
+ if (point.equals(fCachedPosition))
+ return fCachedResult;
+ fCachedPosition = point ;
+ int offset= getOffset(textWidget, textWidget.toControl(x, y));
+ if (fCachedOffset == offset)
+ return fCachedResult;
+ fCachedOffset= offset;
+ if (isValidTemplate(template, offset, 0))
+ return fCachedResult= true;
+ } catch (BadLocationException e) {
+ }
+ return fCachedResult= false;
+ }
+
+ /**
+ * Get the document relative offset from the textwidget relative point
+ *
+ * @param textWidget
+ * @param point
+ * @return offset
+ * @throws BadLocationException
+ */
+ private int getOffset(StyledText textWidget, Point point) throws BadLocationException {
+ ITextViewerExtension5 ext= (ITextViewerExtension5) fEditor.getViewer();
+ try {
+ return ext.widgetOffset2ModelOffset(textWidget.getOffsetAtLocation(point));
+ } catch (IllegalArgumentException e) {
+ int docLineIndex= ext.widgetLine2ModelLine(textWidget.getLineIndex(point.y));
+ String lineDelimiter= fDocument.getLineDelimiter(docLineIndex);
+ int delimLength= lineDelimiter == null ? 0 : lineDelimiter.length();
+ return fDocument.getLineOffset(docLineIndex) + fDocument.getLineLength(docLineIndex) - delimLength;
+ }
+ }
+
+ /**
+ * Check whether the template is valid for the given offset
+ *
+ * @param template
+ * @param offset
+ * @param length
+ * @return true if the template is valid
+ */
+ private boolean isValidTemplate(Template template, int offset, int length) {
+ try {
+ if (!getContextId(offset).equals(template.getContextTypeId()))
+ return false ;
+ if (length > 0) // length > 0 iff no selection in editor or DnD operation
+ return true ;
+ String identifierPart= getIdentifierPart(offset);
+ return ((identifierPart.length() > 0 && template.getName().startsWith(identifierPart.toString())) ||
+ (offset == fDocument.getLineInformationOfOffset(offset).getOffset()) ||
+ (Character.isWhitespace(fDocument.getChar(offset - 1))));
+ } catch (BadLocationException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Get the context id for at the given offset
+ *
+ * @param offset
+ * @return the context id
+ * @throws BadLocationException
+ */
+ private String getContextId(int offset) throws BadLocationException {
+ String partition= TextUtilities.getContentType(fDocument, IJavaPartitions.JAVA_PARTITIONING, offset, true);
+ String id= fJavaId;
+ if (partition.equals(IJavaPartitions.JAVA_DOC))
+ id= fJavaDocId;
+ return id;
+ }
+
+ /**
+ * Get the java identifier terminated at the given offset
+ *
+ * @param offset
+ * @return the identifier part
+ * @throws BadLocationException
+ */
+ private String getIdentifierPart(int offset) throws BadLocationException {
+ int end= offset;
+ int start= end;
+ while (--start >= 0) {
+ if (!Character.isJavaIdentifierPart(fDocument.getChar(start)))
+ break;
+ }
+ start++;
+ return fDocument.get(start, end - start);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.templates.TemplatesPage#isEditorModifiable()
+ */
+ protected boolean isEditorModifiable() {
+ return fEditor.isEditorInputModifiable();
+ }
+}
#P org.eclipse.ui.views
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 6 Aug 2007 15:33:13 -0000
@@ -7,10 +7,11 @@
#
# Contributors:
# IBM Corporation - initial API and implementation
+# Dakshinamurthy Karra - Templates support (bug 69581)
###############################################################################
pluginName= Views
providerName= Eclipse.org
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 6 Aug 2007 15:33:13 -0000
@@ -18,6 +18,13 @@
class="org.eclipse.ui.views.contentoutline.ContentOutline"
id="org.eclipse.ui.views.ContentOutline">
+
+
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 6 Aug 2007 15:33:13 -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: 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,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - initial API and implementation
+ *******************************************************************************/
+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,11 @@
+###############################################################################
+# Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+# Dakshinamurthy Karra - initial API and implementation
+###############################################################################
+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,185 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - 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.
+ *
+ *
+ * @since 3.4
+ */
+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,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 Dakshinamurthy Karra 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:
+ * Dakshinamurthy Karra - initial API and implementation
+ *******************************************************************************/
+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
+ * @since 3.4
+ */
+public interface ITemplatesPage extends IPageBookViewPage {
+}