Example #1
0
    private static int getNSVisualPosition(EditorPane txt, int pos, int direction) {
      Element root = txt.getDocument().getDefaultRootElement();
      int numLines = root.getElementIndex(txt.getDocument().getLength() - 1) + 1;
      int line = root.getElementIndex(pos) + 1;
      int tarLine = direction == SwingConstants.NORTH ? line - 1 : line + 1;
      try {
        if (tarLine <= 0) {
          return 0;
        }
        if (tarLine > numLines) {
          return txt.getDocument().getLength();
        }

        Rectangle curRect = txt.modelToView(pos);
        Rectangle tarEndRect;
        if (tarLine < numLines) {
          tarEndRect = txt.modelToView(txt.getLineStartOffset(tarLine) - 1);
        } else {
          tarEndRect = txt.modelToView(txt.getDocument().getLength() - 1);
        }
        Debug.log(9, "curRect: " + curRect + ", tarEnd: " + tarEndRect);

        if (curRect.x > tarEndRect.x) {
          pos = txt.viewToModel(new Point(tarEndRect.x, tarEndRect.y));
        } else {
          pos = txt.viewToModel(new Point(curRect.x, tarEndRect.y));
        }
      } catch (BadLocationException e) {
        Debug.error(me + "Problem getting next visual position\n%s", e.getMessage());
      }

      return pos;
    }
Example #2
0
  /*
   *  We need to know if the caret is currently positioned on the line we
   *  are about to paint so the line number can be highlighted.
   */
  private boolean isCurrentLine(int rowStartOffset) {
    int caretPosition = component.getCaretPosition();
    Element root = component.getDocument().getDefaultRootElement();

    if (root.getElementIndex(rowStartOffset) == root.getElementIndex(caretPosition)) return true;
    else return false;
  }
  /**
   * Returns the bounding box (in the current view) of a specified position in the model. This
   * method is designed for line-wrapped views to use, as it allows you to specify a "starting
   * position" in the line, from which the x-value is assumed to be zero. The idea is that you
   * specify the first character in a physical line as <code>p0</code>, as this is the character
   * where the x-pixel value is 0.
   *
   * @param textArea The text area containing the text.
   * @param s A segment in which to load the line. This is passed in so we don't have to reallocate
   *     a new <code>Segment</code> for each call.
   * @param p0 The starting position in the physical line in the document.
   * @param p1 The position for which to get the bounding box in the view.
   * @param e How to expand tabs.
   * @param rect The rectangle whose x- and width-values are changed to represent the bounding box
   *     of <code>p1</code>. This is reused to keep from needlessly reallocating Rectangles.
   * @param x0 The x-coordinate (pixel) marking the left-hand border of the text. This is useful if
   *     the text area has a border, for example.
   * @return The bounding box in the view of the character <code>p1</code>.
   * @throws BadLocationException If <code>p0</code> or <code>p1</code> is not a valid location in
   *     the specified text area's document.
   * @throws IllegalArgumentException If <code>p0</code> and <code>p1</code> are not on the same
   *     line.
   */
  public static Rectangle getLineWidthUpTo(
      RSyntaxTextArea textArea, Segment s, int p0, int p1, TabExpander e, Rectangle rect, int x0)
      throws BadLocationException {

    RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument();

    // Ensure p0 and p1 are valid document positions.
    if (p0 < 0) throw new BadLocationException("Invalid document position", p0);
    else if (p1 > doc.getLength()) throw new BadLocationException("Invalid document position", p1);

    // Ensure p0 and p1 are in the same line, and get the start/end
    // offsets for that line.
    Element map = doc.getDefaultRootElement();
    int lineNum = map.getElementIndex(p0);
    // We do ">1" because p1 might be the first position on the next line
    // or the last position on the previous one.
    // if (lineNum!=map.getElementIndex(p1))
    if (Math.abs(lineNum - map.getElementIndex(p1)) > 1)
      throw new IllegalArgumentException(
          "p0 and p1 are not on the " + "same line (" + p0 + ", " + p1 + ").");

    // Get the token list.
    Token t = doc.getTokenListForLine(lineNum);

    // Modify the token list 't' to begin at p0 (but still have correct
    // token types, etc.), and get the x-location (in pixels) of the
    // beginning of this new token list.
    makeTokenListStartAt(t, p0, e, textArea, 0);

    rect = t.listOffsetToView(textArea, e, p1, x0, rect);
    return rect;
  }
