示例#1
0
 /**
  * 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;
 }
示例#3
0
    /*
     * @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());
     }
   }
 }