org.eclipse.help.ui.internal.views.BrowserPart.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.help.ui.internal.views.BrowserPart.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2011 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.help.ui.internal.views;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpBasePlugin;
import org.eclipse.help.internal.base.util.LinkUtil;
import org.eclipse.help.internal.util.URLCoder;
import org.eclipse.help.ui.internal.HelpUIPlugin;
import org.eclipse.help.ui.internal.HelpUIResources;
import org.eclipse.help.ui.internal.IHelpUIConstants;
import org.eclipse.help.ui.internal.Messages;
import org.eclipse.help.ui.internal.util.FontUtils;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.OpenWindowListener;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.browser.StatusTextEvent;
import org.eclipse.swt.browser.StatusTextListener;
import org.eclipse.swt.browser.WindowEvent;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.osgi.service.prefs.BackingStoreException;

public class BrowserPart extends AbstractFormPart implements IHelpPart {
    private final static String QUERY = "BrowserPartQuery:"; //$NON-NLS-1$
    private final static String HIGHLIGHT_ON = "highlight-on"; //$NON-NLS-1$
    private final static String HELP_VIEW_SCALE = "help_view_scale"; //$NON-NLS-1$
    private final static String EMPTY_PAGE = "<html><head></head><body></body></html>"; //$NON-NLS-1$

    private ReusableHelpPart parent;

    private Browser browser;

    private String id;

    private int lastProgress = -1;

    private static final int SCALE_MAX = 250;

    private static final int SCALE_MIN = 50;

    private static final int SCALE_INCREMENT = 10;

    private int fontScalePercentage = 100;

    private String url;

    private Action showExternalAction;

    private Action syncTocAction;

    private Action highlightAction;

    private Action bookmarkAction;

    private Action printAction;

    private Action magnifyAction;

    private Action reduceAction;

    private String statusURL;

    private String title;

    public BrowserPart(final Composite parent, FormToolkit toolkit, final IToolBarManager tbm,
            IMenuManager menuManager) {
        browser = new Browser(parent, SWT.NULL);
        browser.addLocationListener(new LocationListener() {
            public void changing(LocationEvent event) {
                if (redirectLink(event.location))
                    event.doit = false;
                if (!event.doit && event.location != null && event.location.startsWith("https://")) { //$NON-NLS-1$
                    try {
                        BaseHelpSystem.getHelpBrowser(true).displayURL(event.location);
                    } catch (Exception exc) {
                    }
                }
            }

            public void changed(LocationEvent event) {
                String url = event.location;
                boolean isResult = url.indexOf("resultof") != -1; //$NON-NLS-1$
                BrowserPart.this.parent.browserChanged(url);
                BrowserPart.this.url = url;
                updateSyncTocAction();
                BrowserPart.this.highlightAction.setEnabled(isResult);
            }
        });
        browser.addProgressListener(new ProgressListener() {
            public void changed(ProgressEvent e) {
                if (e.current == e.total)
                    return;
                IStatusLineManager slm = BrowserPart.this.parent.getStatusLineManager();
                IProgressMonitor monitor = slm != null ? slm.getProgressMonitor() : null;
                if (lastProgress == -1) {
                    lastProgress = 0;
                    if (monitor != null) {
                        monitor.beginTask("", e.total); //$NON-NLS-1$
                        slm.setCancelEnabled(true);
                    }
                } else if (monitor != null && monitor.isCanceled()) {
                    browser.stop();
                    return;
                }
                if (monitor != null)
                    monitor.worked(e.current - lastProgress);
                lastProgress = e.current;
            }

            public void completed(ProgressEvent e) {
                IStatusLineManager slm = BrowserPart.this.parent.getStatusLineManager();
                IProgressMonitor monitor = slm != null ? slm.getProgressMonitor() : null;
                if (monitor != null) {
                    slm.setCancelEnabled(false);
                    monitor.done();
                }
                lastProgress = -1;
                if (fontScalePercentage != 100) {
                    rescale();
                }
                String value = executeQuery("document.title"); //$NON-NLS-1$
                BrowserPart.this.title = value != null ? value : "N/A"; //$NON-NLS-1$
            }
        });
        browser.addStatusTextListener(new StatusTextListener() {
            public void changed(StatusTextEvent event) {
                if (processQuery(event.text))
                    return;
                IStatusLineManager statusLine = BrowserPart.this.parent.getStatusLineManager();
                if (statusLine != null)
                    statusLine.setMessage(event.text);
                if (event.text.indexOf("://") != -1) //$NON-NLS-1$
                    statusURL = event.text;
            }
        });
        browser.addOpenWindowListener(new OpenWindowListener() {
            public void open(WindowEvent event) {
                if (statusURL != null) {
                    try {
                        String relativeURL = BaseHelpSystem.unresolve(new URL(statusURL));
                        if (BrowserPart.this.parent.isHelpResource(relativeURL)) {
                            BrowserPart.this.parent.showExternalURL(relativeURL);
                            event.required = true;
                        }
                    } catch (MalformedURLException e) {
                        HelpUIPlugin.logError("Malformed URL: " + statusURL, e); //$NON-NLS-1$
                    }
                }
            }
        });
        contributeToToolBar(tbm);
        contributeToMenu(menuManager);
    }