Example #4
0
 public Element getLineAtCaret(int caretPosition) {
   Element root = getDocument().getDefaultRootElement();
   if (caretPosition == -1) {
     return root.getElement(root.getElementIndex(getCaretPosition()));
   } else {
     return root.getElement(root.getElementIndex(root.getElementIndex(caretPosition)));
   }
 }
Example #5
0
 public void caretUpdate(CaretEvent e) {
   // when the cursor moves on _textView
   // this method will be called. Then, we
   // must determine what the line number is
   // and update the line number view
   Element root = textView.getDocument().getDefaultRootElement();
   int line = root.getElementIndex(e.getDot());
   root = root.getElement(line);
   int col = root.getElementIndex(e.getDot());
   lineNumberView.setText(line + ":" + col);
   // if text is selected then enable copy and cut
   boolean isSelection = e.getDot() != e.getMark();
   copyAction.setEnabled(isSelection);
   cutAction.setEnabled(isSelection);
 }
Example #6
0
  /**
   * Adds the matching block end.
   *
   * @param offset the offset
   * @return the string after adding the matching block end
   * @throws BadLocationException if the offset is invalid
   */
  protected String addMatchingBlockEnd(int offset) throws BadLocationException {
    StringBuffer result;
    StringBuffer whiteSpace = new StringBuffer();
    int line = m_RootElement.getElementIndex(offset);
    int i = m_RootElement.getElement(line).getStartOffset();

    while (true) {
      String temp = m_Self.getText(i, 1);

      if (temp.equals(" ") || temp.equals("\t")) {
        whiteSpace.append(temp);
        i++;
      } else {
        break;
      }
    }

    // assemble string
    result = new StringBuffer();
    result.append(m_BlockStart);
    result.append("\n");
    result.append(whiteSpace.toString());
    if (m_UseBlanks) result.append(m_Indentation);
    else result.append("\t");
    result.append("\n");
    result.append(whiteSpace.toString());
    result.append(m_BlockEnd);

    return result.toString();
  }
Example #7
0
 /**
  * Returns the line.
  *
  * @param content the content
  * @param offset the offset to start at
  * @return the line
  */
 protected String getLine(String content, int offset) {
   int line = m_RootElement.getElementIndex(offset);
   Element lineElement = m_RootElement.getElement(line);
   int start = lineElement.getStartOffset();
   int end = lineElement.getEndOffset();
   return content.substring(start, end - 1);
 }
Example #8
0
  /**
   * Highlight lines to start or end delimiter.
   *
   * @param content the content to parse
   * @param line the line number
   * @throws BadLocationException if offsets are wrong
   */
  protected void highlightLinesAfter(String content, int line) throws BadLocationException {
    int offset = m_RootElement.getElement(line).getEndOffset();

    // Start/End delimiter not found, nothing to do

    int startDelimiter = -1;
    int endDelimiter = -1;
    if (getMultiLineComment()) {
      startDelimiter = indexOf(content, getMultiLineCommentStart(), offset);
      endDelimiter = indexOf(content, getMultiLineCommentEnd(), offset);
    }

    if (startDelimiter < 0) startDelimiter = content.length();

    if (endDelimiter < 0) endDelimiter = content.length();

    int delimiter = Math.min(startDelimiter, endDelimiter);

    if (delimiter < offset) return;

    // Start/End delimiter found, reapply highlighting

    int endLine = m_RootElement.getElementIndex(delimiter);

    for (int i = line + 1; i < endLine; i++) {
      Element branch = m_RootElement.getElement(i);
      Element leaf = m_Self.getCharacterElement(branch.getStartOffset());
      AttributeSet as = leaf.getAttributes();

      if (as.isEqual(DEFAULT_COMMENT)) applyHighlighting(content, i);
    }
  }
