private void updateTemplateFromEditor(PrintfTemplate template) {
    ArrayList params = new ArrayList();
    String format = null;
    int text_length = editorPane.getDocument().getLength();
    try {
      format = editorPane.getDocument().getText(0, text_length);
    } catch (BadLocationException ex1) {
    }
    Element section_el = editorPane.getDocument().getDefaultRootElement();
    // Get number of paragraphs.
    int num_para = section_el.getElementCount();
    for (int p_count = 0; p_count < num_para; p_count++) {
      Element para_el = section_el.getElement(p_count);
      // Enumerate the content elements
      int num_cont = para_el.getElementCount();
      for (int c_count = 0; c_count < num_cont; c_count++) {
        Element content_el = para_el.getElement(c_count);
        AttributeSet attr = content_el.getAttributes();
        // Get the name of the style applied to this content element; may be null
        String sn = (String) attr.getAttribute(StyleConstants.NameAttribute);
        // Check if style name match
        if (sn != null && sn.startsWith("Parameter")) {
          // we extract the label.
          JLabel l = (JLabel) StyleConstants.getComponent(attr);
          if (l != null) {
            params.add(l.getName());
          }
        }
      }
    }

    template.setFormat(format);
    template.setTokens(params);
  }
  /**
   * 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);
        }
      }
    }
  }
Exemple #3
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;
  }
  /**
   * Paints the word-wrapped text.
   *
   * @param g The graphics context in which to paint.
   * @param a The shape (usually a rectangle) in which to paint.
   */
  public void paint(Graphics g, Shape a) {

    Rectangle alloc = (a instanceof Rectangle) ? (Rectangle) a : a.getBounds();
    tabBase = alloc.x;

    Graphics2D g2d = (Graphics2D) g;
    host = (RSyntaxTextArea) getContainer();
    int ascent = host.getMaxAscent();
    int fontHeight = host.getLineHeight();
    FoldManager fm = host.getFoldManager();
    TokenPainter painter = host.getTokenPainter();
    Element root = getElement();

    // Whether token styles should always be painted, even in selections
    int selStart = host.getSelectionStart();
    int selEnd = host.getSelectionEnd();
    boolean useSelectedTextColor = host.getUseSelectedTextColor();

    int n = getViewCount(); // Number of lines.
    int x = alloc.x + getLeftInset();
    tempRect.y = alloc.y + getTopInset();
    Rectangle clip = g.getClipBounds();
    for (int i = 0; i < n; i++) {

      tempRect.x = x + getOffset(X_AXIS, i);
      // tempRect.y = y + getOffset(Y_AXIS, i);
      tempRect.width = getSpan(X_AXIS, i);
      tempRect.height = getSpan(Y_AXIS, i);
      // System.err.println("For line " + i + ": tempRect==" + tempRect);

      if (tempRect.intersects(clip)) {
        Element lineElement = root.getElement(i);
        int startOffset = lineElement.getStartOffset();
        int endOffset = lineElement.getEndOffset() - 1; // Why always "-1"?
        View view = getView(i);
        if (!useSelectedTextColor
            || selStart == selEnd
            || (startOffset >= selEnd || endOffset < selStart)) {
          drawView(painter, g2d, alloc, view, fontHeight, tempRect.y + ascent);
        } else {
          // System.out.println("Drawing line with selection: " + i);
          drawViewWithSelection(
              painter, g2d, alloc, view, fontHeight, tempRect.y + ascent, selStart, selEnd);
        }
      }

      tempRect.y += tempRect.height;

      Fold possibleFold = fm.getFoldForLine(i);
      if (possibleFold != null && possibleFold.isCollapsed()) {
        i += possibleFold.getCollapsedLineCount();
        // Visible indicator of collapsed lines
        Color c = RSyntaxUtilities.getFoldedLineBottomColor(host);
        if (c != null) {
          g.setColor(c);
          g.drawLine(x, tempRect.y - 1, alloc.width, tempRect.y - 1);
        }
      }
    }
  }
  public int computeDocumentOffset(int line, int column) throws BadLocationException {
    if (line < 0 || column < 0) throw new BadLocationException("Negative line/col", -1);

    Element lineElement = editor.getDocument().getDefaultRootElement().getElement(line - 1);

    int beginLineOffset = lineElement.getStartOffset();
    int endLineOffset = lineElement.getEndOffset();

    String text = editor.getDocument().getText(beginLineOffset, endLineOffset - beginLineOffset);

    int parserChar = 1;
    int documentChar = 0;

    while (parserChar < column) {
      if (documentChar < text.length() && text.charAt(documentChar) == '\t') {
        parserChar += 8;
        documentChar += 1;
      } else {
        parserChar += 1;
        documentChar += 1;
      }
    }

    return beginLineOffset + documentChar;
  }
 protected int getViewIndexAtPosition(int pos) {
   Element elem = getElement();
   if (elem.isLeaf()) {
     return 0;
   }
   return super.getViewIndexAtPosition(pos);
 }
