/** * Creates content change listeners and set the default content model. */ void installDefaultContent() { textChangeListener = new TextChangeListener() { public void textChanging(TextChangingEvent event) { handleTextChanging(event); } public void textChanged(TextChangedEvent event) { handleTextChanged(event); } public void textSet(TextChangedEvent event) { handleTextSet(event); } }; content = new DefaultContent(); content.addTextChangeListener(textChangeListener); } /**
/** * Returns whether the given offset is inside a multi byte line delimiter. * Example: * "Line1\r\n" isLineDelimiter(5) == false but isLineDelimiter(6) == true * * @return true if the given offset is inside a multi byte line delimiter. * false if the given offset is before or after a line delimiter. */ boolean isLineDelimiter(int offset) { int line = content.getLineAtOffset(offset); int lineOffset = content.getOffsetAtLine(line); int offsetInLine = offset - lineOffset; // offsetInLine will be greater than line length if the line // delimiter is longer than one character and the offset is set // in between parts of the line delimiter. return offsetInLine > content.getLine(line).length(); } /**
/** * Copies the text of the specified <code>StyledTextContent</code>. * </p> * @param original the <code>StyledTextContent</code> to copy. */ StyledTextContent copyContent(StyledTextContent original) { StyledTextContent printerContent = new DefaultContent(); int insertOffset = 0; for (int i = 0; i < original.getLineCount(); i++) { int insertEndOffset; if (i < original.getLineCount() - 1) { insertEndOffset = original.getOffsetAtLine(i + 1); } else { insertEndOffset = original.getCharCount(); } printerContent.replaceTextRange(insertOffset, 0, original.getTextRange(insertOffset, insertEndOffset - insertOffset)); insertOffset = insertEndOffset; } return printerContent; } /**
/** * Returns the selected text. * * @return selected text, or an empty String if there is no selection. * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public String getSelectionText() { checkWidget(); if (blockSelection && blockXLocation != -1) { return getBlockSelectionText(content.getLineDelimiter()); } return content.getTextRange(selection.x, selection.y - selection.x); } StyledTextEvent getBidiSegments(int lineOffset, String line) {
void handleCompositionChanged(Event event) { String text = event.text; int start = event.start; int end = event.end; int charCount = content.getCharCount(); start = Math.min(start, charCount); end = Math.min(end, charCount); int length = text.length(); if (length == ime.getCommitCount()) { content.replaceTextRange(start, end - start, ""); setCaretOffset(ime.getCompositionOffset(), SWT.DEFAULT); caretWidth = 0; caretDirection = SWT.NULL; } else { content.replaceTextRange(start, end - start, text); int alignment = SWT.DEFAULT; if (ime.getWideCaret()) { start = ime.getCompositionOffset(); int lineIndex = getCaretLine(); int lineOffset = content.getOffsetAtLine(lineIndex); TextLayout layout = renderer.getTextLayout(lineIndex); caretWidth = layout.getBounds(start - lineOffset, start + length - 1 - lineOffset).width; renderer.disposeTextLayout(layout); alignment = OFFSET_LEADING; } setCaretOffset(ime.getCaretOffset(), alignment); } showCaret(); } /**
/** * Deletes the next character. Delete the selected text if any. */ void doDelete() { Event event = new Event(); event.text = ""; if (selection.x != selection.y) { event.start = selection.x; event.end = selection.y; sendKeyEvent(event); } else if (caretOffset < content.getCharCount()) { int line = content.getLineAtOffset(caretOffset); int lineOffset = content.getOffsetAtLine(line); int lineLength = content.getLine(line).length(); if (caretOffset == lineOffset + lineLength) { event.start = caretOffset; event.end = content.getOffsetAtLine(line + 1); } else { event.start = caretOffset; event.end = getClusterNext(caretOffset, line); } sendKeyEvent(event); } } /**
int getWordNext (int offset, int movement, boolean ignoreListener) { int newOffset, lineOffset; String lineText; if (offset >= getCharCount()) { newOffset = offset; int lineIndex = content.getLineCount() - 1; lineOffset = content.getOffsetAtLine(lineIndex); lineText = content.getLine(lineIndex); } else { int lineIndex = content.getLineAtOffset(offset); lineOffset = content.getOffsetAtLine(lineIndex); lineText = content.getLine(lineIndex); int lineLength = lineText.length(); if (offset >= lineOffset + lineLength) { newOffset = content.getOffsetAtLine(lineIndex + 1); } else { TextLayout layout = renderer.getTextLayout(lineIndex); newOffset = lineOffset + layout.getNextOffset(offset - lineOffset, movement); renderer.disposeTextLayout(layout); } } if (ignoreListener) return newOffset; return sendWordBoundaryEvent(ST.WordNext, movement, offset, newOffset, lineText, lineOffset); } int getWordPrevious(int offset, int movement) {
/** * Sets the content implementation to use for text storage. * * @param newContent StyledTextContent implementation to use for text storage. * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT when listener is null</li> * </ul> */ public void setContent(StyledTextContent newContent) { checkWidget(); if (newContent == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); } if (content != null) { content.removeTextChangeListener(textChangeListener); } content = newContent; content.addTextChangeListener(textChangeListener); reset(); } /**
int getClusterPrevious(int offset, int lineIndex) { int lineOffset = content.getOffsetAtLine(lineIndex); TextLayout layout = renderer.getTextLayout(lineIndex); offset -= lineOffset; offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_CLUSTER); offset += lineOffset; renderer.disposeTextLayout(layout); return offset; } /**
/** * Gets the number of characters. * * @return number of characters in the widget * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public int getCharCount() { checkWidget(); return content.getCharCount(); } /**
void setContent(StyledTextContent content) { reset(); this.content = content; lineCount = content.getLineCount(); lineWidth = new int[lineCount]; lineHeight = new int[lineCount]; maxWidth = 0; maxWidthLineIndex = -1; reset(0, lineCount); } void setFont(Font font, int tabs) {
int getCaretLine() { return content.getLineAtOffset(caretOffset); } int getWrapWidth () {
/** * Moves the caret to the end of the line. */ void doLineEnd() { int caretLine = getCaretLine(); int lineOffset = content.getOffsetAtLine(caretLine); int lineEndOffset; if (wordWrap || visualWrap) { TextLayout layout = renderer.getTextLayout(caretLine); int offsetInLine = caretOffset - lineOffset; int lineIndex = getVisualLineIndex(layout, offsetInLine); int[] offsets = layout.getLineOffsets(); lineEndOffset = lineOffset + offsets[lineIndex + 1]; renderer.disposeTextLayout(layout); } else { int lineLength = content.getLine(caretLine).length(); lineEndOffset = lineOffset + lineLength; } setCaretOffset(lineEndOffset, PREVIOUS_OFFSET_TRAILING); showCaret(); } /**
/** * Returns the line delimiter used for entering new lines by key down * or paste operation. * * @return line delimiter used for entering new lines by key down * or paste operation. * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public String getLineDelimiter() { checkWidget(); return content.getLineDelimiter(); } /**
/** * Returns a copy of the widget content. * * @return copy of the widget content * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public String getText() { checkWidget(); return content.getTextRange(0, getCharCount()); } /**
@Override public void uninstall(AbstractThemedScrollBarAdapter abstractThemedScrollBarAdapter, boolean disposing) { super.uninstall(abstractThemedScrollBarAdapter, disposing); fStyledText.removeModifyListener(this); if (fTextContent != null) { fTextContent.removeTextChangeListener(this); fTextContent = null; } this.fAbstractThemedScrollBarAdapter = null; }
int getHeight () { int defaultLineHeight = getLineHeight(); if (styledText.isFixedLineHeight()) { return lineCount * defaultLineHeight + styledText.topMargin + styledText.bottomMargin; } int totalHeight = 0; int width = styledText.getWrapWidth(); for (int i = 0; i < lineCount; i++) { int height = lineHeight[i]; if (height == -1) { if (width > 0) { int length = content.getLine(i).length(); height = ((length * averageCharWidth / width) + 1) * defaultLineHeight; } else { height = defaultLineHeight; } } totalHeight += height; } return totalHeight + styledText.topMargin + styledText.bottomMargin; } boolean hasLink(int offset) {
void handleCompositionChanged(Event event) { String text = event.text; int start = event.start; int end = event.end; int charCount = content.getCharCount(); start = Math.min(start, charCount); end = Math.min(end, charCount); int length = text.length(); if (length == ime.getCommitCount()) { content.replaceTextRange(start, end - start, ""); setCaretOffset(ime.getCompositionOffset(), SWT.DEFAULT); caretWidth = 0; caretDirection = SWT.NULL; } else { content.replaceTextRange(start, end - start, text); int alignment = SWT.DEFAULT; if (ime.getWideCaret()) { start = ime.getCompositionOffset(); int lineIndex = getCaretLine(); int lineOffset = content.getOffsetAtLine(lineIndex); TextLayout layout = renderer.getTextLayout(lineIndex); caretWidth = layout.getBounds(start - lineOffset, start + length - 1 - lineOffset).width; renderer.disposeTextLayout(layout); alignment = OFFSET_LEADING; } setCaretOffset(ime.getCaretOffset(), alignment); } showCaret(); } /**
/** * Deletes the next character. Delete the selected text if any. */ void doDelete() { Event event = new Event(); event.text = ""; if (selection.x != selection.y) { event.start = selection.x; event.end = selection.y; sendKeyEvent(event); } else if (caretOffset < content.getCharCount()) { int line = content.getLineAtOffset(caretOffset); int lineOffset = content.getOffsetAtLine(line); int lineLength = content.getLine(line).length(); if (caretOffset == lineOffset + lineLength) { event.start = caretOffset; event.end = content.getOffsetAtLine(line + 1); } else { event.start = caretOffset; event.end = getClusterNext(caretOffset, line); } sendKeyEvent(event); } } /**
/** * Sets the content implementation to use for text storage. * * @param newContent StyledTextContent implementation to use for text storage. * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT when listener is null</li> * </ul> */ public void setContent(StyledTextContent newContent) { checkWidget(); if (newContent == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); } if (content != null) { content.removeTextChangeListener(textChangeListener); } content = newContent; content.addTextChangeListener(textChangeListener); reset(); } /**