Example #9
0
  /**
   * Repaint the region of change covered by the given document event. Damages the line that begins
   * the range to cover the case when the insert/remove is only on one line. If lines are added or
   * removed, damages the whole view. The longest line is checked to see if it has changed.
   */
  protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f) {
    Component host = getContainer();
    updateMetrics();
    Element elem = getElement();
    DocumentEvent.ElementChange ec = changes.getChange(elem);
    Element[] added = (ec != null) ? ec.getChildrenAdded() : null;
    Element[] removed = (ec != null) ? ec.getChildrenRemoved() : null;
    if (((added != null) && (added.length > 0)) || ((removed != null) && (removed.length > 0))) {
      // lines were added or removed...
      if (added != null) {
        int addedAt = ec.getIndex(); // FIXME: Is this correct?????
        for (int i = 0; i < added.length; i++) possiblyUpdateLongLine(added[i], addedAt + i);
      }
      if (removed != null) {
        for (int i = 0; i < removed.length; i++) {
          if (removed[i] == longLine) {
            longLineWidth = -1; // Must do this!!
            calculateLongestLine();
            break;
          }
        }
      }
      preferenceChanged(null, true, true);
      host.repaint();
    }

    // This occurs when syntax highlighting only changes on lines
    // (i.e. beginning a multiline comment).
    else if (changes.getType() == DocumentEvent.EventType.CHANGE) {
      // System.err.println("Updating the damage due to a CHANGE event...");
      int startLine = changes.getOffset();
      int endLine = changes.getLength();
      damageLineRange(startLine, endLine, a, host);
    } else {
      Element map = getElement();
      int line = map.getElementIndex(changes.getOffset());
      damageLineRange(line, line, a, host);
      if (changes.getType() == DocumentEvent.EventType.INSERT) {
        // check to see if the line is longer than current
        // longest line.
        Element e = map.getElement(line);
        if (e == longLine) {
          // We must recalculate longest line's width here
          // because it has gotten longer.
          longLineWidth = getLineWidth(line);
          preferenceChanged(null, true, false);
        } else {
          // If long line gets updated, update the status bars too.
          if (possiblyUpdateLongLine(e, line)) preferenceChanged(null, true, false);
        }
      } else if (changes.getType() == DocumentEvent.EventType.REMOVE) {
        if (map.getElement(line) == longLine) {
          // removed from longest line... recalc
          longLineWidth = -1; // Must do this!
          calculateLongestLine();
          preferenceChanged(null, true, false);
        }
      }
    }
  }
Example #10
0
  @Override
  public int getKeyword(int pos, boolean strict) {
    Element line = elem.getElement(elem.getElementIndex(pos));
    int end = line.getEndOffset();
    int tok = -1;
    start = line.getStartOffset();
    int startL = start;
    int s = -1;

    try {
      yyreset(new StringReader(doc.getText(start, end - start)));
      if (!strict) {
        pos++;
      }

      while (startL < pos && s != startL) {
        s = startL;
        tok = yylex();
        startL = start + yychar + yylength();
      }

      return tok;
    } catch (Exception e) {
      return LexerConstants.DEFAULT;
    }
  }
Example #11
0
  /** Paints one view that corresponds to a line (or multiple lines if folding takes effect). */
  private void paintView(View view, Graphics g, int yBase) {
    JTextComponent component = editorUI.getComponent();
    if (component == null) return;
    BaseTextUI textUI = (BaseTextUI) component.getUI();

    Element rootElem = textUI.getRootView(component).getElement();
    int line = rootElem.getElementIndex(view.getStartOffset());

    String annotation = ""; // NOI18N
    AnnotateLine al = null;
    if (!elementAnnotations.isEmpty()) {
      al = getAnnotateLine(line);
      if (al != null) {
        annotation = getDisplayName(al); // NOI18N
      }
    } else {
      annotation = elementAnnotationsSubstitute;
    }

    if (al != null && al.getRevision().equals(recentRevision)) {
      g.setColor(selectedColor());
    } else {
      g.setColor(foregroundColor());
    }
    int texty = yBase + editorUI.getLineAscent();
    int textx = 2;
    g.drawString(annotation, textx, texty);
  }
Example #12
0
  /*
   *	Get the line number to be drawn. The empty string will be returned
   *  when a line of text has wrapped.
   */
  protected String getTextLineNumber(int rowStartOffset) {
    Element root = component.getDocument().getDefaultRootElement();
    int index = root.getElementIndex(rowStartOffset);
    Element line = root.getElement(index);

    if (line.getStartOffset() == rowStartOffset) return String.valueOf(index + 1);
    else return "";
  }
 private static final Element getLineElem(Document d, int offs) {
   Element map = d.getDefaultRootElement();
   int index = map.getElementIndex(offs);
   Element elem = map.getElement(index);
   if ((offs >= elem.getStartOffset()) && (offs < elem.getEndOffset())) {
     return elem;
   }
   return null;
 }
