1 11 package org.eclipse.ui.internal.dialogs; 12 13 import java.io.IOException ; 14 import java.net.MalformedURLException ; 15 import java.net.URL ; 16 import java.util.ArrayList ; 17 import java.util.StringTokenizer ; 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 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 67 public ProductInfoDialog(Shell parentShell) { 68 super(parentShell); 69 } 70 71 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 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 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 ex) { 120 } 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 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 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 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 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 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 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 216 protected Cursor getBusyCursor() { 217 return busyCursor; 218 } 219 220 224 protected void setBusyCursor(Cursor busyCursor) { 225 this.busyCursor = busyCursor; 226 } 227 228 232 protected Cursor getHandCursor() { 233 return handCursor; 234 } 235 236 240 protected void setHandCursor(Cursor handCursor) { 241 this.handCursor = handCursor; 242 } 243 244 248 protected AboutItem getItem() { 249 return item; 250 } 251 252 256 protected void setItem(AboutItem item) { 257 this.item = item; 258 } 259 260 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 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 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 311 private void openWebBrowserError(final String href, final Throwable t) { 312 String title = WorkbenchMessages.ProductInfoDialog_errorTitle; 313 String msg = NLS.bind( 314 WorkbenchMessages.ProductInfoDialog_unableToOpenWebBrowser, 315 href); 316 IStatus status = WorkbenchPlugin.getStatus(t); 317 StatusUtil.handleStatus(status, title + ": " + msg, StatusManager.SHOW, getShell()); 319 } 320 321 324 protected void openLink(String href) { 325 if (href.startsWith("file:")) { href = href.substring(5); 329 while (href.startsWith("/")) { href = href.substring(1); 331 } 332 href = "file:///" + href; } 334 IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport(); 335 try { 336 IWebBrowser browser = support.getExternalBrowser(); 337 browser.openURL(new URL (urlEncodeForSpaces(href.toCharArray()))); 338 } 339 catch (MalformedURLException e) { 340 openWebBrowserError(href, e); 341 } 342 catch (PartInitException e) { 343 openWebBrowserError(href, e); 344 } 345 } 346 347 354 private String urlEncodeForSpaces(char[] input) { 355 StringBuffer retu = new StringBuffer (input.length); 356 for (int i = 0; i < input.length; i++) { 357 if (input[i] == ' ') { 358 retu.append("%20"); } else { 360 retu.append(input[i]); 361 } 362 } 363 return retu.toString(); 364 } 365 366 373 protected boolean openBrowser(URL url) { 374 if (url != null) { 375 try { 376 url = Platform.asLocalURL(url); 377 } catch (IOException e) { 378 return false; 379 } 380 } 381 if (url == null) { 382 return false; 383 } 384 openLink(url.toString()); 385 return true; 386 } 387 388 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 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 415 protected AboutItem scan(String s) { 416 ArrayList linkRanges = new ArrayList (); 417 ArrayList links = new ArrayList (); 418 419 422 int urlSeparatorOffset= s.indexOf("://"); while(urlSeparatorOffset >= 0) { 424 425 boolean startDoubleQuote= false; 426 427 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 StringTokenizer tokenizer= new StringTokenizer (s.substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); 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); } 466 return new AboutItem(s, (int[][]) linkRanges.toArray(new int[linkRanges 467 .size()][2]), (String []) links 468 .toArray(new String [links.size()])); 469 } 470 471 } 472 | Popular Tags |