1 11 package org.eclipse.jdt.internal.debug.ui.actions; 12 13 14 15 import java.lang.reflect.InvocationTargetException ; 16 import java.util.Iterator ; 17 18 import org.eclipse.core.resources.IResource; 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.core.runtime.IStatus; 22 import org.eclipse.core.runtime.Status; 23 import org.eclipse.debug.core.DebugEvent; 24 import org.eclipse.debug.core.DebugException; 25 import org.eclipse.debug.core.ILaunch; 26 import org.eclipse.debug.core.model.ISourceLocator; 27 import org.eclipse.debug.core.model.IStackFrame; 28 import org.eclipse.debug.core.model.IValue; 29 import org.eclipse.debug.ui.DebugUITools; 30 import org.eclipse.debug.ui.IDebugModelPresentation; 31 import org.eclipse.debug.ui.IDebugUIConstants; 32 import org.eclipse.debug.ui.IDebugView; 33 import org.eclipse.jdt.core.IJavaElement; 34 import org.eclipse.jdt.core.IJavaProject; 35 import org.eclipse.jdt.core.JavaCore; 36 import org.eclipse.jdt.debug.core.IJavaDebugTarget; 37 import org.eclipse.jdt.debug.core.IJavaObject; 38 import org.eclipse.jdt.debug.core.IJavaStackFrame; 39 import org.eclipse.jdt.debug.core.IJavaThread; 40 import org.eclipse.jdt.debug.core.IJavaValue; 41 import org.eclipse.jdt.debug.core.IJavaVariable; 42 import org.eclipse.jdt.debug.core.JDIDebugModel; 43 import org.eclipse.jdt.debug.eval.IEvaluationEngine; 44 import org.eclipse.jdt.debug.eval.IEvaluationListener; 45 import org.eclipse.jdt.debug.eval.IEvaluationResult; 46 import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; 47 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin; 48 import org.eclipse.jdt.internal.debug.ui.EvaluationContextManager; 49 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; 50 import org.eclipse.jdt.internal.debug.ui.JavaWordFinder; 51 import org.eclipse.jdt.internal.debug.ui.display.IDataDisplay; 52 import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression; 53 import org.eclipse.jdt.internal.debug.ui.snippeteditor.ISnippetStateChangedListener; 54 import org.eclipse.jdt.internal.debug.ui.snippeteditor.JavaSnippetEditor; 55 import org.eclipse.jface.action.IAction; 56 import org.eclipse.jface.dialogs.ErrorDialog; 57 import org.eclipse.jface.operation.IRunnableWithProgress; 58 import org.eclipse.jface.text.BadLocationException; 59 import org.eclipse.jface.text.IDocument; 60 import org.eclipse.jface.text.IRegion; 61 import org.eclipse.jface.text.ITextSelection; 62 import org.eclipse.jface.text.ITextViewer; 63 import org.eclipse.jface.text.Region; 64 import org.eclipse.jface.viewers.ISelection; 65 import org.eclipse.jface.viewers.ISelectionProvider; 66 import org.eclipse.jface.viewers.IStructuredSelection; 67 import org.eclipse.swt.custom.StyledText; 68 import org.eclipse.swt.graphics.GC; 69 import org.eclipse.swt.graphics.Point; 70 import org.eclipse.swt.widgets.Control; 71 import org.eclipse.swt.widgets.Display; 72 import org.eclipse.swt.widgets.Shell; 73 import org.eclipse.ui.IEditorActionDelegate; 74 import org.eclipse.ui.IEditorInput; 75 import org.eclipse.ui.IEditorPart; 76 import org.eclipse.ui.IObjectActionDelegate; 77 import org.eclipse.ui.IPartListener; 78 import org.eclipse.ui.IViewActionDelegate; 79 import org.eclipse.ui.IViewPart; 80 import org.eclipse.ui.IWorkbench; 81 import org.eclipse.ui.IWorkbenchPage; 82 import org.eclipse.ui.IWorkbenchPart; 83 import org.eclipse.ui.IWorkbenchWindow; 84 import org.eclipse.ui.IWorkbenchWindowActionDelegate; 85 import org.eclipse.ui.PartInitException; 86 import org.eclipse.ui.texteditor.ITextEditor; 87 88 import com.ibm.icu.text.MessageFormat; 89 import com.sun.jdi.InvocationException; 90 import com.sun.jdi.ObjectReference; 91 92 93 98 public abstract class EvaluateAction implements IEvaluationListener, IWorkbenchWindowActionDelegate, IObjectActionDelegate, IEditorActionDelegate, IPartListener, IViewActionDelegate, ISnippetStateChangedListener { 99 100 private IAction fAction; 101 private IWorkbenchPart fTargetPart; 102 private IWorkbenchWindow fWindow; 103 private Object fSelection; 104 private IRegion fRegion; 105 106 109 private boolean fEvaluating; 110 111 114 private IWorkbenchPart fNewTargetPart= null; 115 116 119 private IDebugModelPresentation fPresentation; 120 121 public EvaluateAction() { 122 super(); 123 } 124 125 134 protected IJavaObject getObjectContext() { 135 IWorkbenchPage page= JDIDebugUIPlugin.getActivePage(); 136 if (page != null) { 137 IWorkbenchPart activePart= page.getActivePart(); 138 if (activePart != null) { 139 IDebugView a = (IDebugView)activePart.getAdapter(IDebugView.class); 140 if (a != null) { 141 if (a.getViewer() != null) { 142 ISelection s = a.getViewer().getSelection(); 143 if (s instanceof IStructuredSelection) { 144 IStructuredSelection structuredSelection = (IStructuredSelection)s; 145 if (structuredSelection.size() == 1) { 146 Object selection= structuredSelection.getFirstElement(); 147 if (selection instanceof IJavaVariable) { 148 IJavaVariable var = (IJavaVariable)selection; 149 try { 151 if (!var.getName().equals("this")) { IValue value= var.getValue(); 153 if (value instanceof IJavaObject) { 154 return (IJavaObject)value; 155 } 156 } 157 } catch (DebugException e) { 158 JDIDebugUIPlugin.log(e); 159 } 160 } else if (selection instanceof JavaInspectExpression) { 161 IValue value= ((JavaInspectExpression)selection).getValue(); 162 if (value instanceof IJavaObject) { 163 return (IJavaObject)value; 164 } 165 } 166 } 167 } 168 } 169 } 170 } 171 } 172 return null; 173 } 174 175 179 protected IJavaStackFrame getStackFrameContext() { 180 IWorkbenchPart part = getTargetPart(); 181 IJavaStackFrame frame = null; 182 if (part == null) { 183 frame = EvaluationContextManager.getEvaluationContext(getWindow()); 184 } else { 185 frame = EvaluationContextManager.getEvaluationContext(part); 186 } 187 return frame; 188 } 189 190 193 public void evaluationComplete(final IEvaluationResult result) { 194 if (JDIDebugUIPlugin.getDefault() == null) { 196 return; 197 } 198 199 final IJavaValue value= result.getValue(); 200 if (result.hasErrors() || value != null) { 201 final Display display= JDIDebugUIPlugin.getStandardDisplay(); 202 if (display.isDisposed()) { 203 return; 204 } 205 displayResult(result); 206 } 207 } 208 209 protected void evaluationCleanup() { 210 setEvaluating(false); 211 setTargetPart(fNewTargetPart); 212 } 213 216 abstract protected void displayResult(IEvaluationResult result); 217 218 protected void run() { 219 final IJavaObject object = getObjectContext(); 221 final IJavaStackFrame stackFrame= getStackFrameContext(); 222 if (stackFrame == null) { 223 reportError(ActionMessages.Evaluate_error_message_stack_frame_context); 224 return; 225 } 226 227 IJavaThread thread = (IJavaThread)stackFrame.getThread(); 229 if (thread.isPerformingEvaluation()) { 230 reportError(ActionMessages.EvaluateAction_Cannot_perform_nested_evaluations__1); 231 return; 232 } 233 234 setNewTargetPart(getTargetPart()); 235 236 IRunnableWithProgress runnable = new IRunnableWithProgress() { 237 public void run(IProgressMonitor monitor) throws InvocationTargetException , InterruptedException { 238 if (stackFrame.isSuspended()) { 239 IJavaElement javaElement= getJavaElement(stackFrame); 240 if (javaElement != null) { 241 IJavaProject project = javaElement.getJavaProject(); 242 IEvaluationEngine engine = null; 243 try { 244 Object selection= getSelectedObject(); 245 if (!(selection instanceof String )) { 246 return; 247 } 248 String expression= (String )selection; 249 250 engine = JDIDebugPlugin.getDefault().getEvaluationEngine(project, (IJavaDebugTarget)stackFrame.getDebugTarget()); 251 setEvaluating(true); 252 boolean hitBreakpoints= JDIDebugModel.getPreferences().getBoolean(JDIDebugModel.PREF_SUSPEND_FOR_BREAKPOINTS_DURING_EVALUATION); 253 if (object == null) { 254 engine.evaluate(expression, stackFrame, EvaluateAction.this, DebugEvent.EVALUATION, hitBreakpoints); 255 } else { 256 engine.evaluate(expression, object, (IJavaThread)stackFrame.getThread(), EvaluateAction.this, DebugEvent.EVALUATION, hitBreakpoints); 257 } 258 return; 259 } catch (CoreException e) { 260 throw new InvocationTargetException (e, getExceptionMessage(e)); 261 } 262 } 263 throw new InvocationTargetException (null, ActionMessages.Evaluate_error_message_src_context); 264 } 265 throw new InvocationTargetException (null, ActionMessages.EvaluateAction_Thread_not_suspended___unable_to_perform_evaluation__1); 267 } 268 }; 269 270 IWorkbench workbench = JDIDebugUIPlugin.getDefault().getWorkbench(); 271 try { 272 workbench.getProgressService().busyCursorWhile(runnable); 273 } catch (InvocationTargetException e) { 274 evaluationCleanup(); 275 String message = e.getMessage(); 276 if (message == null) { 277 message = e.getClass().getName(); 278 if (e.getCause() != null) { 279 message = e.getCause().getClass().getName(); 280 if (e.getCause().getMessage() != null) { 281 message = e.getCause().getMessage(); 282 } 283 } 284 } 285 reportError(message); 286 } catch (InterruptedException e) { 287 } 288 } 289 290 protected IJavaElement getJavaElement(IStackFrame stackFrame) { 291 292 ILaunch launch = stackFrame.getLaunch(); 294 if (launch == null) { 295 return null; 296 } 297 ISourceLocator locator= launch.getSourceLocator(); 298 if (locator == null) 299 return null; 300 301 Object sourceElement = locator.getSourceElement(stackFrame); 302 if (sourceElement instanceof IJavaElement) { 303 return (IJavaElement) sourceElement; 304 } else if (sourceElement instanceof IResource) { 305 IJavaProject project = JavaCore.create(((IResource)sourceElement).getProject()); 306 if (project.exists()) { 307 return project; 308 } 309 } 310 return null; 311 } 312 313 317 protected void update() { 318 IAction action= getAction(); 319 if (action != null) { 320 resolveSelectedObject(); 321 } 322 } 323 324 328 protected void resolveSelectedObject() { 329 Object selectedObject= null; 330 fRegion = null; 331 ISelection selection= getTargetSelection(); 332 if (selection instanceof ITextSelection) { 333 ITextSelection ts = (ITextSelection)selection; 334 String text= ts.getText(); 335 if (textHasContent(text)) { 336 selectedObject= text; 337 fRegion = new Region(ts.getOffset(), ts.getLength()); 338 } else if (getTargetPart() instanceof IEditorPart) { 339 IEditorPart editor= (IEditorPart)getTargetPart(); 340 if (editor instanceof ITextEditor) { 341 selectedObject = resolveSelectedObjectUsingToken(selectedObject, ts, editor); 342 } 343 } 344 } else if (selection instanceof IStructuredSelection) { 345 if (!selection.isEmpty()) { 346 if (getTargetPart().getSite().getId().equals(IDebugUIConstants.ID_DEBUG_VIEW)) { 347 IEditorPart editor= getTargetPart().getSite().getPage().getActiveEditor(); 349 setTargetPart(editor); 350 selection= getTargetSelection(); 351 if (selection instanceof ITextSelection) { 352 ITextSelection ts = (ITextSelection)selection; 353 String text= ts.getText(); 354 if (textHasContent(text)) { 355 selectedObject= text; 356 } else if (editor instanceof ITextEditor) { 357 selectedObject= resolveSelectedObjectUsingToken(selectedObject, ts, editor); 358 } 359 } 360 } else { 361 IStructuredSelection ss= (IStructuredSelection)selection; 362 Iterator elements = ss.iterator(); 363 while (elements.hasNext()) { 364 if (!(elements.next() instanceof IJavaVariable)) { 365 setSelectedObject(null); 366 return; 367 } 368 } 369 selectedObject= ss; 370 } 371 } 372 } 373 setSelectedObject(selectedObject); 374 } 375 376 private Object resolveSelectedObjectUsingToken(Object selectedObject, ITextSelection ts, IEditorPart editor) { 377 ITextEditor textEditor= (ITextEditor) editor; 378 IDocument doc= textEditor.getDocumentProvider().getDocument(editor.getEditorInput()); 379 fRegion= JavaWordFinder.findWord(doc, ts.getOffset()); 380 if (fRegion != null) { 381 try { 382 selectedObject= doc.get(fRegion.getOffset(), fRegion.getLength()); 383 } catch (BadLocationException e) { 384 } 385 } 386 return selectedObject; 387 } 388 389 protected ISelection getTargetSelection() { 390 IWorkbenchPart part = getTargetPart(); 391 if (part != null) { 392 ISelectionProvider provider = part.getSite().getSelectionProvider(); 393 if (provider != null) { 394 return provider.getSelection(); 395 } 396 } 397 return null; 398 } 399 400 405 protected boolean compareToEditorInput(IStackFrame stackFrame) { 406 ILaunch launch = stackFrame.getLaunch(); 407 if (launch == null) { 408 return false; 409 } 410 ISourceLocator locator= launch.getSourceLocator(); 411 if (locator == null) { 412 return false; 413 } 414 Object sourceElement = locator.getSourceElement(stackFrame); 415 if (sourceElement == null) { 416 return false; 417 } 418 IEditorInput sfEditorInput= getDebugModelPresentation().getEditorInput(sourceElement); 419 if (getTargetPart() instanceof IEditorPart) { 420 return ((IEditorPart)getTargetPart()).getEditorInput().equals(sfEditorInput); 421 } 422 return false; 423 } 424 425 protected Shell getShell() { 426 if (getTargetPart() != null) { 427 return getTargetPart().getSite().getShell(); 428 } 429 return JDIDebugUIPlugin.getActiveWorkbenchShell(); 430 } 431 432 protected IDataDisplay getDataDisplay() { 433 IDataDisplay display= getDirectDataDisplay(); 434 if (display != null) { 435 return display; 436 } 437 IWorkbenchPage page= JDIDebugUIPlugin.getActivePage(); 438 if (page != null) { 439 IWorkbenchPart activePart= page.getActivePart(); 440 if (activePart != null) { 441 IViewPart view = page.findView(IJavaDebugUIConstants.ID_DISPLAY_VIEW); 442 if (view == null) { 443 try { 444 view= page.showView(IJavaDebugUIConstants.ID_DISPLAY_VIEW); 445 } catch (PartInitException e) { 446 JDIDebugUIPlugin.statusDialog(ActionMessages.EvaluateAction_Cannot_open_Display_view, e.getStatus()); 447 } finally { 448 page.activate(activePart); 449 } 450 } 451 if (view != null) { 452 page.bringToTop(view); 453 return (IDataDisplay)view.getAdapter(IDataDisplay.class); 454 } 455 } 456 } 457 458 return null; 459 } 460 461 protected IDataDisplay getDirectDataDisplay() { 462 IWorkbenchPart part= getTargetPart(); 463 if (part != null) { 464 IDataDisplay display= (IDataDisplay)part.getAdapter(IDataDisplay.class); 465 if (display != null) { 466 IWorkbenchPage page= JDIDebugUIPlugin.getActivePage(); 467 if (page != null) { 468 IWorkbenchPart activePart= page.getActivePart(); 469 if (activePart != null) { 470 if (activePart != part) { 471 page.activate(part); 472 } 473 } 474 } 475 return display; 476 } 477 } 478 IWorkbenchPage page= JDIDebugUIPlugin.getActivePage(); 479 if (page != null) { 480 IWorkbenchPart activePart= page.getActivePart(); 481 if (activePart != null) { 482 IDataDisplay display= (IDataDisplay)activePart.getAdapter(IDataDisplay.class); 483 if (display != null) { 484 return display; 485 } 486 } 487 } 488 return null; 489 } 490 491 protected boolean textHasContent(String text) { 492 if (text != null) { 493 int length= text.length(); 494 if (length > 0) { 495 for (int i= 0; i < length; i++) { 496 if (Character.isLetterOrDigit(text.charAt(i))) { 497 return true; 498 } 499 } 500 } 501 } 502 return false; 503 } 504 505 508 protected void reportErrors(IEvaluationResult result) { 509 String message= getErrorMessage(result); 510 reportError(message); 511 } 512 513 protected void reportError(String message) { 514 IDataDisplay dataDisplay= getDirectDataDisplay(); 515 if (dataDisplay != null) { 516 if (message.length() != 0) { 517 dataDisplay.displayExpressionValue(MessageFormat.format(ActionMessages.EvaluateAction__evaluation_failed__Reason, new String [] {format(message)})); 518 } else { 519 dataDisplay.displayExpressionValue(ActionMessages.EvaluateAction__evaluation_failed__1); 520 } 521 } else { 522 Status status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, message, null); 523 ErrorDialog.openError(getShell(), ActionMessages.Evaluate_error_title_eval_problems, null, status); 524 } 525 } 526 527 private String format(String message) { 528 StringBuffer result= new StringBuffer (); 529 int index= 0, pos; 530 while ((pos= message.indexOf('\n', index)) != -1) { 531 result.append("\t\t").append(message.substring(index, index= pos + 1)); } 533 if (index < message.length()) { 534 result.append("\t\t").append(message.substring(index)); } 536 return result.toString(); 537 } 538 539 public static String getExceptionMessage(Throwable exception) { 540 if (exception instanceof CoreException) { 541 CoreException ce = (CoreException)exception; 542 Throwable throwable= ce.getStatus().getException(); 543 if (throwable instanceof com.sun.jdi.InvocationException) { 544 return getInvocationExceptionMessage((com.sun.jdi.InvocationException)throwable); 545 } else if (throwable instanceof CoreException) { 546 return getExceptionMessage(throwable); 548 } 549 return ce.getStatus().getMessage(); 550 } 551 String message= MessageFormat.format(ActionMessages.Evaluate_error_message_direct_exception, new Object [] { exception.getClass() }); 552 if (exception.getMessage() != null) { 553 message= MessageFormat.format(ActionMessages.Evaluate_error_message_exception_pattern, new Object [] { message, exception.getMessage() }); 554 } 555 return message; 556 } 557 558 561 protected static String getInvocationExceptionMessage(com.sun.jdi.InvocationException exception) { 562 InvocationException ie= exception; 563 ObjectReference ref= ie.exception(); 564 return MessageFormat.format(ActionMessages.Evaluate_error_message_wrapped_exception, new Object [] { ref.referenceType().name() }); 565 } 566 567 protected String getErrorMessage(IEvaluationResult result) { 568 String [] errors= result.getErrorMessages(); 569 if (errors.length == 0) { 570 return getExceptionMessage(result.getException()); 571 } 572 return getErrorMessage(errors); 573 } 574 575 protected String getErrorMessage(String [] errors) { 576 String message= ""; for (int i= 0; i < errors.length; i++) { 578 String msg= errors[i]; 579 if (i == 0) { 580 message= msg; 581 } else { 582 message= MessageFormat.format(ActionMessages.Evaluate_error_problem_append_pattern, new Object [] { message, msg }); 583 } 584 } 585 return message; 586 } 587 588 591 public void run(IAction action) { 592 update(); 593 run(); 594 } 595 596 599 public void selectionChanged(IAction action, ISelection selection) { 600 setAction(action); 601 } 602 603 606 public void dispose() { 607 disposeDebugModelPresentation(); 608 IWorkbenchWindow win = getWindow(); 609 if (win != null) { 610 win.getPartService().removePartListener(this); 611 } 612 } 613 614 617 public void init(IWorkbenchWindow window) { 618 setWindow(window); 619 IWorkbenchPage page= window.getActivePage(); 620 if (page != null) { 621 setTargetPart(page.getActivePart()); 622 } 623 window.getPartService().addPartListener(this); 624 update(); 625 } 626 627 protected IAction getAction() { 628 return fAction; 629 } 630 631 protected void setAction(IAction action) { 632 fAction = action; 633 } 634 635 641 protected IDebugModelPresentation getDebugModelPresentation() { 642 if (fPresentation == null) { 643 fPresentation = DebugUITools.newDebugModelPresentation(JDIDebugModel.getPluginIdentifier()); 644 } 645 return fPresentation; 646 } 647 648 652 protected void disposeDebugModelPresentation() { 653 if (fPresentation != null) { 654 fPresentation.dispose(); 655 } 656 } 657 658 661 public void setActiveEditor(IAction action, IEditorPart targetEditor) { 662 setAction(action); 663 setTargetPart(targetEditor); 664 } 665 666 669 public void partActivated(IWorkbenchPart part) { 670 setTargetPart(part); 671 } 672 673 676 public void partBroughtToTop(IWorkbenchPart part) { 677 } 678 679 682 public void partClosed(IWorkbenchPart part) { 683 if (part == getTargetPart()) { 684 setTargetPart(null); 685 } 686 if (part == getNewTargetPart()) { 687 setNewTargetPart(null); 688 } 689 } 690 691 694 public void partDeactivated(IWorkbenchPart part) { 695 } 696 697 700 public void partOpened(IWorkbenchPart part) { 701 } 702 703 706 public void init(IViewPart view) { 707 setTargetPart(view); 708 } 709 710 protected IWorkbenchPart getTargetPart() { 711 return fTargetPart; 712 } 713 714 protected void setTargetPart(IWorkbenchPart part) { 715 if (isEvaluating()) { 716 setNewTargetPart(part); 719 } else { 720 if (getTargetPart() instanceof JavaSnippetEditor) { 721 ((JavaSnippetEditor)getTargetPart()).removeSnippetStateChangedListener(this); 722 } 723 fTargetPart= part; 724 if (part instanceof JavaSnippetEditor) { 725 ((JavaSnippetEditor)part).addSnippetStateChangedListener(this); 726 } 727 } 728 } 729 730 protected IWorkbenchWindow getWindow() { 731 return fWindow; 732 } 733 734 protected void setWindow(IWorkbenchWindow window) { 735 fWindow = window; 736 } 737 738 741 public void setActivePart(IAction action, IWorkbenchPart targetPart) { 742 setAction(action); 743 setTargetPart(targetPart); 744 update(); 745 } 746 747 protected Object getSelectedObject() { 748 return fSelection; 749 } 750 751 protected void setSelectedObject(Object selection) { 752 fSelection = selection; 753 } 754 755 758 public void snippetStateChanged(JavaSnippetEditor editor) { 759 if (editor != null && !editor.isEvaluating() && editor.getFile() != null) { 760 update(); 761 getAction().setEnabled(getSelectedObject() != null); 762 } else { 763 getAction().setEnabled(false); 764 } 765 } 766 767 protected IWorkbenchPart getNewTargetPart() { 768 return fNewTargetPart; 769 } 770 771 protected void setNewTargetPart(IWorkbenchPart newTargetPart) { 772 fNewTargetPart = newTargetPart; 773 } 774 775 protected boolean isEvaluating() { 776 return fEvaluating; 777 } 778 779 protected void setEvaluating(boolean evaluating) { 780 fEvaluating = evaluating; 781 } 782 783 788 protected IRegion getRegion() { 789 return fRegion; 790 } 791 792 799 public static StyledText getStyledText(IWorkbenchPart part) { 800 ITextViewer viewer = (ITextViewer)part.getAdapter(ITextViewer.class); 801 StyledText textWidget = null; 802 if (viewer == null) { 803 Control control = (Control) part.getAdapter(Control.class); 804 if (control instanceof StyledText) { 805 textWidget = (StyledText) control; 806 } 807 } else { 808 textWidget = viewer.getTextWidget(); 809 } 810 return textWidget; 811 } 812 813 820 public static Point getPopupAnchor(StyledText textWidget) { 821 if (textWidget != null) { 822 Point docRange = textWidget.getSelectionRange(); 823 int midOffset = docRange.x + (docRange.y / 2); 824 Point point = textWidget.getLocationAtOffset(midOffset); 825 point = textWidget.toDisplay(point); 826 827 GC gc = new GC(textWidget); 828 gc.setFont(textWidget.getFont()); 829 int height = gc.getFontMetrics().getHeight(); 830 gc.dispose(); 831 point.y += height; 832 return point; 833 } 834 return null; 835 } 836 } 837 | Popular Tags |