Example #14
0
 /**
  * Returns the starting line of this fold region. This is the only line in the fold region that is
  * not hidden when a fold is collapsed.
  *
  * <p>The value returned by this method will automatically update as the text area's contents are
  * modified, to track the starting line of the code block.
  *
  * @return The starting line of the code block.
  * @see #getEndLine()
  * @see #getStartOffset()
  */
 public int getStartLine() {
   int startOffs = getStartOffset();
   if (lastStartOffs == startOffs) {
     return cachedStartLine;
   }
   lastStartOffs = startOffs;
   Element root = textArea.getDocument().getDefaultRootElement();
   return cachedStartLine = root.getElementIndex(startOffs);
 }
Example #15
0
 /**
  * Returns the end line of this fold. For example, in languages such as C and Java, this might be
  * the line containing the closing curly brace of a code block.
  *
  * <p>The value returned by this method will automatically update as the text area's contents are
  * modified, to track the ending line of the code block.
  *
  * @return The end line of this code block.
  * @see #getEndOffset()
  * @see #getStartLine()
  */
 public int getEndLine() {
   int endOffs = getEndOffset();
   if (lastEndOffs == endOffs) {
     return cachedEndLine;
   }
   lastEndOffs = endOffs;
   Element root = textArea.getDocument().getDefaultRootElement();
   return cachedEndLine = root.getElementIndex(endOffs);
 }
Example #16
0
 /**
  * Returns whether the specified offset is "inside" the fold. This method returns <code>true
  * </code> if the offset is greater than the fold start offset, and no further than the last
  * offset of the last folded line.
  *
  * @param offs The offset to check.
  * @return Whether the offset is "inside" the fold.
  * @see #containsLine(int)
  */
 public boolean containsOffset(int offs) {
   boolean contained = false;
   if (offs > getStartOffset()) {
     // Use Elements to avoid BadLocationExceptions
     Element root = textArea.getDocument().getDefaultRootElement();
     int line = root.getElementIndex(offs);
     contained = line <= getEndLine();
   }
   return contained;
 }
Example #17
0
    /**
     * Provides a mapping from the document model coordinate space to the coordinate space of the
     * view mapped to it.
     *
     * @param pos the position to convert
     * @param a the allocated region to render into
     * @return the bounding box of the given position is returned
     * @exception BadLocationException if the given position does not represent a valid location in
     *     the associated document.
     */
    @Override
    public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {

      // System.err.println("--- begin modelToView ---");
      Rectangle alloc = a.getBounds();
      RSyntaxTextArea textArea = (RSyntaxTextArea) getContainer();
      alloc.height = textArea.getLineHeight(); // metrics.getHeight();
      alloc.width = 1;
      int p0 = getStartOffset();
      int p1 = getEndOffset();
      int testP = (b == Position.Bias.Forward) ? pos : Math.max(p0, pos - 1);

      // Get the token list for this line so we don't have to keep
      // recomputing it if this logical line spans multiple physical
      // lines.
      RSyntaxDocument doc = (RSyntaxDocument) getDocument();
      Element map = doc.getDefaultRootElement();
      int line = map.getElementIndex(p0);
      Token tokenList = doc.getTokenListForLine(line);
      float x0 = alloc.x; // 0;

      while (p0 < p1) {
        TokenSubList subList =
            TokenUtils.getSubTokenList(
                tokenList, p0, WrappedSyntaxView.this, textArea, x0, lineCountTempToken);
        x0 = subList != null ? subList.x : x0;
        tokenList = subList != null ? subList.tokenList : null;
        int p = calculateBreakPosition(p0, tokenList, x0);
        if ((pos >= p0) && (testP < p)) { // pos < p)) {
          // it's in this line
          alloc =
              RSyntaxUtilities.getLineWidthUpTo(
                  textArea, s, p0, pos, WrappedSyntaxView.this, alloc, alloc.x);
          // System.err.println("--- end modelToView ---");
          return alloc;
        }
        // if (p == p1 && pos == p1) {
        if (p == p1 - 1 && pos == p1 - 1) {
          // Wants end.
          if (pos > p0) {
            alloc =
                RSyntaxUtilities.getLineWidthUpTo(
                    textArea, s, p0, pos, WrappedSyntaxView.this, alloc, alloc.x);
          }
          // System.err.println("--- end modelToView ---");
          return alloc;
        }

        p0 = (p == p0) ? p1 : p;
        // System.err.println("... ... Incrementing y");
        alloc.y += alloc.height;
      }

      throw new BadLocationException(null, pos);
    }
