예제 #1
0
  /**
   * Paints the specified line onto the graphics context. Note that this method munges the offset
   * and count values of the segment.
   *
   * @param line The line segment
   * @param tokens The token list for the line
   * @param styles The syntax style list
   * @param expander The tab expander used to determine tab stops. May be null
   * @param gfx The graphics context
   * @param x The x co-ordinate
   * @param y The y co-ordinate
   * @return The x co-ordinate, plus the width of the painted string
   */
  public static int paintSyntaxLine(
      Segment line,
      Token tokens,
      SyntaxStyle[] styles,
      TabExpander expander,
      Graphics gfx,
      int x,
      int y) {
    Font defaultFont = gfx.getFont();
    Color defaultColor = gfx.getColor();

    int offset = 0;
    for (; ; ) {
      byte id = tokens.id;
      if (id == Token.END) break;

      int length = tokens.length;
      if (id == Token.NULL) {
        if (!defaultColor.equals(gfx.getColor())) gfx.setColor(defaultColor);
        if (!defaultFont.equals(gfx.getFont())) gfx.setFont(defaultFont);
      } else styles[id].setGraphicsFlags(gfx, defaultFont);

      line.count = length;
      x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0);
      line.offset += length;
      offset += length;

      tokens = tokens.next;
    }

    return x;
  }
예제 #2
0
 public void getChars(int where, int len, Segment txt) throws BadLocationException {
   CharBuffer b = buffer;
   int start = b.getSegment(where, len);
   if (start < 0) throw new BadLocationException("invalid offset", where);
   txt.offset = start;
   txt.array = b.getArray();
   txt.count = len;
 }
 /** This helper method will return the end of the next word in the buffer. */
 private static int getNextWordEnd(Segment text, int startPos) {
   for (char ch = text.setIndex(startPos); ch != Segment.DONE; ch = text.next()) {
     if (!Character.isLetterOrDigit(ch)) {
       return text.getIndex();
     }
   }
   return text.getEndIndex();
 }
예제 #4
0
 /**
  * Copies the specified substring of the document into a segment. If the offsets are invalid, the
  * segment will contain a null string.
  *
  * @param start The start offset
  * @param len The length of the substring
  * @param segment The segment
  */
 public final void getText(int start, int len, Segment segment) {
   try {
     document.getText(start, len, segment);
   } catch (BadLocationException bl) {
     bl.printStackTrace();
     segment.offset = segment.count = 0;
   }
 }
 @Override
 public Segment getText(int p0, int p1) {
   if (p0 < 0 || p1 > segment.array.length) {
     throw new RuntimeException("ImageLabelView: Stale view");
   }
   segment.offset = p0;
   segment.count = p1 - p0;
   return segment;
 }
예제 #6
0
 /**
  * Gets the line at given position. The line returned will NOT include the line terminator '\n'
  *
  * @param pos Position (usually from text.getCaretPosition()
  * @return the STring of text at given position
  * @throws BadLocationException
  */
 public String getLineAt(int pos) throws BadLocationException {
   Element e = getParagraphElement(pos);
   Segment seg = new Segment();
   getText(e.getStartOffset(), e.getEndOffset() - e.getStartOffset(), seg);
   char last = seg.last();
   if (last == '\n' || last == '\r') {
     seg.count--;
   }
   return seg.toString();
 }
예제 #7
0
 /**
  * Removes any spaces or tabs from the end of the segment.
  *
  * @param segment The segment from which to remove tailing whitespace.
  * @return <code>segment</code> with trailing whitespace removed.
  */
 private static Segment removeEndingWhitespace(Segment segment) {
   int toTrim = 0;
   char currentChar = segment.setIndex(segment.getEndIndex() - 1);
   while ((currentChar == ' ' || currentChar == '\t') && currentChar != CharacterIterator.DONE) {
     toTrim++;
     currentChar = segment.previous();
   }
   String stringVal = segment.toString();
   String newStringVal = stringVal.substring(0, stringVal.length() - toTrim);
   return new Segment(newStringVal.toCharArray(), 0, newStringVal.length());
 }