    private String executeQuery(String domValue) {
        return (String) browser.evaluate("return " + domValue + ';'); //$NON-NLS-1$
    }

    private boolean processQuery(String text) {
        if (text.startsWith(QUERY)) {
            browser.setData("query", text.substring(QUERY.length())); //$NON-NLS-1$
            return true;
        }
        return false;
    }

    private void contributeToToolBar(IToolBarManager tbm) {
        boolean highlight = Platform.getPreferencesService().getBoolean(HelpBasePlugin.PLUGIN_ID, HIGHLIGHT_ON,
                true, null);
        showExternalAction = new Action() {
            public void run() {
                BusyIndicator.showWhile(browser.getDisplay(), new Runnable() {
                    public void run() {
                        try {
                            parent.showExternalURL(BaseHelpSystem.unresolve(new URL(url)));
                        } catch (MalformedURLException e) {
                            HelpUIPlugin.logError("Malformed URL: " + statusURL, e); //$NON-NLS-1$
                        }
                    }
                });
            }
        };
        showExternalAction.setToolTipText(Messages.BrowserPart_showExternalTooltip);
        showExternalAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_NW));
        syncTocAction = new Action() {
            public void run() {
                doSyncToc();
            }
        };
        syncTocAction.setToolTipText(Messages.BrowserPart_syncTocTooltip);
        syncTocAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_SYNC_TOC));
        syncTocAction.setEnabled(false);
        bookmarkAction = new Action() {
            public void run() {
                String href = LinkUtil.stripParams(BaseHelpSystem.unresolve(url));
                BaseHelpSystem.getBookmarkManager().addBookmark(href, title);
            }
        };
        bookmarkAction.setToolTipText(Messages.BrowserPart_bookmarkTooltip);
        bookmarkAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_ADD_BOOKMARK));

        highlightAction = new Action() {
            public void run() {
                IScopeContext instanceScope = InstanceScope.INSTANCE;
                IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID);
                prefs.putBoolean(HIGHLIGHT_ON, highlightAction.isChecked());
                if (browser.getUrl().indexOf("resultof") != -1) //$NON-NLS-1$
                    browser.execute("setHighlight(" + highlightAction.isChecked() + ");"); //$NON-NLS-1$ //$NON-NLS-2$
            }
        };
        highlightAction.setChecked(highlight);
        highlightAction.setToolTipText(Messages.BrowserPart_highlightTooltip);
        highlightAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_HIGHLIGHT));

        printAction = new Action(ActionFactory.PRINT.getId()) {
            public void run() {
                doPrint();
            }
        };
        printAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_HELP_PRINT));
        printAction.setToolTipText(Messages.BrowserPart_printTooltip);

        tbm.insertBefore("back", showExternalAction); //$NON-NLS-1$
        tbm.insertBefore("back", syncTocAction); //$NON-NLS-1$
        tbm.insertBefore("back", printAction); //$NON-NLS-1$
        tbm.insertBefore("back", bookmarkAction); //$NON-NLS-1$
        tbm.insertBefore("back", highlightAction); //$NON-NLS-1$
        tbm.insertBefore("back", new Separator()); //$NON-NLS-1$
        enableButtons();
    }

    private void contributeToMenu(IMenuManager menuManager) {
        if (FontUtils.canRescaleHelpView()) {
            fontScalePercentage = Platform.getPreferencesService().getInt(HelpBasePlugin.PLUGIN_ID, HELP_VIEW_SCALE,
                    100, null);
            if (menuManager != null) {
                addMenuActions(menuManager);
            }
        }
    }

    private void addMenuActions(IMenuManager menuManager) {
        magnifyAction = new Action() {

            public void run() {
                doMagnify(SCALE_INCREMENT);
            }
        };
        magnifyAction.setToolTipText(Messages.BrowserPart_magnifyTooltip);
        magnifyAction.setText(Messages.BrowserPart_magnifyTooltip);
        magnifyAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_MAGNIFY));
        magnifyAction
                .setDisabledImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_D_MAGNIFY));

        reduceAction = new Action() {

            public void run() {
                doMagnify(-SCALE_INCREMENT);
            }
        };
        reduceAction.setToolTipText(Messages.BrowserPart_reduceTooltip);
        reduceAction.setText(Messages.BrowserPart_reduceTooltip);
        reduceAction.setImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_REDUCE));
        reduceAction
                .setDisabledImageDescriptor(HelpUIResources.getImageDescriptor(IHelpUIConstants.IMAGE_D_REDUCE));
        menuManager.add(new Separator());
        menuManager.add(reduceAction);
        menuManager.add(magnifyAction);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.help.ui.internal.views.IHelpPart#init(org.eclipse.help.ui.internal.views.NewReusableHelpPart)
     */
    public void init(ReusableHelpPart parent, String id, IMemento memento) {
        this.parent = parent;
        this.id = id;
        if (memento != null) {
            String href = memento.getString("BrowserPart.url"); //$NON-NLS-1$
            if (href != null)
                showURL(BaseHelpSystem.resolve(href, "/help/ntopic").toString()); //$NON-NLS-1$
        }
    }

    public String getId() {
        return id;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.help.ui.internal.views.IHelpPart#getControl()
     */
    public Control getControl() {
        return browser;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.help.ui.internal.views.IHelpPart#setVisible(boolean)
     */
    public void setVisible(boolean visible) {
        if (browser != null) {
            browser.setVisible(visible);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.forms.IFormPart#setFocus()
     */
    public void setFocus() {
        if (browser != null)
            browser.setFocus();
    }

    public void showURL(String url) {
        if (browser != null && url != null) {
            browser.setUrl(url);
        }
    }

    public void clearBrowser() {
        if (browser != null) {
            browser.setText(EMPTY_PAGE);
        }
    }

    public void stop() {
        if (browser != null && !browser.isDisposed()) {
            browser.stop();
        }
    }

    private void doPrint() {
        browser.execute("window.print();"); //$NON-NLS-1$
    }

    private void doSyncToc() {
        String href = BaseHelpSystem.unresolve(this.url);
        int ix = href.indexOf("?resultof="); //$NON-NLS-1$
        if (ix >= 0) {
            href = href.substring(0, ix);
        }
        parent.showPage(IHelpUIConstants.HV_ALL_TOPICS_PAGE);
        AllTopicsPart part = (AllTopicsPart) parent.findPart(IHelpUIConstants.HV_TOPIC_TREE);
        if (part != null) {
            part.selectReveal(href);
        }
    }

    private void updateSyncTocAction() {
        String href = BaseHelpSystem.unresolve(this.url);
        syncTocAction.setEnabled(parent.isHelpResource(href));
    }

    private boolean redirectLink(final String url) {
        if (url.indexOf("/topic/") != -1) { //$NON-NLS-1$
            if (url.indexOf("noframes") == -1) { //$NON-NLS-1$
                return true;
            }
        } else if (url.indexOf("livehelp/?pluginID=") > 0) { //$NON-NLS-1$
            processLiveAction(url);
            return true;
        } else if (url.indexOf("helpview:") == 0) { //$NON-NLS-1$
            HelpviewProtocol.handleProtocolCall(url, parent);
            return true;
        }
        return false;
    }

    private void processLiveAction(String url) {
        if (!Platform.getPreferencesService().getBoolean(HelpBasePlugin.PLUGIN_ID, "activeHelp", false, null)) { //$NON-NLS-1$
            return;
        }

        String query = null;
        try {
            URL u = new URL(url);
            query = u.getQuery();
        } catch (MalformedURLException mue) {
        }
        if (query == null)
            return;
        StringTokenizer st = new StringTokenizer(query, "=&"); //$NON-NLS-1$
        if (st.countTokens() < 6) {
            return;
        }
        st.nextToken();
        String pluginId = URLCoder.decode(st.nextToken());
        st.nextToken();
        String className = URLCoder.decode(st.nextToken());
        st.nextToken();
        String arg = URLCoder.decode(st.nextToken());
        if (pluginId == null || className == null || arg == null)
            return;
        BaseHelpSystem.runLiveHelp(pluginId, className, arg);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.help.ui.internal.views.IHelpPart#fillContextMenu(org.eclipse.jface.action.IMenuManager)
     */

    public boolean fillContextMenu(IMenuManager manager) {
        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.help.ui.internal.views.IHelpPart#hasFocusControl(org.eclipse.swt.widgets.Control)
     */
    public boolean hasFocusControl(Control control) {
        return browser.equals(control);
    }

    public IAction getGlobalAction(String id) {
        if (id.equals(ActionFactory.PRINT.getId()))
            return printAction;
        return null;
    }

    private void enableButtons() {
        if (magnifyAction != null) {
            magnifyAction.setEnabled(fontScalePercentage < SCALE_MAX);
            reduceAction.setEnabled(fontScalePercentage > SCALE_MIN);
        }
    }

    private void doMagnify(int percent) {
        fontScalePercentage += percent;
        IScopeContext instanceScope = InstanceScope.INSTANCE;
        IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID);
        prefs.putInt(HELP_VIEW_SCALE, fontScalePercentage);
        try {
            prefs.flush();
        } catch (BackingStoreException e) {
        }
        rescale();
    }

    public void rescale() {
        browser.execute(FontUtils.getRescaleScript(fontScalePercentage));
        enableButtons();
    }

    public void toggleRoleFilter() {
    }

    public void refilter() {
        showURL(this.url);
    }

    public void saveState(IMemento memento) {
        if (url != null) {
            String href = BaseHelpSystem.unresolve(url);
            memento.putString("BrowserPart.url", href); //$NON-NLS-1$
        }
    }
}