Example #18
0
  /**
   * Alerts all listeners to this document of an insertion. This is overridden so we can update our
   * syntax highlighting stuff.
   *
   * <p>The syntax highlighting stuff has to be here instead of in <code>insertUpdate</code> because
   * <code>insertUpdate</code> is not called by the undo/redo actions, but this method is.
   *
   * @param e The change.
   */
  protected void fireInsertUpdate(DocumentEvent e) {

    /*
     * Now that the text is actually inserted into the content and
     * element structure, we can update our token elements and "last
     * tokens on lines" structure.
     */

    Element lineMap = getDefaultRootElement();
    DocumentEvent.ElementChange change = e.getChange(lineMap);
    Element[] added = change == null ? null : change.getChildrenAdded();

    int numLines = lineMap.getElementCount();
    int line = lineMap.getElementIndex(e.getOffset());
    int previousLine = line - 1;
    int previousTokenType = (previousLine > -1 ? lastTokensOnLines.get(previousLine) : Token.NULL);

    // If entire lines were added...
    if (added != null && added.length > 0) {

      Element[] removed = change.getChildrenRemoved();
      int numRemoved = removed != null ? removed.length : 0;

      int endBefore = line + added.length - numRemoved;
      // System.err.println("... adding lines: " + line + " - " + (endBefore-1));
      // System.err.println("... ... added: " + added.length + ", removed:" + numRemoved);
      for (int i = line; i < endBefore; i++) {

        setSharedSegment(i); // Loads line i's text into s.

        int tokenType = tokenMaker.getLastTokenTypeOnLine(s, previousTokenType);
        lastTokensOnLines.add(i, tokenType);
        // System.err.println("--------- lastTokensOnLines.size() == " +
        // lastTokensOnLines.getSize());

        previousTokenType = tokenType;
      } // End of for (int i=line; i<endBefore; i++).

      // Update last tokens for lines below until they stop changing.
      updateLastTokensBelow(endBefore, numLines, previousTokenType);

    } // End of if (added!=null && added.length>0).

    // Otherwise, text was inserted on a single line...
    else {

      // Update last tokens for lines below until they stop changing.
      updateLastTokensBelow(line, numLines, previousTokenType);
    } // End of else.

    // Let all listeners know about the insertion.
    super.fireInsertUpdate(e);
  }
Example #19
0
 public Element getLineAtPoint(MouseEvent me) {
   Point p = me.getLocationOnScreen();
   Point pp = getLocationOnScreen();
   p.translate(-pp.x, -pp.y);
   int pos = viewToModel(p);
   Element root = getDocument().getDefaultRootElement();
   int e = root.getElementIndex(pos);
   if (e == -1) {
     return null;
   }
   return root.getElement(e);
 }
Example #20
0
  /**
   * Sets whether this <code>Fold</code> is collapsed. Calling this method will update both the text
   * area and all <code>Gutter</code> components.
   *
   * @param collapsed Whether this fold should be collapsed.
   * @see #isCollapsed()
   * @see #toggleCollapsedState()
   */
  public void setCollapsed(boolean collapsed) {

    if (collapsed != this.collapsed) {

      // Change our fold state and cached info about folded line count.
      int lineCount = getLineCount();
      int linesToCollapse = lineCount - childCollapsedLineCount;
      if (!collapsed) { // If we're expanding
        linesToCollapse = -linesToCollapse;
      }
      // System.out.println("Hiding lines: " + linesToCollapse +
      //		" (" + lineCount + ", " + linesToCollapse + ")");
      this.collapsed = collapsed;
      if (parent != null) {
        parent.updateChildCollapsedLineCount(linesToCollapse);
      }

      // If an end point of the selection is being hidden, move the caret
      // "out" of the fold.
      if (collapsed) {
        int dot = textArea.getSelectionStart(); // Forgive variable name
        Element root = textArea.getDocument().getDefaultRootElement();
        int dotLine = root.getElementIndex(dot);
        boolean updateCaret = containsLine(dotLine);
        if (!updateCaret) {
          int mark = textArea.getSelectionEnd();
          if (mark != dot) {
            int markLine = root.getElementIndex(mark);
            updateCaret = containsLine(markLine);
          }
        }
        if (updateCaret) {
          dot = root.getElement(getStartLine()).getEndOffset() - 1;
          textArea.setCaretPosition(dot);
        }
      }

      textArea.foldToggled(this);
    }
  }
