2 * Copyright (c) 2003 IBM Corporation and others. All rights reserved. � This
3 * program and the accompanying materials are made available under the terms of
4 * the Common Public License v1.0 which accompanies this distribution, and is
5 * available at http://www.eclipse.org/legal/cpl-v10.html �* Contributors: IBM -
6 * Initial API and implementation
9 // TODO 1. Handle the sizing of a popup running in shelled out secondary window.
10 // TODO 2. Support printing: waiting on eclipse bug 47937/44823.
11 package net.sourceforge.phpeclipse.webbrowser.internal;
13 import java.util.Iterator;
15 import net.sourceforge.phpeclipse.webbrowser.IURLMap;
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.browser.Browser;
19 import org.eclipse.swt.browser.CloseWindowListener;
20 import org.eclipse.swt.browser.LocationEvent;
21 import org.eclipse.swt.browser.LocationListener;
22 import org.eclipse.swt.browser.OpenWindowListener;
23 import org.eclipse.swt.browser.ProgressEvent;
24 import org.eclipse.swt.browser.ProgressListener;
25 import org.eclipse.swt.browser.StatusTextEvent;
26 import org.eclipse.swt.browser.StatusTextListener;
27 import org.eclipse.swt.browser.TitleEvent;
28 import org.eclipse.swt.browser.TitleListener;
29 import org.eclipse.swt.browser.WindowEvent;
30 import org.eclipse.swt.dnd.Clipboard;
31 import org.eclipse.swt.events.SelectionAdapter;
32 import org.eclipse.swt.events.SelectionEvent;
33 import org.eclipse.swt.graphics.Point;
34 import org.eclipse.swt.graphics.Rectangle;
35 import org.eclipse.swt.layout.FillLayout;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Combo;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.eclipse.swt.widgets.Event;
42 import org.eclipse.swt.widgets.Label;
43 import org.eclipse.swt.widgets.Listener;
44 import org.eclipse.swt.widgets.Menu;
45 import org.eclipse.swt.widgets.MenuItem;
46 import org.eclipse.swt.widgets.ProgressBar;
47 import org.eclipse.swt.widgets.Shell;
48 import org.eclipse.swt.widgets.ToolBar;
49 import org.eclipse.swt.widgets.ToolItem;
50 import org.eclipse.ui.PlatformUI;
52 public class WebBrowser extends Composite {
53 protected Composite toolbarComp;
55 protected Composite statusComp;
57 protected Combo combo;
59 protected Clipboard clipboard;
61 protected boolean showToolbar;
63 protected ToolItem back;
65 protected ToolItem forward;
67 protected ToolItem stop;
69 protected ToolItem favorites;
71 protected ToolItem refresh;
73 protected BusyIndicator busy;
75 protected boolean showStatusbar;
77 protected ProgressBar progress;
79 protected Label status;
81 private static int MAX_HISTORY = 50;
83 protected static java.util.List history;
85 protected Browser browser;
87 protected Shell shell;
89 protected WebBrowserEditor editor;
91 protected String title;
93 public WebBrowser(Composite parent, final boolean showToolbar,
94 final boolean showStatusbar) {
95 super(parent, SWT.NONE);
97 this.showToolbar = showToolbar;
98 this.showStatusbar = showStatusbar;
100 GridLayout layout = new GridLayout();
101 layout.marginHeight = 3;
102 layout.marginWidth = 3;
103 layout.horizontalSpacing = 3;
104 layout.verticalSpacing = 3;
105 layout.numColumns = 1;
107 setLayoutData(new GridData(GridData.FILL_BOTH));
108 clipboard = new Clipboard(parent.getDisplay());
109 PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
110 ContextIds.WEB_BROWSER);
113 toolbarComp = new Composite(this, SWT.NONE);
114 GridLayout outerLayout = new GridLayout();
115 outerLayout.numColumns = 2;
116 outerLayout.marginWidth = 0;
117 outerLayout.marginHeight = 0;
118 toolbarComp.setLayout(outerLayout);
119 toolbarComp.setLayoutData(new GridData(
120 GridData.VERTICAL_ALIGN_BEGINNING
121 | GridData.FILL_HORIZONTAL));
123 // create the top line, with a combo box for history and a "go"
125 Composite top = new Composite(toolbarComp, SWT.NONE);
126 GridLayout topLayout = new GridLayout();
127 topLayout.numColumns = 2;
128 topLayout.marginWidth = 0;
129 topLayout.marginHeight = 0;
130 top.setLayout(topLayout);
131 top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER
132 | GridData.FILL_HORIZONTAL));
134 combo = new Combo(top, SWT.DROP_DOWN);
138 combo.addSelectionListener(new SelectionAdapter() {
139 public void widgetSelected(SelectionEvent we) {
141 if (combo.getSelectionIndex() != -1)
142 setURL(combo.getItem(combo.getSelectionIndex()));
143 } catch (Exception e) {
147 combo.addListener(SWT.DefaultSelection, new Listener() {
148 public void handleEvent(Event e) {
149 setURL(combo.getText());
152 combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
153 PlatformUI.getWorkbench().getHelpSystem().setHelp(combo,
154 ContextIds.WEB_BROWSER_URL);
156 ToolBar toolbar = new ToolBar(top, SWT.FLAT);
157 fillToolBar(toolbar);
159 new ToolItem(toolbar, SWT.SEPARATOR);
161 busy = new BusyIndicator(toolbarComp, SWT.NONE);
162 busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
165 // create a new SWT Web browser widget, checking once again to make sure
166 // we can use it in this environment
167 // if (WebBrowserUtil.canUseInternalWebBrowser() &
168 // WebBrowserUtil.isInternalBrowserOperational())
169 if (WebBrowserUtil.isInternalBrowserOperational())
170 this.browser = new Browser(this, SWT.NONE);
172 WebBrowserUtil.openError(WebBrowserUIPlugin
173 .getResource("%errorCouldNotLaunchInternalWebBrowser"));
178 back.setEnabled(browser.isBackEnabled());
179 forward.setEnabled(browser.isForwardEnabled());
182 PlatformUI.getWorkbench().getHelpSystem().setHelp(browser,
183 ContextIds.WEB_BROWSER_WEB);
184 GridData data = new GridData();
185 data.horizontalAlignment = GridData.FILL;
186 data.verticalAlignment = GridData.FILL;
187 data.horizontalSpan = 3;
188 data.grabExcessHorizontalSpace = true;
189 data.grabExcessVerticalSpace = true;
190 browser.setLayoutData(data);
193 createStatusArea(this);
195 addBrowserListeners();
201 protected void addBrowserListeners() {
203 // respond to Browser StatusTextEvents events by updating the status
205 browser.addStatusTextListener(new StatusTextListener() {
206 public void changed(StatusTextEvent event) {
207 status.setText(event.text);
213 * Add listener for new window creation so that we can instead of
214 * opening a separate new window in which the session is lost, we can
215 * instead open a new window in a new shell within the browser area
216 * thereby maintaining the session.
218 browser.addOpenWindowListener(new OpenWindowListener() {
219 public void open(WindowEvent event) {
220 Shell shell2 = new Shell(getDisplay());
221 shell2.setLayout(new FillLayout());
222 shell2.setText(WebBrowserUIPlugin
223 .getResource("%viewWebBrowserTitle"));
224 shell2.setImage(getShell().getImage());
225 WebBrowser browser2 = new WebBrowser(shell2, showToolbar,
227 browser2.shell = shell2;
228 event.browser = browser2.browser;
233 browser.addCloseWindowListener(new CloseWindowListener() {
234 public void close(WindowEvent event) {
235 // if shell is not null, it must be a secondary popup window,
236 // else its an editor window
240 // #1365431 (toshihiro) editor.closeEditor(); causes NPE
241 if (editor != null) editor.closeEditor();
246 browser.addProgressListener(new ProgressListener() {
247 public void changed(ProgressEvent event) {
248 if (event.total == 0)
251 boolean done = (event.current == event.total);
253 int percentProgress = event.current * 100 / event.total;
256 progress.setSelection(0);
258 progress.setSelection(percentProgress);
263 && (percentProgress > 0 && percentProgress < 100)) {
266 // Once the progress hits 100 percent, done, set busy to
268 else if (busy.isBusy() && done) {
274 public void completed(ProgressEvent event) {
276 progress.setSelection(0);
279 back.setEnabled(browser.isBackEnabled());
280 forward.setEnabled(browser.isForwardEnabled());
286 browser.addLocationListener(new LocationListener() {
287 public void changed(LocationEvent event) {
291 combo.setText(event.location);
292 addToHistory(event.location);
298 public void changing(LocationEvent event) {
303 browser.addTitleListener(new TitleListener() {
304 public void changed(TitleEvent event) {
311 * Return the underlying browser control.
313 * @return org.eclipse.swt.browser.Browser
315 public Browser getBrowser() {
322 protected void forward() {
329 protected void back() {
336 protected void stop() {
343 protected void navigate(String url) {
344 Trace.trace(Trace.FINER, "Navigate: " + url);
345 if (url != null && url.equals(getURL())) {
353 * Refresh the currently viewed page.
355 public void refresh() {
359 protected void setURL(String url, boolean browse) {
360 Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
366 if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
370 Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
371 String newURL = null;
372 while (iterator.hasNext() && newURL == null) {
374 IURLMap map = (IURLMap) iterator.next();
375 newURL = map.getMappedURL(url);
376 } catch (Exception e) {
389 protected void addToHistory(String url) {
391 history = WebBrowserPreference.getInternalWebBrowserHistory();
393 int size = history.size();
394 for (int i = 0; i < size; i++) {
395 String s = (String) history.get(i);
403 if (size >= MAX_HISTORY)
404 history.remove(size - 1);
406 WebBrowserPreference.setInternalWebBrowserHistory(history);
407 } else if (found != 0) {
408 history.remove(found);
410 WebBrowserPreference.setInternalWebBrowserHistory(history);
414 public void setURL(String url) {
419 * Creates the Web browser status area.
421 private void createStatusArea(Composite parent) {
422 Composite composite = new Composite(parent, SWT.NONE);
423 GridLayout layout = new GridLayout();
424 layout.numColumns = 2;
425 layout.marginHeight = 0;
426 layout.marginWidth = 0;
427 layout.horizontalSpacing = 4;
428 layout.verticalSpacing = 0;
429 composite.setLayout(layout);
430 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
432 // Add a label for displaying status messages as they are received from
434 status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
435 GridData gridData = new GridData(GridData.FILL_HORIZONTAL
436 | GridData.VERTICAL_ALIGN_FILL);
437 gridData.horizontalIndent = 2;
438 status.setLayoutData(gridData);
440 // Add a progress bar to display downloading progress information
441 progress = new ProgressBar(composite, SWT.BORDER);
442 gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
443 | GridData.VERTICAL_ALIGN_FILL);
444 gridData.widthHint = 100;
445 gridData.heightHint = 10;
446 progress.setLayoutData(gridData);
452 public void dispose() {
455 showStatusbar = false;
466 * Populate the toolbar.
469 * org.eclipse.swt.widgets.ToolBar
471 private void fillToolBar(final ToolBar toolbar) {
472 ToolItem go = new ToolItem(toolbar, SWT.NONE);
473 go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
474 go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
475 go.setDisabledImage(ImageResource
476 .getImage(ImageResource.IMG_DLCL_NAV_GO));
478 .setToolTipText(WebBrowserUIPlugin
479 .getResource("%actionWebBrowserGo"));
480 go.addSelectionListener(new SelectionAdapter() {
481 public void widgetSelected(SelectionEvent event) {
482 setURL(combo.getText());
486 new ToolItem(toolbar, SWT.SEPARATOR);
488 favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
489 favorites.setImage(ImageResource
490 .getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
491 favorites.setHotImage(ImageResource
492 .getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
493 favorites.setDisabledImage(ImageResource
494 .getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
495 favorites.setToolTipText(WebBrowserUIPlugin
496 .getResource("%actionWebBrowserFavorites"));
498 favorites.addSelectionListener(new SelectionAdapter() {
499 public void widgetSelected(SelectionEvent event) {
500 if (event.detail == SWT.ARROW) {
501 Rectangle r = favorites.getBounds();
502 showFavorites(toolbar, toolbar.toDisplay(r.x, r.y
509 // create back and forward actions
510 back = new ToolItem(toolbar, SWT.NONE);
511 back.setImage(ImageResource
512 .getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
513 back.setHotImage(ImageResource
514 .getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
515 back.setDisabledImage(ImageResource
516 .getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
517 back.setToolTipText(WebBrowserUIPlugin
518 .getResource("%actionWebBrowserBack"));
519 back.addSelectionListener(new SelectionAdapter() {
520 public void widgetSelected(SelectionEvent event) {
525 forward = new ToolItem(toolbar, SWT.NONE);
526 forward.setImage(ImageResource
527 .getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
528 forward.setHotImage(ImageResource
529 .getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
530 forward.setDisabledImage(ImageResource
531 .getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
532 forward.setToolTipText(WebBrowserUIPlugin
533 .getResource("%actionWebBrowserForward"));
534 forward.addSelectionListener(new SelectionAdapter() {
535 public void widgetSelected(SelectionEvent event) {
540 // create refresh, stop, and print actions
541 stop = new ToolItem(toolbar, SWT.NONE);
542 stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
543 stop.setHotImage(ImageResource
544 .getImage(ImageResource.IMG_CLCL_NAV_STOP));
545 stop.setDisabledImage(ImageResource
546 .getImage(ImageResource.IMG_DLCL_NAV_STOP));
547 stop.setToolTipText(WebBrowserUIPlugin
548 .getResource("%actionWebBrowserStop"));
549 stop.addSelectionListener(new SelectionAdapter() {
550 public void widgetSelected(SelectionEvent event) {
555 refresh = new ToolItem(toolbar, SWT.NONE);
556 refresh.setImage(ImageResource
557 .getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
558 refresh.setHotImage(ImageResource
559 .getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
560 refresh.setDisabledImage(ImageResource
561 .getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
562 refresh.setToolTipText(WebBrowserUIPlugin
563 .getResource("%actionWebBrowserRefresh"));
564 refresh.addSelectionListener(new SelectionAdapter() {
565 public void widgetSelected(SelectionEvent event) {
571 protected void addFavorite() {
572 java.util.List list = WebBrowserPreference
573 .getInternalWebBrowserFavorites();
574 Favorite f = new Favorite(title, browser.getUrl());
575 if (!list.contains(f)) {
577 WebBrowserPreference.setInternalWebBrowserFavorites(list);
581 protected void showFavorites(Control parent, Point p) {
582 Menu perspectiveBarMenu = null;
583 if (perspectiveBarMenu == null) {
584 Menu menu = new Menu(parent);
587 Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
588 if (iterator.hasNext()) {
589 while (iterator.hasNext()) {
590 final Favorite f = (Favorite) iterator.next();
591 MenuItem item = new MenuItem(menu, SWT.NONE);
592 item.setText(f.getName());
593 item.setImage(ImageResource
594 .getImage(ImageResource.IMG_FAVORITE));
595 item.addSelectionListener(new SelectionAdapter() {
596 public void widgetSelected(SelectionEvent event) {
602 new MenuItem(menu, SWT.SEPARATOR);
605 iterator = WebBrowserPreference.getInternalWebBrowserFavorites()
607 if (!iterator.hasNext()) {
608 MenuItem item = new MenuItem(menu, SWT.NONE);
609 item.setText(WebBrowserUIPlugin
610 .getResource("%actionWebBrowserNoFavorites"));
612 while (iterator.hasNext()) {
613 final Favorite f = (Favorite) iterator.next();
614 MenuItem item = new MenuItem(menu, SWT.NONE);
615 item.setText(f.getName());
616 item.setImage(ImageResource
617 .getImage(ImageResource.IMG_FAVORITE));
618 item.addSelectionListener(new SelectionAdapter() {
619 public void widgetSelected(SelectionEvent event) {
625 new MenuItem(menu, SWT.SEPARATOR);
627 MenuItem item = new MenuItem(menu, SWT.NONE);
628 item.setText(WebBrowserUIPlugin
629 .getResource("%actionWebBrowserOrganizeFavorites"));
630 item.addSelectionListener(new SelectionAdapter() {
631 public void widgetSelected(SelectionEvent event) {
632 OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(
638 perspectiveBarMenu = menu;
641 if (perspectiveBarMenu != null) {
642 perspectiveBarMenu.setLocation(p.x, p.y);
643 perspectiveBarMenu.setVisible(true);
648 navigate(WebBrowserPreference.getHomePageURL());
652 * Returns true if the homepage is currently being displayed.
656 protected boolean isHome() {
657 return getURL() != null
658 && getURL().endsWith(
659 WebBrowserPreference.getHomePageURL().substring(9));
662 protected String getURL() {
663 return browser.getUrl();
667 * Update the history list to the global copy.
669 protected void updateHistory() {
673 String temp = combo.getText();
675 history = WebBrowserPreference.getInternalWebBrowserHistory();
677 String[] historyList = new String[history.size()];
678 history.toArray(historyList);
679 combo.setItems(historyList);
684 public void addProgressListener(ProgressListener listener) {
685 browser.addProgressListener(listener);
688 public void addStatusTextListener(StatusTextListener listener) {
689 browser.addStatusTextListener(listener);
692 public void addTitleListener(TitleListener listener) {
693 browser.addTitleListener(listener);