Exemple #7
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 "";
  }
 protected void loadChildren(ViewFactory f) {
   Element elem = getElement();
   if (elem.isLeaf()) {
     View v = new LabelView(elem);
     append(v);
   } else {
     super.loadChildren(f);
   }
 }
 /**
  * Loads all of the children to initialize the view. This is called by the <code>setParent</code>
  * method. Subclasses can re-implement this to initialize their child views in a different manner.
  * The default implementation creates a child view for each child element.
  *
  * @param f the view factory
  */
 protected void loadChildren(ViewFactory f) {
   Element e = getElement();
   int n = e.getElementCount();
   if (n > 0) {
     View[] added = new View[n];
     for (int i = 0; i < n; i++) added[i] = new WrappedLine(e.getElement(i));
     replace(0, 0, added);
   }
 }
Exemple #10
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);
    }
  /**
   * 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);
  }
  /**
   * 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);
  }
Exemple #13
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;
    }
  }
Exemple #14
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);
 }
 /**
  * Returns a token list for the specified segment of text representing the specified line number.
  * This method is basically a wrapper for <code>tokenMaker.getTokenList</code> that takes into
  * account the last token on the previous line to assure token accuracy.
  *
  * @param line The line number of <code>text</code> in the document, >= 0.
  * @return A token list representing the specified line.
  */
 public final Token getTokenListForLine(int line) {
   Element map = getDefaultRootElement();
   Element elem = map.getElement(line);
   int startOffset = elem.getStartOffset();
   // int endOffset = (line==map.getElementCount()-1 ? elem.getEndOffset() - 1:
   //									elem.getEndOffset() - 1);
   int endOffset = elem.getEndOffset() - 1; // Why always "-1"?
   try {
     getText(startOffset, endOffset - startOffset, s);
   } catch (BadLocationException ble) {
     ble.printStackTrace();
     return null;
   }
   int initialTokenType = line == 0 ? Token.NULL : getLastTokenTypeOnLine(line - 1);
   return tokenMaker.getTokenList(s, initialTokenType, startOffset);
 }
 /**
  * Loads all of the children to initialize the view. This is called by the {@link #setParent}
  * method. Subclasses can reimplement this to initialize their child views in a different manner.
  * The default implementation creates a child view for each child element.
  *
  * @param f the view factory
  * @see #setParent
  */
 protected void loadChildren(ViewFactory f) {
   if (f == null) {
     // No factory. This most likely indicates the parent view
     // has changed out from under us, bail!
     return;
   }
   Element e = getElement();
   int n = e.getElementCount();
   if (n > 0) {
     View[] added = new View[n];
     for (int i = 0; i < n; i++) {
       added[i] = f.create(e.getElement(i));
     }
     replace(0, 0, added);
   }
 }
 /**
  * Iterate over the lines represented by the child elements of the element this view represents,
  * looking for the line that is the longest. The <em>longLine</em> variable is updated to
  * represent the longest line contained. The <em>font</em> variable is updated to indicate the
  * font used to calculate the longest line.
  */
 void calculateLongestLine() {
   Component c = getContainer();
   font = c.getFont();
   metrics = c.getFontMetrics(font);
   tabSize = getTabSize() * metrics.charWidth(' ');
   Element lines = getElement();
   int n = lines.getElementCount();
   for (int i = 0; i < n; i++) {
     Element line = lines.getElement(i);
     float w = getLineWidth(i);
     if (w > longLineWidth) {
       longLineWidth = w;
       longLine = line;
     }
   }
 }