예제 #8
0
    @Override
    @SuppressWarnings("SleepWhileHoldingLock")
    public void run() {
      try {
        // initialize the statusbar
        status.removeAll();
        JProgressBar progress = new JProgressBar();
        progress.setMinimum(0);
        progress.setMaximum(doc.getLength());
        status.add(progress);
        status.revalidate();

        // start writing
        Writer out = new FileWriter(f);
        Segment text = new Segment();
        text.setPartialReturn(true);
        int charsLeft = doc.getLength();
        int offset = 0;
        while (charsLeft > 0) {
          doc.getText(offset, Math.min(4096, charsLeft), text);
          out.write(text.array, text.offset, text.count);
          charsLeft -= text.count;
          offset += text.count;
          progress.setValue(offset);
          try {
            Thread.sleep(10);
          } catch (InterruptedException e) {
            Logger.getLogger(FileSaver.class.getName()).log(Level.SEVERE, null, e);
          }
        }
        out.flush();
        out.close();
      } catch (IOException e) {
        final String msg = e.getMessage();
        SwingUtilities.invokeLater(
            new Runnable() {

              public void run() {
                JOptionPane.showMessageDialog(
                    getFrame(),
                    "Could not save file: " + msg,
                    "Error saving file",
                    JOptionPane.ERROR_MESSAGE);
              }
            });
      } catch (BadLocationException e) {
        System.err.println(e.getMessage());
      }
      // we are done... get rid of progressbar
      status.removeAll();
      status.revalidate();
    }
예제 #9
0
  /**
   * Attempts to find the next subsequence of the input sequence that matches the pattern.
   *
   * <p>This method starts at the beginning of the input sequence or, if a previous invocation of
   * the method was successful and the matcher has not since been reset, at the first character not
   * matched by the previous match.
   *
   * @return the index of the first occurrence of the search string, starting at the specified
   *     offset, or -1 if no occurrence was found.
   */
  public int findNext() {
    // Don't match empty strings and don't match if we are at the end of the document.
    if (findString.length() == 0 || document.getLength() - findString.length() < startIndex) {
      return -1;
    }

    try {
      int nextMatch = 0; // index of next matching character

      // Iterate through all segments of the document starting from offset
      Segment text = new Segment();
      text.setPartialReturn(true);
      int offset = startIndex;
      int nleft = document.getLength() - startIndex;
      while (nleft > 0) {
        document.getText(offset, nleft, text);

        // Iterate through the characters in the current segment
        char next = text.first();
        for (text.first(); next != Segment.DONE; next = text.next()) {

          // Check if the current character matches with the next
          // search character.
          char current = text.current();
          if (current == matchUpperCase[nextMatch] || current == matchLowerCase[nextMatch]) {
            nextMatch++;

            // Did we match all search characters?
            if (nextMatch == matchLowerCase.length) {
              int foundIndex =
                  text.getIndex() - text.getBeginIndex() + offset - matchLowerCase.length + 1;
              if (matchType == MatchType.CONTAINS) {
                return foundIndex;
                // break; <- never reached
              } else if (matchType == MatchType.STARTS_WITH) {
                if (!isWordChar(foundIndex - 1)) {
                  return foundIndex;
                }
              } else if (matchType == MatchType.FULL_WORD) {
                if (!isWordChar(foundIndex - 1)
                    && !isWordChar(foundIndex + matchLowerCase.length)) {
                  return foundIndex;
                }
              }
              nextMatch = 0;
            }
          } else {
            nextMatch = 0;
          }
        }

        // Move forward to the next segment
        nleft -= text.count;
        offset += text.count;
      }
      return -1;
    } catch (BadLocationException e) {
      throw new IndexOutOfBoundsException();
    }
  }
  private void validateRegions() {
    if (region_map == null) return;

    synchronized (region_map) {
      if (regions_valid) return;

      Segment s = new Segment();

      region_map.clear();

      for (BaleRegion br : fragment_regions) {
        RegionData rd = new RegionData(indent_size);
        region_map.put(br, rd);
        int soff = br.getStart();
        int eoff = br.getEnd();
        if (eoff < soff) continue;
        try {
          base_document.getText(soff, eoff - soff, s);
        } catch (BadLocationException e) {
          BoardLog.logE("BALE", "Problem getting region indentation", e);
          continue;
        }
        int ln = s.length();

        LineData ld;
        boolean sol = true;
        for (int i = 0; i < ln; ++i) {
          char c = s.charAt(i);
          if (sol) {
            ld = computeLineData(i, s);
            rd.add(ld);
            sol = false;
          }
          if (c == '\n') sol = true;
        }
        if (!sol) {
          ld = computeLineData(ln, s);
          rd.add(ld);
          ++ln;
        }
      }

      regions_valid = true;
    }
  }
