KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > dialogs > ProductInfoDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.dialogs;
12
13 import java.io.IOException JavaDoc;
14 import java.net.MalformedURLException JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.StringTokenizer JavaDoc;
18
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.Platform;
21 import org.eclipse.jface.dialogs.TrayDialog;
22 import org.eclipse.jface.resource.JFaceColors;
23 import org.eclipse.osgi.util.NLS;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.custom.StyleRange;
26 import org.eclipse.swt.custom.StyledText;
27 import org.eclipse.swt.events.KeyAdapter;
28 import org.eclipse.swt.events.KeyEvent;
29 import org.eclipse.swt.events.MouseAdapter;
30 import org.eclipse.swt.events.MouseEvent;
31 import org.eclipse.swt.events.MouseMoveListener;
32 import org.eclipse.swt.events.TraverseEvent;
33 import org.eclipse.swt.events.TraverseListener;
34 import org.eclipse.swt.graphics.Color;
35 import org.eclipse.swt.graphics.Cursor;
36 import org.eclipse.swt.graphics.Point;
37 import org.eclipse.swt.widgets.Shell;
38 import org.eclipse.ui.PartInitException;
39 import org.eclipse.ui.PlatformUI;
40 import org.eclipse.ui.browser.IWebBrowser;
41 import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
42 import org.eclipse.ui.internal.WorkbenchMessages;
43 import org.eclipse.ui.internal.WorkbenchPlugin;
44 import org.eclipse.ui.internal.about.AboutItem;
45 import org.eclipse.ui.internal.misc.StatusUtil;
46 import org.eclipse.ui.statushandlers.StatusManager;
47
48 /**
49  * Abstract superclass of about dialogs
50  */