Exemple #18
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();
    }
  /**
   * Updates internal state information; e.g. the "last tokens on lines" data. After this, a changed
   * update is fired to let listeners know that the document's structure has changed.
   *
   * <p>This is called internally whenever the syntax style changes.
   */
  protected void updateSyntaxHighlightingInformation() {

    // Reinitialize the "last token on each line" array.  Note that since
    // the actual text in the document isn't changing, the number of lines
    // is the same.
    Element map = getDefaultRootElement();
    int numLines = map.getElementCount();
    int lastTokenType = Token.NULL;
    for (int i = 0; i < numLines; i++) {
      setSharedSegment(i);
      lastTokenType = tokenMaker.getLastTokenTypeOnLine(s, lastTokenType);
      lastTokensOnLines.set(i, lastTokenType);
    }

    // Let everybody know that syntax styles have (probably) changed.
    fireChangedUpdate(new DefaultDocumentEvent(0, numLines - 1, DocumentEvent.EventType.CHANGE));
  }
  /**
   * Makes our private <code>Segment s</code> point to the text in our document referenced by the
   * specified element. Note that <code>line</code> MUST be a valid line number in the document.
   *
   * @param line The line number you want to get.
   */
  private final void setSharedSegment(int line) {

    Element map = getDefaultRootElement();
    // int numLines = map.getElementCount();

    Element element = map.getElement(line);
    if (element == null) throw new InternalError("Invalid line number: " + line);
    int startOffset = element.getStartOffset();
    // int endOffset = (line==numLines-1 ?
    //			element.getEndOffset()-1 : element.getEndOffset() - 1);
    int endOffset = element.getEndOffset() - 1; // Why always "-1"?
    try {
      getText(startOffset, endOffset - startOffset, s);
    } catch (BadLocationException ble) {
      throw new InternalError("Text range not in document: " + startOffset + "-" + endOffset);
    }
  }
 void editorPane_keyPressed(KeyEvent e) {
   StyledDocument doc = editorPane.getStyledDocument();
   int pos = editorPane.getCaretPosition();
   int code = e.getKeyCode();
   Element el;
   switch (code) {
     case KeyEvent.VK_BACK_SPACE:
     case KeyEvent.VK_DELETE:
     case KeyEvent.VK_LEFT:
     case KeyEvent.VK_KP_LEFT:
       if (pos == 0) return;
       // we want to get the element to the left of position.
       el = doc.getCharacterElement(pos - 1);
       break;
     case KeyEvent.VK_RIGHT:
     case KeyEvent.VK_KP_RIGHT:
       // we want to get the element to the right of position.
       el = doc.getCharacterElement(pos + 1);
       break;
     default:
       return; // bail we don't handle it.
   }
   AttributeSet attr = el.getAttributes();
   String el_name = (String) attr.getAttribute(StyleConstants.NameAttribute);
   int el_range = el.getEndOffset() - el.getStartOffset() - 1;
   if (el_name.startsWith("Parameter") && StyleConstants.getComponent(attr) != null) {
     try {
       switch (code) {
         case KeyEvent.VK_BACK_SPACE:
         case KeyEvent.VK_DELETE:
           doc.remove(el.getStartOffset(), el_range);
           break;
         case KeyEvent.VK_LEFT:
         case KeyEvent.VK_KP_LEFT:
           editorPane.setCaretPosition(pos - el_range);
           break;
         case KeyEvent.VK_RIGHT:
         case KeyEvent.VK_KP_RIGHT:
           editorPane.setCaretPosition(pos + (el_range));
           break;
       }
     } catch (BadLocationException ex) {
     }
   }
 }
