org.jboss.tools.vpe.preview.editor.VpvEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.vpe.preview.editor.VpvEditor.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is 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
 *
 * Contributor:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.jboss.tools.vpe.preview.editor;

import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationAdapter;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.ILocationProvider;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.progress.UIJob;
import org.jboss.tools.common.resref.core.ResourceReference;
import org.jboss.tools.jst.web.ui.WebUiPlugin;
import org.jboss.tools.jst.web.ui.internal.editor.preferences.IVpePreferencesPage;
import org.jboss.tools.vpe.editor.mozilla.MozillaEditor;
import org.jboss.tools.vpe.editor.mozilla.listener.EditorLoadWindowListener;
import org.jboss.tools.vpe.editor.preferences.VpeEditorPreferencesPage;
import org.jboss.tools.vpe.editor.preferences.VpeResourcesDialogFactory;
import org.jboss.tools.vpe.editor.toolbar.IVpeToolBarManager;
import org.jboss.tools.vpe.editor.toolbar.format.FormatControllerManager;
import org.jboss.tools.vpe.editor.util.FileUtil;
import org.jboss.tools.vpe.messages.VpeUIMessages;
import org.jboss.tools.vpe.preview.core.exceptions.BrowserErrorWrapper;
import org.jboss.tools.vpe.preview.core.exceptions.CannotOpenExternalFileException;
import org.jboss.tools.vpe.preview.core.exceptions.Messages;
import org.jboss.tools.vpe.preview.core.transform.VpvVisualModel;
import org.jboss.tools.vpe.preview.core.transform.VpvVisualModelHolder;
import org.jboss.tools.vpe.preview.core.util.ActionBar;
import org.jboss.tools.vpe.preview.core.util.EditorUtil;
import org.jboss.tools.vpe.preview.core.util.NavigationUtil;
import org.jboss.tools.vpe.preview.core.util.SuitableFileExtensions;
import org.jboss.tools.vpe.resref.core.CSSReferenceList;

/**
 * @author Konstantin Marmalyukov (kmarmaliykov)
 */

public class VpvEditor extends EditorPart implements VpvVisualModelHolder, IReusableEditor {
    /*
     * Paths for tool bar icons
     */
    public static final String ICON_PREFERENCE = "icons/preference.gif"; //$NON-NLS-1$
    public static final String ICON_PREFERENCE_DISABLED = "icons/preference_disabled.gif"; //$NON-NLS-1$
    public static final String ICON_REFRESH = "icons/refresh.gif"; //$NON-NLS-1$
    public static final String ICON_REFRESH_DISABLED = "icons/refresh_disabled.gif"; //$NON-NLS-1$
    public static final String ICON_PAGE_DESIGN_OPTIONS = "icons/point_to_css.gif"; //$NON-NLS-1$
    public static final String ICON_PAGE_DESIGN_OPTIONS_DISABLED = "icons/point_to_css_disabled.gif"; //$NON-NLS-1$
    public static final String ICON_ORIENTATION_SOURCE_LEFT = "icons/source_left.gif"; //$NON-NLS-1$
    public static final String ICON_ORIENTATION_SOURCE_TOP = "icons/source_top.gif"; //$NON-NLS-1$
    public static final String ICON_ORIENTATION_VISUAL_LEFT = "icons/visual_left.gif"; //$NON-NLS-1$
    public static final String ICON_ORIENTATION_VISUAI_TOP = "icons/visual_top.gif"; //$NON-NLS-1$
    public static final String ICON_ORIENTATION_SOURCE_LEFT_DISABLED = "icons/source_left_disabled.gif"; //$NON-NLS-1$
    public static final String ICON_SELECTION_BAR = "icons/selbar.gif"; //$NON-NLS-1$
    public static final String ICON_TEXT_FORMATTING = "icons/text-formatting.gif"; //$NON-NLS-1$
    public static final String ICON_SCROLL_LOCK = "icons/scroll_lock.gif"; //$NON-NLS-1$