51
52 public abstract class ProductInfoDialog extends TrayDialog {
53
54     private AboutItem item;
55
56     private Cursor handCursor;
57
58     private Cursor busyCursor;
59
60     private boolean mouseDown = false;
61
62     private boolean dragEvent = false;
63
64     /**
65      * Create an instance of this Dialog
66      */

67     public ProductInfoDialog(Shell parentShell) {
68         super(parentShell);
69     }
70
71     /**
72      * Adds listeners to the given styled text
73      */

74     protected void addListeners(StyledText styledText) {
75         styledText.addMouseListener(new MouseAdapter() {
76             public void mouseDown(MouseEvent e) {
77                 if (e.button != 1) {
78                     return;
79                 }
80                 mouseDown = true;
81             }
82
83             public void mouseUp(MouseEvent e) {
84                 mouseDown = false;
85                 StyledText text = (StyledText) e.widget;
86                 int offset = text.getCaretOffset();
87                 if (dragEvent) {
88                     // don't activate a link during a drag/mouse up operation
89
dragEvent = false;
90                     if (item != null && item.isLinkAt(offset)) {
91                         text.setCursor(handCursor);
92                     }
93                 } else if (item != null && item.isLinkAt(offset)) {
94                     text.setCursor(busyCursor);
95                     openLink(item.getLinkAt(offset));
96                     StyleRange selectionRange = getCurrentRange(text);
97                     text.setSelectionRange(selectionRange.start,
98                             selectionRange.length);
99                     text.setCursor(null);
100                 }
101             }
102         });
103
104         styledText.addMouseMoveListener(new MouseMoveListener() {
105             public void mouseMove(MouseEvent e) {
106                 // Do not change cursor on drag events
107
if (mouseDown) {
108                     if (!dragEvent) {
109                         StyledText text = (StyledText) e.widget;
110                         text.setCursor(null);
111                     }
112                     dragEvent = true;
113                     return;
114                 }
115                 StyledText text = (StyledText) e.widget;
116                 int offset = -1;
117                 try {
118                     offset = text.getOffsetAtLocation(new Point(e.x, e.y));
119                 } catch (IllegalArgumentException JavaDoc ex) {
120                     // leave value as -1
121
}
122                 if (offset == -1) {
123                     text.setCursor(null);
124                 } else if (item != null && item.isLinkAt(offset)) {
125                     text.setCursor(handCursor);
126                 } else {
127                     text.setCursor(null);
128                 }
129             }
130         });
131
132         styledText.addTraverseListener(new TraverseListener() {
133             public void keyTraversed(TraverseEvent e) {
134                 StyledText text = (StyledText) e.widget;
135                 switch (e.detail) {
136                 case SWT.TRAVERSE_ESCAPE:
137                     e.doit = true;
138                     break;
139                 case SWT.TRAVERSE_TAB_NEXT:
140                     //Previously traverse out in the backward direction?
141
Point nextSelection = text.getSelection();
142                     int charCount = text.getCharCount();
143                     if ((nextSelection.x == charCount)
144                             && (nextSelection.y == charCount)) {
145                         text.setSelection(0);
146                     }
147                     StyleRange nextRange = findNextRange(text);
148                     if (nextRange == null) {
149                         // Next time in start at beginning, also used by
150
// TRAVERSE_TAB_PREVIOUS to indicate we traversed out
151
// in the forward direction
152
text.setSelection(0);
153                         e.doit = true;
154                     } else {
155                         text.setSelectionRange(nextRange.start,
156                                 nextRange.length);
157                         e.doit = true;
158                         e.detail = SWT.TRAVERSE_NONE;
159                     }
160                     break;
161                 case SWT.TRAVERSE_TAB_PREVIOUS:
162                     //Previously traverse out in the forward direction?
163
Point previousSelection = text.getSelection();
164                     if ((previousSelection.x == 0)
165                             && (previousSelection.y == 0)) {
166                         text.setSelection(text.getCharCount());
167                     }
168                     StyleRange previousRange = findPreviousRange(text);
169                     if (previousRange == null) {
170                         // Next time in start at the end, also used by
171
// TRAVERSE_TAB_NEXT to indicate we traversed out
172
// in the backward direction
173
text.setSelection(text.getCharCount());
174                         e.doit = true;
175                     } else {
176                         text.setSelectionRange(previousRange.start,
177                                 previousRange.length);
178                         e.doit = true;
179                         e.detail = SWT.TRAVERSE_NONE;
180                     }
181                     break;
182                 default:
183                     break;
184                 }
185             }
186         });
187
188         //Listen for Tab and Space to allow keyboard navigation
189
styledText.addKeyListener(new KeyAdapter() {
190             public void keyPressed(KeyEvent event) {
191                 StyledText text = (StyledText) event.widget;
192                 if (event.character == ' ' || event.character == SWT.CR) {
193                     if (item != null) {
194                         //Be sure we are in the selection
195
int offset = text.getSelection().x + 1;
196
197                         if (item.isLinkAt(offset)) {
198                             text.setCursor(busyCursor);
199                             openLink(item.getLinkAt(offset));
200                             StyleRange selectionRange = getCurrentRange(text);
201                             text.setSelectionRange(selectionRange.start,
202                                     selectionRange.length);
203                             text.setCursor(null);
204                         }
205                     }
206                     return;
207                 }
208             }
209         });
210     }
211
212     /**
213      * Gets the busy cursor.
214      * @return the busy cursor
215      */

216     protected Cursor getBusyCursor() {
217         return busyCursor;
218     }
219
220     /**
221      * Sets the busy cursor.
222      * @param busyCursor the busy cursor
223      */

224     protected void setBusyCursor(Cursor busyCursor) {
225         this.busyCursor = busyCursor;
226     }
227
228     /**
229      * Gets the hand cursor.
230      * @return Returns a hand cursor
231      */

232     protected Cursor getHandCursor() {
233         return handCursor;
234     }
235
236     /**
237      * Sets the hand cursor.
238      * @param handCursor The hand cursor to set
239      */

240     protected void setHandCursor(Cursor handCursor) {
241         this.handCursor = handCursor;
242     }
243
244     /**
245      * Gets the about item.
246      * @return the about item
247      */

248     protected AboutItem getItem() {
249         return item;
250     }
251
252     /**
253      * Sets the about item.
254      * @param item about item
255      */

256     protected void setItem(AboutItem item) {
257         this.item = item;
258     }
259
260     /**
261      * Find the range of the current selection.
262      */

263     protected StyleRange getCurrentRange(StyledText text) {
264         StyleRange[] ranges = text.getStyleRanges();
265         int currentSelectionEnd = text.getSelection().y;
266         int currentSelectionStart = text.getSelection().x;
267
268         for (int i = 0; i < ranges.length; i++) {
269             if ((currentSelectionStart >= ranges[i].start)
270                     && (currentSelectionEnd <= (ranges[i].start + ranges[i].length))) {
271                 return ranges[i];
272             }
273         }
274         return null;
275     }
276
277     /**
278      * Find the next range after the current
279      * selection.
280      */

281     protected StyleRange findNextRange(StyledText text) {
282         StyleRange[] ranges = text.getStyleRanges();
283         int currentSelectionEnd = text.getSelection().y;
284
285         for (int i = 0; i < ranges.length; i++) {
286             if (ranges[i].start >= currentSelectionEnd) {
287                 return ranges[i];
288             }
289         }
290         return null;
291     }
292
293     /**
294      * Find the previous range before the current selection.
295      */

296     protected StyleRange findPreviousRange(StyledText text) {
297         StyleRange[] ranges = text.getStyleRanges();
298         int currentSelectionStart = text.getSelection().x;
299
300         for (int i = ranges.length - 1; i > -1; i--) {
301             if ((ranges[i].start + ranges[i].length - 1) < currentSelectionStart) {
302                 return ranges[i];
303             }
304         }
305         return null;
306     }
307
308     /**
309      * display an error message
310      */

311     private void openWebBrowserError(final String JavaDoc href, final Throwable JavaDoc t) {
312         String JavaDoc title = WorkbenchMessages.ProductInfoDialog_errorTitle;
313         String JavaDoc msg = NLS.bind(
314                 WorkbenchMessages.ProductInfoDialog_unableToOpenWebBrowser,
315                 href);
316         IStatus status = WorkbenchPlugin.getStatus(t);
317         StatusUtil.handleStatus(status, title + ": " + msg, StatusManager.SHOW, //$NON-NLS-1$
318
getShell());
319     }
320
321     /**
322      * Open a link
323      */

324     protected void openLink(String JavaDoc href) {
325         // format the href for an html file (file:///<filename.html>
326
// required for Mac only.
327
if (href.startsWith("file:")) { //$NON-NLS-1$
328
href = href.substring(5);
329             while (href.startsWith("/")) { //$NON-NLS-1$
330
href = href.substring(1);
331             }
332             href = "file:///" + href; //$NON-NLS-1$
333
}
334         IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
335         try {
336             IWebBrowser browser = support.getExternalBrowser();
337             browser.openURL(new URL JavaDoc(urlEncodeForSpaces(href.toCharArray())));
338         }
339         catch (MalformedURLException JavaDoc e) {
340             openWebBrowserError(href, e);
341         }
342         catch (PartInitException e) {
343             openWebBrowserError(href, e);
344         }
345     }
346
347     /**
348      * This method encodes the url, removes the spaces from the url and replaces
349      * the same with <code>"%20"</code>. This method is required to fix Bug
350      * 77840.
351      *
352      * @since 3.0.2
353      */

354     private String JavaDoc urlEncodeForSpaces(char[] input) {
355        StringBuffer JavaDoc retu = new StringBuffer JavaDoc(input.length);
356        for (int i = 0; i < input.length; i++) {
357            if (input[i] == ' ') {
358             retu.append("%20"); //$NON-NLS-1$
359
} else {
360             retu.append(input[i]);
361         }
362        }
363        return retu.toString();
364     }
365
366     /**
367      * Open a browser with the argument title on the argument url. If the url refers to a
368      * resource within a bundle, then a temp copy of the file will be extracted and opened.
369      * @see <code>Platform.asLocalUrl</code>
370      * @param url The target url to be displayed, null will be safely ignored
371      * @return true if the url was successfully displayed and false otherwise
372      */

373     protected boolean openBrowser(URL JavaDoc url) {
374         if (url != null) {
375             try {
376                 url = Platform.asLocalURL(url);
377             } catch (IOException JavaDoc e) {
378                 return false;
379             }
380         }
381         if (url == null) {
382             return false;
383         }
384         openLink(url.toString());
385         return true;
386     }
387
388     /**
389      * Sets the styled text's bold ranges
390      */

391     protected void setBoldRanges(StyledText styledText, int[][] boldRanges) {
392         for (int i = 0; i < boldRanges.length; i++) {
393             StyleRange r = new StyleRange(boldRanges[i][0], boldRanges[i][1],
394                     null, null, SWT.BOLD);
395             styledText.setStyleRange(r);
396         }
397     }
398
399     /**
400      * Sets the styled text's link (blue) ranges
401      */

402     protected void setLinkRanges(StyledText styledText, int[][] linkRanges) {
403         Color fg = JFaceColors.getHyperlinkText(styledText.getShell()
404                 .getDisplay());
405         for (int i = 0; i < linkRanges.length; i++) {
406             StyleRange r = new StyleRange(linkRanges[i][0], linkRanges[i][1],
407                     fg, null);
408             styledText.setStyleRange(r);
409         }
410     }
411
412     /**
413      * Scan the contents of the about text
414      */

415     protected AboutItem scan(String JavaDoc s) {
416         ArrayList JavaDoc linkRanges = new ArrayList JavaDoc();
417         ArrayList JavaDoc links = new ArrayList JavaDoc();
418         
419         // slightly modified version of jface url detection
420
// see org.eclipse.jface.text.hyperlink.URLHyperlinkDetector
421

422         int urlSeparatorOffset= s.indexOf("://"); //$NON-NLS-1$
423
while(urlSeparatorOffset >= 0) {
424     
425             boolean startDoubleQuote= false;
426     
427             // URL protocol (left to "://")
428
int urlOffset= urlSeparatorOffset;
429             char ch;
430             do {
431                 urlOffset--;
432                 ch= ' ';
433                 if (urlOffset > -1)
434                     ch= s.charAt(urlOffset);
435                 startDoubleQuote= ch == '"';
436             } while (Character.isUnicodeIdentifierStart(ch));
437             urlOffset++;
438             
439     
440             // Right to "://"
441
StringTokenizer JavaDoc tokenizer= new StringTokenizer JavaDoc(s.substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); //$NON-NLS-1$
442
if (!tokenizer.hasMoreTokens())
443                 return null;
444     
445             int urlLength= tokenizer.nextToken().length() + 3 + urlSeparatorOffset - urlOffset;
446     
447             if (startDoubleQuote) {
448                 int endOffset= -1;
449                 int nextDoubleQuote= s.indexOf('"', urlOffset);
450                 int nextWhitespace= s.indexOf(' ', urlOffset);
451                 if (nextDoubleQuote != -1 && nextWhitespace != -1)
452                     endOffset= Math.min(nextDoubleQuote, nextWhitespace);
453                 else if (nextDoubleQuote != -1)
454                     endOffset= nextDoubleQuote;
455                 else if (nextWhitespace != -1)
456                     endOffset= nextWhitespace;
457                 if (endOffset != -1)
458                     urlLength= endOffset - urlOffset;
459             }
460             
461             linkRanges.add(new int[] { urlOffset, urlLength });
462             links.add(s.substring(urlOffset, urlOffset+urlLength));
463             
464             urlSeparatorOffset= s.indexOf("://", urlOffset+urlLength+1); //$NON-NLS-1$
465
}
466         return new AboutItem(s, (int[][]) linkRanges.toArray(new int[linkRanges
467                 .size()][2]), (String JavaDoc[]) links
468                 .toArray(new String JavaDoc[links.size()]));
469     }
470
471 }
472
Popular Tags