Exemple #23
0
  /** Calculate the width needed to display the maximum line number */
  private void setPreferredWidth() {
    Element root = component.getDocument().getDefaultRootElement();
    int lines = root.getElementCount();
    int digits = Math.max(String.valueOf(lines).length(), minimumDisplayDigits);

    //  Update sizes when number of digits in the line number changes
    if (lastDigits != digits) {
      lastDigits = digits;
      FontMetrics fontMetrics = getFontMetrics(getFont());
      int width = fontMetrics.charWidth('0') * digits;
      Insets insets = getInsets();
      int preferredWidth = insets.left + insets.right + width;

      Dimension d = getPreferredSize();
      d.setSize(preferredWidth, HEIGHT);
      setPreferredSize(d);
      setSize(d);
    }
  }
  /**
   * Provides a mapping from the view coordinate space to the logical coordinate space of the model.
   *
   * @param fx the X coordinate &gt;= 0
   * @param fy the Y coordinate &gt;= 0
   * @param a the allocated region to render into
   * @return the location within the model that best represents the given point in the view &gt;= 0
   */
  @Override
  public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {

    bias[0] = Position.Bias.Forward;

    Rectangle alloc = a.getBounds();
    RSyntaxDocument doc = (RSyntaxDocument) getDocument();
    int x = (int) fx;
    int y = (int) fy;

    // If they're asking about a view position above the area covered by
    // this view, then the position is assumed to be the starting position
    // of this view.
    if (y < alloc.y) {
      return getStartOffset();
    }

    // If they're asking about a position below this view, the position
    // is assumed to be the ending position of this view.
    else if (y > alloc.y + alloc.height) {
      return host.getLastVisibleOffset();
    }

    // They're asking about a position within the coverage of this view
    // vertically.  So, we figure out which line the point corresponds to.
    // If the line is greater than the number of lines contained, then
    // simply use the last line as it represents the last possible place
    // we can position to.
    else {

      Element map = doc.getDefaultRootElement();
      int lineIndex = Math.abs((y - alloc.y) / lineHeight); // metrics.getHeight() );
      FoldManager fm = host.getFoldManager();
      // System.out.print("--- " + lineIndex);
      lineIndex += fm.getHiddenLineCountAbove(lineIndex, true);
      // System.out.println(" => " + lineIndex);
      if (lineIndex >= map.getElementCount()) {
        return host.getLastVisibleOffset();
      }

      Element line = map.getElement(lineIndex);

      // If the point is to the left of the line...
      if (x < alloc.x) {
        return line.getStartOffset();
      } else if (x > alloc.x + alloc.width) {
        return line.getEndOffset() - 1;
      } else {
        // Determine the offset into the text
        int p0 = line.getStartOffset();
        Token tokenList = doc.getTokenListForLine(lineIndex);
        tabBase = alloc.x;
        int offs = tokenList.getListOffset((RSyntaxTextArea) getContainer(), this, tabBase, x);
        return offs != -1 ? offs : p0;
      }
    } // End of else.
  }
  /**
   * 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 &gt;= 0
   * @param a the allocated region to render into
   * @return the bounding box of the given position
   * @exception BadLocationException if the given position does not represent a valid location in
   *     the associated document
   * @see View#modelToView
   */
  @Override
  public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {

    // line coordinates
    Element map = getElement();
    RSyntaxDocument doc = (RSyntaxDocument) getDocument();
    int lineIndex = map.getElementIndex(pos);
    Token tokenList = doc.getTokenListForLine(lineIndex);
    Rectangle lineArea = lineToRect(a, lineIndex);
    tabBase = lineArea.x; // Used by listOffsetToView().

    // int x = (int)RSyntaxUtilities.getTokenListWidthUpTo(tokenList,
    //							(RSyntaxTextArea)getContainer(),
    //							this, 0, pos);
    // We use this method instead as it returns the actual bounding box,
    // not just the x-coordinate.
    lineArea =
        tokenList.listOffsetToView((RSyntaxTextArea) getContainer(), this, pos, tabBase, lineArea);

    return lineArea;
  }
 /**
  * Returns a token list for the <i>physical</i> line above the physical line containing the
  * specified offset into the document. Note that for this plain (non-wrapped) view, this is simply
  * the token list for the logical line above the line containing <code>offset</code>, since lines
  * are not wrapped.
  *
  * @param offset The offset in question.
  * @return A token list for the physical (and in this view, logical) line before this one. If
  *     <code>offset</code> is in the first line in the document, <code>null</code> is returned.
  */
 public Token getTokenListForPhysicalLineAbove(int offset) {
   RSyntaxDocument document = (RSyntaxDocument) getDocument();
   Element map = document.getDefaultRootElement();
   int line = map.getElementIndex(offset);
   FoldManager fm = host.getFoldManager();
   if (fm == null) {
     line--;
     if (line >= 0) {
       return document.getTokenListForLine(line);
     }
   } else {
     line = fm.getVisibleLineAbove(line);
     if (line >= 0) {
       return document.getTokenListForLine(line);
     }
   }
   //		int line = map.getElementIndex(offset) - 1;
   //		if (line>=0)
   //			return document.getTokenListForLine(line);
   return null;
 }
 /**
  * Returns a token list for the <i>physical</i> line below the physical line containing the
  * specified offset into the document. Note that for this plain (non-wrapped) view, this is simply
  * the token list for the logical line below the line containing <code>offset</code>, since lines
  * are not wrapped.
  *
  * @param offset The offset in question.
  * @return A token list for the physical (and in this view, logical) line after this one. If
  *     <code>offset</code> is in the last physical line in the document, <code>null</code> is
  *     returned.
  */
 public Token getTokenListForPhysicalLineBelow(int offset) {
   RSyntaxDocument document = (RSyntaxDocument) getDocument();
   Element map = document.getDefaultRootElement();
   int lineCount = map.getElementCount();
   int line = map.getElementIndex(offset);
   if (!host.isCodeFoldingEnabled()) {
     if (line < lineCount - 1) {
       return document.getTokenListForLine(line + 1);
     }
   } else {
     FoldManager fm = host.getFoldManager();
     line = fm.getVisibleLineBelow(line);
     if (line >= 0 && line < lineCount) {
       return document.getTokenListForLine(line);
     }
   }
   //		int line = map.getElementIndex(offset);
   //		int lineCount = map.getElementCount();
   //		if (line<lineCount-1)
   //			return document.getTokenListForLine(line+1);
   return null;
 }