Example #21
0
  /**
   * This method is called AFTER the content has been inserted into the document and the element
   * structure has been updated.
   *
   * <p>The syntax-highlighting updates need to be done here (as opposed to an override of <code>
   * postRemoveUpdate</code>) as this method is called in response to undo/redo events, whereas
   * <code>postRemoveUpdate</code> is not.
   *
   * <p>Now that the text is actually inserted into the content and element structure, we can update
   * our token elements and "last tokens on lines" structure.
   *
   * @param chng The change that occurred.
   * @see #removeUpdate
   */
  protected void fireRemoveUpdate(DocumentEvent chng) {

    Element lineMap = getDefaultRootElement();
    int numLines = lineMap.getElementCount();

    DocumentEvent.ElementChange change = chng.getChange(lineMap);
    Element[] removed = change == null ? null : change.getChildrenRemoved();

    // If entire lines were removed...
    if (removed != null && removed.length > 0) {

      int line = change.getIndex(); // First line entirely removed.
      int previousLine = line - 1; // Line before that.
      int previousTokenType =
          (previousLine > -1 ? lastTokensOnLines.get(previousLine) : Token.NULL);

      Element[] added = change.getChildrenAdded();
      int numAdded = added == null ? 0 : added.length;

      // Remove the cached last-token values for the removed lines.
      int endBefore = line + removed.length - numAdded;
      // System.err.println("... removing lines: " + line + " - " + (endBefore-1));
      // System.err.println("... added: " + numAdded + ", removed: " + removed.length);

      lastTokensOnLines.removeRange(
          line, endBefore); // Removing values for lines [line-(endBefore-1)].
      // System.err.println("--------- lastTokensOnLines.size() == " + lastTokensOnLines.getSize());

      // Update last tokens for lines below until they've stopped changing.
      updateLastTokensBelow(line, numLines, previousTokenType);

    } // End of if (removed!=null && removed.size()>0).

    // Otherwise, text was removed from just one line...
    else {

      int line = lineMap.getElementIndex(chng.getOffset());
      if (line >= lastTokensOnLines.getSize())
        return; // If we're editing the last line in a document...

      int previousLine = line - 1;
      int previousTokenType =
          (previousLine > -1 ? lastTokensOnLines.get(previousLine) : Token.NULL);
      // System.err.println("previousTokenType for line : " + previousLine + " is " +
      // previousTokenType);
      // Update last tokens for lines below until they've stopped changing.
      updateLastTokensBelow(line, numLines, previousTokenType);
    }

    // Let all of our listeners know about the removal.
    super.fireRemoveUpdate(chng);
  }
Example #22
0
    public void actionPerformed(JTextComponent text) {
      indentationLogic = ((EditorPane) text).getIndentationLogic();
      StyledDocument doc = (StyledDocument) text.getDocument();
      Element map = doc.getDefaultRootElement();
      Caret c = text.getCaret();
      int dot = c.getDot();
      int mark = c.getMark();
      int line1 = map.getElementIndex(dot);

      if (dot != mark) {
        int line2 = map.getElementIndex(mark);
        int begin = Math.min(line1, line2);
        int end = Math.max(line1, line2);
        Element elem;
        try {
          for (line1 = begin; line1 < end; line1++) {
            elem = map.getElement(line1);
            handleDecreaseIndent(line1, elem, doc);
          }
          elem = map.getElement(end);
          int start = elem.getStartOffset();
          if (Math.max(c.getDot(), c.getMark()) != start) {
            handleDecreaseIndent(end, elem, doc);
          }
        } catch (BadLocationException ble) {
          Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage());
          UIManager.getLookAndFeel().provideErrorFeedback(text);
        }
      } else {
        Element elem = map.getElement(line1);
        try {
          handleDecreaseIndent(line1, elem, doc);
        } catch (BadLocationException ble) {
          Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage());
          UIManager.getLookAndFeel().provideErrorFeedback(text);
        }
      }
    }
