/* * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed * under the Eclipse Public License (EPL), which is available at * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: XMind Ltd. - initial API and implementation */ package org.xmind.ui.internal.browser; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.SWTException; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.CloseWindowListener; 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.TitleEvent; import org.eclipse.swt.browser.TitleListener; import org.eclipse.swt.browser.VisibilityWindowListener; import org.eclipse.swt.browser.WindowEvent; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.PartInitException; import org.xmind.ui.animation.AnimationViewer; import org.xmind.ui.animation.IAnimationContentProvider; import org.xmind.ui.browser.BrowserSupport; import org.xmind.ui.browser.IBrowser; import org.xmind.ui.browser.IBrowserSupport; import org.xmind.ui.browser.IBrowserViewer; import org.xmind.ui.browser.IBrowserViewerContainer; import org.xmind.ui.browser.IBrowserViewerContribution; import org.xmind.ui.browser.IBrowserViewerContribution2; import org.xmind.ui.browser.IPropertyChangingListener; import org.xmind.ui.browser.PropertyChangingEvent; import org.xmind.ui.viewers.ImageCachedLabelProvider; /** * A viewer implementing a web browser. It provides an embeded SWT Browser * widget with an optional toolbar consisting of a URL combo box, back & forward * buttons, a refresh button and a home logo. */ public class BrowserViewer implements IBrowserViewer { private static Object DEFAULT_BUSY_PICTURES = null; private static class BusyIndicatorContentProvider extends ArrayContentProvider implements IAnimationContentProvider { public long getDuration(Object element) { return SWT.DEFAULT; // use default duration } public Object getStaticElement(Object inputElement, Object[] elements) { return elements[0]; } } private static class BusyIndicatorLabelProvider extends ImageCachedLabelProvider { protected Image createImage(Object element) { if (element instanceof ImageDescriptor) { ImageDescriptor desc = (ImageDescriptor) element; return desc.createImage(false); } return null; } } private class OpenInExternalAction extends Action { public OpenInExternalAction() { super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); setToolTipText( BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); } public void run() { IBrowser browser = BrowserSupport.getInstance() .createBrowser(IBrowserSupport.AS_EXTERNAL); try { browser.openURL(getURL()); } catch (PartInitException e) { BrowserPlugin.log(e); } } } private class BackAction extends Action { public BackAction() { super(BrowserMessages.BrowserViewer_PrevPage_toolTip, BrowserImages .getImageDescriptor(BrowserImages.BACKWARD, true)); setToolTipText(BrowserMessages.BrowserViewer_PrevPage_toolTip); setDisabledImageDescriptor(BrowserImages .getImageDescriptor(BrowserImages.BACKWARD, false)); } public void run() { back(); } } private class ForwardAction extends Action { public ForwardAction() { super(BrowserMessages.BrowserViewer_NextPage_toolTip, BrowserImages .getImageDescriptor(BrowserImages.FORWARD, true)); setToolTipText(BrowserMessages.BrowserViewer_NextPage_toolTip); setDisabledImageDescriptor(BrowserImages .getImageDescriptor(BrowserImages.FORWARD, false)); } public void run() { forward(); } } private class StopRefreshAction extends Action { private boolean stop = false; public StopRefreshAction() { setRefresh(); } public void setStop() { stop = true; setText(BrowserMessages.BrowserViewer_Stop_toolTip); setToolTipText(BrowserMessages.BrowserViewer_Stop_toolTip); setImageDescriptor( BrowserImages.getImageDescriptor(BrowserImages.STOP, true)); setDisabledImageDescriptor(BrowserImages .getImageDescriptor(BrowserImages.STOP, false)); } public void setRefresh() { stop = false; setText(BrowserMessages.BrowserViewer_Refresh_toolTip); setToolTipText(BrowserMessages.BrowserViewer_Refresh_toolTip); setImageDescriptor(BrowserImages .getImageDescriptor(BrowserImages.REFRESH, true)); setDisabledImageDescriptor(BrowserImages .getImageDescriptor(BrowserImages.REFRESH, false)); } public void run() { if (stop) { stop(); } else { refresh(); } } } protected class BrowserListener implements LocationListener, OpenWindowListener, VisibilityWindowListener, CloseWindowListener, ProgressListener, TitleListener, StatusTextListener { private String locationText; private String titleText; private String statusText; public void hook(Browser browser) { browser.addLocationListener(this); browser.addOpenWindowListener(this); browser.addVisibilityWindowListener(this); browser.addCloseWindowListener(this); browser.addProgressListener(this); browser.addTitleListener(this); browser.addStatusTextListener(this); } public void unhook(Browser browser) { browser.removeLocationListener(this); browser.removeOpenWindowListener(this); browser.removeVisibilityWindowListener(this); browser.removeCloseWindowListener(this); browser.removeProgressListener(this); browser.removeTitleListener(this); browser.removeStatusTextListener(this); } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.LocationListener#changed(org.eclipse.swt. * browser.LocationEvent) */ public void changed(LocationEvent event) { if (getControl() == null || getControl().isDisposed()) return; if (!event.top) return; if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ String oldLocation = locationText; locationText = event.location; if (location != null) { location.setText(event.location); } addToHistory(event.location); updateHistory(); firePropertyChangeEvent(PROPERTY_LOCATION, oldLocation, event.location); } } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.LocationListener#changing(org.eclipse.swt * .browser.LocationEvent) */ public void changing(LocationEvent event) { if (getControl() == null || getControl().isDisposed()) return; if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ event.doit = firePropertyChangingEvent(PROPERTY_LOCATION, locationText, event.location, event.doit); if (event.doit && redirect) { event.location = makeRedirectUrl(event.location); } } } /* * (non-Javadoc) * * @see org.eclipse.swt.browser.OpenWindowListener#open(org.eclipse.swt. * browser .WindowEvent) */ public void open(WindowEvent event) { if (getControl() == null || getControl().isDisposed()) return; if (container != null) { event.browser = container.openNewBrowser(); } } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.VisibilityWindowListener#hide(org.eclipse * .swt.browser.WindowEvent) */ public void hide(WindowEvent event) { // do nothing } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.VisibilityWindowListener#show(org.eclipse * .swt.browser.WindowEvent) */ public void show(WindowEvent event) { // if (event.widget == browser) { // if (composite.getParent() instanceof Shell) { // Shell shell = (Shell) composite.getParent(); // if (event.location != null) // shell.setLocation(event.location); // if (event.size != null) // shell.setSize(shell.computeSize(event.size.x, // event.size.y)); // shell.open(); // } // } } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.CloseWindowListener#close(org.eclipse.swt * .browser.WindowEvent) */ public void close(WindowEvent event) { if (getControl() == null || getControl().isDisposed()) return; if (container != null) { container.close(); } } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.ProgressListener#changed(org.eclipse.swt. * browser.ProgressEvent) */ public void changed(ProgressEvent event) { if (getControl() == null || getControl().isDisposed()) return; if (event.total == 0) return; boolean done = (event.current == event.total); int percentProgress = event.current * 100 / event.total; if (container != null) { IProgressMonitor monitor = container.getActionBars() .getStatusLineManager().getProgressMonitor(); if (done) { monitor.done(); progressWorked = 0; } else if (progressWorked == 0) { monitor.beginTask("", event.total); //$NON-NLS-1$ progressWorked = percentProgress; } else { monitor.worked(event.current - progressWorked); progressWorked = event.current; } } if (homeBusy != null) { if (!homeBusy.isAnimating() && !done) setLoading(true); else if (homeBusy.isAnimating() && done) // once the progress hits // 100 percent, done, set // busy to false setLoading(false); } updateBackNextBusy(); updateHistory(); } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.ProgressListener#completed(org.eclipse.swt * .browser.ProgressEvent) */ public void completed(ProgressEvent event) { if (getControl() == null || getControl().isDisposed()) return; if (container != null) { IProgressMonitor monitor = container.getActionBars() .getStatusLineManager().getProgressMonitor(); monitor.done(); } setLoading(false); updateBackNextBusy(); updateHistory(); } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.TitleListener#changed(org.eclipse.swt.browser * .TitleEvent) */ public void changed(TitleEvent event) { if (getControl() == null || getControl().isDisposed()) return; String oldTitle = titleText; titleText = event.title; firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, titleText); } /* * (non-Javadoc) * * @see * org.eclipse.swt.browser.StatusTextListener#changed(org.eclipse.swt * .browser.StatusTextEvent) */ public void changed(StatusTextEvent event) { if (getControl() == null || getControl().isDisposed()) return; boolean doit = true; String oldStatus = statusText; if (!firePropertyChangingEvent(PROPERTY_STATUS, oldStatus, event.text, doit)) { event.text = ""; //$NON-NLS-1$ } if (container != null) { IStatusLineManager status = container.getActionBars() .getStatusLineManager(); status.setMessage(event.text); } statusText = event.text; firePropertyChangeEvent(PROPERTY_STATUS, oldStatus, statusText); } } private static final int MAX_HISTORY = 50; private static final String URL_HOME = "http://www.xmind.net"; //$NON-NLS-1$ private static List<String> URL_HISTORY; private Composite composite; private boolean mozilla; private Clipboard clipboard; private Composite toolBar; private ToolBarManager actionBar; private Combo location; private AnimationViewer homeBusy; private boolean loading; private Composite browserContainer; private Browser browser; // private Browser alternateBrowser; private BrowserListener browserListener; private BrowserErrorText errorText; // private boolean newWindow; private IBrowserViewerContainer container; private int progressWorked = 0; private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( this); private BackAction backAction; private ForwardAction forwardAction; private StopRefreshAction stopRefreshAction; private boolean redirect = true; private int style = 0; private Label description; public BrowserViewer(Composite parent, int style) { this(parent, style, null); } public BrowserViewer(Composite parent, int style, IBrowserViewerContainer container) { this.style = style; this.container = container; this.composite = new Composite(parent, style); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; layout.horizontalSpacing = 0; layout.verticalSpacing = 0; layout.numColumns = 1; this.composite.setLayout(layout); this.composite .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); createContents(this.composite); hookControl(this.composite); } public int getStyle() { return style; } Label getDescriptionLabel() { return description; } protected void hookControl(Control control) { control.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { handleDispose(); } }); for (IBrowserViewerContribution contribution : BrowserContributionManager .getInstance().getContributions()) { if (contribution instanceof IBrowserViewerContribution2) { ((IBrowserViewerContribution2) contribution) .installBrowserListeners(this); } } } protected void createContents(Composite parent) { clipboard = new Clipboard(parent.getDisplay()); createToolBar(parent); createBrowser(parent); updateWithStyle(); updateHistory(); updateBackNextBusy(); // if (browserContainer != null) { // } else { // errorText.getControl().setLayoutData( // new GridData(SWT.FILL, SWT.FILL, true, true)); // } // addBrowserListeners(browser); } protected void createToolBar(Composite parent) { toolBar = new Composite(parent, SWT.NONE); GridLayout toolbarLayout = new GridLayout(); toolbarLayout.marginHeight = 2; toolbarLayout.marginWidth = 2; toolbarLayout.horizontalSpacing = 5; toolbarLayout.verticalSpacing = 0; toolBar.setLayout(toolbarLayout); toolBar.setLayoutData( new GridData(SWT.FILL, SWT.BEGINNING, true, false)); createActionBar(toolBar); createLocationBar(toolBar); //forbid extra contributions, such as SearchBoxContribution //if accept in the future, we can delete browserViewerContributions extension about search box. // createExtraContributions(toolBar); createHomeBusyIndicator(toolBar); toolbarLayout.numColumns = toolBar.getChildren().length; } // private void createExtraContributions(final Composite toolbarContainer) { // ContributionManager manager = new ContributionManager() { // public void update(boolean force) { // if ((style & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) == 0) { // for (IContributionItem item : getItems()) { // item.fill(toolbarContainer); // } // } // } // }; // for (IBrowserViewerContribution contribution : BrowserContributionManager // .getInstance().getContributions()) { // contribution.fillToolBar(this, manager); // } // manager.update(true); // } private void createActionBar(Composite parent) { actionBar = new ToolBarManager(SWT.FLAT); actionBar.add(new OpenInExternalAction()); actionBar.add(backAction = new BackAction()); actionBar.add(forwardAction = new ForwardAction()); actionBar.add(stopRefreshAction = new StopRefreshAction()); actionBar.createControl(parent); actionBar.getControl().setLayoutData( new GridData(SWT.FILL, SWT.CENTER, false, false)); } private void createLocationBar(Composite parent) { location = new Combo(parent, SWT.BORDER | SWT.DROP_DOWN); location.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); description = new Label(parent, SWT.NONE); description.setText(""); //$NON-NLS-1$ description .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); updateHistory(); /* * We ignore selection event to avoid unneccessary selection (e.g. mouse * scrolling in the combo, arrow up/down, or even showing drop-down on * some platforms). User must press Enter whenver they have selected an * item in order to go to that URL. */ // location.addSelectionListener(new SelectionAdapter() { // @Override // public void widgetSelected(SelectionEvent we) { // try { // if (location.getSelectionIndex() != -1) // setURL(location.getItem(location.getSelectionIndex())); // } catch (Exception ignore) { // } // } // }); location.addListener(SWT.FocusIn, new Listener() { public void handleEvent(Event event) { int end = location.getText().length(); location.setSelection(new Point(0, end)); } }); location.addListener(SWT.DefaultSelection, new Listener() { public void handleEvent(Event e) { setURL(location.getText()); } }); } protected void createHomeBusyIndicator(Composite parenet) { homeBusy = new AnimationViewer(parenet, SWT.NONE); homeBusy.setContentProvider(new BusyIndicatorContentProvider()); homeBusy.setLabelProvider(new BusyIndicatorLabelProvider()); homeBusy.setInput(getDefaultBusyPictures()); homeBusy.getControl() .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); homeBusy.getControl().addListener(SWT.MouseDown, new Listener() { public void handleEvent(Event event) { setURL(URL_HOME); } }); } public AnimationViewer getBusyIndicator() { return homeBusy; } protected void createBrowser(Composite parent) { browserContainer = new Composite(parent, SWT.NONE); browserContainer.setLayout(new StackLayout()); browserContainer .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Browser b = null; // try { // // try Mozilla // b = createBrowser(browserContainer, SWT.MOZILLA | SWT.BORDER); // mozilla = true; // } catch (SWTError e) { // mozilla = false; try { // try default browser b = createBrowser(browserContainer, SWT.NONE); } catch (SWTError e2) { if (e2.code != SWT.ERROR_NO_HANDLES) { return; } // show error text errorText = new BrowserErrorText(browserContainer, this, e2); } // } if (b != null) { this.browser = b; } mozilla = b != null && "mozilla".equals(b.getBrowserType()); //$NON-NLS-1$ if (mozilla) new MozillaPref(this); browserListener = new BrowserListener(); if (browser != null) { browserListener.hook(browser); show(browser); } else { show(errorText.getControl()); } } private void show(Control control) { ((StackLayout) browserContainer.getLayout()).topControl = control; for (Control c : browserContainer.getChildren()) { c.setVisible(c == control); } browserContainer.layout(); } // private void changeBrowser() { // if (errorText != null) // return; // // ensureAlternateBrowser(); // if (alternateBrowser == null || alternateBrowser.isDisposed()) // return; // // browserListener.unhook(browser); // // Browser temp = alternateBrowser; // alternateBrowser = browser; // browser = temp; // // browserListener.hook(browser); // show(browser); // } // // private void ensureAlternateBrowser() { // if (alternateBrowser != null && !alternateBrowser.isDisposed()) // return; // // if (errorText != null) // return; // // try { // if (mozilla) { // alternateBrowser = new Browser(browserContainer, SWT.MOZILLA // | SWT.BORDER); // } else { // alternateBrowser = new Browser(browserContainer, SWT.NONE); // } // // } catch (SWTError e) { // if (e.code != SWT.ERROR_NO_HANDLES) { // return; // } // errorText = new BrowserErrorText(browserContainer, this, e); // } // // if (alternateBrowser != null) { // alternateBrowser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, // true, true)); // } else { // errorText.getControl().setLayoutData( // new GridData(SWT.FILL, SWT.FILL, true, true)); // } // } private Browser createBrowser(Composite parent, int style) { return new Browser(parent, style); } public void changeStyle(int newStyle) { this.style = newStyle; if (composite != null && !composite.isDisposed()) { updateWithStyle(); } } protected void updateWithStyle() { boolean locationVisible = (style & IBrowserSupport.NO_LOCATION_BAR) == 0; location.setVisible(locationVisible); ((GridData) location.getLayoutData()).exclude = !locationVisible; boolean descriptionVisible = !locationVisible; description.setVisible(descriptionVisible); ((GridData) description.getLayoutData()).exclude = !descriptionVisible; toolBar.layout(true); boolean hasToolBar = (style & IBrowserSupport.NO_TOOLBAR) == 0; toolBar.setVisible(hasToolBar); ((GridData) toolBar.getLayoutData()).exclude = !hasToolBar; composite.layout(true); } public Browser getBrowser() { return browser; } public Control getControl() { return composite; } private void home() { if (browser == null || browser.isDisposed()) return; browser.setText(""); //$NON-NLS-1$ } /** * Loads a URL. * * @param url * the URL to be loaded * @return true if the operation was successful and false otherwise. * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT - if the url is null</li> * </ul> * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong * thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been * disposed</li> * </ul> * @see #getURL() */ public boolean setURL(String url) { return setURL(url, true); } private boolean setURL(String url, boolean browse) { if (url == null) { home(); return true; } if ("xmind".equalsIgnoreCase(url)) //$NON-NLS-1$ url = URL_HOME; if (redirect) { url = makeRedirectUrl(url); } if (browse) navigate(url); addToHistory(url); updateHistory(); return true; } protected void updateBackNextBusy() { if (backAction != null) backAction.setEnabled(isBackEnabled()); if (forwardAction != null) forwardAction.setEnabled(isForwardEnabled()); if (homeBusy != null && homeBusy.getControl() != null && !homeBusy.getControl().isDisposed()) { if (loading) { homeBusy.start(); } else { homeBusy.stop(); } } } // /** // * // */ // private void addBrowserListeners(Browser browser) { // if (browser == null) // return; // // browser.addStatusTextListener(new StatusTextListener() { // public void changed(StatusTextEvent event) { // if (container != null) { // IStatusLineManager status = container.getActionBars() // .getStatusLineManager(); // status.setMessage(event.text); // } // } // }); // // /* // * Add listener for new window creation. Use just the same browser for // * the new window. // */ // browser.addOpenWindowListener(new OpenWindowListener() { // public void open(WindowEvent event) { // event.browser = BrowserViewer.this.browser; // // // Forget about the following way.... // //// Display display = Display.getCurrent(); //// final Shell tempShell = new Shell(display); //// tempShell.setBounds(-100, -100, 50, 50); //// tempShell.setLayout(new FillLayout()); //// BrowserViewer tempBrowserViewer = new BrowserViewer(tempShell, //// 0, null); //// tempBrowserViewer.newWindow = true; //// Browser tempBrowser = tempBrowserViewer.browser; //// tempBrowser.addLocationListener(new LocationListener() { //// //// public void changing(LocationEvent event) { //// } //// //// public void changed(LocationEvent event) { //// String url = event.location; //// if (container != null && url != null && !"".equals(url)) { //$NON-NLS-1$ //// container.openInExternalBrowser(url); //// } //// tempShell.close(); //// tempShell.dispose(); //// } //// //// }); //// event.browser = tempBrowser; // } // }); // // browser.addVisibilityWindowListener(new VisibilityWindowListener() { // public void hide(WindowEvent e) { // } // // public void show(WindowEvent e) { // Browser browser2 = (Browser) e.widget; // if (browser2.getParent().getParent() instanceof Shell) { // Shell shell = (Shell) browser2.getParent().getParent(); // if (e.location != null) // shell.setLocation(e.location); // if (e.size != null) // shell.setSize(shell.computeSize(e.size.x, e.size.y)); // shell.open(); // } // } // }); // // browser.addCloseWindowListener(new CloseWindowListener() { // public void close(WindowEvent event) { // // if shell is not null, it must be a secondary popup window, // // else its an editor window //// if (newWindow) { //// getControl().getShell().dispose(); //// } else { //// container.close(); //// } // } // }); // // browser.addProgressListener(new ProgressListener() { // public void changed(ProgressEvent event) { // if (event.total == 0) // return; // // boolean done = (event.current == event.total); // // int percentProgress = event.current * 100 / event.total; // if (container != null) { // IProgressMonitor monitor = container.getActionBars() // .getStatusLineManager().getProgressMonitor(); // if (done) { // monitor.done(); // progressWorked = 0; // } else if (progressWorked == 0) { // monitor.beginTask("", event.total); //$NON-NLS-1$ // progressWorked = percentProgress; // } else { // monitor.worked(event.current - progressWorked); // progressWorked = event.current; // } // } // // if (!homeBusy.isAnimating() && !done) // setLoading(true); // else if (homeBusy.isAnimating() && done) // once the progress hits // // 100 percent, done, set // // busy to false // setLoading(false); // // updateBackNextBusy(); // updateHistory(); // } // // public void completed(ProgressEvent event) { // if (container != null) { // IProgressMonitor monitor = container.getActionBars() // .getStatusLineManager().getProgressMonitor(); // monitor.done(); // } // setLoading(false); // updateBackNextBusy(); // updateHistory(); // } // }); // // browser.addLocationListener(new LocationListener() { // public void changed(LocationEvent event) { // if (!event.top) // return; // if (location != null) { // if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ // String oldLocation = location.getText(); // location.setText(event.location); // addToHistory(event.location); // updateHistory(); // firePropertyChangeEvent(PROPERTY_LOCATION, // event.location, oldLocation); // } // } // } // // public void changing(LocationEvent event) { // // do nothing // } // }); // // browser.addTitleListener(new TitleListener() { // public void changed(TitleEvent event) { // String oldTitle = title; // title = event.title; // firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, title); // } // }); // // } public Combo getLocationBar() { return location; } public Clipboard getClipboard() { return clipboard; } public void copy() { if (location == null || location.isDisposed() || !location.isFocusControl()) return; location.copy(); } public void cut() { if (location == null || location.isDisposed() || !location.isFocusControl()) return; location.cut(); } public void delete() { if (location == null || location.isDisposed() || !location.isFocusControl()) return; String text = location.getText(); Point selection = location.getSelection(); if (selection.y > selection.x) { text = text.substring(0, selection.x) + text.substring(selection.y); location.setText(text); location.setSelection(new Point(selection.x, selection.x)); } } public void paste() { if (location == null || location.isDisposed() || !location.isFocusControl()) return; location.paste(); } public void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(propertyName, listener); } protected void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) { propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); } protected boolean firePropertyChangingEvent(String propertyName, Object oldValue, Object newValue, boolean doit) { PropertyChangingEvent event = new PropertyChangingEvent(this, propertyName, oldValue, newValue, doit); PropertyChangeListener[] listeners = propertyChangeSupport .getPropertyChangeListeners(); if (firePropertyChangingEvent(listeners, event)) { listeners = propertyChangeSupport .getPropertyChangeListeners(propertyName); return firePropertyChangingEvent(listeners, event); } return event.doit; } private boolean firePropertyChangingEvent( PropertyChangeListener[] listeners, PropertyChangingEvent event) { for (Object pcl : listeners) { if (pcl instanceof IPropertyChangingListener) { try { ((IPropertyChangingListener) pcl).propertyChanging(event); } catch (Throwable ignore) { } } } return event.doit; } /** * Navigate to the next session history item. Convenience method that calls * the underlying SWT browser. * * @return <code>true</code> if the operation was successful and * <code>false</code> otherwise * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong * thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been * disposed</li> * </ul> */ public boolean forward() { if (browser == null || browser.isDisposed()) return false; boolean forward = browser.forward(); if (!forward) { } return forward; } /** * Navigate to the previous session history item. Convenience method that * calls the underlying SWT browser. * * @return <code>true</code> if the operation was successful and * <code>false</code> otherwise * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong * thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been * disposed</li> * </ul> */ public boolean back() { if (browser == null || browser.isDisposed()) return false; return browser.back(); } /** * Returns <code>true</code> if the receiver can navigate to the previous * session history item, and <code>false</code> otherwise. Convenience * method that calls the underlying SWT browser. * * @return the receiver's back command enabled state * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public boolean isBackEnabled() { if (browser == null || browser.isDisposed()) return false; return browser.isBackEnabled(); } /** * Returns <code>true</code> if the receiver can navigate to the next * session history item, and <code>false</code> otherwise. Convenience * method that calls the underlying SWT browser. * * @return the receiver's forward command enabled state * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public boolean isForwardEnabled() { if (browser == null || browser.isDisposed()) return false; return browser.isForwardEnabled(); } /** * Stop any loading and rendering activity. Convenience method that calls * the underlying SWT browser. * * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong * thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been * disposed</li> * </ul> */ public void stop() { if (browser != null && !browser.isDisposed()) browser.stop(); setLoading(false); } public boolean setText(String html) { return false; } private boolean navigate(String url) { if (url != null && url.equals(getURL())) { refresh(); return true; } if (browser != null && !browser.isDisposed()) return browser.setUrl(url); if (errorText != null && errorText.getControl() != null && !errorText.getControl().isDisposed()) return errorText.setUrl(url); return false; } /** * Refresh the current page. Convenience method that calls the underlying * SWT browser. * * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong * thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been * disposed</li> * </ul> */ public void refresh() { if (browser != null) { if (!browser.isDisposed()) browser.refresh(); } else { if (errorText != null && errorText.getControl() != null && !errorText.getControl().isDisposed()) errorText.refresh(); } try { Thread.sleep(50); } catch (Exception ignore) { } } protected void addToHistory(String url) { if (URL_HISTORY == null) URL_HISTORY = BrowserPref.getInternalWebBrowserHistory(); int found = -1; int size = URL_HISTORY.size(); for (int i = 0; i < size; i++) { String s = URL_HISTORY.get(i); if (s.equals(url)) { found = i; break; } } if (found == -1) { if (size >= MAX_HISTORY) URL_HISTORY.remove(size - 1); URL_HISTORY.add(0, url); BrowserPref.setInternalWebBrowserHistory(URL_HISTORY); } else if (found != 0) { URL_HISTORY.remove(found); URL_HISTORY.add(0, url); BrowserPref.setInternalWebBrowserHistory(URL_HISTORY); } } protected void handleDispose() { for (IBrowserViewerContribution contribution : BrowserContributionManager .getInstance().getContributions()) { if (contribution instanceof IBrowserViewerContribution2) { ((IBrowserViewerContribution2) contribution) .uninstallBrowserListeners(this); } } if (this.container != null) { IStatusLineManager manager = this.container.getActionBars() .getStatusLineManager(); if (manager != null) manager.getProgressMonitor().done(); } homeBusy = null; browser = null; errorText = null; if (clipboard != null) clipboard.dispose(); clipboard = null; } private void setLoading(boolean loading) { this.loading = loading; if (loading) { if (stopRefreshAction != null) { stopRefreshAction.setStop(); } } else { if (stopRefreshAction != null) { stopRefreshAction.setRefresh(); } if (homeBusy != null && homeBusy.getControl() != null && !homeBusy.getControl().isDisposed()) homeBusy.stop(); if (container != null) { IProgressMonitor monitor = container.getActionBars() .getStatusLineManager().getProgressMonitor(); monitor.done(); } } } /** * Returns the current URL. Convenience method that calls the underlying SWT * browser. * * @return the current URL or an empty <code>String</code> if there is no * current URL * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong * thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been * disposed</li> * </ul> * @see #setURL(String) */ public String getURL() { if (browser != null) return browser.getUrl(); return errorText.getUrl(); } protected void updateHistory() { if (location == null || location.isDisposed()) return; String temp = location.getText(); if (URL_HISTORY == null) URL_HISTORY = BrowserPref.getInternalWebBrowserHistory(); String[] historyList = new String[URL_HISTORY.size()]; URL_HISTORY.toArray(historyList); location.setItems(historyList); location.setText(temp); } public IBrowserViewerContainer getContainer() { return container; } public void setFocus() { if (browser != null && !browser.isDisposed()) { if (browser.setFocus()) { updateHistory(); } else if (location != null) { location.setFocus(); } } } /** * @return the mozilla */ public boolean isMozilla() { return mozilla; } public BackAction getBackAction() { return backAction; } public ForwardAction getForwardAction() { return forwardAction; } public StopRefreshAction getStopRefreshAction() { return stopRefreshAction; } private static Object getDefaultBusyPictures() { if (DEFAULT_BUSY_PICTURES == null) { ArrayList<ImageDescriptor> list = new ArrayList<ImageDescriptor>( 13); list.add(BrowserImages.getImageDescriptor(BrowserImages.XMIND)); list.addAll(Arrays.asList(BrowserImages.getBusyImages())); DEFAULT_BUSY_PICTURES = list.toArray(); } return DEFAULT_BUSY_PICTURES; } private String makeRedirectUrl(String source) { if (!source.startsWith("file:")) { //$NON-NLS-1$ try { return BrowserUtil.makeRedirectURL(source); } catch (Throwable e) { //ignore } finally { redirect = false; } } return source; } }