1 11 package org.eclipse.jface.text; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.Set ; 21 import java.util.regex.PatternSyntaxException ; 22 23 import org.eclipse.swt.SWT; 24 import org.eclipse.swt.custom.LineBackgroundEvent; 25 import org.eclipse.swt.custom.LineBackgroundListener; 26 import org.eclipse.swt.custom.MovementEvent; 27 import org.eclipse.swt.custom.MovementListener; 28 import org.eclipse.swt.custom.ST; 29 import org.eclipse.swt.custom.StyleRange; 30 import org.eclipse.swt.custom.StyledText; 31 import org.eclipse.swt.custom.VerifyKeyListener; 32 import org.eclipse.swt.events.ControlEvent; 33 import org.eclipse.swt.events.ControlListener; 34 import org.eclipse.swt.events.DisposeEvent; 35 import org.eclipse.swt.events.DisposeListener; 36 import org.eclipse.swt.events.KeyEvent; 37 import org.eclipse.swt.events.KeyListener; 38 import org.eclipse.swt.events.MouseAdapter; 39 import org.eclipse.swt.events.MouseEvent; 40 import org.eclipse.swt.events.MouseListener; 41 import org.eclipse.swt.events.SelectionEvent; 42 import org.eclipse.swt.events.SelectionListener; 43 import org.eclipse.swt.events.TraverseEvent; 44 import org.eclipse.swt.events.TraverseListener; 45 import org.eclipse.swt.events.VerifyEvent; 46 import org.eclipse.swt.events.VerifyListener; 47 import org.eclipse.swt.graphics.Color; 48 import org.eclipse.swt.graphics.GC; 49 import org.eclipse.swt.graphics.Point; 50 import org.eclipse.swt.graphics.Rectangle; 51 import org.eclipse.swt.printing.PrintDialog; 52 import org.eclipse.swt.printing.Printer; 53 import org.eclipse.swt.printing.PrinterData; 54 import org.eclipse.swt.widgets.Composite; 55 import org.eclipse.swt.widgets.Control; 56 import org.eclipse.swt.widgets.Display; 57 import org.eclipse.swt.widgets.Event; 58 import org.eclipse.swt.widgets.Listener; 59 import org.eclipse.swt.widgets.ScrollBar; 60 61 import org.eclipse.core.runtime.Assert; 62 63 import org.eclipse.jface.internal.text.NonDeletingPositionUpdater; 64 import org.eclipse.jface.viewers.IPostSelectionProvider; 65 import org.eclipse.jface.viewers.ISelection; 66 import org.eclipse.jface.viewers.ISelectionChangedListener; 67 import org.eclipse.jface.viewers.ISelectionProvider; 68 import org.eclipse.jface.viewers.SelectionChangedEvent; 69 import org.eclipse.jface.viewers.Viewer; 70 71 import org.eclipse.jface.text.hyperlink.HyperlinkManager; 72 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; 73 import org.eclipse.jface.text.hyperlink.IHyperlinkDetectorExtension; 74 import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter; 75 import org.eclipse.jface.text.projection.ChildDocument; 76 import org.eclipse.jface.text.projection.ChildDocumentManager; 77 78 79 99 public class TextViewer extends Viewer implements 100 ITextViewer, ITextViewerExtension, ITextViewerExtension2, ITextViewerExtension4, ITextViewerExtension6, ITextViewerExtension7, 101 IEditingSupportRegistry, ITextOperationTarget, ITextOperationTargetExtension, 102 IWidgetTokenOwner, IWidgetTokenOwnerExtension, IPostSelectionProvider { 103 104 105 public static final boolean TRACE_ERRORS= false; 106 107 private static final boolean TRACE_DOUBLE_CLICK= false; 108 109 114 protected class WidgetCommand { 115 116 117 public DocumentEvent event; 118 119 public int start; 120 121 public int length; 122 123 public String text; 124 125 public String preservedText; 126 127 132 public void setEvent(DocumentEvent e) { 133 134 event= e; 135 136 start= e.getOffset(); 137 length= e.getLength(); 138 text= e.getText(); 139 140 if (length != 0) { 141 try { 142 143 if (e instanceof SlaveDocumentEvent) { 144 SlaveDocumentEvent slave= (SlaveDocumentEvent) e; 145 DocumentEvent master= slave.getMasterEvent(); 146 if (master != null) 147 preservedText= master.getDocument().get(master.getOffset(), master.getLength()); 148 } else { 149 preservedText= e.getDocument().get(e.getOffset(), e.getLength()); 150 } 151 152 } catch (BadLocationException x) { 153 preservedText= null; 154 if (TRACE_ERRORS) 155 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.WidgetCommand.setEvent")); } 157 } else 158 preservedText= null; 159 } 160 } 161 162 163 168 class TextDoubleClickStrategyConnector extends MouseAdapter implements MovementListener { 169 170 171 private Point fDoubleClickSelection; 172 173 177 public void mouseUp(MouseEvent e) { 178 fDoubleClickSelection= null; 179 } 180 181 185 public void getNextOffset(MovementEvent event) { 186 if (event.movement != SWT.MOVEMENT_WORD_END) 187 return; 188 189 if (TRACE_DOUBLE_CLICK) { 190 System.out.println("\n+++"); print(event); 192 } 193 194 if (fDoubleClickSelection != null) { 195 if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y) 196 event.newOffset= fDoubleClickSelection.y; 197 } 198 } 199 200 204 public void getPreviousOffset(MovementEvent event) { 205 if (event.movement != SWT.MOVEMENT_WORD_START) 206 return; 207 208 if (TRACE_DOUBLE_CLICK) { 209 System.out.println("\n---"); print(event); 211 } 212 if (fDoubleClickSelection == null) { 213 ITextDoubleClickStrategy s= (ITextDoubleClickStrategy) selectContentTypePlugin(getSelectedRange().x, fDoubleClickStrategies); 214 if (s != null) { 215 StyledText textWidget= getTextWidget(); 216 s.doubleClicked(TextViewer.this); 217 fDoubleClickSelection= textWidget.getSelection(); 218 event.newOffset= fDoubleClickSelection.x; 219 if (TRACE_DOUBLE_CLICK) 220 System.out.println("- setting selection: x= " + fDoubleClickSelection.x + ", y= " + fDoubleClickSelection.y); } 222 } else { 223 if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y) 224 event.newOffset= fDoubleClickSelection.x; 225 } 226 } 227 } 228 229 235 private void print(MovementEvent e) { 236 System.out.println("line offset: " + e.lineOffset); System.out.println("line: " + e.lineText); System.out.println("type: " + e.movement); System.out.println("offset: " + e.offset); System.out.println("newOffset: " + e.newOffset); } 242 243 249 class ViewportGuard extends MouseAdapter 250 implements ControlListener, KeyListener, SelectionListener { 251 252 255 public void controlResized(ControlEvent e) { 256 updateViewportListeners(RESIZE); 257 } 258 259 262 public void controlMoved(ControlEvent e) { 263 } 264 265 268 public void keyReleased(KeyEvent e) { 269 updateViewportListeners(KEY); 270 } 271 272 275 public void keyPressed(KeyEvent e) { 276 updateViewportListeners(KEY); 277 } 278 279 282 public void mouseUp(MouseEvent e) { 283 if (fTextWidget != null) 284 fTextWidget.removeSelectionListener(this); 285 updateViewportListeners(MOUSE_END); 286 } 287 288 291 public void mouseDown(MouseEvent e) { 292 if (fTextWidget != null) 293 fTextWidget.addSelectionListener(this); 294 } 295 296 299 public void widgetSelected(SelectionEvent e) { 300 if (e.widget == fScroller) 301 updateViewportListeners(SCROLLER); 302 else 303 updateViewportListeners(MOUSE); 304 } 305 306 309 public void widgetDefaultSelected(SelectionEvent e) {} 310 } 311 312 315 static class ShiftPositionUpdater extends DefaultPositionUpdater { 316 317 322 protected ShiftPositionUpdater(String category) { 323 super(category); 324 } 325 326 330 protected void adaptToInsert() { 331 332 int myStart= fPosition.offset; 333 int myEnd= fPosition.offset + fPosition.length -1; 334 myEnd= Math.max(myStart, myEnd); 335 336 int yoursStart= fOffset; 337 int yoursEnd= fOffset + fReplaceLength -1; 338 yoursEnd= Math.max(yoursStart, yoursEnd); 339 340 if (myEnd < yoursStart) 341 return; 342 343 if (myStart <= yoursStart) { 344 fPosition.length += fReplaceLength; 345 return; 346 } 347 348 if (myStart > yoursStart) 349 fPosition.offset += fReplaceLength; 350 } 351 } 352 353 356 class VisibleDocumentListener implements IDocumentListener { 357 358 361 public void documentAboutToBeChanged(DocumentEvent e) { 362 if (e.getDocument() == getVisibleDocument()) 363 fWidgetCommand.setEvent(e); 364 handleVisibleDocumentAboutToBeChanged(e); 365 } 366 367 370 public void documentChanged(DocumentEvent e) { 371 if (fWidgetCommand.event == e) 372 updateTextListeners(fWidgetCommand); 373 fLastSentSelectionChange= null; 374 handleVisibleDocumentChanged(e); 375 } 376 } 377 378 381 class TextVerifyListener implements VerifyListener { 382 383 387 private boolean fForward= true; 388 389 395 public void forward(boolean forward) { 396 fForward= forward; 397 } 398 399 402 public void verifyText(VerifyEvent e) { 403 if (fForward) 404 handleVerifyEvent(e); 405 } 406 } 407 408 418 class VerifyKeyListenersManager implements VerifyKeyListener { 419 420 423 class Batch { 424 425 int index; 426 427 VerifyKeyListener listener; 428 429 435 public Batch(VerifyKeyListener l, int i) { 436 listener= l; 437 index= i; 438 } 439 } 440 441 442 private List fListeners= new ArrayList (); 443 444 private List fBatched= new ArrayList (); 445 446 private int fReentranceCount= 0; 447 448 451 public void verifyKey(VerifyEvent event) { 452 if (fListeners.isEmpty()) 453 return; 454 455 try { 456 fReentranceCount++; 457 Iterator iterator= fListeners.iterator(); 458 while (iterator.hasNext() && event.doit) { 459 VerifyKeyListener listener= (VerifyKeyListener) iterator.next(); 460 listener.verifyKey(event); } 462 } finally { 463 fReentranceCount--; 464 } 465 if (fReentranceCount == 0) 466 processBatchedRequests(); 467 } 468 469 472 private void processBatchedRequests() { 473 if (!fBatched.isEmpty()) { 474 Iterator e= fBatched.iterator(); 475 while (e.hasNext()) { 476 Batch batch= (Batch) e.next(); 477 insertListener(batch.listener, batch.index); 478 } 479 fBatched.clear(); 480 } 481 } 482 483 488 public int numberOfListeners() { 489 return fListeners.size(); 490 } 491 492 499 public void insertListener(VerifyKeyListener listener, int index) { 500 501 if (index == -1) { 502 removeListener(listener); 503 } else if (listener != null) { 504 505 if (fReentranceCount > 0) { 506 507 fBatched.add(new Batch(listener, index)); 508 509 } else { 510 511 int idx= -1; 512 513 int size= fListeners.size(); 515 for (int i= 0; i < size; i++) { 516 if (listener == fListeners.get(i)) { 517 idx= i; 518 break; 519 } 520 } 521 522 if (idx != index) { 524 525 if (idx != -1) 526 fListeners.remove(idx); 527 528 if (index > fListeners.size()) 529 fListeners.add(listener); 530 else 531 fListeners.add(index, listener); 532 } 533 534 if (size == 0) install(); 536 } 537 } 538 } 539 540 545 public void removeListener(VerifyKeyListener listener) { 546 if (listener == null) 547 return; 548 549 if (fReentranceCount > 0) { 550 551 fBatched.add(new Batch(listener, -1)); 552 553 } else { 554 555 int size= fListeners.size(); 556 for (int i= 0; i < size; i++) { 557 if (listener == fListeners.get(i)) { 558 fListeners.remove(i); 559 if (size == 1) uninstall(); 561 return; 562 } 563 } 564 } 565 } 566 567 570 private void install() { 571 StyledText textWidget= getTextWidget(); 572 if (textWidget != null && !textWidget.isDisposed()) 573 textWidget.addVerifyKeyListener(this); 574 } 575 576 579 private void uninstall() { 580 StyledText textWidget= getTextWidget(); 581 if (textWidget != null && !textWidget.isDisposed()) 582 textWidget.removeVerifyKeyListener(this); 583 } 584 } 585 586 587 593 class FindReplaceRange implements LineBackgroundListener, ITextListener, IPositionUpdater { 594 595 596 private final static String RANGE_CATEGORY= "org.eclipse.jface.text.TextViewer.find.range"; 598 599 private Color fHighlightColor; 600 601 private Position fPosition; 602 603 607 public FindReplaceRange(IRegion range) { 608 setRange(range); 609 } 610 611 616 public void setRange(IRegion range) { 617 fPosition= new Position(range.getOffset(), range.getLength()); 618 } 619 620 625 public IRegion getRange() { 626 return new Region(fPosition.getOffset(), fPosition.getLength()); 627 } 628 629 634 public void setHighlightColor(Color color) { 635 fHighlightColor= color; 636 paint(); 637 } 638 639 643 public void lineGetBackground(LineBackgroundEvent event) { 644 645 646 if (fTextWidget != null) { 647 int offset= widgetOffset2ModelOffset(event.lineOffset); 648 if (fPosition.includes(offset)) 649 event.lineBackground= fHighlightColor; 650 } 651 } 652 653 658 public void install() { 659 TextViewer.this.addTextListener(this); 660 fTextWidget.addLineBackgroundListener(this); 661 662 IDocument document= TextViewer.this.getDocument(); 663 try { 664 document.addPositionCategory(RANGE_CATEGORY); 665 document.addPosition(RANGE_CATEGORY, fPosition); 666 document.addPositionUpdater(this); 667 } catch (BadPositionCategoryException e) { 668 } catch (BadLocationException e) { 670 } 672 673 paint(); 674 } 675 676 680 public void uninstall() { 681 682 684 IDocument document= TextViewer.this.getDocument(); 685 if (document != null) { 686 document.removePositionUpdater(this); 687 document.removePosition(fPosition); 688 } 689 690 if (fTextWidget != null && !fTextWidget.isDisposed()) 691 fTextWidget.removeLineBackgroundListener(this); 692 693 TextViewer.this.removeTextListener(this); 694 695 clear(); 696 } 697 698 701 private void clear() { 702 if (fTextWidget != null && !fTextWidget.isDisposed()) 703 fTextWidget.redraw(); 704 } 705 706 709 private void paint() { 710 711 IRegion widgetRegion= modelRange2WidgetRange(fPosition); 712 int offset= widgetRegion.getOffset(); 713 int length= widgetRegion.getLength(); 714 715 int count= fTextWidget.getCharCount(); 716 if (offset + length >= count) { 717 length= count - offset; 719 Point upperLeft= fTextWidget.getLocationAtOffset(offset); 720 Point lowerRight= fTextWidget.getLocationAtOffset(offset + length); 721 int width= fTextWidget.getClientArea().width; 722 int height= fTextWidget.getLineHeight(offset + length) + lowerRight.y - upperLeft.y; 723 fTextWidget.redraw(upperLeft.x, upperLeft.y, width, height, false); 724 } 725 726 fTextWidget.redrawRange(offset, length, true); 727 } 728 729 733 public void textChanged(TextEvent event) { 734 if (event.getViewerRedrawState()) 735 paint(); 736 } 737 738 742 public void update(DocumentEvent event) { 743 int offset= event.getOffset(); 744 int length= event.getLength(); 745 int delta= event.getText().length() - length; 746 747 if (offset < fPosition.getOffset()) 748 fPosition.setOffset(fPosition.getOffset() + delta); 749 else if (offset < fPosition.getOffset() + fPosition.getLength()) 750 fPosition.setLength(fPosition.getLength() + delta); 751 } 752 } 753 754 757 class FindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension3 { 758 759 760 private FindReplaceRange fRange; 761 762 private Color fScopeHighlightColor; 763 764 private Map fRememberedPartitioners; 765 769 private DocumentRewriteSession fRewriteSession; 770 771 774 public String getSelectionText() { 775 Point s= TextViewer.this.getSelectedRange(); 776 if (s.x > -1 && s.y > -1) { 777 try { 778 IDocument document= TextViewer.this.getDocument(); 779 return document.get(s.x, s.y); 780 } catch (BadLocationException x) { 781 } 782 } 783 return null; 784 } 785 786 789 public void replaceSelection(String text) { 790 replaceSelection(text, false); 791 } 792 793 796 public void replaceSelection(String text, boolean regExReplace) { 797 Point s= TextViewer.this.getSelectedRange(); 798 if (s.x > -1 && s.y > -1) { 799 try { 800 IRegion matchRegion= TextViewer.this.getFindReplaceDocumentAdapter().replace(text, regExReplace); 801 int length= -1; 802 if (matchRegion != null) 803 length= matchRegion.getLength(); 804 805 if (text != null && length > 0) 806 TextViewer.this.setSelectedRange(s.x, length); 807 } catch (BadLocationException x) { 808 } 809 } 810 } 811 812 815 public boolean isEditable() { 816 return TextViewer.this.isEditable(); 817 } 818 819 822 public Point getSelection() { 823 Point modelSelection= TextViewer.this.getSelectedRange(); 824 return modelSelection2WidgetSelection(modelSelection); 825 } 826 827 830 public int findAndSelect(int widgetOffset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord) { 831 try { 832 return findAndSelect(widgetOffset, findString, searchForward, caseSensitive, wholeWord, false); 833 } catch (PatternSyntaxException x) { 834 return -1; 835 } 836 } 837 838 841 public int findAndSelect(int widgetOffset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord, boolean regExSearch) { 842 843 int modelOffset= widgetOffset == -1 ? -1 : widgetOffset2ModelOffset(widgetOffset); 844 845 if (fRange != null) { 846 IRegion range= fRange.getRange(); 847 modelOffset= TextViewer.this.findAndSelectInRange(modelOffset, findString, searchForward, caseSensitive, wholeWord, range.getOffset(), range.getLength(), regExSearch); 848 } else { 849 modelOffset= TextViewer.this.findAndSelect(modelOffset, findString, searchForward, caseSensitive, wholeWord, regExSearch); 850 } 851 852 widgetOffset= modelOffset == -1 ? -1 : modelOffset2WidgetOffset(modelOffset); 853 return widgetOffset; 854 } 855 856 859 public boolean canPerformFind() { 860 return TextViewer.this.canPerformFind(); 861 } 862 863 867 public void beginSession() { 868 fRange= null; 869 } 870 871 875 public void endSession() { 876 if (fRange != null) { 877 fRange.uninstall(); 878 fRange= null; 879 } 880 } 881 882 886 public IRegion getScope() { 887 return fRange == null ? null : fRange.getRange(); 888 } 889 890 894 public Point getLineSelection() { 895 Point point= TextViewer.this.getSelectedRange(); 896 897 try { 898 IDocument document= TextViewer.this.getDocument(); 899 900 int line= document.getLineOfOffset(point.x); 902 int offset= document.getLineOffset(line); 903 904 IRegion lastLineInfo= document.getLineInformationOfOffset(point.x + point.y); 906 int lastLine= document.getLineOfOffset(point.x + point.y); 907 int length; 908 if (lastLineInfo.getOffset() == point.x + point.y && lastLine > 0) 909 length= document.getLineOffset(lastLine - 1) + document.getLineLength(lastLine - 1) - offset; 910 else 911 length= lastLineInfo.getOffset() + lastLineInfo.getLength() - offset; 912 913 return new Point(offset, length); 914 915 } catch (BadLocationException e) { 916 return new Point(point.x, 0); 918 } 919 } 920 921 925 public void setSelection(int modelOffset, int modelLength) { 926 TextViewer.this.setSelectedRange(modelOffset, modelLength); 927 } 928 929 933 public void setScope(IRegion scope) { 934 if (fRange != null) 935 fRange.uninstall(); 936 937 if (scope == null) { 938 fRange= null; 939 return; 940 } 941 942 fRange= new FindReplaceRange(scope); 943 fRange.setHighlightColor(fScopeHighlightColor); 944 fRange.install(); 945 } 946 947 951 public void setScopeHighlightColor(Color color) { 952 if (fRange != null) 953 fRange.setHighlightColor(color); 954 fScopeHighlightColor= color; 955 } 956 957 961 public void setReplaceAllMode(boolean replaceAll) { 962 963 965 IDocument document= TextViewer.this.getDocument(); 966 967 if (replaceAll) { 968 969 if (document instanceof IDocumentExtension4) { 970 IDocumentExtension4 extension= (IDocumentExtension4) document; 971 fRewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL); 972 } else { 973 TextViewer.this.setRedraw(false); 974 TextViewer.this.startSequentialRewriteMode(false); 975 976 if (fUndoManager != null) 977 fUndoManager.beginCompoundChange(); 978 979 fRememberedPartitioners= TextUtilities.removeDocumentPartitioners(document); 980 } 981 982 } else { 983 984 if (document instanceof IDocumentExtension4) { 985 IDocumentExtension4 extension= (IDocumentExtension4) document; 986 extension.stopRewriteSession(fRewriteSession); 987 } else { 988 TextViewer.this.setRedraw(true); 989 TextViewer.this.stopSequentialRewriteMode(); 990 991 if (fUndoManager != null) 992 fUndoManager.endCompoundChange(); 993 994 if (fRememberedPartitioners != null) 995 TextUtilities.addDocumentPartitioners(document, fRememberedPartitioners); 996 } 997 } 998 } 999 } 1000 1001 1002 1006 class RewriteTarget implements IRewriteTarget { 1007 1008 1011 public void beginCompoundChange() { 1012 if (fUndoManager != null) 1013 fUndoManager.beginCompoundChange(); 1014 } 1015 1016 1019 public void endCompoundChange() { 1020 if (fUndoManager != null) 1021 fUndoManager.endCompoundChange(); 1022 } 1023 1024 1027 public IDocument getDocument() { 1028 return TextViewer.this.getDocument(); 1029 } 1030 1031 1034 public void setRedraw(boolean redraw) { 1035 TextViewer.this.setRedraw(redraw); 1036 } 1037 } 1038 1039 1046 protected class TextHoverKey { 1047 1048 1049 private String fContentType; 1050 1051 private int fStateMask; 1052 1053 1059 protected TextHoverKey(String contentType, int stateMask) { 1060 Assert.isNotNull(contentType); 1061 fContentType= contentType; 1062 fStateMask= stateMask; 1063 } 1064 1065 1068 public boolean equals(Object obj) { 1069 if (obj == null || obj.getClass() != getClass()) 1070 return false; 1071 TextHoverKey textHoverKey= (TextHoverKey)obj; 1072 return textHoverKey.fContentType.equals(fContentType) && textHoverKey.fStateMask == fStateMask; 1073 } 1074 1075 1078 public int hashCode() { 1079 return fStateMask << 16 | fContentType.hashCode(); 1080 } 1081 1082 1087 private void setStateMask(int stateMask) { 1088 fStateMask= stateMask; 1089 } 1090 } 1091 1092 1103 private final class ViewerState { 1104 1105 private Position fSelection; 1106 1107 private boolean fReverseSelection; 1108 1109 private boolean fSelectionSet; 1110 1111 private Position fStableLine; 1112 1113 private int fStablePixel; 1114 1115 1116 private IPositionUpdater fUpdater; 1117 1118 private IDocument fUpdaterDocument; 1119 1120 private String fUpdaterCategory; 1121 1122 1125 public ViewerState() { 1126 IDocument document= getDocument(); 1127 if (document != null) 1128 connect(document); 1129 } 1130 1131 1136 public Point getSelection() { 1137 if (fSelection == null) 1138 return new Point(-1, -1); 1139 return new Point(fSelection.getOffset(), fSelection.getLength()); 1140 } 1141 1142 1148 public void updateSelection(int offset, int length) { 1149 fSelectionSet= true; 1150 if (fSelection == null) 1151 fSelection= new Position(offset, length); 1152 else 1153 updatePosition(fSelection, offset, length); 1154 } 1155 1156 1163 public void restore(boolean restoreViewport) { 1164 if (isConnected()) 1165 disconnect(); 1166 if (fSelection != null) { 1167 int offset= fSelection.getOffset(); 1168 int length= fSelection.getLength(); 1169 if (fReverseSelection) { 1170 offset-= length; 1171 length= -length; 1172 } 1173 setSelectedRange(offset, length); 1174 if (restoreViewport) 1175 updateViewport(); 1176 } 1177 } 1178 1179 1184 private void updateViewport() { 1185 if (fSelectionSet) { 1186 revealRange(fSelection.getOffset(), fSelection.getLength()); 1187 } else if (fStableLine != null) { 1188 int stableLine; 1189 try { 1190 stableLine= fUpdaterDocument.getLineOfOffset(fStableLine.getOffset()); 1191 } catch (BadLocationException x) { 1192 return; 1194 } 1195 int stableWidgetLine= getClosestWidgetLineForModelLine(stableLine); 1196 if (stableWidgetLine == -1) 1197 return; 1198 int linePixel= getTextWidget().getLinePixel(stableWidgetLine); 1199 int delta= fStablePixel - linePixel; 1200 int topPixel= getTextWidget().getTopPixel(); 1201 getTextWidget().setTopPixel(topPixel - delta); 1202 } 1203 } 1204 1205 1210 private void connect(IDocument document) { 1211 Assert.isLegal(document != null); 1212 Assert.isLegal(!isConnected()); 1213 fUpdaterDocument= document; 1214 try { 1215 fUpdaterCategory= SELECTION_POSITION_CATEGORY + hashCode(); 1216 fUpdater= new NonDeletingPositionUpdater(fUpdaterCategory); 1217 fUpdaterDocument.addPositionCategory(fUpdaterCategory); 1218 fUpdaterDocument.addPositionUpdater(fUpdater); 1219 1220 Point selectionRange= getSelectedRange(); 1221 fReverseSelection= selectionRange.y < 0; 1222 int offset, length; 1223 if (fReverseSelection) { 1224 offset= selectionRange.x + selectionRange.y; 1225 length= -selectionRange.y; 1226 } else { 1227 offset= selectionRange.x; 1228 length= selectionRange.y; 1229 } 1230 1231 fSelection= new Position(offset, length); 1232 fSelectionSet= false; 1233 fUpdaterDocument.addPosition(fUpdaterCategory, fSelection); 1234 1235 int stableLine= getStableLine(); 1236 int stableWidgetLine= modelLine2WidgetLine(stableLine); 1237 fStablePixel= getTextWidget().getLinePixel(stableWidgetLine); 1238 IRegion stableLineInfo= fUpdaterDocument.getLineInformation(stableLine); 1239 fStableLine= new Position(stableLineInfo.getOffset(), stableLineInfo.getLength()); 1240 fUpdaterDocument.addPosition(fUpdaterCategory, fStableLine); 1241 } catch (BadPositionCategoryException e) { 1242 Assert.isTrue(false); 1244 } catch (BadLocationException e) { 1245 disconnect(); 1248 } 1249 } 1250 1251 1258 private void updatePosition(Position position, int offset, int length) { 1259 position.setOffset(offset); 1260 position.setLength(length); 1261 position.isDeleted= false; 1263 } 1264 1265 1271 private int getStableLine() { 1272 int stableLine; int caretLine= getTextWidget().getLineAtOffset(getTextWidget().getCaretOffset()); 1274 if (caretLine < JFaceTextUtil.getPartialTopIndex(getTextWidget()) || caretLine > JFaceTextUtil.getPartialBottomIndex(getTextWidget())) { 1275 stableLine= JFaceTextUtil.getPartialTopIndex(TextViewer.this); 1276 } else { 1277 stableLine= widgetLine2ModelLine(caretLine); 1278 } 1279 return stableLine; 1280 } 1281 1282 1288 private boolean isConnected() { 1289 return fUpdater != null; 1290 } 1291 1292 1295 private void disconnect() { 1296 Assert.isTrue(isConnected()); 1297 try { 1298 fUpdaterDocument.removePosition(fUpdaterCategory, fSelection); 1299 fUpdaterDocument.removePosition(fUpdaterCategory, fStableLine); 1300 fUpdaterDocument.removePositionUpdater(fUpdater); 1301 fUpdater= null; 1302 fUpdaterDocument.removePositionCategory(fUpdaterCategory); 1303 fUpdaterCategory= null; 1304 } catch (BadPositionCategoryException x) { 1305 Assert.isTrue(false); 1307 } 1308 } 1309 } 1310 1311 1316 private class CursorListener implements KeyListener, MouseListener { 1317 1318 1321 private void install() { 1322 if (fTextWidget != null && !fTextWidget.isDisposed()) { 1323 fTextWidget.addKeyListener(this); 1324 fTextWidget.addMouseListener(this); 1325 } 1326 } 1327 1328 1331 private void uninstall() { 1332 if (fTextWidget != null && !fTextWidget.isDisposed()) { 1333 fTextWidget.removeKeyListener(this); 1334 fTextWidget.removeMouseListener(this); 1335 } 1336 } 1337 1338 1341 public void keyPressed(KeyEvent event) { 1342 } 1343 1344 1347 public void keyReleased(KeyEvent e) { 1348 if (fTextWidget.getSelectionCount() == 0) { 1349 fLastSentSelectionChange= null; 1350 queuePostSelectionChanged(e.character == SWT.DEL); 1351 } 1352 } 1353 1354 1357 public void mouseDoubleClick(MouseEvent e) { 1358 } 1359 1360 1363 public void mouseDown(MouseEvent e) { 1364 } 1365 1366 1369 public void mouseUp(MouseEvent event) { 1370 if (fTextWidget.getSelectionCount() == 0) 1371 queuePostSelectionChanged(false); 1372 } 1373 } 1374 1375 1379 private class DocumentRewriteSessionListener implements IDocumentRewriteSessionListener { 1380 1381 1384 public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) { 1385 IRewriteTarget target= TextViewer.this.getRewriteTarget(); 1386 boolean toggleRedraw= true || event.getSession().getSessionType() != DocumentRewriteSessionType.UNRESTRICTED_SMALL; 1389 final boolean viewportStabilize= !toggleRedraw; 1390 if (DocumentRewriteSessionEvent.SESSION_START == event.getChangeType()) { 1391 if (toggleRedraw) 1392 target.setRedraw(false); 1393 target.beginCompoundChange(); 1394 if (viewportStabilize && fViewerState == null) 1395 fViewerState= new ViewerState(); 1396 } else if (DocumentRewriteSessionEvent.SESSION_STOP == event.getChangeType()) { 1397 if (viewportStabilize && fViewerState != null) { 1398 fViewerState.restore(true); 1399 fViewerState= null; 1400 } 1401 target.endCompoundChange(); 1402 if (toggleRedraw) 1403 target.setRedraw(true); 1404 } 1405 } 1406 } 1407 1408 1409 1412 protected static final int SCROLLER= 1; 1413 1416 protected static final int MOUSE= 2; 1417 1420 protected static final int MOUSE_END= 3; 1421 1424 protected static final int KEY= 4; 1425 1428 protected static final int RESIZE= 5; 1429 1432 protected static final int INTERNAL= 6; 1433 1434 1435 protected static final String SHIFTING= "__TextViewer_shifting"; 1437 1441 private static final String SELECTION_POSITION_CATEGORY= "_textviewer_selection_category"; 1443 private StyledText fTextWidget; 1444 1445 private IDocument fDocument; 1446 1447 private IDocument fVisibleDocument; 1448 1449 private IDocumentAdapter fDocumentAdapter; 1450 1451 private ISlaveDocumentManager fSlaveDocumentManager; 1452 1453 private TextDoubleClickStrategyConnector fDoubleClickStrategyConnector; 1454 1455 private ViewportGuard fViewportGuard; 1456 1457 private int fTopInset= 0; 1458 1459 private WidgetCommand fWidgetCommand= new WidgetCommand(); 1460 1461 private ScrollBar fScroller; 1462 1463 private VisibleDocumentListener fVisibleDocumentListener= new VisibleDocumentListener(); 1464 1465 private TextVerifyListener fVerifyListener= new TextVerifyListener(); 1466 1467 private DocumentCommand fDocumentCommand= new DocumentCommand(); 1468 1469 private IFindReplaceTarget fFindReplaceTarget; 1470 1474 private TextViewerHoverManager fTextHoverManager; 1475 1479 private IWidgetTokenKeeper fWidgetTokenKeeper; 1480 1484 private VerifyKeyListenersManager fVerifyKeyListenersManager= new VerifyKeyListenersManager(); 1485 1489 protected Position fMarkPosition; 1490 1494 private final String MARK_POSITION_CATEGORY="__mark_category_" + hashCode(); 1499 private final IPositionUpdater fMarkPositionUpdater= new DefaultPositionUpdater(MARK_POSITION_CATEGORY); 1500 1504 private int fRedrawCounter= 0; 1505 1509 private IRewriteTarget fRewriteTarget; 1510 1514 private CursorListener fCursorListener; 1515 1519 private IRegion fLastSentSelectionChange; 1520 1524 private List fPostSelectionChangedListeners; 1525 1529 private final int[] fNumberOfPostSelectionChangedEvents= new int[1]; 1530 1534 private IRegion fLastSentPostSelectionChange; 1535 1539 private Set fEditorHelpers= new HashSet (); 1540 1544 private DocumentRewriteSessionListener fDocumentRewriteSessionListener= new DocumentRewriteSessionListener(); 1545 1546 1547 protected boolean fIgnoreAutoIndent= false; 1548 1549 protected Map fIndentChars; 1550 1551 protected Map fDefaultPrefixChars; 1552 1553 protected Map fDoubleClickStrategies; 1554 1555 protected IUndoManager fUndoManager; 1556 1557 protected Map fAutoIndentStrategies; 1558 1559 protected Map fTextHovers; 1560 1561 protected List fViewportListeners; 1562 1563 protected int fLastTopPixel; 1564 1565 protected List fTextListeners; 1566 1567 protected List fTextInputListeners; 1568 1569 protected IEventConsumer fEventConsumer; 1570 1571 protected boolean fReplaceTextPresentation= false; 1572 1576 protected IInformationControlCreator fHoverControlCreator; 1577 1581 protected IDocumentInformationMapping fInformationMapping; 1582 1586 protected PaintManager fPaintManager; 1587 1591 protected String fPartitioning; 1592 1596 protected List fTextPresentationListeners; 1597 1601 protected FindReplaceDocumentAdapter fFindReplaceDocumentAdapter; 1602 1603 1607 protected IHyperlinkDetector[] fHyperlinkDetectors; 1608 1612 protected IHyperlinkPresenter fHyperlinkPresenter; 1613 1617 protected HyperlinkManager fHyperlinkManager; 1618 1623 protected int fHyperlinkStateMask; 1624 1628 private ViewerState fViewerState; 1629 1633 private IAutoEditStrategy fTabsToSpacesConverter; 1634 1635 1636 1638 1639 1642 protected TextViewer() { 1643 } 1644 1645 1653 public TextViewer(Composite parent, int styles) { 1654 createControl(parent, styles); 1655 } 1656 1657 1664 protected StyledText createTextWidget(Composite parent, int styles) { 1665 return new StyledText(parent, styles); 1666 } 1667 1668 1673 protected IDocumentAdapter createDocumentAdapter() { 1674 return new DefaultDocumentAdapter(); 1675 } 1676 1677 1684 protected void createControl(Composite parent, int styles) { 1685 1686 fTextWidget= createTextWidget(parent, styles); 1687 1688 fTextWidget.addListener(SWT.MouseWheel, new Listener() { 1690 public void handleEvent(Event event) { 1691 if (((event.stateMask & SWT.MOD1) == 0)) 1692 return; 1693 1694 int topIndex= fTextWidget.getTopIndex(); 1695 int bottomIndex= JFaceTextUtil.getBottomIndex(fTextWidget); 1696 1697 if (event.count > 0) 1698 fTextWidget.setTopIndex(2 * topIndex - bottomIndex); 1699 else 1700 fTextWidget.setTopIndex(bottomIndex); 1701 1702 updateViewportListeners(INTERNAL); 1703 } 1704 }); 1705 1706 fTextWidget.addDisposeListener( 1707 new DisposeListener() { 1708 public void widgetDisposed(DisposeEvent e) { 1709 handleDispose(); 1710 } 1711 } 1712 ); 1713 1714 fTextWidget.setFont(parent.getFont()); 1715 fTextWidget.setDoubleClickEnabled(true); 1716 1717 1721 fTextWidget.addTraverseListener(new TraverseListener() { 1722 public void keyTraversed(TraverseEvent e) { 1723 if ((SWT.SHIFT == e.stateMask) && ('\t' == e.character)) 1724 e.doit= false; 1725 } 1726 }); 1727 1728 fTopInset= -fTextWidget.computeTrim(0, 0, 0, 0).y; 1730 1731 fVerifyListener.forward(true); 1732 fTextWidget.addVerifyListener(fVerifyListener); 1733 1734 fTextWidget.addSelectionListener(new SelectionListener() { 1735 public void widgetDefaultSelected(SelectionEvent event) { 1736 selectionChanged(event.x, event.y - event.x); 1737 } 1738 public void widgetSelected(SelectionEvent event) { 1739 selectionChanged(event.x, event.y - event.x); 1740 } 1741 }); 1742 1743 fCursorListener= new CursorListener(); 1744 fCursorListener.install(); 1745 1746 initializeViewportUpdate(); 1747 } 1748 1749 1752 public Control getControl() { 1753 return fTextWidget; 1754 } 1755 1756 1759 public void activatePlugins() { 1760 1761 if (fDoubleClickStrategies != null && !fDoubleClickStrategies.isEmpty() && fDoubleClickStrategyConnector == null) { 1762 fDoubleClickStrategyConnector= new TextDoubleClickStrategyConnector(); 1763 fTextWidget.addWordMovementListener(fDoubleClickStrategyConnector); 1764 fTextWidget.addMouseListener(fDoubleClickStrategyConnector); 1765 } 1766 1767 ensureHoverControlManagerInstalled(); 1768 ensureHyperlinkManagerInstalled(); 1769 1770 if (fUndoManager != null) { 1771 fUndoManager.connect(this); 1772 fUndoManager.reset(); 1773 } 1774 } 1775 1776 1779 private void ensureHoverControlManagerInstalled() { 1780 if (fTextHovers != null && !fTextHovers.isEmpty() && fHoverControlCreator != null && fTextHoverManager == null) { 1781 fTextHoverManager= new TextViewerHoverManager(this, fHoverControlCreator); 1782 fTextHoverManager.install(this.getTextWidget()); 1783 fTextHoverManager.setSizeConstraints(60, 10, false, true); 1784 } 1785 } 1786 1787 1790 public void resetPlugins() { 1791 if (fUndoManager != null) 1792 fUndoManager.reset(); 1793 } 1794 1795 1799 protected void handleDispose() { 1800 1801 setDocument(null); 1802 1803 if (fPaintManager != null) { 1804 fPaintManager.dispose(); 1805 fPaintManager= null; 1806 } 1807 1808 removeViewPortUpdate(); 1809 fViewportGuard= null; 1810 1811 if (fViewportListeners != null) { 1812 fViewportListeners.clear(); 1813 fViewportListeners= null; 1814 } 1815 1816 if (fTextListeners != null) { 1817 fTextListeners.clear(); 1818 fTextListeners= null; 1819 } 1820 1821 if (fTextInputListeners != null) { 1822 fTextInputListeners.clear(); 1823 fTextInputListeners= null; 1824 } 1825 1826 if (fPostSelectionChangedListeners != null) { 1827 fPostSelectionChangedListeners.clear(); 1828 fPostSelectionChangedListeners= null; 1829 } 1830 1831 if (fAutoIndentStrategies != null) { 1832 fAutoIndentStrategies.clear(); 1833 fAutoIndentStrategies= null; 1834 } 1835 1836 if (fUndoManager != null) { 1837 fUndoManager.disconnect(); 1838 fUndoManager= null; 1839 } 1840 1841 if (fDoubleClickStrategies != null) { 1842 fDoubleClickStrategies.clear(); 1843 fDoubleClickStrategies= null; 1844 } 1845 1846 if (fTextHovers != null) { 1847 fTextHovers.clear(); 1848 fTextHovers= null; 1849 } 1850 1851 fDoubleClickStrategyConnector= null; 1852 1853 if (fTextHoverManager != null) { 1854 fTextHoverManager.dispose(); 1855 fTextHoverManager= null; 1856 } 1857 1858 if (fVisibleDocumentListener !=null) { 1859 if (fVisibleDocument != null) 1860 fVisibleDocument.removeDocumentListener(fVisibleDocumentListener); 1861 fVisibleDocumentListener= null; 1862 } 1863 1864 if (fDocumentAdapter != null) { 1865 fDocumentAdapter.setDocument(null); 1866 fDocumentAdapter= null; 1867 } 1868 1869 if (fSlaveDocumentManager != null) { 1870 if (fVisibleDocument != null) 1871 fSlaveDocumentManager.freeSlaveDocument(fVisibleDocument); 1872 fSlaveDocumentManager= null; 1873 } 1874 1875 if (fCursorListener != null) { 1876 fCursorListener.uninstall(); 1877 fCursorListener= null; 1878 } 1879 1880 if (fHyperlinkManager != null) { 1881 fHyperlinkManager.uninstall(); 1882 fHyperlinkManager= null; 1883 } 1884 1885 fHyperlinkDetectors= null; 1886 fVisibleDocument= null; 1887 fDocument= null; 1888 fScroller= null; 1889 1890 fTextWidget= null; 1891 } 1892 1893 1894 1896 1899 public StyledText getTextWidget() { 1900 return fTextWidget; 1901 } 1902 1903 1916 protected int getEmptySelectionChangedEventDelay() { 1917 return 500; 1918 } 1919 1920 1926 public void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType) { 1927 setAutoEditStrategies(new IAutoEditStrategy[] { strategy }, contentType); 1928 } 1929 1930 1937 protected final void setAutoEditStrategies(IAutoEditStrategy[] strategies, String contentType) { 1938 if (fAutoIndentStrategies == null) 1939 fAutoIndentStrategies= new HashMap (); 1940 1941 List autoEditStrategies= (List ) fAutoIndentStrategies.get(contentType); 1942 1943 if (strategies == null) { 1944 if (autoEditStrategies == null) 1945 return; 1946 1947 fAutoIndentStrategies.put(contentType, null); 1948 1949 } else { 1950 if (autoEditStrategies == null) { 1951 autoEditStrategies= new ArrayList (); 1952 fAutoIndentStrategies.put(contentType, autoEditStrategies); 1953 } 1954 1955 autoEditStrategies.clear(); 1956 autoEditStrategies.addAll(Arrays.asList(strategies)); 1957 } 1958 } 1959 1960 1964 public void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType) { 1965 1966 if (strategy == null || contentType == null) 1967 throw new IllegalArgumentException (); 1968 1969 if (fAutoIndentStrategies == null) 1970 fAutoIndentStrategies= new HashMap (); 1971 1972 List autoEditStrategies= (List ) fAutoIndentStrategies.get(contentType); 1973 if (autoEditStrategies == null) { 1974 autoEditStrategies= new ArrayList (); 1975 fAutoIndentStrategies.put(contentType, autoEditStrategies); 1976 } 1977 1978 autoEditStrategies.add(0, strategy); 1979 } 1980 1981 1985 public void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType) { 1986 if (fAutoIndentStrategies == null) 1987 return; 1988 1989 List autoEditStrategies= (List ) fAutoIndentStrategies.get(contentType); 1990 if (autoEditStrategies == null) 1991 return; 1992 1993 for (final Iterator iterator= autoEditStrategies.iterator(); iterator.hasNext(); ) { 1994 if (iterator.next().equals(strategy)) { 1995 iterator.remove(); 1996 break; 1997 } 1998 } 1999 2000 if (autoEditStrategies.isEmpty()) 2001 fAutoIndentStrategies.put(contentType, null); 2002 } 2003 2004 2007 public void setEventConsumer(IEventConsumer consumer) { 2008 fEventConsumer= consumer; 2009 } 2010 2011 2014 public void setIndentPrefixes(String [] indentPrefixes, String contentType) { 2015 2016 int i= -1; 2017 boolean ok= (indentPrefixes != null); 2018 while (ok && ++i < indentPrefixes.length) 2019 ok= (indentPrefixes[i] != null); 2020 2021 if (ok) { 2022 2023 if (fIndentChars == null) 2024 fIndentChars= new HashMap (); 2025 2026 fIndentChars.put(contentType, indentPrefixes); 2027 2028 } else if (fIndentChars != null) 2029 fIndentChars.remove(contentType); 2030 } 2031 2032 2035 public int getTopInset() { 2036 return fTopInset; 2037 } 2038 2039 2042 public boolean isEditable() { 2043 if (fTextWidget == null) 2044 return false; 2045 return fTextWidget.getEditable(); 2046 } 2047 2048 2051 public void setEditable(boolean editable) { 2052 if (fTextWidget != null) 2053 fTextWidget.setEditable(editable); 2054 } 2055 2056 2060 public void setDefaultPrefixes(String [] defaultPrefixes, String contentType) { 2061 2062 if (defaultPrefixes != null && defaultPrefixes.length > 0) { 2063 if (fDefaultPrefixChars == null) 2064 fDefaultPrefixChars= new HashMap (); 2065 fDefaultPrefixChars.put(contentType, defaultPrefixes); 2066 } else if (fDefaultPrefixChars != null) 2067 fDefaultPrefixChars.remove(contentType); 2068 } 2069 2070 2073 public void setUndoManager(IUndoManager undoManager) { 2074 fUndoManager= undoManager; 2075 } 2076 2077 2081 public IUndoManager getUndoManager() { 2082 return fUndoManager; 2083 } 2084 2085 2088 public void setTextHover(ITextHover hover, String contentType) { 2089 setTextHover(hover, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); 2090 } 2091 2092 2096 public void setTextHover(ITextHover hover, String contentType, int stateMask) { 2097 TextHoverKey key= new TextHoverKey(contentType, stateMask); 2098 if (hover != null) { 2099 if (fTextHovers == null) { 2100 fTextHovers= new HashMap (); 2101 } 2102 fTextHovers.put(key, hover); 2103 } else if (fTextHovers != null) 2104 fTextHovers.remove(key); 2105 2106 ensureHoverControlManagerInstalled(); 2107 } 2108 2109 2113 public void removeTextHovers(String contentType) { 2114 if (fTextHovers == null) 2115 return; 2116 2117 Iterator iter= new HashSet (fTextHovers.keySet()).iterator(); 2118 while (iter.hasNext()) { 2119 TextHoverKey key= (TextHoverKey)iter.next(); 2120 if (key.fContentType.equals(contentType)) 2121 fTextHovers.remove(key); 2122 } 2123 } 2124 2125 2131 protected ITextHover getTextHover(int offset) { 2132 return getTextHover(offset, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); 2133 } 2134 2135 2143 protected ITextHover getTextHover(int offset, int stateMask) { 2144 if (fTextHovers == null) 2145 return null; 2146 2147 IDocument document= getDocument(); 2148 if (document == null) 2149 return null; 2150 2151 try { 2152 TextHoverKey key= new TextHoverKey(TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true), stateMask); 2153 Object textHover= fTextHovers.get(key); 2154 if (textHover == null) { 2155 key.setStateMask(ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); 2157 textHover= fTextHovers.get(key); 2158 } 2159 return (ITextHover) textHover; 2160 } catch (BadLocationException x) { 2161 if (TRACE_ERRORS) 2162 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.selectContentTypePlugin")); } 2164 return null; 2165 } 2166 2167 2173 protected AbstractInformationControlManager getTextHoveringController() { 2174 return fTextHoverManager; 2175 } 2176 2177 2183 public void setHoverControlCreator(IInformationControlCreator creator) { 2184 fHoverControlCreator= creator; 2185 } 2186 2187 2191 public boolean requestWidgetToken(IWidgetTokenKeeper requester) { 2192 if (fTextWidget != null) { 2193 if (fWidgetTokenKeeper != null) { 2194 if (fWidgetTokenKeeper == requester) 2195 return true; 2196 if (fWidgetTokenKeeper.requestWidgetToken(this)) { 2197 fWidgetTokenKeeper= requester; 2198 return true; 2199 } 2200 } else { 2201 fWidgetTokenKeeper= requester; 2202 return true; 2203 } 2204 } 2205 return false; 2206 } 2207 2208 2212 public boolean requestWidgetToken(IWidgetTokenKeeper requester, int priority) { 2213 if (fTextWidget != null) { 2214 if (fWidgetTokenKeeper != null) { 2215 2216 if (fWidgetTokenKeeper == requester) 2217 return true; 2218 2219 boolean accepted= false; 2220 if (fWidgetTokenKeeper instanceof IWidgetTokenKeeperExtension) { 2221 IWidgetTokenKeeperExtension extension= (IWidgetTokenKeeperExtension) fWidgetTokenKeeper; 2222 accepted= extension.requestWidgetToken(this, priority); 2223 } else { 2224 accepted= fWidgetTokenKeeper.requestWidgetToken(this); 2225 } 2226 2227 if (accepted) { 2228 fWidgetTokenKeeper= requester; 2229 return true; 2230 } 2231 2232 } else { 2233 fWidgetTokenKeeper= requester; 2234 return true; 2235 } 2236 } 2237 return false; 2238 } 2239 2240 2244 public void releaseWidgetToken(IWidgetTokenKeeper tokenKeeper) { 2245 if (fWidgetTokenKeeper == tokenKeeper) 2246 fWidgetTokenKeeper= null; 2247 } 2248 2249 2250 2252 2255 public Point getSelectedRange() { 2256 2257 if (!redraws() && fViewerState != null) 2258 return fViewerState.getSelection(); 2259 2260 if (fTextWidget != null) { 2261 Point p= fTextWidget.getSelectionRange(); 2262 p= widgetSelection2ModelSelection(p); 2263 if (p != null) 2264 return p; 2265 } 2266 2267 return new Point(-1, -1); 2268 } 2269 2270 2273 public void setSelectedRange(int selectionOffset, int selectionLength) { 2274 2275 if (!redraws()) { 2276 if (fViewerState != null) 2277 fViewerState.updateSelection(selectionOffset, selectionLength); 2278 return; 2279 } 2280 2281 if (fTextWidget == null) 2282 return; 2283 2284 IRegion widgetSelection= modelRange2ClosestWidgetRange(new Region(selectionOffset, selectionLength)); 2285 if (widgetSelection != null) { 2286 2287 int[] selectionRange= new int[] { widgetSelection.getOffset(), widgetSelection.getLength() }; 2288 validateSelectionRange(selectionRange); 2289 if (selectionRange[0] >= 0) { 2290 fTextWidget.setSelectionRange(selectionRange[0], selectionRange[1]); 2291 selectionChanged(selectionRange[0], selectionRange[1]); 2292 } 2293 } 2294 } 2295 2296 2310 protected void validateSelectionRange(int[] selectionRange) { 2311 2312 IDocument document= getVisibleDocument(); 2313 if (document == null) { 2314 selectionRange[0]= -1; 2315 selectionRange[1]= -1; 2316 return; 2317 } 2318 2319 int documentLength= document.getLength(); 2320 int offset= selectionRange[0]; 2321 int length= selectionRange[1]; 2322 2323 if (length < 0) { 2324 length= - length; 2325 offset -= length; 2326 } 2327 2328 if (offset <0) 2329 offset= 0; 2330 2331 if (offset > documentLength) 2332 offset= documentLength; 2333 2334 int delta= (offset + length) - documentLength; 2335 if (delta > 0) 2336 length -= delta; 2337 2338 try { 2339 2340 int lineNumber= document.getLineOfOffset(offset); 2341 IRegion lineInformation= document.getLineInformation(lineNumber); 2342 2343 int lineEnd= lineInformation.getOffset() + lineInformation.getLength(); 2344 delta= offset - lineEnd; 2345 if (delta > 0) { 2346 offset= lineEnd; 2348 String delimiter= document.getLineDelimiter(lineNumber); 2349 if (delimiter != null) 2350 offset += delimiter.length(); 2351 } 2352 2353 int end= offset + length; 2354 lineInformation= document.getLineInformationOfOffset(end); 2355 lineEnd= lineInformation.getOffset() + lineInformation.getLength(); 2356 delta= end - lineEnd; 2357 if (delta > 0) { 2358 length -= delta; 2360 } 2361 2362 } catch (BadLocationException x) { 2363 selectionRange[0]= -1; 2364 selectionRange[1]= -1; 2365 return; 2366 } 2367 2368 if (selectionRange[1] < 0) { 2369 selectionRange[0]= offset + length; 2370 selectionRange[1]= -length; 2371 } else { 2372 selectionRange[0]= offset; 2373 selectionRange[1]= length; 2374 } 2375 } 2376 2377 2380 public void setSelection(ISelection selection, boolean reveal) { 2381 if (selection instanceof ITextSelection) { 2382 ITextSelection s= (ITextSelection) selection; 2383 setSelectedRange(s.getOffset(), s.getLength()); 2384 if (reveal) 2385 revealRange(s.getOffset(), s.getLength()); 2386 } 2387 } 2388 2389 2392 public ISelection getSelection() { 2393 Point p= getSelectedRange(); 2394 if (p.x == -1 || p.y == -1) 2395 return TextSelection.emptySelection(); 2396 2397 return new TextSelection(getDocument(), p.x, p.y); 2398 } 2399 2400 2403 public ISelectionProvider getSelectionProvider() { 2404 return this; 2405 } 2406 2407 2411 public void addPostSelectionChangedListener(ISelectionChangedListener listener) { 2412 2413 Assert.isNotNull(listener); 2414 2415 if (fPostSelectionChangedListeners == null) 2416 fPostSelectionChangedListeners= new ArrayList (); 2417 2418 if (! fPostSelectionChangedListeners.contains(listener)) 2419 fPostSelectionChangedListeners.add(listener); 2420 } 2421 2422 2426 public void removePostSelectionChangedListener(ISelectionChangedListener listener) { 2427 2428 Assert.isNotNull(listener); 2429 2430 if (fPostSelectionChangedListeners != null) { 2431 fPostSelectionChangedListeners.remove(listener); 2432 if (fPostSelectionChangedListeners.size() == 0) 2433 fPostSelectionChangedListeners= null; 2434 } 2435 } 2436 2437 2443 private Display getDisplay() { 2444 if (fTextWidget == null || fTextWidget.isDisposed()) 2445 return null; 2446 2447 Display display= fTextWidget.getDisplay(); 2448 if (display != null && display.isDisposed()) 2449 return null; 2450 2451 return display; 2452 } 2453 2454 2460 private void queuePostSelectionChanged(final boolean fireEqualSelection) { 2461 Display display= getDisplay(); 2462 if (display == null) 2463 return; 2464 2465 fNumberOfPostSelectionChangedEvents[0]++; 2466 display.timerExec(getEmptySelectionChangedEventDelay(), new Runnable () { 2467 final int id= fNumberOfPostSelectionChangedEvents[0]; 2468 public void run() { 2469 if (id == fNumberOfPostSelectionChangedEvents[0]) { 2470 if (getDisplay() != null) { 2472 Point selection= fTextWidget.getSelectionRange(); 2473 if (selection != null) { 2474 IRegion r= widgetRange2ModelRange(new Region(selection.x, selection.y)); 2475 if (fireEqualSelection || (r != null && !r.equals(fLastSentPostSelectionChange)) || r == null) { 2476 fLastSentPostSelectionChange= r; 2477 firePostSelectionChanged(selection.x, selection.y); 2478 } 2479 } 2480 } 2481 } 2482 } 2483 }); 2484 } 2485 2486 2493 protected void firePostSelectionChanged(int offset, int length) { 2494 if (redraws()) { 2495 IRegion r= widgetRange2ModelRange(new Region(offset, length)); 2496 ISelection selection= r != null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection(); 2497 SelectionChangedEvent event= new SelectionChangedEvent(this, selection); 2498 firePostSelectionChanged(event); 2499 } 2500 } 2501 2502 2510 protected void selectionChanged(int offset, int length) { 2511 queuePostSelectionChanged(true); 2512 fireSelectionChanged(offset, length); 2513 } 2514 2515 2522 protected void fireSelectionChanged(int offset, int length) { 2523 if (redraws()) { 2524 IRegion r= widgetRange2ModelRange(new Region(offset, length)); 2525 if ((r != null && !r.equals(fLastSentSelectionChange)) || r == null) { 2526 fLastSentSelectionChange= r; 2527 ISelection selection= r != null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection(); 2528 SelectionChangedEvent event= new SelectionChangedEvent(this, selection); 2529 fireSelectionChanged(event); 2530 } 2531 } 2532 } 2533 2534 2540 private void firePostSelectionChanged(SelectionChangedEvent event) { 2541 List listeners= fPostSelectionChangedListeners; 2542 if (listeners != null) { 2543 listeners= new ArrayList (listeners); 2544 for (int i= 0; i < listeners.size(); i++) { 2545 ISelectionChangedListener l= (ISelectionChangedListener) listeners.get(i); 2546 l.selectionChanged(event); 2547 } 2548 } 2549 } 2550 2551 2558 protected void markChanged(int offset, int length) { 2559 if (redraws()) { 2560 2561 if (offset != -1) { 2562 IRegion r= widgetRange2ModelRange(new Region(offset, length)); 2563 offset= r.getOffset(); 2564 length= r.getLength(); 2565 } 2566 2567 ISelection selection= new MarkSelection(getDocument(), offset, length); 2568 SelectionChangedEvent event= new SelectionChangedEvent(this, selection); 2569 fireSelectionChanged(event); 2570 } 2571 } 2572 2573 2574 2576 2579 public void addTextListener(ITextListener listener) { 2580 2581 Assert.isNotNull(listener); 2582 2583 if (fTextListeners == null) 2584 fTextListeners= new ArrayList (); 2585 2586 if (!fTextListeners.contains(listener)) 2587 fTextListeners.add(listener); 2588 } 2589 2590 2593 public void removeTextListener(ITextListener listener) { 2594 2595 Assert.isNotNull(listener); 2596 2597 if (fTextListeners != null) { 2598 fTextListeners.remove(listener); 2599 if (fTextListeners.size() == 0) 2600 fTextListeners= null; 2601 } 2602 } 2603 2604 2610 protected void updateTextListeners(WidgetCommand cmd) { 2611 2612 if (fTextListeners != null) { 2613 2614 DocumentEvent event= cmd.event; 2615 if (event instanceof SlaveDocumentEvent) 2616 event= ((SlaveDocumentEvent) event).getMasterEvent(); 2617 2618 TextEvent e= new TextEvent(cmd.start, cmd.length, cmd.text, cmd.preservedText, event, redraws()); 2619 for (int i= 0; i < fTextListeners.size(); i++) { 2620 ITextListener l= (ITextListener) fTextListeners.get(i); 2621 l.textChanged(e); 2622 } 2623 } 2624 } 2625 2626 2628 2631 public void addTextInputListener(ITextInputListener listener) { 2632 2633 Assert.isNotNull(listener); 2634 2635 if (fTextInputListeners == null) 2636 fTextInputListeners= new ArrayList (); 2637 2638 if (!fTextInputListeners.contains(listener)) 2639 fTextInputListeners.add(listener); 2640 } 2641 2642 2645 public void removeTextInputListener(ITextInputListener listener) { 2646 2647 Assert.isNotNull(listener); 2648 2649 if (fTextInputListeners != null) { 2650 fTextInputListeners.remove(listener); 2651 if (fTextInputListeners.size() == 0) 2652 fTextInputListeners= null; 2653 } 2654 } 2655 2656 2663 protected void fireInputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { 2664 List listener= fTextInputListeners; 2665 if (listener != null) { 2666 for (int i= 0; i < listener.size(); i++) { 2667 ITextInputListener l= (ITextInputListener) listener.get(i); 2668 l.inputDocumentAboutToBeChanged(oldInput, newInput); 2669 } 2670 } 2671 } 2672 2673 2680 protected void fireInputDocumentChanged(IDocument oldInput, IDocument newInput) { 2681 List listener= fTextInputListeners; 2682 if (listener != null) { 2683 for (int i= 0; i < listener.size(); i++) { 2684 ITextInputListener l= (ITextInputListener) listener.get(i); 2685 l.inputDocumentChanged(oldInput, newInput); 2686 } 2687 } 2688 } 2689 2690 2692 2695 public Object getInput() { 2696 return getDocument(); 2697 } 2698 2699 2702 public IDocument getDocument() { 2703 return fDocument; 2704 } 2705 2706 2709 public void setInput(Object input) { 2710 2711 IDocument document= null; 2712 if (input instanceof IDocument) 2713 document= (IDocument) input; 2714 2715 setDocument(document); 2716 } 2717 2718 2721 public void setDocument(IDocument document) { 2722 2723 fReplaceTextPresentation= true; 2724 fireInputDocumentAboutToBeChanged(fDocument, document); 2725 2726 IDocument oldDocument= fDocument; 2727 fDocument= document; 2728 2729 setVisibleDocument(fDocument); 2730 2731 resetPlugins(); 2732 inputChanged(fDocument, oldDocument); 2733 2734 fireInputDocumentChanged(oldDocument, fDocument); 2735 fLastSentSelectionChange= null; 2736 fReplaceTextPresentation= false; 2737 } 2738 2739 2742 public void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength) { 2743 2744 fReplaceTextPresentation= true; 2745 fireInputDocumentAboutToBeChanged(fDocument, document); 2746 2747 IDocument oldDocument= fDocument; 2748 fDocument= document; 2749 2750 try { 2751 2752 IDocument slaveDocument= createSlaveDocument(document); 2753 updateSlaveDocument(slaveDocument, modelRangeOffset, modelRangeLength); 2754 setVisibleDocument(slaveDocument); 2755 2756 } catch (BadLocationException x) { 2757 throw new IllegalArgumentException (JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_1")); } 2759 2760 resetPlugins(); 2761 inputChanged(fDocument, oldDocument); 2762 2763 fireInputDocumentChanged(oldDocument, fDocument); 2764 fLastSentSelectionChange= null; 2765 fReplaceTextPresentation= false; 2766 } 2767 2768 2776 protected IDocument createSlaveDocument(IDocument document) { 2777 ISlaveDocumentManager manager= getSlaveDocumentManager(); 2778 if (manager != null) { 2779 if (manager.isSlaveDocument(document)) 2780 return document; 2781 return manager.createSlaveDocument(document); 2782 } 2783 return document; 2784 } 2785 2786 2797 protected boolean updateVisibleDocument(IDocument visibleDocument, int visibleRegionOffset, int visibleRegionLength) throws BadLocationException { 2798 if (visibleDocument instanceof ChildDocument) { 2799 ChildDocument childDocument= (ChildDocument) visibleDocument; 2800 2801 IDocument document= childDocument.getParentDocument(); 2802 int line= document.getLineOfOffset(visibleRegionOffset); 2803 int offset= document.getLineOffset(line); 2804 int length= (visibleRegionOffset - offset) + visibleRegionLength; 2805 2806 Position parentRange= childDocument.getParentDocumentRange(); 2807 if (offset != parentRange.getOffset() || length != parentRange.getLength()) { 2808 childDocument.setParentDocumentRange(offset, length); 2809 return true; 2810 } 2811 } 2812 return false; 2813 } 2814 2815 2825 protected boolean updateSlaveDocument(IDocument slaveDocument, int modelRangeOffset, int modelRangeLength) throws BadLocationException { 2826 return updateVisibleDocument(slaveDocument, modelRangeOffset, modelRangeLength); 2827 } 2828 2829 2830 2831 2833 2836 private void initializeViewportUpdate() { 2837 2838 if (fViewportGuard != null) 2839 return; 2840 2841 if (fTextWidget != null) { 2842 2843 fViewportGuard= new ViewportGuard(); 2844 fLastTopPixel= -1; 2845 2846 fTextWidget.addKeyListener(fViewportGuard); 2847 fTextWidget.addMouseListener(fViewportGuard); 2848 2849 fScroller= fTextWidget.getVerticalBar(); 2850 if (fScroller != null) 2851 fScroller.addSelectionListener(fViewportGuard); 2852 } 2853 } 2854 2855 2858 private void removeViewPortUpdate() { 2859 2860 if (fTextWidget != null) { 2861 2862 fTextWidget.removeKeyListener(fViewportGuard); 2863 fTextWidget.removeMouseListener(fViewportGuard); 2864 2865 if (fScroller != null && !fScroller.isDisposed()) { 2866 fScroller.removeSelectionListener(fViewportGuard); 2867 fScroller= null; 2868 } 2869 2870 fViewportGuard= null; 2871 } 2872 } 2873 2874 2877 public void addViewportListener(IViewportListener listener) { 2878 2879 if (fViewportListeners == null) { 2880 fViewportListeners= new ArrayList (); 2881 initializeViewportUpdate(); 2882 } 2883 2884 if (!fViewportListeners.contains(listener)) 2885 fViewportListeners.add(listener); 2886 } 2887 2888 2891 public void removeViewportListener(IViewportListener listener) { 2892 if (fViewportListeners != null) 2893 fViewportListeners.remove(listener); 2894 } 2895 2896 2904 protected void updateViewportListeners(int origin) { 2905 2906 if (redraws()) { 2907 int topPixel= fTextWidget.getTopPixel(); 2908 if (topPixel >= 0 && topPixel != fLastTopPixel) { 2909 if (fViewportListeners != null) { 2910 for (int i= 0; i < fViewportListeners.size(); i++) { 2911 IViewportListener l= (IViewportListener) fViewportListeners.get(i); 2912 l.viewportChanged(topPixel); 2913 } 2914 } 2915 fLastTopPixel= topPixel; 2916 } 2917 } 2918 } 2919 2920 2922 2925 public int getTopIndex() { 2926 2927 if (fTextWidget != null) { 2928 int top= fTextWidget.getTopIndex(); 2929 return widgetLine2ModelLine(top); 2930 } 2931 2932 return -1; 2933 } 2934 2935 2938 public void setTopIndex(int index) { 2939 2940 if (fTextWidget != null) { 2941 2942 int widgetLine= modelLine2WidgetLine(index); 2943 if (widgetLine == -1) 2944 widgetLine= getClosestWidgetLineForModelLine(index); 2945 2946 if (widgetLine > -1) { 2947 fTextWidget.setTopIndex(widgetLine); 2948 updateViewportListeners(INTERNAL); 2949 } 2950 } 2951 } 2952 2953 2963 protected int getVisibleLinesInViewport() { 2964 if (fTextWidget != null) { 2965 Rectangle clArea= fTextWidget.getClientArea(); 2966 if (!clArea.isEmpty()) 2967 return clArea.height / fTextWidget.getLineHeight(); 2968 } 2969 return -1; 2970 } 2971 2972 2975 public int getBottomIndex() { 2976 2977 if (fTextWidget == null) 2978 return -1; 2979 2980 int widgetBottom= JFaceTextUtil.getBottomIndex(fTextWidget); 2981 return widgetLine2ModelLine(widgetBottom); 2982 } 2983 2984 2987 public int getTopIndexStartOffset() { 2988 2989 if (fTextWidget != null) { 2990 int top= fTextWidget.getTopIndex(); 2991 try { 2992 top= getVisibleDocument().getLineOffset(top); 2993 return widgetOffset2ModelOffset(top); 2994 } catch (BadLocationException ex) { 2995 if (TRACE_ERRORS) 2996 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getTopIndexStartOffset")); } 2998 } 2999 3000 return -1; 3001 } 3002 3003 3006 public int getBottomIndexEndOffset() { 3007 try { 3008 3009 IRegion line= getDocument().getLineInformation(getBottomIndex()); 3010 int bottomEndOffset= line.getOffset() + line.getLength() - 1; 3011 3012 IRegion coverage= getModelCoverage(); 3013 if (coverage == null) 3014 return -1; 3015 3016 int coverageEndOffset= coverage.getOffset() + coverage.getLength() - 1; 3017 return Math.min(coverageEndOffset, bottomEndOffset); 3018 3019 } catch (BadLocationException ex) { 3020 if (TRACE_ERRORS) 3021 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getBottomIndexEndOffset")); return getDocument().getLength() - 1; 3023 } 3024 } 3025 3026 3029 public void revealRange(int start, int length) { 3030 3031 if (fTextWidget == null || !redraws()) 3032 return; 3033 3034 IRegion modelRange= new Region(start, length); 3035 IRegion widgetRange= modelRange2ClosestWidgetRange(modelRange); 3036 if (widgetRange != null) { 3037 3038 int[] range= new int[] { widgetRange.getOffset(), widgetRange.getLength() }; 3039 validateSelectionRange(range); 3040 if (range[0] >= 0) 3041 internalRevealRange(range[0], range[0] + range[1]); 3042 3043 } else { 3044 3045 IRegion coverage= getModelCoverage(); 3046 int cursor= (coverage == null || start < coverage.getOffset()) ? 0 : getVisibleDocument().getLength(); 3047 internalRevealRange(cursor, cursor); 3048 } 3049 } 3050 3051 3057 protected void internalRevealRange(int start, int end) { 3058 3059 try { 3060 3061 IDocument doc= getVisibleDocument(); 3062 3063 int startLine= doc.getLineOfOffset(start); 3064 int endLine= doc.getLineOfOffset(end); 3065 3066 int top= fTextWidget.getTopIndex(); 3067 if (top > -1) { 3068 3069 int bottom= JFaceTextUtil.getBottomIndex(fTextWidget); 3071 int lines= bottom - top; 3072 3073 3076 if (startLine >= top && startLine <= bottom && endLine >= top && endLine <= bottom ) { 3077 3078 3080 } else { 3081 3082 int delta= Math.max(0, lines - (endLine - startLine)); 3083 fTextWidget.setTopIndex(startLine - delta/3); 3084 updateViewportListeners(INTERNAL); 3085 } 3086 3087 3089 if (endLine < startLine) { 3090 endLine += startLine; 3091 startLine= endLine - startLine; 3092 endLine -= startLine; 3093 } 3094 3095 int startPixel= -1; 3096 int endPixel= -1; 3097 3098 if (endLine > startLine) { 3099 IRegion extent= getExtent(start, start); 3101 startPixel= extent.getOffset() + fTextWidget.getHorizontalPixel(); 3102 endPixel= startPixel; 3103 3104 } else { 3105 IRegion extent= getExtent(start, end); 3106 startPixel= extent.getOffset() + fTextWidget.getHorizontalPixel(); 3107 endPixel= startPixel + extent.getLength(); 3108 } 3109 3110 int visibleStart= fTextWidget.getHorizontalPixel(); 3111 int visibleEnd= visibleStart + fTextWidget.getClientArea().width; 3112 3113 if (startPixel < visibleStart || visibleEnd < endPixel) { 3115 3116 int bufferZone= 10; 3118 3119 int newOffset= visibleStart; 3120 3121 int visibleWidth= visibleEnd - visibleStart; 3122 int selectionPixelWidth= endPixel - startPixel; 3123 3124 if (startPixel < visibleStart) 3125 newOffset= startPixel; 3126 else if (selectionPixelWidth + bufferZone < visibleWidth) 3127 newOffset= endPixel + bufferZone - visibleWidth; 3128 else 3129 newOffset= startPixel; 3130 3131 float index= ((float)newOffset) / ((float)getAverageCharWidth()); 3132 3133 fTextWidget.setHorizontalIndex(Math.round(index)); 3134 } 3135 3136 } 3137 } catch (BadLocationException e) { 3138 throw new IllegalArgumentException (JFaceTextMessages.getString("TextViewer.error.invalid_range")); } 3140 } 3141 3142 3149 final protected int getWidthInPixels(String text) { 3150 GC gc= new GC(fTextWidget); 3151 gc.setFont(fTextWidget.getFont()); 3152 Point extent= gc.textExtent(text); 3153 gc.dispose(); 3154 return extent.x; 3155 } 3156 3157 3168 final protected IRegion getExtent(int start, int end) { 3169 if (end > 0 && start < end) { 3170 Rectangle bounds= fTextWidget.getTextBounds(start, end - 1); 3171 return new Region(bounds.x, bounds.width); 3172 } 3173 3174 return new Region(fTextWidget.getLocationAtOffset(start).x, 0); 3175 } 3176 3177 3187 final protected int getWidthInPixels(int offset, int length) { 3188 return getExtent(offset, offset + length).getLength(); 3189 } 3190 3191 3196 final protected int getAverageCharWidth() { 3197 GC gc= new GC(fTextWidget); 3198 gc.setFont(fTextWidget.getFont()); 3199 int increment= gc.getFontMetrics().getAverageCharWidth(); 3200 gc.dispose(); 3201 return increment; 3202 } 3203 3204 3207 public void refresh() { 3208 setDocument(getDocument()); 3209 } 3210 3211 3213 3219 protected ISlaveDocumentManager getSlaveDocumentManager() { 3220 if (fSlaveDocumentManager == null) 3221 fSlaveDocumentManager= createSlaveDocumentManager(); 3222 return fSlaveDocumentManager; 3223 } 3224 3225 3232 protected ISlaveDocumentManager createSlaveDocumentManager() { 3233 return new ChildDocumentManager(); 3234 } 3235 3236 3239 public final void invalidateTextPresentation() { 3240 if (fVisibleDocument != null) { 3241 fWidgetCommand.event= null; 3242 fWidgetCommand.start= 0; 3243 fWidgetCommand.length= fVisibleDocument.getLength(); 3244 fWidgetCommand.text= fVisibleDocument.get(); 3245 updateTextListeners(fWidgetCommand); 3246 } 3247 } 3248 3249 3256 public final void invalidateTextPresentation(int offset, int length) { 3257 if (fVisibleDocument != null) { 3258 3259 IRegion widgetRange= modelRange2WidgetRange(new Region(offset, length)); 3260 if (widgetRange != null) { 3261 3262 fWidgetCommand.event= null; 3263 fWidgetCommand.start= widgetRange.getOffset(); 3264 fWidgetCommand.length= widgetRange.getLength(); 3265 3266 try { 3267 fWidgetCommand.text= fVisibleDocument.get(widgetRange.getOffset(), widgetRange.getLength()); 3268 updateTextListeners(fWidgetCommand); 3269 } catch (BadLocationException x) { 3270 } 3272 } 3273 } 3274 } 3275 3276 3280 private void initializeWidgetContents() { 3281 3282 if (fTextWidget != null && fVisibleDocument != null) { 3283 3284 if (fDocumentAdapter == null) 3286 fDocumentAdapter= createDocumentAdapter(); 3287 3288 fDocumentAdapter.setDocument(fVisibleDocument); 3289 fTextWidget.setContent(fDocumentAdapter); 3290 3291 invalidateTextPresentation(); 3293 } 3294 } 3295 3296 3302 protected void freeSlaveDocument(IDocument slave) { 3303 ISlaveDocumentManager manager= getSlaveDocumentManager(); 3304 if (manager != null && manager.isSlaveDocument(slave)) 3305 manager.freeSlaveDocument(slave); 3306 } 3307 3308 3314 protected void setVisibleDocument(IDocument document) { 3315 3316 if (fVisibleDocument == document && fVisibleDocument instanceof ChildDocument) { 3317 return; 3319 } 3320 3321 if (fVisibleDocument != null) { 3322 if (fVisibleDocumentListener != null) 3323 fVisibleDocument.removeDocumentListener(fVisibleDocumentListener); 3324 if (fVisibleDocument != document) 3325 freeSlaveDocument(fVisibleDocument); 3326 } 3327 3328 fVisibleDocument= document; 3329 initializeDocumentInformationMapping(fVisibleDocument); 3330 3331 initializeWidgetContents(); 3332 3333 fFindReplaceDocumentAdapter= null; 3334 if (fVisibleDocument != null && fVisibleDocumentListener != null) 3335 fVisibleDocument.addDocumentListener(fVisibleDocumentListener); 3336 } 3337 3338 3346 protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) { 3347 } 3348 3349 3357 protected void handleVisibleDocumentChanged(DocumentEvent event) { 3358 } 3359 3360 3367 protected void initializeDocumentInformationMapping(IDocument visibleDocument) { 3368 ISlaveDocumentManager manager= getSlaveDocumentManager(); 3369 fInformationMapping= manager == null ? null : manager.createMasterSlaveMapping(visibleDocument); 3370 } 3371 3372 3377 protected IDocument getVisibleDocument() { 3378 return fVisibleDocument; 3379 } 3380 3381 3386 protected int _getVisibleRegionOffset() { 3387 3388 IDocument document= getVisibleDocument(); 3389 if (document instanceof ChildDocument) { 3390 ChildDocument cdoc= (ChildDocument) document; 3391 return cdoc.getParentDocumentRange().getOffset(); 3392 } 3393 3394 return 0; 3395 } 3396 3397 3400 public IRegion getVisibleRegion() { 3401 3402 IDocument document= getVisibleDocument(); 3403 if (document instanceof ChildDocument) { 3404 Position p= ((ChildDocument) document).getParentDocumentRange(); 3405 return new Region(p.getOffset(), p.getLength()); 3406 } 3407 3408 return new Region(0, document == null ? 0 : document.getLength()); 3409 } 3410 3411 3414 public boolean overlapsWithVisibleRegion(int start, int length) { 3415 IDocument document= getVisibleDocument(); 3416 if (document instanceof ChildDocument) { 3417 ChildDocument cdoc= (ChildDocument) document; 3418 return cdoc.getParentDocumentRange().overlapsWith(start, length); 3419 } else if (document != null) { 3420 int size= document.getLength(); 3421 return (start >= 0 && length >= 0 && start + length <= size); 3422 } 3423 return false; 3424 } 3425 3426 3429 public void setVisibleRegion(int start, int length) { 3430 3431 IRegion region= getVisibleRegion(); 3432 if (start == region.getOffset() && length == region.getLength()) { 3433 return; 3435 } 3436 3437 setRedraw(false); 3438 try { 3439 3440 IDocument slaveDocument= createSlaveDocument(getVisibleDocument()); 3441 if (updateSlaveDocument(slaveDocument, start, length)) 3442 setVisibleDocument(slaveDocument); 3443 3444 } catch (BadLocationException x) { 3445 throw new IllegalArgumentException (JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_2")); } finally { 3447 setRedraw(true); 3448 } 3449 } 3450 3451 3454 public void resetVisibleRegion() { 3455 ISlaveDocumentManager manager= getSlaveDocumentManager(); 3456 if (manager != null) { 3457 IDocument slave= getVisibleDocument(); 3458 IDocument master= manager.getMasterDocument(slave); 3459 if (master != null) { 3460 setVisibleDocument(master); 3461 manager.freeSlaveDocument(slave); 3462 } 3463 } 3464 } 3465 3466 3467 3469 3472 public void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType) { 3473 3474 if (strategy != null) { 3475 if (fDoubleClickStrategies == null) 3476 fDoubleClickStrategies= new HashMap (); 3477 fDoubleClickStrategies.put(contentType, strategy); 3478 } else if (fDoubleClickStrategies != null) 3479 fDoubleClickStrategies.remove(contentType); 3480 } 3481 3482 3490 protected Object selectContentTypePlugin(int offset, Map plugins) { 3491 try { 3492 return selectContentTypePlugin(TextUtilities.getContentType(getDocument(), getDocumentPartitioning(), offset, true), plugins); 3493 } catch (BadLocationException x) { 3494 if (TRACE_ERRORS) 3495 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.selectContentTypePlugin")); } 3497 return null; 3498 } 3499 3500 3508 private Object selectContentTypePlugin(String type, Map plugins) { 3509 3510 if (plugins == null) 3511 return null; 3512 3513 return plugins.get(type); 3514 } 3515 3516 3524 protected void customizeDocumentCommand(DocumentCommand command) { 3525 if (isIgnoringAutoEditStrategies()) 3526 return; 3527 3528 IDocument document= getDocument(); 3529 3530 if (fTabsToSpacesConverter != null) 3531 fTabsToSpacesConverter.customizeDocumentCommand(document, command); 3532 3533 List strategies= (List ) selectContentTypePlugin(command.offset, fAutoIndentStrategies); 3534 if (strategies == null) 3535 return; 3536 3537 switch (strategies.size()) { 3538 case 0: 3540 break; 3541 3542 case 1: 3543 ((IAutoEditStrategy) strategies.iterator().next()).customizeDocumentCommand(document, command); 3544 break; 3545 3546 default: 3548 strategies= new ArrayList (strategies); 3549 for (final Iterator iterator= strategies.iterator(); iterator.hasNext(); ) 3550 ((IAutoEditStrategy) iterator.next()).customizeDocumentCommand(document, command); 3551 3552 break; 3553 } 3554 } 3555 3556 3562 protected void handleVerifyEvent(VerifyEvent e) { 3563 3564 if (fEventConsumer != null) { 3565 fEventConsumer.processEvent(e); 3566 if (!e.doit) 3567 return; 3568 } 3569 3570 IRegion modelRange= event2ModelRange(e); 3571 fDocumentCommand.setEvent(e, modelRange); 3572 customizeDocumentCommand(fDocumentCommand); 3573 if (!fDocumentCommand.fillEvent(e, modelRange)) { 3574 3575 boolean compoundChange= fDocumentCommand.getCommandCount() > 1; 3576 try { 3577 3578 fVerifyListener.forward(false); 3579 3580 if (compoundChange && fUndoManager != null) 3581 fUndoManager.beginCompoundChange(); 3582 3583 fDocumentCommand.execute(getDocument()); 3584 3585 if (fTextWidget != null) { 3586 int documentCaret= fDocumentCommand.caretOffset; 3587 if (documentCaret == -1) { 3588 documentCaret= fDocumentCommand.offset + (fDocumentCommand.text == null ? 0 : fDocumentCommand.text.length()); 3590 } 3591 3592 int widgetCaret= modelOffset2WidgetOffset(documentCaret); 3593 if (widgetCaret == -1) { 3594 IRegion region= getModelCoverage(); 3596 if (region != null) { 3597 if (documentCaret <= region.getOffset()) 3598 widgetCaret= 0; 3599 else if (documentCaret >= region.getOffset() + region.getLength()) 3600 widgetCaret= getVisibleRegion().getLength(); 3601 } 3602 } 3603 3604 if (widgetCaret != -1) { 3605 fTextWidget.setCaretOffset(widgetCaret); 3607 } 3608 3609 fTextWidget.showSelection(); 3610 } 3611 } catch (BadLocationException x) { 3612 3613 if (TRACE_ERRORS) 3614 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.verifyText")); 3616 } finally { 3617 3618 if (compoundChange && fUndoManager != null) 3619 fUndoManager.endCompoundChange(); 3620 3621 fVerifyListener.forward(true); 3622 3623 } 3624 } 3625 } 3626 3627 3629 3635 private boolean isMarkedRegionEmpty() { 3636 return 3637 fTextWidget == null || 3638 fMarkPosition == null || 3639 fMarkPosition.isDeleted() || 3640 modelRange2WidgetRange(fMarkPosition) == null; 3641 } 3642 3643 3646 public boolean canDoOperation(int operation) { 3647 3648 if (fTextWidget == null || !redraws()) 3649 return false; 3650 3651 switch (operation) { 3652 case CUT: 3653 return isEditable() &&(fTextWidget.getSelectionCount() > 0 || !isMarkedRegionEmpty()); 3654 case COPY: 3655 return fTextWidget.getSelectionCount() > 0 || !isMarkedRegionEmpty(); 3656 case DELETE: 3657 case PASTE: 3658 return isEditable(); 3659 case SELECT_ALL: 3660 return true; 3661 case SHIFT_LEFT: 3662 case SHIFT_RIGHT: 3663 return isEditable() && fIndentChars != null && areMultipleLinesSelected(); 3664 case PREFIX: 3665 case STRIP_PREFIX: 3666 return isEditable() && fDefaultPrefixChars != null; 3667 case UNDO: 3668 return fUndoManager != null && fUndoManager.undoable(); 3669 case REDO: 3670 return fUndoManager != null && fUndoManager.redoable(); 3671 case PRINT: 3672 return isPrintable(); 3673 } 3674 3675 return false; 3676 } 3677 3678 3681 public void doOperation(int operation) { 3682 3683 if (fTextWidget == null || !redraws()) 3684 return; 3685 3686 Point selection= null; 3687 3688 switch (operation) { 3689 3690 case UNDO: 3691 if (fUndoManager != null) { 3692 ignoreAutoEditStrategies(true); 3693 fUndoManager.undo(); 3694 ignoreAutoEditStrategies(false); 3695 } 3696 break; 3697 case REDO: 3698 if (fUndoManager != null) { 3699 ignoreAutoEditStrategies(true); 3700 fUndoManager.redo(); 3701 ignoreAutoEditStrategies(false); 3702 } 3703 break; 3704 case CUT: 3705 if (fTextWidget.getSelectionCount() == 0) 3706 copyMarkedRegion(true); 3707 else 3708 fTextWidget.cut(); 3709 3710 selection= fTextWidget.getSelectionRange(); 3711 fireSelectionChanged(selection.x, selection.y); 3712 3713 break; 3714 case COPY: 3715 if (fTextWidget.getSelectionCount() == 0) 3716 copyMarkedRegion(false); 3717 else 3718 fTextWidget.copy(); 3719 break; 3720 case PASTE: 3721 fTextWidget.paste(); 3723 selection= fTextWidget.getSelectionRange(); 3724 fireSelectionChanged(selection.x, selection.y); 3725 break; 3727 case DELETE: 3728 fTextWidget.invokeAction(ST.DELETE_NEXT); 3729 selection= fTextWidget.getSelectionRange(); 3730 fireSelectionChanged(selection.x, selection.y); 3731 break; 3732 case SELECT_ALL: { 3733 if (getDocument() != null) 3734 setSelectedRange(0, getDocument().getLength()); 3735 break; 3736 } 3737 case SHIFT_RIGHT: 3738 shift(false, true, false); 3739 break; 3740 case SHIFT_LEFT: 3741 shift(false, false, false); 3742 break; 3743 case PREFIX: 3744 shift(true, true, true); 3745 break; 3746 case STRIP_PREFIX: 3747 shift(true, false, true); 3748 break; 3749 case PRINT: 3750 print(); 3751 break; 3752 } 3753 } 3754 3755 3761 protected void ignoreAutoEditStrategies(boolean ignore) { 3762 if (fIgnoreAutoIndent == ignore) 3763 return; 3764 3765 fIgnoreAutoIndent= ignore; 3766 3767 IDocument document= getDocument(); 3768 if (document instanceof IDocumentExtension2) { 3769 IDocumentExtension2 extension= (IDocumentExtension2) document; 3770 if (ignore) 3771 extension.ignorePostNotificationReplaces(); 3772 else 3773 extension.acceptPostNotificationReplaces(); 3774 } 3775 } 3776 3777 3783 protected boolean isIgnoringAutoEditStrategies() { 3784 return fIgnoreAutoIndent; 3785 } 3786 3787 3791 public void enableOperation(int operation, boolean enable) { 3792 3796 } 3797 3798 3804 protected void copyMarkedRegion(boolean delete) { 3805 3806 if (fTextWidget == null) 3807 return; 3808 3809 if (fMarkPosition == null || fMarkPosition.isDeleted() || modelRange2WidgetRange(fMarkPosition) == null) 3810 return; 3811 3812 int widgetMarkOffset= modelOffset2WidgetOffset(fMarkPosition.offset); 3813 Point selection= fTextWidget.getSelection(); 3814 if (selection.x <= widgetMarkOffset) 3815 fTextWidget.setSelection(selection.x, widgetMarkOffset); 3816 else 3817 fTextWidget.setSelection(widgetMarkOffset, selection.x); 3818 3819 if (delete) { 3820 fTextWidget.cut(); 3821 } else { 3822 fTextWidget.copy(); 3823 fTextWidget.setSelection(selection.x); } 3825 } 3826 3827 3834 protected void deleteText() { 3835 fTextWidget.invokeAction(ST.DELETE_NEXT); 3836 } 3837 3838 3844 protected boolean isBlockSelected() { 3845 3846 Point s= getSelectedRange(); 3847 if (s.y == 0) 3848 return false; 3849 3850 try { 3851 3852 IDocument document= getDocument(); 3853 int line= document.getLineOfOffset(s.x); 3854 int start= document.getLineOffset(line); 3855 return (s.x == start); 3856 3857 } catch (BadLocationException x) { 3858 } 3859 3860 return false; 3861 } 3862 3863 3871 protected boolean areMultipleLinesSelected() { 3872 Point s= getSelectedRange(); 3873 if (s.y == 0) 3874 return false; 3875 3876 try { 3877 3878 IDocument document= getDocument(); 3879 int startLine= document.getLineOfOffset(s.x); 3880 int endLine= document.getLineOfOffset(s.x + s.y); 3881 IRegion line= document.getLineInformation(startLine); 3882 return startLine != endLine || (s.x == line.getOffset() && s.y == line.getLength()); 3883 3884 } catch (BadLocationException x) { 3885 } 3886 3887 return false; 3888 } 3889 3890 3896 private int getFirstCompleteLineOfRegion(IRegion region) { 3897 3898 try { 3899 3900 IDocument d= getDocument(); 3901 3902 int startLine= d.getLineOfOffset(region.getOffset()); 3903 3904 int offset= d.getLineOffset(startLine); 3905 if (offset >= region.getOffset()) 3906 return startLine; 3907 3908 offset= d.getLineOffset(startLine + 1); 3909 return (offset > region.getOffset() + region.getLength() ? -1 : startLine + 1); 3910 3911 } catch (BadLocationException x) { 3912 if (TRACE_ERRORS) 3913 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getFirstCompleteLineOfRegion")); } 3915 3916 return -1; 3917 } 3918 3919 3920 3928 private IRegion getTextBlockFromSelection(Point selection) { 3929 3930 try { 3931 IDocument document= getDocument(); 3932 IRegion line= document.getLineInformationOfOffset(selection.x); 3933 int length= selection.y == 0 ? line.getLength() : selection.y + (selection.x - line.getOffset()); 3934 return new Region(line.getOffset(), length); 3935 3936 } catch (BadLocationException x) { 3937 } 3938 3939 return null; 3940 } 3941 3942 3951 protected void shift(boolean useDefaultPrefixes, boolean right) { 3952 shift(useDefaultPrefixes, right, false); 3953 } 3954 3955 3965 protected void shift(boolean useDefaultPrefixes, boolean right, boolean ignoreWhitespace) { 3966 if (fUndoManager != null) 3967 fUndoManager.beginCompoundChange(); 3968 3969 IDocument d= getDocument(); 3970 Map partitioners= null; 3971 DocumentRewriteSession rewriteSession= null; 3972 try { 3973 Point selection= getSelectedRange(); 3974 IRegion block= getTextBlockFromSelection(selection); 3975 ITypedRegion[] regions= TextUtilities.computePartitioning(d, getDocumentPartitioning(), block.getOffset(), block.getLength(), false); 3976 3977 int lineCount= 0; 3978 int[] lines= new int[regions.length * 2]; for (int i= 0, j= 0; i < regions.length; i++, j+= 2) { 3980 lines[j]= getFirstCompleteLineOfRegion(regions[i]); 3982 int length= regions[i].getLength(); 3984 int offset= regions[i].getOffset() + length; 3985 if (length > 0) 3986 offset--; 3987 lines[j + 1]= (lines[j] == -1 ? -1 : d.getLineOfOffset(offset)); 3988 lineCount += lines[j + 1] - lines[j] + 1; 3989 } 3990 3991 if (d instanceof IDocumentExtension4) { 3992 IDocumentExtension4 extension= (IDocumentExtension4) d; 3993 rewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL); 3994 } else { 3995 setRedraw(false); 3996 startSequentialRewriteMode(true); 3997 } 3998 if (lineCount >= 20) 3999 partitioners= TextUtilities.removeDocumentPartitioners(d); 4000 4001 Map map= (useDefaultPrefixes ? fDefaultPrefixChars : fIndentChars); 4003 for (int i= 0, j= 0; i < regions.length; i++, j += 2) { 4004 String [] prefixes= (String []) selectContentTypePlugin(regions[i].getType(), map); 4005 if (prefixes != null && prefixes.length > 0 && lines[j] >= 0 && lines[j + 1] >= 0) { 4006 if (right) 4007 shiftRight(lines[j], lines[j + 1], prefixes[0]); 4008 else 4009 shiftLeft(lines[j], lines[j + 1], prefixes, ignoreWhitespace); 4010 } 4011 } 4012 4013 } catch (BadLocationException x) { 4014 if (TRACE_ERRORS) 4015 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.shift_1")); 4017 } finally { 4018 4019 if (partitioners != null) 4020 TextUtilities.addDocumentPartitioners(d, partitioners); 4021 4022 if (d instanceof IDocumentExtension4) { 4023 IDocumentExtension4 extension= (IDocumentExtension4) d; 4024 extension.stopRewriteSession(rewriteSession); 4025 } else { 4026 stopSequentialRewriteMode(); 4027 setRedraw(true); 4028 } 4029 4030 if (fUndoManager != null) 4031 fUndoManager.endCompoundChange(); 4032 } 4033 } 4034 4035 4044 private void shiftRight(int startLine, int endLine, String prefix) { 4045 4046 try { 4047 4048 IDocument d= getDocument(); 4049 while (startLine <= endLine) { 4050 d.replace(d.getLineOffset(startLine++), 0, prefix); 4051 } 4052 4053 } catch (BadLocationException x) { 4054 if (TRACE_ERRORS) 4055 System.out.println("TextViewer.shiftRight: BadLocationException"); } 4057 } 4058 4059 4071 private void shiftLeft(int startLine, int endLine, String [] prefixes, boolean ignoreWhitespace) { 4072 4073 IDocument d= getDocument(); 4074 4075 try { 4076 4077 IRegion[] occurrences= new IRegion[endLine - startLine + 1]; 4078 4079 for (int i= 0; i < occurrences.length; i++) { 4081 4082 IRegion line= d.getLineInformation(startLine + i); 4083 String text= d.get(line.getOffset(), line.getLength()); 4084 4085 int index= -1; 4086 int[] found= TextUtilities.indexOf(prefixes, text, 0); 4087 if (found[0] != -1) { 4088 if (ignoreWhitespace) { 4089 String s= d.get(line.getOffset(), found[0]); 4090 s= s.trim(); 4091 if (s.length() == 0) 4092 index= line.getOffset() + found[0]; 4093 } else if (found[0] == 0) 4094 index= line.getOffset(); 4095 } 4096 4097 if (index > -1) { 4098 int length= prefixes[found[1]].length(); 4100 if (length == 0 && !ignoreWhitespace && line.getLength() > 0) { 4101 return; 4103 } 4104 occurrences[i]= new Region(index, length); 4105 } else { 4106 return; 4108 } 4109 } 4110 4111 int decrement= 0; 4113 for (int i= 0; i < occurrences.length; i++) { 4114 IRegion r= occurrences[i]; 4115 d.replace(r.getOffset() - decrement, r.getLength(), ""); decrement += r.getLength(); 4117 } 4118 4119 } catch (BadLocationException x) { 4120 if (TRACE_ERRORS) 4121 System.out.println("TextViewer.shiftLeft: BadLocationException"); } 4123 } 4124 4125 4130 protected boolean isPrintable() { 4131 4135 PrinterData[] printerList= Printer.getPrinterList(); 4136 return (printerList != null && printerList.length > 0); 4137 } 4138 4139 4143 protected void print() { 4144 4145 final PrintDialog dialog= new PrintDialog(fTextWidget.getShell(), SWT.PRIMARY_MODAL); 4146 final PrinterData data= dialog.open(); 4147 4148 if (data != null) { 4149 4150 final Printer printer= new Printer(data); 4151 final Runnable styledTextPrinter= fTextWidget.print(printer); 4152 4153 Thread printingThread= new Thread ("Printing") { public void run() { 4155 styledTextPrinter.run(); 4156 printer.dispose(); 4157 } 4158 }; 4159 printingThread.start(); 4160 } 4161 } 4162 4163 4164 4166 4171 protected boolean canPerformFind() { 4172 IDocument d= getVisibleDocument(); 4173 return (fTextWidget != null && d != null && d.getLength() > 0); 4174 } 4175 4176 4187 protected int findAndSelect(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord) { 4188 try { 4189 return findAndSelect(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false); 4190 } catch (IllegalStateException ex) { 4191 return -1; 4192 } catch (PatternSyntaxException ex) { 4193 return -1; 4194 } 4195 } 4196 4197 4210 protected int findAndSelect(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, boolean regExSearch) { 4211 if (fTextWidget == null) 4212 return -1; 4213 4214 try { 4215 4216 int widgetOffset= (startPosition == -1 ? startPosition : modelOffset2WidgetOffset(startPosition)); 4217 FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter(); 4218 IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); 4219 if (matchRegion != null) { 4220 int widgetPos= matchRegion.getOffset(); 4221 int length= matchRegion.getLength(); 4222 4223 char startChar= adapter.charAt(widgetPos); 4225 char endChar= adapter.charAt(widgetPos+length-1); 4226 boolean borderHasLineDelimiter= startChar == '\n' || startChar == '\r' || endChar == '\n' || endChar == '\r'; 4227 boolean redraws= redraws(); 4228 if (borderHasLineDelimiter && redraws) 4229 setRedraw(false); 4230 4231 if (redraws()) { 4232 fTextWidget.setSelectionRange(widgetPos, length); 4233 internalRevealRange(widgetPos, widgetPos + length); 4234 selectionChanged(widgetPos, length); 4235 } else { 4236 setSelectedRange(widgetOffset2ModelOffset(widgetPos), length); 4237 if (redraws) 4238 setRedraw(true); 4239 } 4240 4241 return widgetOffset2ModelOffset(widgetPos); 4242 } 4243 4244 } catch (BadLocationException x) { 4245 if (TRACE_ERRORS) 4246 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); } 4248 4249 return -1; 4250 } 4251 4252 4266 protected int findAndSelectInRange(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, int rangeOffset, int rangeLength, boolean regExSearch) { 4267 if (fTextWidget == null) 4268 return -1; 4269 4270 try { 4271 4272 int modelOffset; 4273 if (forwardSearch && (startPosition == -1 || startPosition < rangeOffset)) { 4274 modelOffset= rangeOffset; 4275 } else if (!forwardSearch && (startPosition == -1 || startPosition > rangeOffset + rangeLength)) { 4276 modelOffset= rangeOffset + rangeLength; 4277 } else { 4278 modelOffset= startPosition; 4279 } 4280 4281 int widgetOffset= modelOffset2WidgetOffset(modelOffset); 4282 if (widgetOffset == -1) 4283 return -1; 4284 4285 FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter(); 4286 IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); 4287 int widgetPos= -1; 4288 int length= 0; 4289 if (matchRegion != null) { 4290 widgetPos= matchRegion.getOffset(); 4291 length= matchRegion.getLength(); 4292 } 4293 int modelPos= widgetPos == -1 ? -1 : widgetOffset2ModelOffset(widgetPos); 4294 4295 if (widgetPos != -1 && (modelPos < rangeOffset || modelPos + length > rangeOffset + rangeLength)) 4296 widgetPos= -1; 4297 4298 if (widgetPos > -1) { 4299 4300 char startChar= adapter.charAt(widgetPos); 4302 char endChar= adapter.charAt(widgetPos+length-1); 4303 boolean borderHasLineDelimiter= startChar == '\n' || startChar == '\r' || endChar == '\n' || endChar == '\r'; 4304 boolean redraws= redraws(); 4305 if (borderHasLineDelimiter && redraws) 4306 setRedraw(false); 4307 4308 if (redraws()) { 4309 fTextWidget.setSelectionRange(widgetPos, length); 4310 internalRevealRange(widgetPos, widgetPos + length); 4311 selectionChanged(widgetPos, length); 4312 } else { 4313 setSelectedRange(modelPos, length); 4314 if (redraws) 4315 setRedraw(true); 4316 } 4317 4318 return modelPos; 4319 } 4320 4321 4322 } catch (BadLocationException x) { 4323 if (TRACE_ERRORS) 4324 System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); } 4326 4327 return -1; 4328 } 4329 4330 4332 4335 public void setTextColor(Color color) { 4336 if (color != null) 4337 setTextColor(color, 0, getDocument().getLength(), true); 4338 } 4339 4340 4343 public void setTextColor(Color color, int start, int length, boolean controlRedraw) { 4344 if (fTextWidget != null) { 4345 4346 StyleRange s= new StyleRange(); 4347 s.foreground= color; 4348 s.start= start; 4349 s.length= length; 4350 4351 s= modelStyleRange2WidgetStyleRange(s); 4352 if (s != null) { 4353 if (controlRedraw) 4354 fTextWidget.setRedraw(false); 4355 try { 4356 fTextWidget.setStyleRange(s); 4357 } finally { 4358 if (controlRedraw) 4359 fTextWidget.setRedraw(true); 4360 } 4361 } 4362 } 4363 } 4364 4365 4370 private void addPresentation(TextPresentation presentation) { 4371 4372 StyleRange range= presentation.getDefaultStyleRange(); 4373 if (range != null) { 4374 4375 range= modelStyleRange2WidgetStyleRange(range); 4376 if (range != null) 4377 fTextWidget.setStyleRange(range); 4378 4379 Iterator e= presentation.getNonDefaultStyleRangeIterator(); 4380 while (e.hasNext()) { 4381 range= (StyleRange) e.next(); 4382 range= modelStyleRange2WidgetStyleRange(range); 4383 if (range != null) 4384 fTextWidget.setStyleRange(range); 4385 } 4386 4387 } else { 4388 IRegion region= modelRange2WidgetRange(presentation.getCoverage()); 4389 if (region == null) 4390 return; 4391 4392 List list= new ArrayList (presentation.getDenumerableRanges()); 4393 Iterator e= presentation.getAllStyleRangeIterator(); 4394 while (e.hasNext()) { 4395 range= (StyleRange) e.next(); 4396 range= modelStyleRange2WidgetStyleRange(range); 4397 if (range != null) 4398 list.add(range); 4399 } 4400 4401 if (!list.isEmpty()) { 4402 StyleRange[] ranges= new StyleRange[list.size()]; 4403 list.toArray(ranges); 4404 fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges); 4405 } 4406 } 4407 } 4408 4409 4415 private void applyTextPresentation(TextPresentation presentation) { 4416 4417 List list= new ArrayList (presentation.getDenumerableRanges()); 4418 Iterator e= presentation.getAllStyleRangeIterator(); 4419 while (e.hasNext()) { 4420 StyleRange range= (StyleRange) e.next(); 4421 range= modelStyleRange2WidgetStyleRange(range); 4422 if (range != null) 4423 list.add(range); 4424 } 4425 4426 if (!list.isEmpty()) { 4427 StyleRange[] ranges= new StyleRange[list.size()]; 4428 list.toArray(ranges); 4429 fTextWidget.setStyleRanges(ranges); 4430 } 4431 } 4432 4433 4439 protected IRegion _internalGetVisibleRegion() { 4440 4441 IDocument document= getVisibleDocument(); 4442 if (document instanceof ChildDocument) { 4443 Position p= ((ChildDocument) document).getParentDocumentRange(); 4444 return new Region(p.getOffset(), p.getLength()); 4445 } 4446 4447 return null; 4448 } 4449 4450 4453 public void changeTextPresentation(TextPresentation presentation, boolean controlRedraw) { 4454 4455 if (presentation == null || !redraws()) 4456 return; 4457 4458 if (fTextWidget == null) 4459 return; 4460 4461 4462 4466 if (fTextPresentationListeners != null) { 4467 ArrayList listeners= new ArrayList (fTextPresentationListeners); 4468 for (int i= 0, size= listeners.size(); i < size; i++) { 4469 ITextPresentationListener listener= (ITextPresentationListener)listeners.get(i); 4470 listener.applyTextPresentation(presentation); 4471 } 4472 } 4473 4474 if (presentation.isEmpty()) 4475 return; 4476 4477 if (controlRedraw) 4478 fTextWidget.setRedraw(false); 4479 4480 if (fReplaceTextPresentation) 4481 applyTextPresentation(presentation); 4482 else 4483 addPresentation(presentation); 4484 4485 if (controlRedraw) 4486 fTextWidget.setRedraw(true); 4487 } 4488 4489 4492 public IFindReplaceTarget getFindReplaceTarget() { 4493 if (fFindReplaceTarget == null) 4494 fFindReplaceTarget= new FindReplaceTarget(); 4495 return fFindReplaceTarget; 4496 } 4497 4498 4504 protected FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() { 4505 if (fFindReplaceDocumentAdapter == null) 4506 fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(getVisibleDocument()); 4507 return fFindReplaceDocumentAdapter; 4508 } 4509 4510 4513 public ITextOperationTarget getTextOperationTarget() { 4514 return this; 4515 } 4516 4517 4521 public void appendVerifyKeyListener(VerifyKeyListener listener) { 4522 int index= fVerifyKeyListenersManager.numberOfListeners(); 4523 fVerifyKeyListenersManager.insertListener(listener, index); 4524 } 4525 4526 4530 public void prependVerifyKeyListener(VerifyKeyListener listener) { 4531 fVerifyKeyListenersManager.insertListener(listener, 0); 4532 4533 } 4534 4535 4539 public void removeVerifyKeyListener(VerifyKeyListener listener) { 4540 fVerifyKeyListenersManager.removeListener(listener); 4541 } 4542 4543 4547 public int getMark() { 4548 return fMarkPosition == null || fMarkPosition.isDeleted() ? -1 : fMarkPosition.getOffset(); 4549 } 4550 4551 4555 public void setMark(int offset) { 4556 4557 if (offset == -1) { 4559 if (fMarkPosition != null && !fMarkPosition.isDeleted()) { 4560 4561 IDocument document= getDocument(); 4562 if (document != null) 4563 document.removePosition(fMarkPosition); 4564 } 4565 4566 fMarkPosition= null; 4567 4568 markChanged(-1, 0); 4569 4570 } else { 4572 4573 IDocument document= getDocument(); 4574 if (document == null) { 4575 fMarkPosition= null; 4576 return; 4577 } 4578 4579 if (fMarkPosition != null) 4580 document.removePosition(fMarkPosition); 4581 4582 fMarkPosition= null; 4583 4584 try { 4585 4586 Position position= new Position(offset); 4587 document.addPosition(MARK_POSITION_CATEGORY, position); 4588 fMarkPosition= position; 4589 4590 } catch (BadLocationException e) { 4591 return; 4592 } catch (BadPositionCategoryException e) { 4593 return; 4594 } 4595 4596 markChanged(modelOffset2WidgetOffset(fMarkPosition.offset), 0); 4597 } 4598 } 4599 4600 4604 protected void inputChanged(Object newInput, Object oldInput) { 4605 4606 IDocument oldDocument= (IDocument) oldInput; 4607 if (oldDocument != null) { 4608 4609 if (fMarkPosition != null && !fMarkPosition.isDeleted()) 4610 oldDocument.removePosition(fMarkPosition); 4611 4612 try { 4613 oldDocument.removePositionUpdater(fMarkPositionUpdater); 4614 oldDocument.removePositionCategory(MARK_POSITION_CATEGORY); 4615 4616 } catch (BadPositionCategoryException e) { 4617 } 4618 } 4619 4620 fMarkPosition= null; 4621 4622 if (oldDocument instanceof IDocumentExtension4) { 4623 IDocumentExtension4 document= (IDocumentExtension4) oldDocument; 4624 document.removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener); 4625 } 4626 4627 super.inputChanged(newInput, oldInput); 4628 4629 if (newInput instanceof IDocumentExtension4) { 4630 IDocumentExtension4 document= (IDocumentExtension4) newInput; 4631 document.addDocumentRewriteSessionListener(fDocumentRewriteSessionListener); 4632 } 4633 4634 IDocument newDocument= (IDocument) newInput; 4635 if (newDocument != null) { 4636 newDocument.addPositionCategory(MARK_POSITION_CATEGORY); 4637 newDocument.addPositionUpdater(fMarkPositionUpdater); 4638 } 4639 } 4640 4641 4645 private void fireRedrawChanged() { 4646 fWidgetCommand.start= 0; 4647 fWidgetCommand.length= 0; 4648 fWidgetCommand.text= null; 4649 fWidgetCommand.event= null; 4650 updateTextListeners(fWidgetCommand); 4651 } 4652 4653 4657 protected void enabledRedrawing() { 4658 enabledRedrawing(-1); 4659 } 4660 4666 protected void enabledRedrawing(int topIndex) { 4667 if (fDocumentAdapter instanceof IDocumentAdapterExtension) { 4668 IDocumentAdapterExtension extension= (IDocumentAdapterExtension) fDocumentAdapter; 4669 StyledText textWidget= getTextWidget(); 4670 if (textWidget != null && !textWidget.isDisposed()) { 4671 extension.resumeForwardingDocumentChanges(); 4672 if (topIndex > -1) { 4673 try { 4674 setTopIndex(topIndex); 4675 } catch (IllegalArgumentException x) { 4676 } 4678 } 4679 } 4680 } 4681 4682 if (fViewerState != null) { 4683 fViewerState.restore(topIndex == -1); 4684 fViewerState= null; 4685 } 4686 4687 if (fTextWidget != null && !fTextWidget.isDisposed()) 4688 fTextWidget.setRedraw(true); 4689 4690 fireRedrawChanged(); 4691 } 4692 4693 4697 protected void disableRedrawing() { 4698 if (fViewerState == null) 4699 fViewerState= new ViewerState(); 4700 4701 if (fDocumentAdapter instanceof IDocumentAdapterExtension) { 4702 IDocumentAdapterExtension extension= (IDocumentAdapterExtension) fDocumentAdapter; 4703 extension.stopForwardingDocumentChanges(); 4704 } 4705 4706 if (fTextWidget != null && !fTextWidget.isDisposed()) 4707 fTextWidget.setRedraw(false); 4708 4709 fireRedrawChanged(); 4710 } 4711 4712 4716 public final void setRedraw(boolean redraw) { 4717 setRedraw(redraw, -1); 4718 } 4719 4720 4734 protected final void setRedraw(boolean redraw, int topIndex) { 4735 if (!redraw) { 4736 4737 ++ fRedrawCounter; 4738 if (fRedrawCounter == 1) 4739 disableRedrawing(); 4740 4741 } else { 4742 -- fRedrawCounter; 4743 if (fRedrawCounter == 0) { 4744 if (topIndex == -1) 4745 enabledRedrawing(); 4746 else 4747 enabledRedrawing(topIndex); 4748 } 4749 } 4750 } 4751 4752 4758 protected final boolean redraws() { 4759 return fRedrawCounter <= 0; 4760 } 4761 4762 4769 protected final void startSequentialRewriteMode(boolean normalized) { 4770 IDocument document= getDocument(); 4771 if (document instanceof IDocumentExtension) { 4772 IDocumentExtension extension= (IDocumentExtension) document; 4773 extension.startSequentialRewrite(normalized); 4774 } 4775 } 4776 4777 4783 protected final void stopSequentialRewriteMode() { 4784 IDocument document= getDocument(); 4785 if (document instanceof IDocumentExtension) { 4786 IDocumentExtension extension= (IDocumentExtension) document; 4787 extension.stopSequentialRewrite(); 4788 } 4789 } 4790 4791 4795 public IRewriteTarget getRewriteTarget() { 4796 if (fRewriteTarget == null) 4797 fRewriteTarget= new RewriteTarget(); 4798 return fRewriteTarget; 4799 } 4800 4801 4804 public ITextHover getCurrentTextHover() { 4805 if (fTextHoverManager == null) 4806 return null; 4807 return fTextHoverManager.getCurrentTextHover(); 4808 } 4809 4810 4813 public Point getHoverEventLocation() { 4814 if (fTextHoverManager == null) 4815 return null; 4816 return fTextHoverManager.getHoverEventLocation(); 4817 } 4818 4819 4825 protected PaintManager getPaintManager() { 4826 if (fPaintManager == null) 4827 fPaintManager= new PaintManager(this); 4828 return fPaintManager; 4829 } 4830 4831 4838 public void addPainter(IPainter painter) { 4839 getPaintManager().addPainter(painter); 4840 } 4841 4842 4849 public void removePainter(IPainter painter) { 4850 getPaintManager().removePainter(painter); 4851 } 4852 4853 4855 4862 public int modelLine2WidgetLine(int modelLine) { 4863 if (fInformationMapping == null) 4864 return modelLine; 4865 4866 try { 4867 return fInformationMapping.toImageLine(modelLine); 4868 } catch (BadLocationException x) { 4869 } 4870 4871 return -1; 4872 } 4873 4874 4881 public int modelOffset2WidgetOffset(int modelOffset) { 4882 if (fInformationMapping == null) 4883 return modelOffset; 4884 4885 try { 4886 return fInformationMapping.toImageOffset(modelOffset); 4887 } catch (BadLocationException x) { 4888 } 4889 4890 return -1; 4891 } 4892 4893 4900 public IRegion modelRange2WidgetRange(IRegion modelRange) { 4901 if (fInformationMapping == null) 4902 return modelRange; 4903 4904 try { 4905 4906 if (modelRange.getLength() < 0) { 4907 Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength()); 4908 IRegion result= fInformationMapping.toImageRegion(reversed); 4909 if (result != null) 4910 return new Region(result.getOffset() + result.getLength(), -result.getLength()); 4911 } 4912 return fInformationMapping.toImageRegion(modelRange); 4913 4914 } catch (BadLocationException x) { 4915 } 4916 4917 return null; 4918 } 4919 4920 4930 protected IRegion modelRange2ClosestWidgetRange(IRegion modelRange) { 4931 if (!(fInformationMapping instanceof IDocumentInformationMappingExtension2)) 4932 return modelRange2WidgetRange(modelRange); 4933 4934 try { 4935 if (modelRange.getLength() < 0) { 4936 Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength()); 4937 IRegion result= ((IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(reversed); 4938 if (result != null) 4939 return new Region(result.getOffset() + result.getLength(), -result.getLength()); 4940 } 4941 return ((IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(modelRange); 4942 4943 } catch (BadLocationException x) { 4944 } 4945 4946 return null; 4947 } 4948 4949 4956 public int widgetlLine2ModelLine(int widgetLine) { 4957 return widgetLine2ModelLine(widgetLine); 4958 } 4959 4960 4967 public int widgetLine2ModelLine(int widgetLine) { 4968 if (fInformationMapping == null) 4969 return widgetLine; 4970 4971 try { 4972 return fInformationMapping.toOriginLine(widgetLine); 4973 } catch (BadLocationException x) { 4974 } 4975 4976 return -1; 4977 } 4978 4979 4986 public int widgetOffset2ModelOffset(int widgetOffset) { 4987 if (fInformationMapping == null) 4988 return widgetOffset; 4989 4990 try { 4991 return fInformationMapping.toOriginOffset(widgetOffset); 4992 } catch (BadLocationException x) { 4993 if (widgetOffset == getVisibleDocument().getLength()) { 4994 IRegion coverage= fInformationMapping.getCoverage(); 4995 return coverage.getOffset() + coverage.getLength(); 4996 } 4997 } 4998 4999 return -1; 5000 } 5001 5002 5009 public IRegion widgetRange2ModelRange(IRegion widgetRange) { 5010 if (fInformationMapping == null) 5011 return widgetRange; 5012 5013 try { 5014 5015 if (widgetRange.getLength() < 0) { 5016 Region reveresed= new Region(widgetRange.getOffset() + widgetRange.getLength(), -widgetRange.getLength()); 5017 IRegion result= fInformationMapping.toOriginRegion(reveresed); 5018 return new Region(result.getOffset() + result.getLength(), -result.getLength()); 5019 } 5020 5021 return fInformationMapping.toOriginRegion(widgetRange); 5022 5023 } catch (BadLocationException x) { 5024 int modelOffset= widgetOffset2ModelOffset(widgetRange.getOffset()); 5025 if (modelOffset > -1) { 5026 int modelEndOffset= widgetOffset2ModelOffset(widgetRange.getOffset() + widgetRange.getLength()); 5027 if (modelEndOffset > -1) 5028 return new Region(modelOffset, modelEndOffset - modelOffset); 5029 } 5030 } 5031 5032 return null; 5033 } 5034 5035 5041 public IRegion getModelCoverage() { 5042 if (fInformationMapping == null) { 5043 IDocument document= getDocument(); 5044 if (document == null) 5045 return null; 5046 return new Region(0, document.getLength()); 5047 } 5048 5049 return fInformationMapping.getCoverage(); 5050 } 5051 5052 5060 protected int getClosestWidgetLineForModelLine(int modelLine) { 5061 if (fInformationMapping == null) 5062 return modelLine; 5063 5064 try { 5065 return fInformationMapping.toClosestImageLine(modelLine); 5066 } catch (BadLocationException x) { 5067 } 5068 5069 return -1; 5070 } 5071 5072 5080 protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) { 5081 IRegion region= modelRange2WidgetRange(new Region(range.start, range.length)); 5082 if (region != null) { 5083 StyleRange result= (StyleRange) range.clone(); 5084 result.start= region.getOffset(); 5085 result.length= region.getLength(); 5086 return result; 5087 } 5088 return null; 5089 } 5090 5091 5098 protected IRegion modelRange2WidgetRange(Position modelPosition) { 5099 return modelRange2WidgetRange(new Region(modelPosition.getOffset(), modelPosition.getLength())); 5100 } 5101 5102 5110 protected IRegion event2ModelRange(VerifyEvent event) { 5111 5112 Region region= null; 5113 if (event.start <= event.end) 5114 region= new Region(event.start, event.end - event.start); 5115 else 5116 region= new Region(event.end, event.start - event.end); 5117 5118 return widgetRange2ModelRange(region); 5119 } 5120 5121 5129 protected Point widgetSelection2ModelSelection(Point widgetSelection) { 5130 IRegion region= new Region(widgetSelection.x, widgetSelection.y); 5131 region= widgetRange2ModelRange(region); 5132 return region == null ? null : new Point(region.getOffset(), region.getLength()); 5133 } 5134 5135 5143 protected Point modelSelection2WidgetSelection(Point modelSelection) { 5144 if (fInformationMapping == null) 5145 return modelSelection; 5146 5147 try { 5148 IRegion region= new Region(modelSelection.x, modelSelection.y); 5149 region= fInformationMapping.toImageRegion(region); 5150 if (region != null) 5151 return new Point(region.getOffset(), region.getLength()); 5152 } catch (BadLocationException x) { 5153 } 5154 5155 return null; 5156 } 5157 5158 5165 public int widgetLineOfWidgetOffset(int widgetOffset) { 5166 IDocument document= getVisibleDocument(); 5167 if (document != null) { 5168 try { 5169 return document.getLineOfOffset(widgetOffset); 5170 } catch (BadLocationException e) { 5171 } 5172 } 5173 return -1; 5174 } 5175 5176 5180 public boolean moveFocusToWidgetToken() { 5181 if (fWidgetTokenKeeper instanceof IWidgetTokenKeeperExtension) { 5182 IWidgetTokenKeeperExtension extension= (IWidgetTokenKeeperExtension) fWidgetTokenKeeper; 5183 return extension.setFocus(this); 5184 } 5185 return false; 5186 } 5187 5188 5195 public void setDocumentPartitioning(String partitioning) { 5196 fPartitioning= partitioning; 5197 } 5198 5199 5205 protected String getDocumentPartitioning() { 5206 return fPartitioning; 5207 } 5208 5209 5211 5215 public void addTextPresentationListener(ITextPresentationListener listener) { 5216 5217 Assert.isNotNull(listener); 5218 5219 if (fTextPresentationListeners == null) 5220 fTextPresentationListeners= new ArrayList (); 5221 5222 if (!fTextPresentationListeners.contains(listener)) 5223 fTextPresentationListeners.add(listener); 5224 } 5225 5226 5230 public void removeTextPresentationListener(ITextPresentationListener listener) { 5231 5232 Assert.isNotNull(listener); 5233 5234 if (fTextPresentationListeners != null) { 5235 fTextPresentationListeners.remove(listener); 5236 if (fTextPresentationListeners.size() == 0) 5237 fTextPresentationListeners= null; 5238 } 5239 } 5240 5241 5245 public void register(IEditingSupport helper) { 5246 Assert.isLegal(helper != null); 5247 fEditorHelpers.add(helper); 5248 } 5249 5250 5254 public void unregister(IEditingSupport helper) { 5255 fEditorHelpers.remove(helper); 5256 } 5257 5258 5262 public IEditingSupport[] getRegisteredSupports() { 5263 return (IEditingSupport[]) fEditorHelpers.toArray(new IEditingSupport[fEditorHelpers.size()]); 5264 } 5265 5266 5270 public void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask) { 5271 if (fHyperlinkDetectors != null) { 5272 for (int i= 0; i < fHyperlinkDetectors.length; i++) { 5273 if (fHyperlinkDetectors[i] instanceof IHyperlinkDetectorExtension) 5274 ((IHyperlinkDetectorExtension)fHyperlinkDetectors[i]).dispose(); 5275 } 5276 } 5277 5278 boolean enable= hyperlinkDetectors != null && hyperlinkDetectors.length > 0; 5279 fHyperlinkStateMask= eventStateMask; 5280 fHyperlinkDetectors= hyperlinkDetectors; 5281 if (enable) { 5282 if (fHyperlinkManager != null) { 5283 fHyperlinkManager.setHyperlinkDetectors(fHyperlinkDetectors); 5284 fHyperlinkManager.setHyperlinkStateMask(fHyperlinkStateMask); 5285 } 5286 ensureHyperlinkManagerInstalled(); 5287 } else { 5288 if (fHyperlinkManager != null) 5289 fHyperlinkManager.uninstall(); 5290 fHyperlinkManager= null; 5291 } 5292 } 5293 5294 5305 public void setHyperlinkPresenter(IHyperlinkPresenter hyperlinkPresenter) throws IllegalStateException { 5306 if (fHyperlinkManager != null) 5307 throw new IllegalStateException (); 5308 5309 fHyperlinkPresenter= hyperlinkPresenter; 5310 ensureHyperlinkManagerInstalled(); 5311 } 5312 5313 5319 private void ensureHyperlinkManagerInstalled() { 5320 if (fHyperlinkDetectors != null && fHyperlinkDetectors.length > 0 && fHyperlinkPresenter != null && fHyperlinkManager == null) { 5321 fHyperlinkManager= new HyperlinkManager(HyperlinkManager.FIRST); 5322 fHyperlinkManager.install(this, fHyperlinkPresenter, fHyperlinkDetectors, fHyperlinkStateMask); 5323 } 5324 } 5325 5326 5330 public void setTabsToSpacesConverter(IAutoEditStrategy converter) { 5331 fTabsToSpacesConverter= converter; 5332 } 5333 5334} 5335 | Popular Tags |