예제 #11
0
  /**
   * Attempts to find the previous subsequence of the input sequence that matches the pattern.
   *
   * <p>This method starts at the beginning of the input sequence or, if a previous invocation of
   * the method was successful and the matcher has not since been reset, at the first character not
   * matched by the previous match.
   *
   * @return the index of the first occurrence of the search string, starting at the specified
   *     offset, or -1 if no occurrence was found.
   */
  public int findPrevious() {
    // Don't match empty strings and don't match if we are at the beginning of the document.
    if (findString.length() == 0 || startIndex < findString.length() - 1) {
      // System.out.println("too close to start");
      return -1;
    }

    try {
      int nextMatch = matchLowerCase.length - 1; // index of next matching character

      // For simplicity, we request all text of the document in a single
      // segment.
      Segment text = new Segment();
      text.setPartialReturn(false);
      document.getText(0, startIndex + 1, text);

      // Iterate through the characters in the current segment
      char previous = text.last();
      // System.out.println("previus isch "+previous);
      for (text.last(); previous != Segment.DONE; previous = text.previous()) {

        // Check if the current character matches with the next
        // search character.
        char current = text.current();
        if (current == matchUpperCase[nextMatch] || current == matchLowerCase[nextMatch]) {
          nextMatch--;
          // System.out.println("matched "+nextMatch);
          // Did we match all search characters?
          if (nextMatch == -1) {
            int foundIndex = text.getIndex() - text.getBeginIndex();
            // System.out.println("found index:"+foundIndex);
            if (matchType == MatchType.CONTAINS) {
              return foundIndex;
            } else if (matchType == MatchType.STARTS_WITH) {
              if (!isWordChar(foundIndex - 1)) {
                return foundIndex;
              }
            } else if (matchType == MatchType.FULL_WORD) {
              if (!isWordChar(foundIndex - 1) && !isWordChar(foundIndex + matchLowerCase.length)) {
                return foundIndex;
              }
            }
            nextMatch = matchLowerCase.length - 1;
          }
        } else {
          nextMatch = matchLowerCase.length - 1;
        }
      }

      return -1;
    } catch (BadLocationException e) {
      throw new IndexOutOfBoundsException();
    }
  }
  /** ***************************************************************************** */
  private LineData computeLineData(int offset, Segment s) {
    int delchar = 0;
    int addchar = 0;
    int indent = 0;
    int ln = s.length();
    boolean havetab = false;

    for (int i = offset; indent < indent_size; ++i) {
      char c = (i < ln ? s.charAt(i) : '\n');
      if (c == ' ') {
        ++indent;
        ++delchar;
      } else if (c == '\t') {
        havetab = true;
        indent = nextTabPosition(indent);
        if (indent > indent_size) {
          delchar = (i - offset + 1);
          addchar = indent - indent_size;
          break;
        } else {
          ++delchar;
        }
      } else if (c == '\n') {
        if (havetab) {
          delchar = (i - offset);
          addchar = indent_size;
        } else {
          addchar = indent_size - (i - offset);
        }
        break;
      } else {
        BoardLog.logE("BALE", "Minimum space compute incorrectly");
        break;
      }
    }

    return new LineData(offset, addchar, delchar);
  }
예제 #13
0
  public void getChars(int offset, int length, Segment chars) throws BadLocationException {

    checkBounds(offset, length, length());

    if ((offset + length) <= gapStart) { // completely below gap
      chars.array = charArray;
      chars.offset = offset;

    } else if (offset >= gapStart) { // completely above gap
      chars.array = charArray;
      chars.offset = offset + gapLength;

    } else { // spans the gap, must copy
      chars.array = copySpanChars(offset, length);
      chars.offset = 0;
    }

    chars.count = length;
  }
