| /******************************************************************************* |
| * Copyright (c) 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.wst.common.snippets.ui; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IDocumentExtension4; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.swt.dnd.DragSourceEvent; |
| import org.eclipse.swt.dnd.TextTransfer; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| import org.eclipse.wst.common.snippets.core.ISnippetItem; |
| import org.eclipse.wst.common.snippets.internal.Logger; |
| import org.eclipse.wst.common.snippets.internal.SnippetsPlugin; |
| import org.eclipse.wst.common.snippets.internal.VariableItemHelper; |
| import org.eclipse.wst.common.snippets.internal.dnd.SnippetTextTransfer; |
| import org.eclipse.wst.common.snippets.internal.ui.EntrySerializer; |
| import org.eclipse.wst.common.snippets.internal.util.StringUtils; |
| |
| /** |
| * An insertion implementation that supports ISnippetVariables. The content |
| * string of the item can contain markers, in the form ${+variable+}, that |
| * will be replaced with user-supplied values at insertion time. |
| * |
| * @since 1.0 |
| */ |
| public class DefaultSnippetInsertion implements ISnippetInsertion { |
| private ISnippetItem fItem = null; |
| private Transfer[] fSupportedTransfers = null; |
| |
| /** |
| * Default constructor. Subclasses may call, but only the Snippets view |
| * should ever instantiate an insertion. |
| */ |
| public DefaultSnippetInsertion() { |
| super(); |
| } |
| |
| /** |
| * @return an array of Transfer types supported by this insertion |
| */ |
| protected Transfer[] createTransfers() { |
| return new Transfer[]{SnippetTextTransfer.getTransferInstance(), TextTransfer.getInstance()}; |
| } |
| |
| /** |
| * Insert the current snippet item. |
| * |
| * @param editorPart |
| * the editor part that is active |
| * @param textEditor |
| * the text editor (or adapter) with which to interact (may be |
| * the same as editorPart) |
| * @param document |
| * the text document to update |
| * @param textSelection |
| * the selection of text within the document to be replaced by |
| * the inserted snippet |
| * @throws BadLocationException |
| */ |
| protected void doInsert(IEditorPart editorPart, ITextEditor textEditor, IDocument document, ITextSelection textSelection) throws BadLocationException { |
| String replacement = getInsertString(editorPart.getEditorSite().getShell()); |
| if (replacement != null && (replacement.length() > 0 || textSelection.getLength() > 0)) { |
| // Update EOLs (bug 80231) |
| replacement = StringUtils.replace(replacement, "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
| replacement = StringUtils.replace(replacement, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| String preferredEOL = null; |
| if (document instanceof IDocumentExtension4) { |
| preferredEOL = ((IDocumentExtension4) document).getDefaultLineDelimiter(); |
| } |
| else { |
| Method getLineDelimiter = null; |
| try { |
| getLineDelimiter = document.getClass().getMethod("getLineDelimiter", new Class[0]); //$NON-NLS-1$ |
| } |
| catch (NoSuchMethodException e) { |
| // nothing, not unusual |
| } |
| if (getLineDelimiter != null) { |
| try { |
| preferredEOL = (String) getLineDelimiter.invoke(document, new Object[0]); |
| } |
| catch (IllegalAccessException e) { |
| // nothing, not unusual for a non-visible method |
| } |
| catch (InvocationTargetException e) { |
| // nothing, not unusual for a protected implementation |
| } |
| } |
| |
| } |
| if (preferredEOL == null) { |
| preferredEOL = System.getProperty("line.separator"); //$NON-NLS-1$ |
| } |
| if (!"\n".equals(preferredEOL) && preferredEOL != null) { //$NON-NLS-1$ |
| replacement = StringUtils.replace(replacement, "\n", preferredEOL); //$NON-NLS-1$ |
| } |
| |
| document.replace(textSelection.getOffset(), textSelection.getLength(), replacement); |
| } |
| } |
| |
| public void dragSetData(DragSourceEvent event, ISnippetItem item) { |
| boolean isSimpleText = TextTransfer.getInstance().isSupportedType(event.dataType); |
| if (isSimpleText) { |
| // set variable values to "" |
| IWorkbenchWindow window = SnippetsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); |
| Shell shell = null; |
| if (window != null) { |
| shell = window.getShell(); |
| } |
| String content = VariableItemHelper.getInsertString(shell, item); |
| // Update EOLs (bug 80231) |
| String systemEOL = System.getProperty("line.separator"); //$NON-NLS-1$ |
| content = StringUtils.replace(content, "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
| content = StringUtils.replace(content, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (!"\n".equals(systemEOL) && systemEOL != null) { //$NON-NLS-1$ |
| content = StringUtils.replace(content, "\n", systemEOL); //$NON-NLS-1$ |
| } |
| event.data = content; |
| } |
| else { |
| /* |
| * All complex insertions send an XML encoded version of the item |
| * itself as the data. The drop action must use this to prompt the |
| * user for the correct insertion data |
| */ |
| event.data = EntrySerializer.getInstance().toXML(item); |
| } |
| } |
| |
| /** |
| * Gets the string to be inserted by interacting further with the user if |
| * needed. |
| * |
| * @param host |
| * Shell to use for creating dialogs |
| * @return the string to be inserted |
| */ |
| protected String getInsertString(Shell host) { |
| if (fItem == null) |
| return ""; //$NON-NLS-1$ |
| String insertString = null; |
| if (fItem.getVariables().length > 0) { |
| insertString = VariableItemHelper.getInsertString(host, fItem); |
| } |
| else { |
| insertString = StringUtils.replace(fItem.getContentString(), "${cursor}", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return insertString; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#getTransfers() |
| */ |
| public Transfer[] getTransfers() { |
| if (fSupportedTransfers == null) |
| fSupportedTransfers = createTransfers(); |
| return fSupportedTransfers; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#insert(org.eclipse.ui.IEditorPart) |
| */ |
| public void insert(IEditorPart editorPart) { |
| if (editorPart == null) |
| return; |
| ITextEditor textEditor = null; |
| |
| if (editorPart instanceof ITextEditor) { |
| textEditor = (ITextEditor) editorPart; |
| } |
| if (textEditor == null) { |
| // MultiPageEditorPart has no accessors for the source |
| textEditor = (ITextEditor) editorPart.getAdapter(ITextEditor.class); |
| } |
| if (textEditor == null) { |
| // any errors here probably aren't really exceptional |
| Method getTextEditor = null; |
| try { |
| getTextEditor = editorPart.getClass().getMethod("getTextEditor", new Class[0]); //$NON-NLS-1$ |
| } |
| catch (NoSuchMethodException e) { |
| // nothing, not unusual |
| } |
| Object editor = null; |
| if (getTextEditor != null) { |
| try { |
| editor = getTextEditor.invoke(editorPart, new Object[0]); |
| } |
| catch (IllegalAccessException e) { |
| // nothing, not unusual for a non-visible method |
| } |
| catch (InvocationTargetException e) { |
| // nothing, not unusual for a protected implementation |
| } |
| if (editor instanceof IEditorPart && editor != editorPart && editor instanceof ITextEditor) { |
| textEditor = (ITextEditor) editor; |
| } |
| } |
| } |
| if (textEditor != null) { |
| insertIntoTextEditor(textEditor); |
| } |
| } |
| |
| private void insertIntoTextEditor(ITextEditor editor) { |
| // find the text widget, its Document, and the current selection |
| if (editor.isEditable()) { |
| IDocumentProvider docprovider = editor.getDocumentProvider(); |
| ISelectionProvider selprovider = editor.getSelectionProvider(); |
| if (docprovider != null && selprovider != null) { |
| IDocument document = docprovider.getDocument(editor.getEditorInput()); |
| ISelection selection = selprovider.getSelection(); |
| if (document != null && selection != null && selection instanceof ITextSelection) { |
| ITextSelection textSel = (ITextSelection) selection; |
| try { |
| doInsert(editor, editor, document, textSel); |
| } |
| catch (Exception t) { |
| Logger.logException("Could not insert " + fItem, t); //$NON-NLS-1$ |
| editor.getSite().getShell().getDisplay().beep(); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#setEditorPart(org.eclipse.ui.IEditorPart) |
| */ |
| public void setEditorPart(IEditorPart editorPart) { |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#setItem(org.eclipse.wst.common.snippets.core.ISnippetItem) |
| */ |
| public void setItem(ISnippetItem item) { |
| fItem = item; |
| } |
| } |