net.refractions.udig.browser.ui.BrowserContainerView.java Source code

Java tutorial

Introduction

Here is the source code for net.refractions.udig.browser.ui.BrowserContainerView.java

Source

/* uDig - User Friendly Desktop Internet GIS client
 * http://udig.refractions.net
 * (C) 2004, Refractions Research Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package net.refractions.udig.browser.ui;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Pattern;

import net.refractions.udig.browser.BrowserPlugin;
import net.refractions.udig.browser.internal.Messages;
import net.refractions.udig.catalog.ui.FileConnectionFactory;
import net.refractions.udig.internal.ui.UDIGDropHandler;
import net.refractions.udig.project.ui.ApplicationGIS;
import net.refractions.udig.project.ui.internal.ApplicationGISInternal;
import net.refractions.udig.project.ui.internal.MapEditor;
import net.refractions.udig.project.ui.internal.MapEditorPart;
import net.refractions.udig.project.ui.internal.MapEditorWithPalette;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
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.TitleEvent;
import org.eclipse.swt.browser.TitleListener;
import org.eclipse.swt.browser.VisibilityWindowListener;
import org.eclipse.swt.browser.WindowEvent;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Adapter;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

/**
 * Provides a tabbed browser view using the native web browser. 
 * <p>
 *
 * </p>
 * @author mleslie
 * @since 1.0.0
 */
public class BrowserContainerView extends ViewPart {
    /** BrowserContainerView ID field */
    public final static String VIEW_ID = "net.refractions.udig.browser.ui.browserContainerView"; //$NON-NLS-1$
    private static String BROWSER_TYPE = "net.refractions.udig.browser.TYPE"; //$NON-NLS-1$
    private static String BROWSER_NAME = "BROWSER_NAME"; //$NON-NLS-1$
    private static String BROWSER_URL = "BROWSER_URL"; //$NON-NLS-1$
    private static String BROWSER_LISTENER = "BROWSER_LISTENER"; //$NON-NLS-1$
    private static String BROWSER_ALERT_URL = "BROWSER_ALERT_URL"; //$NON-NLS-1$

    /** BrowserContainerView tabFolder field */
    private CTabFolder tabFolder;
    private static int count = 1;
    private LocationListener locListen;
    private URL lastAlertURL;

    // next time use policy bind less code!
    private String forwardIconEnabled = "icons/elcl16/forward_nav.gif"; //$NON-NLS-1$
    private String forwardIconDisabled = "icons/dlcl16/forward_nav.gif"; //$NON-NLS-1$
    private String backwardIconEnabled = "icons/elcl16/backward_nav.gif"; //$NON-NLS-1$
    private String backwardIconDisabled = "icons/dlcl16/backward_nav.gif"; //$NON-NLS-1$    
    private String refreshIconEnabled = "icons/elcl16/refresh_co.gif"; //$NON-NLS-1$

    private IAction forward;
    private IAction backward;
    private ChangeListener changeListener;

    private Map<Browser, CTabItem> tabMap = new HashMap<Browser, CTabItem>();
    private Map<Browser, String> listenerMap = new HashMap<Browser, String>();
    private List<BrowserData> browserData;
    private LocationEntry locationEntry;

    private final class BrowserProgressListener implements ProgressListener {
        private final IProgressMonitor monitor;
        private CTabItem item;

        public BrowserProgressListener(final IProgressMonitor monitor, final CTabItem item, CTabFolder tabFolder) {
            this.monitor = monitor;
            this.item = item;
            tabFolder.addCTabFolder2Listener(new CTabFolder2Adapter() {
                @Override
                public void close(CTabFolderEvent event) {
                    if (event.item == item) {
                        monitor.done();
                    }
                }
            });

            item.addListener(SWT.Dispose, new Listener() {

                public void handleEvent(Event event) {
                    monitor.done();
                }

            });
        }

        int current = -1;
        Timer timer = new Timer();
        Timeout timeout = null;

        class Timeout extends TimerTask {

            @Override
            public void run() {
                Display.getDefault().asyncExec(new Runnable() {
                    public void run() {
                        monitor.done();
                    }

                });
            }

        };

        public void changed(ProgressEvent event) {
            if (timeout != null) {
                timeout.cancel();
            }
            timeout = new Timeout();
            timer.schedule(timeout, 20000);
            if (current > 0) {
                monitor.worked(Math.max(0, event.current - current));
                if (event.current >= event.total) {
                    completed(event);
                }
            } else {
                String msg = MessageFormat.format(Messages.BrowserContainerView_loadingMessage, item.getText());
                monitor.beginTask(msg, event.total);
                monitor.worked(event.current);
                current = event.current;
            }
        }