예제 #14
0
  /**
   * Prints a <code>Document</code> using the specified font, word wrapping on the characters ' ',
   * '\t', '\n', ',', '.', and ';'. This method is expected to be called from Printable
   * 'print(Graphics g)' functions.
   *
   * @param g The graphics context to write to.
   * @param textComponent The <code>javax.swing.text.JTextComponent</code> whose text you're
   *     printing.
   * @param font The font to use for printing. If <code>null</code>, then <code>textComponent</code>
   *     's font is used.
   * @param pageIndex The page number to print.
   * @param pageFormat The format to print the page with.
   * @param tabSize The number of spaces to convert tabs to.
   */
  public static int printDocumentWordWrap(
      Graphics g,
      JTextComponent textComponent,
      Font font,
      int pageIndex,
      PageFormat pageFormat,
      int tabSize) {

    // Initialize our graphics object.
    g.setColor(Color.BLACK);
    g.setFont(font != null ? font : textComponent.getFont());

    // Initialize our static variables (these are used by our tab expander below).
    tabSizeInSpaces = tabSize;
    fm = g.getFontMetrics();
    int fontHeight = fm.getHeight();

    final int LINE_LENGTH_IN_PIXELS = (int) pageFormat.getImageableWidth();
    final int MAX_LINES_PER_PAGE = (int) pageFormat.getImageableHeight() / fontHeight;

    final int STARTING_LINE_NUMBER = MAX_LINES_PER_PAGE * pageIndex;

    // Create our tab expander.
    RPrintTabExpander tabExpander = new RPrintTabExpander();

    // The (x,y) coordinate to print at (in pixels, not characters).
    // Since y is the baseline of where we'll start printing (not the top-left
    // corner), we offset it by the font's ascent ( + 1 just for good measure).
    xOffset = (int) pageFormat.getImageableX();
    int y = (int) pageFormat.getImageableY() + fm.getAscent() + 1;

    // A counter to keep track of the number of lines that WOULD HAVE been
    // printed if we were printing all lines.
    int numPrintedLines = 0;

    // Keep going while there are more lines in the document.
    Document doc = textComponent.getDocument();
    rootElement = doc.getDefaultRootElement();
    numDocLines = rootElement.getElementCount(); // The number of lines in our document.
    currentDocLineNumber = 0; // The line number of the document we're currently on.
    int startingOffset = 0; // Used when a line is so long it has to be wrapped.
    while (currentDocLineNumber < numDocLines) {

      Segment currentLineSeg = new Segment();

      // Get the current line (as an Element), and its starting and ending offset in doc.
      Element currentLine = rootElement.getElement(currentDocLineNumber);
      int currentLineStart = currentLine.getStartOffset();
      int currentLineEnd = currentLine.getEndOffset();

      // Put the chars of this line in currentLineSeg, but only starting at our desired offset
      // (because this line may be the second part of a wrapped line, so we'd start after the part
      // that has already been printed).
      try {
        doc.getText(
            currentLineStart + startingOffset,
            currentLineEnd - (currentLineStart + startingOffset),
            currentLineSeg);
      } catch (BadLocationException ble) {
        System.err.println("BadLocationException in print (where there shouldn't be one!): " + ble);
        return Printable.NO_SUCH_PAGE;
      }

      // Remove any spaces and/or tabs from the end of the segment (would cause problems if you left
      // 'em).
      currentLineSeg = removeEndingWhitespace(currentLineSeg);

      // Figger out how long the line is, in pixels.
      int currentLineLengthInPixels =
          Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0);

      // System.err.println("'" + currentLineSeg + "' - " + currentLineLengthInPixels + "/" +
      // LINE_LENGTH_IN_PIXELS);
      // If it'll fit by itself on a printed line, great.
      if (currentLineLengthInPixels <= LINE_LENGTH_IN_PIXELS) {
        currentDocLineNumber += 1; // We (will) have printed one more line from the document.
        startingOffset = 0; // Start at the first character in the new document line.
      }

      // If it won't fit on a printed line by itself (i.e., it needs to be wrapped)...
      else {

        // Loop while the current line is too long to fit on a printed line.
        int currentPos = -1;
        while (currentLineLengthInPixels > LINE_LENGTH_IN_PIXELS) {

          // System.err.println("'" + currentLineSeg + "' - " + currentLineLengthInPixels + "/" +
          // LINE_LENGTH_IN_PIXELS);

          // Remove any spaces and/or tabs from the end of the segment (would cause problems if you
          // left 'em).
          currentLineSeg = removeEndingWhitespace(currentLineSeg);

          // currentPos will be the last position in the current text of a "line break character."
          currentPos = -1;
          String currentLineString = currentLineSeg.toString();
          for (int i = 0; i < breakChars.length; i++) {
            // "+1" below so we include the character on the line.
            int pos = currentLineString.lastIndexOf(breakChars[i]) + 1;
            // if (pos>-1 && pos>currentPos)
            //	currentPos = pos;
            if (pos > 0 && pos > currentPos & pos != currentLineString.length()) currentPos = pos;
          }

          // If we didn't find a line break character, we'll simply break the line at
          // the last character that fits on a printed line.
          // So here, we set currentPos to be the position of the last character that fits
          // on the current printed line.
          if (currentPos == -1) {

            // Fix currentLineSeg so that it contains exactly enough text to fit in
            // LINE_LENGTH_IN_PIXELS pixels...
            currentPos = 0;
            do {
              currentPos++;
              try {
                doc.getText(currentLineStart + startingOffset, currentPos, currentLineSeg);
              } catch (BadLocationException ble) {
                System.err.println(ble);
                return Printable.NO_SUCH_PAGE;
              }
              currentLineLengthInPixels =
                  Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0);
            } while (currentLineLengthInPixels <= LINE_LENGTH_IN_PIXELS);
            currentPos--;
          }

          try {
            doc.getText((currentLineStart + startingOffset), currentPos, currentLineSeg);
          } catch (BadLocationException ble) {
            System.err.println("BadLocationException in print (a):");
            System.err.println(
                "==> currentLineStart: "
                    + currentLineStart
                    + "; startingOffset: "
                    + startingOffset
                    + "; currentPos: "
                    + currentPos);
            System.err.println(
                "==> Range: "
                    + (currentLineStart + startingOffset)
                    + " - "
                    + (currentLineStart + startingOffset + currentPos));
            ble.printStackTrace();
            return Printable.NO_SUCH_PAGE;
          }

          currentLineLengthInPixels =
              Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0);
        } // End of while (currentLineLengthInPixels > LINE_LENGTH_IN_PIXELS).

        startingOffset +=
            currentPos; // Where to start (offset from line's start), since this line wraps.
      } // End of else.

      numPrintedLines++;
      if (numPrintedLines > STARTING_LINE_NUMBER) {
        // g.drawString(currentLineSeg.toString(), xOffset,y);
        Utilities.drawTabbedText(currentLineSeg, xOffset, y, g, tabExpander, 0);
        y += fontHeight;
        if (numPrintedLines == STARTING_LINE_NUMBER + MAX_LINES_PER_PAGE)
          return Printable.PAGE_EXISTS;
      }
    }

    // Now, the whole document has been "printed."  Decide if this page had any text on it or not.
    if (numPrintedLines > STARTING_LINE_NUMBER) return Printable.PAGE_EXISTS;
    return Printable.NO_SUCH_PAGE;
  }
    boolean getText(Segment brtext, int voff, int len, Segment s) {
      s.array = new char[len + 1];
      s.count = 0;
      s.offset = 0;

      if (len == 0) return false;

      int spos = 0;
      int line = 0;

      // first find the line where the data starts
      for (int i = 1; i < num_lines; ++i) {
        int npos =
            spos
                + line_data[i].getOffset()
                - line_data[i - 1].getOffset()
                + line_data[i - 1].getViewDelta();
        if (voff < npos) break;
        spos = npos;
        line = i;
      }

      // now add the data
      int pos = spos;
      for (int i = line + 1; i < num_lines; ++i) {
        int rpos = line_data[i - 1].getOffset();
        rpos += line_data[i - 1].getDelete();
        int npos =
            spos
                + line_data[i].getOffset()
                - line_data[i - 1].getOffset()
                + line_data[i - 1].getViewDelta();
        int addct = (line_data[i - 1].getDelete() > 0 ? line_data[i - 1].getAdd() : 0);
        while (pos < npos) {
          char c;
          if (pos - spos < addct) c = ' ';
          else c = brtext.charAt(rpos + pos - spos - addct);
          if (pos >= voff) s.array[s.count++] = c;
          if (s.count == len) break;
          ++pos;
        }
        spos = npos;
        if (s.count == len) break;
      }

      boolean lastbad = false;

      if (s.count < len && num_lines > 0) {
        if (pos < voff) pos = voff;
        int rpos = line_data[num_lines - 1].getOffset();
        rpos += line_data[num_lines - 1].getDelete();
        int addct = line_data[num_lines - 1].getAdd();
        while (s.count < len) {
          char c;
          int idx = rpos + pos - spos - addct;
          if (pos - spos < addct) c = ' ';
          else if (idx < brtext.length()) c = brtext.charAt(idx);
          else {
            lastbad = true;
            c = '\n';
          }
          s.array[s.count++] = c;
          ++pos;
        }
      } else if (s.count < len) {
        while (s.count < len) {
          s.array[s.count++] = '\n';
        }
        lastbad = true;
      }

      return lastbad;
    }
