/** * Convert mouse screen coordinates to a <code>StyledText</code> offset. * * @param x screen X-coordinate * @param y screen Y-coordinate * @param absolute if <code>true</code>, coordinates are expected to be absolute screen * coordinates * @return text offset * @see StyledText#getOffsetAtLocation() */ private int getOffsetAtLocation(int x, int y, boolean absolute) { StyledText textWidget = fViewer.getTextWidget(); StyledTextContent content = textWidget.getContent(); Point location; if (absolute) { location = textWidget.toControl(x, y); } else { location = new Point(x, y); } int line = (textWidget.getTopPixel() + location.y) / textWidget.getLineHeight(); if (line >= content.getLineCount()) { return content.getCharCount(); } int lineOffset = content.getOffsetAtLine(line); String lineText = content.getLine(line); Point endOfLine = textWidget.getLocationAtOffset(lineOffset + lineText.length()); if (location.x >= endOfLine.x) { return lineOffset + lineText.length(); } try { return textWidget.getOffsetAtLocation(location); } catch (IllegalArgumentException iae) { // we are expecting this return -1; } }
private boolean getStyledTextContentChangedAndStoreNew() { StyledTextContent currentContent = this.styledText.getContent(); StyledTextContent oldContent = this.content; if (currentContent != oldContent) { // Important: the content may change during runtime, so, we have to stop listening the old one // and // start listening the new one. if (oldContent != null) { oldContent.removeTextChangeListener(this); } this.content = currentContent; currentContent.addTextChangeListener(this); return true; } return false; }
/* * @see org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color) */ public void draw( Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { if (annotation instanceof ProjectionAnnotation) { ProjectionAnnotation projectionAnnotation = (ProjectionAnnotation) annotation; if (projectionAnnotation.isCollapsed()) { if (gc != null) { StyledTextContent content = textWidget.getContent(); int line = content.getLineAtOffset(offset); int lineStart = content.getOffsetAtLine(line); String text = content.getLine(line); int lineLength = text == null ? 0 : text.length(); int lineEnd = lineStart + lineLength; Point p = textWidget.getLocationAtOffset(lineEnd); Color c = gc.getForeground(); gc.setForeground(color); FontMetrics metrics = gc.getFontMetrics(); // baseline: where the dots are drawn int baseline = textWidget.getBaseline(offset); // descent: number of pixels that the box extends over baseline int descent = Math.min(2, textWidget.getLineHeight(offset) - baseline); // ascent: so much does the box stand up from baseline int ascent = metrics.getAscent(); // leading: free space from line top to box upper line int leading = baseline - ascent; // height: height of the box int height = ascent + descent; int width = metrics.getAverageCharWidth(); gc.drawRectangle(p.x, p.y + leading, width, height); int third = width / 3; int dotsVertical = p.y + baseline - 1; gc.drawPoint(p.x + third, dotsVertical); gc.drawPoint(p.x + width - third, dotsVertical); gc.setForeground(c); } else { textWidget.redrawRange(offset, length, true); } } } }
/** * Writes data in BRF format to <code>Writer</code>. * * @param writer the writer stream to write the data. * @exception IOException * @see #readBRF(Reader) */ public void writeBRF(Writer writer) throws IOException { // write first line String line = content.getLine(0); if (line.length() > 0 && line.charAt(line.length() - 1) == PARAGRAPH_END) writer.write(line.substring(0, line.length() - 1)); else writer.write(line); // write remaining lines for (int i = 1; i < content.getLineCount(); i++) { writer.write(eol); if (isFirstLineOnPage(i)) writer.write(0xc); line = content.getLine(i); if (line.length() > 0 && line.charAt(line.length() - 1) == PARAGRAPH_END) writer.write(line.substring(0, line.length() - 1)); else writer.write(line); } writer.flush(); resetChanges(); }
/** * Reads data in BRF format from <code>Reader</code>. * * <p>An attempt is made to determine the number of lines per page. * * @param reader the reader stream from which to read the data. * @exception IOException * @see #writeBRF(Writer) */ public void readBRF(Reader reader) throws IOException { StringBuilder stringBuilder = new StringBuilder(65536); boolean checkLinesPerPage = true; boolean removeFormFeed = true; char buffer[] = new char[65536]; int cnt, trim; eol = null; while ((cnt = reader.read(buffer)) > 0) { // see if lines per page can be determined if (checkLinesPerPage) { checkLinesPerPage = false; int lines = 0, i; outer: for (i = 0; i < cnt; i++) switch (buffer[i]) { case '\n': lines++; break; case '\r': if (eol == null) eol = "\r\n"; break; case 0xc: linesPerPage = lines; break outer; } if (eol == null) eol = "\n"; if (i == cnt) removeFormFeed = false; } // remove form feeds if (removeFormFeed) { trim = 0; for (int i = 0; i < cnt; i++) if (buffer[i] != 0xc) { buffer[trim] = buffer[i]; trim++; } } else trim = cnt; stringBuilder.append(buffer, 0, trim); } content.setText(stringBuilder.toString()); clearChanges(); }
/** * Wraps lines at and below the caret that exceed the number of characters per line. * * <p>Lines are wrapped at spaces between words when possible. Lines that don't exceed the number * of characters per line are not changed. * * <p>Currently this cannot be undone. */ public void rewrapFromCaret() { StringBuilder stringBuilder = new StringBuilder(charsPerLine * 3); for (int i = content.getLineAtOffset(currentText.getCaretOffset()); i < content.getLineCount(); i++) { String line = content.getLine(i); if (line.length() == 0) continue; // line too long if (line.length() > charsPerLine) { int wordWrap, wordEnd; // find beginning of word being wrapped if (line.charAt(charsPerLine) != ' ') { for (wordWrap = charsPerLine; wordWrap > charsPerLine / 2; wordWrap--) if (line.charAt(wordWrap) == ' ') break; if (wordWrap == charsPerLine / 2) continue; wordWrap++; } else { for (wordWrap = charsPerLine; wordWrap < line.length(); wordWrap++) if (line.charAt(wordWrap) != ' ') break; if (wordWrap == line.length()) continue; } // find end of word before word being wrapped for (wordEnd = wordWrap - 1; wordEnd > charsPerLine / 4; wordEnd--) if (line.charAt(wordEnd) != ' ') break; if (wordEnd == charsPerLine / 4) continue; wordEnd++; // build replacement text int length = line.length(); stringBuilder.setLength(0); stringBuilder .append(line.substring(0, wordEnd)) .append(eol) .append(line.substring(wordWrap, length)); if (length > 0 && line.charAt(length - 1) != PARAGRAPH_END) if (i < content.getLineCount() - 1) { String next = content.getLine(i + 1); stringBuilder.append(' ').append(next); length += eol.length() + next.length(); } content.replaceTextRange(content.getOffsetAtLine(i), length, stringBuilder.toString()); } else if (line.length() > 0 && line.charAt(line.length() - 1) == PARAGRAPH_END) break; } clearChanges(); }
/** * Writes data in BrailleZephyr file format to <code>Writer</code>. * * @param writer the writer stream to write the data. * @exception IOException * @see #readBZY(Reader) */ public void writeBZY(Writer writer) throws IOException { // write configuration lines writer.write("Version " + versionMajor + ' ' + versionMinor + ' ' + versionPatch + eol); writer.write("CharsPerLine " + charsPerLine + eol); writer.write("LinesPerPage " + linesPerPage + eol); writer.write("CaretOffset " + currentText.getCaretOffset() + eol); writer.write("ViewFocus "); if (currentText == brailleText) writer.write("braille" + eol); else writer.write("ascii" + eol); if (content.getCharCount() > 0) writer.write( "ReturnAtEnd " + (content.getLine(content.getLineCount() - 1).length() == 0) + eol); else writer.write("ReturnAtEnd false" + eol); writer.write("HeaderEnd" + eol); // write first line String line = content.getLine(0); if (line.length() > 0 && line.charAt(line.length() - 1) == PARAGRAPH_END) writer.write(line.substring(0, line.length() - 1) + (char) 0xb6); else writer.write(line); // write text for (int i = 1; i < content.getLineCount(); i++) { writer.write(eol); line = content.getLine(i); if (line.length() > 0 && line.charAt(line.length() - 1) == PARAGRAPH_END) writer.write(line.substring(0, line.length() - 1) + (char) 0xb6); else writer.write(line); } writer.flush(); resetChanges(); }
/** * Reads data in BrailleZephyr file format from <code>Reader</code>. * * @param reader the reader stream from which to read the data. * @exception IOException * @see #writeBZY(Writer) */ public void readBZY(Reader reader) throws IOException, BZException { String line; boolean returnAtEnd = false; int caretOffset = 0; int unknown = 0; content.setText(""); eol = System.getProperty("line.separator"); BufferedReader buffer = new BufferedReader(reader); // read configuration lines header: while ((line = buffer.readLine()) != null) { String tokens[] = line.split(" "); switch (tokens[0]) { // don't do anything for now case "Version": break; case "CharsPerLine": charsPerLine = Integer.parseInt(tokens[1]); break; case "LinesPerPage": linesPerPage = Integer.parseInt(tokens[1]); break; case "CaretOffset": caretOffset = Integer.parseInt(tokens[1]); break; case "ViewFocus": if (tokens[1].equals("braille")) { if (brailleText.isVisible()) brailleText.setFocus(); } else if (tokens[1].equals("ascii")) { if (asciiText.isVisible()) asciiText.setFocus(); } else logWriter.println("ERROR: Invalid ViewFocus value: " + line); break; case "ReturnAtEnd": returnAtEnd = Boolean.parseBoolean(tokens[1]); break; case "HeaderEnd": break header; default: logWriter.println("WARNING: Unknown file format parameter: " + line); unknown++; if (unknown > 6) throw new BZException("Invalid file format"); break; } } if (line == null) throw new BZException("Invalid file format"); // read first line, may be null for empty document if ((line = buffer.readLine()) != null) { if (line.length() > 0 && line.charAt(line.length() - 1) == 0xb6) content.replaceTextRange(0, 0, line.substring(0, line.length() - 1) + PARAGRAPH_END); else content.replaceTextRange(0, 0, line); // read next lines while ((line = buffer.readLine()) != null) { content.replaceTextRange(content.getCharCount(), 0, eol); if (line.length() > 0 && line.charAt(line.length() - 1) == 0xb6) content.replaceTextRange( content.getCharCount(), 0, line.substring(0, line.length() - 1) + PARAGRAPH_END); else content.replaceTextRange(content.getCharCount(), 0, line); } } if (returnAtEnd) content.replaceTextRange(content.getCharCount(), 0, eol); clearChanges(); brailleText.setCaretOffset(caretOffset); asciiText.setCaretOffset(caretOffset); }
/** * Sets the text for both braille and ascii texts. * * @param text the string to set the text */ public void setText(String text) { content.setText(text); changes.clear(); changeIndex = saveIndex = 0; }
/** * Draw characters of content range. * * @param gc the GC * @param startOffset inclusive start index * @param endOffset exclusive end index */ private void drawCharRange(GC gc, int startOffset, int endOffset) { StyledTextContent content = fTextWidget.getContent(); int length = endOffset - startOffset; String text = content.getTextRange(startOffset, length); StyleRange styleRange = null; Color fg = null; Point selection = fTextWidget.getSelection(); StringBuffer visibleChar = new StringBuffer(10); for (int textOffset = 0; textOffset <= length; ++textOffset) { int delta = 0; boolean eol = false; if (textOffset < length) { delta = 1; char c = text.charAt(textOffset); switch (c) { case ' ': visibleChar.append(SPACE_SIGN); // 'continue' would improve performance but may produce // drawing errors // for long runs of space if width of space and dot differ break; case '\u3000': // ideographic whitespace visibleChar.append(IDEOGRAPHIC_SPACE_SIGN); // 'continue' would improve performance but may produce // drawing errors // for long runs of space if width of space and dot differ break; case '\t': visibleChar.append(TAB_SIGN); break; case '\r': visibleChar.append(CARRIAGE_RETURN_SIGN); if (textOffset >= length - 1 || text.charAt(textOffset + 1) != '\n') { eol = true; break; } continue; case '\n': visibleChar.append(LINE_FEED_SIGN); eol = true; break; default: delta = 0; break; } } if (visibleChar.length() > 0) { int widgetOffset = startOffset + textOffset - visibleChar.length() + delta; if (!eol || !isFoldedLine(content.getLineAtOffset(widgetOffset))) { if (widgetOffset >= selection.x && widgetOffset < selection.y) { fg = fTextWidget.getSelectionForeground(); } else if (styleRange == null || styleRange.start + styleRange.length <= widgetOffset) { styleRange = fTextWidget.getStyleRangeAtOffset(widgetOffset); if (styleRange == null || styleRange.foreground == null) { fg = fTextWidget.getForeground(); } else { fg = styleRange.foreground; } } draw(gc, widgetOffset, visibleChar.toString(), fg); } visibleChar.delete(0, visibleChar.length()); } } }