        public void completed(ProgressEvent event) {
            if (timeout != null) {
                timeout.cancel();
            }
            monitor.done();
            current = -1;
        }
    }

    private static class BrowserData {
        private String name;
        private String url;
        private String listener;

        BrowserData(String name1, String url1, String listener1) {
            this.name = name1;
            this.url = url1;
            this.listener = listener1;
        }

        BrowserData(IMemento m) {
            this(m.getString(BROWSER_NAME), m.getString(BROWSER_URL), m.getString(BROWSER_LISTENER));
        }

        /**
         *
         * @return page name
         */
        public String getName() {
            return this.name;
        }

        /**
         *
         * @return String
         */
        public String getUrl() {
            return this.url;
        }

        /**
         *
         * @return LocationListener, or null
         */
        public LocationListener getListener() {
            if (this.listener == null || this.listener.equals("DEFAULT")) //$NON-NLS-1$
                return null;
            try {
                return (LocationListener) Class.forName(this.listener).newInstance();
            } catch (InstantiationException e) {
                //
            } catch (IllegalAccessException e) {
                //
            } catch (ClassNotFoundException e) {
                //
            }
            return null;
        }
    }

    /**
     * 
     */
    public BrowserContainerView() {
        super();
    }

    @Override
    public void createPartControl(Composite parent) {
        FormLayout layout = new FormLayout();
        parent.setLayout(layout);

        locationEntry = new LocationEntry(this);
        Control control = locationEntry.createControl(parent);
        FormData data = new FormData();
        data.left = new FormAttachment(0, 0);
        data.right = new FormAttachment(100, 0);
        control.setLayoutData(data);

        this.tabFolder = new CTabFolder(parent, SWT.BORDER | SWT.TOP | SWT.CLOSE);
        this.tabFolder.addSelectionListener(getChangeListener());
        data = new FormData();
        data.left = new FormAttachment(0, 0);
        data.right = new FormAttachment(100, 0);
        data.top = new FormAttachment(control, 0);
        data.bottom = new FormAttachment(100, 0);
        tabFolder.setLayoutData(data);

        IViewSite site = getViewSite();
        IActionBars bars = site.getActionBars();
        IToolBarManager toolbarMgr = bars.getToolBarManager();
        toolbarMgr.add(getBackwardAction());
        toolbarMgr.add(getForwardAction());
        toolbarMgr.add(getRefreshAction());
        toolbarMgr.add(locationEntry.getButton());

        if (this.browserData != null) {
            for (BrowserData bd : this.browserData) {
                addTab(bd.getName(), bd.getUrl(), bd.getListener());
            }
            this.browserData = null;
        } else {
            addTab(Messages.BrowserContainerView_tabTitle, "http://udig.refractions.net/confluence/display/DATA", //$NON-NLS-1$
                    (Image) null, getListener());
        }
    }

    @Override
    public void setFocus() {
        this.tabFolder.getSelection().getControl().setFocus();
    }

    /**
     *
     * @return Action
     */
    public IAction getForwardAction() {
        if (this.forward == null) {
            this.forward = new Action() {
                public void run() {
                    CTabItem tab = tabFolder.getSelection();
                    if (tab == null)
                        return;
                    Control cont = tab.getControl();
                    if (cont instanceof Browser) {
                        ((Browser) cont).forward();
                    }
                }
            };
            this.forward.setEnabled(false);
            this.forward.setText(Messages.BrowserContainerView_forward_text);
            this.forward.setImageDescriptor(BrowserPlugin.getImageDescriptor(this.forwardIconEnabled));
            this.forward.setDisabledImageDescriptor(BrowserPlugin.getImageDescriptor(this.forwardIconDisabled));
            this.forward.setToolTipText(Messages.BrowserContainerView_forward_tooltip);
        }
        return this.forward;
    }

    /**
     *
     * @return Action
     */
    public IAction getBackwardAction() {
        if (this.backward == null) {
            this.backward = new Action() {
                public void run() {
                    CTabItem tab = tabFolder.getSelection();
                    if (tab == null)
                        return;
                    Control cont = tab.getControl();
                    if (cont instanceof Browser) {
                        ((Browser) cont).back();
                    }
                }

            };
            this.backward.setEnabled(false);
            this.backward.setText(Messages.BrowserContainerView_back_text);
            this.backward.setImageDescriptor(BrowserPlugin.getImageDescriptor(this.backwardIconEnabled));
            this.backward.setDisabledImageDescriptor(BrowserPlugin.getImageDescriptor(this.backwardIconDisabled));
            this.backward.setToolTipText(Messages.BrowserContainerView_back_tooltip);
        }
        return this.backward;
    }