예제 #16
0
  /**
   * Iterates over the Element tree and controls the writing out of all the tags and its attributes.
   *
   * @exception IOException on any I/O error
   * @exception BadLocationException if pos represents an invalid location within the document.
   */
  public void write() throws IOException, BadLocationException {
    ElementIterator it = getElementIterator();
    Element current = null;
    Element next = null;

    wroteHead = false;
    setCurrentLineLength(0);
    replaceEntities = false;
    setCanWrapLines(false);
    if (segment == null) {
      segment = new Segment();
    }
    inPre = false;
    boolean forcedBody = false;
    while ((next = it.next()) != null) {
      if (!inRange(next)) {
        if (completeDoc
            && next.getAttributes().getAttribute(StyleConstants.NameAttribute) == HTML.Tag.BODY) {
          forcedBody = true;
        } else {
          continue;
        }
      }
      if (current != null) {

        /*
          if next is child of current increment indent
        */

        if (indentNeedsIncrementing(current, next)) {
          incrIndent();
        } else if (current.getParentElement() != next.getParentElement()) {
          /*
             next and current are not siblings
             so emit end tags for items on the stack until the
             item on top of the stack, is the parent of the
             next.
          */
          Element top = (Element) blockElementStack.peek();
          while (top != next.getParentElement()) {
            /*
               pop() will return top.
            */
            blockElementStack.pop();
            if (!synthesizedElement(top)) {
              AttributeSet attrs = top.getAttributes();
              if (!matchNameAttribute(attrs, HTML.Tag.PRE) && !isFormElementWithContent(attrs)) {
                decrIndent();
              }
              endTag(top);
            }
            top = (Element) blockElementStack.peek();
          }
        } else if (current.getParentElement() == next.getParentElement()) {
          /*
             if next and current are siblings the indent level
             is correct.  But, we need to make sure that if current is
             on the stack, we pop it off, and put out its end tag.
          */
          Element top = (Element) blockElementStack.peek();
          if (top == current) {
            blockElementStack.pop();
            endTag(top);
          }
        }
      }
      if (!next.isLeaf() || isFormElementWithContent(next.getAttributes())) {
        blockElementStack.push(next);
        startTag(next);
      } else {
        emptyTag(next);
      }
      current = next;
    }
    /* Emit all remaining end tags */

    /* A null parameter ensures that all embedded tags
       currently in the tags vector have their
       corresponding end tags written out.
    */
    closeOutUnwantedEmbeddedTags(null);

    if (forcedBody) {
      blockElementStack.pop();
      endTag(current);
    }
    while (!blockElementStack.empty()) {
      current = (Element) blockElementStack.pop();
      if (!synthesizedElement(current)) {
        AttributeSet attrs = current.getAttributes();
        if (!matchNameAttribute(attrs, HTML.Tag.PRE) && !isFormElementWithContent(attrs)) {
          decrIndent();
        }
        endTag(current);
      }
    }

    if (completeDoc) {
      writeAdditionalComments();
    }

    segment.array = null;
  }
 /** Returns the current text that is being tokenized (includes any changes that have been made) */
 public String getContext() {
   return text.toString();
 }
  /** ***************************************************************************** */
  private void setupSpacing() {
    // get the tab_size from appropriate property
    BoardProperties bp = BoardProperties.getProperties("Bale");
    String v = bp.getProperty("indent.tabulation.size");
    if (v == null)
      v = BumpClient.getBump().getOption("org.eclipse.jdt.core.formatter.tabulation.size");
    if (v == null) v = bp.getProperty("Bale.tabsize");
    tab_size = 8;
    try {
      if (v != null) tab_size = Integer.parseInt(v);
    } catch (NumberFormatException e) {
    }

    region_map = null;
    regions_valid = true;
    indent_size = 0;
    indent_string = null;

    // determine minimum indent
    Segment s = new Segment();
    int minsp = -1;
    for (BaleRegion br : fragment_regions) {
      int soff = br.getStart();
      int eoff = br.getEnd();
      try {
        base_document.getText(soff, eoff - soff, s);
      } catch (BadLocationException e) {
        BoardLog.logE(
            "BALE",
            "Problem getting region text "
                + soff
                + " "
                + eoff
                + " "
                + s.length()
                + " "
                + base_document.getLength(),
            e);
        // should this be "throw e;"
        continue;
      }

      int ln = s.length();

      boolean sol = true;
      int ind = 0;
      for (int i = 0; i < ln && (minsp < 0 || minsp >= MIN_INDENT); ++i) {
        char c = s.charAt(i);
        if (sol) {
          switch (c) {
            case ' ':
              ind += 1;
              break;
            case '\t':
              ind = nextTabPosition(ind);
              break;
            case '\n':
              ind = 0;
              break;
            default:
              if (minsp < 0 || minsp > ind) minsp = ind;
              sol = false;
              break;
          }
        } else if (c == '\n') {
          sol = true;
          ind = 0;
        }
      }

      if (minsp >= 0 && minsp < MIN_INDENT) break;
    }

    if (minsp <= 0 || minsp < MIN_INDENT) return;

    indent_size = minsp;
    indent_string = "";
    for (int i = 0; i < minsp; ++i) indent_string += " ";

    region_map = new HashMap<BaleRegion, RegionData>();
    regions_valid = false;
    for (BaleRegion br : fragment_regions) {
      for (int i = getRegionLength(br) - 1; i >= 0; --i) {
        fixupOffset(br, i, true);
      }
    }
  }
