org.dslforge.texteditor.BasicTextEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.dslforge.texteditor.BasicTextEditor.java

Source

/**
 * <copyright>
 *
 * Copyright (c) 2015 PlugBee. 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:
 *     Amine Lajmi - Initial API and implementation
 *
 * </copyright>
 */
package org.dslforge.texteditor;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.apache.log4j.Logger;
import org.dslforge.styledtext.Annotation;
import org.dslforge.styledtext.BasicText;
import org.dslforge.styledtext.IContentAssistListener;
import org.dslforge.styledtext.ITextChangeListener;
import org.dslforge.styledtext.ITextModifyListener;
import org.dslforge.styledtext.ITextSaveListener;
import org.dslforge.styledtext.TextChangedEvent;
import org.dslforge.styledtext.TextSavedEvent;
import org.dslforge.styledtext.TextSelection;
import org.dslforge.styledtext.jface.IDocument;
import org.dslforge.styledtext.jface.ITextViewer;
import org.dslforge.styledtext.jface.TextDocument;
import org.dslforge.styledtext.jface.TextViewer;
import org.dslforge.texteditor.internal.Activator;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.IPropertySourceProvider;
import org.eclipse.ui.views.properties.PropertySheetPage;

public class BasicTextEditor extends EditorPart implements ISaveablesSource, IBasicTextEditor {

    static final Logger logger = Logger.getLogger(BasicTextEditor.class);

    private static final String DEFAULT_TEXT_FONT = "Tahoma, Geneva, sans-serif";
    /**
     * This editor's text viewer.
     */
    private ITextViewer viewer;
    private PropertySheetPage propertySheetPage;
    private IPath filePath;
    private ArrayList<String> index;
    private TextEditorSavable fSavable;
    private boolean isDirty;

    public BasicTextEditor() {
        super();
    }

