1 11 package org.eclipse.swt.custom; 12 13 14 import java.util.*; 15 16 import org.eclipse.swt.*; 17 import org.eclipse.swt.accessibility.*; 18 import org.eclipse.swt.dnd.*; 19 import org.eclipse.swt.events.*; 20 import org.eclipse.swt.graphics.*; 21 import org.eclipse.swt.internal.*; 22 import org.eclipse.swt.printing.*; 23 import org.eclipse.swt.widgets.*; 24 25 77 public class StyledText extends Canvas { 78 static final char TAB = '\t'; 79 static final String PlatformLineDelimiter = System.getProperty("line.separator"); 80 static final int BIDI_CARET_WIDTH = 3; 81 static final int DEFAULT_WIDTH = 64; 82 static final int DEFAULT_HEIGHT = 64; 83 static final int V_SCROLL_RATE = 50; 84 static final int H_SCROLL_RATE = 10; 85 86 static final int ExtendedModify = 3000; 87 static final int LineGetBackground = 3001; 88 static final int LineGetStyle = 3002; 89 static final int TextChanging = 3003; 90 static final int TextSet = 3004; 91 static final int VerifyKey = 3005; 92 static final int TextChanged = 3006; 93 static final int LineGetSegments = 3007; 94 static final int PaintObject = 3008; 95 static final int WordNext = 3009; 96 static final int WordPrevious = 3010; 97 98 static final int PREVIOUS_OFFSET_TRAILING = 0; 99 static final int OFFSET_LEADING = 1; 100 101 Color selectionBackground; Color selectionForeground; StyledTextContent content; StyledTextRenderer renderer; 105 Listener listener; 106 TextChangeListener textChangeListener; int verticalScrollOffset = 0; int horizontalScrollOffset = 0; int topIndex = 0; int topIndexY; 111 int clientAreaHeight = 0; int clientAreaWidth = 0; int tabLength = 4; int leftMargin; 115 int topMargin; 116 int rightMargin; 117 int bottomMargin; 118 int columnX; int caretOffset = 0; 120 int caretAlignment; 121 Point selection = new Point(0, 0); Point clipboardSelection; int selectionAnchor; Point doubleClickSelection; boolean editable = true; 126 boolean wordWrap = false; 127 boolean doubleClickEnabled = true; boolean overwrite = false; int textLimit = -1; Hashtable keyActionMap = new Hashtable(); 131 Color background = null; Color foreground = null; Clipboard clipboard; 134 int clickCount; 135 int autoScrollDirection = SWT.NULL; int autoScrollDistance = 0; 137 int lastTextChangeStart; int lastTextChangeNewLineCount; int lastTextChangeNewCharCount; int lastTextChangeReplaceLineCount; int lastTextChangeReplaceCharCount; 142 int lastLineBottom; boolean isMirrored; 144 boolean bidiColoring = false; Image leftCaretBitmap = null; 146 Image rightCaretBitmap = null; 147 int caretDirection = SWT.NULL; 148 Caret defaultCaret = null; 149 boolean updateCaretDirection = true; 150 boolean fixedLineHeight; 151 boolean dragDetect = true; 152 153 int alignment; 154 boolean justify; 155 int indent; 156 int lineSpacing; 157 158 final static boolean IS_CARBON, IS_GTK, IS_MOTIF; 159 static { 160 String platform = SWT.getPlatform(); 161 IS_CARBON = "carbon".equals(platform); 162 IS_GTK = "gtk".equals(platform); 163 IS_MOTIF = "motif".equals(platform); 164 } 165 166 172 static class Printing implements Runnable { 173 final static int LEFT = 0; final static int CENTER = 1; final static int RIGHT = 2; 177 Printer printer; 178 StyledTextRenderer printerRenderer; 179 StyledTextPrintOptions printOptions; 180 Rectangle clientArea; 181 FontData fontData; 182 Font printerFont; 183 Hashtable resources; 184 int tabLength; 185 GC gc; int pageWidth; int startPage; int endPage; int startLine; int endLine; boolean singleLine; Point selection = null; boolean mirrored; int lineSpacing; 195 int printMargin; 196 197 206 Printing(StyledText styledText, Printer printer, StyledTextPrintOptions printOptions) { 207 this.printer = printer; 208 this.printOptions = printOptions; 209 this.mirrored = (styledText.getStyle() & SWT.MIRRORED) != 0; 210 singleLine = styledText.isSingleLine(); 211 startPage = 1; 212 endPage = Integer.MAX_VALUE; 213 PrinterData data = printer.getPrinterData(); 214 if (data.scope == PrinterData.PAGE_RANGE) { 215 startPage = data.startPage; 216 endPage = data.endPage; 217 if (endPage < startPage) { 218 int temp = endPage; 219 endPage = startPage; 220 startPage = temp; 221 } 222 } else if (data.scope == PrinterData.SELECTION) { 223 selection = styledText.getSelectionRange(); 224 } 225 printerRenderer = new StyledTextRenderer(printer, null); 226 printerRenderer.setContent(copyContent(styledText.getContent())); 227 cacheLineData(styledText); 228 } 229 235 void cacheLineData(StyledText styledText) { 236 StyledTextRenderer renderer = styledText.renderer; 237 renderer.copyInto(printerRenderer); 238 fontData = styledText.getFont().getFontData()[0]; 239 tabLength = styledText.tabLength; 240 int lineCount = printerRenderer.lineCount; 241 if (styledText.isListening(LineGetBackground) || (styledText.isBidi() && styledText.isListening(LineGetSegments)) || styledText.isListening(LineGetStyle)) { 242 StyledTextContent content = printerRenderer.content; 243 for (int i = 0; i < lineCount; i++) { 244 String line = content.getLine(i); 245 int lineOffset = content.getOffsetAtLine(i); 246 StyledTextEvent event = styledText.getLineBackgroundData(lineOffset, line); 247 if (event != null && event.lineBackground != null) { 248 printerRenderer.setLineBackground(i, 1, event.lineBackground); 249 } 250 if (styledText.isBidi()) { 251 int[] segments = styledText.getBidiSegments(lineOffset, line); 252 printerRenderer.setLineSegments(i, 1, segments); 253 } 254 event = styledText.getLineStyleData(lineOffset, line); 255 if (event != null) { 256 printerRenderer.setLineIndent(i, 1, event.indent); 257 printerRenderer.setLineAlignment(i, 1, event.alignment); 258 printerRenderer.setLineJustify(i, 1, event.justify); 259 printerRenderer.setLineBullet(i, 1, event.bullet); 260 StyleRange[] styles = event.styles; 261 if (styles != null && styles.length > 0) { 262 printerRenderer.setStyleRanges(event.ranges, styles); 263 } 264 } 265 } 266 } 267 Point screenDPI = styledText.getDisplay().getDPI(); 268 Point printerDPI = printer.getDPI(); 269 resources = new Hashtable (); 270 for (int i = 0; i < lineCount; i++) { 271 Color color = printerRenderer.getLineBackground(i, null); 272 if (color != null) { 273 if (printOptions.printLineBackground) { 274 Color printerColor = (Color)resources.get(color); 275 if (printerColor == null) { 276 printerColor = new Color (printer, color.getRGB()); 277 resources.put(color, printerColor); 278 } 279 printerRenderer.setLineBackground(i, 1, printerColor); 280 } else { 281 printerRenderer.setLineBackground(i, 1, null); 282 } 283 } 284 int indent = printerRenderer.getLineIndent(i, 0); 285 if (indent != 0) { 286 printerRenderer.setLineIndent(i, 1, indent * printerDPI.x / screenDPI.x); 287 } 288 } 289 StyleRange[] styles = printerRenderer.styles; 290 for (int i = 0; i < printerRenderer.styleCount; i++) { 291 StyleRange style = styles[i]; 292 Font font = style.font; 293 if (style.font != null) { 294 Font printerFont = (Font)resources.get(font); 295 if (printerFont == null) { 296 printerFont = new Font (printer, font.getFontData()); 297 resources.put(font, printerFont); 298 } 299 style.font = printerFont; 300 } 301 Color color = style.foreground; 302 if (color != null) { 303 Color printerColor = (Color)resources.get(color); 304 if (printOptions.printTextForeground) { 305 if (printerColor == null) { 306 printerColor = new Color (printer, color.getRGB()); 307 resources.put(color, printerColor); 308 } 309 style.foreground = printerColor; 310 } else { 311 style.foreground = null; 312 } 313 } 314 color = style.background; 315 if (color != null) { 316 Color printerColor = (Color)resources.get(color); 317 if (printOptions.printTextBackground) { 318 if (printerColor == null) { 319 printerColor = new Color (printer, color.getRGB()); 320 resources.put(color, printerColor); 321 } 322 style.background = printerColor; 323 } else { 324 style.background = null; 325 } 326 } 327 if (!printOptions.printTextFontStyle) { 328 style.fontStyle = SWT.NORMAL; 329 } 330 style.rise = style.rise * printerDPI.y / screenDPI.y; 331 GlyphMetrics metrics = style.metrics; 332 if (metrics != null) { 333 metrics.ascent = metrics.ascent * printerDPI.y / screenDPI.y; 334 metrics.descent = metrics.descent * printerDPI.y / screenDPI.y; 335 metrics.width = metrics.width * printerDPI.x / screenDPI.x; 336 } 337 } 338 lineSpacing = styledText.lineSpacing * printerDPI.y / screenDPI.y; 339 if (printOptions.printLineNumbers) { 340 printMargin = 3 * printerDPI.x / screenDPI.x; 341 } 342 } 343 348 StyledTextContent copyContent(StyledTextContent original) { 349 StyledTextContent printerContent = new DefaultContent(); 350 int insertOffset = 0; 351 for (int i = 0; i < original.getLineCount(); i++) { 352 int insertEndOffset; 353 if (i < original.getLineCount() - 1) { 354 insertEndOffset = original.getOffsetAtLine(i + 1); 355 } else { 356 insertEndOffset = original.getCharCount(); 357 } 358 printerContent.replaceTextRange(insertOffset, 0, original.getTextRange(insertOffset, insertEndOffset - insertOffset)); 359 insertOffset = insertEndOffset; 360 } 361 return printerContent; 362 } 363 366 void dispose() { 367 if (gc != null) { 368 gc.dispose(); 369 gc = null; 370 } 371 if (resources != null) { 372 Enumeration enumeration = resources.elements(); 373 while (enumeration.hasMoreElements()) { 374 Resource resource = (Resource) enumeration.nextElement(); 375 resource.dispose(); 376 } 377 resources = null; 378 } 379 if (printerFont != null) { 380 printerFont.dispose(); 381 printerFont = null; 382 } 383 if (printerRenderer != null) { 384 printerRenderer.dispose(); 385 printerRenderer = null; 386 } 387 } 388 void init() { 389 Rectangle trim = printer.computeTrim(0, 0, 0, 0); 390 Point dpi = printer.getDPI(); 391 392 printerFont = new Font(printer, fontData.getName(), fontData.getHeight(), SWT.NORMAL); 393 clientArea = printer.getClientArea(); 394 pageWidth = clientArea.width; 395 clientArea.x = dpi.x + trim.x; 397 clientArea.y = dpi.y + trim.y; 398 clientArea.width -= (clientArea.x + trim.width); 399 clientArea.height -= (clientArea.y + trim.height); 400 401 int style = mirrored ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT; 402 gc = new GC(printer, style); 403 gc.setFont(printerFont); 404 printerRenderer.setFont(printerFont, tabLength); 405 int lineHeight = printerRenderer.getLineHeight(); 406 if (printOptions.header != null) { 407 clientArea.y += lineHeight * 2; 408 clientArea.height -= lineHeight * 2; 409 } 410 if (printOptions.footer != null) { 411 clientArea.height -= lineHeight * 2; 412 } 413 414 StyledTextContent content = printerRenderer.content; 416 startLine = 0; 417 endLine = singleLine ? 0 : content.getLineCount() - 1; 418 PrinterData data = printer.getPrinterData(); 419 if (data.scope == PrinterData.PAGE_RANGE) { 420 int pageSize = clientArea.height / lineHeight; startLine = (startPage - 1) * pageSize; 422 } else if (data.scope == PrinterData.SELECTION) { 423 startLine = content.getLineAtOffset(selection.x); 424 if (selection.y > 0) { 425 endLine = content.getLineAtOffset(selection.x + selection.y - 1); 426 } else { 427 endLine = startLine - 1; 428 } 429 } 430 } 431 434 void print() { 435 Color background = gc.getBackground(); 436 Color foreground = gc.getForeground(); 437 int paintY = clientArea.y; 438 int paintX = clientArea.x; 439 int width = clientArea.width; 440 int page = startPage; 441 int pageBottom = clientArea.y + clientArea.height; 442 int orientation = gc.getStyle() & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT); 443 TextLayout printLayout = null; 444 if (printOptions.printLineNumbers || printOptions.header != null || printOptions.footer != null) { 445 printLayout = new TextLayout(printer); 446 printLayout.setFont(printerFont); 447 } 448 if (printOptions.printLineNumbers) { 449 int count = endLine - startLine + 1; 450 StringBuffer buffer = new StringBuffer ("0"); 451 while ((count /= 10) > 0) buffer.append("0"); 452 printLayout.setText(buffer.toString()); 453 int numberingWidth = printLayout.getBounds().width + printMargin; 454 if (numberingWidth > width) numberingWidth = width; 455 paintX += numberingWidth; 456 width -= numberingWidth; 457 } 458 for (int i = startLine; i <= endLine && page <= endPage; i++) { 459 if (paintY == clientArea.y) { 460 printer.startPage(); 461 printDecoration(page, true, printLayout); 462 } 463 TextLayout layout = printerRenderer.getTextLayout(i, orientation, width, lineSpacing); 464 Color lineBackground = printerRenderer.getLineBackground(i, background); 465 int paragraphBottom = paintY + layout.getBounds().height; 466 if (paragraphBottom <= pageBottom) { 467 printLine(paintX, paintY, gc, foreground, lineBackground, layout, printLayout, i); 469 paintY = paragraphBottom; 470 } else { 471 int lineCount = layout.getLineCount(); 472 while (paragraphBottom > pageBottom && lineCount > 0) { 473 lineCount--; 474 paragraphBottom -= layout.getLineBounds(lineCount).height + layout.getSpacing(); 475 } 476 if (lineCount == 0) { 477 printDecoration(page, false, printLayout); 479 printer.endPage(); 480 page++; 481 if (page <= endPage) { 482 printer.startPage(); 483 printDecoration(page, true, printLayout); 484 paintY = clientArea.y; 485 printLine(paintX, paintY, gc, foreground, lineBackground, layout, printLayout, i); 486 paintY += layout.getBounds().height; 487 } 488 } else { 489 int height = paragraphBottom - paintY; 491 gc.setClipping(paintX, paintY, width, height); 492 printLine(paintX, paintY, gc, foreground, lineBackground, layout, printLayout, i); 493 printDecoration(page, false, printLayout); 494 printer.endPage(); 495 page++; 496 if (page <= endPage) { 497 printer.startPage(); 498 printDecoration(page, true, printLayout); 499 paintY = clientArea.y - height; 500 int layoutHeight = layout.getBounds().height; 501 gc.setClipping(paintX, clientArea.y, width, layoutHeight - height); 502 printLine(paintX, paintY, gc, foreground, lineBackground, layout, printLayout, i); 503 paintY += layoutHeight; 504 } 505 gc.setClipping((Rectangle)null); 506 } 507 } 508 printerRenderer.disposeTextLayout(layout); 509 } 510 if (paintY > clientArea.y) { 511 printDecoration(page, false, printLayout); 513 printer.endPage(); 514 } 515 if (printLayout != null) printLayout.dispose(); 516 } 517 523 void printDecoration(int page, boolean header, TextLayout layout) { 524 String text = header ? printOptions.header : printOptions.footer; 525 if (text == null) return; 526 int lastSegmentIndex = 0; 527 for (int i = 0; i < 3; i++) { 528 int segmentIndex = text.indexOf(StyledTextPrintOptions.SEPARATOR, lastSegmentIndex); 529 String segment; 530 if (segmentIndex == -1) { 531 segment = text.substring(lastSegmentIndex); 532 printDecorationSegment(segment, i, page, header, layout); 533 break; 534 } else { 535 segment = text.substring(lastSegmentIndex, segmentIndex); 536 printDecorationSegment(segment, i, page, header, layout); 537 lastSegmentIndex = segmentIndex + StyledTextPrintOptions.SEPARATOR.length(); 538 } 539 } 540 } 541 551 void printDecorationSegment(String segment, int alignment, int page, boolean header, TextLayout layout) { 552 int pageIndex = segment.indexOf(StyledTextPrintOptions.PAGE_TAG); 553 if (pageIndex != -1) { 554 int pageTagLength = StyledTextPrintOptions.PAGE_TAG.length(); 555 StringBuffer buffer = new StringBuffer (segment.substring (0, pageIndex)); 556 buffer.append (page); 557 buffer.append (segment.substring(pageIndex + pageTagLength)); 558 segment = buffer.toString(); 559 } 560 if (segment.length() > 0) { 561 layout.setText(segment); 562 int segmentWidth = layout.getBounds().width; 563 int segmentHeight = printerRenderer.getLineHeight(); 564 int drawX = 0, drawY; 565 if (alignment == LEFT) { 566 drawX = clientArea.x; 567 } else if (alignment == CENTER) { 568 drawX = (pageWidth - segmentWidth) / 2; 569 } else if (alignment == RIGHT) { 570 drawX = clientArea.x + clientArea.width - segmentWidth; 571 } 572 if (header) { 573 drawY = clientArea.y - segmentHeight * 2; 574 } else { 575 drawY = clientArea.y + clientArea.height + segmentHeight; 576 } 577 layout.draw(gc, drawX, drawY); 578 } 579 } 580 void printLine(int x, int y, GC gc, Color foreground, Color background, TextLayout layout, TextLayout printLayout, int index) { 581 if (background != null) { 582 Rectangle rect = layout.getBounds(); 583 gc.setBackground(background); 584 gc.fillRectangle(x, y, rect.width, rect.height); 585 586 } 595 if (printOptions.printLineNumbers) { 596 FontMetrics metrics = layout.getLineMetrics(0); 597 printLayout.setAscent(metrics.getAscent() + metrics.getDescent()); 598 printLayout.setDescent(metrics.getDescent()); 599 printLayout.setText(String.valueOf(index)); 600 int paintX = x - printMargin - printLayout.getBounds().width; 601 printLayout.draw(gc, paintX, y); 602 printLayout.setAscent(-1); 603 printLayout.setDescent(-1); 604 } 605 gc.setForeground(foreground); 606 layout.draw(gc, x, y); 607 } 608 611 public void run() { 612 String jobName = printOptions.jobName; 613 if (jobName == null) { 614 jobName = "Printing"; 615 } 616 if (printer.startJob(jobName)) { 617 init(); 618 print(); 619 dispose(); 620 printer.endJob(); 621 } 622 } 623 } 624 639 class RTFWriter extends TextWriter { 640 static final int DEFAULT_FOREGROUND = 0; 641 static final int DEFAULT_BACKGROUND = 1; 642 Vector colorTable, fontTable; 643 boolean WriteUnicode; 644 645 654 public RTFWriter(int start, int length) { 655 super(start, length); 656 colorTable = new Vector(); 657 fontTable = new Vector(); 658 colorTable.addElement(getForeground()); 659 colorTable.addElement(getBackground()); 660 fontTable.addElement(getFont()); 661 setUnicode(); 662 } 663 668 public void close() { 669 if (!isClosed()) { 670 writeHeader(); 671 write("\n}}\0"); 672 super.close(); 673 } 674 } 675 683 int getColorIndex(Color color, int defaultIndex) { 684 if (color == null) return defaultIndex; 685 int index = colorTable.indexOf(color); 686 if (index == -1) { 687 index = colorTable.size(); 688 colorTable.addElement(color); 689 } 690 return index; 691 } 692 700 int getFontIndex(Font font) { 701 int index = fontTable.indexOf(font); 702 if (index == -1) { 703 index = fontTable.size(); 704 fontTable.addElement(font); 705 } 706 return index; 707 } 708 712 void setUnicode() { 713 final String Win95 = "windows 95"; 714 final String Win98 = "windows 98"; 715 final String WinME = "windows me"; 716 final String WinNT = "windows nt"; 717 String osName = System.getProperty("os.name").toLowerCase(); 718 String osVersion = System.getProperty("os.version"); 719 int majorVersion = 0; 720 721 if (osName.startsWith(WinNT) && osVersion != null) { 722 int majorIndex = osVersion.indexOf('.'); 723 if (majorIndex != -1) { 724 osVersion = osVersion.substring(0, majorIndex); 725 try { 726 majorVersion = Integer.parseInt(osVersion); 727 } catch (NumberFormatException exception) { 728 } 731 } 732 } 733 WriteUnicode = !osName.startsWith(Win95) && 734 !osName.startsWith(Win98) && 735 !osName.startsWith(WinME) && 736 (!osName.startsWith(WinNT) || majorVersion > 4); 737 } 738 747 void write(String string, int start, int end) { 748 for (int index = start; index < end; index++) { 749 char ch = string.charAt(index); 750 if (ch > 0xFF && WriteUnicode) { 751 if (index > start) { 754 write(string.substring(start, index)); 755 } 756 write("\\u"); 757 write(Integer.toString((short) ch)); 758 write(' '); start = index + 1; 760 } else if (ch == '}' || ch == '{' || ch == '\\') { 761 if (index > start) { 764 write(string.substring(start, index)); 765 } 766 write('\\'); 767 write(ch); 768 start = index + 1; 769 } 770 } 771 if (start < end) { 774 write(string.substring(start, end)); 775 } 776 } 777 780 void writeHeader() { 781 StringBuffer header = new StringBuffer (); 782 FontData fontData = getFont().getFontData()[0]; 783 header.append("{\\rtf1\\ansi"); 784 String cpg = System.getProperty("file.encoding").toLowerCase(); 787 if (cpg.startsWith("cp") || cpg.startsWith("ms")) { 788 cpg = cpg.substring(2, cpg.length()); 789 header.append("\\ansicpg"); 790 header.append(cpg); 791 } 792 header.append("\\uc0\\deff0{\\fonttbl{\\f0\\fnil "); 793 header.append(fontData.getName()); 794 header.append(";"); 795 for (int i = 1; i < fontTable.size(); i++) { 796 header.append("\\f"); 797 header.append(i); 798 header.append(" "); 799 FontData fd = ((Font)fontTable.elementAt(i)).getFontData()[0]; 800 header.append(fd.getName()); 801 header.append(";"); 802 } 803 header.append("}}\n{\\colortbl"); 804 for (int i = 0; i < colorTable.size(); i++) { 805 Color color = (Color) colorTable.elementAt(i); 806 header.append("\\red"); 807 header.append(color.getRed()); 808 header.append("\\green"); 809 header.append(color.getGreen()); 810 header.append("\\blue"); 811 header.append(color.getBlue()); 812 header.append(";"); 813 } 814 header.append("}\n{\\f0\\fs"); 817 header.append(fontData.getHeight() * 2); 819 header.append(" "); 820 write(header.toString(), 0); 821 } 822 836 public void writeLine(String line, int lineOffset) { 837 if (isClosed()) { 838 SWT.error(SWT.ERROR_IO); 839 } 840 int lineIndex = content.getLineAtOffset(lineOffset); 841 int lineAlignment, lineIndent; 842 boolean lineJustify; 843 int[] ranges; 844 StyleRange[] styles; 845 StyledTextEvent event = getLineStyleData(lineOffset, line); 846 if (event != null) { 847 lineAlignment = event.alignment; 848 lineIndent = event.indent; 849 lineJustify = event.justify; 850 ranges = event.ranges; 851 styles = event.styles; 852 } else { 853 lineAlignment = renderer.getLineAlignment(lineIndex, alignment); 854 lineIndent = renderer.getLineIndent(lineIndex, indent); 855 lineJustify = renderer.getLineJustify(lineIndex, justify); 856 ranges = renderer.getRanges(lineOffset, line.length()); 857 styles = renderer.getStyleRanges(lineOffset, line.length(), false); 858 } 859 if (styles == null) styles = new StyleRange[0]; 860 Color lineBackground = renderer.getLineBackground(lineIndex, null); 861 event = getLineBackgroundData(lineOffset, line); 862 if (event != null && event.lineBackground != null) lineBackground = event.lineBackground; 863 writeStyledLine(line, lineOffset, ranges, styles, lineBackground, lineIndent, lineAlignment, lineJustify); 864 } 865 873 public void writeLineDelimiter(String lineDelimiter) { 874 if (isClosed()) { 875 SWT.error(SWT.ERROR_IO); 876 } 877 write(lineDelimiter, 0, lineDelimiter.length()); 878 write("\\par "); 879 } 880 898 void writeStyledLine(String line, int lineOffset, int ranges[], StyleRange[] styles, Color lineBackground, int indent, int alignment, boolean justify) { 899 int lineLength = line.length(); 900 int startOffset = getStart(); 901 int writeOffset = startOffset - lineOffset; 902 if (writeOffset >= lineLength) return; 903 int lineIndex = Math.max(0, writeOffset); 904 905 write("\\fi"); 906 write(indent); 907 switch (alignment) { 908 case SWT.LEFT: write("\\ql"); break; 909 case SWT.CENTER: write("\\qc"); break; 910 case SWT.RIGHT: write("\\qr"); break; 911 } 912 if (justify) write("\\qj"); 913 write(" "); 914 915 if (lineBackground != null) { 916 write("{\\highlight"); 917 write(getColorIndex(lineBackground, DEFAULT_BACKGROUND)); 918 write(" "); 919 } 920 int endOffset = startOffset + super.getCharCount(); 921 int lineEndOffset = Math.min(lineLength, endOffset - lineOffset); 922 for (int i = 0; i < styles.length; i++) { 923 StyleRange style = styles[i]; 924 int start, end; 925 if (ranges != null) { 926 start = ranges[i << 1] - lineOffset; 927 end = start + ranges[(i << 1) + 1]; 928 } else { 929 start = style.start - lineOffset; 930 end = start + style.length; 931 } 932 if (end < writeOffset) { 934 continue; 935 } 936 if (start >= lineEndOffset) { 938 break; 939 } 940 if (lineIndex < start) { 942 write(line, lineIndex, start); 946 lineIndex = start; 947 } 948 write("{\\cf"); 950 write(getColorIndex(style.foreground, DEFAULT_FOREGROUND)); 951 int colorIndex = getColorIndex(style.background, DEFAULT_BACKGROUND); 952 if (colorIndex != DEFAULT_BACKGROUND) { 953 write("\\highlight"); 954 write(colorIndex); 955 } 956 Font font = style.font; 957 if (font != null) { 958 int fontIndex = getFontIndex(font); 959 write("\\f"); 960 write(fontIndex); 961 FontData fontData = font.getFontData()[0]; 962 write("\\fs"); 963 write(fontData.getHeight() * 2); 964 } else { 965 if ((style.fontStyle & SWT.BOLD) != 0) { 966 write("\\b"); 967 } 968 if ((style.fontStyle & SWT.ITALIC) != 0) { 969 write("\\i"); 970 } 971 } 972 if (style.underline) { 973 write("\\ul"); 974 } 975 if (style.strikeout) { 976 write("\\strike"); 977 } 978 write(" "); 979 int copyEnd = Math.min(end, lineEndOffset); 981 copyEnd = Math.max(copyEnd, lineIndex); 983 write(line, lineIndex, copyEnd); 984 if (font == null) { 985 if ((style.fontStyle & SWT.BOLD) != 0) { 986 write("\\b0"); 987 } 988 if ((style.fontStyle & SWT.ITALIC) != 0) { 989 write("\\i0"); 990 } 991 } 992 if (style.underline) { 993 write("\\ul0"); 994 } 995 if (style.strikeout) { 996 write("\\strike0"); 997 } 998 write("}"); 999 lineIndex = copyEnd; 1000 } 1001 if (lineIndex < lineEndOffset) { 1003 write(line, lineIndex, lineEndOffset); 1004 } 1005 if (lineBackground != null) write("}"); 1006 } 1007 } 1008 1018 class TextWriter { 1019 private StringBuffer buffer; 1020 private int startOffset; private int endOffset; private boolean isClosed = false; 1024 1025 1032 public TextWriter(int start, int length) { 1033 buffer = new StringBuffer (length); 1034 startOffset = start; 1035 endOffset = start + length; 1036 } 1037 1042 public void close() { 1043 if (!isClosed) { 1044 isClosed = true; 1045 } 1046 } 1047 1051 public int getCharCount() { 1052 return endOffset - startOffset; 1053 } 1054 1059 public int getStart() { 1060 return startOffset; 1061 } 1062 1066 public boolean isClosed() { 1067 return isClosed; 1068 } 1069 1075 public String toString() { 1076 return buffer.toString(); 1077 } 1078 1081 void write(String string) { 1082 buffer.append(string); 1083 } 1084 1093 void write(String string, int offset) { 1094 if (offset < 0 || offset > buffer.length()) { 1095 return; 1096 } 1097 buffer.insert(offset, string); 1098 } 1099 1102 void write(int i) { 1103 buffer.append(i); 1104 } 1105 1108 void write(char i) { 1109 buffer.append(i); 1110 } 1111 1123 public void writeLine(String line, int lineOffset) { 1124 if (isClosed) { 1125 SWT.error(SWT.ERROR_IO); 1126 } 1127 int writeOffset = startOffset - lineOffset; 1128 int lineLength = line.length(); 1129 int lineIndex; 1130 if (writeOffset >= lineLength) { 1131 return; } else if (writeOffset > 0) { 1133 lineIndex = writeOffset; } else { 1135 lineIndex = 0; 1136 } 1137 int copyEnd = Math.min(lineLength, endOffset - lineOffset); 1138 if (lineIndex < copyEnd) { 1139 write(line.substring(lineIndex, copyEnd)); 1140 } 1141 } 1142 1150 public void writeLineDelimiter(String lineDelimiter) { 1151 if (isClosed) { 1152 SWT.error(SWT.ERROR_IO); 1153 } 1154 write(lineDelimiter); 1155 } 1156 } 1157 1158 1188public StyledText(Composite parent, int style) { 1189 super(parent, checkStyle(style)); 1190 super.setForeground(getForeground()); 1193 super.setDragDetect(false); 1194 Display display = getDisplay(); 1195 isMirrored = (super.getStyle() & SWT.MIRRORED) != 0; 1196 fixedLineHeight = true; 1197 if ((style & SWT.READ_ONLY) != 0) { 1198 setEditable(false); 1199 } 1200 leftMargin = rightMargin = isBidiCaret() ? BIDI_CARET_WIDTH - 1: 0; 1201 if ((style & SWT.SINGLE) != 0 && (style & SWT.BORDER) != 0) { 1202 leftMargin = topMargin = rightMargin = bottomMargin = 2; 1203 } 1204 alignment = style & (SWT.LEFT | SWT.RIGHT | SWT.CENTER); 1205 if (alignment == 0) alignment = SWT.LEFT; 1206 clipboard = new Clipboard(display); 1207 installDefaultContent(); 1208 renderer = new StyledTextRenderer(getDisplay(), this); 1209 renderer.setContent(content); 1210 renderer.setFont(getFont(), tabLength); 1211 defaultCaret = new Caret(this, SWT.NULL); 1212 if ((style & SWT.WRAP) != 0) { 1213 setWordWrap(true); 1214 } 1215 if (isBidiCaret()) { 1216 createCaretBitmaps(); 1217 Runnable runnable = new Runnable () { 1218 public void run() { 1219 int direction = BidiUtil.getKeyboardLanguage() == BidiUtil.KEYBOARD_BIDI ? SWT.RIGHT : SWT.LEFT; 1220 if (direction == caretDirection) return; 1221 if (getCaret() != defaultCaret) return; 1222 Point newCaretPos = getPointAtOffset(caretOffset); 1223 setCaretLocation(newCaretPos, direction); 1224 } 1225 }; 1226 BidiUtil.addLanguageListener(handle, runnable); 1227 } 1228 setCaret(defaultCaret); 1229 calculateScrollBars(); 1230 createKeyBindings(); 1231 setCursor(display.getSystemCursor(SWT.CURSOR_IBEAM)); 1232 installListeners(); 1233 initializeAccessible(); 1234 setData("DEFAULT_DROP_TARGET_EFFECT", new StyledTextDropTargetEffect(this)); 1235} 1236 1249public void addExtendedModifyListener(ExtendedModifyListener extendedModifyListener) { 1250 checkWidget(); 1251 if (extendedModifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1252 StyledTextListener typedListener = new StyledTextListener(extendedModifyListener); 1253 addListener(ExtendedModify, typedListener); 1254} 1255 1280public void addBidiSegmentListener(BidiSegmentListener listener) { 1281 checkWidget(); 1282 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1283 addListener(LineGetSegments, new StyledTextListener(listener)); 1284} 1285 1298public void addLineBackgroundListener(LineBackgroundListener listener) { 1299 checkWidget(); 1300 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1301 if (!isListening(LineGetBackground)) { 1302 renderer.clearLineBackground(0, content.getLineCount()); 1303 } 1304 addListener(LineGetBackground, new StyledTextListener(listener)); 1305} 1306 1319public void addLineStyleListener(LineStyleListener listener) { 1320 checkWidget(); 1321 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1322 if (!isListening(LineGetStyle)) { 1323 setStyleRanges(0, 0, null, null, true); 1324 renderer.clearLineStyle(0, content.getLineCount()); 1325 } 1326 addListener(LineGetStyle, new StyledTextListener(listener)); 1327} 1328 1341public void addModifyListener(ModifyListener modifyListener) { 1342 checkWidget(); 1343 if (modifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1344 addListener(SWT.Modify, new TypedListener(modifyListener)); 1345} 1346 1364public void addPaintObjectListener(PaintObjectListener listener) { 1365 checkWidget(); 1366 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1367 addListener(PaintObject, new StyledTextListener(listener)); 1368} 1369 1392public void addSelectionListener(SelectionListener listener) { 1393 checkWidget(); 1394 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1395 addListener(SWT.Selection, new TypedListener(listener)); 1396} 1397 1411public void addVerifyKeyListener(VerifyKeyListener listener) { 1412 checkWidget(); 1413 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1414 addListener(VerifyKey, new StyledTextListener(listener)); 1415} 1416 1431public void addVerifyListener(VerifyListener verifyListener) { 1432 checkWidget(); 1433 if (verifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1434 addListener(SWT.Verify, new TypedListener(verifyListener)); 1435} 1436 1456public void addWordMovementListener(MovementListener movementListener) { 1457 checkWidget(); 1458 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1459 addListener(WordNext, new StyledTextListener(movementListener)); 1460 addListener(WordPrevious, new StyledTextListener(movementListener)); 1461} 1462 1475public void append(String string) { 1476 checkWidget(); 1477 if (string == null) { 1478 SWT.error(SWT.ERROR_NULL_ARGUMENT); 1479 } 1480 int lastChar = Math.max(getCharCount(), 0); 1481 replaceTextRange(lastChar, 0, string); 1482} 1483 1486void calculateScrollBars() { 1487 ScrollBar horizontalBar = getHorizontalBar(); 1488 ScrollBar verticalBar = getVerticalBar(); 1489 setScrollBars(true); 1490 if (verticalBar != null) { 1491 verticalBar.setIncrement(getVerticalIncrement()); 1492 } 1493 if (horizontalBar != null) { 1494 horizontalBar.setIncrement(getHorizontalIncrement()); 1495 } 1496} 1497 1503void calculateTopIndex(int delta) { 1504 int oldTopIndex = topIndex; 1505 int oldTopIndexY = topIndexY; 1506 if (isFixedLineHeight()) { 1507 int verticalIncrement = getVerticalIncrement(); 1508 if (verticalIncrement == 0) { 1509 return; 1510 } 1511 topIndex = Compatibility.ceil(getVerticalScrollOffset(), verticalIncrement); 1512 if (topIndex > 0) { 1516 if (clientAreaHeight > 0) { 1517 int bottomPixel = getVerticalScrollOffset() + clientAreaHeight; 1518 int fullLineTopPixel = topIndex * verticalIncrement; 1519 int fullLineVisibleHeight = bottomPixel - fullLineTopPixel; 1520 if (fullLineVisibleHeight < verticalIncrement) { 1524 topIndex--; 1525 } 1526 } else if (topIndex >= content.getLineCount()) { 1527 topIndex = content.getLineCount() - 1; 1528 } 1529 } 1530 } else { 1531 if (delta >= 0) { 1532 delta -= topIndexY; 1533 int lineIndex = topIndex; 1534 int lineCount = content.getLineCount(); 1535 while (lineIndex < lineCount) { 1536 if (delta <= 0) break; 1537 delta -= renderer.getLineHeight(lineIndex++); 1538 } 1539 if (lineIndex < lineCount && -delta + renderer.getLineHeight(lineIndex) <= clientAreaHeight - topMargin - bottomMargin) { 1540 topIndex = lineIndex; 1541 topIndexY = -delta; 1542 } else { 1543 topIndex = lineIndex - 1; 1544 topIndexY = -renderer.getLineHeight(topIndex) - delta; 1545 } 1546 } else { 1547 delta -= topIndexY; 1548 int lineIndex = topIndex; 1549 while (lineIndex > 0) { 1550 int lineHeight = renderer.getLineHeight(lineIndex - 1); 1551 if (delta + lineHeight > 0) break; 1552 delta += lineHeight; 1553 lineIndex--; 1554 } 1555 if (lineIndex == 0 || -delta + renderer.getLineHeight(lineIndex) <= clientAreaHeight - topMargin - bottomMargin) { 1556 topIndex = lineIndex; 1557 topIndexY = - delta; 1558 } else { 1559 topIndex = lineIndex - 1; 1560 topIndexY = - renderer.getLineHeight(topIndex) - delta; 1561 } 1562 } 1563 } 1564 if (topIndex != oldTopIndex || oldTopIndexY != topIndexY) { 1565 renderer.calculateClientArea(); 1566 setScrollBars(false); 1567 } 1568} 1569 1572static int checkStyle(int style) { 1573 if ((style & SWT.SINGLE) != 0) { 1574 style &= ~(SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP | SWT.MULTI); 1575 } else { 1576 style |= SWT.MULTI; 1577 if ((style & SWT.WRAP) != 0) { 1578 style &= ~SWT.H_SCROLL; 1579 } 1580 } 1581 style |= SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND; 1582 return style; 1583} 1584 1588void claimBottomFreeSpace() { 1589 int clientAreaHeight = this.clientAreaHeight - topMargin - bottomMargin; 1590 if (isFixedLineHeight()) { 1591 int lineHeight = renderer.getLineHeight(); 1592 int newVerticalOffset = Math.max(0, content.getLineCount() * lineHeight - clientAreaHeight); 1593 if (newVerticalOffset < getVerticalScrollOffset()) { 1594 scrollVertical(newVerticalOffset - getVerticalScrollOffset(), true); 1595 } 1596 } else { 1597 int bottomIndex = getPartialBottomIndex(); 1598 int height = getLinePixel(bottomIndex + 1); 1599 if (clientAreaHeight > height) { 1600 scrollVertical(-getAvailableHeightAbove(clientAreaHeight - height), true); 1601 } 1602 } 1603} 1604 1607void claimRightFreeSpace() { 1608 int newHorizontalOffset = Math.max(0, renderer.getWidth() - (clientAreaWidth - leftMargin - rightMargin)); 1609 if (newHorizontalOffset < horizontalScrollOffset) { 1610 scrollHorizontal(newHorizontalOffset - horizontalScrollOffset, true); 1614 } 1615} 1616 1621void clearSelection(boolean sendEvent) { 1622 int selectionStart = selection.x; 1623 int selectionEnd = selection.y; 1624 resetSelection(); 1625 if (selectionEnd - selectionStart > 0) { 1627 int length = content.getCharCount(); 1628 int redrawStart = Math.min(selectionStart, length); 1631 int redrawEnd = Math.min(selectionEnd, length); 1632 if (redrawEnd - redrawStart > 0) { 1633 internalRedrawRange(redrawStart, redrawEnd - redrawStart); 1634 } 1635 if (sendEvent) { 1636 sendSelectionEvent(); 1637 } 1638 } 1639} 1640public Point computeSize (int wHint, int hHint, boolean changed) { 1641 checkWidget(); 1642 int lineCount = (getStyle() & SWT.SINGLE) != 0 ? 1 : content.getLineCount(); 1643 int width = 0; 1644 int height = 0; 1645 if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) { 1646 Display display = getDisplay(); 1647 int maxHeight = display.getClientArea().height; 1648 for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) { 1649 TextLayout layout = renderer.getTextLayout(lineIndex); 1650 if (wordWrap) layout.setWidth(wHint == 0 ? 1 : wHint); 1651 Rectangle rect = layout.getBounds(); 1652 height += rect.height; 1653 width = Math.max(width, rect.width); 1654 renderer.disposeTextLayout(layout); 1655 if (isFixedLineHeight() && height > maxHeight) break; 1656 } 1657 if (isFixedLineHeight()) { 1658 height = lineCount * renderer.getLineHeight(); 1659 } 1660 } 1661 if (width == 0) width = DEFAULT_WIDTH; 1663 if (height == 0) height = DEFAULT_HEIGHT; 1664 if (wHint != SWT.DEFAULT) width = wHint; 1665 if (hHint != SWT.DEFAULT) height = hHint; 1666 int wTrim = leftMargin + rightMargin + getCaretWidth(); 1667 int hTrim = topMargin + bottomMargin; 1668 Rectangle rect = computeTrim(0, 0, width + wTrim, height + hTrim); 1669 return new Point (rect.width, rect.height); 1670} 1671 1685public void copy() { 1686 checkWidget(); 1687 copy(DND.CLIPBOARD); 1688} 1689 1710public void copy(int clipboardType) { 1711 checkWidget(); 1712 if (clipboardType != DND.CLIPBOARD && clipboardType != DND.SELECTION_CLIPBOARD) return; 1713 int length = selection.y - selection.x; 1714 if (length > 0) { 1715 try { 1716 setClipboardContent(selection.x, length, clipboardType); 1717 } catch (SWTError error) { 1718 if (error.code != DND.ERROR_CANNOT_SET_CLIPBOARD) { 1723 throw error; 1724 } 1725 } 1726 } 1727} 1728 1742public int getAlignment() { 1743 checkWidget(); 1744 return alignment; 1745} 1746int getAvailableHeightAbove(int height) { 1747 int maxHeight = verticalScrollOffset; 1748 if (maxHeight == -1) { 1749 int lineIndex = topIndex - 1; 1750 maxHeight = -topIndexY; 1751 if (topIndexY > 0) { 1752 maxHeight += renderer.getLineHeight(lineIndex--); 1753 } 1754 while (height > maxHeight && lineIndex >= 0) { 1755 maxHeight += renderer.getLineHeight(lineIndex--); 1756 } 1757 } 1758 return Math.min(height, maxHeight); 1759} 1760int getAvailableHeightBellow(int height) { 1761 int partialBottomIndex = getPartialBottomIndex(); 1762 int topY = getLinePixel(partialBottomIndex); 1763 int lineHeight = renderer.getLineHeight(partialBottomIndex); 1764 int availableHeight = 0; 1765 int clientAreaHeight = this.clientAreaHeight - topMargin - bottomMargin; 1766 if (topY + lineHeight > clientAreaHeight) { 1767 availableHeight = lineHeight - (clientAreaHeight - topY); 1768 } 1769 int lineIndex = partialBottomIndex + 1; 1770 int lineCount = content.getLineCount(); 1771 while (height > availableHeight && lineIndex < lineCount) { 1772 availableHeight += renderer.getLineHeight(lineIndex++); 1773 } 1774 return Math.min(height, availableHeight); 1775} 1776 1790String getModelDelimitedText(String text) { 1791 int length = text.length(); 1792 if (length == 0) { 1793 return text; 1794 } 1795 int crIndex = 0; 1796 int lfIndex = 0; 1797 int i = 0; 1798 StringBuffer convertedText = new StringBuffer (length); 1799 String delimiter = getLineDelimiter(); 1800 while (i < length) { 1801 if (crIndex != -1) { 1802 crIndex = text.indexOf(SWT.CR, i); 1803 } 1804 if (lfIndex != -1) { 1805 lfIndex = text.indexOf(SWT.LF, i); 1806 } 1807 if (lfIndex == -1 && crIndex == -1) { break; 1809 } else if ((crIndex < lfIndex && crIndex != -1) || lfIndex == -1) { 1810 convertedText.append(text.substring(i, crIndex)); 1811 if (lfIndex == crIndex + 1) { i = lfIndex + 1; 1813 } else { 1814 i = crIndex + 1; 1815 } 1816 } else { convertedText.append(text.substring(i, lfIndex)); 1818 i = lfIndex + 1; 1819 } 1820 if (isSingleLine()) { 1821 break; 1822 } 1823 convertedText.append(delimiter); 1824 } 1825 if (i < length && (!isSingleLine() || convertedText.length() == 0)) { 1828 convertedText.append(text.substring(i)); 1829 } 1830 return convertedText.toString(); 1831} 1832boolean checkDragDetect(Event event) { 1833 if (!isListening(SWT.DragDetect)) return false; 1834 if (IS_MOTIF) { 1835 if (event.button != 2) return false; 1836 } else { 1837 if (event.button != 1) return false; 1838 } 1839 if (selection.x == selection.y) return false; 1840 int offset = getOffsetAtPoint(event.x, event.y); 1841 if (offset > selection.x && offset < selection.y) { 1842 return dragDetect(event); 1843 } 1844 return false; 1845} 1846 1849void createKeyBindings() { 1850 int nextKey = isMirrored() ? SWT.ARROW_LEFT : SWT.ARROW_RIGHT; 1851 int previousKey = isMirrored() ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT; 1852 1853 setKeyBinding(SWT.ARROW_UP, ST.LINE_UP); 1855 setKeyBinding(SWT.ARROW_DOWN, ST.LINE_DOWN); 1856 if (IS_CARBON) { 1857 setKeyBinding(previousKey | SWT.MOD1, ST.LINE_START); 1858 setKeyBinding(nextKey | SWT.MOD1, ST.LINE_END); 1859 setKeyBinding(SWT.HOME, ST.TEXT_START); 1860 setKeyBinding(SWT.END, ST.TEXT_END); 1861 setKeyBinding(SWT.ARROW_UP | SWT.MOD1, ST.TEXT_START); 1862 setKeyBinding(SWT.ARROW_DOWN | SWT.MOD1, ST.TEXT_END); 1863 setKeyBinding(nextKey | SWT.MOD3, ST.WORD_NEXT); 1864 setKeyBinding(previousKey | SWT.MOD3, ST.WORD_PREVIOUS); 1865 } else { 1866 setKeyBinding(SWT.HOME, ST.LINE_START); 1867 setKeyBinding(SWT.END, ST.LINE_END); 1868 setKeyBinding(SWT.HOME | SWT.MOD1, ST.TEXT_START); 1869 setKeyBinding(SWT.END | SWT.MOD1, ST.TEXT_END); 1870 setKeyBinding(nextKey | SWT.MOD1, ST.WORD_NEXT); 1871 setKeyBinding(previousKey | SWT.MOD1, ST.WORD_PREVIOUS); 1872 } 1873 setKeyBinding(SWT.PAGE_UP, ST.PAGE_UP); 1874 setKeyBinding(SWT.PAGE_DOWN, ST.PAGE_DOWN); 1875 setKeyBinding(SWT.PAGE_UP | SWT.MOD1, ST.WINDOW_START); 1876 setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1, ST.WINDOW_END); 1877 setKeyBinding(nextKey, ST.COLUMN_NEXT); 1878 setKeyBinding(previousKey, ST.COLUMN_PREVIOUS); 1879 1880 setKeyBinding(SWT.ARROW_UP | SWT.MOD2, ST.SELECT_LINE_UP); 1882 setKeyBinding(SWT.ARROW_DOWN | SWT.MOD2, ST.SELECT_LINE_DOWN); 1883 if (IS_CARBON) { 1884 setKeyBinding(previousKey | SWT.MOD1 | SWT.MOD2, ST.SELECT_LINE_START); 1885 setKeyBinding(nextKey | SWT.MOD1 | SWT.MOD2, ST.SELECT_LINE_END); 1886 setKeyBinding(SWT.HOME | SWT.MOD2, ST.SELECT_TEXT_START); 1887 setKeyBinding(SWT.END | SWT.MOD2, ST.SELECT_TEXT_END); 1888 setKeyBinding(SWT.ARROW_UP | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_START); 1889 setKeyBinding(SWT.ARROW_DOWN | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_END); 1890 setKeyBinding(nextKey | SWT.MOD2 | SWT.MOD3, ST.SELECT_WORD_NEXT); 1891 setKeyBinding(previousKey | SWT.MOD2 | SWT.MOD3, ST.SELECT_WORD_PREVIOUS); 1892 } else { 1893 setKeyBinding(SWT.HOME | SWT.MOD2, ST.SELECT_LINE_START); 1894 setKeyBinding(SWT.END | SWT.MOD2, ST.SELECT_LINE_END); 1895 setKeyBinding(SWT.HOME | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_START); 1896 setKeyBinding(SWT.END | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_END); 1897 setKeyBinding(nextKey | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT); 1898 setKeyBinding(previousKey | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS); 1899 } 1900 setKeyBinding(SWT.PAGE_UP | SWT.MOD2, ST.SELECT_PAGE_UP); 1901 setKeyBinding(SWT.PAGE_DOWN | SWT.MOD2, ST.SELECT_PAGE_DOWN); 1902 setKeyBinding(SWT.PAGE_UP | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_START); 1903 setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_END); 1904 setKeyBinding(nextKey | SWT.MOD2, ST.SELECT_COLUMN_NEXT); 1905 setKeyBinding(previousKey | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS); 1906 1907 setKeyBinding('X' | SWT.MOD1, ST.CUT); 1910 setKeyBinding('C' | SWT.MOD1, ST.COPY); 1911 setKeyBinding('V' | SWT.MOD1, ST.PASTE); 1912 if (IS_CARBON) { 1913 setKeyBinding(SWT.DEL | SWT.MOD2, ST.DELETE_NEXT); 1914 setKeyBinding(SWT.BS | SWT.MOD3, ST.DELETE_WORD_PREVIOUS); 1915 setKeyBinding(SWT.DEL | SWT.MOD3, ST.DELETE_WORD_NEXT); 1916 } else { 1917 setKeyBinding(SWT.DEL | SWT.MOD2, ST.CUT); 1919 setKeyBinding(SWT.INSERT | SWT.MOD1, ST.COPY); 1920 setKeyBinding(SWT.INSERT | SWT.MOD2, ST.PASTE); 1921 } 1922 setKeyBinding(SWT.BS | SWT.MOD2, ST.DELETE_PREVIOUS); 1923 setKeyBinding(SWT.BS, ST.DELETE_PREVIOUS); 1924 setKeyBinding(SWT.DEL, ST.DELETE_NEXT); 1925 setKeyBinding(SWT.BS | SWT.MOD1, ST.DELETE_WORD_PREVIOUS); 1926 setKeyBinding(SWT.DEL | SWT.MOD1, ST.DELETE_WORD_NEXT); 1927 1928 setKeyBinding(SWT.INSERT, ST.TOGGLE_OVERWRITE); 1930} 1931 1936void createCaretBitmaps() { 1937 int caretWidth = BIDI_CARET_WIDTH; 1938 Display display = getDisplay(); 1939 if (leftCaretBitmap != null) { 1940 if (defaultCaret != null && leftCaretBitmap.equals(defaultCaret.getImage())) { 1941 defaultCaret.setImage(null); 1942 } 1943 leftCaretBitmap.dispose(); 1944 } 1945 int lineHeight = renderer.getLineHeight(); 1946 leftCaretBitmap = new Image(display, caretWidth, lineHeight); 1947 GC gc = new GC (leftCaretBitmap); 1948 gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); 1949 gc.fillRectangle(0, 0, caretWidth, lineHeight); 1950 gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); 1951 gc.drawLine(0,0,0,lineHeight); 1952 gc.drawLine(0,0,caretWidth-1,0); 1953 gc.drawLine(0,1,1,1); 1954 gc.dispose(); 1955 1956 if (rightCaretBitmap != null) { 1957 if (defaultCaret != null && rightCaretBitmap.equals(defaultCaret.getImage())) { 1958 defaultCaret.setImage(null); 1959 } 1960 rightCaretBitmap.dispose(); 1961 } 1962 rightCaretBitmap = new Image(display, caretWidth, lineHeight); 1963 gc = new GC (rightCaretBitmap); 1964 gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); 1965 gc.fillRectangle(0, 0, caretWidth, lineHeight); 1966 gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); 1967 gc.drawLine(caretWidth-1,0,caretWidth-1,lineHeight); 1968 gc.drawLine(0,0,caretWidth-1,0); 1969 gc.drawLine(caretWidth-1,1,1,1); 1970 gc.dispose(); 1971} 1972 1981public void cut(){ 1982 checkWidget(); 1983 int length = selection.y - selection.x; 1984 if (length > 0) { 1985 try { 1986 setClipboardContent(selection.x, length, DND.CLIPBOARD); 1987 } catch (SWTError error) { 1988 if (error.code != DND.ERROR_CANNOT_SET_CLIPBOARD) { 1993 throw error; 1994 } 1995 return; 1998 } 1999 doDelete(); 2000 } 2001} 2002 2007void doAutoScroll(Event event) { 2008 if (event.y > clientAreaHeight) { 2009 doAutoScroll(SWT.DOWN, event.y - clientAreaHeight); 2010 } else if (event.y < 0) { 2011 doAutoScroll(SWT.UP, -event.y); 2012 } else if (event.x < leftMargin && !wordWrap) { 2013 doAutoScroll(ST.COLUMN_PREVIOUS, leftMargin - event.x); 2014 } else if (event.x > clientAreaWidth - leftMargin - rightMargin && !wordWrap) { 2015 doAutoScroll(ST.COLUMN_NEXT, event.x - (clientAreaWidth - leftMargin - rightMargin)); 2016 } else { 2017 endAutoScroll(); 2018 } 2019} 2020 2025void doAutoScroll(int direction, int distance) { 2026 autoScrollDistance = distance; 2027 if (autoScrollDirection == direction) { 2029 return; 2030 } 2031 2032 Runnable timer = null; 2033 final Display display = getDisplay(); 2034 if (direction == SWT.UP) { 2037 timer = new Runnable () { 2038 public void run() { 2039 if (autoScrollDirection == SWT.UP) { 2040 doSelectionPageUp(autoScrollDistance); 2041 display.timerExec(V_SCROLL_RATE, this); 2042 } 2043 } 2044 }; 2045 autoScrollDirection = direction; 2046 display.timerExec(V_SCROLL_RATE, timer); 2047 } else if (direction == SWT.DOWN) { 2048 timer = new Runnable () { 2049 public void run() { 2050 if (autoScrollDirection == SWT.DOWN) { 2051 doSelectionPageDown(autoScrollDistance); 2052 display.timerExec(V_SCROLL_RATE, this); 2053 } 2054 } 2055 }; 2056 autoScrollDirection = direction; 2057 display.timerExec(V_SCROLL_RATE, timer); 2058 } else if (direction == ST.COLUMN_NEXT) { 2059 timer = new Runnable () { 2060 public void run() { 2061 if (autoScrollDirection == ST.COLUMN_NEXT) { 2062 doVisualNext(); 2063 setMouseWordSelectionAnchor(); 2064 doMouseSelection(); 2065 display.timerExec(H_SCROLL_RATE, this); 2066 } 2067 } 2068 }; 2069 autoScrollDirection = direction; 2070 display.timerExec(H_SCROLL_RATE, timer); 2071 } else if (direction == ST.COLUMN_PREVIOUS) { 2072 timer = new Runnable () { 2073 public void run() { 2074 if (autoScrollDirection == ST.COLUMN_PREVIOUS) { 2075 doVisualPrevious(); 2076 setMouseWordSelectionAnchor(); 2077 doMouseSelection(); 2078 display.timerExec(H_SCROLL_RATE, this); 2079 } 2080 } 2081 }; 2082 autoScrollDirection = direction; 2083 display.timerExec(H_SCROLL_RATE, timer); 2084 } 2085} 2086 2090void doBackspace() { 2091 Event event = new Event(); 2092 event.text = ""; 2093 if (selection.x != selection.y) { 2094 event.start = selection.x; 2095 event.end = selection.y; 2096 sendKeyEvent(event); 2097 } else if (caretOffset > 0) { 2098 int lineIndex = content.getLineAtOffset(caretOffset); 2099 int lineOffset = content.getOffsetAtLine(lineIndex); 2100 if (caretOffset == lineOffset) { 2101 lineOffset = content.getOffsetAtLine(lineIndex - 1); 2102 event.start = lineOffset + content.getLine(lineIndex - 1).length(); 2103 event.end = caretOffset; 2104 } else { 2105 TextLayout layout = renderer.getTextLayout(lineIndex); 2106 int start = layout.getPreviousOffset(caretOffset - lineOffset, SWT.MOVEMENT_CHAR); 2107 renderer.disposeTextLayout(layout); 2108 event.start = start + lineOffset; 2109 event.end = caretOffset; 2110 } 2111 sendKeyEvent(event); 2112 } 2113} 2114 2124void doContent(char key) { 2125 if (textLimit > 0 && 2126 content.getCharCount() - (selection.y - selection.x) >= textLimit) { 2127 return; 2128 } 2129 Event event = new Event(); 2130 event.start = selection.x; 2131 event.end = selection.y; 2132 if (key == SWT.CR || key == SWT.LF) { 2136 if (!isSingleLine()) { 2137 event.text = getLineDelimiter(); 2138 } 2139 } else if (selection.x == selection.y && overwrite && key != TAB) { 2140 int lineIndex = content.getLineAtOffset(event.end); 2143 int lineOffset = content.getOffsetAtLine(lineIndex); 2144 String line = content.getLine(lineIndex); 2145 if (event.end < lineOffset + line.length()) { 2148 event.end++; 2149 } 2150 event.text = new String (new char[] {key}); 2151 } else { 2152 event.text = new String (new char[] {key}); 2153 } 2154 if (event.text != null) { 2155 sendKeyEvent(event); 2156 } 2157} 2158 2161void doContentEnd() { 2162 if (isSingleLine()) { 2165 doLineEnd(); 2166 } else { 2167 int length = content.getCharCount(); 2168 if (caretOffset < length) { 2169 caretOffset = length; 2170 showCaret(); 2171 } 2172 } 2173} 2174 2177void doContentStart() { 2178 if (caretOffset > 0) { 2179 caretOffset = 0; 2180 showCaret(); 2181 } 2182} 2183 2190void doCursorPrevious() { 2191 if (selection.y - selection.x > 0) { 2192 caretOffset = selection.x; 2193 caretAlignment = OFFSET_LEADING; 2194 showCaret(); 2195 } else { 2196 doSelectionCursorPrevious(); 2197 } 2198} 2199 2206void doCursorNext() { 2207 if (selection.y - selection.x > 0) { 2208 caretOffset = selection.y; 2209 caretAlignment = PREVIOUS_OFFSET_TRAILING; 2210 showCaret(); 2211 } else { 2212 doSelectionCursorNext(); 2213 } 2214} 2215 2218void doDelete() { 2219 Event event = new Event(); 2220 event.text = ""; 2221 if (selection.x != selection.y) { 2222 event.start = selection.x; 2223 event.end = selection.y; 2224 sendKeyEvent(event); 2225 } else if (caretOffset < content.getCharCount()) { 2226 int line = content.getLineAtOffset(caretOffset); 2227 int lineOffset = content.getOffsetAtLine(line); 2228 int lineLength = content.getLine(line).length(); 2229 if (caretOffset == lineOffset + lineLength) { 2230 event.start = caretOffset; 2231 event.end = content.getOffsetAtLine(line + 1); 2232 } else { 2233 event.start = caretOffset; 2234 event.end = getClusterNext(caretOffset, line); 2235 } 2236 sendKeyEvent(event); 2237 } 2238} 2239 2242void doDeleteWordNext() { 2243 if (selection.x != selection.y) { 2244 doDelete(); 2247 } else { 2248 Event event = new Event(); 2249 event.text = ""; 2250 event.start = caretOffset; 2251 event.end = getWordNext(caretOffset, SWT.MOVEMENT_WORD); 2252 sendKeyEvent(event); 2253 } 2254} 2255 2258void doDeleteWordPrevious() { 2259 if (selection.x != selection.y) { 2260 doBackspace(); 2263 } else { 2264 Event event = new Event(); 2265 event.text = ""; 2266 event.start = getWordPrevious(caretOffset, SWT.MOVEMENT_WORD); 2267 event.end = caretOffset; 2268 sendKeyEvent(event); 2269 } 2270} 2271 2276void doLineDown(boolean select) { 2277 int caretLine = getCaretLine(); 2278 int lineCount = content.getLineCount(); 2279 int y = 0; 2280 boolean lastLine = false; 2281 if (wordWrap) { 2282 int lineOffset = content.getOffsetAtLine(caretLine); 2283 int offsetInLine = caretOffset - lineOffset; 2284 TextLayout layout = renderer.getTextLayout(caretLine); 2285 int lineIndex = getVisualLineIndex(layout, offsetInLine); 2286 int layoutLineCount = layout.getLineCount(); 2287 if (lineIndex == layoutLineCount - 1) { 2288 lastLine = caretLine == lineCount - 1; 2289 caretLine++; 2290 } else { 2291 y = layout.getLineBounds(lineIndex + 1).y; 2292 } 2293 renderer.disposeTextLayout(layout); 2294 } else { 2295 lastLine = caretLine == lineCount - 1; 2296 caretLine++; 2297 } 2298 if (lastLine) { 2299 if (select) caretOffset = content.getCharCount(); 2300 } else { 2301 caretOffset = getOffsetAtPoint(columnX, y, caretLine); 2302 } 2303 int oldColumnX = columnX; 2304 int oldHScrollOffset = horizontalScrollOffset; 2305 if (select) { 2306 setMouseWordSelectionAnchor(); 2307 doSelection(ST.COLUMN_NEXT); 2310 } 2311 showCaret(); 2312 int hScrollChange = oldHScrollOffset - horizontalScrollOffset; 2313 columnX = oldColumnX + hScrollChange; 2314} 2315 2318void doLineEnd() { 2319 int caretLine = getCaretLine(); 2320 int lineOffset = content.getOffsetAtLine(caretLine); 2321 int lineEndOffset; 2322 if (wordWrap) { 2323 TextLayout layout = renderer.getTextLayout(caretLine); 2324 int offsetInLine = caretOffset - lineOffset; 2325 int lineIndex = getVisualLineIndex(layout, offsetInLine); 2326 int[] offsets = layout.getLineOffsets(); 2327 lineEndOffset = lineOffset + offsets[lineIndex + 1]; 2328 renderer.disposeTextLayout(layout); 2329 } else { 2330 int lineLength = content.getLine(caretLine).length(); 2331 lineEndOffset = lineOffset + lineLength; 2332 } 2333 if (caretOffset < lineEndOffset) { 2334 caretOffset = lineEndOffset; 2335 caretAlignment = PREVIOUS_OFFSET_TRAILING; 2336 showCaret(); 2337 } 2338} 2339 2342void doLineStart() { 2343 int caretLine = getCaretLine(); 2344 int lineOffset = content.getOffsetAtLine(caretLine); 2345 if (wordWrap) { 2346 TextLayout layout = renderer.getTextLayout(caretLine); 2347 int offsetInLine = caretOffset - lineOffset; 2348 int lineIndex = getVisualLineIndex(layout, offsetInLine); 2349 int[] offsets = layout.getLineOffsets(); 2350 lineOffset += offsets[lineIndex]; 2351 renderer.disposeTextLayout(layout); 2352 } 2353 if (caretOffset > lineOffset) { 2354 caretOffset = lineOffset; 2355 caretAlignment = OFFSET_LEADING; 2356 showCaret(); 2357 } 2358} 2359 2364void doLineUp(boolean select) { 2365 int caretLine = getCaretLine(), y = 0; 2366 boolean firstLine = false; 2367 if (wordWrap) { 2368 int lineOffset = content.getOffsetAtLine(caretLine); 2369 int offsetInLine = caretOffset - lineOffset; 2370 TextLayout layout = renderer.getTextLayout(caretLine); 2371 int lineIndex = getVisualLineIndex(layout, offsetInLine); 2372 if (lineIndex == 0) { 2373 firstLine = caretLine == 0; 2374 if (!firstLine) { 2375 caretLine--; 2376 y = renderer.getLineHeight(caretLine) - 1; 2377 } 2378 } else { 2379 y = layout.getLineBounds(lineIndex - 1).y; 2380 } 2381 renderer.disposeTextLayout(layout); 2382 } else { 2383 firstLine = caretLine == 0; 2384 caretLine--; 2385 } 2386 if (firstLine) { 2387 if (select) caretOffset = 0; 2388 } else { 2389 caretOffset = getOffsetAtPoint(columnX, y, caretLine); 2390 } 2391 int oldColumnX = columnX; 2392 int oldHScrollOffset = horizontalScrollOffset; 2393 if (select) setMouseWordSelectionAnchor(); 2394 showCaret(); 2395 if (select) doSelection(ST.COLUMN_PREVIOUS); 2396 int hScrollChange = oldHScrollOffset - horizontalScrollOffset; 2397 columnX = oldColumnX + hScrollChange; 2398} 2399 2407void doMouseLocationChange(int x, int y, boolean select) { 2408 int line = getLineIndex(y); 2409 2410 updateCaretDirection = true; 2411 if (line < 0 || (isSingleLine() && line > 0)) { 2414 return; 2415 } 2416 int oldCaretAlignment = caretAlignment; 2417 int newCaretOffset = getOffsetAtPoint(x, y); 2418 2419 if (clickCount > 1) { 2420 newCaretOffset = doMouseWordSelect(x, newCaretOffset, line); 2422 } 2423 2424 int newCaretLine = content.getLineAtOffset(newCaretOffset); 2425 2426 if (0 <= y && y < clientAreaHeight && 2430 (0 <= x && x < clientAreaWidth || wordWrap || 2431 newCaretLine != content.getLineAtOffset(caretOffset))) { 2432 if (newCaretOffset != caretOffset || caretAlignment != oldCaretAlignment) { 2433 caretOffset = newCaretOffset; 2434 if (select) doMouseSelection(); 2435 showCaret(); 2436 } 2437 } 2438 if (!select) { 2439 caretOffset = newCaretOffset; 2440 clearSelection(true); 2441 } 2442} 2443 2446void doMouseSelection() { 2447 if (caretOffset <= selection.x || 2448 (caretOffset > selection.x && 2449 caretOffset < selection.y && selectionAnchor == selection.x)) { 2450 doSelection(ST.COLUMN_PREVIOUS); 2451 } else { 2452 doSelection(ST.COLUMN_NEXT); 2453 } 2454} 2455 2468int doMouseWordSelect(int x, int newCaretOffset, int line) { 2469 if (newCaretOffset < selectionAnchor && selectionAnchor == selection.x) { 2474 selectionAnchor = doubleClickSelection.y; 2475 } else if (newCaretOffset > selectionAnchor && selectionAnchor == selection.y) { 2476 selectionAnchor = doubleClickSelection.x; 2477 } 2478 if (0 <= x && x < clientAreaWidth) { 2479 boolean wordSelect = (clickCount & 1) == 0; 2480 if (caretOffset == selection.x) { 2481 if (wordSelect) { 2482 newCaretOffset = getWordPrevious(newCaretOffset, SWT.MOVEMENT_WORD_START); 2483 } else { 2484 newCaretOffset = content.getOffsetAtLine(line); 2485 } 2486 } else { 2487 if (wordSelect) { 2488 newCaretOffset = getWordNext(newCaretOffset, SWT.MOVEMENT_WORD_END); 2489 } else { 2490 int lineEnd = content.getCharCount(); 2491 if (line + 1 < content.getLineCount()) { 2492 lineEnd = content.getOffsetAtLine(line + 1); 2493 } 2494 newCaretOffset = lineEnd; 2495 } 2496 } 2497 } 2498 return newCaretOffset; 2499} 2500 2512void doPageDown(boolean select, int height) { 2513 if (isSingleLine()) return; 2514 int oldColumnX = columnX; 2515 int oldHScrollOffset = horizontalScrollOffset; 2516 if (isFixedLineHeight()) { 2517 int lineCount = content.getLineCount(); 2518 int caretLine = getCaretLine(); 2519 if (caretLine < lineCount - 1) { 2520 int lineHeight = renderer.getLineHeight(); 2521 int lines = (height == -1 ? clientAreaHeight : height) / lineHeight; 2522 int scrollLines = Math.min(lineCount - caretLine - 1, lines); 2523 scrollLines = Math.max(1, scrollLines); 2526 caretOffset = getOffsetAtPoint(columnX, getLinePixel(caretLine + scrollLines)); 2527 if (select) { 2528 doSelection(ST.COLUMN_NEXT); 2529 } 2530 int verticalMaximum = lineCount * getVerticalIncrement(); 2532 int pageSize = clientAreaHeight; 2533 int verticalScrollOffset = getVerticalScrollOffset(); 2534 int scrollOffset = verticalScrollOffset + scrollLines * getVerticalIncrement(); 2535 if (scrollOffset + pageSize > verticalMaximum) { 2536 scrollOffset = verticalMaximum - pageSize; 2537 } 2538 if (scrollOffset > verticalScrollOffset) { 2539 scrollVertical(scrollOffset - verticalScrollOffset, true); 2540 } 2541 } 2542 } else { 2543 int lineCount = content.getLineCount(); 2544 int caretLine = getCaretLine(); 2545 int lineIndex, lineHeight; 2546 if (height == -1) { 2547 lineIndex = getPartialBottomIndex(); 2548 int topY = getLinePixel(lineIndex); 2549 lineHeight = renderer.getLineHeight(lineIndex); 2550 height = topY; 2551 if (topY + lineHeight <= clientAreaHeight) { 2552 height += lineHeight; 2553 } else { 2554 if (wordWrap) { 2555 TextLayout layout = renderer.getTextLayout(lineIndex); 2556 int y = clientAreaHeight - topY; 2557 for (int i = 0; i < layout.getLineCount(); i++) { 2558 Rectangle bounds = layout.getLineBounds(i); 2559 if (bounds.contains(bounds.x, y)) { 2560 height += bounds.y; 2561 break; 2562 } 2563 } 2564 renderer.disposeTextLayout(layout); 2565 } 2566 } 2567 } else { 2568 lineIndex = getLineIndex(height); 2569 int topLineY = getLinePixel(lineIndex); 2570 if (wordWrap) { 2571 TextLayout layout = renderer.getTextLayout(lineIndex); 2572 int y = height - topLineY; 2573 for (int i = 0; i < layout.getLineCount(); i++) { 2574 Rectangle bounds = layout.getLineBounds(i); 2575 if (bounds.contains(bounds.x, y)) { 2576 height = topLineY + bounds.y + bounds.height; 2577 break; 2578 } 2579 } 2580 renderer.disposeTextLayout(layout); 2581 } else { 2582 height = topLineY + renderer.getLineHeight(lineIndex); 2583 } 2584 } 2585 int caretHeight = height; 2586 if (wordWrap) { 2587 TextLayout layout = renderer.getTextLayout(caretLine); 2588 int offsetInLine = caretOffset - content.getOffsetAtLine(caretLine); 2589 lineIndex = getVisualLineIndex(layout, offsetInLine); 2590 caretHeight += layout.getLineBounds(lineIndex).y; 2591 renderer.disposeTextLayout(layout); 2592 } 2593 lineIndex = caretLine; 2594 lineHeight = renderer.getLineHeight(lineIndex); 2595 while (caretHeight - lineHeight >= 0 && lineIndex < lineCount - 1) { 2596 caretHeight -= lineHeight; 2597 lineHeight = renderer.getLineHeight(++lineIndex); 2598 } 2599 caretOffset = getOffsetAtPoint(columnX, caretHeight, lineIndex); 2600 if (select) doSelection(ST.COLUMN_NEXT); 2601 height = getAvailableHeightBellow(height); 2602 scrollVertical(height, true); 2603 if (height == 0) setCaretLocation(); 2604 } 2605 showCaret(); 2606 int hScrollChange = oldHScrollOffset - horizontalScrollOffset; 2607 columnX = oldColumnX + hScrollChange; 2608} 2609 2612void doPageEnd() { 2613 if (isSingleLine()) { 2615 doLineEnd(); 2616 } else { 2617 int bottomOffset; 2618 if (wordWrap) { 2619 int lineIndex = getPartialBottomIndex(); 2620 TextLayout layout = renderer.getTextLayout(lineIndex); 2621 int y = (clientAreaHeight - bottomMargin) - getLinePixel(lineIndex); 2622 int index = layout.getLineCount() - 1; 2623 while (index >= 0) { 2624 Rectangle bounds = layout.getLineBounds(index); 2625 if (y >= bounds.y + bounds.height) break; 2626 index--; 2627 } 2628 if (index == -1 && lineIndex > 0) { 2629 bottomOffset = content.getOffsetAtLine(lineIndex - 1) + content.getLine(lineIndex - 1).length(); 2630 } else { 2631 bottomOffset = content.getOffsetAtLine(lineIndex) + Math.max(0, layout.getLineOffsets()[index + 1] - 1); 2632 } 2633 renderer.disposeTextLayout(layout); 2634 } else { 2635 int lineIndex = getBottomIndex(); 2636 bottomOffset = content.getOffsetAtLine(lineIndex) + content.getLine(lineIndex).length(); 2637 } 2638 if (caretOffset < bottomOffset) { 2639 caretOffset = bottomOffset; 2640 caretAlignment = OFFSET_LEADING; 2641 showCaret(); 2642 } 2643 } 2644} 2645 2648void doPageStart() { 2649 int topOffset; 2650 if (wordWrap) { 2651 int y, lineIndex; 2652 if (topIndexY > 0) { 2653 lineIndex = topIndex - 1; 2654 y = renderer.getLineHeight(lineIndex) - topIndexY; 2655 } else { 2656 lineIndex = topIndex; 2657 y = -topIndexY; 2658 } 2659 TextLayout layout = renderer.getTextLayout(lineIndex); 2660 int index = 0; 2661 int lineCount = layout.getLineCount(); 2662 while (index < lineCount) { 2663 Rectangle bounds = layout.getLineBounds(index); 2664 if (y <= bounds.y) break; 2665 index++; 2666 } 2667 if (index == lineCount) { 2668 topOffset = content.getOffsetAtLine(lineIndex + 1); 2669 } else { 2670 topOffset = content.getOffsetAtLine(lineIndex) + layout.getLineOffsets()[index]; 2671 } 2672 renderer.disposeTextLayout(layout); 2673 } else { 2674 topOffset = content.getOffsetAtLine(topIndex); 2675 } 2676 if (caretOffset > topOffset) { 2677 caretOffset = topOffset; 2678 caretAlignment = OFFSET_LEADING; 2679 showCaret(); 2680 } 2681} 2682 2690void doPageUp(boolean select, int height) { 2691 if (isSingleLine()) return; 2692 int oldHScrollOffset = horizontalScrollOffset; 2693 int oldColumnX = columnX; 2694 if (isFixedLineHeight()) { 2695 int caretLine = getCaretLine(); 2696 if (caretLine > 0) { 2697 int lineHeight = renderer.getLineHeight(); 2698 int lines = (height == -1 ? clientAreaHeight : height) / lineHeight; 2699 int scrollLines = Math.max(1, Math.min(caretLine, lines)); 2700 caretLine -= scrollLines; 2701 caretOffset = getOffsetAtPoint(columnX, getLinePixel(caretLine)); 2702 if (select) { 2703 doSelection(ST.COLUMN_PREVIOUS); 2704 } 2705 int verticalScrollOffset = getVerticalScrollOffset(); 2706 int scrollOffset = Math.max(0, verticalScrollOffset - scrollLines * getVerticalIncrement()); 2707 if (scrollOffset < verticalScrollOffset) { 2708 scrollVertical(scrollOffset - verticalScrollOffset, true); 2709 } 2710 } 2711 } else { 2712 int caretLine = getCaretLine(); 2713 int lineHeight, lineIndex; 2714 if (height == -1) { 2715 if (topIndexY == 0) { 2716 height = clientAreaHeight; 2717 } else { 2718 int y; 2719 if (topIndex > 0) { 2720 lineIndex = topIndex - 1; 2721 lineHeight = renderer.getLineHeight(lineIndex); 2722 height = clientAreaHeight - topIndexY; 2723 y = lineHeight - topIndexY; 2724 } else { 2725 lineIndex = topIndex; 2726 lineHeight = renderer.getLineHeight(lineIndex); 2727 height = clientAreaHeight - (lineHeight + topIndexY); 2728 y = -topIndexY; 2729 } 2730 if (wordWrap) { 2731 TextLayout layout = renderer.getTextLayout(lineIndex); 2732 for (int i = 0; i < layout.getLineCount(); i++) { 2733 Rectangle bounds = layout.getLineBounds(i); 2734 if (bounds.contains(bounds.x, y)) { 2735 height += lineHeight - (bounds.y + bounds.height); 2736 break; 2737 } 2738 } 2739 renderer.disposeTextLayout(layout); 2740 } 2741 } 2742 } else { 2743 lineIndex = getLineIndex(clientAreaHeight - height); 2744 int topLineY = getLinePixel(lineIndex); 2745 if (wordWrap) { 2746 TextLayout layout = renderer.getTextLayout(lineIndex); 2747 int y = topLineY; 2748 for (int i = 0; i < layout.getLineCount(); i++) { 2749 Rectangle bounds = layout.getLineBounds(i); 2750 if (bounds.contains(bounds.x, y)) { 2751 height = clientAreaHeight - (topLineY + bounds.y); 2752 break; 2753 } 2754 } 2755 renderer.disposeTextLayout(layout); 2756 } else { 2757 height = clientAreaHeight - topLineY; 2758 } 2759 } 2760 int caretHeight = height; 2761 if (wordWrap) { 2762 TextLayout layout = renderer.getTextLayout(caretLine); 2763 int offsetInLine = caretOffset - content.getOffsetAtLine(caretLine); 2764 lineIndex = getVisualLineIndex(layout, offsetInLine); 2765 caretHeight += layout.getBounds().height - layout.getLineBounds(lineIndex).y; 2766 renderer.disposeTextLayout(layout); 2767 } 2768 lineIndex = caretLine; 2769 lineHeight = renderer.getLineHeight(lineIndex); 2770 while (caretHeight - lineHeight >= 0 && lineIndex > 0) { 2771 caretHeight -= lineHeight; 2772 lineHeight = renderer.getLineHeight(--lineIndex); 2773 } 2774 lineHeight = renderer.getLineHeight(lineIndex); 2775 caretOffset = getOffsetAtPoint(columnX, lineHeight - caretHeight, lineIndex); 2776 if (select) doSelection(ST.COLUMN_PREVIOUS); 2777 height = getAvailableHeightAbove(height); 2778 scrollVertical(-height, true); 2779 if (height == 0) setCaretLocation(); 2780 } 2781 showCaret(); 2782 int hScrollChange = oldHScrollOffset - horizontalScrollOffset; 2783 columnX = oldColumnX + hScrollChange; 2784} 2785 2788void doSelection(int direction) { 2789 int redrawStart = -1; 2790 int redrawEnd = -1; 2791 if (selectionAnchor == -1) { 2792 selectionAnchor = selection.x; 2793 } 2794 if (direction == ST.COLUMN_PREVIOUS) { 2795 if (caretOffset < selection.x) { 2796 redrawEnd = selection.x; 2798 redrawStart = selection.x = caretOffset; 2799 if (selection.y != selectionAnchor) { 2801 redrawEnd = selection.y; 2802 selection.y = selectionAnchor; 2803 } 2804 } else if (selectionAnchor == selection.x && caretOffset < selection.y) { 2806 redrawEnd = selection.y; 2809 redrawStart = selection.y = caretOffset; 2810 } 2811 } else { 2812 if (caretOffset > selection.y) { 2813 redrawStart = selection.y; 2815 redrawEnd = selection.y = caretOffset; 2816 if (selection.x != selectionAnchor) { 2818 redrawStart = selection.x; 2819 selection.x = selectionAnchor; 2820 } 2821 } else if (selectionAnchor == selection.y && caretOffset > selection.x) { 2823 redrawStart = selection.x; 2826 redrawEnd = selection.x = caretOffset; 2827 } 2828 } 2829 if (redrawStart != -1 && redrawEnd != -1) { 2830 internalRedrawRange(redrawStart, redrawEnd - redrawStart); 2831 sendSelectionEvent(); 2832 } 2833} 2834 2838void doSelectionCursorNext() { 2839 int caretLine = getCaretLine(); 2840 int lineOffset = content.getOffsetAtLine(caretLine); 2841 int offsetInLine = caretOffset - lineOffset; 2842 if (offsetInLine < content.getLine(caretLine).length()) { 2843 TextLayout layout = renderer.getTextLayout(caretLine); 2844 offsetInLine = layout.getNextOffset(offsetInLine, SWT.MOVEMENT_CLUSTER); 2845 int lineStart = layout.getLineOffsets()[layout.getLineIndex(offsetInLine)]; 2846 renderer.disposeTextLayout(layout); 2847 caretOffset = offsetInLine + lineOffset; 2848 caretAlignment = offsetInLine == lineStart ? OFFSET_LEADING : PREVIOUS_OFFSET_TRAILING; 2849 showCaret(); 2850 } else if (caretLine < content.getLineCount() - 1 && !isSingleLine()) { 2851 caretLine++; 2852 caretOffset = content.getOffsetAtLine(caretLine); 2853 caretAlignment = PREVIOUS_OFFSET_TRAILING; 2854 showCaret(); 2855 } 2856} 2857 2861void doSelectionCursorPrevious() { 2862 int caretLine = getCaretLine(); 2863 int lineOffset = content.getOffsetAtLine(caretLine); 2864 int offsetInLine = caretOffset - lineOffset; 2865 caretAlignment = OFFSET_LEADING; 2866 if (offsetInLine > 0) { 2867 caretOffset = getClusterPrevious(caretOffset, caretLine); 2868 showCaret(); 2869 } else if (caretLine > 0) { 2870 caretLine--; 2871 lineOffset = content.getOffsetAtLine(caretLine); 2872 caretOffset = lineOffset + content.getLine(caretLine).length(); 2873 showCaret(); 2874 } 2875} 2876 2886void doSelectionLineDown() { 2887 int oldColumnX = columnX = getPointAtOffset(caretOffset).x; 2888 doLineDown(true); 2889 columnX = oldColumnX; 2890} 2891 2901void doSelectionLineUp() { 2902 int oldColumnX = columnX = getPointAtOffset(caretOffset).x; 2903 doLineUp(true); 2904 columnX = oldColumnX; 2905} 2906 2920void doSelectionPageDown(int pixels) { 2921 int oldColumnX = columnX = getPointAtOffset(caretOffset).x; 2922 doPageDown(true, pixels); 2923 columnX = oldColumnX; 2924} 2925 2939void doSelectionPageUp(int pixels) { 2940 int oldColumnX = columnX = getPointAtOffset(caretOffset).x; 2941 doPageUp(true, pixels); 2942 columnX = oldColumnX; 2943} 2944 2947void doSelectionWordNext() { 2948 int newCaretOffset = getWordNext(caretOffset, SWT.MOVEMENT_WORD); 2949 caretAlignment = OFFSET_LEADING; 2951 if (!isSingleLine() || 2954 content.getLineAtOffset(caretOffset) == content.getLineAtOffset(newCaretOffset)) { 2955 caretOffset = newCaretOffset; 2956 showCaret(); 2957 } 2958} 2959 2962void doSelectionWordPrevious() { 2963 caretAlignment = OFFSET_LEADING; 2964 caretOffset = getWordPrevious(caretOffset, SWT.MOVEMENT_WORD); 2965 int caretLine = content.getLineAtOffset(caretOffset); 2966 if (wordWrap && caretLine < content.getLineCount() - 1 && 2969 caretOffset == content.getOffsetAtLine(caretLine + 1)) { 2970 caretLine++; 2971 } 2972 showCaret(); 2973} 2974 2980void doVisualPrevious() { 2981 caretOffset = getClusterPrevious(caretOffset, getCaretLine()); 2982 showCaret(); 2983} 2984 2990void doVisualNext() { 2991 caretOffset = getClusterNext(caretOffset, getCaretLine()); 2992 showCaret(); 2993} 2994 2999void doWordNext() { 3000 if (selection.y - selection.x > 0) { 3001 caretOffset = selection.y; 3002 showCaret(); 3003 } else { 3004 doSelectionWordNext(); 3005 } 3006} 3007 3012void doWordPrevious() { 3013 if (selection.y - selection.x > 0) { 3014 caretOffset = selection.x; 3015 showCaret(); 3016 } else { 3017 doSelectionWordPrevious(); 3018 } 3019} 3020 3023void endAutoScroll() { 3024 autoScrollDirection = SWT.NULL; 3025} 3026public Color getBackground() { 3027 checkWidget(); 3028 if (background == null) { 3029 return getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); 3030 } 3031 return background; 3032} 3033 3048public int getBaseline() { 3049 checkWidget(); 3050 return renderer.getBaseline(); 3051} 3052 3069public int getBaseline(int offset) { 3070 checkWidget(); 3071 if (!(0 <= offset && offset <= content.getCharCount())) { 3072 SWT.error(SWT.ERROR_INVALID_RANGE); 3073 } 3074 if (isFixedLineHeight()) { 3075 return renderer.getBaseline(); 3076 } 3077 int lineIndex = content.getLineAtOffset(offset); 3078 int lineOffset = content.getOffsetAtLine(lineIndex); 3079 TextLayout layout = renderer.getTextLayout(lineIndex); 3080 int lineInParagraph = layout.getLineIndex(Math.min(offset - lineOffset, layout.getText().length())); 3081 FontMetrics metrics = layout.getLineMetrics(lineInParagraph); 3082 renderer.disposeTextLayout(layout); 3083 return metrics.getAscent() + metrics.getLeading(); 3084} 3085 3098public boolean getBidiColoring() { 3099 checkWidget(); 3100 return bidiColoring; 3101} 3102 3107int getBottomIndex() { 3108 int bottomIndex; 3109 if (isFixedLineHeight()) { 3110 int lineCount = 1; 3111 int lineHeight = renderer.getLineHeight(); 3112 if (lineHeight != 0) { 3113 int partialTopLineHeight = topIndex * lineHeight - getVerticalScrollOffset(); 3115 lineCount = (clientAreaHeight - partialTopLineHeight) / lineHeight; 3116 } 3117 bottomIndex = Math.min(content.getLineCount() - 1, topIndex + Math.max(0, lineCount - 1)); 3118 } else { 3119 int clientAreaHeight = this.clientAreaHeight - bottomMargin; 3120 bottomIndex = getLineIndex(clientAreaHeight); 3121 if (bottomIndex > 0) { 3122 int linePixel = getLinePixel(bottomIndex); 3123 int lineHeight = renderer.getLineHeight(bottomIndex); 3124 if (linePixel + lineHeight > clientAreaHeight) { 3125 if (getLinePixel(bottomIndex - 1) >= topMargin) { 3126 bottomIndex--; 3127 } 3128 } 3129 } 3130 } 3131 return bottomIndex; 3132} 3133Rectangle getBoundsAtOffset(int offset) { 3134 int lineIndex = content.getLineAtOffset(offset); 3135 String line = content.getLine(lineIndex); 3136 Rectangle bounds; 3137 if (line.length() != 0) { 3138 int offsetInLine = offset - content.getOffsetAtLine(lineIndex); 3139 TextLayout layout = renderer.getTextLayout(lineIndex); 3140 bounds = layout.getBounds(offsetInLine, offsetInLine); 3141 renderer.disposeTextLayout(layout); 3142 } else { 3143 bounds = new Rectangle (0, 0, 0, renderer.getLineHeight()); 3144 } 3145 bounds.x += leftMargin - horizontalScrollOffset; 3146 bounds.y += getLinePixel(lineIndex); 3147 return bounds; 3148} 3149 3150 3159public int getCaretOffset() { 3160 checkWidget(); 3161 return caretOffset; 3162} 3163 3168int getCaretWidth() { 3169 Caret caret = getCaret(); 3170 if (caret == null) return 0; 3171 return caret.getSize().x; 3172} 3173Object getClipboardContent(int clipboardType) { 3174 TextTransfer plainTextTransfer = TextTransfer.getInstance(); 3175 return clipboard.getContents(plainTextTransfer, clipboardType); 3176} 3177int getClusterNext(int offset, int lineIndex) { 3178 int lineOffset = content.getOffsetAtLine(lineIndex); 3179 TextLayout layout = renderer.getTextLayout(lineIndex); 3180 offset -= lineOffset; 3181 offset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER); 3182 offset += lineOffset; 3183 renderer.disposeTextLayout(layout); 3184 return offset; 3185} 3186int getClusterPrevious(int offset, int lineIndex) { 3187 int lineOffset = content.getOffsetAtLine(lineIndex); 3188 TextLayout layout = renderer.getTextLayout(lineIndex); 3189 offset -= lineOffset; 3190 offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_CLUSTER); 3191 offset += lineOffset; 3192 renderer.disposeTextLayout(layout); 3193 return offset; 3194} 3195 3206public StyledTextContent getContent() { 3207 checkWidget(); 3208 return content; 3209} 3210public boolean getDragDetect () { 3211 checkWidget (); 3212 return dragDetect; 3213} 3214 3224public boolean getDoubleClickEnabled() { 3225 checkWidget(); 3226 return doubleClickEnabled; 3227} 3228 3237public boolean getEditable() { 3238 checkWidget(); 3239 return editable; 3240} 3241public Color getForeground() { 3242 checkWidget(); 3243 if (foreground == null) { 3244 return getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND); 3245 } 3246 return foreground; 3247} 3248 3253int getHorizontalIncrement() { 3254 return renderer.averageCharWidth; 3255} 3256 3266public int getHorizontalIndex() { 3267 checkWidget(); 3268 return horizontalScrollOffset / getHorizontalIncrement(); 3269} 3270 3280public int getHorizontalPixel() { 3281 checkWidget(); 3282 return horizontalScrollOffset; 3283} 3284 3298public int getIndent() { 3299 checkWidget(); 3300 return indent; 3301} 3302 3316public boolean getJustify() { 3317 checkWidget(); 3318 return justify; 3319} 3320 3336public int getKeyBinding(int key) { 3337 checkWidget(); 3338 Integer action = (Integer ) keyActionMap.get(new Integer (key)); 3339 return action == null ? SWT.NULL : action.intValue(); 3340} 3341 3350public int getCharCount() { 3351 checkWidget(); 3352 return content.getCharCount(); 3353} 3354 3373public int getLineAlignment(int index) { 3374 checkWidget(); 3375 if (index < 0 || index > content.getLineCount()) { 3376 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3377 } 3378 return renderer.getLineAlignment(index, alignment); 3379} 3380 3396public int getLineAtOffset(int offset) { 3397 checkWidget(); 3398 if (offset < 0 || offset > getCharCount()) { 3399 SWT.error(SWT.ERROR_INVALID_RANGE); 3400 } 3401 return content.getLineAtOffset(offset); 3402} 3403 3421public Color getLineBackground(int index) { 3422 checkWidget(); 3423 if (index < 0 || index > content.getLineCount()) { 3424 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3425 } 3426 return isListening(LineGetBackground) ? null : renderer.getLineBackground(index, null); 3427} 3428 3445public Bullet getLineBullet(int index) { 3446 checkWidget(); 3447 if (index < 0 || index > content.getLineCount()) { 3448 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3449 } 3450 return isListening(LineGetStyle) ? null : renderer.getLineBullet(index, null); 3451} 3452 3461StyledTextEvent getLineBackgroundData(int lineOffset, String line) { 3462 return sendLineEvent(LineGetBackground, lineOffset, line); 3463} 3464 3473public int getLineCount() { 3474 checkWidget(); 3475 return content.getLineCount(); 3476} 3477 3484int getLineCountWhole() { 3485 if (isFixedLineHeight()) { 3486 int lineHeight = renderer.getLineHeight(); 3487 return lineHeight != 0 ? clientAreaHeight / lineHeight : 1; 3488 } 3489 return getBottomIndex() - topIndex + 1; 3490} 3491 3502public String getLineDelimiter() { 3503 checkWidget(); 3504 return content.getLineDelimiter(); 3505} 3506 3520public int getLineHeight() { 3521 checkWidget(); 3522 return renderer.getLineHeight(); 3523} 3524 3541public int getLineHeight(int offset) { 3542 checkWidget(); 3543 if (!(0 <= offset && offset <= content.getCharCount())) { 3544 SWT.error(SWT.ERROR_INVALID_RANGE); 3545 } 3546 if (isFixedLineHeight()) { 3547 return renderer.getLineHeight(); 3548 } 3549 int lineIndex = content.getLineAtOffset(offset); 3550 int lineOffset = content.getOffsetAtLine(lineIndex); 3551 TextLayout layout = renderer.getTextLayout(lineIndex); 3552 int lineInParagraph = layout.getLineIndex(Math.min(offset - lineOffset, layout.getText().length())); 3553 int height = layout.getLineBounds(lineInParagraph).height; 3554 renderer.disposeTextLayout(layout); 3555 return height; 3556} 3557 3576public int getLineIndent(int index) { 3577 checkWidget(); 3578 if (index < 0 || index > content.getLineCount()) { 3579 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3580 } 3581 return isListening(LineGetStyle) ? 0 : renderer.getLineIndent(index, indent); 3582} 3583 3602public boolean getLineJustify(int index) { 3603 checkWidget(); 3604 if (index < 0 || index > content.getLineCount()) { 3605 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3606 } 3607 return isListening(LineGetStyle) ? false : renderer.getLineJustify(index, justify); 3608} 3609 3621public int getLineSpacing() { 3622 checkWidget(); 3623 return lineSpacing; 3624} 3625 3640StyledTextEvent getLineStyleData(int lineOffset, String line) { 3641 return sendLineEvent(LineGetStyle, lineOffset, line); 3642} 3643 3653public int getLinePixel(int lineIndex) { 3654 checkWidget(); 3655 int lineCount = content.getLineCount(); 3656 lineIndex = Math.max(0, Math.min(lineCount, lineIndex)); 3657 if (isFixedLineHeight()) { 3658 int lineHeight = renderer.getLineHeight(); 3659 return lineIndex * lineHeight - getVerticalScrollOffset() + topMargin; 3660 } 3661 if (lineIndex == topIndex) return topIndexY + topMargin; 3662 int height = topIndexY; 3663 if (lineIndex > topIndex) { 3664 for (int i = topIndex; i < lineIndex; i++) { 3665 height += renderer.getLineHeight(i); 3666 } 3667 } else { 3668 for (int i = topIndex - 1; i >= lineIndex; i--) { 3669 height -= renderer.getLineHeight(i); 3670 } 3671 } 3672 return height + topMargin; 3673} 3674 3680public int getLineIndex(int y) { 3681 checkWidget(); 3682 y -= topMargin; 3683 if (isFixedLineHeight()) { 3684 int lineHeight = renderer.getLineHeight(); 3685 int lineIndex = (y + getVerticalScrollOffset()) / lineHeight; 3686 int lineCount = content.getLineCount(); 3687 lineIndex = Math.max(0, Math.min(lineCount - 1, lineIndex)); 3688 return lineIndex; 3689 } 3690 if (y == topIndexY) return topIndex; 3691 int line = topIndex; 3692 if (y < topIndexY) { 3693 while (y < topIndexY && line > 0) { 3694 y += renderer.getLineHeight(--line); 3695 } 3696 } else { 3697 int lineCount = content.getLineCount(); 3698 int lineHeight = renderer.getLineHeight(line); 3699 while (y - lineHeight >= topIndexY && line < lineCount - 1) { 3700 y -= lineHeight; 3701 lineHeight = renderer.getLineHeight(++line); 3702 } 3703 } 3704 return line; 3705} 3706 3723public Point getLocationAtOffset(int offset) { 3724 checkWidget(); 3725 if (offset < 0 || offset > getCharCount()) { 3726 SWT.error(SWT.ERROR_INVALID_RANGE); 3727 } 3728 return getPointAtOffset(offset); 3729} 3730 3750public int getOffsetAtLine(int lineIndex) { 3751 checkWidget(); 3752 if (lineIndex < 0 || 3753 (lineIndex > 0 && lineIndex >= content.getLineCount())) { 3754 SWT.error(SWT.ERROR_INVALID_RANGE); 3755 } 3756 return content.getOffsetAtLine(lineIndex); 3757} 3758 3781public int getOffsetAtLocation(Point point) { 3782 checkWidget(); 3783 if (point == null) { 3784 SWT.error(SWT.ERROR_NULL_ARGUMENT); 3785 } 3786 if (point.y + getVerticalScrollOffset() < 0 || point.x + horizontalScrollOffset < 0) { 3788 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3789 } 3790 int bottomIndex = getLineIndex(clientAreaHeight); 3791 int height = getLinePixel(bottomIndex) + renderer.getLineHeight(bottomIndex); 3792 if (point.y > height) { 3793 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3794 } 3795 int lineIndex = getLineIndex(point.y); 3796 int lineOffset = content.getOffsetAtLine(lineIndex); 3797 TextLayout layout = renderer.getTextLayout(lineIndex); 3798 int[] trailing = new int[1]; 3799 int x = point.x + horizontalScrollOffset - leftMargin ; 3800 int y = point.y - getLinePixel(lineIndex); 3801 int offsetInLine = layout.getOffset(x, y, trailing); 3802 String line = content.getLine(lineIndex); 3803 if (offsetInLine != line.length() - 1) { 3804 offsetInLine = Math.min(line.length(), offsetInLine + trailing[0]); 3805 } 3806 Rectangle rect = layout.getLineBounds(layout.getLineIndex(offsetInLine)); 3807 renderer.disposeTextLayout(layout); 3808 if (x > rect.x + rect.width) { 3809 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3810 } 3811 return lineOffset + offsetInLine; 3812} 3813int getOffsetAtPoint(int x, int y) { 3814 int lineIndex = getLineIndex(y); 3815 y -= getLinePixel(lineIndex); 3816 return getOffsetAtPoint(x, y, lineIndex); 3817} 3818 3826int getOffsetAtPoint(int x, int y, int lineIndex) { 3827 TextLayout layout = renderer.getTextLayout(lineIndex); 3828 x += horizontalScrollOffset - leftMargin; 3829 int[] trailing = new int[1]; 3830 int offsetInLine = layout.getOffset(x, y, trailing); 3831 caretAlignment = OFFSET_LEADING; 3832 if (trailing[0] != 0) { 3833 int lineInParagraph = layout.getLineIndex(offsetInLine + trailing[0]); 3834 int lineStart = layout.getLineOffsets()[lineInParagraph]; 3836 if (offsetInLine + trailing[0] == lineStart) { 3837 offsetInLine += trailing[0]; 3838 caretAlignment = PREVIOUS_OFFSET_TRAILING; 3839 } else { 3840 String line = content.getLine(lineIndex); 3841 int level; 3842 int offset = offsetInLine; 3843 while (offset > 0 && Character.isDigit(line.charAt(offset))) offset--; 3844 if (offset == 0 && Character.isDigit(line.charAt(offset))) { 3845 level = isMirrored() ? 1 : 0; 3846 } else { 3847 level = layout.getLevel(offset) & 0x1; 3848 } 3849 offsetInLine += trailing[0]; 3850 int trailingLevel = layout.getLevel(offsetInLine) & 0x1; 3851 if ((level ^ trailingLevel) != 0) { 3852 caretAlignment = PREVIOUS_OFFSET_TRAILING; 3853 } else { 3854 caretAlignment = OFFSET_LEADING; 3855 } 3856 } 3857 } 3858 renderer.disposeTextLayout(layout); 3859 return offsetInLine + content.getOffsetAtLine(lineIndex); 3860} 3861 3873public int getOrientation () { 3874 checkWidget(); 3875 return isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT; 3876} 3877 3882int getPartialBottomIndex() { 3883 if (isFixedLineHeight()) { 3884 int lineHeight = renderer.getLineHeight(); 3885 int partialLineCount = Compatibility.ceil(clientAreaHeight, lineHeight); 3886 return Math.min(content.getLineCount(), topIndex + partialLineCount) - 1; 3887 } 3888 return getLineIndex(clientAreaHeight - bottomMargin); 3889} 3890 3895int getPartialTopIndex() { 3896 if (isFixedLineHeight()) { 3897 int lineHeight = renderer.getLineHeight(); 3898 return getVerticalScrollOffset() / lineHeight; 3899 } 3900 return topIndexY <= 0 ? topIndex : topIndex - 1; 3901} 3902 3910String getPlatformDelimitedText(TextWriter writer) { 3911 int end = writer.getStart() + writer.getCharCount(); 3912 int startLine = content.getLineAtOffset(writer.getStart()); 3913 int endLine = content.getLineAtOffset(end); 3914 String endLineText = content.getLine(endLine); 3915 int endLineOffset = content.getOffsetAtLine(endLine); 3916 3917 for (int i = startLine; i <= endLine; i++) { 3918 writer.writeLine(content.getLine(i), content.getOffsetAtLine(i)); 3919 if (i < endLine) { 3920 writer.writeLineDelimiter(PlatformLineDelimiter); 3921 } 3922 } 3923 if (end > endLineOffset + endLineText.length()) { 3924 writer.writeLineDelimiter(PlatformLineDelimiter); 3925 } 3926 writer.close(); 3927 return writer.toString(); 3928} 3929 3952public int[] getRanges() { 3953 checkWidget(); 3954 if (!isListening(LineGetStyle)) { 3955 int[] ranges = renderer.getRanges(0, content.getCharCount()); 3956 if (ranges != null) return ranges; 3957 } 3958 return new int[0]; 3959} 3960 3989public int[] getRanges(int start, int length) { 3990 checkWidget(); 3991 int contentLength = getCharCount(); 3992 int end = start + length; 3993 if (start > end || start < 0 || end > contentLength) { 3994 SWT.error(SWT.ERROR_INVALID_RANGE); 3995 } 3996 if (!isListening(LineGetStyle)) { 3997 int[] ranges = renderer.getRanges(start, length); 3998 if (ranges != null) return ranges; 3999 } 4000 return new int[0]; 4001} 4002 4022public Point getSelection() { 4023 checkWidget(); 4024 return new Point(selection.x, selection.y); 4025} 4026 4041public Point getSelectionRange() { 4042 checkWidget(); 4043 return new Point(selection.x, selection.y - selection.x); 4044} 4045 4056public Color getSelectionBackground() { 4057 checkWidget(); 4058 if (selectionBackground == null) { 4059 return getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION); 4060 } 4061 return selectionBackground; 4062} 4063 4072public int getSelectionCount() { 4073 checkWidget(); 4074 return getSelectionRange().y; 4075} 4076 4087public Color getSelectionForeground() { 4088 checkWidget(); 4089 if (selectionForeground == null) { 4090 return getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); 4091 } 4092 return selectionForeground; 4093} 4094 4103public String getSelectionText() { 4104 checkWidget(); 4105 return content.getTextRange(selection.x, selection.y - selection.x); 4106} 4107public int getStyle() { 4108 int style = super.getStyle(); 4109 style &= ~(SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.MIRRORED); 4110 if (isMirrored()) { 4111 style |= SWT.RIGHT_TO_LEFT | SWT.MIRRORED; 4112 } else { 4113 style |= SWT.LEFT_TO_RIGHT; 4114 } 4115 return style; 4116} 4117 4118 4135int [] getBidiSegments(int lineOffset, String line) { 4136 if (!isBidi()) return null; 4137 if (!isListening(LineGetSegments)) { 4138 return getBidiSegmentsCompatibility(line, lineOffset); 4139 } 4140 StyledTextEvent event = sendLineEvent(LineGetSegments, lineOffset, line); 4141 int lineLength = line.length(); 4142 int[] segments; 4143 if (event == null || event.segments == null || event.segments.length == 0) { 4144 segments = new int[] {0, lineLength}; 4145 } else { 4146 int segmentCount = event.segments.length; 4147 4148 if (event.segments[0] != 0) { 4150 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 4151 } 4152 for (int i = 1; i < segmentCount; i++) { 4153 if (event.segments[i] <= event.segments[i - 1] || event.segments[i] > lineLength) { 4154 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 4155 } 4156 } 4157 if (event.segments[segmentCount - 1] != lineLength) { 4159 segments = new int[segmentCount + 1]; 4160 System.arraycopy(event.segments, 0, segments, 0, segmentCount); 4161 segments[segmentCount] = lineLength; 4162 } else { 4163 segments = event.segments; 4164 } 4165 } 4166 return segments; 4167} 4168 4172int [] getBidiSegmentsCompatibility(String line, int lineOffset) { 4173 int lineLength = line.length(); 4174 if (!bidiColoring) { 4175 return new int[] {0, lineLength}; 4176 } 4177 StyleRange [] styles = null; 4178 StyledTextEvent event = getLineStyleData(lineOffset, line); 4179 if (event != null) { 4180 styles = event.styles; 4181 } else { 4182 styles = renderer.getStyleRanges(lineOffset, lineLength, true); 4183 } 4184 if (styles == null || styles.length == 0) { 4185 return new int[] {0, lineLength}; 4186 } 4187 int k=0, count = 1; 4188 while (k < styles.length && styles[k].start == 0 && styles[k].length == lineLength) { 4189 k++; 4190 } 4191 int[] offsets = new int[(styles.length - k) * 2 + 2]; 4192 for (int i = k; i < styles.length; i++) { 4193 StyleRange style = styles[i]; 4194 int styleLineStart = Math.max(style.start - lineOffset, 0); 4195 int styleLineEnd = Math.max(style.start + style.length - lineOffset, styleLineStart); 4196 styleLineEnd = Math.min (styleLineEnd, line.length ()); 4197 if (i > 0 && count > 1 && 4198 ((styleLineStart >= offsets[count-2] && styleLineStart <= offsets[count-1]) || 4199 (styleLineEnd >= offsets[count-2] && styleLineEnd <= offsets[count-1])) && 4200 style.similarTo(styles[i-1])) { 4201 offsets[count-2] = Math.min(offsets[count-2], styleLineStart); 4202 offsets[count-1] = Math.max(offsets[count-1], styleLineEnd); 4203 } else { 4204 if (styleLineStart > offsets[count - 1]) { 4205 offsets[count] = styleLineStart; 4206 count++; 4207 } 4208 offsets[count] = styleLineEnd; 4209 count++; 4210 } 4211 } 4212 if (lineLength > offsets[count-1]) { 4214 offsets [count] = lineLength; 4215 count++; 4216 } 4217 if (count == offsets.length) { 4218 return offsets; 4219 } 4220 int [] result = new int [count]; 4221 System.arraycopy (offsets, 0, result, 0, count); 4222 return result; 4223} 4224 4246public StyleRange getStyleRangeAtOffset(int offset) { 4247 checkWidget(); 4248 if (offset < 0 || offset >= getCharCount()) { 4249 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 4250 } 4251 if (!isListening(LineGetStyle)) { 4252 StyleRange[] ranges = renderer.getStyleRanges(offset, 1, true); 4253 if (ranges != null) return ranges[0]; 4254 } 4255 return null; 4256} 4257 4280public StyleRange[] getStyleRanges() { 4281 checkWidget(); 4282 return getStyleRanges(0, content.getCharCount(), true); 4283} 4284 4312public StyleRange[] getStyleRanges(boolean includeRanges) { 4313 checkWidget(); 4314 return getStyleRanges(0, content.getCharCount(), includeRanges); 4315} 4316 4350public StyleRange[] getStyleRanges(int start, int length) { 4351 checkWidget(); 4352 return getStyleRanges(start, length, true); 4353} 4354 4391public StyleRange[] getStyleRanges(int start, int length, boolean includeRanges) { 4392 checkWidget(); 4393 int contentLength = getCharCount(); 4394 int end = start + length; 4395 if (start > end || start < 0 || end > contentLength) { 4396 SWT.error(SWT.ERROR_INVALID_RANGE); 4397 } 4398 if (!isListening(LineGetStyle)) { 4399 StyleRange[] ranges = renderer.getStyleRanges(start, length, includeRanges); 4400 if (ranges != null) return ranges; 4401 } 4402 return new StyleRange[0]; 4403} 4404 4413public int getTabs() { 4414 checkWidget(); 4415 return tabLength; 4416} 4417 4426public String getText() { 4427 checkWidget(); 4428 return content.getTextRange(0, getCharCount()); 4429} 4430 4445public String getText(int start, int end) { 4446 checkWidget(); 4447 int contentLength = getCharCount(); 4448 if (start < 0 || start >= contentLength || end < 0 || end >= contentLength || start > end) { 4449 SWT.error(SWT.ERROR_INVALID_RANGE); 4450 } 4451 return content.getTextRange(start, end - start + 1); 4452} 4453 4468public Rectangle getTextBounds(int start, int end) { 4469 checkWidget(); 4470 int contentLength = getCharCount(); 4471 if (start < 0 || start >= contentLength || end < 0 || end >= contentLength || start > end) { 4472 SWT.error(SWT.ERROR_INVALID_RANGE); 4473 } 4474 int lineStart = content.getLineAtOffset(start); 4475 int lineEnd = content.getLineAtOffset(end); 4476 Rectangle rect; 4477 int y = getLinePixel(lineStart); 4478 int height = 0; 4479 int left = 0x7fffffff, right = 0; 4480 for (int i = lineStart; i <= lineEnd; i++) { 4481 int lineOffset = content.getOffsetAtLine(i); 4482 TextLayout layout = renderer.getTextLayout(i); 4483 if (layout.getText().length() > 0) { 4484 if (i == lineStart && i == lineEnd) { 4485 rect = layout.getBounds(start - lineOffset, end - lineOffset); 4486 } else if (i == lineStart) { 4487 String line = content.getLine(i); 4488 rect = layout.getBounds(start - lineOffset, line.length()); 4489 } else if (i == lineEnd) { 4490 rect = layout.getBounds(0, end - lineOffset); 4491 } else { 4492 rect = layout.getBounds(); 4493 } 4494 left = Math.min(left, rect.x); 4495 right = Math.max(right, rect.x + rect.width); 4496 height += rect.height; 4497 } else { 4498 height += renderer.getLineHeight(); 4499 } 4500 renderer.disposeTextLayout(layout); 4501 } 4502 rect = new Rectangle (left, y, right-left, height); 4503 rect.x += leftMargin - horizontalScrollOffset; 4504 return rect; 4505} 4506 4520public String getTextRange(int start, int length) { 4521 checkWidget(); 4522 int contentLength = getCharCount(); 4523 int end = start + length; 4524 if (start > end || start < 0 || end > contentLength) { 4525 SWT.error(SWT.ERROR_INVALID_RANGE); 4526 } 4527 return content.getTextRange(start, length); 4528} 4529 4539public int getTextLimit() { 4540 checkWidget(); 4541 return textLimit; 4542} 4543 4557public int getTopIndex() { 4558 checkWidget(); 4559 return topIndex; 4560} 4561 4577public int getTopPixel() { 4578 checkWidget(); 4579 return getVerticalScrollOffset(); 4580} 4581 4586int getVerticalIncrement() { 4587 return renderer.getLineHeight(); 4588} 4589int getVerticalScrollOffset() { 4590 if (verticalScrollOffset == -1) { 4591 renderer.calculate(0, topIndex); 4592 int height = 0; 4593 for (int i = 0; i < topIndex; i++) { 4594 height += renderer.getLineHeight(i); 4595 } 4596 height -= topIndexY; 4597 verticalScrollOffset = height; 4598 } 4599 return verticalScrollOffset; 4600} 4601int getVisualLineIndex(TextLayout layout, int offsetInLine) { 4602 int lineIndex = layout.getLineIndex(offsetInLine); 4603 int[] offsets = layout.getLineOffsets(); 4604 if (lineIndex != 0 && offsetInLine == offsets[lineIndex]) { 4605 int lineY = layout.getLineBounds(lineIndex).y; 4606 int caretY = getCaret().getLocation().y - topMargin - getLinePixel(getCaretLine()); 4607 if (lineY > caretY) lineIndex--; 4608 } 4609 return lineIndex; 4610} 4611int getCaretDirection() { 4612 if (!isBidiCaret()) return SWT.DEFAULT; 4613 if (!updateCaretDirection && caretDirection != SWT.NULL) return caretDirection; 4614 updateCaretDirection = false; 4615 int caretLine = getCaretLine(); 4616 int lineOffset = content.getOffsetAtLine(caretLine); 4617 String line = content.getLine(caretLine); 4618 int offset = caretOffset - lineOffset; 4619 int lineLength = line.length(); 4620 if (lineLength == 0) return isMirrored() ? SWT.RIGHT : SWT.LEFT; 4621 if (caretAlignment == PREVIOUS_OFFSET_TRAILING && offset > 0) offset--; 4622 if (offset == lineLength && offset > 0) offset--; 4623 while (offset > 0 && Character.isDigit(line.charAt(offset))) offset--; 4624 if (offset == 0 && Character.isDigit(line.charAt(offset))) { 4625 return isMirrored() ? SWT.RIGHT : SWT.LEFT; 4626 } 4627 TextLayout layout = renderer.getTextLayout(caretLine); 4628 int level = layout.getLevel(offset); 4629 renderer.disposeTextLayout(layout); 4630 return ((level & 1) != 0) ? SWT.RIGHT : SWT.LEFT; 4631} 4632 4635int getCaretLine() { 4636 return content.getLineAtOffset(caretOffset); 4637} 4638int getWrapWidth () { 4639 if (wordWrap && !isSingleLine()) { 4640 int width = clientAreaWidth - leftMargin - rightMargin; 4641 return width > 0 ? width : 1; 4642 } 4643 return -1; 4644} 4645int getWordNext (int offset, int movement) { 4646 int newOffset, lineOffset; 4647 String lineText; 4648 if (offset >= getCharCount()) { 4649 newOffset = offset; 4650 int lineIndex = content.getLineCount() - 1; 4651 lineOffset = content.getOffsetAtLine(lineIndex); 4652 lineText = content.getLine(lineIndex); 4653 } else { 4654 int lineIndex = content.getLineAtOffset(offset); 4655 lineOffset = content.getOffsetAtLine(lineIndex); 4656 lineText = content.getLine(lineIndex); 4657 int lineLength = lineText.length(); 4658 if (offset == lineOffset + lineLength) { 4659 newOffset = content.getOffsetAtLine(lineIndex + 1); 4660 } else { 4661 TextLayout layout = renderer.getTextLayout(lineIndex); 4662 newOffset = lineOffset + layout.getNextOffset(offset - lineOffset, movement); 4663 renderer.disposeTextLayout(layout); 4664 } 4665 } 4666 return sendWordBoundaryEvent(WordNext, movement, offset, newOffset, lineText, lineOffset); 4667} 4668int getWordPrevious(int offset, int movement) { 4669 int newOffset, lineOffset; 4670 String lineText; 4671 if (offset <= 0) { 4672 newOffset = 0; 4673 int lineIndex = content.getLineAtOffset(newOffset); 4674 lineOffset = content.getOffsetAtLine(lineIndex); 4675 lineText = content.getLine(lineIndex); 4676 } else { 4677 int lineIndex = content.getLineAtOffset(offset); 4678 lineOffset = content.getOffsetAtLine(lineIndex); 4679 lineText = content.getLine(lineIndex); 4680 if (offset == lineOffset) { 4681 String nextLineText = content.getLine(lineIndex - 1); 4682 int nextLineOffset = content.getOffsetAtLine(lineIndex - 1); 4683 newOffset = nextLineOffset + nextLineText.length(); 4684 } else { 4685 TextLayout layout = renderer.getTextLayout(lineIndex); 4686 newOffset = lineOffset + layout.getPreviousOffset(offset - lineOffset, movement); 4687 renderer.disposeTextLayout(layout); 4688 } 4689 } 4690 return sendWordBoundaryEvent(WordPrevious, movement, offset, newOffset, lineText, lineOffset); 4691} 4692 4698public boolean getWordWrap() { 4699 checkWidget(); 4700 return wordWrap; 4701} 4702 4710Point getPointAtOffset(int offset) { 4711 int lineIndex = content.getLineAtOffset(offset); 4712 String line = content.getLine(lineIndex); 4713 int lineOffset = content.getOffsetAtLine(lineIndex); 4714 int offsetInLine = offset - lineOffset; 4715 int lineLength = line.length(); 4716 if (lineIndex < content.getLineCount() - 1) { 4717 int endLineOffset = content.getOffsetAtLine(lineIndex + 1) - 1; 4718 if (lineLength < offsetInLine && offsetInLine <= endLineOffset) { 4719 offsetInLine = lineLength; 4720 } 4721 } 4722 Point point; 4723 TextLayout layout = renderer.getTextLayout(lineIndex); 4724 if (lineLength != 0 && offsetInLine <= lineLength) { 4725 if (offsetInLine == lineLength) { 4726 point = layout.getLocation(offsetInLine - 1, true); 4727 } else { 4728 switch (caretAlignment) { 4729 case OFFSET_LEADING: 4730 point = layout.getLocation(offsetInLine, false); 4731 break; 4732 case PREVIOUS_OFFSET_TRAILING: 4733 default: 4734 if (offsetInLine == 0) { 4735 point = layout.getLocation(offsetInLine, false); 4736 } else { 4737 point = layout.getLocation(offsetInLine - 1, true); 4738 } 4739 break; 4740 } 4741 } 4742 } else { 4743 point = new Point(layout.getIndent(), 0); 4744 } 4745 renderer.disposeTextLayout(layout); 4746 point.x += leftMargin - horizontalScrollOffset; 4747 point.y += getLinePixel(lineIndex); 4748 return point; 4749} 4750 4763public void insert(String string) { 4764 checkWidget(); 4765 if (string == null) { 4766 SWT.error(SWT.ERROR_NULL_ARGUMENT); 4767 } 4768 Point sel = getSelectionRange(); 4769 replaceTextRange(sel.x, sel.y, string); 4770} 4771 4774void installDefaultContent() { 4775 textChangeListener = new TextChangeListener() { 4776 public void textChanging(TextChangingEvent event) { 4777 handleTextChanging(event); 4778 } 4779 public void textChanged(TextChangedEvent event) { 4780 handleTextChanged(event); 4781 } 4782 public void textSet(TextChangedEvent event) { 4783 handleTextSet(event); 4784 } 4785 }; 4786 content = new DefaultContent(); 4787 content.addTextChangeListener(textChangeListener); 4788} 4789 4792void installListeners() { 4793 ScrollBar verticalBar = getVerticalBar(); 4794 ScrollBar horizontalBar = getHorizontalBar(); 4795 4796 listener = new Listener() { 4797 public void handleEvent(Event event) { 4798 switch (event.type) { 4799 case SWT.Dispose: handleDispose(event); break; 4800 case SWT.KeyDown: handleKeyDown(event); break; 4801 case SWT.KeyUp: handleKeyUp(event); break; 4802 case SWT.MouseDown: handleMouseDown(event); break; 4803 case SWT.MouseUp: handleMouseUp(event); break; 4804 case SWT.MouseMove: handleMouseMove(event); break; 4805 case SWT.Paint: handlePaint(event); break; 4806 case SWT.Resize: handleResize(event); break; 4807 case SWT.Traverse: handleTraverse(event); break; 4808 } 4809 } 4810 }; 4811 addListener(SWT.Dispose, listener); 4812 addListener(SWT.KeyDown, listener); 4813 addListener(SWT.KeyUp, listener); 4814 addListener(SWT.MouseDown, listener); 4815 addListener(SWT.MouseUp, listener); 4816 addListener(SWT.MouseMove, listener); 4817 addListener(SWT.Paint, listener); 4818 addListener(SWT.Resize, listener); 4819 addListener(SWT.Traverse, listener); 4820 if (verticalBar != null) { 4821 verticalBar.addListener(SWT.Selection, new Listener() { 4822 public void handleEvent(Event event) { 4823 handleVerticalScroll(event); 4824 } 4825 }); 4826 } 4827 if (horizontalBar != null) { 4828 horizontalBar.addListener(SWT.Selection, new Listener() { 4829 public void handleEvent(Event event) { 4830 handleHorizontalScroll(event); 4831 } 4832 }); 4833 } 4834} 4835void internalRedrawRange(int start, int length) { 4836 if (length <= 0) return; 4837 int end = start + length; 4838 int startLine = content.getLineAtOffset(start); 4839 int endLine = content.getLineAtOffset(end); 4840 int partialBottomIndex = getPartialBottomIndex(); 4841 int partialTopIndex = getPartialTopIndex(); 4842 if (startLine > partialBottomIndex || endLine < partialTopIndex) { 4843 return; 4844 } 4845 if (partialTopIndex > startLine) { 4846 startLine = partialTopIndex; 4847 start = 0; 4848 } else { 4849 start -= content.getOffsetAtLine(startLine); 4850 } 4851 if (partialBottomIndex < endLine) { 4852 endLine = partialBottomIndex + 1; 4853 end = 0; 4854 } else { 4855 end -= content.getOffsetAtLine(endLine); 4856 } 4857 4858 TextLayout layout = renderer.getTextLayout(startLine); 4859 int lineX = leftMargin - horizontalScrollOffset, startLineY = getLinePixel(startLine); 4860 int[] offsets = layout.getLineOffsets(); 4861 int startIndex = layout.getLineIndex(Math.min(start, layout.getText().length())); 4862 4863 4864 if (wordWrap && startIndex > 0 && offsets[startIndex] == start) { 4865 Rectangle rect = layout.getLineBounds(startIndex - 1); 4866 rect.x = rect.width; 4867 rect.width = clientAreaWidth - rightMargin - rect.x; 4868 rect.x += lineX; 4869 rect.y += startLineY; 4870 super.redraw(rect.x, rect.y, rect.width, rect.height, false); 4871 } 4872 4873 if (startLine == endLine) { 4874 int endIndex = layout.getLineIndex(Math.min(end, layout.getText().length())); 4875 if (startIndex == endIndex) { 4876 4877 Rectangle rect = layout.getBounds(start, end - 1); 4878 rect.x += lineX; 4879 rect.y += startLineY; 4880 super.redraw(rect.x, rect.y, rect.width, rect.height, false); 4881 renderer.disposeTextLayout(layout); 4882 return; 4883 } 4884 } 4885 4886 4887 Rectangle startRect = layout.getBounds(start, offsets[startIndex + 1] - 1); 4888 if (startRect.height == 0) { 4889 Rectangle bounds = layout.getLineBounds(startIndex); 4890 startRect.x = bounds.width; 4891 startRect.y = bounds.y; 4892 startRect.height = bounds.height; 4893 } 4894 startRect.x += lineX; 4895 startRect.y += startLineY; 4896 startRect.width = clientAreaWidth - rightMargin - startRect.x; 4897 super.redraw(startRect.x, startRect.y, startRect.width, startRect.height, false); 4898 4899 4900 if (startLine != endLine) { 4901 renderer.disposeTextLayout(layout); 4902 layout = renderer.getTextLayout(endLine); 4903 offsets = layout.getLineOffsets(); 4904 } 4905 int endIndex = layout.getLineIndex(Math.min(end, layout.getText().length())); 4906 Rectangle endRect = layout.getBounds(offsets[endIndex], end - 1); 4907 if (endRect.height == 0) { 4908 Rectangle bounds = layout.getLineBounds(endIndex); 4909 endRect.y = bounds.y; 4910 endRect.height = bounds.height; 4911 } 4912 endRect.x += lineX; 4913 endRect.y += getLinePixel(endLine); 4914 super.redraw(endRect.x, endRect.y, endRect.width, endRect.height, false); 4915 renderer.disposeTextLayout(layout); 4916 4917 4918 int y = startRect.y + startRect.height; 4919 if (endRect.y > y) { 4920 super.redraw(leftMargin, y, clientAreaWidth - rightMargin - leftMargin, endRect.y - y, false); 4921 } 4922} 4923 4926void handleDispose(Event event) { 4927 removeListener(SWT.Dispose, listener); 4928 notifyListeners(SWT.Dispose, event); 4929 event.type = SWT.None; 4930 4931 clipboard.dispose(); 4932 if (renderer != null) { 4933 renderer.dispose(); 4934 renderer = null; 4935 } 4936 if (content != null) { 4937 content.removeTextChangeListener(textChangeListener); 4938 content = null; 4939 } 4940 if (defaultCaret != null) { 4941 defaultCaret.dispose(); 4942 defaultCaret = null; 4943 } 4944 if (leftCaretBitmap != null) { 4945 leftCaretBitmap.dispose(); 4946 leftCaretBitmap = null; 4947 } 4948 if (rightCaretBitmap != null) { 4949 rightCaretBitmap.dispose(); 4950 rightCaretBitmap = null; 4951 } 4952 if (isBidiCaret()) { 4953 BidiUtil.removeLanguageListener(handle); 4954 } 4955 selectionBackground = null; 4956 selectionForeground = null; 4957 textChangeListener = null; 4958 selection = null; 4959 doubleClickSelection = null; 4960 keyActionMap = null; 4961 background = null; 4962 foreground = null; 4963 clipboard = null; 4964} 4965 4968void handleHorizontalScroll(Event event) { 4969 int scrollPixel = getHorizontalBar().getSelection() - horizontalScrollOffset; 4970 scrollHorizontal(scrollPixel, false); 4971} 4972 4978void handleKey(Event event) { 4979 int action; 4980 caretAlignment = PREVIOUS_OFFSET_TRAILING; 4981 if (event.keyCode != 0) { 4982 action = getKeyBinding(event.keyCode | event.stateMask); 4984 } else { 4985 action = getKeyBinding(event.character | event.stateMask); 4987 if (action == SWT.NULL) { 4988 if ((event.stateMask & SWT.CTRL) != 0 && (event.character >= 0) && event.character <= 31) { 4990 int c = event.character + 64; 4993 action = getKeyBinding(c | event.stateMask); 4994 } 4995 } 4996 } 4997 if (action == SWT.NULL) { 4998 boolean ignore = false; 4999 5000 if (IS_CARBON) { 5001 ignore = (event.stateMask ^ SWT.COMMAND) == 0 || 5006 (event.stateMask ^ (SWT.COMMAND | SWT.SHIFT)) == 0; 5007 } else if (IS_MOTIF) { 5008 ignore = (event.stateMask ^ SWT.CTRL) == 0 || 5013 (event.stateMask ^ (SWT.CTRL | SWT.SHIFT)) == 0; 5014 } else { 5015 ignore = (event.stateMask ^ SWT.ALT) == 0 || 5020 (event.stateMask ^ SWT.CTRL) == 0 || 5021 (event.stateMask ^ (SWT.ALT | SWT.SHIFT)) == 0 || 5022 (event.stateMask ^ (SWT.CTRL | SWT.SHIFT)) == 0; 5023 } 5024 if (!ignore && event.character > 31 && event.character != SWT.DEL || 5027 event.character == SWT.CR || event.character == SWT.LF || 5028 event.character == TAB) { 5029 doContent(event.character); 5030 update(); 5031 } 5032 } else { 5033 invokeAction(action); 5034 } 5035} 5036 5042void handleKeyDown(Event event) { 5043 if (clipboardSelection == null) { 5044 clipboardSelection = new Point(selection.x, selection.y); 5045 } 5046 5047 Event verifyEvent = new Event(); 5048 verifyEvent.character = event.character; 5049 verifyEvent.keyCode = event.keyCode; 5050 verifyEvent.stateMask = event.stateMask; 5051 verifyEvent.doit = true; 5052 notifyListeners(VerifyKey, verifyEvent); 5053 if (verifyEvent.doit) { 5054 handleKey(event); 5055 } 5056} 5057 5062void handleKeyUp(Event event) { 5063 if (clipboardSelection != null) { 5064 if (clipboardSelection.x != selection.x || clipboardSelection.y != selection.y) { 5065 try { 5066 if (selection.y - selection.x > 0) { 5067 setClipboardContent(selection.x, selection.y - selection.x, DND.SELECTION_CLIPBOARD); 5068 } 5069 } catch (SWTError error) { 5070 if (error.code != DND.ERROR_CANNOT_SET_CLIPBOARD) { 5075 throw error; 5076 } 5077 } 5078 } 5079 } 5080 clipboardSelection = null; 5081} 5082 5086void handleMouseDown(Event event) { 5087 forceFocus(); 5089 5090 if (dragDetect && checkDragDetect(event)) return; 5092 5093 if (event.button == 2) { 5095 String text = (String )getClipboardContent(DND.SELECTION_CLIPBOARD); 5096 if (text != null && text.length() > 0) { 5097 doMouseLocationChange(event.x, event.y, false); 5099 Event e = new Event(); 5101 e.start = selection.x; 5102 e.end = selection.y; 5103 e.text = getModelDelimitedText(text); 5104 sendKeyEvent(e); 5105 } 5106 } 5107 5108 if ((event.button != 1) || (IS_CARBON && (event.stateMask & SWT.MOD4) != 0)) { 5110 return; 5111 } 5112 clickCount = event.count; 5113 if (clickCount == 1) { 5114 boolean select = (event.stateMask & SWT.MOD2) != 0; 5115 doMouseLocationChange(event.x, event.y, select); 5116 } else { 5117 if (doubleClickEnabled) { 5118 clearSelection(false); 5119 int offset = getOffsetAtPoint(event.x, event.y); 5120 int lineIndex = content.getLineAtOffset(offset); 5121 int lineOffset = content.getOffsetAtLine(lineIndex); 5122 int lineEnd = content.getCharCount(); 5123 if (lineIndex + 1 < content.getLineCount()) { 5124 lineEnd = content.getOffsetAtLine(lineIndex + 1); 5125 } 5126 int start, end; 5127 if ((clickCount & 1) == 0) { 5128 start = Math.max(0, getWordPrevious(offset, SWT.MOVEMENT_WORD_START)); 5129 end = Math.min(content.getCharCount(), getWordNext(start, SWT.MOVEMENT_WORD_END)); 5130 } else { 5131 start = lineOffset; 5132 end = lineEnd; 5133 } 5134 selection.x = selection.y = start; 5135 selectionAnchor = -1; 5136 caretOffset = end; 5137 showCaret(); 5138 doMouseSelection(); 5139 doubleClickSelection = new Point(selection.x, selection.y); 5140 } 5141 } 5142} 5143 5147void handleMouseMove(Event event) { 5148 if (clickCount == 0) return; 5149 doMouseLocationChange(event.x, event.y, true); 5150 update(); 5151 doAutoScroll(event); 5152} 5153 5156void handleMouseUp(Event event) { 5157 clickCount = 0; 5158 endAutoScroll(); 5159 if (event.button == 1) { 5160 try { 5161 if (selection.y - selection.x > 0) { 5162 setClipboardContent(selection.x, selection.y - selection.x, DND.SELECTION_CLIPBOARD); 5163 } 5164 } catch (SWTError error) { 5165 if (error.code != DND.ERROR_CANNOT_SET_CLIPBOARD) { 5170 throw error; 5171 } 5172 } 5173 } 5174} 5175 5180void handlePaint(Event event) { 5181 if (event.width == 0 || event.height == 0) return; 5182 if (clientAreaWidth == 0 || clientAreaHeight == 0) return; 5183 5184 int startLine = getLineIndex(event.y); 5185 int y = getLinePixel(startLine); 5186 int endY = event.y + event.height; 5187 GC gc = event.gc; 5188 Color background = getBackground(); 5189 Color foreground = getForeground(); 5190 if (endY > 0) { 5191 int lineCount = isSingleLine() ? 1 : content.getLineCount(); 5192 int x = leftMargin - horizontalScrollOffset; 5193 for (int i = startLine; y < endY && i < lineCount; i++) { 5194 y += renderer.drawLine(i, x, y, gc, background, foreground); 5195 } 5196 if (y < endY) { 5197 gc.setBackground(background); 5198 drawBackground(gc, 0, y, clientAreaWidth, endY - y); 5199 } 5200 } 5201 gc.setBackground(background); 5203 if (topMargin > 0) { 5204 drawBackground(gc, 0, 0, clientAreaWidth, topMargin); 5205 } 5206 if (bottomMargin > 0) { 5207 drawBackground(gc, 0, clientAreaHeight - bottomMargin, clientAreaWidth, bottomMargin); 5208 } 5209 if (leftMargin > 0) { 5210 drawBackground(gc, 0, 0, leftMargin, clientAreaHeight); 5211 } 5212 if (rightMargin > 0) { 5213 drawBackground(gc, clientAreaWidth - rightMargin, 0, rightMargin, clientAreaHeight); 5214 } 5215} 5216 5222void handleResize(Event event) { 5223 int oldHeight = clientAreaHeight; 5224 int oldWidth = clientAreaWidth; 5225 Rectangle clientArea = getClientArea(); 5226 clientAreaHeight = clientArea.height; 5227 clientAreaWidth = clientArea.width; 5228 5229 if (oldWidth != clientAreaWidth) { 5230 if (rightMargin > 0) { 5231 int x = (oldWidth < clientAreaWidth ? oldWidth : clientAreaWidth) - rightMargin; 5232 super.redraw(x, 0, rightMargin, oldHeight, false); 5233 } 5234 } 5235 if (oldHeight != clientAreaHeight) { 5236 if (bottomMargin > 0) { 5237 int y = (oldHeight < clientAreaHeight ? oldHeight : clientAreaHeight) - bottomMargin; 5238 super.redraw(0, y, oldWidth, bottomMargin, false); 5239 } 5240 } 5241 if (wordWrap) { 5242 if (oldWidth != clientAreaWidth) { 5243 renderer.reset(0, content.getLineCount()); 5244 verticalScrollOffset = -1; 5245 renderer.calculateIdle(); 5246 super.redraw(); 5247 } 5248 if (oldHeight != clientAreaHeight) { 5249 if (oldHeight == 0) topIndexY = 0; 5250 setScrollBars(true); 5251 } 5252 setCaretLocation(); 5253 } else { 5254 renderer.calculateClientArea(); 5255 setScrollBars(true); 5256 claimRightFreeSpace(); 5257 if (clientAreaWidth != 0) { 5260 ScrollBar horizontalBar = getHorizontalBar(); 5261 if (horizontalBar != null && horizontalBar.getVisible()) { 5262 if (horizontalScrollOffset != horizontalBar.getSelection()) { 5263 horizontalBar.setSelection(horizontalScrollOffset); 5264 horizontalScrollOffset = horizontalBar.getSelection(); 5265 } 5266 } 5267 } 5268 } 5269 claimBottomFreeSpace(); 5270 } 5275 5279void handleTextChanged(TextChangedEvent event) { 5280 int firstLine = content.getLineAtOffset(lastTextChangeStart); 5281 resetCache(firstLine, 0); 5282 if (!isFixedLineHeight() && topIndex > firstLine) { 5283 topIndex = firstLine; 5284 topIndexY = 0; 5285 super.redraw(); 5286 } else { 5287 int lastLine = firstLine + lastTextChangeNewLineCount; 5288 int firstLineTop = getLinePixel(firstLine); 5289 int newLastLineBottom = getLinePixel(lastLine + 1); 5290 if (lastLineBottom != newLastLineBottom) { 5291 super.redraw(); 5292 if (wordWrap) setCaretLocation(); 5293 } else { 5294 super.redraw(0, firstLineTop, clientAreaWidth, newLastLineBottom - firstLineTop, false); 5295 redrawLinesBullet(renderer.redrawLines); 5296 } 5297 } 5298 renderer.redrawLines = null; 5299 updateSelection(lastTextChangeStart, lastTextChangeReplaceCharCount, lastTextChangeNewCharCount); 5307 if (lastTextChangeReplaceLineCount > 0 || wordWrap) { 5308 claimBottomFreeSpace(); 5309 } 5310 if (lastTextChangeReplaceCharCount > 0) { 5311 claimRightFreeSpace(); 5312 } 5313} 5314 5325void handleTextChanging(TextChangingEvent event) { 5326 if (event.replaceCharCount < 0) { 5327 event.start += event.replaceCharCount; 5328 event.replaceCharCount *= -1; 5329 } 5330 lastTextChangeStart = event.start; 5331 lastTextChangeNewLineCount = event.newLineCount; 5332 lastTextChangeNewCharCount = event.newCharCount; 5333 lastTextChangeReplaceLineCount = event.replaceLineCount; 5334 lastTextChangeReplaceCharCount = event.replaceCharCount; 5335 int lineIndex = content.getLineAtOffset(event.start); 5336 int srcY = getLinePixel(lineIndex + event.replaceLineCount + 1); 5337 int destY = getLinePixel(lineIndex + 1) + event.newLineCount * renderer.getLineHeight(); 5338 lastLineBottom = destY; 5339 if (srcY < 0 && destY < 0) { 5340 lastLineBottom += srcY - destY; 5341 verticalScrollOffset += destY - srcY; 5342 calculateTopIndex(destY - srcY); 5343 setScrollBars(true); 5344 } else { 5345 scrollText(srcY, destY); 5346 } 5347 5348 renderer.textChanging(event); 5349 5350 int newEndOfText = content.getCharCount() - event.replaceCharCount + event.newCharCount; 5355 if (caretOffset > newEndOfText) caretOffset = newEndOfText; 5356} 5357 5364void handleTextSet(TextChangedEvent event) { 5365 reset(); 5366} 5367 5376void handleTraverse(Event event) { 5377 switch (event.detail) { 5378 case SWT.TRAVERSE_ESCAPE: 5379 case SWT.TRAVERSE_PAGE_NEXT: 5380 case SWT.TRAVERSE_PAGE_PREVIOUS: 5381 event.doit = true; 5382 break; 5383 case SWT.TRAVERSE_RETURN: 5384 case SWT.TRAVERSE_TAB_NEXT: 5385 case SWT.TRAVERSE_TAB_PREVIOUS: 5386 if ((getStyle() & SWT.SINGLE) != 0) { 5387 event.doit = true; 5388 } else { 5389 if (!editable || (event.stateMask & SWT.MODIFIER_MASK) != 0) { 5390 event.doit = true; 5391 } 5392 } 5393 break; 5394 } 5395} 5396 5399void handleVerticalScroll(Event event) { 5400 int scrollPixel = getVerticalBar().getSelection() - getVerticalScrollOffset(); 5401 scrollVertical(scrollPixel, false); 5402} 5403 5406void initializeAccessible() { 5407 final Accessible accessible = getAccessible(); 5408 accessible.addAccessibleListener(new AccessibleAdapter() { 5409 public void getName (AccessibleEvent e) { 5410 String name = null; 5411 Label label = getAssociatedLabel (); 5412 if (label != null) { 5413 name = stripMnemonic (label.getText()); 5414 } 5415 e.result = name; 5416 } 5417 public void getHelp(AccessibleEvent e) { 5418 e.result = getToolTipText(); 5419 } 5420 public void getKeyboardShortcut(AccessibleEvent e) { 5421 String shortcut = null; 5422 Label label = getAssociatedLabel (); 5423 if (label != null) { 5424 String text = label.getText (); 5425 if (text != null) { 5426 char mnemonic = _findMnemonic (text); 5427 if (mnemonic != '\0') { 5428 shortcut = "Alt+"+mnemonic; } 5430 } 5431 } 5432 e.result = shortcut; 5433 } 5434 }); 5435 accessible.addAccessibleTextListener(new AccessibleTextAdapter() { 5436 public void getCaretOffset(AccessibleTextEvent e) { 5437 e.offset = StyledText.this.getCaretOffset(); 5438 } 5439 public void getSelectionRange(AccessibleTextEvent e) { 5440 Point selection = StyledText.this.getSelectionRange(); 5441 e.offset = selection.x; 5442 e.length = selection.y; 5443 } 5444 }); 5445 accessible.addAccessibleControlListener(new AccessibleControlAdapter() { 5446 public void getRole(AccessibleControlEvent e) { 5447 e.detail = ACC.ROLE_TEXT; 5448 } 5449 public void getState(AccessibleControlEvent e) { 5450 int state = 0; 5451 if (isEnabled()) state |= ACC.STATE_FOCUSABLE; 5452 if (isFocusControl()) state |= ACC.STATE_FOCUSED; 5453 if (!isVisible()) state |= ACC.STATE_INVISIBLE; 5454 if (!getEditable()) state |= ACC.STATE_READONLY; 5455 e.detail = state; 5456 } 5457 public void getValue(AccessibleControlEvent e) { 5458 e.result = StyledText.this.getText(); 5459 } 5460 }); 5461 addListener(SWT.FocusIn, new Listener() { 5462 public void handleEvent(Event event) { 5463 accessible.setFocus(ACC.CHILDID_SELF); 5464 } 5465 }); 5466} 5467 5471Label getAssociatedLabel () { 5472 Control[] siblings = getParent ().getChildren (); 5473 for (int i = 0; i < siblings.length; i++) { 5474 if (siblings [i] == StyledText.this) { 5475 if (i > 0 && siblings [i-1] instanceof Label) { 5476 return (Label) siblings [i-1]; 5477 } 5478 } 5479 } 5480 return null; 5481} 5482String stripMnemonic (String string) { 5483 int index = 0; 5484 int length = string.length (); 5485 do { 5486 while ((index < length) && (string.charAt (index) != '&')) index++; 5487 if (++index >= length) return string; 5488 if (string.charAt (index) != '&') { 5489 return string.substring(0, index-1) + string.substring(index, length); 5490 } 5491 index++; 5492 } while (index < length); 5493 return string; 5494} 5495 5500char _findMnemonic (String string) { 5501 if (string == null) return '\0'; 5502 int index = 0; 5503 int length = string.length (); 5504 do { 5505 while (index < length && string.charAt (index) != '&') index++; 5506 if (++index >= length) return '\0'; 5507 if (string.charAt (index) != '&') return Character.toLowerCase (string.charAt (index)); 5508 index++; 5509 } while (index < length); 5510 return '\0'; 5511} 5512 5517public void invokeAction(int action) { 5518 checkWidget(); 5519 updateCaretDirection = true; 5520 switch (action) { 5521 case ST.LINE_UP: 5523 doLineUp(false); 5524 clearSelection(true); 5525 break; 5526 case ST.LINE_DOWN: 5527 doLineDown(false); 5528 clearSelection(true); 5529 break; 5530 case ST.LINE_START: 5531 doLineStart(); 5532 clearSelection(true); 5533 break; 5534 case ST.LINE_END: 5535 doLineEnd(); 5536 clearSelection(true); 5537 break; 5538 case ST.COLUMN_PREVIOUS: 5539 doCursorPrevious(); 5540 clearSelection(true); 5541 break; 5542 case ST.COLUMN_NEXT: 5543 doCursorNext(); 5544 clearSelection(true); 5545 break; 5546 case ST.PAGE_UP: 5547 doPageUp(false, -1); 5548 clearSelection(true); 5549 break; 5550 case ST.PAGE_DOWN: 5551 doPageDown(false, -1); 5552 clearSelection(true); 5553 break; 5554 case ST.WORD_PREVIOUS: 5555 doWordPrevious(); 5556 clearSelection(true); 5557 break; 5558 case ST.WORD_NEXT: 5559 doWordNext(); 5560 clearSelection(true); 5561 break; 5562 case ST.TEXT_START: 5563 doContentStart(); 5564 clearSelection(true); 5565 break; 5566 case ST.TEXT_END: 5567 doContentEnd(); 5568 clearSelection(true); 5569 break; 5570 case ST.WINDOW_START: 5571 doPageStart(); 5572 clearSelection(true); 5573 break; 5574 case ST.WINDOW_END: 5575 doPageEnd(); 5576 clearSelection(true); 5577 break; 5578 case ST.SELECT_LINE_UP: 5580 doSelectionLineUp(); 5581 break; 5582 case ST.SELECT_ALL: 5583 selectAll(); 5584 break; 5585 case ST.SELECT_LINE_DOWN: 5586 doSelectionLineDown(); 5587 break; 5588 case ST.SELECT_LINE_START: 5589 doLineStart(); 5590 doSelection(ST.COLUMN_PREVIOUS); 5591 break; 5592 case ST.SELECT_LINE_END: 5593 doLineEnd(); 5594 doSelection(ST.COLUMN_NEXT); 5595 break; 5596 case ST.SELECT_COLUMN_PREVIOUS: 5597 doSelectionCursorPrevious(); 5598 doSelection(ST.COLUMN_PREVIOUS); 5599 break; 5600 case ST.SELECT_COLUMN_NEXT: 5601 doSelectionCursorNext(); 5602 doSelection(ST.COLUMN_NEXT); 5603 break; 5604 case ST.SELECT_PAGE_UP: 5605 doSelectionPageUp(-1); 5606 break; 5607 case ST.SELECT_PAGE_DOWN: 5608 doSelectionPageDown(-1); 5609 break; 5610 case ST.SELECT_WORD_PREVIOUS: 5611 doSelectionWordPrevious(); 5612 doSelection(ST.COLUMN_PREVIOUS); 5613 break; 5614 case ST.SELECT_WORD_NEXT: 5615 doSelectionWordNext(); 5616 doSelection(ST.COLUMN_NEXT); 5617 break; 5618 case ST.SELECT_TEXT_START: 5619 doContentStart(); 5620 doSelection(ST.COLUMN_PREVIOUS); 5621 break; 5622 case ST.SELECT_TEXT_END: 5623 doContentEnd(); 5624 doSelection(ST.COLUMN_NEXT); 5625 break; 5626 case ST.SELECT_WINDOW_START: 5627 doPageStart(); 5628 doSelection(ST.COLUMN_PREVIOUS); 5629 break; 5630 case ST.SELECT_WINDOW_END: 5631 doPageEnd(); 5632 doSelection(ST.COLUMN_NEXT); 5633 break; 5634 case ST.CUT: 5636 cut(); 5637 break; 5638 case ST.COPY: 5639 copy(); 5640 break; 5641 case ST.PASTE: 5642 paste(); 5643 break; 5644 case ST.DELETE_PREVIOUS: 5645 doBackspace(); 5646 break; 5647 case ST.DELETE_NEXT: 5648 doDelete(); 5649 break; 5650 case ST.DELETE_WORD_PREVIOUS: 5651 doDeleteWordPrevious(); 5652 break; 5653 case ST.DELETE_WORD_NEXT: 5654 doDeleteWordNext(); 5655 break; 5656 case ST.TOGGLE_OVERWRITE: 5658 overwrite = !overwrite; break; 5660 } 5661} 5662 5665boolean isBidi() { 5666 return IS_GTK || BidiUtil.isBidiPlatform() || isMirrored; 5667} 5668boolean isBidiCaret() { 5669 return BidiUtil.isBidiPlatform(); 5670} 5671boolean isFixedLineHeight() { 5672 return fixedLineHeight; 5673} 5674 5682boolean isLineDelimiter(int offset) { 5683 int line = content.getLineAtOffset(offset); 5684 int lineOffset = content.getOffsetAtLine(line); 5685 int offsetInLine = offset - lineOffset; 5686 return offsetInLine > content.getLine(line).length(); 5690} 5691 5698boolean isMirrored() { 5699 return isMirrored; 5700} 5701 5707boolean isSingleLine() { 5708 return (getStyle() & SWT.SINGLE) != 0; 5709} 5710 5723void modifyContent(Event event, boolean updateCaret) { 5724 event.doit = true; 5725 notifyListeners(SWT.Verify, event); 5726 if (event.doit) { 5727 StyledTextEvent styledTextEvent = null; 5728 int replacedLength = event.end - event.start; 5729 if (isListening(ExtendedModify)) { 5730 styledTextEvent = new StyledTextEvent(content); 5731 styledTextEvent.start = event.start; 5732 styledTextEvent.end = event.start + event.text.length(); 5733 styledTextEvent.text = content.getTextRange(event.start, replacedLength); 5734 } 5735 if (updateCaret) { 5736 if (event.text.length() == 0) { 5738 int lineIndex = content.getLineAtOffset(event.start); 5739 int lineOffset = content.getOffsetAtLine(lineIndex); 5740 TextLayout layout = renderer.getTextLayout(lineIndex); 5741 int levelStart = layout.getLevel(event.start - lineOffset); 5742 int lineIndexEnd = content.getLineAtOffset(event.end); 5743 if (lineIndex != lineIndexEnd) { 5744 renderer.disposeTextLayout(layout); 5745 lineOffset = content.getOffsetAtLine(lineIndexEnd); 5746 layout = renderer.getTextLayout(lineIndexEnd); 5747 } 5748 int levelEnd = layout.getLevel(event.end - lineOffset); 5749 renderer.disposeTextLayout(layout); 5750 if (levelStart != levelEnd) { 5751 caretAlignment = PREVIOUS_OFFSET_TRAILING; 5752 } else { 5753 caretAlignment = OFFSET_LEADING; 5754 } 5755 } 5756 } 5757 content.replaceTextRange(event.start, replacedLength, event.text); 5758 if (updateCaret) { 5761 setSelection(event.start + event.text.length(), 0, true); 5763 showCaret(); 5764 } 5765 sendModifyEvent(event); 5766 if (isListening(ExtendedModify)) { 5767 notifyListeners(ExtendedModify, styledTextEvent); 5768 } 5769 } 5770} 5771void paintObject(GC gc, int x, int y, int ascent, int descent, StyleRange style, Bullet bullet, int bulletIndex) { 5772 if (isListening(PaintObject)) { 5773 StyledTextEvent event = new StyledTextEvent (content) ; 5774 event.gc = gc; 5775 event.x = x; 5776 event.y = y; 5777 event.ascent = ascent; 5778 event.descent = descent; 5779 event.style = style; 5780 event.bullet = bullet; 5781 event.bulletIndex = bulletIndex; 5782 notifyListeners(PaintObject, event); 5783 } 5784} 5785 5797public void paste(){ 5798 checkWidget(); 5799 String text = (String ) getClipboardContent(DND.CLIPBOARD); 5800 if (text != null && text.length() > 0) { 5801 Event event = new Event(); 5802 event.start = selection.x; 5803 event.end = selection.y; 5804 event.text = getModelDelimitedText(text); 5805 sendKeyEvent(event); 5806 } 5807} 5808 5816public void print() { 5817 checkWidget(); 5818 Printer printer = new Printer(); 5819 StyledTextPrintOptions options = new StyledTextPrintOptions(); 5820 options.printTextForeground = true; 5821 options.printTextBackground = true; 5822 options.printTextFontStyle = true; 5823 options.printLineBackground = true; 5824 new Printing(this, printer, options).run(); 5825 printer.dispose(); 5826} 5827 5843public Runnable print(Printer printer) { 5844 checkWidget(); 5845 if (printer == null) { 5846 SWT.error(SWT.ERROR_NULL_ARGUMENT); 5847 } 5848 StyledTextPrintOptions options = new StyledTextPrintOptions(); 5849 options.printTextForeground = true; 5850 options.printTextBackground = true; 5851 options.printTextFontStyle = true; 5852 options.printLineBackground = true; 5853 return print(printer, options); 5854} 5855 5873public Runnable print(Printer printer, StyledTextPrintOptions options) { 5874 checkWidget(); 5875 if (printer == null || options == null) { 5876 SWT.error(SWT.ERROR_NULL_ARGUMENT); 5877 } 5878 return new Printing(this, printer, options); 5879} 5880 5898public void redraw() { 5899 super.redraw(); 5900 int itemCount = getPartialBottomIndex() - topIndex + 1; 5901 renderer.reset(topIndex, itemCount); 5902 renderer.calculate(topIndex, itemCount); 5903 setScrollBars(false); 5904} 5905 5935public void redraw(int x, int y, int width, int height, boolean all) { 5936 super.redraw(x, y, width, height, all); 5937 if (height > 0) { 5938 int firstLine = getLineIndex(y); 5939 int lastLine = getLineIndex(y + height); 5940 resetCache(firstLine, lastLine - firstLine + 1); 5941 } 5942} 5943void redrawLines(int startLine, int lineCount) { 5944 int partialBottomIndex = getPartialBottomIndex(); 5946 if (startLine > partialBottomIndex || startLine + lineCount - 1 < topIndex) { 5947 return; 5948 } 5949 if (startLine < topIndex) { 5951 lineCount -= topIndex - startLine; 5952 startLine = topIndex; 5953 } 5954 if (startLine + lineCount - 1 > partialBottomIndex) { 5955 lineCount = partialBottomIndex - startLine + 1; 5956 } 5957 startLine -= topIndex; 5958 int redrawTop = getLinePixel(startLine); 5959 int redrawBottom = getLinePixel(startLine + lineCount); 5960 int redrawWidth = clientAreaWidth - leftMargin - rightMargin; 5961 super.redraw(leftMargin, redrawTop, redrawWidth, redrawBottom - redrawTop, true); 5962} 5963void redrawLinesBullet (int[] redrawLines) { 5964 if (redrawLines == null) return; 5965 int topIndex = getPartialTopIndex(); 5966 int bottomIndex = getPartialBottomIndex(); 5967 for (int i = 0; i < redrawLines.length; i++) { 5968 int lineIndex = redrawLines[i]; 5969 if (!(topIndex <= lineIndex && lineIndex <= bottomIndex)) continue; 5970 int width = -1; 5971 Bullet bullet = renderer.getLineBullet(lineIndex, null); 5972 if (bullet != null) { 5973 StyleRange style = bullet.style; 5974 GlyphMetrics metrics = style.metrics; 5975 width = metrics.width; 5976 } 5977 if (width == -1) width = getClientArea().width; 5978 int height = renderer.getLineHeight(lineIndex); 5979 int y = getLinePixel(lineIndex); 5980 super.redraw(0, y, width, height, false); 5981 } 5982} 5983 6007public void redrawRange(int start, int length, boolean clearBackground) { 6008 checkWidget(); 6009 int end = start + length; 6010 int contentLength = content.getCharCount(); 6011 if (start > end || start < 0 || end > contentLength) { 6012 SWT.error(SWT.ERROR_INVALID_RANGE); 6013 } 6014 int firstLine = content.getLineAtOffset(start); 6015 int lastLine = content.getLineAtOffset(end); 6016 resetCache(firstLine, lastLine - firstLine + 1); 6017 internalRedrawRange(start, length); 6018} 6019 6032public void removeBidiSegmentListener(BidiSegmentListener listener) { 6033 checkWidget(); 6034 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6035 removeListener(LineGetSegments, listener); 6036} 6037 6049public void removeExtendedModifyListener(ExtendedModifyListener extendedModifyListener) { 6050 checkWidget(); 6051 if (extendedModifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6052 removeListener(ExtendedModify, extendedModifyListener); 6053} 6054 6066public void removeLineBackgroundListener(LineBackgroundListener listener) { 6067 checkWidget(); 6068 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6069 removeListener(LineGetBackground, listener); 6070} 6071 6083public void removeLineStyleListener(LineStyleListener listener) { 6084 checkWidget(); 6085 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6086 removeListener(LineGetStyle, listener); 6087} 6088 6100public void removeModifyListener(ModifyListener modifyListener) { 6101 checkWidget(); 6102 if (modifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6103 removeListener(SWT.Modify, modifyListener); 6104} 6105 6118public void removePaintObjectListener(PaintObjectListener listener) { 6119 checkWidget(); 6120 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6121 removeListener(PaintObject, listener); 6122} 6123 6140public void removeSelectionListener(SelectionListener listener) { 6141 checkWidget(); 6142 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6143 removeListener(SWT.Selection, listener); 6144} 6145 6157public void removeVerifyListener(VerifyListener verifyListener) { 6158 checkWidget(); 6159 if (verifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6160 removeListener(SWT.Verify, verifyListener); 6161} 6162 6174public void removeVerifyKeyListener(VerifyKeyListener listener) { 6175 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6176 removeListener(VerifyKey, listener); 6177} 6178 6196 6197public void removeWordMovementListener(MovementListener listener) { 6198 checkWidget(); 6199 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6200 removeListener(WordNext, listener); 6201 removeListener(WordPrevious, listener); 6202} 6203 6237public void replaceStyleRanges(int start, int length, StyleRange[] ranges) { 6238 checkWidget(); 6239 if (isListening(LineGetStyle)) return; 6240 if (ranges == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 6241 setStyleRanges(start, length, null, ranges, false); 6242} 6243 6276public void replaceTextRange(int start, int length, String text) { 6277 checkWidget(); 6278 if (text == null) { 6279 SWT.error(SWT.ERROR_NULL_ARGUMENT); 6280 } 6281 int contentLength = getCharCount(); 6282 int end = start + length; 6283 if (start > end || start < 0 || end > contentLength) { 6284 SWT.error(SWT.ERROR_INVALID_RANGE); 6285 } 6286 Event event = new Event(); 6287 event.start = start; 6288 event.end = end; 6289 event.text = text; 6290 modifyContent(event, false); 6291} 6292 6296void reset() { 6297 ScrollBar verticalBar = getVerticalBar(); 6298 ScrollBar horizontalBar = getHorizontalBar(); 6299 caretOffset = 0; 6300 topIndex = 0; 6301 topIndexY = 0; 6302 verticalScrollOffset = 0; 6303 horizontalScrollOffset = 0; 6304 resetSelection(); 6305 renderer.setContent(content); 6306 if (verticalBar != null) { 6307 verticalBar.setSelection(0); 6308 } 6309 if (horizontalBar != null) { 6310 horizontalBar.setSelection(0); 6311 } 6312 resetCache(0, 0); 6313 setCaretLocation(); 6314 super.redraw(); 6315} 6316void resetCache(int firstLine, int count) { 6317 int maxLineIndex = renderer.maxWidthLineIndex; 6318 renderer.reset(firstLine, count); 6319 renderer.calculateClientArea(); 6320 if (0 <= maxLineIndex && maxLineIndex < content.getLineCount()) { 6321 renderer.calculate(maxLineIndex, 1); 6322 } 6323 setScrollBars(true); 6324 if (!isFixedLineHeight()) { 6325 if (topIndex > firstLine) { 6326 verticalScrollOffset = -1; 6327 } 6328 renderer.calculateIdle(); 6329 } 6330} 6331 6334void resetSelection() { 6335 selection.x = selection.y = caretOffset; 6336 selectionAnchor = -1; 6337} 6338 6339public void scroll(int destX, int destY, int x, int y, int width, int height, boolean all) { 6340 super.scroll(destX, destY, x, y, width, height, false); 6341 if (all) { 6342 int deltaX = destX - x, deltaY = destY - y; 6343 Control[] children = getChildren(); 6344 for (int i=0; i<children.length; i++) { 6345 Control child = children[i]; 6346 Rectangle rect = child.getBounds(); 6347 child.setLocation(rect.x + deltaX, rect.y + deltaY); 6348 } 6349 } 6350} 6351 6352 6364boolean scrollHorizontal(int pixels, boolean adjustScrollBar) { 6365 if (pixels == 0) { 6366 return false; 6367 } 6368 ScrollBar horizontalBar = getHorizontalBar(); 6369 if (horizontalBar != null && adjustScrollBar) { 6370 horizontalBar.setSelection(horizontalScrollOffset + pixels); 6371 } 6372 int scrollHeight = clientAreaHeight - topMargin - bottomMargin; 6373 if (pixels > 0) { 6374 int sourceX = leftMargin + pixels; 6375 int scrollWidth = clientAreaWidth - sourceX - rightMargin; 6376 if (scrollWidth > 0) { 6377 scroll(leftMargin, topMargin, sourceX, topMargin, scrollWidth, scrollHeight, true); 6378 } 6379 if (sourceX > scrollWidth) { 6380 super.redraw(leftMargin + scrollWidth, topMargin, pixels - scrollWidth, scrollHeight, true); 6381 } 6382 } else { 6383 int destinationX = leftMargin - pixels; 6384 int scrollWidth = clientAreaWidth - destinationX - rightMargin; 6385 if (scrollWidth > 0) { 6386 scroll(destinationX, topMargin, leftMargin, topMargin, scrollWidth, scrollHeight, true); 6387 } 6388 if (destinationX > scrollWidth) { 6389 super.redraw(leftMargin + scrollWidth, topMargin, -pixels - scrollWidth, scrollHeight, true); 6390 } 6391 } 6392 horizontalScrollOffset += pixels; 6393 int oldColumnX = columnX; 6394 setCaretLocation(); 6395 columnX = oldColumnX; 6396 return true; 6397} 6398 6409boolean scrollVertical(int pixels, boolean adjustScrollBar) { 6410 if (pixels == 0) { 6411 return false; 6412 } 6413 if (verticalScrollOffset != -1) { 6414 ScrollBar verticalBar = getVerticalBar(); 6415 if (verticalBar != null && adjustScrollBar) { 6416 verticalBar.setSelection(verticalScrollOffset + pixels); 6417 } 6418 int scrollWidth = clientAreaWidth - leftMargin - rightMargin; 6419 if (pixels > 0) { 6420 int sourceY = topMargin + pixels; 6421 int scrollHeight = clientAreaHeight - sourceY - bottomMargin; 6422 if (scrollHeight > 0) { 6423 scroll(leftMargin, topMargin, leftMargin, sourceY, scrollWidth, scrollHeight, true); 6424 } 6425 if (sourceY > scrollHeight) { 6426 int redrawY = Math.max(0, topMargin + scrollHeight); 6427 int redrawHeight = Math.min(clientAreaHeight, pixels - scrollHeight); 6428 super.redraw(leftMargin, redrawY, scrollWidth, redrawHeight, true); 6429 } 6430 } else { 6431 int destinationY = topMargin - pixels; 6432 int scrollHeight = clientAreaHeight - destinationY - bottomMargin; 6433 if (scrollHeight > 0) { 6434 scroll(leftMargin, destinationY, leftMargin, topMargin, scrollWidth, scrollHeight, true); 6435 } 6436 if (destinationY > scrollHeight) { 6437 int redrawY = Math.max(0, topMargin + scrollHeight); 6438 int redrawHeight = Math.min(clientAreaHeight, -pixels - scrollHeight); 6439 super.redraw(leftMargin, redrawY, scrollWidth, redrawHeight, true); 6440 } 6441 } 6442 verticalScrollOffset += pixels; 6443 calculateTopIndex(pixels); 6444 } else { 6445 calculateTopIndex(pixels); 6446 super.redraw(); 6447 } 6448 int oldColumnX = columnX; 6449 setCaretLocation(); 6450 columnX = oldColumnX; 6451 return true; 6452} 6453void scrollText(int srcY, int destY) { 6454 if (srcY == destY) return; 6455 int deltaY = destY - srcY; 6456 int scrollWidth = clientAreaWidth - leftMargin - rightMargin, scrollHeight; 6457 if (deltaY > 0) { 6458 scrollHeight = clientAreaHeight - srcY - bottomMargin; 6459 } else { 6460 scrollHeight = clientAreaHeight - destY - bottomMargin; 6461 } 6462 scroll(leftMargin, destY, leftMargin, srcY, scrollWidth, scrollHeight, true); 6463 if ((0 < srcY + scrollHeight) && (topMargin > srcY)) { 6464 super.redraw(leftMargin, deltaY, scrollWidth, topMargin, false); 6465 } 6466 if ((0 < destY + scrollHeight) && (topMargin > destY)) { 6467 super.redraw(leftMargin, 0, scrollWidth, topMargin, false); 6468 } 6469 if ((clientAreaHeight - bottomMargin < srcY + scrollHeight) && (clientAreaHeight > srcY)) { 6470 super.redraw(leftMargin, clientAreaHeight - bottomMargin + deltaY, scrollWidth, bottomMargin, false); 6471 } 6472 if ((clientAreaHeight - bottomMargin < destY + scrollHeight) && (clientAreaHeight > destY)) { 6473 super.redraw(leftMargin, clientAreaHeight - bottomMargin, scrollWidth, bottomMargin, false); 6474 } 6475} 6476 6484public void selectAll() { 6485 checkWidget(); 6486 setSelection(0, Math.max(getCharCount(),0)); 6487} 6488 6498void sendKeyEvent(Event event) { 6499 if (editable) { 6500 modifyContent(event, true); 6501 } 6502} 6503 6519StyledTextEvent sendLineEvent(int eventType, int lineOffset, String line) { 6520 StyledTextEvent event = null; 6521 if (isListening(eventType)) { 6522 event = new StyledTextEvent(content); 6523 event.detail = lineOffset; 6524 event.text = line; 6525 event.alignment = alignment; 6526 event.indent = indent; 6527 event.justify = justify; 6528 notifyListeners(eventType, event); 6529 } 6530 return event; 6531} 6532void sendModifyEvent(Event event) { 6533 Accessible accessible = getAccessible(); 6534 if (event.text.length() == 0) { 6535 accessible.textChanged(ACC.TEXT_DELETE, event.start, event.end - event.start); 6536 } else { 6537 if (event.start == event.end) { 6538 accessible.textChanged(ACC.TEXT_INSERT, event.start, event.text.length()); 6539 } else { 6540 accessible.textChanged(ACC.TEXT_DELETE, event.start, event.end - event.start); 6541 accessible.textChanged(ACC.TEXT_INSERT, event.start, event.text.length()); 6542 } 6543 } 6544 notifyListeners(SWT.Modify, event); 6545} 6546 6549void sendSelectionEvent() { 6550 getAccessible().textSelectionChanged(); 6551 Event event = new Event(); 6552 event.x = selection.x; 6553 event.y = selection.y; 6554 notifyListeners(SWT.Selection, event); 6555} 6556int sendWordBoundaryEvent(int eventType, int movement, int offset, int newOffset, String lineText, int lineOffset) { 6557 if (isListening(eventType)) { 6558 StyledTextEvent event = new StyledTextEvent(content); 6559 event.detail = lineOffset; 6560 event.text = lineText; 6561 event.count = movement; 6562 event.start = offset; 6563 event.end = newOffset; 6564 notifyListeners(eventType, event); 6565 offset = event.end; 6566 if (offset != newOffset) { 6567 int length = getCharCount(); 6568 if (offset < 0) { 6569 offset = 0; 6570 } else if (offset > length) { 6571 offset = length; 6572 } else { 6573 if (isLineDelimiter(offset)) { 6574 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 6575 } 6576 } 6577 } 6578 return offset; 6579 } 6580 return newOffset; 6581} 6582 6597public void setAlignment(int alignment) { 6598 checkWidget(); 6599 alignment &= (SWT.LEFT | SWT.RIGHT | SWT.CENTER); 6600 if (alignment == 0 || this.alignment == alignment) return; 6601 this.alignment = alignment; 6602 resetCache(0, content.getLineCount()); 6603 setCaretLocation(); 6604 super.redraw(); 6605} 6606 6609public void setBackground(Color color) { 6610 checkWidget(); 6611 background = color; 6612 super.redraw(); 6613} 6614 6625public void setCaret(Caret caret) { 6626 checkWidget (); 6627 super.setCaret(caret); 6628 caretDirection = SWT.NULL; 6629 if (caret != null) { 6630 setCaretLocation(); 6631 } 6632} 6633 6646public void setBidiColoring(boolean mode) { 6647 checkWidget(); 6648 bidiColoring = mode; 6649} 6650 6653void setCaretLocation() { 6654 Point newCaretPos = getPointAtOffset(caretOffset); 6655 setCaretLocation(newCaretPos, getCaretDirection()); 6656} 6657void setCaretLocation(Point location, int direction) { 6658 Caret caret = getCaret(); 6659 if (caret != null) { 6660 boolean isDefaultCaret = caret == defaultCaret; 6661 int lineHeight = renderer.getLineHeight(); 6662 int caretHeight = lineHeight; 6663 if (!isFixedLineHeight() && isDefaultCaret) { 6664 caretHeight = getBoundsAtOffset(caretOffset).height; 6665 if (caretHeight != lineHeight) { 6666 direction = SWT.DEFAULT; 6667 } 6668 } 6669 int imageDirection = direction; 6670 if (isMirrored()) { 6671 if (imageDirection == SWT.LEFT) { 6672 imageDirection = SWT.RIGHT; 6673 } else if (imageDirection == SWT.RIGHT) { 6674 imageDirection = SWT.LEFT; 6675 } 6676 } 6677 if (isDefaultCaret && imageDirection == SWT.RIGHT) { 6678 location.x -= (caret.getSize().x - 1); 6679 } 6680 if (isDefaultCaret) { 6681 caret.setBounds(location.x, location.y, 0, caretHeight); 6682 } else { 6683 caret.setLocation(location); 6684 } 6685 getAccessible().textCaretMoved(getCaretOffset()); 6686 if (direction != caretDirection) { 6687 caretDirection = direction; 6688 if (isDefaultCaret) { 6689 if (imageDirection == SWT.DEFAULT) { 6690 defaultCaret.setImage(null); 6691 } else if (imageDirection == SWT.LEFT) { 6692 defaultCaret.setImage(leftCaretBitmap); 6693 } else if (imageDirection == SWT.RIGHT) { 6694 defaultCaret.setImage(rightCaretBitmap); 6695 } 6696 } 6697 if (caretDirection == SWT.LEFT) { 6698 BidiUtil.setKeyboardLanguage(BidiUtil.KEYBOARD_NON_BIDI); 6699 } else if (caretDirection == SWT.RIGHT) { 6700 BidiUtil.setKeyboardLanguage(BidiUtil.KEYBOARD_BIDI); 6701 } 6702 } 6703 } 6704 columnX = location.x; 6705} 6706 6719public void setCaretOffset(int offset) { 6720 checkWidget(); 6721 int length = getCharCount(); 6722 if (length > 0 && offset != caretOffset) { 6723 if (offset < 0) { 6724 caretOffset = 0; 6725 } else if (offset > length) { 6726 caretOffset = length; 6727 } else { 6728 if (isLineDelimiter(offset)) { 6729 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 6732 } 6733 caretOffset = offset; 6734 } 6735 clearSelection(false); 6738 } 6739 setCaretLocation(); 6740} 6741 6751void setClipboardContent(int start, int length, int clipboardType) throws SWTError { 6752 if (clipboardType == DND.SELECTION_CLIPBOARD && !(IS_MOTIF || IS_GTK)) return; 6753 TextTransfer plainTextTransfer = TextTransfer.getInstance(); 6754 TextWriter plainTextWriter = new TextWriter(start, length); 6755 String plainText = getPlatformDelimitedText(plainTextWriter); 6756 Object [] data; 6757 Transfer[] types; 6758 if (clipboardType == DND.SELECTION_CLIPBOARD) { 6759 data = new Object []{plainText}; 6760 types = new Transfer[]{plainTextTransfer}; 6761 } else { 6762 RTFTransfer rtfTransfer = RTFTransfer.getInstance(); 6763 RTFWriter rtfWriter = new RTFWriter(start, length); 6764 String rtfText = getPlatformDelimitedText(rtfWriter); 6765 data = new Object []{rtfText, plainText}; 6766 types = new Transfer[]{rtfTransfer, plainTextTransfer}; 6767 } 6768 clipboard.setContents(data, types, clipboardType); 6769} 6770 6782public void setContent(StyledTextContent newContent) { 6783 checkWidget(); 6784 if (newContent == null) { 6785 SWT.error(SWT.ERROR_NULL_ARGUMENT); 6786 } 6787 if (content != null) { 6788 content.removeTextChangeListener(textChangeListener); 6789 } 6790 content = newContent; 6791 content.addTextChangeListener(textChangeListener); 6792 reset(); 6793} 6794 6801public void setCursor (Cursor cursor) { 6802 if (cursor == null) { 6803 Display display = getDisplay(); 6804 super.setCursor(display.getSystemCursor(SWT.CURSOR_IBEAM)); 6805 } else { 6806 super.setCursor(cursor); 6807 } 6808} 6809 6820public void setDoubleClickEnabled(boolean enable) { 6821 checkWidget(); 6822 doubleClickEnabled = enable; 6823} 6824public void setDragDetect (boolean dragDetect) { 6825 checkWidget (); 6826 this.dragDetect = dragDetect; 6827} 6828 6839public void setEditable(boolean editable) { 6840 checkWidget(); 6841 this.editable = editable; 6842} 6843 6856public void setFont(Font font) { 6857 checkWidget(); 6858 int oldLineHeight = renderer.getLineHeight(); 6859 super.setFont(font); 6860 renderer.setFont(getFont(), tabLength); 6861 if (isFixedLineHeight()) { 6863 int lineHeight = renderer.getLineHeight(); 6864 if (lineHeight != oldLineHeight) { 6865 int vscroll = (getVerticalScrollOffset() * lineHeight / oldLineHeight) - getVerticalScrollOffset(); 6866 scrollVertical(vscroll, true); 6867 } 6868 } 6869 resetCache(0, content.getLineCount()); 6870 claimBottomFreeSpace(); 6871 calculateScrollBars(); 6872 if (isBidiCaret()) createCaretBitmaps(); 6873 caretDirection = SWT.NULL; 6874 setCaretLocation(); 6875 super.redraw(); 6876} 6877 6880public void setForeground(Color color) { 6881 checkWidget(); 6882 foreground = color; 6883 super.setForeground(getForeground()); 6884 super.redraw(); 6885} 6886 6902public void setHorizontalIndex(int offset) { 6903 checkWidget(); 6904 if (getCharCount() == 0) { 6905 return; 6906 } 6907 if (offset < 0) { 6908 offset = 0; 6909 } 6910 offset *= getHorizontalIncrement(); 6911 if (clientAreaWidth > 0) { 6916 int width = renderer.getWidth(); 6917 if (offset > width - clientAreaWidth) { 6921 offset = Math.max(0, width - clientAreaWidth); 6922 } 6923 } 6924 scrollHorizontal(offset - horizontalScrollOffset, true); 6925} 6926 6942public void setHorizontalPixel(int pixel) { 6943 checkWidget(); 6944 if (getCharCount() == 0) { 6945 return; 6946 } 6947 if (pixel < 0) { 6948 pixel = 0; 6949 } 6950 if (clientAreaWidth > 0) { 6955 int width = renderer.getWidth(); 6956 if (pixel > width - clientAreaWidth) { 6960 pixel = Math.max(0, width - clientAreaWidth); 6961 } 6962 } 6963 scrollHorizontal(pixel - horizontalScrollOffset, true); 6964} 6965 6983public void setIndent(int indent) { 6984 checkWidget(); 6985 if (this.indent == indent || indent < 0) return; 6986 this.indent = indent; 6987 resetCache(0, content.getLineCount()); 6988 setCaretLocation(); 6989 super.redraw(); 6990} 6991 7005public void setJustify(boolean justify) { 7006 checkWidget(); 7007 if (this.justify == justify) return; 7008 this.justify = justify; 7009 resetCache(0, content.getLineCount()); 7010 setCaretLocation(); 7011 super.redraw(); 7012} 7013 7032public void setKeyBinding(int key, int action) { 7033 checkWidget(); 7034 int modifierValue = key & SWT.MODIFIER_MASK; 7035 char keyChar = (char)(key & SWT.KEY_MASK); 7036 if (Compatibility.isLetter(keyChar)) { 7037 char ch = Character.toUpperCase(keyChar); 7040 int newKey = ch | modifierValue; 7041 if (action == SWT.NULL) { 7042 keyActionMap.remove(new Integer (newKey)); 7043 } else { 7044 keyActionMap.put(new Integer (newKey), new Integer (action)); 7045 } 7046 ch = Character.toLowerCase(keyChar); 7047 newKey = ch | modifierValue; 7048 if (action == SWT.NULL) { 7049 keyActionMap.remove(new Integer (newKey)); 7050 } else { 7051 keyActionMap.put(new Integer (newKey), new Integer (action)); 7052 } 7053 } else { 7054 if (action == SWT.NULL) { 7055 keyActionMap.remove(new Integer (key)); 7056 } else { 7057 keyActionMap.put(new Integer (key), new Integer (action)); 7058 } 7059 } 7060} 7061 7094public void setLineAlignment(int startLine, int lineCount, int alignment) { 7095 checkWidget(); 7096 if (isListening(LineGetStyle)) return; 7097 if (startLine < 0 || startLine + lineCount > content.getLineCount()) { 7098 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7099 } 7100 7101 renderer.setLineAlignment(startLine, lineCount, alignment); 7102 resetCache(startLine, lineCount); 7103 redrawLines(startLine, lineCount); 7104 int caretLine = getCaretLine(); 7105 if (startLine <= caretLine && caretLine < startLine + lineCount) { 7106 setCaretLocation(); 7107 } 7108} 7109 7144public void setLineBackground(int startLine, int lineCount, Color background) { 7145 checkWidget(); 7146 if (isListening(LineGetBackground)) return; 7147 if (startLine < 0 || startLine + lineCount > content.getLineCount()) { 7148 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7149 } 7150 if (background != null) { 7151 renderer.setLineBackground(startLine, lineCount, background); 7152 } else { 7153 renderer.clearLineBackground(startLine, lineCount); 7154 } 7155 redrawLines(startLine, lineCount); 7156} 7157 7189public void setLineBullet(int startLine, int lineCount, Bullet bullet) { 7190 checkWidget(); 7191 if (isListening(LineGetStyle)) return; 7192 if (startLine < 0 || startLine + lineCount > content.getLineCount()) { 7193 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7194 } 7195 7196 renderer.setLineBullet(startLine, lineCount, bullet); 7197 resetCache(startLine, lineCount); 7198 redrawLines(startLine, lineCount); 7199 int caretLine = getCaretLine(); 7200 if (startLine <= caretLine && caretLine < startLine + lineCount) { 7201 setCaretLocation(); 7202 } 7203} 7204void setVariableLineHeight () { 7205 if (!fixedLineHeight) return; 7206 fixedLineHeight = false; 7207 renderer.calculateIdle(); 7208} 7209 7242public void setLineIndent(int startLine, int lineCount, int indent) { 7243 checkWidget(); 7244 if (isListening(LineGetStyle)) return; 7245 if (startLine < 0 || startLine + lineCount > content.getLineCount()) { 7246 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7247 } 7248 7249 renderer.setLineIndent(startLine, lineCount, indent); 7250 resetCache(startLine, lineCount); 7251 redrawLines(startLine, lineCount); 7252 int caretLine = getCaretLine(); 7253 if (startLine <= caretLine && caretLine < startLine + lineCount) { 7254 setCaretLocation(); 7255 } 7256} 7257 7290public void setLineJustify(int startLine, int lineCount, boolean justify) { 7291 checkWidget(); 7292 if (isListening(LineGetStyle)) return; 7293 if (startLine < 0 || startLine + lineCount > content.getLineCount()) { 7294 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7295 } 7296 7297 renderer.setLineJustify(startLine, lineCount, justify); 7298 resetCache(startLine, lineCount); 7299 redrawLines(startLine, lineCount); 7300 int caretLine = getCaretLine(); 7301 if (startLine <= caretLine && caretLine < startLine + lineCount) { 7302 setCaretLocation(); 7303 } 7304} 7305 7315public void setLineSpacing(int lineSpacing) { 7316 checkWidget(); 7317 if (this.lineSpacing == lineSpacing || lineSpacing < 0) return; 7318 this.lineSpacing = lineSpacing; 7319 setVariableLineHeight(); 7320 resetCache(0, content.getLineCount()); 7321 setCaretLocation(); 7322 super.redraw(); 7323} 7324void setMargins (int leftMargin, int topMargin, int rightMargin, int bottomMargin) { 7325 checkWidget(); 7326 this.leftMargin = leftMargin; 7327 this.topMargin = topMargin; 7328 this.rightMargin = rightMargin; 7329 this.bottomMargin = bottomMargin; 7330 setCaretLocation(); 7331} 7332 7335void setMouseWordSelectionAnchor() { 7336 if (clickCount > 1) { 7337 if (caretOffset < doubleClickSelection.x) { 7338 selectionAnchor = doubleClickSelection.y; 7339 } else if (caretOffset > doubleClickSelection.y) { 7340 selectionAnchor = doubleClickSelection.x; 7341 } 7342 } 7343} 7344 7357public void setOrientation(int orientation) { 7358 if ((orientation & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT)) == 0) { 7359 return; 7360 } 7361 if ((orientation & SWT.RIGHT_TO_LEFT) != 0 && (orientation & SWT.LEFT_TO_RIGHT) != 0) { 7362 return; 7363 } 7364 if ((orientation & SWT.RIGHT_TO_LEFT) != 0 && isMirrored()) { 7365 return; 7366 } 7367 if ((orientation & SWT.LEFT_TO_RIGHT) != 0 && !isMirrored()) { 7368 return; 7369 } 7370 if (!BidiUtil.setOrientation(handle, orientation)) { 7371 return; 7372 } 7373 isMirrored = (orientation & SWT.RIGHT_TO_LEFT) != 0; 7374 caretDirection = SWT.NULL; 7375 resetCache(0, content.getLineCount()); 7376 setCaretLocation(); 7377 keyActionMap.clear(); 7378 createKeyBindings(); 7379 super.redraw(); 7380} 7381 7387void setScrollBars(boolean vertical) { 7388 int inactive = 1; 7389 if (vertical || !isFixedLineHeight()) { 7390 ScrollBar verticalBar = getVerticalBar(); 7391 if (verticalBar != null) { 7392 int maximum = renderer.getHeight(); 7393 if (clientAreaHeight < maximum) { 7397 verticalBar.setMaximum(maximum); 7398 verticalBar.setThumb(clientAreaHeight); 7399 verticalBar.setPageIncrement(clientAreaHeight); 7400 } else if (verticalBar.getThumb() != inactive || verticalBar.getMaximum() != inactive) { 7401 verticalBar.setValues( 7402 verticalBar.getSelection(), 7403 verticalBar.getMinimum(), 7404 inactive, 7405 inactive, 7406 verticalBar.getIncrement(), 7407 inactive); 7408 } 7409 } 7410 } 7411 ScrollBar horizontalBar = getHorizontalBar(); 7412 if (horizontalBar != null && horizontalBar.getVisible()) { 7413 int maximum = renderer.getWidth(); 7414 if (clientAreaWidth < maximum) { 7418 horizontalBar.setMaximum(maximum); 7419 horizontalBar.setThumb(clientAreaWidth - leftMargin - rightMargin); 7420 horizontalBar.setPageIncrement(clientAreaWidth - leftMargin - rightMargin); 7421 } else if (horizontalBar.getThumb() != inactive || horizontalBar.getMaximum() != inactive) { 7422 horizontalBar.setValues( 7423 horizontalBar.getSelection(), 7424 horizontalBar.getMinimum(), 7425 inactive, 7426 inactive, 7427 horizontalBar.getIncrement(), 7428 inactive); 7429 } 7430 } 7431} 7432 7446public void setSelection(int start) { 7447 setSelection(start, start); 7449} 7450 7471public void setSelection(Point point) { 7472 checkWidget(); 7473 if (point == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 7474 setSelection(point.x, point.y); 7475} 7476 7492public void setSelectionBackground (Color color) { 7493 checkWidget (); 7494 if (color != null) { 7495 if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7496 } 7497 selectionBackground = color; 7498 super.redraw(); 7499} 7500 7519public void setSelectionForeground (Color color) { 7520 checkWidget (); 7521 if (color != null) { 7522 if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7523 } 7524 selectionForeground = color; 7525 super.redraw(); 7526} 7527 7548public void setSelection(int start, int end) { 7549 setSelectionRange(start, end - start); 7550 showSelection(); 7551} 7552 7566void setSelection(int start, int length, boolean sendEvent) { 7567 int end = start + length; 7568 if (start > end) { 7569 int temp = end; 7570 end = start; 7571 start = temp; 7572 } 7573 if (selection.x != start || selection.y != end || 7576 (length > 0 && selectionAnchor != selection.x) || 7577 (length < 0 && selectionAnchor != selection.y)) { 7578 clearSelection(sendEvent); 7579 if (length < 0) { 7580 selectionAnchor = selection.y = end; 7581 caretOffset = selection.x = start; 7582 } else { 7583 selectionAnchor = selection.x = start; 7584 caretOffset = selection.y = end; 7585 } 7586 internalRedrawRange(selection.x, selection.y - selection.x); 7587 } 7588} 7589 7608public void setSelectionRange(int start, int length) { 7609 checkWidget(); 7610 int contentLength = getCharCount(); 7611 start = Math.max(0, Math.min (start, contentLength)); 7612 int end = start + length; 7613 if (end < 0) { 7614 length = -start; 7615 } else { 7616 if (end > contentLength) length = contentLength - start; 7617 } 7618 if (isLineDelimiter(start) || isLineDelimiter(start + length)) { 7619 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7623 } 7624 setSelection(start, length, false); 7625 setCaretLocation(); 7626} 7627 7650public void setStyleRange(StyleRange range) { 7651 checkWidget(); 7652 if (isListening(LineGetStyle)) return; 7653 if (range != null) { 7654 if (range.isUnstyled()) { 7655 setStyleRanges(range.start, range.length, null, null, false); 7656 } else { 7657 setStyleRanges(range.start, 0, null, new StyleRange[]{range}, false); 7658 } 7659 } else { 7660 setStyleRanges(0, 0, null, null, true); 7661 } 7662} 7663 7698public void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles) { 7699 checkWidget(); 7700 if (isListening(LineGetStyle)) return; 7701 if (ranges == null || styles == null) { 7702 setStyleRanges(start, length, null, null, false); 7703 } else { 7704 setStyleRanges(start, length, ranges, styles, false); 7705 } 7706} 7707 7740public void setStyleRanges(int[] ranges, StyleRange[] styles) { 7741 checkWidget(); 7742 if (isListening(LineGetStyle)) return; 7743 if (ranges == null || styles == null) { 7744 setStyleRanges(0, 0, null, null, true); 7745 } else { 7746 setStyleRanges(0, 0, ranges, styles, true); 7747 } 7748} 7749void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, boolean reset) { 7750 int charCount = content.getCharCount(); 7751 int end = start + length; 7752 if (start > end || start < 0) { 7753 SWT.error(SWT.ERROR_INVALID_RANGE); 7754 } 7755 if (styles != null) { 7756 if (end > charCount) { 7757 SWT.error(SWT.ERROR_INVALID_RANGE); 7758 } 7759 if (ranges != null) { 7760 if (ranges.length != styles.length << 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7761 } 7762 int lastOffset = 0; 7763 boolean variableHeight = false; 7764 for (int i = 0; i < styles.length; i ++) { 7765 if (styles[i] == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7766 int rangeStart, rangeLength; 7767 if (ranges != null) { 7768 rangeStart = ranges[i << 1]; 7769 rangeLength = ranges[(i << 1) + 1]; 7770 } else { 7771 rangeStart = styles[i].start; 7772 rangeLength = styles[i].length; 7773 } 7774 if (rangeLength < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7775 if (!(0 <= rangeStart && rangeStart + rangeLength <= charCount)) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7776 if (lastOffset > rangeStart) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 7777 variableHeight |= styles[i].isVariableHeight(); 7778 lastOffset = rangeStart + rangeLength; 7779 } 7780 if (variableHeight) setVariableLineHeight(); 7781 } 7782 int rangeStart = start, rangeEnd = end; 7783 if (styles != null && styles.length > 0) { 7784 if (ranges != null) { 7785 rangeStart = ranges[0]; 7786 rangeEnd = ranges[ranges.length - 2] + ranges[ranges.length - 1]; 7787 } else { 7788 rangeStart = styles[0].start; 7789 rangeEnd = styles[styles.length - 1].start + styles[styles.length - 1].length; 7790 } 7791 } 7792 int lastLineBottom = 0; 7793 if (!isFixedLineHeight() && !reset) { 7794 int lineEnd = content.getLineAtOffset(Math.max(end, rangeEnd)); 7795 int partialTopIndex = getPartialTopIndex(); 7796 int partialBottomIndex = getPartialBottomIndex(); 7797 if (partialTopIndex <= lineEnd && lineEnd <= partialBottomIndex) { 7798 lastLineBottom = getLinePixel(lineEnd + 1); 7799 } 7800 } 7801 if (reset) { 7802 renderer.setStyleRanges(null, null); 7803 } else { 7804 renderer.updateRanges(start, length, length); 7805 } 7806 if (styles != null && styles.length > 0) { 7807 renderer.setStyleRanges(ranges, styles); 7808 } 7809 if (reset) { 7810 resetCache(0, content.getLineCount()); 7811 super.redraw(); 7812 } else { 7813 int lineStart = content.getLineAtOffset(Math.min(start, rangeStart)); 7814 int lineEnd = content.getLineAtOffset(Math.max(end, rangeEnd)); 7815 resetCache(lineStart, lineEnd - lineStart + 1); 7816 int partialTopIndex = getPartialTopIndex(); 7817 int partialBottomIndex = getPartialBottomIndex(); 7818 if (!(lineStart > partialBottomIndex || lineEnd < partialTopIndex)) { 7819 int y = 0; 7820 int height = clientAreaHeight; 7821 if (partialTopIndex <= lineStart && lineStart <= partialBottomIndex) { 7822 int lineTop = Math.max(y, getLinePixel(lineStart)); 7823 y = lineTop; 7824 height -= lineTop; 7825 } 7826 if (partialTopIndex <= lineEnd && lineEnd <= partialBottomIndex) { 7827 int newLastLineBottom = getLinePixel(lineEnd + 1); 7828 if (!isFixedLineHeight()) { 7829 scrollText(lastLineBottom, newLastLineBottom); 7830 } 7831 height = newLastLineBottom - y; 7832 } 7833 super.redraw(0, y, clientAreaWidth, height, false); 7834 } 7835 } 7836 setCaretLocation(); 7837} 7838 7866public void setStyleRanges(StyleRange[] ranges) { 7867 checkWidget(); 7868 if (isListening(LineGetStyle)) return; 7869 if (ranges == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 7870 setStyleRanges(0, 0, null, ranges, true); 7871} 7872 7881public void setTabs(int tabs) { 7882 checkWidget(); 7883 tabLength = tabs; 7884 renderer.setFont(null, tabs); 7885 if (caretOffset > 0) { 7886 caretOffset = 0; 7887 showCaret(); 7888 clearSelection(false); 7889 } 7890 resetCache(0, content.getLineCount()); 7891 super.redraw(); 7892} 7893 7915public void setText(String text) { 7916 checkWidget(); 7917 if (text == null) { 7918 SWT.error(SWT.ERROR_NULL_ARGUMENT); 7919 } 7920 Event event = new Event(); 7921 event.start = 0; 7922 event.end = getCharCount(); 7923 event.text = text; 7924 event.doit = true; 7925 notifyListeners(SWT.Verify, event); 7926 if (event.doit) { 7927 StyledTextEvent styledTextEvent = null; 7928 if (isListening(ExtendedModify)) { 7929 styledTextEvent = new StyledTextEvent(content); 7930 styledTextEvent.start = event.start; 7931 styledTextEvent.end = event.start + event.text.length(); 7932 styledTextEvent.text = content.getTextRange(event.start, event.end - event.start); 7933 } 7934 content.setText(event.text); 7935 sendModifyEvent(event); 7936 if (styledTextEvent != null) { 7937 notifyListeners(ExtendedModify, styledTextEvent); 7938 } 7939 } 7940} 7941 7957public void setTextLimit(int limit) { 7958 checkWidget(); 7959 if (limit == 0) { 7960 SWT.error(SWT.ERROR_CANNOT_BE_ZERO); 7961 } 7962 textLimit = limit; 7963} 7964 7982public void setTopIndex(int topIndex) { 7983 checkWidget(); 7984 if (getCharCount() == 0) { 7985 return; 7986 } 7987 int lineCount = content.getLineCount(), pixel; 7988 if (isFixedLineHeight()) { 7989 int pageSize = Math.max(1, Math.min(lineCount, getLineCountWhole())); 7990 if (topIndex < 0) { 7991 topIndex = 0; 7992 } else if (topIndex > lineCount - pageSize) { 7993 topIndex = lineCount - pageSize; 7994 } 7995 pixel = getLinePixel(topIndex); 7996 } else { 7997 topIndex = Math.max(0, Math.min(lineCount - 1, topIndex)); 7998 pixel = getLinePixel(topIndex); 7999 if (pixel > 0) { 8000 pixel = getAvailableHeightBellow(pixel); 8001 } else { 8002 pixel = getAvailableHeightAbove(pixel); 8003 } 8004 } 8005 scrollVertical(pixel, true); 8006} 8007 8025public void setTopPixel(int pixel) { 8026 checkWidget(); 8027 if (getCharCount() == 0) { 8028 return; 8029 } 8030 if (pixel < 0) pixel = 0; 8031 int lineCount = content.getLineCount(); 8032 int height = clientAreaHeight - topMargin - bottomMargin; 8033 int verticalOffset = getVerticalScrollOffset(); 8034 if (isFixedLineHeight()) { 8035 int maxTopPixel = Math.max(0, lineCount * getVerticalIncrement() - height); 8036 if (pixel > maxTopPixel) pixel = maxTopPixel; 8037 pixel -= verticalOffset; 8038 } else { 8039 pixel -= verticalOffset; 8040 if (pixel > 0) { 8041 pixel = getAvailableHeightBellow(pixel); 8042 } 8043 } 8044 scrollVertical(pixel, true); 8045} 8046 8055public void setWordWrap(boolean wrap) { 8056 checkWidget(); 8057 if ((getStyle() & SWT.SINGLE) != 0) return; 8058 if (wordWrap == wrap) return; 8059 wordWrap = wrap; 8060 setVariableLineHeight(); 8061 resetCache(0, content.getLineCount()); 8062 horizontalScrollOffset = 0; 8063 ScrollBar horizontalBar = getHorizontalBar(); 8064 if (horizontalBar != null) { 8065 horizontalBar.setVisible(!wordWrap); 8066 } 8067 setScrollBars(true); 8068 setCaretLocation(); 8069 super.redraw(); 8070} 8071boolean showLocation(Rectangle rect, boolean scrollPage) { 8072 int clientAreaWidth = this.clientAreaWidth - leftMargin - rightMargin; 8073 int clientAreaHeight = this.clientAreaHeight - topMargin - bottomMargin; 8074 boolean scrolled = false; 8075 if (rect.y <= topMargin) { 8076 scrolled = scrollVertical(rect.y - topMargin, true); 8077 } else if (rect.y + rect.height > clientAreaHeight) { 8078 if (clientAreaHeight == 0) { 8079 scrolled = scrollVertical(rect.y, true); 8080 } else { 8081 scrolled = scrollVertical(rect.y + rect.height - clientAreaHeight, true); 8082 } 8083 } 8084 if (clientAreaWidth > 0) { 8085 int minScroll = scrollPage ? clientAreaWidth / 4 : 0; 8086 if (rect.x < leftMargin) { 8087 int scrollWidth = Math.max(leftMargin - rect.x, minScroll); 8088 int maxScroll = horizontalScrollOffset; 8089 scrolled = scrollHorizontal(-Math.min(maxScroll, scrollWidth), true); 8090 } else if (rect.x + rect.width > clientAreaWidth) { 8091 int scrollWidth = Math.max(rect.x + rect.width - clientAreaWidth, minScroll); 8092 int maxScroll = renderer.getWidth() - horizontalScrollOffset - this.clientAreaWidth; 8093 scrolled = scrollHorizontal(Math.min(maxScroll, scrollWidth), true); 8094 } 8095 } 8096 return scrolled; 8097} 8098 8101void showCaret() { 8102 Rectangle bounds = getBoundsAtOffset(caretOffset); 8103 if (!showLocation(bounds, true)) { 8104 setCaretLocation(); 8105 } 8106} 8107 8120public void showSelection() { 8121 checkWidget(); 8122 boolean rightToLeft = caretOffset == selection.x; 8124 int startOffset, endOffset; 8125 if (rightToLeft) { 8126 startOffset = selection.y; 8127 endOffset = selection.x; 8128 } else { 8129 startOffset = selection.x; 8130 endOffset = selection.y; 8131 } 8132 8133 Rectangle startBounds = getBoundsAtOffset(startOffset); 8134 Rectangle endBounds = getBoundsAtOffset(endOffset); 8135 8136 int w = clientAreaWidth - leftMargin - rightMargin; 8138 boolean selectionFits = rightToLeft ? startBounds.x - endBounds.x <= w : endBounds.x - startBounds.x <= w; 8139 if (selectionFits) { 8140 if (showLocation(startBounds, false)) { 8143 endBounds = getBoundsAtOffset(endOffset); 8145 } 8146 endBounds.width = 0; 8148 showLocation(endBounds, false); 8149 } else { 8150 showLocation(endBounds, true); 8153 } 8154} 8155 8169void updateSelection(int startOffset, int replacedLength, int newLength) { 8170 if (selection.y <= startOffset) { 8171 return; 8173 } 8174 if (selection.x < startOffset) { 8175 internalRedrawRange(selection.x, startOffset - selection.x); 8177 } 8178 if (selection.y > startOffset + replacedLength && selection.x < startOffset + replacedLength) { 8179 int netNewLength = newLength - replacedLength; 8183 int redrawStart = startOffset + newLength; 8184 internalRedrawRange(redrawStart, selection.y + netNewLength - redrawStart); 8185 } 8186 if (selection.y > startOffset && selection.x < startOffset + replacedLength) { 8187 setSelection(startOffset + newLength, 0, true); 8189 } else { 8190 setSelection(selection.x + newLength - replacedLength, selection.y - selection.x, true); 8192 } 8193 setCaretLocation(); 8194} 8195} 8196 | Popular Tags |