예제 #19
0
  public Rectangle listOffsetToView(
      RSyntaxTextArea textArea, TabExpander e, int pos, int x0, Rectangle rect) {

    int stableX = x0; // Cached ending x-coord. of last tab or token.
    TokenImpl token = this;
    FontMetrics fm = null;
    Segment s = new Segment();

    while (token != null && token.isPaintable()) {

      fm = textArea.getFontMetricsForTokenType(token.getType());
      if (fm == null) {
        return rect; // Don't return null as things'll error.
      }
      char[] text = token.text;
      int start = token.textOffset;
      int end = start + token.textCount;

      // If this token contains the position for which to get the
      // bounding box...
      if (token.containsPosition(pos)) {

        s.array = token.text;
        s.offset = token.textOffset;
        s.count = pos - token.getOffset();

        // Must use this (actually fm.charWidth()), and not
        // fm.charsWidth() for returned value to match up with where
        // text is actually painted on OS X!
        int w = Utilities.getTabbedTextWidth(s, fm, stableX, e, token.getOffset());
        rect.x = stableX + w;
        end = token.documentToToken(pos);

        if (text[end] == '\t') {
          rect.width = fm.charWidth(' ');
        } else {
          rect.width = fm.charWidth(text[end]);
        }

        return rect;

      }

      // If this token does not contain the position for which to get
      // the bounding box...
      else {
        s.array = token.text;
        s.offset = token.textOffset;
        s.count = token.textCount;
        stableX += Utilities.getTabbedTextWidth(s, fm, stableX, e, token.getOffset());
      }

      token = (TokenImpl) token.getNextToken();
    }

    // If we didn't find anything, we're at the end of the line. Return
    // a width of 1 (so selection highlights don't extend way past line's
    // text). A ConfigurableCaret will know to paint itself with a larger
    // width.
    rect.x = stableX;
    rect.width = 1;
    return rect;
  }