    private IAction refresh;

    public IAction getRefreshAction() {
        if (this.refresh == null) {
            this.refresh = new Action() {
                public void run() {
                    CTabItem tab = tabFolder.getSelection();
                    if (tab == null)
                        return;
                    Control cont = tab.getControl();
                    if (cont instanceof Browser) {
                        ((Browser) cont).refresh();
                    }
                }
            };
            this.refresh.setEnabled(true);
            this.refresh.setText(Messages.BrowserContainerView_refresh);
            this.refresh.setImageDescriptor(BrowserPlugin.getImageDescriptor(this.refreshIconEnabled));
            this.refresh.setImageDescriptor(BrowserPlugin.getImageDescriptor(this.refreshIconEnabled));
            this.refresh.setToolTipText(Messages.BrowserContainerView_refresh);
        }
        return this.refresh;
    }

    public void setName(String name) {
        this.setPartName(name);
    }

    /**
     *
     * @return singleton LocationListener
     */
    public LocationListener getListener() {
        if (this.locListen == null) {
            this.locListen = new LocationListener() {
                public void changing(LocationEvent event) {
                    String url = event.location;
                    // Should be part of ServiceExtension extension point.
                    if (url.toLowerCase().indexOf("=getcapabilities") != -1 //$NON-NLS-1$
                            || url.toLowerCase().indexOf("jdbc:postgis://") != -1 //$NON-NLS-1$
                            || url.toLowerCase().indexOf("postgis:jdbc://") != -1 //$NON-NLS-1$
                            || recognizedFile(url)) {
                        event.doit = false;

                        UDIGDropHandler dropHandler = new UDIGDropHandler();
                        MapEditorPart editor = ApplicationGISInternal.getActiveEditor();
                        dropHandler.setTarget(editor);
                        dropHandler.performDrop(url, null);
                    }
                }

                private boolean recognizedFile(String url) {
                    if (url.toLowerCase().indexOf("file://") != -1) { //$NON-NLS-1$
                        return new FileConnectionFactory().canProcess(url);
                    }
                    final Pattern PATTERN = Pattern.compile("[^:/]+://?.+"); //$NON-NLS-1$
                    if (PATTERN.matcher(url).matches()) {
                        return new FileConnectionFactory().canProcess(url);
                    }
                    return false;
                }

                public void changed(LocationEvent event) {
                    //
                }
            };
        }
        return this.locListen;
    }

    /**
     *
     * @return change listener
     */
    public ChangeListener getChangeListener() {
        if (this.changeListener == null) {
            this.changeListener = new ChangeListener();
        }
        return changeListener;
    }

    /**
     *
     * @param name
     * @param url
     * @param listen 
     */
    public void addTab(String name, String url, LocationListener listen) {
        addTab(name, url, (Image) null, listen);
    }

    /**
     *
     * @param name
     * @param url
     * @param desc
     * @param listen 
     */
    public void addTab(String name, String url, ImageDescriptor desc, LocationListener listen) {
        if (desc != null)
            addTab(name, url, desc.createImage(), listen);
        else
            addTab(name, url, (Image) null, listen);
    }

    /**
     *
     * @param name
     * @param url
     * @param desc
     * @param listen 
     */
    public void addTab(String name, URL url, ImageDescriptor desc, LocationListener listen) {
        addTab(name, url.toString(), desc, listen);
    }

    /**
     *
     * @param name
     * @param url
     * @param image
     * @param listen 
     */
    public void addTab(String name, String url, Image image, LocationListener listen) {
        CTabItem item = new CTabItem(this.tabFolder, SWT.NONE);
        if (name != null) {
            item.setText(name);
        } else {
            item.setText(MessageFormat.format(Messages.BrowserContainerView_pageCount, new Object[] { count++ }));
        }
        Browser browser = createBrowser(item, listen);
        browser.setUrl(url);

        if (image != null)
            item.setImage(image);
        this.tabFolder.setSelection(item);
        this.tabFolder.layout();
    }

    /**
     *
     * @param url
     * @param listen 
     */
    public void addTab(URL url, LocationListener listen) {
        addTab(null, url, listen);
    }

    /**
     *
     * @param url
     * @param image
     * @param listen 
     */
    public void addTab(URL url, Image image, LocationListener listen) {
        addTab(null, url.toString(), image, listen);
    }

