1 11 package org.eclipse.jdt.internal.ui.infoviews; 12 13 import java.io.BufferedReader ; 14 import java.io.IOException ; 15 import java.io.InputStreamReader ; 16 import java.io.Reader ; 17 import java.io.StringReader ; 18 import java.net.URL ; 19 20 import org.eclipse.core.runtime.Assert; 21 import org.eclipse.core.runtime.FileLocator; 22 import org.eclipse.core.runtime.ListenerList; 23 import org.eclipse.core.runtime.Platform; 24 25 import org.eclipse.swt.SWT; 26 import org.eclipse.swt.SWTError; 27 import org.eclipse.swt.browser.Browser; 28 import org.eclipse.swt.custom.StyledText; 29 import org.eclipse.swt.events.ControlAdapter; 30 import org.eclipse.swt.events.ControlEvent; 31 import org.eclipse.swt.events.SelectionAdapter; 32 import org.eclipse.swt.events.SelectionEvent; 33 import org.eclipse.swt.graphics.Color; 34 import org.eclipse.swt.graphics.FontData; 35 import org.eclipse.swt.graphics.RGB; 36 import org.eclipse.swt.graphics.Rectangle; 37 import org.eclipse.swt.widgets.Composite; 38 import org.eclipse.swt.widgets.Control; 39 import org.eclipse.swt.widgets.Display; 40 41 import org.eclipse.jface.action.Action; 42 import org.eclipse.jface.action.IAction; 43 import org.eclipse.jface.dialogs.MessageDialogWithToggle; 44 import org.eclipse.jface.internal.text.html.HTMLPrinter; 45 import org.eclipse.jface.internal.text.html.HTMLTextPresenter; 46 import org.eclipse.jface.preference.IPreferenceStore; 47 import org.eclipse.jface.resource.JFaceResources; 48 import org.eclipse.jface.util.IPropertyChangeListener; 49 import org.eclipse.jface.util.PropertyChangeEvent; 50 import org.eclipse.jface.viewers.ISelection; 51 import org.eclipse.jface.viewers.ISelectionChangedListener; 52 import org.eclipse.jface.viewers.ISelectionProvider; 53 import org.eclipse.jface.viewers.SelectionChangedEvent; 54 import org.eclipse.jface.viewers.StructuredSelection; 55 import org.eclipse.jface.window.Window; 56 57 import org.eclipse.jface.text.BadLocationException; 58 import org.eclipse.jface.text.BadPartitioningException; 59 import org.eclipse.jface.text.DefaultInformationControl; 60 import org.eclipse.jface.text.Document; 61 import org.eclipse.jface.text.IDocument; 62 import org.eclipse.jface.text.IDocumentExtension3; 63 import org.eclipse.jface.text.ITextSelection; 64 import org.eclipse.jface.text.ITypedRegion; 65 import org.eclipse.jface.text.TextPresentation; 66 import org.eclipse.jface.text.TextSelection; 67 import org.eclipse.jface.text.TextUtilities; 68 69 import org.eclipse.ui.IWorkbenchPart; 70 import org.eclipse.ui.PlatformUI; 71 import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; 72 import org.eclipse.ui.texteditor.IDocumentProvider; 73 import org.eclipse.ui.texteditor.ITextEditor; 74 75 import org.eclipse.jdt.core.IClassFile; 76 import org.eclipse.jdt.core.ICompilationUnit; 77 import org.eclipse.jdt.core.IJavaElement; 78 import org.eclipse.jdt.core.IMember; 79 import org.eclipse.jdt.core.IOpenable; 80 import org.eclipse.jdt.core.IPackageFragmentRoot; 81 import org.eclipse.jdt.core.JavaModelException; 82 83 import org.eclipse.jdt.internal.corext.javadoc.JavaDocLocations; 84 85 import org.eclipse.jdt.ui.JavaElementLabels; 86 import org.eclipse.jdt.ui.JavadocContentAccess; 87 import org.eclipse.jdt.ui.PreferenceConstants; 88 import org.eclipse.jdt.ui.text.IJavaPartitions; 89 90 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; 91 import org.eclipse.jdt.internal.ui.JavaPlugin; 92 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; 93 94 import org.osgi.framework.Bundle; 95 96 104 public class JavadocView extends AbstractInfoView { 105 106 111 private static final String DO_NOT_WARN_PREFERENCE_KEY= "JavadocView.error.doNotWarn"; 113 private static final boolean WARNING_DIALOG_ENABLED= false; 115 116 117 private static final long LABEL_FLAGS= JavaElementLabels.ALL_FULLY_QUALIFIED 118 | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_EXCEPTIONS 119 | JavaElementLabels.F_PRE_TYPE_SIGNATURE | JavaElementLabels.T_TYPE_PARAMETERS; 120 121 122 123 private Browser fBrowser; 124 125 private StyledText fText; 126 127 private DefaultInformationControl.IInformationPresenter fPresenter; 128 129 private TextPresentation fPresentation= new TextPresentation(); 130 131 private SelectAllAction fSelectAllAction; 132 133 private static String fgStyleSheet; 134 138 private static boolean fgStyleSheetLoaded= false; 139 140 141 private boolean fIsUsingBrowserWidget; 142 143 private RGB fBackgroundColorRGB; 144 148 private IPropertyChangeListener fFontListener; 149 150 151 154 private class SelectAllAction extends Action { 155 156 157 private Control fControl; 158 159 private SelectionProvider fSelectionProvider; 160 161 167 public SelectAllAction(Control control, SelectionProvider selectionProvider) { 168 super("selectAll"); 170 Assert.isNotNull(control); 171 Assert.isNotNull(selectionProvider); 172 fControl= control; 173 fSelectionProvider= selectionProvider; 174 175 setEnabled(!fIsUsingBrowserWidget); 177 178 setText(InfoViewMessages.SelectAllAction_label); 179 setToolTipText(InfoViewMessages.SelectAllAction_tooltip); 180 setDescription(InfoViewMessages.SelectAllAction_description); 181 182 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAbstractTextEditorHelpContextIds.SELECT_ALL_ACTION); 183 } 184 185 188 public void run() { 189 if (fControl instanceof StyledText) 190 ((StyledText)fControl).selectAll(); 191 else { 192 if (fSelectionProvider != null) 195 fSelectionProvider.fireSelectionChanged(); 196 } 197 } 198 } 199 200 203 private static class SelectionProvider implements ISelectionProvider { 204 205 206 private ListenerList fListeners= new ListenerList(ListenerList.IDENTITY); 207 208 private Control fControl; 209 210 215 public SelectionProvider(Control control) { 216 Assert.isNotNull(control); 217 fControl= control; 218 if (fControl instanceof StyledText) { 219 ((StyledText)fControl).addSelectionListener(new SelectionAdapter() { 220 public void widgetSelected(SelectionEvent e) { 221 fireSelectionChanged(); 222 } 223 }); 224 } else { 225 } 232 } 233 234 237 public void fireSelectionChanged() { 238 ISelection selection= getSelection(); 239 SelectionChangedEvent event= new SelectionChangedEvent(this, selection); 240 Object [] selectionChangedListeners= fListeners.getListeners(); 241 for (int i= 0; i < selectionChangedListeners.length; i++) 242 ((ISelectionChangedListener)selectionChangedListeners[i]).selectionChanged(event); 243 } 244 245 248 public void addSelectionChangedListener(ISelectionChangedListener listener) { 249 fListeners.add(listener); 250 } 251 252 255 public ISelection getSelection() { 256 if (fControl instanceof StyledText) { 257 IDocument document= new Document(((StyledText)fControl).getSelectionText()); 258 return new TextSelection(document, 0, document.getLength()); 259 } else { 260 return StructuredSelection.EMPTY; 262 } 263 } 264 265 268 public void removeSelectionChangedListener(ISelectionChangedListener listener) { 269 fListeners.remove(listener); 270 } 271 272 275 public void setSelection(ISelection selection) { 276 } 278 } 279 280 283 protected void internalCreatePartControl(Composite parent) { 284 try { 285 fBrowser= new Browser(parent, SWT.NONE); 286 fIsUsingBrowserWidget= true; 287 288 } catch (SWTError er) { 289 290 297 298 IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); 299 boolean doNotWarn= store.getBoolean(DO_NOT_WARN_PREFERENCE_KEY); 300 if (WARNING_DIALOG_ENABLED && !doNotWarn) { 301 String title= InfoViewMessages.JavadocView_error_noBrowser_title; 302 String message= InfoViewMessages.JavadocView_error_noBrowser_message; 303 String toggleMessage= InfoViewMessages.JavadocView_error_noBrowser_doNotWarn; 304 MessageDialogWithToggle dialog= MessageDialogWithToggle.openError(parent.getShell(), title, message, toggleMessage, false, null, null); 305 if (dialog.getReturnCode() == Window.OK) 306 store.setValue(DO_NOT_WARN_PREFERENCE_KEY, dialog.getToggleState()); 307 } 308 309 fIsUsingBrowserWidget= false; 310 } 311 312 if (!fIsUsingBrowserWidget) { 313 fText= new StyledText(parent, SWT.V_SCROLL | SWT.H_SCROLL); 314 fText.setEditable(false); 315 fPresenter= new HTMLTextPresenter(false); 316 317 fText.addControlListener(new ControlAdapter() { 318 321 public void controlResized(ControlEvent e) { 322 setInput(fText.getText()); 323 } 324 }); 325 } 326 327 initStyleSheet(); 328 listenForFontChanges(); 329 getViewSite().setSelectionProvider(new SelectionProvider(getControl())); 330 } 331 332 337 private void listenForFontChanges() { 338 fFontListener= new IPropertyChangeListener() { 339 public void propertyChange(PropertyChangeEvent event) { 340 if (PreferenceConstants.APPEARANCE_JAVADOC_FONT.equals(event.getProperty())) { 341 fgStyleSheetLoaded= false; 342 final Display display= getSite().getPage().getWorkbenchWindow().getWorkbench().getDisplay(); 345 if (!display.isDisposed()) { 346 display.asyncExec(new Runnable () { 347 public void run() { 348 if (!display.isDisposed()) { 349 initStyleSheet(); 350 refresh(); 351 } 352 } 353 }); 354 } 355 } 356 } 357 }; 358 JFaceResources.getFontRegistry().addListener(fFontListener); 359 } 360 361 private static void initStyleSheet() { 362 if (fgStyleSheetLoaded) 363 return; 364 fgStyleSheetLoaded= true; 365 fgStyleSheet= loadStyleSheet(); 366 } 367 368 private static String loadStyleSheet() { 369 Bundle bundle= Platform.getBundle(JavaPlugin.getPluginId()); 370 URL styleSheetURL= bundle.getEntry("/JavadocViewStyleSheet.css"); if (styleSheetURL == null) 372 return null; 373 374 try { 375 styleSheetURL= FileLocator.toFileURL(styleSheetURL); 376 BufferedReader reader= new BufferedReader (new InputStreamReader (styleSheetURL.openStream())); 377 StringBuffer buffer= new StringBuffer (200); 378 String line= reader.readLine(); 379 while (line != null) { 380 buffer.append(line); 381 buffer.append('\n'); 382 line= reader.readLine(); 383 } 384 385 FontData fontData= JFaceResources.getFontRegistry().getFontData(PreferenceConstants.APPEARANCE_JAVADOC_FONT)[0]; 386 return HTMLPrinter.convertTopLevelFont(buffer.toString(), fontData); 387 } catch (IOException ex) { 388 JavaPlugin.log(ex); 389 return null; 390 } 391 } 392 393 396 protected void createActions() { 397 super.createActions(); 398 fSelectAllAction= new SelectAllAction(getControl(), (SelectionProvider)getSelectionProvider()); 399 } 400 401 402 406 protected IAction getSelectAllAction() { 407 if (fIsUsingBrowserWidget) 409 return null; 410 411 return fSelectAllAction; 412 } 413 414 418 protected IAction getCopyToClipboardAction() { 419 if (fIsUsingBrowserWidget) 421 return null; 422 423 return super.getCopyToClipboardAction(); 424 } 425 426 429 protected void setForeground(Color color) { 430 getControl().setForeground(color); 431 } 432 433 436 protected void setBackground(Color color) { 437 getControl().setBackground(color); 438 fBackgroundColorRGB= color.getRGB(); 439 refresh(); 440 } 441 442 447 private void refresh() { 448 IJavaElement input= getInput(); 449 if (input == null) { 450 StringBuffer buffer= new StringBuffer (""); HTMLPrinter.insertPageProlog(buffer, 0, fBackgroundColorRGB, fgStyleSheet); 452 setInput(buffer.toString()); 453 } else { 454 setInput(computeInput(input)); 455 } 456 } 457 458 462 protected String getBackgroundColorKey() { 463 return "org.eclipse.jdt.ui.JavadocView.backgroundColor"; } 465 466 469 protected void internalDispose() { 470 fText= null; 471 fBrowser= null; 472 if (fFontListener != null) { 473 JFaceResources.getFontRegistry().removeListener(fFontListener); 474 fFontListener= null; 475 } 476 } 477 478 481 public void setFocus() { 482 getControl().setFocus(); 483 } 484 485 488 protected Object computeInput(Object input) { 489 if (getControl() == null || ! (input instanceof IJavaElement)) 490 return null; 491 492 IJavaElement je= (IJavaElement)input; 493 String javadocHtml; 494 495 switch (je.getElementType()) { 496 case IJavaElement.COMPILATION_UNIT: 497 try { 498 javadocHtml= getJavadocHtml(((ICompilationUnit)je).getTypes()); 499 } catch (JavaModelException ex) { 500 javadocHtml= null; 501 } 502 break; 503 case IJavaElement.CLASS_FILE: 504 javadocHtml= getJavadocHtml(new IJavaElement[] {((IClassFile)je).getType()}); 505 break; 506 default: 507 javadocHtml= getJavadocHtml(new IJavaElement[] { je }); 508 } 509 510 if (javadocHtml == null) 511 return ""; 513 return javadocHtml; 514 } 515 516 519 protected void setInput(Object input) { 520 String javadocHtml= (String )input; 521 522 if (fIsUsingBrowserWidget) { 523 if (javadocHtml != null && javadocHtml.length() > 0) { 524 boolean RTL= (getSite().getShell().getStyle() & SWT.RIGHT_TO_LEFT) != 0; 525 if (RTL) { 526 StringBuffer buffer= new StringBuffer (javadocHtml); 527 HTMLPrinter.insertStyles(buffer, new String [] { "direction:rtl" } ); javadocHtml= buffer.toString(); 529 } 530 } 531 fBrowser.setText(javadocHtml); 532 } else { 533 fPresentation.clear(); 534 Rectangle size= fText.getClientArea(); 535 536 try { 537 javadocHtml= ((DefaultInformationControl.IInformationPresenterExtension)fPresenter).updatePresentation(getSite().getShell(), javadocHtml, fPresentation, size.width, size.height); 538 } catch (IllegalArgumentException ex) { 539 return; 541 } 542 fText.setText(javadocHtml); 543 TextPresentation.applyTextPresentation(fPresentation, fText); 544 } 545 } 546 547 553 private String getJavadocHtml(IJavaElement[] result) { 554 StringBuffer buffer= new StringBuffer (); 555 int nResults= result.length; 556 557 if (nResults == 0) 558 return null; 559 560 if (nResults > 1) { 561 562 for (int i= 0; i < result.length; i++) { 563 HTMLPrinter.startBulletList(buffer); 564 IJavaElement curr= result[i]; 565 if (curr instanceof IMember) 566 HTMLPrinter.addBullet(buffer, getInfoText((IMember) curr)); 567 HTMLPrinter.endBulletList(buffer); 568 } 569 570 } else { 571 572 IJavaElement curr= result[0]; 573 if (curr instanceof IMember) { 574 IMember member= (IMember) curr; 575 Reader reader; 577 try { 578 reader= JavadocContentAccess.getHTMLContentReader(member, true, true); 579 580 if (reader == null && member.isBinary()) { 582 boolean hasAttachedJavadoc= JavaDocLocations.getJavadocBaseLocation(member) != null; 583 IPackageFragmentRoot root= (IPackageFragmentRoot)member.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); 584 boolean hasAttachedSource= root != null && root.getSourceAttachmentPath() != null; 585 IOpenable openable= member.getOpenable(); 586 boolean hasSource= openable.getBuffer() != null; 587 588 if (!hasAttachedSource && !hasAttachedJavadoc) 589 reader= new StringReader (InfoViewMessages.JavadocView_noAttachments); 590 else if (!hasAttachedJavadoc && !hasSource) 591 reader= new StringReader (InfoViewMessages.JavadocView_noAttachedJavadoc); 592 else if (!hasAttachedSource) 593 reader= new StringReader (InfoViewMessages.JavadocView_noAttachedSource); 594 else if (!hasSource) 595 reader= new StringReader (InfoViewMessages.JavadocView_noInformation); 596 } 597 598 } catch (JavaModelException ex) { 599 reader= new StringReader (InfoViewMessages.JavadocView_error_gettingJavadoc); 600 JavaPlugin.log(ex.getStatus()); 601 } 602 if (reader != null) { 603 HTMLPrinter.addParagraph(buffer, reader); 604 } 605 } 606 } 607 608 boolean flushContent= true; 609 if (buffer.length() > 0 || flushContent) { 610 HTMLPrinter.insertPageProlog(buffer, 0, fBackgroundColorRGB, fgStyleSheet); 611 HTMLPrinter.addPageEpilog(buffer); 612 return buffer.toString(); 613 } 614 615 return null; 616 } 617 618 624 private String getInfoText(IMember member) { 625 return JavaElementLabels.getElementLabel(member, LABEL_FLAGS); 626 } 627 628 632 protected boolean isIgnoringNewInput(IJavaElement je, IWorkbenchPart part, ISelection selection) { 633 if (super.isIgnoringNewInput(je, part, selection) 634 && part instanceof ITextEditor 635 && selection instanceof ITextSelection) { 636 637 ITextEditor editor= (ITextEditor)part; 638 IDocumentProvider docProvider= editor.getDocumentProvider(); 639 if (docProvider == null) 640 return false; 641 642 IDocument document= docProvider.getDocument(editor.getEditorInput()); 643 if (!(document instanceof IDocumentExtension3)) 644 return false; 645 646 try { 647 int offset= ((ITextSelection)selection).getOffset(); 648 String partition= ((IDocumentExtension3)document).getContentType(IJavaPartitions.JAVA_PARTITIONING, offset, false); 649 return partition != IJavaPartitions.JAVA_DOC; 650 } catch (BadPartitioningException ex) { 651 return false; 652 } catch (BadLocationException ex) { 653 return false; 654 } 655 656 } 657 return false; 658 } 659 660 663 protected IJavaElement findSelectedJavaElement(IWorkbenchPart part, ISelection selection) { 664 IJavaElement element; 665 try { 666 element= super.findSelectedJavaElement(part, selection); 667 668 if (element == null && part instanceof JavaEditor && selection instanceof ITextSelection) { 669 670 JavaEditor editor= (JavaEditor)part; 671 ITextSelection textSelection= (ITextSelection)selection; 672 673 IDocumentProvider documentProvider= editor.getDocumentProvider(); 674 if (documentProvider == null) 675 return null; 676 677 IDocument document= documentProvider.getDocument(editor.getEditorInput()); 678 if (document == null) 679 return null; 680 681 ITypedRegion typedRegion= TextUtilities.getPartition(document, IJavaPartitions.JAVA_PARTITIONING, textSelection.getOffset(), false); 682 if (IJavaPartitions.JAVA_DOC.equals(typedRegion.getType())) 683 return TextSelectionConverter.getElementAtOffset((JavaEditor)part, textSelection); 684 else 685 return null; 686 } else 687 return element; 688 } catch (JavaModelException e) { 689 return null; 690 } catch (BadLocationException e) { 691 return null; 692 } 693 } 694 695 698 protected Control getControl() { 699 if (fIsUsingBrowserWidget) 700 return fBrowser; 701 else 702 return fText; 703 } 704 705 709 protected String getHelpContextId() { 710 return IJavaHelpContextIds.JAVADOC_VIEW; 711 } 712 } 713 | Popular Tags |