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;
11 import java.util.Iterator;
13 import net.sourceforge.phpeclipse.webbrowser.IURLMap;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.browser.Browser;
17 import org.eclipse.swt.browser.CloseWindowListener;
18 import org.eclipse.swt.browser.LocationEvent;
19 import org.eclipse.swt.browser.LocationListener;
20 import org.eclipse.swt.browser.OpenWindowListener;
21 import org.eclipse.swt.browser.ProgressEvent;
22 import org.eclipse.swt.browser.ProgressListener;
23 import org.eclipse.swt.browser.StatusTextEvent;
24 import org.eclipse.swt.browser.StatusTextListener;
25 import org.eclipse.swt.browser.TitleEvent;
26 import org.eclipse.swt.browser.TitleListener;
27 import org.eclipse.swt.browser.WindowEvent;
28 import org.eclipse.swt.dnd.Clipboard;
29 import org.eclipse.swt.events.SelectionAdapter;
30 import org.eclipse.swt.events.SelectionEvent;
31 import org.eclipse.swt.graphics.Point;
32 import org.eclipse.swt.graphics.Rectangle;
33 import org.eclipse.swt.layout.FillLayout;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Combo;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.swt.widgets.Event;
40 import org.eclipse.swt.widgets.Label;
41 import org.eclipse.swt.widgets.Listener;
42 import org.eclipse.swt.widgets.Menu;
43 import org.eclipse.swt.widgets.MenuItem;
44 import org.eclipse.swt.widgets.ProgressBar;
45 import org.eclipse.swt.widgets.Shell;
46 import org.eclipse.swt.widgets.ToolBar;
47 import org.eclipse.swt.widgets.ToolItem;
48 import org.eclipse.ui.help.WorkbenchHelp;
50 public class WebBrowser extends Composite {
51 protected Composite toolbarComp;
53 protected Composite statusComp;
55 protected Combo combo;
57 protected Clipboard clipboard;
59 protected boolean showToolbar;
61 protected ToolItem back;
63 protected ToolItem forward;
65 protected ToolItem stop;
67 protected ToolItem favorites;
69 protected ToolItem refresh;
71 protected BusyIndicator busy;
73 protected boolean showStatusbar;
75 protected ProgressBar progress;
77 protected Label status;
79 private static int MAX_HISTORY = 50;
81 protected static java.util.List history;
83 protected Browser browser;
85 protected Shell shell;
87 protected WebBrowserEditor editor;
89 protected String title;
91 public WebBrowser(Composite parent, final boolean showToolbar, final boolean showStatusbar) {
92 super(parent, SWT.NONE);
94 this.showToolbar = showToolbar;
95 this.showStatusbar = showStatusbar;
97 GridLayout layout = new GridLayout();
98 layout.marginHeight = 3;
99 layout.marginWidth = 3;
100 layout.horizontalSpacing = 3;
101 layout.verticalSpacing = 3;
102 layout.numColumns = 1;
104 setLayoutData(new GridData(GridData.FILL_BOTH));
105 clipboard = new Clipboard(parent.getDisplay());
106 WorkbenchHelp.setHelp(this, ContextIds.WEB_BROWSER);
109 toolbarComp = new Composite(this, SWT.NONE);
110 GridLayout outerLayout = new GridLayout();
111 outerLayout.numColumns = 2;
112 outerLayout.marginWidth = 0;
113 outerLayout.marginHeight = 0;
114 toolbarComp.setLayout(outerLayout);
115 toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
117 // create the top line, with a combo box for history and a "go" button
118 Composite top = new Composite(toolbarComp, SWT.NONE);
119 GridLayout topLayout = new GridLayout();
120 topLayout.numColumns = 2;
121 topLayout.marginWidth = 0;
122 topLayout.marginHeight = 0;
123 top.setLayout(topLayout);
124 top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL));
126 combo = new Combo(top, SWT.DROP_DOWN);
130 combo.addSelectionListener(new SelectionAdapter() {
131 public void widgetSelected(SelectionEvent we) {
133 if (combo.getSelectionIndex() != -1)
134 setURL(combo.getItem(combo.getSelectionIndex()));
135 } catch (Exception e) {
139 combo.addListener(SWT.DefaultSelection, new Listener() {
140 public void handleEvent(Event e) {
141 setURL(combo.getText());
144 combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
145 WorkbenchHelp.setHelp(combo, ContextIds.WEB_BROWSER_URL);
147 ToolBar toolbar = new ToolBar(top, SWT.FLAT);
148 fillToolBar(toolbar);
150 new ToolItem(toolbar, SWT.SEPARATOR);
152 busy = new BusyIndicator(toolbarComp, SWT.NONE);
153 busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
156 // create a new SWT Web browser widget, checking once again to make sure we can use it in this environment
157 // if (WebBrowserUtil.canUseInternalWebBrowser() & WebBrowserUtil.isInternalBrowserOperational())
158 if (WebBrowserUtil.isInternalBrowserOperational())
159 this.browser = new Browser(this, SWT.NONE);
161 WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchInternalWebBrowser"));
166 back.setEnabled(browser.isBackEnabled());
167 forward.setEnabled(browser.isForwardEnabled());
170 WorkbenchHelp.setHelp(browser, ContextIds.WEB_BROWSER_WEB);
171 GridData data = new GridData();
172 data.horizontalAlignment = GridData.FILL;
173 data.verticalAlignment = GridData.FILL;
174 data.horizontalSpan = 3;
175 data.grabExcessHorizontalSpace = true;
176 data.grabExcessVerticalSpace = true;
177 browser.setLayoutData(data);
180 createStatusArea(this);
182 addBrowserListeners();
188 protected void addBrowserListeners() {
190 // respond to Browser StatusTextEvents events by updating the status Text label
191 browser.addStatusTextListener(new StatusTextListener() {
192 public void changed(StatusTextEvent event) {
193 status.setText(event.text);
199 * Add listener for new window creation so that we can instead of opening a separate new window in which the session is lost, we
200 * can instead open a new window in a new shell within the browser area thereby maintaining the session.
202 browser.addOpenWindowListener(new OpenWindowListener() {
203 public void open(WindowEvent event) {
204 Shell shell2 = new Shell(getDisplay());
205 shell2.setLayout(new FillLayout());
206 shell2.setText(WebBrowserUIPlugin.getResource("%viewWebBrowserTitle"));
207 shell2.setImage(getShell().getImage());
208 WebBrowser browser2 = new WebBrowser(shell2, showToolbar, showStatusbar);
209 browser2.shell = shell2;
210 event.browser = browser2.browser;
215 browser.addCloseWindowListener(new CloseWindowListener() {
216 public void close(WindowEvent event) {
217 // if shell is not null, it must be a secondary popup window, else its an editor window
221 editor.closeEditor();
225 browser.addProgressListener(new ProgressListener() {
226 public void changed(ProgressEvent event) {
227 if (event.total == 0)
230 boolean done = (event.current == event.total);
232 int percentProgress = event.current * 100 / event.total;
235 progress.setSelection(0);
237 progress.setSelection(percentProgress);
241 if (!busy.isBusy() && (percentProgress > 0 && percentProgress < 100)) {
244 // Once the progress hits 100 percent, done, set busy to false
245 else if (busy.isBusy() && done) {
251 public void completed(ProgressEvent event) {
253 progress.setSelection(0);
256 back.setEnabled(browser.isBackEnabled());
257 forward.setEnabled(browser.isForwardEnabled());
263 browser.addLocationListener(new LocationListener() {
264 public void changed(LocationEvent event) {
268 combo.setText(event.location);
269 addToHistory(event.location);
275 public void changing(LocationEvent event) {
280 browser.addTitleListener(new TitleListener() {
281 public void changed(TitleEvent event) {
288 * Return the underlying browser control.
290 * @return org.eclipse.swt.browser.Browser
292 public Browser getBrowser() {
299 protected void forward() {
306 protected void back() {
313 protected void stop() {
320 protected void navigate(String url) {
321 Trace.trace(Trace.FINER, "Navigate: " + url);
322 if (url != null && url.equals(getURL())) {
330 * Refresh the currently viewed page.
332 public void refresh() {
336 protected void setURL(String url, boolean browse) {
337 Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
343 if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
347 Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
348 String newURL = null;
349 while (iterator.hasNext() && newURL == null) {
351 IURLMap map = (IURLMap) iterator.next();
352 newURL = map.getMappedURL(url);
353 } catch (Exception e) {
366 protected void addToHistory(String url) {
368 history = WebBrowserPreference.getInternalWebBrowserHistory();
370 int size = history.size();
371 for (int i = 0; i < size; i++) {
372 String s = (String) history.get(i);
380 if (size >= MAX_HISTORY)
381 history.remove(size - 1);
383 WebBrowserPreference.setInternalWebBrowserHistory(history);
384 } else if (found != 0) {
385 history.remove(found);
387 WebBrowserPreference.setInternalWebBrowserHistory(history);
391 public void setURL(String url) {
396 * Creates the Web browser status area.
398 private void createStatusArea(Composite parent) {
399 Composite composite = new Composite(parent, SWT.NONE);
400 GridLayout layout = new GridLayout();
401 layout.numColumns = 2;
402 layout.marginHeight = 0;
403 layout.marginWidth = 0;
404 layout.horizontalSpacing = 4;
405 layout.verticalSpacing = 0;
406 composite.setLayout(layout);
407 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
409 // Add a label for displaying status messages as they are received from the control
410 status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
411 GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
412 gridData.horizontalIndent = 2;
413 status.setLayoutData(gridData);
415 // Add a progress bar to display downloading progress information
416 progress = new ProgressBar(composite, SWT.BORDER);
417 gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL);
418 gridData.widthHint = 100;
419 gridData.heightHint = 10;
420 progress.setLayoutData(gridData);
426 public void dispose() {
429 showStatusbar = false;
440 * Populate the toolbar.
443 * org.eclipse.swt.widgets.ToolBar
445 private void fillToolBar(final ToolBar toolbar) {
446 ToolItem go = new ToolItem(toolbar, SWT.NONE);
447 go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
448 go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
449 go.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_GO));
450 go.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserGo"));
451 go.addSelectionListener(new SelectionAdapter() {
452 public void widgetSelected(SelectionEvent event) {
453 setURL(combo.getText());
457 new ToolItem(toolbar, SWT.SEPARATOR);
459 favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
460 favorites.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
461 favorites.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
462 favorites.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
463 favorites.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserFavorites"));
465 favorites.addSelectionListener(new SelectionAdapter() {
466 public void widgetSelected(SelectionEvent event) {
467 if (event.detail == SWT.ARROW) {
468 Rectangle r = favorites.getBounds();
469 showFavorites(toolbar, toolbar.toDisplay(r.x, r.y + r.height));
475 // create back and forward actions
476 back = new ToolItem(toolbar, SWT.NONE);
477 back.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
478 back.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
479 back.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
480 back.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserBack"));
481 back.addSelectionListener(new SelectionAdapter() {
482 public void widgetSelected(SelectionEvent event) {
487 forward = new ToolItem(toolbar, SWT.NONE);
488 forward.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
489 forward.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
490 forward.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
491 forward.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserForward"));
492 forward.addSelectionListener(new SelectionAdapter() {
493 public void widgetSelected(SelectionEvent event) {
498 // create refresh, stop, and print actions
499 stop = new ToolItem(toolbar, SWT.NONE);
500 stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
501 stop.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_STOP));
502 stop.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_STOP));
503 stop.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserStop"));
504 stop.addSelectionListener(new SelectionAdapter() {
505 public void widgetSelected(SelectionEvent event) {
510 refresh = new ToolItem(toolbar, SWT.NONE);
511 refresh.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
512 refresh.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
513 refresh.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
514 refresh.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserRefresh"));
515 refresh.addSelectionListener(new SelectionAdapter() {
516 public void widgetSelected(SelectionEvent event) {
522 protected void addFavorite() {
523 java.util.List list = WebBrowserPreference.getInternalWebBrowserFavorites();
524 Favorite f = new Favorite(title, browser.getUrl());
525 if (!list.contains(f)) {
527 WebBrowserPreference.setInternalWebBrowserFavorites(list);
531 protected void showFavorites(Control parent, Point p) {
532 Menu perspectiveBarMenu = null;
533 if (perspectiveBarMenu == null) {
534 Menu menu = new Menu(parent);
537 Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
538 if (iterator.hasNext()) {
539 while (iterator.hasNext()) {
540 final Favorite f = (Favorite) iterator.next();
541 MenuItem item = new MenuItem(menu, SWT.NONE);
542 item.setText(f.getName());
543 item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
544 item.addSelectionListener(new SelectionAdapter() {
545 public void widgetSelected(SelectionEvent event) {
551 new MenuItem(menu, SWT.SEPARATOR);
554 iterator = WebBrowserPreference.getInternalWebBrowserFavorites().iterator();
555 if (!iterator.hasNext()) {
556 MenuItem item = new MenuItem(menu, SWT.NONE);
557 item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserNoFavorites"));
559 while (iterator.hasNext()) {
560 final Favorite f = (Favorite) iterator.next();
561 MenuItem item = new MenuItem(menu, SWT.NONE);
562 item.setText(f.getName());
563 item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
564 item.addSelectionListener(new SelectionAdapter() {
565 public void widgetSelected(SelectionEvent event) {
571 new MenuItem(menu, SWT.SEPARATOR);
573 MenuItem item = new MenuItem(menu, SWT.NONE);
574 item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserOrganizeFavorites"));
575 item.addSelectionListener(new SelectionAdapter() {
576 public void widgetSelected(SelectionEvent event) {
577 OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(shell);
582 perspectiveBarMenu = menu;
585 if (perspectiveBarMenu != null) {
586 perspectiveBarMenu.setLocation(p.x, p.y);
587 perspectiveBarMenu.setVisible(true);
592 navigate(WebBrowserPreference.getHomePageURL());
596 * Returns true if the homepage is currently being displayed.
600 protected boolean isHome() {
601 return getURL() != null && getURL().endsWith(WebBrowserPreference.getHomePageURL().substring(9));
604 protected String getURL() {
605 return browser.getUrl();
609 * Update the history list to the global copy.
611 protected void updateHistory() {
615 String temp = combo.getText();
617 history = WebBrowserPreference.getInternalWebBrowserHistory();
619 String[] historyList = new String[history.size()];
620 history.toArray(historyList);
621 combo.setItems(historyList);
626 public void addProgressListener(ProgressListener listener) {
627 browser.addProgressListener(listener);
630 public void addStatusTextListener(StatusTextListener listener) {
631 browser.addStatusTextListener(listener);
634 public void addTitleListener(TitleListener listener) {
635 browser.addTitleListener(listener);