Initial version from the webtools project; sligthly modified for phpeclipse
[phpeclipse.git] / net.sourceforge.phpeclipse.webbrowser / src / org / eclipse / webbrowser / internal / WebBrowser.java
1 /**
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
7  *
8  * Contributors:
9  *    IBM - Initial API and implementation
10  */
11
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.
14
15 package org.eclipse.webbrowser.internal;
16
17 import java.util.*;
18 import org.eclipse.webbrowser.IURLMap;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.widgets.*;
21 import org.eclipse.swt.layout.FillLayout;
22 import org.eclipse.swt.layout.GridData;
23 import org.eclipse.swt.layout.GridLayout;
24 import org.eclipse.swt.dnd.Clipboard;
25 import org.eclipse.swt.events.*;
26 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.swt.graphics.Rectangle;
28 import org.eclipse.ui.help.WorkbenchHelp;
29 import org.eclipse.swt.browser.*;
30
31 public class WebBrowser extends Composite {
32         protected Composite toolbarComp;
33         protected Composite statusComp;
34         protected Combo combo;
35         protected Clipboard clipboard;
36         protected boolean showToolbar;
37         protected ToolItem back;
38         protected ToolItem forward;
39         protected ToolItem stop;
40         protected ToolItem favorites;
41         protected ToolItem refresh;
42         protected BusyIndicator busy;
43         protected boolean showStatusbar;
44         protected ProgressBar progress;
45         protected Label status;
46         private static int MAX_HISTORY = 50;
47         protected static java.util.List history;
48         protected Browser browser; 
49         protected Shell shell;
50         protected WebBrowserEditor editor;
51         protected String title;
52         
53         public WebBrowser(Composite parent, final boolean showToolbar, final boolean showStatusbar) {
54                 super(parent, SWT.NONE);
55
56                 this.showToolbar = showToolbar;
57                 this.showStatusbar = showStatusbar;     
58
59                 GridLayout layout = new GridLayout();
60                 layout.marginHeight = 3;
61                 layout.marginWidth = 3;
62                 layout.horizontalSpacing = 3;
63                 layout.verticalSpacing = 3;
64                 layout.numColumns = 1;
65                 setLayout(layout);
66                 setLayoutData(new GridData(GridData.FILL_BOTH));
67                 clipboard = new Clipboard(parent.getDisplay());
68                 WorkbenchHelp.setHelp(this, ContextIds.WEB_BROWSER);
69                 
70                 if (showToolbar) {
71                         toolbarComp = new Composite(this, SWT.NONE);
72                         GridLayout outerLayout = new GridLayout();
73                         outerLayout.numColumns = 2;
74                         outerLayout.marginWidth = 0;
75                         outerLayout.marginHeight = 0;
76                         toolbarComp.setLayout(outerLayout);
77                         toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
78                         
79                         // create the top line, with a combo box for history and a "go" button
80                         Composite top = new Composite(toolbarComp, SWT.NONE);
81                         GridLayout topLayout = new GridLayout();
82                         topLayout.numColumns = 2;
83                         topLayout.marginWidth = 0;
84                         topLayout.marginHeight = 0;
85                         top.setLayout(topLayout);
86                         top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL));
87                         
88                         combo = new Combo(top, SWT.DROP_DOWN);
89                         
90                         updateHistory();
91                         
92                         combo.addSelectionListener(new SelectionAdapter() {
93                                 public void widgetSelected(SelectionEvent we) {
94                                         try {
95                                                 if (combo.getSelectionIndex() != -1)
96                                                         setURL(combo.getItem(combo.getSelectionIndex()));
97                                         } catch (Exception e) { }
98                                 }
99                         });
100                         combo.addListener(SWT.DefaultSelection, new Listener() {
101                                 public void handleEvent(Event e) {
102                                         setURL(combo.getText());
103                                 }
104                         });
105                         combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
106                         WorkbenchHelp.setHelp(combo, ContextIds.WEB_BROWSER_URL);
107                         
108                         ToolBar toolbar = new ToolBar(top, SWT.FLAT);
109                         fillToolBar(toolbar);
110                         
111                         new ToolItem(toolbar, SWT.SEPARATOR);
112                         
113                         busy = new BusyIndicator(toolbarComp, SWT.NONE);
114                         busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
115                 }
116
117                 // create a new SWT Web browser widget, checking once again to make sure we can use it in this environment
118                 if (WebBrowserUtil.canUseInternalWebBrowser() & WebBrowserUtil.isInternalBrowserOperational())
119                         this.browser = new Browser(this, SWT.NONE);
120                 else {
121                         WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchInternalWebBrowser"));
122                         return;
123                 }
124                 
125                 if (showToolbar) {
126                         back.setEnabled(browser.isBackEnabled());
127                         forward.setEnabled(browser.isForwardEnabled());
128                 }
129
130                 WorkbenchHelp.setHelp(browser, ContextIds.WEB_BROWSER_WEB);
131                 GridData data = new GridData();
132                 data.horizontalAlignment = GridData.FILL;
133                 data.verticalAlignment = GridData.FILL;
134                 data.horizontalSpan = 3;
135                 data.grabExcessHorizontalSpace = true;
136                 data.grabExcessVerticalSpace = true;
137                 browser.setLayoutData(data);
138                 
139                 if (showStatusbar)
140                         createStatusArea(this);
141                 
142                 addBrowserListeners();
143         }
144         /**
145          *
146          */
147         protected void addBrowserListeners() {  
148                 if (showStatusbar) {
149                         // respond to Browser StatusTextEvents events by updating the status Text label
150                         browser.addStatusTextListener(new StatusTextListener() {
151                                 public void changed(StatusTextEvent event) {
152                                         status.setText(event.text);     
153                                 }
154                         });
155                 }
156
157                 /** Add listener for new window creation so that we can instead of opening a separate
158                  *  new window in which the session is lost, we can instead open a new window in a new
159                  *  shell within the browser area thereby maintaining the session.
160                  */
161                 browser.addOpenWindowListener(new OpenWindowListener() {
162                         public void open(WindowEvent event) {
163                                 Shell shell2 = new Shell(getDisplay());
164                                 shell2.setLayout(new FillLayout());
165                                 shell2.setText(WebBrowserUIPlugin.getResource("%viewWebBrowserTitle"));
166                                 shell2.setImage(getShell().getImage());
167                                 WebBrowser browser2 = new WebBrowser(shell2, showToolbar, showStatusbar);
168                                 browser2.shell = shell2;
169                                 event.browser = browser2.browser;
170                                 shell2.open();
171                         }
172                 });
173                 
174                 browser.addCloseWindowListener(new CloseWindowListener(){
175                         public void close(WindowEvent event) {
176                                 // if shell is not null, it must be a secondary popup window, else its an editor window
177                                 if (shell != null)
178                                         shell.dispose();
179                                 else
180                                         editor.closeEditor();
181                         }
182                 });
183                 
184                 browser.addProgressListener(new ProgressListener() {
185                         public void changed(ProgressEvent event) {
186                                 if (event.total == 0)
187                                         return;
188                                 
189                                 boolean done = (event.current == event.total);
190
191                                 int percentProgress = event.current * 100 / event.total;
192                                 if (showStatusbar) {
193                                         if (done)
194                                                 progress.setSelection(0);
195                                         else
196                                                 progress.setSelection(percentProgress);
197                                 }
198                                 
199                                 if (showToolbar) {
200                                         if (!busy.isBusy() && (percentProgress > 0 && percentProgress < 100)) {
201                                                 busy.setBusy(true);
202                                         }
203                                         // Once the progress hits 100 percent, done, set busy to false
204                                         else if (busy.isBusy() && done) {
205                                                 busy.setBusy(false);
206                                         }
207                                 }
208                         }
209                         
210                         public void completed(ProgressEvent event) {
211                                 if (showStatusbar)
212                                         progress.setSelection(0);
213                                 if (showToolbar) {
214                                         busy.setBusy(false);
215                                         back.setEnabled(browser.isBackEnabled());
216                                         forward.setEnabled(browser.isForwardEnabled());
217                                 }
218                         }
219                 });
220
221                 if (showToolbar) {
222                         browser.addLocationListener(new LocationListener() {
223                                 public void changed(LocationEvent event) {
224                                         if (!event.top)
225                                                 return;
226                                         if (!isHome()) {
227                                                 combo.setText(event.location);
228                                                 addToHistory(event.location);
229                                                 updateHistory();
230                                         } else
231                                                 combo.setText("");
232                                 }
233                                 
234                                 public void changing(LocationEvent event) { }
235                         });
236                 }
237                 
238                 browser.addTitleListener(new TitleListener() {
239                         public void changed(TitleEvent event) {
240                                 title = event.title;
241                         }
242                 });
243         }
244
245         /**
246          * Return the underlying browser control.
247          * 
248          * @return org.eclipse.swt.browser.Browser
249          */
250         public Browser getBrowser() {
251                 return browser;
252         }
253
254         /**
255          * 
256          */
257         protected void forward() {
258                 browser.forward();
259         }
260
261         /**
262          * 
263          */
264         protected void back() {
265                 browser.back();
266         }
267         
268         /**
269          * 
270          */
271         protected void stop() {
272                 browser.stop();
273         }
274
275         /**
276          * 
277          */
278         protected void navigate(String url) {
279                 Trace.trace(Trace.FINER, "Navigate: " + url);
280                 if (url != null && url.equals(getURL())) {
281                         refresh();
282                         return;
283                 }
284                 browser.setUrl(url);
285         }
286
287         /**
288          * Refresh the currently viewed page.
289          */
290         public void refresh() {
291                 browser.refresh();
292         }
293
294         protected void setURL(String url, boolean browse) {
295                 Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
296                 if (url == null) {
297                         home();
298                         return;
299                 }
300                 
301                 if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
302                         return;
303
304                 // check URL maps
305                 Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
306                 String newURL = null;
307                 while (iterator.hasNext() && newURL == null) {
308                         try {
309                                 IURLMap map = (IURLMap) iterator.next();
310                                 newURL = map.getMappedURL(url);
311                         } catch (Exception e) { }
312                 }
313                 if (newURL != null)
314                         url = newURL;
315                 
316                 if (browse)
317                         navigate(url);
318                 
319                 addToHistory(url);
320                 updateHistory();
321         }
322
323         protected void addToHistory(String url) {
324                 if (history == null)
325                         history = WebBrowserPreference.getInternalWebBrowserHistory();
326                 int found = -1;
327                 int size = history.size();
328                 for (int i = 0; i < size; i++){
329                         String s = (String) history.get(i);
330                         if (s.equals(url)) {
331                                 found = i;
332                                 break;
333                         }
334                 }
335                 
336                 if (found == -1) {
337                         if (size >= MAX_HISTORY)
338                                 history.remove(size - 1);
339                         history.add(0, url);
340                         WebBrowserPreference.setInternalWebBrowserHistory(history);
341                 } else if (found != 0) {
342                         history.remove(found);
343                         history.add(0, url);
344                         WebBrowserPreference.setInternalWebBrowserHistory(history);
345                 }
346         }
347
348         public void setURL(String url) {
349                 setURL(url, true);
350         }
351         
352         /**
353          * Creates the Web browser status area.
354          */
355         private void createStatusArea(Composite parent) {
356                 Composite composite = new Composite(parent, SWT.NONE);
357                 GridLayout layout = new GridLayout();
358                 layout.numColumns = 2;
359                 layout.marginHeight = 0;
360                 layout.marginWidth = 0;
361                 layout.horizontalSpacing = 4;
362                 layout.verticalSpacing = 0;
363                 composite.setLayout(layout);
364                 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
365         
366                 // Add a label for displaying status messages as they are received from the control
367                 status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
368                 GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
369                 gridData.horizontalIndent = 2;
370                 status.setLayoutData(gridData);
371         
372                 // Add a progress bar to display downloading progress information
373                 progress = new ProgressBar(composite, SWT.BORDER);
374                 gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL);
375                 gridData.widthHint = 100;
376                 gridData.heightHint = 10;
377                 progress.setLayoutData(gridData);
378         }
379         
380         /**
381          *
382          */
383         public void dispose() {
384                 super.dispose();
385
386                 showStatusbar = false;
387                 showToolbar = false;
388         
389                 if (busy != null)
390                         busy.dispose();
391                 busy = null;
392
393                 browser = null;
394         }
395         
396         /**
397          * Populate the toolbar.
398          * @param toolbar org.eclipse.swt.widgets.ToolBar
399          */
400         private void fillToolBar(final ToolBar toolbar) {
401                 ToolItem go = new ToolItem(toolbar, SWT.NONE);
402                 go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
403                 go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
404                 go.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_GO));
405                 go.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserGo"));
406                 go.addSelectionListener(new SelectionAdapter() {
407                         public void widgetSelected(SelectionEvent event) {
408                                 setURL(combo.getText());
409                         }
410                 });
411         
412                 new ToolItem(toolbar, SWT.SEPARATOR);
413                 
414                 favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
415                 favorites.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
416                 favorites.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
417                 favorites.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
418                 favorites.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserFavorites"));
419                 
420                 favorites.addSelectionListener(new SelectionAdapter() {
421                         public void widgetSelected(SelectionEvent event) {
422                                 if (event.detail == SWT.ARROW) {
423                                         Rectangle r = favorites.getBounds();
424                                         showFavorites(toolbar, toolbar.toDisplay(r.x, r.y + r.height));
425                                 } else
426                                         addFavorite();
427                         }
428                 });
429         
430                 // create back and forward actions
431                 back = new ToolItem(toolbar, SWT.NONE);
432                 back.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
433                 back.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
434                 back.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
435                 back.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserBack"));
436                 back.addSelectionListener(new SelectionAdapter() {
437                         public void widgetSelected(SelectionEvent event) {
438                                 back();
439                         }
440                 });
441
442                 forward = new ToolItem(toolbar, SWT.NONE);
443                 forward.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
444                 forward.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
445                 forward.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
446                 forward.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserForward"));
447                 forward.addSelectionListener(new SelectionAdapter() {
448                         public void widgetSelected(SelectionEvent event) {
449                                 forward();
450                         }
451                 });
452                 
453                 // create refresh, stop, and print actions
454                 stop = new ToolItem(toolbar, SWT.NONE);
455                 stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
456                 stop.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_STOP));
457                 stop.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_STOP));
458                 stop.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserStop"));
459                 stop.addSelectionListener(new SelectionAdapter() {
460                         public void widgetSelected(SelectionEvent event) {
461                                 stop();
462                         }
463                 });
464         
465                 refresh = new ToolItem(toolbar, SWT.NONE);
466                 refresh.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
467                 refresh.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
468                 refresh.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
469                 refresh.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserRefresh"));
470                 refresh.addSelectionListener(new SelectionAdapter() {
471                         public void widgetSelected(SelectionEvent event) {
472                                 refresh();
473                         }
474                 });
475         }
476         
477         protected void addFavorite() {
478                 java.util.List list = WebBrowserPreference.getInternalWebBrowserFavorites();
479                 Favorite f = new Favorite(title, browser.getUrl());
480                 if (!list.contains(f)) {
481                         list.add(f);
482                         WebBrowserPreference.setInternalWebBrowserFavorites(list);
483                 }
484         }
485         
486         protected void showFavorites(Control parent, Point p) {
487                 Menu perspectiveBarMenu = null;
488                 if (perspectiveBarMenu == null) {
489                         Menu menu = new Menu(parent);
490                         
491                         // locked favorites
492                         Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
493                         if (iterator.hasNext()) {
494                                 while (iterator.hasNext()) {
495                                         final Favorite f = (Favorite) iterator.next();
496                                         MenuItem item = new MenuItem(menu, SWT.NONE);
497                                         item.setText(f.getName());
498                                         item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
499                                         item.addSelectionListener(new SelectionAdapter() {
500                                                 public void widgetSelected(SelectionEvent event) {
501                                                         setURL(f.getURL());
502                                                 }
503                                         });
504                                 }
505                                 
506                                 new MenuItem(menu, SWT.SEPARATOR);
507                         }
508                         
509                         iterator = WebBrowserPreference.getInternalWebBrowserFavorites().iterator();
510                         if (!iterator.hasNext()) {
511                                 MenuItem item = new MenuItem(menu, SWT.NONE);
512                                 item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserNoFavorites"));
513                         }
514                         while (iterator.hasNext()) {
515                                 final Favorite f = (Favorite) iterator.next();
516                                 MenuItem item = new MenuItem(menu, SWT.NONE);
517                                 item.setText(f.getName());
518                                 item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
519                                 item.addSelectionListener(new SelectionAdapter() {
520                                         public void widgetSelected(SelectionEvent event) {
521                                                 setURL(f.getURL());
522                                         }
523                                 });
524                         }
525                         
526                         new MenuItem(menu, SWT.SEPARATOR);
527         
528                         MenuItem item = new MenuItem(menu, SWT.NONE);
529                         item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserOrganizeFavorites"));
530                         item.addSelectionListener(new SelectionAdapter() {
531                                 public void widgetSelected(SelectionEvent event) {
532                                         OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(shell);
533                                         dialog.open();
534                                 }
535                         });
536                         
537                         perspectiveBarMenu = menu;
538                 }
539                 
540                 if (perspectiveBarMenu != null) {
541                         perspectiveBarMenu.setLocation(p.x, p.y);
542                         perspectiveBarMenu.setVisible(true);
543                 }
544         }
545
546         public void home() {
547            navigate(WebBrowserPreference.getHomePageURL());
548         }
549
550         /**
551          * Returns true if the homepage is currently being displayed.
552          * @return boolean
553          */
554         protected boolean isHome() {
555                 return getURL() != null && getURL().endsWith(WebBrowserPreference.getHomePageURL().substring(9));
556         }
557
558         protected String getURL() {
559                 return browser.getUrl();
560         }
561
562         /**
563          * Update the history list to the global copy.
564          */
565         protected void updateHistory() {
566                 if (combo == null)
567                         return;
568         
569                 String temp = combo.getText();
570                 if (history == null)
571                         history = WebBrowserPreference.getInternalWebBrowserHistory();
572         
573                 String[] historyList = new String[history.size()];
574                 history.toArray(historyList);
575                 combo.setItems(historyList);
576         
577                 combo.setText(temp);
578         }
579 }