    private static Map<String, String> layoutIcons;
    private static Map<String, String> layoutNames;
    private static List<String> layoutValues;
    private int currentOrientationIndex = 1;
    private Action openVPEPreferencesAction;
    private Action showResouceDialogAction;
    private Action rotateEditorsAction;
    private Action showSelectionBarAction;
    static {
        /*
         * Values from <code>layoutValues</code> should correspond to the order
         * when increasing the index of the array will cause 
         * the source editor rotation 
         */
        layoutIcons = new HashMap<String, String>();
        layoutIcons.put(IVpePreferencesPage.SPLITTING_HORIZ_LEFT_SOURCE_VALUE, ICON_ORIENTATION_SOURCE_LEFT);
        layoutIcons.put(IVpePreferencesPage.SPLITTING_VERT_TOP_SOURCE_VALUE, ICON_ORIENTATION_SOURCE_TOP);
        layoutIcons.put(IVpePreferencesPage.SPLITTING_HORIZ_LEFT_VISUAL_VALUE, ICON_ORIENTATION_VISUAL_LEFT);
        layoutIcons.put(IVpePreferencesPage.SPLITTING_VERT_TOP_VISUAL_VALUE, ICON_ORIENTATION_VISUAI_TOP);

        layoutNames = new HashMap<String, String>();
        layoutNames.put(IVpePreferencesPage.SPLITTING_HORIZ_LEFT_SOURCE_VALUE,
                VpeUIMessages.SPLITTING_HORIZ_LEFT_SOURCE_TOOLTIP);
        layoutNames.put(IVpePreferencesPage.SPLITTING_VERT_TOP_SOURCE_VALUE,
                VpeUIMessages.SPLITTING_VERT_TOP_SOURCE_TOOLTIP);
        layoutNames.put(IVpePreferencesPage.SPLITTING_HORIZ_LEFT_VISUAL_VALUE,
                VpeUIMessages.SPLITTING_HORIZ_LEFT_VISUAL_TOOLTIP);
        layoutNames.put(IVpePreferencesPage.SPLITTING_VERT_TOP_VISUAL_VALUE,
                VpeUIMessages.SPLITTING_VERT_TOP_VISUAL_TOOLTIP);

        layoutValues = new ArrayList<String>();
        layoutValues.add(IVpePreferencesPage.SPLITTING_HORIZ_LEFT_SOURCE_VALUE);
        layoutValues.add(IVpePreferencesPage.SPLITTING_VERT_TOP_SOURCE_VALUE);
        layoutValues.add(IVpePreferencesPage.SPLITTING_HORIZ_LEFT_VISUAL_VALUE);
        layoutValues.add(IVpePreferencesPage.SPLITTING_VERT_TOP_VISUAL_VALUE);

    }

    private final ToolBarManager toolBarManager = new ToolBarManager(SWT.VERTICAL | SWT.FLAT);
    private FormatControllerManager formatControllerManager = new FormatControllerManager();
    private VpvEditorController controller;
    private ToolBar verBar = null;
    private IPropertyChangeListener selectionBarCloseListener;

    private IVpeToolBarManager vpeToolBarManager;

    private EditorLoadWindowListener editorLoadWindowListener;
    private EditorListener editorListener;
    private IDocumentListener documentListener;

    private Browser browser;
    private VpvVisualModel visualModel;
    private int modelHolderId;
    private SelectionListener selectionListener;
    protected IEditorPart sourceEditor;
    private Job currentJob;

    private ActionBar actionBar;
    protected BrowserErrorWrapper errorWrapper = new BrowserErrorWrapper();

    public VpvEditor() {
    }

    public VpvEditor(IEditorPart sourceEditor) {
        setModelHolderId(Activator.getDefault().getVisualModelHolderRegistry().registerHolder(this));
        setSourceEditor(sourceEditor);
    }

    @Override
    public void doSave(IProgressMonitor arg0) {
    }

    @Override
    public void doSaveAs() {
    }

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

    public void setInput(IEditorInput input) {
        boolean isVisualRefreshRequired = (getEditorInput() != null && getEditorInput() != input
                && controller != null);
        super.setInput(input);
        if (isVisualRefreshRequired)
            controller.visualRefresh();
    }

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

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

    public void setController(VpvEditorController controller) {
        this.controller = controller;
        formatControllerManager.setVpeController(controller);
        controller.setToolbarFormatControllerManager(formatControllerManager);
    }

