Package org.rssowl.ui.internal

Source Code of org.rssowl.ui.internal.CBrowser

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2006 RSSOwl Development Team                                  **
**   http://www.rssowl.org/                                                 **
**                                                                          **
**   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.rssowl.org/legal/epl-v10.html                               **
**                                                                          **
**   A copy is found in the file epl-v10.html and important notices to the  **
**   license from the team is found in the textfile LICENSE.txt distributed **
**   in this package.                                                       **
**                                                                          **
**   This copyright notice MUST APPEAR in all copies of the file!           **
**                                                                          **
**   Contributors:                                                          **
**     RSSOwl Development Team - initial API and implementation             **
**                                                                          **
**  **********************************************************************  */

package org.rssowl.ui.internal;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
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.WindowEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.rssowl.core.Owl;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.util.StringUtils;
import org.rssowl.core.util.URIUtils;
import org.rssowl.ui.internal.editors.browser.WebBrowserInput;
import org.rssowl.ui.internal.editors.browser.WebBrowserView;
import org.rssowl.ui.internal.util.BrowserUtils;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

/**
* Instances of <code>CBrowser</code> wrap around the Browser-Widget and
* enhance it by some means.
*
* @author bpasero
*/
public class CBrowser {

  /* JavaScript: print() Method */
  private static final String JAVA_SCRIPT_PRINT = "window.print();";

  /* Flag to check if Mozilla is available on Windows */
  private static boolean fgMozillaAvailable = true;

  private Browser fBrowser;
  private boolean fBlockNavigation;
  private IPreferenceScope fPreferences;
  private Map<String, ILinkHandler> fLinkHandler;

  /**
   * @param parent The Parent Composite of this Browser.
   * @param style The Style to use for the Browser-
   */
  public CBrowser(Composite parent, int style) {
    fBrowser = createBrowser(parent, style);
    fPreferences = Owl.getPreferenceService().getGlobalScope();
    fLinkHandler = new HashMap<String, ILinkHandler>();
    hookListeners();

    /* Add custom Context Menu on OS where this is not supported */
    if (Application.IS_LINUX || fgMozillaAvailable)
      hookMenu();
  }

  /**
   * Adds the given Handler to this instance responsible for the given Command.
   *
   * @param commandId The ID of the Command the provided Handler is responsible
   * for.
   * @param handler The Handler responsible for the fiven ID.
   */
  public void addLinkHandler(String commandId, ILinkHandler handler) {
    fLinkHandler.put(commandId, handler);
  }

  private Browser createBrowser(Composite parent, int style) {
    Browser browser = null;

    /* Try Mozilla over IE on Windows */
    if (Application.IS_WINDOWS && fgMozillaAvailable) {
      try {
        browser = new Browser(parent, style | SWT.MOZILLA);
      } catch (SWTError e) {
        fgMozillaAvailable = false;
        Activator.getDefault().getLog().log(Activator.getDefault().createInfoStatus(e.getMessage(), null));
      }
    }

    /* Any other OS, or Mozilla unavailable, use default */
    if (browser == null)
      browser = new Browser(parent, style);

    /* Add Focusless Scroll Hook on Windows */
    if (Application.IS_WINDOWS)
      browser.setData(ApplicationWorkbenchWindowAdvisor.FOCUSLESS_SCROLL_HOOK, true);

    /* Clear all Link Handlers upon disposal */
    browser.addDisposeListener(new DisposeListener() {
      public void widgetDisposed(DisposeEvent e) {
        fLinkHandler.clear();
      }
    });

    return browser;
  }

  private void hookMenu() {
    MenuManager manager = new MenuManager();
    manager.setRemoveAllWhenShown(true);
    manager.addMenuListener(new IMenuListener() {
      public void menuAboutToShow(IMenuManager manager) {

        /* Back */
        manager.add(new Action("Back") {
          @Override
          public void run() {
            fBrowser.back();
          }

          @Override
          public boolean isEnabled() {
            return fBrowser.isBackEnabled();
          }

          @Override
          public ImageDescriptor getImageDescriptor() {
            return OwlUI.getImageDescriptor("icons/etool16/backward.gif");
          }
        });

        /* Forward */
        manager.add(new Action("Forward") {
          @Override
          public void run() {
            fBrowser.forward();
          }

          @Override
          public boolean isEnabled() {
            return fBrowser.isForwardEnabled();
          }

          @Override
          public ImageDescriptor getImageDescriptor() {
            return OwlUI.getImageDescriptor("icons/etool16/forward.gif");
          }
        });

        /* Reload */
        manager.add(new Separator());
        manager.add(new Action("Reload") {
          @Override
          public void run() {
            fBrowser.refresh();
          }

          @Override
          public ImageDescriptor getImageDescriptor() {
            return OwlUI.getImageDescriptor("icons/elcl16/reload.gif");
          }
        });

        /* Stop */
        manager.add(new Action("Stop") {
          @Override
          public void run() {
            fBrowser.stop();
          }

          @Override
          public ImageDescriptor getImageDescriptor() {
            return OwlUI.getImageDescriptor("icons/etool16/cancel.gif");
          }
        });
      }
    });

    Menu menu = manager.createContextMenu(fBrowser);
    fBrowser.setMenu(menu);
  }

