2  * Copyright (c) 2003 IBM Corporation and others.
 
   3  * All rights reserved.   This program and the accompanying materials
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
   9  *    IBM - Initial API and implementation
 
  12 //TODO 1. Handle the sizing of a popup running in shelled out secondary window.
 
  13 //TODO 2. Support printing: waiting on eclipse bug 47937/44823.
 
  15 package net.sourceforge.phpeclipse.webbrowser.internal;
 
  19 import net.sourceforge.phpeclipse.webbrowser.IURLMap;
 
  21 import org.eclipse.swt.SWT;
 
  22 import org.eclipse.swt.widgets.*;
 
  23 import org.eclipse.swt.layout.FillLayout;
 
  24 import org.eclipse.swt.layout.GridData;
 
  25 import org.eclipse.swt.layout.GridLayout;
 
  26 import org.eclipse.swt.dnd.Clipboard;
 
  27 import org.eclipse.swt.events.*;
 
  28 import org.eclipse.swt.graphics.Point;
 
  29 import org.eclipse.swt.graphics.Rectangle;
 
  30 import org.eclipse.ui.help.WorkbenchHelp;
 
  31 import org.eclipse.swt.browser.*;
 
  33 public class WebBrowser extends Composite {
 
  34         protected Composite toolbarComp;
 
  35         protected Composite statusComp;
 
  36         protected Combo combo;
 
  37         protected Clipboard clipboard;
 
  38         protected boolean showToolbar;
 
  39         protected ToolItem back;
 
  40         protected ToolItem forward;
 
  41         protected ToolItem stop;
 
  42         protected ToolItem favorites;
 
  43         protected ToolItem refresh;
 
  44         protected BusyIndicator busy;
 
  45         protected boolean showStatusbar;
 
  46         protected ProgressBar progress;
 
  47         protected Label status;
 
  48         private static int MAX_HISTORY = 50;
 
  49         protected static java.util.List history;
 
  50         protected Browser browser; 
 
  51         protected Shell shell;
 
  52         protected WebBrowserEditor editor;
 
  53         protected String title;
 
  55         public WebBrowser(Composite parent, final boolean showToolbar, final boolean showStatusbar) {
 
  56                 super(parent, SWT.NONE);
 
  58                 this.showToolbar = showToolbar;
 
  59                 this.showStatusbar = showStatusbar;     
 
  61                 GridLayout layout = new GridLayout();
 
  62                 layout.marginHeight = 3;
 
  63                 layout.marginWidth = 3;
 
  64                 layout.horizontalSpacing = 3;
 
  65                 layout.verticalSpacing = 3;
 
  66                 layout.numColumns = 1;
 
  68                 setLayoutData(new GridData(GridData.FILL_BOTH));
 
  69                 clipboard = new Clipboard(parent.getDisplay());
 
  70                 WorkbenchHelp.setHelp(this, ContextIds.WEB_BROWSER);
 
  73                         toolbarComp = new Composite(this, SWT.NONE);
 
  74                         GridLayout outerLayout = new GridLayout();
 
  75                         outerLayout.numColumns = 2;
 
  76                         outerLayout.marginWidth = 0;
 
  77                         outerLayout.marginHeight = 0;
 
  78                         toolbarComp.setLayout(outerLayout);
 
  79                         toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
 
  81                         // create the top line, with a combo box for history and a "go" button
 
  82                         Composite top = new Composite(toolbarComp, SWT.NONE);
 
  83                         GridLayout topLayout = new GridLayout();
 
  84                         topLayout.numColumns = 2;
 
  85                         topLayout.marginWidth = 0;
 
  86                         topLayout.marginHeight = 0;
 
  87                         top.setLayout(topLayout);
 
  88                         top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL));
 
  90                         combo = new Combo(top, SWT.DROP_DOWN);
 
  94                         combo.addSelectionListener(new SelectionAdapter() {
 
  95                                 public void widgetSelected(SelectionEvent we) {
 
  97                                                 if (combo.getSelectionIndex() != -1)
 
  98                                                         setURL(combo.getItem(combo.getSelectionIndex()));
 
  99                                         } catch (Exception e) { }
 
 102                         combo.addListener(SWT.DefaultSelection, new Listener() {
 
 103                                 public void handleEvent(Event e) {
 
 104                                         setURL(combo.getText());
 
 107                         combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 108                         WorkbenchHelp.setHelp(combo, ContextIds.WEB_BROWSER_URL);
 
 110                         ToolBar toolbar = new ToolBar(top, SWT.FLAT);
 
 111                         fillToolBar(toolbar);
 
 113                         new ToolItem(toolbar, SWT.SEPARATOR);
 
 115                         busy = new BusyIndicator(toolbarComp, SWT.NONE);
 
 116                         busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
 
 119                 // create a new SWT Web browser widget, checking once again to make sure we can use it in this environment
 
 120                 if (WebBrowserUtil.canUseInternalWebBrowser() & WebBrowserUtil.isInternalBrowserOperational())
 
 121                         this.browser = new Browser(this, SWT.NONE);
 
 123                         WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchInternalWebBrowser"));
 
 128                         back.setEnabled(browser.isBackEnabled());
 
 129                         forward.setEnabled(browser.isForwardEnabled());
 
 132                 WorkbenchHelp.setHelp(browser, ContextIds.WEB_BROWSER_WEB);
 
 133                 GridData data = new GridData();
 
 134                 data.horizontalAlignment = GridData.FILL;
 
 135                 data.verticalAlignment = GridData.FILL;
 
 136                 data.horizontalSpan = 3;
 
 137                 data.grabExcessHorizontalSpace = true;
 
 138                 data.grabExcessVerticalSpace = true;
 
 139                 browser.setLayoutData(data);
 
 142                         createStatusArea(this);
 
 144                 addBrowserListeners();
 
 149         protected void addBrowserListeners() {  
 
 151                         // respond to Browser StatusTextEvents events by updating the status Text label
 
 152                         browser.addStatusTextListener(new StatusTextListener() {
 
 153                                 public void changed(StatusTextEvent event) {
 
 154                                         status.setText(event.text);     
 
 159                 /** Add listener for new window creation so that we can instead of opening a separate
 
 160                  *  new window in which the session is lost, we can instead open a new window in a new
 
 161                  *  shell within the browser area thereby maintaining the session.
 
 163                 browser.addOpenWindowListener(new OpenWindowListener() {
 
 164                         public void open(WindowEvent event) {
 
 165                                 Shell shell2 = new Shell(getDisplay());
 
 166                                 shell2.setLayout(new FillLayout());
 
 167                                 shell2.setText(WebBrowserUIPlugin.getResource("%viewWebBrowserTitle"));
 
 168                                 shell2.setImage(getShell().getImage());
 
 169                                 WebBrowser browser2 = new WebBrowser(shell2, showToolbar, showStatusbar);
 
 170                                 browser2.shell = shell2;
 
 171                                 event.browser = browser2.browser;
 
 176                 browser.addCloseWindowListener(new CloseWindowListener(){
 
 177                         public void close(WindowEvent event) {
 
 178                                 // if shell is not null, it must be a secondary popup window, else its an editor window
 
 182                                         editor.closeEditor();
 
 186                 browser.addProgressListener(new ProgressListener() {
 
 187                         public void changed(ProgressEvent event) {
 
 188                                 if (event.total == 0)
 
 191                                 boolean done = (event.current == event.total);
 
 193                                 int percentProgress = event.current * 100 / event.total;
 
 196                                                 progress.setSelection(0);
 
 198                                                 progress.setSelection(percentProgress);
 
 202                                         if (!busy.isBusy() && (percentProgress > 0 && percentProgress < 100)) {
 
 205                                         // Once the progress hits 100 percent, done, set busy to false
 
 206                                         else if (busy.isBusy() && done) {
 
 212                         public void completed(ProgressEvent event) {
 
 214                                         progress.setSelection(0);
 
 217                                         back.setEnabled(browser.isBackEnabled());
 
 218                                         forward.setEnabled(browser.isForwardEnabled());
 
 224                         browser.addLocationListener(new LocationListener() {
 
 225                                 public void changed(LocationEvent event) {
 
 229                                                 combo.setText(event.location);
 
 230                                                 addToHistory(event.location);
 
 236                                 public void changing(LocationEvent event) { }
 
 240                 browser.addTitleListener(new TitleListener() {
 
 241                         public void changed(TitleEvent event) {
 
 248          * Return the underlying browser control.
 
 250          * @return org.eclipse.swt.browser.Browser
 
 252         public Browser getBrowser() {
 
 259         protected void forward() {
 
 266         protected void back() {
 
 273         protected void stop() {
 
 280         protected void navigate(String url) {
 
 281                 Trace.trace(Trace.FINER, "Navigate: " + url);
 
 282                 if (url != null && url.equals(getURL())) {
 
 290          * Refresh the currently viewed page.
 
 292         public void refresh() {
 
 296         protected void setURL(String url, boolean browse) {
 
 297                 Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
 
 303                 if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
 
 307                 Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
 
 308                 String newURL = null;
 
 309                 while (iterator.hasNext() && newURL == null) {
 
 311                                 IURLMap map = (IURLMap) iterator.next();
 
 312                                 newURL = map.getMappedURL(url);
 
 313                         } catch (Exception e) { }
 
 325         protected void addToHistory(String url) {
 
 327                         history = WebBrowserPreference.getInternalWebBrowserHistory();
 
 329                 int size = history.size();
 
 330                 for (int i = 0; i < size; i++){
 
 331                         String s = (String) history.get(i);
 
 339                         if (size >= MAX_HISTORY)
 
 340                                 history.remove(size - 1);
 
 342                         WebBrowserPreference.setInternalWebBrowserHistory(history);
 
 343                 } else if (found != 0) {
 
 344                         history.remove(found);
 
 346                         WebBrowserPreference.setInternalWebBrowserHistory(history);
 
 350         public void setURL(String url) {
 
 355          * Creates the Web browser status area.
 
 357         private void createStatusArea(Composite parent) {
 
 358                 Composite composite = new Composite(parent, SWT.NONE);
 
 359                 GridLayout layout = new GridLayout();
 
 360                 layout.numColumns = 2;
 
 361                 layout.marginHeight = 0;
 
 362                 layout.marginWidth = 0;
 
 363                 layout.horizontalSpacing = 4;
 
 364                 layout.verticalSpacing = 0;
 
 365                 composite.setLayout(layout);
 
 366                 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 368                 // Add a label for displaying status messages as they are received from the control
 
 369                 status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
 
 370                 GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
 
 371                 gridData.horizontalIndent = 2;
 
 372                 status.setLayoutData(gridData);
 
 374                 // Add a progress bar to display downloading progress information
 
 375                 progress = new ProgressBar(composite, SWT.BORDER);
 
 376                 gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL);
 
 377                 gridData.widthHint = 100;
 
 378                 gridData.heightHint = 10;
 
 379                 progress.setLayoutData(gridData);
 
 385         public void dispose() {
 
 388                 showStatusbar = false;
 
 399          * Populate the toolbar.
 
 400          * @param toolbar org.eclipse.swt.widgets.ToolBar
 
 402         private void fillToolBar(final ToolBar toolbar) {
 
 403                 ToolItem go = new ToolItem(toolbar, SWT.NONE);
 
 404                 go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
 
 405                 go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
 
 406                 go.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_GO));
 
 407                 go.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserGo"));
 
 408                 go.addSelectionListener(new SelectionAdapter() {
 
 409                         public void widgetSelected(SelectionEvent event) {
 
 410                                 setURL(combo.getText());
 
 414                 new ToolItem(toolbar, SWT.SEPARATOR);
 
 416                 favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
 
 417                 favorites.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
 
 418                 favorites.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
 
 419                 favorites.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
 
 420                 favorites.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserFavorites"));
 
 422                 favorites.addSelectionListener(new SelectionAdapter() {
 
 423                         public void widgetSelected(SelectionEvent event) {
 
 424                                 if (event.detail == SWT.ARROW) {
 
 425                                         Rectangle r = favorites.getBounds();
 
 426                                         showFavorites(toolbar, toolbar.toDisplay(r.x, r.y + r.height));
 
 432                 // create back and forward actions
 
 433                 back = new ToolItem(toolbar, SWT.NONE);
 
 434                 back.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
 
 435                 back.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
 
 436                 back.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
 
 437                 back.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserBack"));
 
 438                 back.addSelectionListener(new SelectionAdapter() {
 
 439                         public void widgetSelected(SelectionEvent event) {
 
 444                 forward = new ToolItem(toolbar, SWT.NONE);
 
 445                 forward.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
 
 446                 forward.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
 
 447                 forward.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
 
 448                 forward.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserForward"));
 
 449                 forward.addSelectionListener(new SelectionAdapter() {
 
 450                         public void widgetSelected(SelectionEvent event) {
 
 455                 // create refresh, stop, and print actions
 
 456                 stop = new ToolItem(toolbar, SWT.NONE);
 
 457                 stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
 
 458                 stop.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_STOP));
 
 459                 stop.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_STOP));
 
 460                 stop.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserStop"));
 
 461                 stop.addSelectionListener(new SelectionAdapter() {
 
 462                         public void widgetSelected(SelectionEvent event) {
 
 467                 refresh = new ToolItem(toolbar, SWT.NONE);
 
 468                 refresh.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
 
 469                 refresh.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
 
 470                 refresh.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
 
 471                 refresh.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserRefresh"));
 
 472                 refresh.addSelectionListener(new SelectionAdapter() {
 
 473                         public void widgetSelected(SelectionEvent event) {
 
 479         protected void addFavorite() {
 
 480                 java.util.List list = WebBrowserPreference.getInternalWebBrowserFavorites();
 
 481                 Favorite f = new Favorite(title, browser.getUrl());
 
 482                 if (!list.contains(f)) {
 
 484                         WebBrowserPreference.setInternalWebBrowserFavorites(list);
 
 488         protected void showFavorites(Control parent, Point p) {
 
 489                 Menu perspectiveBarMenu = null;
 
 490                 if (perspectiveBarMenu == null) {
 
 491                         Menu menu = new Menu(parent);
 
 494                         Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
 
 495                         if (iterator.hasNext()) {
 
 496                                 while (iterator.hasNext()) {
 
 497                                         final Favorite f = (Favorite) iterator.next();
 
 498                                         MenuItem item = new MenuItem(menu, SWT.NONE);
 
 499                                         item.setText(f.getName());
 
 500                                         item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
 
 501                                         item.addSelectionListener(new SelectionAdapter() {
 
 502                                                 public void widgetSelected(SelectionEvent event) {
 
 508                                 new MenuItem(menu, SWT.SEPARATOR);
 
 511                         iterator = WebBrowserPreference.getInternalWebBrowserFavorites().iterator();
 
 512                         if (!iterator.hasNext()) {
 
 513                                 MenuItem item = new MenuItem(menu, SWT.NONE);
 
 514                                 item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserNoFavorites"));
 
 516                         while (iterator.hasNext()) {
 
 517                                 final Favorite f = (Favorite) iterator.next();
 
 518                                 MenuItem item = new MenuItem(menu, SWT.NONE);
 
 519                                 item.setText(f.getName());
 
 520                                 item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
 
 521                                 item.addSelectionListener(new SelectionAdapter() {
 
 522                                         public void widgetSelected(SelectionEvent event) {
 
 528                         new MenuItem(menu, SWT.SEPARATOR);
 
 530                         MenuItem item = new MenuItem(menu, SWT.NONE);
 
 531                         item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserOrganizeFavorites"));
 
 532                         item.addSelectionListener(new SelectionAdapter() {
 
 533                                 public void widgetSelected(SelectionEvent event) {
 
 534                                         OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(shell);
 
 539                         perspectiveBarMenu = menu;
 
 542                 if (perspectiveBarMenu != null) {
 
 543                         perspectiveBarMenu.setLocation(p.x, p.y);
 
 544                         perspectiveBarMenu.setVisible(true);
 
 549            navigate(WebBrowserPreference.getHomePageURL());
 
 553          * Returns true if the homepage is currently being displayed.
 
 556         protected boolean isHome() {
 
 557                 return getURL() != null && getURL().endsWith(WebBrowserPreference.getHomePageURL().substring(9));
 
 560         protected String getURL() {
 
 561                 return browser.getUrl();
 
 565          * Update the history list to the global copy.
 
 567         protected void updateHistory() {
 
 571                 String temp = combo.getText();
 
 573                         history = WebBrowserPreference.getInternalWebBrowserHistory();
 
 575                 String[] historyList = new String[history.size()];
 
 576                 history.toArray(historyList);
 
 577                 combo.setItems(historyList);