2  * Copyright (c) 2003 IBM Corporation and others. All rights reserved.   This program and the accompanying materials are made
 
   3  * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
 
   4  * http://www.eclipse.org/legal/cpl-v10.html  * Contributors: IBM - Initial API and implementation
 
   7 //TODO 1. Handle the sizing of a popup running in shelled out secondary window.
 
   8 //TODO 2. Support printing: waiting on eclipse bug 47937/44823.
 
   9 package net.sourceforge.phpeclipse.webbrowser.internal;
 
  13 import net.sourceforge.phpeclipse.webbrowser.IURLMap;
 
  15 import org.eclipse.swt.SWT;
 
  16 import org.eclipse.swt.widgets.*;
 
  17 import org.eclipse.swt.layout.FillLayout;
 
  18 import org.eclipse.swt.layout.GridData;
 
  19 import org.eclipse.swt.layout.GridLayout;
 
  20 import org.eclipse.swt.dnd.Clipboard;
 
  21 import org.eclipse.swt.events.*;
 
  22 import org.eclipse.swt.graphics.Point;
 
  23 import org.eclipse.swt.graphics.Rectangle;
 
  24 import org.eclipse.ui.help.WorkbenchHelp;
 
  25 import org.eclipse.swt.browser.*;
 
  27 public class WebBrowser extends Composite {
 
  28   protected Composite toolbarComp;
 
  30   protected Composite statusComp;
 
  32   protected Combo combo;
 
  34   protected Clipboard clipboard;
 
  36   protected boolean showToolbar;
 
  38   protected ToolItem back;
 
  40   protected ToolItem forward;
 
  42   protected ToolItem stop;
 
  44   protected ToolItem favorites;
 
  46   protected ToolItem refresh;
 
  48   protected BusyIndicator busy;
 
  50   protected boolean showStatusbar;
 
  52   protected ProgressBar progress;
 
  54   protected Label status;
 
  56   private static int MAX_HISTORY = 50;
 
  58   protected static java.util.List history;
 
  60   protected Browser browser;
 
  62   protected Shell shell;
 
  64   protected WebBrowserEditor editor;
 
  66   protected String title;
 
  68   public WebBrowser(Composite parent, final boolean showToolbar, final boolean showStatusbar) {
 
  69     super(parent, SWT.NONE);
 
  71     this.showToolbar = showToolbar;
 
  72     this.showStatusbar = showStatusbar;
 
  74     GridLayout layout = new GridLayout();
 
  75     layout.marginHeight = 3;
 
  76     layout.marginWidth = 3;
 
  77     layout.horizontalSpacing = 3;
 
  78     layout.verticalSpacing = 3;
 
  79     layout.numColumns = 1;
 
  81     setLayoutData(new GridData(GridData.FILL_BOTH));
 
  82     clipboard = new Clipboard(parent.getDisplay());
 
  83     WorkbenchHelp.setHelp(this, ContextIds.WEB_BROWSER);
 
  86       toolbarComp = new Composite(this, SWT.NONE);
 
  87       GridLayout outerLayout = new GridLayout();
 
  88       outerLayout.numColumns = 2;
 
  89       outerLayout.marginWidth = 0;
 
  90       outerLayout.marginHeight = 0;
 
  91       toolbarComp.setLayout(outerLayout);
 
  92       toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
 
  94       // create the top line, with a combo box for history and a "go" button
 
  95       Composite top = new Composite(toolbarComp, SWT.NONE);
 
  96       GridLayout topLayout = new GridLayout();
 
  97       topLayout.numColumns = 2;
 
  98       topLayout.marginWidth = 0;
 
  99       topLayout.marginHeight = 0;
 
 100       top.setLayout(topLayout);
 
 101       top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL));
 
 103       combo = new Combo(top, SWT.DROP_DOWN);
 
 107       combo.addSelectionListener(new SelectionAdapter() {
 
 108         public void widgetSelected(SelectionEvent we) {
 
 110             if (combo.getSelectionIndex() != -1)
 
 111               setURL(combo.getItem(combo.getSelectionIndex()));
 
 112           } catch (Exception e) {
 
 116       combo.addListener(SWT.DefaultSelection, new Listener() {
 
 117         public void handleEvent(Event e) {
 
 118           setURL(combo.getText());
 
 121       combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 122       WorkbenchHelp.setHelp(combo, ContextIds.WEB_BROWSER_URL);
 
 124       ToolBar toolbar = new ToolBar(top, SWT.FLAT);
 
 125       fillToolBar(toolbar);
 
 127       new ToolItem(toolbar, SWT.SEPARATOR);
 
 129       busy = new BusyIndicator(toolbarComp, SWT.NONE);
 
 130       busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
 
 133     // create a new SWT Web browser widget, checking once again to make sure we can use it in this environment
 
 134     if (WebBrowserUtil.canUseInternalWebBrowser() & WebBrowserUtil.isInternalBrowserOperational())
 
 135       this.browser = new Browser(this, SWT.NONE);
 
 137       WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchInternalWebBrowser"));
 
 142       back.setEnabled(browser.isBackEnabled());
 
 143       forward.setEnabled(browser.isForwardEnabled());
 
 146     WorkbenchHelp.setHelp(browser, ContextIds.WEB_BROWSER_WEB);
 
 147     GridData data = new GridData();
 
 148     data.horizontalAlignment = GridData.FILL;
 
 149     data.verticalAlignment = GridData.FILL;
 
 150     data.horizontalSpan = 3;
 
 151     data.grabExcessHorizontalSpace = true;
 
 152     data.grabExcessVerticalSpace = true;
 
 153     browser.setLayoutData(data);
 
 156       createStatusArea(this);
 
 158     addBrowserListeners();
 
 164   protected void addBrowserListeners() {
 
 166       // respond to Browser StatusTextEvents events by updating the status Text label
 
 167       browser.addStatusTextListener(new StatusTextListener() {
 
 168         public void changed(StatusTextEvent event) {
 
 169           status.setText(event.text);
 
 175      * Add listener for new window creation so that we can instead of opening a separate new window in which the session is lost, we
 
 176      * can instead open a new window in a new shell within the browser area thereby maintaining the session.
 
 178     browser.addOpenWindowListener(new OpenWindowListener() {
 
 179       public void open(WindowEvent event) {
 
 180         Shell shell2 = new Shell(getDisplay());
 
 181         shell2.setLayout(new FillLayout());
 
 182         shell2.setText(WebBrowserUIPlugin.getResource("%viewWebBrowserTitle"));
 
 183         shell2.setImage(getShell().getImage());
 
 184         WebBrowser browser2 = new WebBrowser(shell2, showToolbar, showStatusbar);
 
 185         browser2.shell = shell2;
 
 186         event.browser = browser2.browser;
 
 191     browser.addCloseWindowListener(new CloseWindowListener() {
 
 192       public void close(WindowEvent event) {
 
 193         // if shell is not null, it must be a secondary popup window, else its an editor window
 
 197           editor.closeEditor();
 
 201     browser.addProgressListener(new ProgressListener() {
 
 202       public void changed(ProgressEvent event) {
 
 203         if (event.total == 0)
 
 206         boolean done = (event.current == event.total);
 
 208         int percentProgress = event.current * 100 / event.total;
 
 211             progress.setSelection(0);
 
 213             progress.setSelection(percentProgress);
 
 217           if (!busy.isBusy() && (percentProgress > 0 && percentProgress < 100)) {
 
 220           // Once the progress hits 100 percent, done, set busy to false
 
 221           else if (busy.isBusy() && done) {
 
 227       public void completed(ProgressEvent event) {
 
 229           progress.setSelection(0);
 
 232           back.setEnabled(browser.isBackEnabled());
 
 233           forward.setEnabled(browser.isForwardEnabled());
 
 239       browser.addLocationListener(new LocationListener() {
 
 240         public void changed(LocationEvent event) {
 
 244             combo.setText(event.location);
 
 245             addToHistory(event.location);
 
 251         public void changing(LocationEvent event) {
 
 256     browser.addTitleListener(new TitleListener() {
 
 257       public void changed(TitleEvent event) {
 
 264    * Return the underlying browser control.
 
 266    * @return org.eclipse.swt.browser.Browser
 
 268   public Browser getBrowser() {
 
 275   protected void forward() {
 
 282   protected void back() {
 
 289   protected void stop() {
 
 296   protected void navigate(String url) {
 
 297     Trace.trace(Trace.FINER, "Navigate: " + url);
 
 298     if (url != null && url.equals(getURL())) {
 
 306    * Refresh the currently viewed page.
 
 308   public void refresh() {
 
 312   protected void setURL(String url, boolean browse) {
 
 313     Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
 
 319     if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
 
 323     Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
 
 324     String newURL = null;
 
 325     while (iterator.hasNext() && newURL == null) {
 
 327         IURLMap map = (IURLMap) iterator.next();
 
 328         newURL = map.getMappedURL(url);
 
 329       } catch (Exception e) {
 
 342   protected void addToHistory(String url) {
 
 344       history = WebBrowserPreference.getInternalWebBrowserHistory();
 
 346     int size = history.size();
 
 347     for (int i = 0; i < size; i++) {
 
 348       String s = (String) history.get(i);
 
 356       if (size >= MAX_HISTORY)
 
 357         history.remove(size - 1);
 
 359       WebBrowserPreference.setInternalWebBrowserHistory(history);
 
 360     } else if (found != 0) {
 
 361       history.remove(found);
 
 363       WebBrowserPreference.setInternalWebBrowserHistory(history);
 
 367   public void setURL(String url) {
 
 372    * Creates the Web browser status area.
 
 374   private void createStatusArea(Composite parent) {
 
 375     Composite composite = new Composite(parent, SWT.NONE);
 
 376     GridLayout layout = new GridLayout();
 
 377     layout.numColumns = 2;
 
 378     layout.marginHeight = 0;
 
 379     layout.marginWidth = 0;
 
 380     layout.horizontalSpacing = 4;
 
 381     layout.verticalSpacing = 0;
 
 382     composite.setLayout(layout);
 
 383     composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 385     // Add a label for displaying status messages as they are received from the control
 
 386     status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
 
 387     GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
 
 388     gridData.horizontalIndent = 2;
 
 389     status.setLayoutData(gridData);
 
 391     // Add a progress bar to display downloading progress information
 
 392     progress = new ProgressBar(composite, SWT.BORDER);
 
 393     gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL);
 
 394     gridData.widthHint = 100;
 
 395     gridData.heightHint = 10;
 
 396     progress.setLayoutData(gridData);
 
 402   public void dispose() {
 
 405     showStatusbar = false;
 
 416    * Populate the toolbar.
 
 419    *          org.eclipse.swt.widgets.ToolBar
 
 421   private void fillToolBar(final ToolBar toolbar) {
 
 422     ToolItem go = new ToolItem(toolbar, SWT.NONE);
 
 423     go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
 
 424     go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
 
 425     go.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_GO));
 
 426     go.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserGo"));
 
 427     go.addSelectionListener(new SelectionAdapter() {
 
 428       public void widgetSelected(SelectionEvent event) {
 
 429         setURL(combo.getText());
 
 433     new ToolItem(toolbar, SWT.SEPARATOR);
 
 435     favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
 
 436     favorites.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
 
 437     favorites.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
 
 438     favorites.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
 
 439     favorites.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserFavorites"));
 
 441     favorites.addSelectionListener(new SelectionAdapter() {
 
 442       public void widgetSelected(SelectionEvent event) {
 
 443         if (event.detail == SWT.ARROW) {
 
 444           Rectangle r = favorites.getBounds();
 
 445           showFavorites(toolbar, toolbar.toDisplay(r.x, r.y + r.height));
 
 451     // create back and forward actions
 
 452     back = new ToolItem(toolbar, SWT.NONE);
 
 453     back.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
 
 454     back.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
 
 455     back.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
 
 456     back.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserBack"));
 
 457     back.addSelectionListener(new SelectionAdapter() {
 
 458       public void widgetSelected(SelectionEvent event) {
 
 463     forward = new ToolItem(toolbar, SWT.NONE);
 
 464     forward.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
 
 465     forward.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
 
 466     forward.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
 
 467     forward.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserForward"));
 
 468     forward.addSelectionListener(new SelectionAdapter() {
 
 469       public void widgetSelected(SelectionEvent event) {
 
 474     // create refresh, stop, and print actions
 
 475     stop = new ToolItem(toolbar, SWT.NONE);
 
 476     stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
 
 477     stop.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_STOP));
 
 478     stop.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_STOP));
 
 479     stop.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserStop"));
 
 480     stop.addSelectionListener(new SelectionAdapter() {
 
 481       public void widgetSelected(SelectionEvent event) {
 
 486     refresh = new ToolItem(toolbar, SWT.NONE);
 
 487     refresh.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
 
 488     refresh.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
 
 489     refresh.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
 
 490     refresh.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserRefresh"));
 
 491     refresh.addSelectionListener(new SelectionAdapter() {
 
 492       public void widgetSelected(SelectionEvent event) {
 
 498   protected void addFavorite() {
 
 499     java.util.List list = WebBrowserPreference.getInternalWebBrowserFavorites();
 
 500     Favorite f = new Favorite(title, browser.getUrl());
 
 501     if (!list.contains(f)) {
 
 503       WebBrowserPreference.setInternalWebBrowserFavorites(list);
 
 507   protected void showFavorites(Control parent, Point p) {
 
 508     Menu perspectiveBarMenu = null;
 
 509     if (perspectiveBarMenu == null) {
 
 510       Menu menu = new Menu(parent);
 
 513       Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
 
 514       if (iterator.hasNext()) {
 
 515         while (iterator.hasNext()) {
 
 516           final Favorite f = (Favorite) iterator.next();
 
 517           MenuItem item = new MenuItem(menu, SWT.NONE);
 
 518           item.setText(f.getName());
 
 519           item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
 
 520           item.addSelectionListener(new SelectionAdapter() {
 
 521             public void widgetSelected(SelectionEvent event) {
 
 527         new MenuItem(menu, SWT.SEPARATOR);
 
 530       iterator = WebBrowserPreference.getInternalWebBrowserFavorites().iterator();
 
 531       if (!iterator.hasNext()) {
 
 532         MenuItem item = new MenuItem(menu, SWT.NONE);
 
 533         item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserNoFavorites"));
 
 535       while (iterator.hasNext()) {
 
 536         final Favorite f = (Favorite) iterator.next();
 
 537         MenuItem item = new MenuItem(menu, SWT.NONE);
 
 538         item.setText(f.getName());
 
 539         item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
 
 540         item.addSelectionListener(new SelectionAdapter() {
 
 541           public void widgetSelected(SelectionEvent event) {
 
 547       new MenuItem(menu, SWT.SEPARATOR);
 
 549       MenuItem item = new MenuItem(menu, SWT.NONE);
 
 550       item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserOrganizeFavorites"));
 
 551       item.addSelectionListener(new SelectionAdapter() {
 
 552         public void widgetSelected(SelectionEvent event) {
 
 553           OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(shell);
 
 558       perspectiveBarMenu = menu;
 
 561     if (perspectiveBarMenu != null) {
 
 562       perspectiveBarMenu.setLocation(p.x, p.y);
 
 563       perspectiveBarMenu.setVisible(true);
 
 568     navigate(WebBrowserPreference.getHomePageURL());
 
 572    * Returns true if the homepage is currently being displayed.
 
 576   protected boolean isHome() {
 
 577     return getURL() != null && getURL().endsWith(WebBrowserPreference.getHomePageURL().substring(9));
 
 580   protected String getURL() {
 
 581     return browser.getUrl();
 
 585    * Update the history list to the global copy.
 
 587   protected void updateHistory() {
 
 591     String temp = combo.getText();
 
 593       history = WebBrowserPreference.getInternalWebBrowserHistory();
 
 595     String[] historyList = new String[history.size()];
 
 596     history.toArray(historyList);
 
 597     combo.setItems(historyList);
 
 602   public void addProgressListener(ProgressListener listener) {
 
 603     browser.addProgressListener(listener);
 
 606   public void addStatusTextListener(StatusTextListener listener) {
 
 607     browser.addStatusTextListener(listener);
 
 610   public void addTitleListener(TitleListener listener) {
 
 611     browser.addTitleListener(listener);