  /**
   * Returns the Browser-Widget this class is wrapping.
   *
   * @return The Browser-Widget this class is wrapping.
   */
  public Browser getControl() {
    return fBrowser;
  }

  /**
   * Browse to the given URL.
   *
   * @param url The URL to browse to.
   */
  public void setUrl(String url) {
    fBlockNavigation = false;
    fBrowser.setUrl(url);
  }

  /**
   * Navigate to the previous session history item.
   *
   * @return <code>true</code> if the operation was successful and
   * <code>false</code> otherwise
   */
  public boolean back() {
    fBlockNavigation = false;
    return fBrowser.back();
  }

  /**
   * Navigate to the next session history item.
   *
   * @return <code>true</code> if the operation was successful and
   * <code>false</code> otherwise
   */
  public boolean forward() {
    fBlockNavigation = false;
    return fBrowser.forward();
  }

  /**
   * Print the Browser using the JavaScript print() method
   *
   * @return <code>TRUE</code> in case of success, <code>FALSE</code>
   * otherwise
   */
  public boolean print() {
    return fBrowser.execute(JAVA_SCRIPT_PRINT);
  }

  private void hookListeners() {

    /* Listen to Open-Window-Changes */
    fBrowser.addOpenWindowListener(new OpenWindowListener() {
      public void open(WindowEvent event) {

        /* Do not handle when external Browser is being used */
        if (useExternalBrowser())
          return;

        /* Open Browser in new Tab */
        WebBrowserInput input = new WebBrowserInput(URIUtils.ABOUT_BLANK);
        IWorkbenchPage page = OwlUI.getPage();
        if (page != null) {
          try {
            WebBrowserView browserView = (WebBrowserView) page.openEditor(input, WebBrowserView.EDITOR_ID, OpenStrategy.activateOnOpen());
            event.browser = browserView.getBrowser().getControl();
          } catch (PartInitException e) {
            Activator.getDefault().getLog().log(e.getStatus());
          }
        }
      }
    });

    /* Listen to Location-Changes */
    fBrowser.addLocationListener(new LocationListener() {
      public void changed(LocationEvent event) {
        if (event.top && useExternalBrowser())
          fBlockNavigation = true;
      }

      public void changing(LocationEvent event) {

        /* Handle Application Protocol */
        if (event.location != null && event.location.contains(ILinkHandler.HANDLER_PROTOCOL)) {
          try {
            URI link = new URI(event.location);
            String host = link.getHost();
            if (StringUtils.isSet(host) && fLinkHandler.containsKey(host)) {
              fLinkHandler.get(host).handle(host, link);
              event.doit = false;
              return;
            }
          } catch (URISyntaxException e) {
            Activator.getDefault().getLog().log(Activator.getDefault().createErrorStatus(e.getMessage(), e));
          }
        }

        /* Feature not enabled */
        if (!useExternalBrowser())
          return;

        /*
         * Bug on Mac: Safari puts out links from images as event.location
         * resulting in RSSOwl to open a browser although its not necessary
         * Workaround is to disable this feature on Mac until its fixed. (see
         * Bug #1068304).
         */
        if (Application.IS_MAC)
          return;

        /* Only proceed if navigation should not be blocked */
        if (!fBlockNavigation)
          return;

        /* Let local ApplicationServer URLs open */
        if (ApplicationServer.getDefault().isNewsServerUrl(event.location))
          return;

        /* The URL must not be empty or about:blank (Problem on Linux) */
        if (!StringUtils.isSet(event.location) || URIUtils.ABOUT_BLANK.equals(event.location))
          return;

        /* Finally, cancel event and open URL external */
        event.doit = false;
        BrowserUtils.openLink(event.location);
      }
    });
  }

  private boolean useExternalBrowser() {
    return fPreferences.getBoolean(DefaultPreferences.USE_DEFAULT_EXTERNAL_BROWSER) || fPreferences.getBoolean(DefaultPreferences.USE_CUSTOM_EXTERNAL_BROWSER);
  }
}
TOP

Related Classes of org.rssowl.ui.internal.CBrowser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.