Exemple #28
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;
  }
Exemple #29
0
  /** Returns the offset where the selection ends on the specified line. */
  public int getSelectionEnd(int line) {
    if (line == selectionEndLine) return selectionEnd;
    else if (rectSelect) {
      Element map = document.getDefaultRootElement();
      int end = selectionEnd - map.getElement(selectionEndLine).getStartOffset();

      Element lineElement = map.getElement(line);
      int lineStart = lineElement.getStartOffset();
      int lineEnd = lineElement.getEndOffset() - 1;
      return Math.min(lineEnd, lineStart + end);
    } else return getLineEndOffset(line) - 1;
  }
Exemple #30
0
  /** Returns the selected text, or null if no selection is active. */
  public final String getSelectedText() {
    if (selectionStart == selectionEnd) return null;

    if (rectSelect) {
      // Return each row of the selection on a new line

      Element map = document.getDefaultRootElement();

      int start = selectionStart - map.getElement(selectionStartLine).getStartOffset();
      int end = selectionEnd - map.getElement(selectionEndLine).getStartOffset();

      // Certain rectangles satisfy this condition...
      if (end < start) {
        int tmp = end;
        end = start;
        start = tmp;
      }

      StringBuffer buf = new StringBuffer();
      Segment seg = new Segment();

      for (int i = selectionStartLine; i <= selectionEndLine; i++) {
        Element lineElement = map.getElement(i);
        int lineStart = lineElement.getStartOffset();
        int lineEnd = lineElement.getEndOffset() - 1;
        int lineLen = lineEnd - lineStart;

        lineStart = Math.min(lineStart + start, lineEnd);
        lineLen = Math.min(end - start, lineEnd - lineStart);

        getText(lineStart, lineLen, seg);
        buf.append(seg.array, seg.offset, seg.count);

        if (i != selectionEndLine) buf.append('\n');
      }

      return buf.toString();
    } else {
      return getText(selectionStart, selectionEnd - selectionStart);
    }
  }