Example #23
0
  //
  //  Implement CaretListener interface
  //
  @Override
  public void caretUpdate(CaretEvent e) {
    //  Get the line the caret is positioned on

    int caretPosition = component.getCaretPosition();
    Element root = component.getDocument().getDefaultRootElement();
    int currentLine = root.getElementIndex(caretPosition);

    //  Need to repaint so the correct line number can be highlighted
    if (lastLine != currentLine) {
      repaint();
      lastLine = currentLine;
    }
  }
Example #24
0
    public void actionPerformed(JTextComponent text) {
      indentationLogic = ((EditorPane) text).getIndentationLogic();
      boolean indentError = false;
      Document doc = text.getDocument();
      Element map = doc.getDefaultRootElement();
      String tabWhitespace = PreferencesUser.getInstance().getTabWhitespace();
      Caret c = text.getCaret();
      int dot = c.getDot();
      int mark = c.getMark();
      int dotLine = map.getElementIndex(dot);
      int markLine = map.getElementIndex(mark);

      if (dotLine != markLine) {
        int first = Math.min(dotLine, markLine);
        int last = Math.max(dotLine, markLine);
        Element elem;
        int start;
        try {
          for (int i = first; i < last; i++) {
            elem = map.getElement(i);
            start = elem.getStartOffset();
            doc.insertString(start, tabWhitespace, null);
          }
          elem = map.getElement(last);
          start = elem.getStartOffset();
          if (Math.max(c.getDot(), c.getMark()) != start) {
            doc.insertString(start, tabWhitespace, null);
          }
        } catch (BadLocationException ble) {
          Debug.error(me + "Problem while indenting line\n%s", ble.getMessage());
          UIManager.getLookAndFeel().provideErrorFeedback(text);
        }
      } else {
        text.replaceSelection(tabWhitespace);
      }
    }
Example #25
0
  /**
   * Determine how many lines have been changed, then apply highlighting to each line.
   *
   * @param offset the offset of the changed lines
   * @param length the length of the change
   * @throws BadLocationException if offset is invalid
   */
  public void processChangedLines(int offset, int length) throws BadLocationException {
    String content = m_Self.getText(0, m_Self.getLength());

    // The lines affected by the latest document update

    int startLine = m_RootElement.getElementIndex(offset);
    int endLine = m_RootElement.getElementIndex(offset + length);

    // Make sure all comment lines prior to the start line are commented
    // and determine if the start line is still in a multi line comment

    if (getMultiLineComment()) setInsideMultiLineComment(commentLinesBefore(content, startLine));

    // Do the actual highlighting

    for (int i = startLine; i <= endLine; i++) {
      applyHighlighting(content, i);
    }

    // Resolve highlighting to the next end multi line delimiter

    if (isMultiLineComment()) commentLinesAfter(content, endLine);
    else highlightLinesAfter(content, endLine);
  }
Example #26
0
    /** Calculate the number of lines that will be rendered by logical line when it is wrapped. */
    final int calculateLineCount() {

      int nlines = 0;
      int startOffset = getStartOffset();
      int p1 = getEndOffset();

      // Get the token list for this line so we don't have to keep
      // recomputing it if this logical line spans multiple physical
      // lines.
      RSyntaxTextArea textArea = (RSyntaxTextArea) getContainer();
      RSyntaxDocument doc = (RSyntaxDocument) getDocument();
      Element map = doc.getDefaultRootElement();
      int line = map.getElementIndex(startOffset);
      Token tokenList = doc.getTokenListForLine(line);
      float x0 = 0; // FIXME:  should be alloc.x!! alloc.x;//0;

      // System.err.println(">>> calculateLineCount: " + startOffset + "-" + p1);
      for (int p0 = startOffset; p0 < p1; ) {
        // System.err.println("... ... " + p0 + ", " + p1);
        nlines += 1;
        TokenSubList subList =
            TokenUtils.getSubTokenList(
                tokenList, p0, WrappedSyntaxView.this, textArea, x0, lineCountTempToken);
        x0 = subList != null ? subList.x : x0;
        tokenList = subList != null ? subList.tokenList : null;
        int p = calculateBreakPosition(p0, tokenList, x0);

        // System.err.println("... ... ... break position p==" + p);
        p0 = (p == p0) ? ++p : p; // this is the fix of #4410243
        // we check on situation when
        // width is too small and
        // break position is calculated
        // incorrectly.
        // System.err.println("... ... ... new p0==" + p0);
      }
      /*
      int numLines = 0;
      try {
      	numLines = textArea.getLineCount();
      } catch (BadLocationException ble) {
      	ble.printStackTrace();
      }
      System.err.println(">>> >>> calculated number of lines for this view (line " + line + "/" + numLines + ": " + nlines);
      */
      return nlines;
    }
    private String addWhiteSpace(Document doc, int offset) throws BadLocationException {
      StringBuilder whiteSpace = new StringBuilder("\n");
      Element rootElement = doc.getDefaultRootElement();
      int line = rootElement.getElementIndex(offset);
      int i = rootElement.getElement(line).getStartOffset();

      while (true) {
        String temp = doc.getText(i, 1);

        if (temp.equals(" ") || temp.equals("\t")) {
          whiteSpace.append(temp);
          i++;
        } else break;
      }

      return whiteSpace.toString();
    }