    /**
     *
     * @param name
     * @param url
     * @param listen 
     */
    public void addTab(String name, URL url, LocationListener listen) {
        addTab(name, url.toString(), listen);
    }

    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        if (memento != null) {
            IMemento[] array = memento.getChildren(BROWSER_TYPE);
            this.browserData = new ArrayList<BrowserData>(array.length);
            for (IMemento mem : array) {
                this.browserData.add(new BrowserData(mem));
            }
            String urlString = memento.getString(BROWSER_ALERT_URL);
            if (urlString != null) {
                try {
                    this.lastAlertURL = new URL(urlString);
                } catch (MalformedURLException ex) {
                    ;
                }
            }
        }
    }

    public void saveState(IMemento memento) {
        super.saveState(memento);
        if (this.lastAlertURL != null)
            memento.putString(BROWSER_ALERT_URL, this.lastAlertURL.toString());
        Control[] controls = this.tabFolder.getChildren();
        for (Control control : controls) {
            if (control instanceof Browser) {
                Browser browser = (Browser) control;
                if (!browser.isDisposed()) {
                    CTabItem item = this.tabMap.get(browser);
                    String listener = this.listenerMap.get(browser);
                    if (item != null && !item.isDisposed()) {
                        IMemento child = memento.createChild(BROWSER_TYPE);
                        child.putString(BROWSER_NAME, item.getText());
                        child.putString(BROWSER_URL, browser.getUrl());
                        child.putString(BROWSER_LISTENER, listener);
                    }
                }
            }
        }
    }

    private Browser createBrowser(CTabItem item, LocationListener listen) {
        Browser browser = new Browser(tabFolder, SWT.NONE);
        if (listen != null) {
            browser.addLocationListener(listen);
            listenerMap.put(browser, listen.getClass().getCanonicalName());
        } else {
            browser.addLocationListener(getListener());
            listenerMap.put(browser, "DEFAULT"); //$NON-NLS-1$
        }
        // needed to keep the forward/back buttons up to date
        browser.addLocationListener(getChangeListener());
        browser.addVisibilityWindowListener(getChangeListener());
        browser.addOpenWindowListener(getChangeListener());
        browser.addTitleListener(getChangeListener());
        item.setControl(browser);
        tabMap.put(browser, item);

        final IProgressMonitor monitor = getViewSite().getActionBars().getStatusLineManager().getProgressMonitor();

        browser.addProgressListener(new BrowserProgressListener(monitor, item, tabFolder));

        return browser;
    }

    public void addTab(String url, LocationListener listen) {
        addTab(null, url, listen);
    }

    private class ChangeListener implements LocationListener, VisibilityWindowListener, SelectionListener,
            OpenWindowListener, CloseWindowListener, TitleListener {

        public void changing(LocationEvent event) {
            locationEntry.setText(event.location);
            return;
        }

        public void changed(LocationEvent event) {
            setEnability();
        }

        public void hide(WindowEvent event) {
            setEnability();
        }

        public void show(WindowEvent event) {
            setEnability();
        }

        private void setEnability() {
            CTabItem tab = tabFolder.getSelection();
            if (tab == null) {
                getForwardAction().setEnabled(false);
                getBackwardAction().setEnabled(false);
                getRefreshAction().setEnabled(false);
            } else {
                Control cont = tab.getControl();
                if (cont instanceof Browser) {
                    getForwardAction().setEnabled(((Browser) cont).isForwardEnabled());
                    getBackwardAction().setEnabled(((Browser) cont).isBackEnabled());
                    getRefreshAction().setEnabled(true);
                }
            }
        }

        public void widgetSelected(SelectionEvent e) {
            setEnability();
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            setEnability();
        }

        public void open(WindowEvent event) {
            CTabItem item = new CTabItem(tabFolder, SWT.NONE);
            Browser browser = createBrowser(item, null);
            item.setText(MessageFormat.format(Messages.BrowserContainerView_pageCount, new Object[] { count++ }));
            tabFolder.setSelection(item);
            event.browser = browser;
        }

        public void changed(TitleEvent event) {
            String title = event.title;
            if (title != null && title.length() != 0) {
                if (title.indexOf("http://") == -1) { //$NON-NLS-1$
                    CTabItem item = tabMap.get(event.getSource());
                    item.setText(title);
                }
            }
        }

        public void close(WindowEvent event) {
            Browser browser = event.browser;
            tabMap.remove(browser);
            listenerMap.remove(browser);
        }
    }

    public void setCurrentURL(String text) {
        CTabItem item = tabFolder.getSelection();
        if (item == null) {
            addTab(Messages.BrowserContainerView_tabTitle, text, (Image) null, getListener());
        } else {
            Browser b = (Browser) item.getControl();
            b.setUrl(text);
        }
    }
}