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()),
144 } catch (Exception e) {
148 combo.addListener(SWT.DefaultSelection, new Listener() {
149 public void handleEvent(Event e) {
150 setURL(combo.getText());
153 combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
154 PlatformUI.getWorkbench().getHelpSystem().setHelp(combo,
155 ContextIds.WEB_BROWSER_URL);
157 ToolBar toolbar = new ToolBar(top, SWT.FLAT);
158 fillToolBar(toolbar);
160 new ToolItem(toolbar, SWT.SEPARATOR);
162 busy = new BusyIndicator(toolbarComp, SWT.NONE);
163 busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
166 // create a new SWT Web browser widget, checking once again to make sure
167 // we can use it in this environment
168 // if (WebBrowserUtil.canUseInternalWebBrowser() &
169 // WebBrowserUtil.isInternalBrowserOperational())
170 if (WebBrowserUtil.isInternalBrowserOperational())
171 this.browser = new Browser(this, SWT.NONE);
173 WebBrowserUtil.openError(WebBrowserUIPlugin
174 .getResource("%errorCouldNotLaunchInternalWebBrowser"));
179 back.setEnabled(browser.isBackEnabled());
180 forward.setEnabled(browser.isForwardEnabled());
183 PlatformUI.getWorkbench().getHelpSystem().setHelp(browser,
184 ContextIds.WEB_BROWSER_WEB);
185 GridData data = new GridData();
186 data.horizontalAlignment = GridData.FILL;
187 data.verticalAlignment = GridData.FILL;
188 data.horizontalSpan = 3;
189 data.grabExcessHorizontalSpace = true;
190 data.grabExcessVerticalSpace = true;
191 browser.setLayoutData(data);
194 createStatusArea(this);
196 addBrowserListeners();
202 protected void addBrowserListeners() {
204 // respond to Browser StatusTextEvents events by updating the status
206 browser.addStatusTextListener(new StatusTextListener() {
207 public void changed(StatusTextEvent event) {
208 status.setText(event.text);
214 * Add listener for new window creation so that we can instead of
215 * opening a separate new window in which the session is lost, we can
216 * instead open a new window in a new shell within the browser area
217 * thereby maintaining the session.
219 browser.addOpenWindowListener(new OpenWindowListener() {
220 public void open(WindowEvent event) {
221 Shell shell2 = new Shell(getDisplay());
222 shell2.setLayout(new FillLayout());
223 shell2.setText(WebBrowserUIPlugin
224 .getResource("%viewWebBrowserTitle"));
225 shell2.setImage(getShell().getImage());
226 WebBrowser browser2 = new WebBrowser(shell2, showToolbar,
228 browser2.shell = shell2;
229 event.browser = browser2.browser;
234 browser.addCloseWindowListener(new CloseWindowListener() {
235 public void close(WindowEvent event) {
236 // if shell is not null, it must be a secondary popup window,
237 // else its an editor window
241 // #1365431 (toshihiro) editor.closeEditor(); causes NPE
243 editor.closeEditor();
248 browser.addProgressListener(new ProgressListener() {
249 public void changed(ProgressEvent event) {
250 if (event.total == 0)
253 boolean done = (event.current == event.total);
255 int percentProgress = event.current * 100 / event.total;
258 progress.setSelection(0);
260 progress.setSelection(percentProgress);
265 && (percentProgress > 0 && percentProgress < 100)) {
268 // Once the progress hits 100 percent, done, set busy to
270 else if (busy.isBusy() && done) {
276 public void completed(ProgressEvent event) {
278 progress.setSelection(0);
281 back.setEnabled(browser.isBackEnabled());
282 forward.setEnabled(browser.isForwardEnabled());
288 browser.addLocationListener(new LocationListener() {
289 public void changed(LocationEvent event) {
293 combo.setText(event.location);
294 addToHistory(event.location);
300 public void changing(LocationEvent event) {
305 browser.addTitleListener(new TitleListener() {
306 public void changed(TitleEvent event) {
313 * Return the underlying browser control.
315 * @return org.eclipse.swt.browser.Browser
317 public Browser getBrowser() {
324 protected void forward() {
331 protected void back() {
338 protected void stop() {
345 protected void navigate(String url) {
346 Trace.trace(Trace.FINER, "Navigate: " + url);
347 if (url != null && url.equals(getURL())) {
355 * Refresh the currently viewed page.
357 public void refresh() {
361 protected void setURL(String url, boolean browse) {
362 Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
368 if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
372 Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
373 String newURL = null;
374 while (iterator.hasNext() && newURL == null) {
376 IURLMap map = (IURLMap) iterator.next();
377 newURL = map.getMappedURL(url);
378 } catch (Exception e) {
392 protected void addToHistory(String url) {
394 history = WebBrowserPreference.getInternalWebBrowserHistory();
396 int size = history.size();
397 for (int i = 0; i < size; i++) {
398 String s = (String) history.get(i);
406 if (size >= MAX_HISTORY)
407 history.remove(size - 1);
409 WebBrowserPreference.setInternalWebBrowserHistory(history);
410 } else if (found != 0) {
411 history.remove(found);
413 WebBrowserPreference.setInternalWebBrowserHistory(history);
417 public void setURL(String url) {
422 * Creates the Web browser status area.
424 private void createStatusArea(Composite parent) {
425 Composite composite = new Composite(parent, SWT.NONE);
426 GridLayout layout = new GridLayout();
427 layout.numColumns = 2;
428 layout.marginHeight = 0;
429 layout.marginWidth = 0;
430 layout.horizontalSpacing = 4;
431 layout.verticalSpacing = 0;
432 composite.setLayout(layout);
433 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
435 // Add a label for displaying status messages as they are received from
437 status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
438 GridData gridData = new GridData(GridData.FILL_HORIZONTAL
439 | GridData.VERTICAL_ALIGN_FILL);
440 gridData.horizontalIndent = 2;
441 status.setLayoutData(gridData);
443 // Add a progress bar to display downloading progress information
444 progress = new ProgressBar(composite, SWT.BORDER);
445 gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
446 | GridData.VERTICAL_ALIGN_FILL);
447 gridData.widthHint = 100;
448 gridData.heightHint = 10;
449 progress.setLayoutData(gridData);
455 public void dispose() {
458 showStatusbar = false;
469 * Populate the toolbar.
472 * org.eclipse.swt.widgets.ToolBar
474 private void fillToolBar(final ToolBar toolbar) {
475 ToolItem go = new ToolItem(toolbar, SWT.NONE);
476 go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
477 go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
478 go.setDisabledImage(ImageResource
479 .getImage(ImageResource.IMG_DLCL_NAV_GO));
481 .setToolTipText(WebBrowserUIPlugin
482 .getResource("%actionWebBrowserGo"));
483 go.addSelectionListener(new SelectionAdapter() {
484 public void widgetSelected(SelectionEvent event) {
485 setURL(combo.getText());
489 new ToolItem(toolbar, SWT.SEPARATOR);
491 favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
492 favorites.setImage(ImageResource
493 .getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
494 favorites.setHotImage(ImageResource
495 .getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
496 favorites.setDisabledImage(ImageResource
497 .getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
498 favorites.setToolTipText(WebBrowserUIPlugin
499 .getResource("%actionWebBrowserFavorites"));
501 favorites.addSelectionListener(new SelectionAdapter() {
502 public void widgetSelected(SelectionEvent event) {
503 if (event.detail == SWT.ARROW) {
504 Rectangle r = favorites.getBounds();
505 showFavorites(toolbar, toolbar.toDisplay(r.x, r.y
512 // create back and forward actions
513 back = new ToolItem(toolbar, SWT.NONE);
514 back.setImage(ImageResource
515 .getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
516 back.setHotImage(ImageResource
517 .getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
518 back.setDisabledImage(ImageResource
519 .getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
520 back.setToolTipText(WebBrowserUIPlugin
521 .getResource("%actionWebBrowserBack"));
522 back.addSelectionListener(new SelectionAdapter() {
523 public void widgetSelected(SelectionEvent event) {
528 forward = new ToolItem(toolbar, SWT.NONE);
529 forward.setImage(ImageResource
530 .getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
531 forward.setHotImage(ImageResource
532 .getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
533 forward.setDisabledImage(ImageResource
534 .getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
535 forward.setToolTipText(WebBrowserUIPlugin
536 .getResource("%actionWebBrowserForward"));
537 forward.addSelectionListener(new SelectionAdapter() {
538 public void widgetSelected(SelectionEvent event) {
543 // create refresh, stop, and print actions
544 stop = new ToolItem(toolbar, SWT.NONE);
545 stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
546 stop.setHotImage(ImageResource
547 .getImage(ImageResource.IMG_CLCL_NAV_STOP));
548 stop.setDisabledImage(ImageResource
549 .getImage(ImageResource.IMG_DLCL_NAV_STOP));
550 stop.setToolTipText(WebBrowserUIPlugin
551 .getResource("%actionWebBrowserStop"));
552 stop.addSelectionListener(new SelectionAdapter() {
553 public void widgetSelected(SelectionEvent event) {
558 refresh = new ToolItem(toolbar, SWT.NONE);
559 refresh.setImage(ImageResource
560 .getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
561 refresh.setHotImage(ImageResource
562 .getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
563 refresh.setDisabledImage(ImageResource
564 .getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
565 refresh.setToolTipText(WebBrowserUIPlugin
566 .getResource("%actionWebBrowserRefresh"));
567 refresh.addSelectionListener(new SelectionAdapter() {
568 public void widgetSelected(SelectionEvent event) {
574 protected void addFavorite() {
575 java.util.List list = WebBrowserPreference
576 .getInternalWebBrowserFavorites();
577 Favorite f = new Favorite(title, browser.getUrl());
578 if (!list.contains(f)) {
580 WebBrowserPreference.setInternalWebBrowserFavorites(list);
584 protected void showFavorites(Control parent, Point p) {
585 Menu perspectiveBarMenu = null;
586 if (perspectiveBarMenu == null) {
587 Menu menu = new Menu(parent);
590 Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
591 if (iterator.hasNext()) {
592 while (iterator.hasNext()) {
593 final Favorite f = (Favorite) iterator.next();
594 MenuItem item = new MenuItem(menu, SWT.NONE);
595 item.setText(f.getName());
596 item.setImage(ImageResource
597 .getImage(ImageResource.IMG_FAVORITE));
598 item.addSelectionListener(new SelectionAdapter() {
599 public void widgetSelected(SelectionEvent event) {
605 new MenuItem(menu, SWT.SEPARATOR);
608 iterator = WebBrowserPreference.getInternalWebBrowserFavorites()
610 if (!iterator.hasNext()) {
611 MenuItem item = new MenuItem(menu, SWT.NONE);
612 item.setText(WebBrowserUIPlugin
613 .getResource("%actionWebBrowserNoFavorites"));
615 while (iterator.hasNext()) {
616 final Favorite f = (Favorite) iterator.next();
617 MenuItem item = new MenuItem(menu, SWT.NONE);
618 item.setText(f.getName());
619 item.setImage(ImageResource
620 .getImage(ImageResource.IMG_FAVORITE));
621 item.addSelectionListener(new SelectionAdapter() {
622 public void widgetSelected(SelectionEvent event) {
628 new MenuItem(menu, SWT.SEPARATOR);
630 MenuItem item = new MenuItem(menu, SWT.NONE);
631 item.setText(WebBrowserUIPlugin
632 .getResource("%actionWebBrowserOrganizeFavorites"));
633 item.addSelectionListener(new SelectionAdapter() {
634 public void widgetSelected(SelectionEvent event) {
635 OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(
641 perspectiveBarMenu = menu;
644 if (perspectiveBarMenu != null) {
645 perspectiveBarMenu.setLocation(p.x, p.y);
646 perspectiveBarMenu.setVisible(true);
651 navigate(WebBrowserPreference.getHomePageURL());
655 * Returns true if the homepage is currently being displayed.
659 protected boolean isHome() {
660 return getURL() != null
661 && getURL().endsWith(
662 WebBrowserPreference.getHomePageURL().substring(9));
665 protected String getURL() {
666 return browser.getUrl();
670 * Update the history list to the global copy.
672 protected void updateHistory() {
676 String temp = combo.getText();
678 history = WebBrowserPreference.getInternalWebBrowserHistory();
680 String[] historyList = new String[history.size()];
681 history.toArray(historyList);
682 combo.setItems(historyList);
687 public void addProgressListener(ProgressListener listener) {
688 browser.addProgressListener(listener);
691 public void addStatusTextListener(StatusTextListener listener) {
692 browser.addStatusTextListener(listener);
695 public void addTitleListener(TitleListener listener) {
696 browser.addTitleListener(listener);