Example #28
0
 private void checkCompletion(java.awt.event.KeyEvent ke) throws BadLocationException {
   Document doc = getDocument();
   Element root = doc.getDefaultRootElement();
   int pos = getCaretPosition();
   int lineIdx = root.getElementIndex(pos);
   Element line = root.getElement(lineIdx);
   int start = line.getStartOffset(), len = line.getEndOffset() - start;
   String strLine = doc.getText(start, len - 1);
   Debug.log(9, "[" + strLine + "]");
   if (strLine.endsWith("find") && ke.getKeyChar() == '(') {
     ke.consume();
     doc.insertString(pos, "(", null);
     ButtonCapture btnCapture = new ButtonCapture(this, line);
     insertComponent(btnCapture);
     doc.insertString(pos + 2, ")", null);
   }
 }
Example #29
0
  /*
   *  Determine the Y offset for the current row
   */
  private int getOffsetY(int rowStartOffset, FontMetrics fontMetrics) throws BadLocationException {
    //  Get the bounding rectangle of the row

    Rectangle r = component.modelToView(rowStartOffset);
    int lineHeight = fontMetrics.getHeight();
    int y = r.y + r.height;
    int descent = 0;

    //  The text needs to be positioned above the bottom of the bounding
    //  rectangle based on the descent of the font(s) contained on the row.
    if (r.height == lineHeight) {
      // default font is being used
      descent = fontMetrics.getDescent();
    } else {
      // We need to check all the attributes for font changes
      if (fonts == null) {
        fonts = new HashMap<String, FontMetrics>();
      }

      Element root = component.getDocument().getDefaultRootElement();
      int index = root.getElementIndex(rowStartOffset);
      Element line = root.getElement(index);

      for (int i = 0; i < line.getElementCount(); i++) {
        Element child = line.getElement(i);
        AttributeSet as = child.getAttributes();
        String fontFamily = (String) as.getAttribute(StyleConstants.FontFamily);
        Integer fontSize = (Integer) as.getAttribute(StyleConstants.FontSize);
        String key = fontFamily + fontSize;

        FontMetrics fm = fonts.get(key);

        if (fm == null) {
          Font font = new Font(fontFamily, Font.PLAIN, fontSize);
          fm = component.getFontMetrics(font);
          fonts.put(key, fm);
        }

        descent = Math.max(descent, fm.getDescent());
      }
    }

    return y - descent;
  }
  /**
   * actionPerformed
   *
   * @param ev ActionEvent
   */
  public void actionPerformed(ActionEvent ev) {
    ScilabEditorPane sep = (ScilabEditorPane) ev.getSource();
    ScilabDocument doc = (ScilabDocument) sep.getDocument();
    int pos = sep.getCaretPosition();
    Element root = doc.getDefaultRootElement();
    int end = root.getElement(root.getElementIndex(pos)).getEndOffset() - 1;
    String str = "";
    try {
      str = doc.getText(pos, end - pos);
    } catch (BadLocationException e) {
      System.err.println(e);
    }
    if (str.matches("[ \\t]+(then|do)")) {
      sep.setCaretPosition(end);
    }

    super.actionPerformed(ev);
    sep.getIndentManager().indentDoc(sep.getCaretPosition() - 1);
  }