    public ToolBar createVisualToolbar(Composite parent) {
        verBar = toolBarManager.createControl(parent);

        /*
         * Create OPEN VPE PREFERENCES tool bar item
         */
        openVPEPreferencesAction = new Action(VpeUIMessages.PREFERENCES, IAction.AS_PUSH_BUTTON) {
            @Override
            public void run() {
                VpeEditorPreferencesPage.openPreferenceDialog();
            }
        };
        openVPEPreferencesAction
                .setImageDescriptor(ImageDescriptor.createFromFile(MozillaEditor.class, ICON_PREFERENCE));
        openVPEPreferencesAction.setToolTipText(VpeUIMessages.PREFERENCES);
        toolBarManager.add(openVPEPreferencesAction);

        /*
         * Create SHOW RESOURCE DIALOG tool bar item
         * 
         * https://jira.jboss.org/jira/browse/JBIDE-3966
         * Disabling Page Design Options for external files. 
         */
        IEditorInput input = getEditorInput();
        IFile file = null;
        if (input instanceof IFileEditorInput) {
            file = ((IFileEditorInput) input).getFile();
        } else if (input instanceof ILocationProvider) {
            ILocationProvider provider = (ILocationProvider) input;
            IPath path = provider.getPath(input);
            if (path != null) {
                file = FileUtil.getFile(input, path.lastSegment());
            }
        }
        boolean fileExistsInWorkspace = ((file != null) && (file.exists()));
        showResouceDialogAction = new Action(VpeUIMessages.PAGE_DESIGN_OPTIONS, IAction.AS_PUSH_BUTTON) {
            @Override
            public void run() {
                VpeResourcesDialogFactory.openVpeResourcesDialog(VpvEditor.this);
            }
        };
        showResouceDialogAction.setImageDescriptor(ImageDescriptor.createFromFile(MozillaEditor.class,
                fileExistsInWorkspace ? ICON_PAGE_DESIGN_OPTIONS : ICON_PAGE_DESIGN_OPTIONS_DISABLED));
        if (!fileExistsInWorkspace) {
            showResouceDialogAction.setEnabled(false);
        }
        showResouceDialogAction.setToolTipText(VpeUIMessages.PAGE_DESIGN_OPTIONS);
        toolBarManager.add(showResouceDialogAction);

        /*
         * Create ROTATE EDITORS tool bar item
         * 
         * https://jira.jboss.org/jira/browse/JBIDE-4152
         * Compute initial icon state and add it to the tool bar.
         */
        String newOrientation = WebUiPlugin.getDefault().getPreferenceStore()
                .getString(IVpePreferencesPage.VISUAL_SOURCE_EDITORS_SPLITTING);
        currentOrientationIndex = layoutValues.indexOf(newOrientation);
        rotateEditorsAction = new Action(VpeUIMessages.VISUAL_SOURCE_EDITORS_SPLITTING, IAction.AS_PUSH_BUTTON) {
            @Override
            public void run() {
                /*
                 * Rotate editors orientation clockwise.
                 */
                currentOrientationIndex++;
                if (currentOrientationIndex >= layoutValues.size()) {
                    currentOrientationIndex = currentOrientationIndex % layoutValues.size();
                }
                String newOrientation = layoutValues.get(currentOrientationIndex);
                /*
                 * Update icon and tooltip
                 */
                this.setImageDescriptor(
                        ImageDescriptor.createFromFile(MozillaEditor.class, layoutIcons.get(newOrientation)));

                this.setToolTipText(layoutNames.get(newOrientation));
                /*
                 * Call <code>filContainer()</code> from VpeEditorPart
                 * to redraw CustomSashForm with new layout.
                 */
                ((VpvEditorPart) getController().getPageContext().getEditPart()).fillContainer(true,
                        newOrientation);
                WebUiPlugin.getDefault().getPreferenceStore()
                        .setValue(IVpePreferencesPage.VISUAL_SOURCE_EDITORS_SPLITTING, newOrientation);
            }
        };
        rotateEditorsAction.setImageDescriptor(
                ImageDescriptor.createFromFile(MozillaEditor.class, layoutIcons.get(newOrientation)));
        rotateEditorsAction.setToolTipText(layoutNames.get(newOrientation));
        toolBarManager.add(rotateEditorsAction);

        /*
         * Create SHOW SELECTION BAR tool bar item
         */
        showSelectionBarAction = new Action(VpeUIMessages.SHOW_SELECTION_BAR, IAction.AS_CHECK_BOX) {
            @Override
            public void run() {
                /*
                 * Update Selection Bar 
                 */
                ((VpvEditorPart) controller.getPageContext().getEditPart()).updateSelectionBar(this.isChecked());
                WebUiPlugin.getDefault().getPreferenceStore().setValue(IVpePreferencesPage.SHOW_SELECTION_TAG_BAR,
                        this.isChecked());
            }
        };

        selectionBarCloseListener = new IPropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent event) {
                /*
                 * Change icon state after sel bar was closed
                 */
                if (IVpePreferencesPage.SHOW_SELECTION_TAG_BAR.equalsIgnoreCase(event.getProperty())) {
                    boolean newValue = (Boolean) event.getNewValue();
                    if (showSelectionBarAction.isChecked() != newValue) {
                        showSelectionBarAction.setChecked(newValue);
                    }
                }
            }
        };
        WebUiPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(selectionBarCloseListener);

        showSelectionBarAction
                .setImageDescriptor(ImageDescriptor.createFromFile(MozillaEditor.class, ICON_SELECTION_BAR));
        showSelectionBarAction.setToolTipText(VpeUIMessages.SHOW_SELECTION_BAR);
        toolBarManager.add(showSelectionBarAction);

        updateToolbarItemsAccordingToPreferences();
        toolBarManager.update(true);

        parent.addDisposeListener(new DisposeListener() {

            public void widgetDisposed(DisposeEvent e) {
                toolBarManager.dispose();
                toolBarManager.removeAll();
                openVPEPreferencesAction = null;
                rotateEditorsAction = null;
                ;
                showSelectionBarAction = null;
            }
        });
        return verBar;
    }

    public void addPreviewToolbarItems() {
        actionBar = new VisualEditorActionBar(browser, Activator.getDefault().getPreferenceStore(), controller);
        actionBar.fillLocalToolBar(toolBarManager);
        toolBarManager.update(true);
    }

    @Override
    public void createPartControl(Composite parent) {
        GridLayout layout = new GridLayout(2, false);
        layout.marginHeight = 0;
        layout.marginWidth = 2;
        layout.verticalSpacing = 2;
        layout.horizontalSpacing = 2;
        layout.marginBottom = 0;
        parent.setLayout(layout);

        // Editors and Toolbar composite 
        Composite cmpEdTl = new Composite(parent, SWT.NONE);
        GridLayout layoutEdTl = new GridLayout(1, false);
        layoutEdTl.verticalSpacing = 0;
        layoutEdTl.marginHeight = 0;
        layoutEdTl.marginBottom = 3;
        layoutEdTl.marginWidth = 0;
        cmpEdTl.setLayout(layoutEdTl);
        cmpEdTl.setLayoutData(new GridData(GridData.FILL_BOTH));

        /*
         * https://jira.jboss.org/jira/browse/JBIDE-4429
         * Toolbar was moved to VpeEditorPart.
         *  'verBar' should be created in createVisualToolbar(..) in VpeEditorPart
         *  and only after that MozillaEditor should be created itself. 
         */
        //      if (null != verBar) {
        //         // Use vpeToolBarManager to create a horizontal toolbar.
        //         vpeToolBarManager = new VpeToolBarManager();
        //         if (vpeToolBarManager != null) {
        //            vpeToolBarManager.createToolBarComposite(cmpEdTl);
        //            vpeToolBarManager.addToolBar(new TextFormattingToolBar(formatControllerManager));
        //         }
        //      }

        //Create a composite to the Editor
        final Composite cmpEd = new Composite(cmpEdTl, SWT.NATIVE);
        GridLayout layoutEd = new GridLayout(1, false);
        layoutEd.marginBottom = 0;
        layoutEd.marginHeight = 1;
        layoutEd.marginWidth = 0;
        layoutEd.marginRight = 0;
        layoutEd.marginLeft = 1;
        layoutEd.verticalSpacing = 0;
        layoutEd.horizontalSpacing = 0;
        cmpEd.setLayout(layoutEd);
        cmpEd.setLayoutData(new GridData(GridData.FILL_BOTH));

        //TODO Add a paintListener to cmpEd and give him a border top and left only
        Color buttonDarker = parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
        cmpEd.setBackground(buttonDarker);

        try {
            browser = new Browser(cmpEd, SWT.NONE);
            browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
            browser.addLocationListener(new LocationAdapter() {
                @Override
                public void changed(LocationEvent event) {
                    NavigationUtil.disableJsPopUps(browser);
                    NavigationUtil.disableLinks(browser);
                    NavigationUtil.disableInputs(browser);

                    ISelection currentSelection = getCurrentSelection();
                    NavigationUtil.updateSelectionAndScrollToIt(currentSelection, browser, visualModel);
                }
            });

            browser.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseUp(MouseEvent event) {
                    NavigationUtil.navigateToVisual(sourceEditor, browser, visualModel, event.x, event.y);
                }

            });

            if (editorLoadWindowListener != null) {
                editorLoadWindowListener.load();
            }

            inizializeSelectionListener();
            inizializeEditorListener();
        } catch (Throwable t) {
            //cannot create browser. show error message then

            /*
             * Disable VPE toolbar
             */
            if (verBar != null) {
                verBar.setEnabled(false);
            }
            errorWrapper.showError(cmpEd, t);
        }

    }

    private void inizializeSelectionListener() {
        selectionListener = new SelectionListener();
        getSite().getPage().addPostSelectionListener(selectionListener);
    }

    private ISelection getCurrentSelection() {
        Activator activator = Activator.getDefault();
        IWorkbench workbench = activator.getWorkbench();
        IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
        ISelectionService selectionService = workbenchWindow.getSelectionService();
        ISelection selection = selectionService.getSelection();
        return selection;
    }

    @Override
    public void setFocus() {
        if (browser != null) {
            browser.setFocus();
        }
    }

    public void dispose() {
        if (selectionBarCloseListener != null) {
            WebUiPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(selectionBarCloseListener);
        }
        if (selectionListener != null) {
            getSite().getPage().removePostSelectionListener(selectionListener);
        }
        if (editorListener != null) {
            getSite().getPage().removePartListener(editorListener);
        }
        Activator.getDefault().getVisualModelHolderRegistry().unregisterHolder(this);

        if (vpeToolBarManager != null) {
            vpeToolBarManager.dispose();
            vpeToolBarManager = null;
        }

        if (controller != null) {
            controller.dispose();
            controller = null;
        }

        if (actionBar != null) {
            actionBar.dispose();
        }

        if (browser != null) {
            browser.dispose();
            browser = null;
        }

        formatControllerManager.setVpeController(null);
        formatControllerManager = null;
        super.dispose();
    }

    public void updateToolbarItemsAccordingToPreferences() {
        String prefsOrientation = WebUiPlugin.getDefault().getPreferenceStore()
                .getString(IVpePreferencesPage.VISUAL_SOURCE_EDITORS_SPLITTING);
        int prefsOrientationIndex = layoutValues.indexOf(prefsOrientation);

        boolean prefsShowSelectionBar = WebUiPlugin.getDefault().getPreferenceStore()
                .getBoolean(IVpePreferencesPage.SHOW_SELECTION_TAG_BAR);

        if (showSelectionBarAction != null) {
            showSelectionBarAction.setChecked(prefsShowSelectionBar);
        }
        if (rotateEditorsAction != null) {
            currentOrientationIndex = prefsOrientationIndex;
            rotateEditorsAction.setImageDescriptor(
                    ImageDescriptor.createFromFile(MozillaEditor.class, layoutIcons.get(prefsOrientation)));
            rotateEditorsAction.setToolTipText(layoutNames.get(prefsOrientation));
        }
    }

    public void reload() {
        if (browser != null)
            formRequestToServer();
        //      browser.setUrl(browser.getUrl());
    }

    public void refresh(Browser browser) {
        if (browser != null && !browser.isDisposed()) {
            browser.setUrl(NavigationUtil.fixUrl(browser));
        }
    }

    private void formRequestToServer() {
        IFile ifile = EditorUtil.getFileOpenedInEditor(sourceEditor);
        if (ifile != null && SuitableFileExtensions.contains(ifile.getFileExtension().toString())) {
            String url;
            try {
                url = EditorUtil.formUrl(ifile, modelHolderId, "" + Activator.getDefault().getServer().getPort()); //$NON-NLS-1$
                browser.setUrl(url);
                ResourceReference[] csss = CSSReferenceList.getInstance().getAllResources(ifile);
                for (ResourceReference css : csss) {
                    String path = "file:///" + css.getLocation();
                    String script = "var fileref = document.createElement('link');"
                            + "fileref.setAttribute('rel', 'stylesheet');"
                            + "fileref.setAttribute('type', 'text/css');" + "fileref.setAttribute('href', '" + path
                            + "');" + "document.getElementsByTagName('head')[0].appendChild(fileref);";
                    browser.execute(script);
                }
            } catch (UnsupportedEncodingException e) {
                Activator.logError(e);
            }
        } else {
            Composite parent = browser.getParent();
            browser.dispose();
            browser = null;
            errorWrapper.showError(parent, new CannotOpenExternalFileException(
                    MessageFormat.format(Messages.CANNOT_SHOW_EXTERNAL_FILE, VpeUIMessages.VISUAL_EDITOR)));
        }
    }

    private void updatePreview() {
        if (currentJob == null || currentJob.getState() != Job.WAITING) {
            if (currentJob != null && currentJob.getState() == Job.SLEEPING) {
                currentJob.cancel();
            }
            currentJob = createPreviewUpdateJob();
        }

        currentJob.schedule(500);
    }

    private Job createPreviewUpdateJob() {
        Job job = new UIJob("Preview Update") { //$NON-NLS-1$
            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                if (browser != null && !browser.isDisposed()) {
                    refresh(browser);
                }
                return Status.OK_STATUS;
            }
        };
        return job;
    }

    /**
     * @return the controller
     */
    public VpvEditorController getController() {
        return controller;
    }

    @Override
    public void setVisualModel(VpvVisualModel visualModel) {
        this.visualModel = visualModel;
    }

    public void setModelHolderId(int modelHolderId) {
        this.modelHolderId = modelHolderId;
    }

    public void setBrowser(Browser browser) {
        this.browser = browser;
    }

    public Browser getBrowser() {
        return browser;
    }

    public void setEditorLoadWindowListener(EditorLoadWindowListener listener) {
        editorLoadWindowListener = listener;
    }

    protected void inizializeEditorListener() {
        editorListener = new EditorListener();
        getSite().getPage().addPartListener(editorListener);
    }

    private class EditorListener implements IPartListener2 {

        @Override
        public void partActivated(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partBroughtToTop(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partClosed(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partDeactivated(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partOpened(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partHidden(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partVisible(IWorkbenchPartReference partRef) {
        }

        @Override
        public void partInputChanged(IWorkbenchPartReference partRef) {
            IWorkbenchPage page = partRef.getPage();
            if (page != null) {
                IEditorPart editor = page.getActiveEditor();
                if (editor != null) {
                    setSourceEditor(editor);
                    formRequestToServer();
                }
            }
        }
    }

    /**
     * @param sourceEditor the sourceEditor to set
     */
    protected void setSourceEditor(IEditorPart sourceEditor) {
        removeDocumentListener(); // removing old document listener
        this.sourceEditor = sourceEditor;
        addDocumentListener(); // adding a new one
    }

    private IDocument getDocument() {
        return (IDocument) this.sourceEditor.getAdapter(IDocument.class);
    }

    private void removeDocumentListener() {
        if (this.sourceEditor != null) {
            IDocument document = getDocument();
            if (document != null) {
                document.removeDocumentListener(getDocumentListener());
            }
        }
    }

    private void addDocumentListener() {
        if (this.sourceEditor != null) {
            IDocument document = getDocument();
            if (document != null) {
                document.addDocumentListener(getDocumentListener());
            }
        }
    }

    private IDocumentListener getDocumentListener() {
        if (documentListener == null) {
            documentListener = new IDocumentListener() {

                @Override
                public void documentAboutToBeChanged(DocumentEvent event) {
                }

                @Override
                public void documentChanged(DocumentEvent event) {
                    if (actionBar.isAutomaticRefreshEnabled() && controller.isVisualEditorVisible()) {
                        updatePreview();
                    }
                }

            };
        }
        return documentListener;
    }

    private class SelectionListener implements ISelectionListener {

        @Override
        public void selectionChanged(IWorkbenchPart part, ISelection selection) {
            if (selection instanceof IStructuredSelection
                    && EditorUtil.isInCurrentEditor((IStructuredSelection) selection, sourceEditor)) {
                NavigationUtil.updateSelectionAndScrollToIt(selection, browser, visualModel);
            }
        }
    }
}