    ITextChangeListener iTextChangeListener = new ITextChangeListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public void handleTextChanged(TextChangedEvent e) {
            setDirty(true);
            JsonObject object = (JsonObject) e.data;
            BasicTextEditor.this.handleTextChanged(object);
        }
    };

    protected void handleTextChanged(JsonObject object) {
        //override in subclasses.
    }

    IContentAssistListener iContentAssistListener = new IContentAssistListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public boolean verifyKey(VerifyEvent event) {
            JsonObject data = (JsonObject) event.data;
            if (data != null && data instanceof JsonObject) {
                JsonObject position = (JsonObject) data.get("pos");
                int row = position.get("row").asInt();
                int column = position.get("column").asInt();
                int offset = viewer.getTextWidget().getOffsetAtPosition(row, column);
                viewer.setSelection(new TextSelection(offset, 0));
                createCompletionProposals(offset);
                return true;
            }
            return false;
        }
    };

    /**
     * Creates completion proposals based on cursor position
     */
    protected void createCompletionProposals() {
        //override in subclass.
    }

    /**
     * Creates completion proposals based on the offset argument
     * 
     * @param offsetAtPosition
     */
    protected void createCompletionProposals(int offsetAtPosition) {
        //example
        //      List<String> proposalsExample = new ArrayList<String>();
        //      proposalsExample.add("my custom proposal 1");
        //      proposalsExample.add("my custom proposal 2");
        //      proposalsExample.add("my custom proposal 3");
        //      proposalsExample.add("my custom proposal 4");
        //      viewer.getTextWidget().setProposals(proposalsExample);
    }

    MenuDetectListener menuDetectListener = new MenuDetectListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public void menuDetected(MenuDetectEvent e) {
            MenuManager menuMgr = new MenuManager("#PopUp");
            menuMgr.setRemoveAllWhenShown(true);
            initContextMenu();
        }
    };

    @SuppressWarnings("serial")
    protected void initContextMenu() {
        MenuManager contextMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        Menu menu = contextMenuManager.createContextMenu(viewer.getTextWidget());
        contextMenuManager.setRemoveAllWhenShown(true);
        contextMenuManager.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                editorContextMenuAboutToShow(manager);
            }
        });
        contextMenuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        getSite().registerContextMenu(contextMenuManager, viewer.getSelectionProvider());
        viewer.getTextWidget().setMenu(menu);
    }

    /**
     * Convenience method to add the action installed under the given action id to the given menu.
     * @param menu the menu to add the action to
     * @param actionId the id of the action to be added
     */
    protected final void addAction(IMenuManager menu, String actionId) {
        IAction action = getAction(actionId);
        if (action != null) {
            menu.add(action);
        }
    }

    /**
     * Convenience method to add the action installed under the given action id to the specified group of the menu.
     * @param menu the menu to add the action to
     * @param group the group in the menu
     * @param actionId the id of the action to add
     */
    protected final void addAction(IMenuManager menu, String group, String actionId) {
        IAction action = getAction(actionId);
        if (action != null) {
            IMenuManager subMenu = menu.findMenuUsingPath(group);
            if (subMenu != null)
                subMenu.add(action);
            else
                menu.appendToGroup(group, action);
        }
    }

    /**
     * Convenience method to add a new group after the specified group.
     * @param menu the menu to add the new group to
     * @param existingGroup the group after which to insert the new group
     * @param newGroup the new group
     */
    protected final void addGroup(IMenuManager menu, String existingGroup, String newGroup) {
        IMenuManager subMenu = menu.findMenuUsingPath(existingGroup);
        if (subMenu != null)
            subMenu.add(new Separator(newGroup));
        else
            menu.appendToGroup(existingGroup, new Separator(newGroup));
    }

    /**
     * Returns the action from the editor contributor instead of duplicating actions creation.
     * 
     * @param actionId
     * @return the action with the given id
     */
    @Override
    public IAction getAction(String actionId) {
        IEditorActionBarContributor actionBarContributor = ((IEditorSite) getSite()).getActionBarContributor();
        if (actionBarContributor instanceof BasicTextEditorContributor) {
            return ((BasicTextEditorContributor) actionBarContributor).getAction(this, actionId);
        }
        return null;
    }

    protected void editorContextMenuAboutToShow(IMenuManager menuManager) {
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_UNDO));
        menuManager.add(new GroupMarker(IBasicTextEditorActionConstants.GROUP_SAVE));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_COPY));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_PRINT));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_EDIT));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_FIND));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_ADD));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.GROUP_REST));
        menuManager.add(new Separator(IBasicTextEditorActionConstants.MB_ADDITIONS));
        if (isEditable()) {
            addAction(menuManager, IBasicTextEditorActionConstants.GROUP_EDIT, ActionFactory.COPY.getId());
            addAction(menuManager, IBasicTextEditorActionConstants.GROUP_EDIT, ActionFactory.CUT.getId());
            addAction(menuManager, IBasicTextEditorActionConstants.GROUP_EDIT, ActionFactory.PASTE.getId());
            menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
            addAction(menuManager, IBasicTextEditorActionConstants.GROUP_UNDO, ActionFactory.UNDO.getId());
            addAction(menuManager, IBasicTextEditorActionConstants.GROUP_UNDO, ActionFactory.REDO.getId());
        }
    }

    @Override
    public boolean isEditable() {
        return viewer.isEditable();
    }

    @Override
    public void createPartControl(Composite parent) {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 1;
        parent.setLayout(gridLayout);
        viewer = createTextViewer(parent, SWT.FILL);
        viewer.setDocument(createEmptyDocument());
        getSite().setSelectionProvider(new ISelectionProvider() {
            @Override
            public void addSelectionChangedListener(ISelectionChangedListener listener) {
            }

            @Override
            public ISelection getSelection() {
                return new StructuredSelection(getEditorInput());
            }

            @Override
            public void removeSelectionChangedListener(ISelectionChangedListener listener) {
            }

            @Override
            public void setSelection(ISelection selection) {
            }
        });
        addListeners();
    }

    /**
     * Creates this editor's styled text widget
     * 
     * @param parent
     * @param styles
     * @return
     */
    protected ITextViewer createTextViewer(Composite parent, int styles) {
        BasicText textWidget = createTextWidget(parent, styles);
        return new TextViewer(textWidget);
    }

    /**
     * Creates and configures this editor's styled text widget
     */
    protected BasicText createTextWidget(Composite parent, int styles) {
        BasicText textWidget = new BasicText(parent, SWT.FILL);
        GridData textLayoutData = new GridData();
        textLayoutData.horizontalAlignment = SWT.FILL;
        textLayoutData.verticalAlignment = SWT.FILL;
        textLayoutData.grabExcessHorizontalSpace = true;
        textLayoutData.grabExcessVerticalSpace = true;
        textWidget.setLayoutData(textLayoutData);

        // set font
        Font font = new Font(Display.getCurrent(), new FontData(DEFAULT_TEXT_FONT, 14, SWT.NORMAL));
        textWidget.setFont(font);

        // set background color
        //Color color = new Color(parent.getDisplay(), new RGB(229, 242, 255));
        //textWidget.setBackground(color);

        // set read/write access
        textWidget.setEditable(true);

        // // add annotations
        // List<Annotation> annotations = new ArrayList<Annotation>();
        // annotations.add(new Annotation(AceSeverity.ERROR, 1, 3, "This is an
        // error"));
        // annotations.add(new Annotation(AceSeverity.WARNING, 3, 1, "This is a
        // warning"));
        // annotations.add(new Annotation(AceSeverity.INFO, 5, 1, "This is an
        // info"));
        // textWidget.setAnnotations(annotations);
        //
        // // highlight text ranges
        // List<TextRange> ranges = new ArrayList<TextRange>();
        // ranges.add(new TextRange(1, 0, 1, 40));
        // textWidget.setMarkers(ranges);

        return textWidget;
    }

    @Override
    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
        setSite(site);
        setPartName(input.getName());
        setInput(input);
        setDirty(false);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Object getAdapter(Class key) {
        if (key.equals(IPropertySheetPage.class)) {
            return getPropertySheetPage();
        }
        return super.getAdapter(key);
    }

    protected IPropertySheetPage getPropertySheetPage() {
        propertySheetPage = new PropertySheetPage();
        propertySheetPage.setPropertySourceProvider(new IPropertySourceProvider() {
            @Override
            public IPropertySource getPropertySource(Object object) {
                if (object instanceof URIEditorInput)
                    return new BasicTextEditorPropertySource((URIEditorInput) object);
                return null;
            }
        });
        return propertySheetPage;
    }

    @Override
    protected void setInput(IEditorInput input) {
        super.setInput(input);
        IPath path = null;
        if (input instanceof IPathEditorInput)
            path = ((IPathEditorInput) input).getPath();
        else if (input instanceof URIEditorInput)
            path = new Path(((URIEditorInput) input).getURI().toFileString());
        else
            throw new UnsupportedOperationException("Unsupported editor input type.");
        loadContentFromFile();
        setFilePath(path);
        firePropertyChange(PROP_INPUT);
    }

    /**
     * Creates an empty document
     */
    protected IDocument createEmptyDocument() {
        return new TextDocument();
    }

    /**
     * Loads the editor text content from file
     */
    protected void loadContentFromFile() {
        Display display = Display.getCurrent();
        if (display != null) {
            display.asyncExec(new Runnable() {
                @Override
                public void run() {
                    String content = "";
                    try {
                        content = readFromFile();
                    } catch (IOException ex) {
                        logger.error(ex.getMessage(), ex);
                    } finally {
                        setTextViewer(content);
                        setURL(filePath.lastSegment().toString());
                    }
                }
            });
        }
    }

    protected void setTextViewer(String content) {
        setText(content);
        viewer.getTextWidget().setText(content);
    }

    protected String readFromFile() throws IOException {
        logger.info("Reading from file " + filePath);
        StringBuilder text = new StringBuilder();
        String NL = System.getProperty("line.separator");
        long start = System.currentTimeMillis();
        Scanner scanner = new Scanner(new FileInputStream(filePath.toFile()), "UTF-8");
        try {
            while (scanner.hasNextLine()) {
                text.append(scanner.nextLine() + NL);
            }
        } finally {
            scanner.close();
        }
        long end = System.currentTimeMillis();
        logger.info("Reading took: " + ((end - start) / 1000));
        return text.toString();
    }

    @SuppressWarnings("serial")
    protected void addListeners() {
        BasicText textWidget = viewer.getTextWidget();
        if (textWidget != null && !textWidget.isDisposed()) {
            textWidget.addTextChangeListener(iTextChangeListener);

            KeyListener iKeyListener = new KeyListener() {

                @Override
                public void keyReleased(KeyEvent e) {
                    //customize in subclasses
                }

                @Override
                public void keyPressed(KeyEvent e) {
                    if ((e.stateMask & SWT.CTRL) == SWT.CTRL) {
                        createCompletionProposals();
                    }
                }
            };
            textWidget.addKeyListener(iKeyListener);

            textWidget.addTextModifyListener(new ITextModifyListener() {

                @Override
                public void handleTextModified(ModifyEvent event) {
                    JsonObject object = (JsonObject) event.data;
                    String text = object.get("value") != null ? object.get("value").asString() : null;
                    if (text != null) {
                        setText(text);
                    }
                }
            });

            textWidget.addTextSaveListener(new ITextSaveListener() {

                @Override
                public void handleTextSaved(TextSavedEvent event) {
                    IRunnableWithProgress runnable = new IRunnableWithProgress() {
                        public void run(IProgressMonitor monitor)
                                throws InvocationTargetException, InterruptedException {
                            Saveable[] saveables = getSaveables();
                            if (saveables.length == 0)
                                return;
                            monitor.beginTask(null, 100 * saveables.length);
                            for (int i = 0; i < saveables.length; i++) {
                                Saveable saveable = saveables[i];
                                try {
                                    saveable.doSave(SubMonitor.convert(monitor, 100));
                                } catch (CoreException e) {
                                    ErrorDialog.openError(getSite().getShell(), null, e.getMessage(),
                                            e.getStatus());
                                }
                                if (monitor.isCanceled()) {
                                    break;
                                }
                            }
                            monitor.done();
                        }
                    };
                    try {
                        runnable.run(new NullProgressMonitor());
                    } catch (InvocationTargetException e) {
                        // handle exception
                    } catch (InterruptedException e) {
                        // handle cancelation
                    }
                }
            });
            textWidget.addFocusListener(new FocusListener() {

                @Override
                public void focusLost(FocusEvent event) {
                    //customize in subclasses
                }

                @Override
                public void focusGained(FocusEvent event) {
                    //customize in subclasses
                }
            });
            textWidget.addMenuDetectListener(menuDetectListener);
            textWidget.addContentAssistListener(iContentAssistListener);
            textWidget.addMouseListener(new MouseListener() {

                @Override
                public void mouseUp(MouseEvent e) {
                    //customize in subclasses
                }

                @Override
                public void mouseDown(MouseEvent e) {
                    //customize in subclasses
                }

                @Override
                public void mouseDoubleClick(MouseEvent e) {
                    //customize in subclasses
                }
            });
        }
    }

    @Override
    public ITextViewer getViewer() {
        return viewer;
    }

    protected void setScope() {
        index = new ArrayList<String>();
        setScope(index);
        index.clear();
    }

    protected void setURL(String url) {
        viewer.getTextWidget().setUrl(url);
    }

    protected void setText(String text) {
        viewer.setText(text);
    }

    protected void setValidationStatus(String status) {
        viewer.getTextWidget().setStatus(status);
    }

    protected void setAnnotations(List<Annotation> annotations) {
        viewer.getTextWidget().setAnnotations(annotations);
    }

    protected void setScope(List<String> scope) {
        viewer.getTextWidget().setScope(scope);
    }

    protected void setProposals(List<String> proposals) {
        viewer.getTextWidget().setProposals(proposals);
    }

    @Override
    public boolean isDirty() {
        return this.isDirty;
    }

    protected void setDirty(boolean isDirty) {
        if (this.isDirty != isDirty) {
            this.isDirty = isDirty;
            firePropertyChange(PROP_DIRTY);
        }
    }

    @Override
    public boolean isSaveAsAllowed() {
        return false;
    }

    @Override
    public void doSave(IProgressMonitor monitor) {
        SubMonitor progress = SubMonitor.convert(monitor, 10);
        Writer writer = null;
        try {
            if (progress.isCanceled())
                throw new OperationCanceledException();
            // actually save resource (save only read/write resources)
            final File file = getFilePath().toFile();
            if (file.exists() && file.canWrite()) {
                try {
                    writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file.getAbsolutePath()),
                            Charset.availableCharsets().get("UTF-8")));
                    progress.worked(5);
                    writer.write(viewer.getTextWidget().getText());
                    progress.worked(5);
                    writer.close();
                } catch (IOException ex) {
                    logger.error(ex.getMessage(), ex);
                }
            }

        } catch (OperationCanceledException ex) {
            // do noting for now, forbid propagating exception
        } finally {
            progress.done();
            setDirty(false);
        }
    }

    @Override
    public void doSaveAs() {
        //not handled by default
    }

    @Override
    public void setFocus() {
    }

    @Override
    public void dispose() {
        if (viewer != null && viewer.getTextWidget() != null) {
            viewer.getTextWidget().dispose();
            viewer = null;
        }
        super.dispose();
    }

    public IWorkbenchWindow getWorkbenchWindow() {
        return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    }

    public IPath getFilePath() {
        return filePath;
    }

    public void setFilePath(IPath path) {
        this.filePath = path;
    }

    @Override
    public Saveable[] getSaveables() {
        if (fSavable == null)
            fSavable = new TextEditorSavable(this);
        return new Saveable[] { fSavable };
    }

    @Override
    public Saveable[] getActiveSaveables() {
        return getSaveables();
    }

    /**
     * This text editor's savable.
     */
    protected static class TextEditorSavable extends Saveable {

        /** The cached editor. */
        private IBasicTextEditor fTextEditor;
        /** The cached editor input. */
        private IEditorInput fEditorInput;

        /**
         * Creates a new savable for this text editor.
         *
         * @param textEditor
         *            the text editor
         */
        public TextEditorSavable(IBasicTextEditor textEditor) {
            Assert.isLegal(textEditor != null);
            fTextEditor = textEditor;
            fEditorInput = fTextEditor.getEditorInput();
            Assert.isLegal(fEditorInput != null);
        }

        /**
         * Disconnects the editor from this savable.
         */
        public void disconnectEditor() {
            fTextEditor = null;
        }

        /**
         * @see org.eclipse.ui.Saveable#getName()
         */
        public String getName() {
            return fEditorInput.getName();
        }

        /**
         * @see org.eclipse.ui.Saveable#getToolTipText()
         */
        public String getToolTipText() {
            return fEditorInput.getToolTipText();
        }

        /**
         * @see org.eclipse.ui.Saveable#getImageDescriptor()
         */
        public ImageDescriptor getImageDescriptor() {
            return fEditorInput.getImageDescriptor();
        }

        /**
         * @see org.eclipse.ui.Saveable#doSave(org.eclipse.core.runtime.
         * IProgressMonitor)
         */
        public void doSave(IProgressMonitor monitor) throws CoreException {
            fTextEditor.doSave(monitor);
        }

        public boolean isDirty() {
            return fTextEditor.isDirty();
        }

        /**
         * @see org.eclipse.ui.Saveable#supportsBackgroundSave()
         */
        public boolean supportsBackgroundSave() {
            return true;
        }

        /**
         * @see org.eclipse.ui.Saveable#hashCode()
         */
        public int hashCode() {
            int PRIME = 31;
            // compute the "normal" hash code, e.g. based on some identifier
            // unique within the defining plug-in
            int hash = Activator.PLUGIN_ID.hashCode();
            return hash * PRIME + Activator.PLUGIN_ID.hashCode();
        }

        /**
         * @see org.eclipse.ui.Saveable#equals(java.lang.Object)
         */
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!(obj instanceof Saveable))
                return false;
            return false;
        }
    }

    /**
     * Copy text to clip board from the given selection
     */
    public void performCopy(TextSelection selection) {
        if (!selection.isEmpty())
            viewer.getTextWidget().copy(selection.getText());
    }

    /**
     * Paste text from clip board at the current caret position
     */
    public void performPaste() {
        viewer.getTextWidget().paste();
    }

    /**
     * Cut text delimited by the given selection
     */
    public void performCut(TextSelection selection) {
        if (!selection.isEmpty())
            viewer.getTextWidget().cut(selection);
    }

    @Override
    public ISelectionProvider getSelectionProvider() {
        return viewer.getSelectionProvider();
    }
}