예제 #1
1
    // TODO: make this a method of SikuliDocument, no need to pass document as argument
    private void changeIndentation(DefaultStyledDocument doc, int linenum, int columns)
        throws BadLocationException {
      PreferencesUser pref = PreferencesUser.getInstance();
      boolean expandTab = pref.getExpandTab();
      int tabWidth = pref.getTabWidth();

      if (linenum < 0) {
        throw new BadLocationException("Negative line", -1);
      }
      Element map = doc.getDefaultRootElement();
      if (linenum >= map.getElementCount()) {
        throw new BadLocationException("No such line", doc.getLength() + 1);
      }
      if (columns == 0) {
        return;
      }

      Element lineElem = map.getElement(linenum);
      int lineStart = lineElem.getStartOffset();
      int lineLength = lineElem.getEndOffset() - lineStart;
      String line = doc.getText(lineStart, lineLength);

      // determine current indentation and number of whitespace characters
      int wsChars;
      int indentation = 0;
      for (wsChars = 0; wsChars < line.length(); wsChars++) {
        char c = line.charAt(wsChars);
        if (c == ' ') {
          indentation++;
        } else if (c == '\t') {
          indentation += tabWidth;
        } else {
          break;
        }
      }

      int newIndentation = indentation + columns;
      if (newIndentation <= 0) {
        doc.remove(lineStart, wsChars);
        return;
      }

      // build whitespace string for new indentation
      StringBuilder newWs = new StringBuilder(newIndentation / tabWidth + tabWidth - 1);
      int ind = 0;
      if (!expandTab) {
        for (; ind + tabWidth <= newIndentation; ind += tabWidth) {
          newWs.append('\t');
        }
      }
      for (; ind < newIndentation; ind++) {
        newWs.append(' ');
      }
      doc.replace(lineStart, wsChars, newWs.toString(), null);
    }
예제 #2
0
 /**
  * @param str
  * @param severity
  */
 public void addLine(String str, int severity) {
   Style style = null;
   switch (severity) {
     case 0:
       str = str + "\n";
       style = send;
       break;
     case 1:
       str = "(Info) " + str + "\n";
       style = send;
       break;
     case 2:
       str = "(Warning) " + str + "\n";
       style = send;
       break;
     case 3:
       str = "(Error)" + str + "\n";
       style = send;
       break;
   }
   try {
     clean();
     document.insertString(document.getLength(), str, null);
     document.setParagraphAttributes(parnum, str.length(), style, false);
     parnum += str.length();
   } catch (Exception e) {
     e.printStackTrace();
   }
 }
  /*
   * Adds a field to the format being composed
   */
  public void addField() {
    DefaultMutableTreeNode node =
        (DefaultMutableTreeNode) availableFieldsComp.getTree().getLastSelectedPathComponent();
    if (node == null
        || !node.isLeaf()
        || !(node.getUserObject() instanceof DataObjDataFieldWrapper)) {
      return; // not really a field that can be added, just empty or a string
    }

    Object obj = node.getUserObject();
    if (obj instanceof DataObjDataFieldWrapper) {
      DataObjDataFieldWrapper wrapper = (DataObjDataFieldWrapper) obj;
      String sep = sepText.getText();
      if (StringUtils.isNotEmpty(sep)) {
        try {
          DefaultStyledDocument doc = (DefaultStyledDocument) formatEditor.getStyledDocument();
          if (doc.getLength() > 0) {
            doc.insertString(doc.getLength(), sep, null);
          }
        } catch (BadLocationException ble) {
        }
      }
      insertFieldIntoTextEditor(wrapper);
      setHasChanged(true);
    }
  }
예제 #4
0
 private void appendText(final DefaultStyledDocument doc, final String text, final Style style) {
   try {
     doc.insertString(doc.getLength(), text, style);
   } catch (final BadLocationException e) {
     throw new RuntimeException(e);
   }
 }
  public void displayString(String string) {
    String logMessage = sdf.format(cal.getTime()) + " " + string + '\n';

    try {
      doc.insertString(doc.getLength(), logMessage, null);
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }
 /*
  * Update the character count
  */
 private void charCount() {
   // Set a label to indicate how many characters remaining
   lblChars.setText((200 - docfilt.getLength()) + "/200");
   // disable/reenable create mp3 button when text area is empty/non-empty
   if (docfilt.getLength() == 0) {
     btnCreateMp.setEnabled(false);
     btnListen.setEnabled(false);
   } else {
     btnCreateMp.setEnabled(true);
     btnListen.setEnabled(true);
   }
 }
  public void testRemoveRedundantTagsFromDoc() throws BadLocationException {
    m_doc.insertString(0, "Foobar", SimpleAttributeSet.EMPTY);

    SimpleAttributeSet actualAttr = new SimpleAttributeSet();
    actualAttr.addAttribute(StyleConstants.Bold, Boolean.TRUE);
    m_doc.setCharacterAttributes(1, 2, actualAttr, true);

    actualAttr = new SimpleAttributeSet();
    actualAttr.addAttribute(StyleConstants.Bold, Boolean.TRUE);
    m_doc.setCharacterAttributes(3, 2, actualAttr, true);

    assertEquals("F<b>ooba</b>r", FormattedText.formatted(m_doc).getFormatted());
  }
예제 #8
0
  private void clean() { // TODO Minor Bug last ln is not colored right
    Element root = document.getDefaultRootElement();
    while (root.getElementCount() > maxLines) {
      try {
        parnum -= document.getText(0, root.getElement(0).getEndOffset()).length();
        document.remove(0, root.getElement(0).getEndOffset());

      } catch (BadLocationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
예제 #9
0
  public void addStyledText(String text, String style, boolean index) {
    Style s = _hexStyledDoc.getStyle(style);
    if (s == null) {
      PacketSamurai.getUserInterface().log("WARNING: Missing style for partType: " + style);
      style = "base";
    }

    try {
      _hexStyledDoc.insertString(_hexStyledDoc.getLength(), text, _hexStyledDoc.getStyle(style));
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }
예제 #10
0
  public void highlightSelectedPart(DataPartNode node) {
    Style style = _hexStyledDoc.getStyle("selected");

    try {
      String text = _hexStyledDoc.getText(node.getOffset(), node.getLength());
      // _hexStyledDoc.remove(node.getOffset(), node.getLength());
      // _hexStyledDoc.insertString(node.getOffset(), text, style);
      _hexStyledDoc.replace(node.getOffset(), node.getLength(), text, style);
      _hexDumpArea.setCaretPosition(node.getOffset());
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }
예제 #11
0
 @Override
 public void mouseMoved(MouseEvent event) {
   JTextPane textPane = (JTextPane) event.getSource();
   Point point = new Point(event.getX(), event.getY());
   int position = textPane.viewToModel(point);
   DefaultStyledDocument document = (DefaultStyledDocument) textPane.getDocument();
   Element element = document.getCharacterElement(position);
   AttributeSet attributeSet = element.getAttributes();
   String sLink = (String) attributeSet.getAttribute("link");
   if (sLink != null) {
     textPane.setCursor(handCursor);
   } else {
     textPane.setCursor(textCursor);
   }
 }
예제 #12
0
 @Override
 public String extract(InputStream input) throws Exception {
   log.debug("extract stream");
   String result = null;
   DefaultStyledDocument styledDoc = new DefaultStyledDocument();
   try {
     new RTFEditorKit().read(input, styledDoc, 0);
     result = styledDoc.getText(0, styledDoc.getLength());
   } catch (IOException e) {
     throw new Exception("Cannot extract text from a RTF document", e);
   } catch (BadLocationException e) {
     throw new Exception("Cannot extract text from a RTF document", e);
   }
   return result;
 }
  /** @param formatter */
  protected void setFormatterFromTextPane(final DataObjSwitchFormatter formatter) {
    // visit every character in the document text looking for fields
    // store characters not associated with components (jbutton) to make up the separator text
    DefaultStyledDocument doc = (DefaultStyledDocument) formatEditor.getStyledDocument();
    String text = formatEditor.getText();
    int docLen = doc.getLength();
    int lastFieldPos = 0;

    Vector<DataObjDataField> fields = new Vector<DataObjDataField>();
    // int cnt = 0;
    for (int i = 0; i < docLen; ++i) {
      Element element = doc.getCharacterElement(i);
      AttributeSet attrs = element.getAttributes();
      Object obj = attrs.getAttribute(StyleConstants.ComponentAttribute);
      // System.out.print(String.format("i: %d, lastFieldPos: %d cnt: %d, F: %s", i, lastFieldPos,
      // cnt, (obj instanceof FieldDefinitionComp ? "Y" : "N")));
      if (obj instanceof FieldDefinitionComp) {
        // System.out.println(cnt+"  "+(obj instanceof FieldDefinitionComp));
        // found button at the current position
        // create corresponding field
        String sepStr = (lastFieldPos <= i - 1) ? text.substring(lastFieldPos, i) : "";

        FieldDefinitionComp fieldDefBtn = (FieldDefinitionComp) obj;
        DataObjDataField fmtField = fieldDefBtn.getValue();
        fmtField.setSep(sepStr);
        fields.add(fmtField);

        // System.out.print(" Sep: ["+sepStr+"]");

        lastFieldPos = i + 1;
        // cnt++;
      }
    }

    // XXX: what do we do with the remaining of the text? right now we ignore it
    // That's because we can't create an empty formatter field just to use the separator...

    DataObjDataField[] fieldsArray = new DataObjDataField[fields.size()];
    for (int i = 0; i < fields.size(); ++i) {
      fieldsArray[i] = fields.elementAt(i);
    }

    DataObjDataFieldFormat singleFormatter =
        fieldsArray.length == 0
            ? null
            : new DataObjDataFieldFormat("", tableInfo.getClassObj(), false, "", "", fieldsArray);
    formatter.setSingle(singleFormatter);
  }
예제 #14
0
  /**
   * Searches for a quote token.
   *
   * @param content the content to search
   * @param startOffset the start of the search
   * @param endOffset the end of the search
   * @return the new position
   */
  protected int getQuoteToken(String content, int startOffset, int endOffset) {
    String quoteDelimiter = content.substring(startOffset, startOffset + 1);
    String escapeString = escapeQuote(quoteDelimiter);

    int index;
    int endOfQuote = startOffset;

    // skip over the escape quotes in this quote

    index = content.indexOf(escapeString, endOfQuote + 1);

    while ((index > -1) && (index < endOffset)) {
      endOfQuote = index + 1;
      index = content.indexOf(escapeString, endOfQuote);
    }

    // now find the matching delimiter

    index = content.indexOf(quoteDelimiter, endOfQuote + 1);

    if ((index < 0) || (index > endOffset)) endOfQuote = endOffset;
    else endOfQuote = index;

    m_Self.setCharacterAttributes(startOffset, endOfQuote - startOffset + 1, DEFAULT_STRING, false);

    return endOfQuote + 1;
  }
예제 #15
0
 private void updateDebug(
     final String command, final String returned, final Parameter... parameters) {
   if (documentDebug.getLength() > 0) {
     appendText(documentDebug, "\n", stylePunctuation);
   }
   appendText(documentDebug, command, styleCommand);
   appendText(documentDebug, "(", stylePunctuation);
   for (int i = 0; i < parameters.length; i++) {
     appendText(documentDebug, parameters[i].getName(), styleParamName);
     appendText(documentDebug, "=", stylePunctuation);
     appendText(documentDebug, parameters[i].getValue(), styleParamValue);
     if (i != parameters.length - 1) {
       appendText(documentDebug, ", ", stylePunctuation);
     }
   }
   appendText(documentDebug, ")", stylePunctuation);
   if (returned != null) {
     appendText(documentDebug, " = ", stylePunctuation);
     appendText(documentDebug, "\"" + returned + "\"", styleReturn);
   }
   SwingUtilities.invokeLater(
       new Runnable() {
         public void run() {
           textPaneDebug.scrollRectToVisible(
               new Rectangle(0, textPaneDebug.getHeight() * 2, 1, 1));
         }
       });
 }
예제 #16
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();
  }
예제 #17
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);
    }
  }
    /** @return */
    public int findFieldButtonPosition() {
      DefaultStyledDocument doc = (DefaultStyledDocument) formatEditor.getStyledDocument();
      int i, n = doc.getLength();
      Object obj = null;
      for (i = 0; i < n; ++i) {
        Element element = doc.getCharacterElement(i);
        AttributeSet attrs = element.getAttributes();
        obj = attrs.getAttribute(StyleConstants.ComponentAttribute);
        if (obj == this) {
          // found button at this position
          return i;
        }
      }

      // this should never happen because the button clicked must be inside text pane
      throw new RuntimeException("Button representing field in text pane was not found.");
    }
  /**
   * Asserts that the style is still set correctly on a styled document after encoding the document
   * into a string representation and decoding it back into a styled document again.
   */
  public void assertStyleRoundtrip(Object style) throws BadLocationException {
    m_doc.insertString(0, "Foobar Test", SimpleAttributeSet.EMPTY);

    SimpleAttributeSet actualAttr = new SimpleAttributeSet();
    actualAttr.addAttribute(style, Boolean.TRUE);
    m_doc.setCharacterAttributes(2, 2, actualAttr, true);

    StyledDocument doc = roundtrip(m_doc);

    AttributeSet exceptedAttr = doc.getCharacterElement(2).getAttributes();
    Boolean hasStyle = (Boolean) exceptedAttr.getAttribute(style);
    if (hasStyle != null) {
      assertTrue(hasStyle.booleanValue());
    } else {
      fail("Style not set");
    }
  }
예제 #20
0
 @Override
 public void remove(final int offs, final int len) throws BadLocationException {
   synchronized (doclock) {
     super.remove(offs, len);
     color(offs, -len);
     documentReader.update(offs, -len);
   }
 }
예제 #21
0
  /**
   * Override to apply syntax highlighting after the document has been updated.
   *
   * @param offset the offset
   * @param str the string to insert
   * @param a the attribute set, can be null
   * @throws BadLocationException if offset is invalid
   */
  public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
    if (m_AddMatchingEndBlocks && (m_BlockStart.length() > 0) && str.equals(m_BlockStart))
      str = addMatchingBlockEnd(offset);
    else if (m_UseBlanks && str.equals("\t")) str = m_Indentation;

    super.insertString(offset, str, a);
    processChangedLines(offset, str.length());
  }
예제 #22
0
 @Override
 public void insertString(final int offs, final String str, final AttributeSet a)
     throws BadLocationException {
   synchronized (doclock) {
     super.insertString(offs, str, a);
     color(offs, str.length());
     documentReader.update(offs, str.length());
   }
 }
  void listCommands() {
    if (ServiceManager.Current != null) {
      Scriptable scope = ServiceManager.Current.getScope();

      Object[] objs = scope.getIds();

      for (int i = 0; i < objs.length; i++) {
        Object obj = objs[i];

        try {
          int pos = commanddoc.getLength();

          commanddoc.insertString(pos, obj.toString() + "\n", responseStyle);
        } catch (BadLocationException ex) {
          Exceptions.printStackTrace(ex);
        }
      }
    }
  }
예제 #24
0
  /**
   * Initializes the document.
   *
   * @param props the properties to obtain the setup from
   */
  public SyntaxDocument(Properties props) {
    m_Self = this;
    m_RootElement = m_Self.getDefaultRootElement();
    m_Keywords = new HashMap<String, MutableAttributeSet>();
    m_FontSize = DEFAULT_FONT_SIZE;
    m_FontName = DEFAULT_FONT_FAMILY;
    putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");

    setup(props);
  }
예제 #25
0
파일: TerminalPanel.java 프로젝트: npk/lcmc
 /** Is called while a string is inserted. It checks if a cheat code is in the string. */
 @Override
 public void insertString(int offs, final String s, final AttributeSet a)
     throws BadLocationException {
   mPosLock.lock();
   if (offs < commandOffset) {
     terminalArea.setCaretPosition(commandOffset);
     offs = commandOffset;
   }
   if (userCommand) {
     if (editEnabled) {
       if (s.charAt(s.length() - 1) == '\n') {
         final int end = terminalArea.getDocument().getLength();
         super.insertString(end, "\n", commandColor);
         final String command = (getText(commandOffset, end - commandOffset) + s).trim();
         prevLine = end + 1;
         pos = end;
         maxPos = end;
         execCommand(command);
       } else {
         super.insertString(offs, s, commandColor);
       }
     }
     for (final String cheat : CHEATS_MAP.keySet()) {
       int cheatPos = CHEATS_MAP.get(cheat);
       if (s.equals(cheat.substring(cheatPos, cheatPos + 1))) {
         cheatPos++;
         CHEATS_MAP.put(cheat, cheatPos);
         if (cheatPos == cheat.length()) {
           for (final String ch : CHEATS_MAP.keySet()) {
             CHEATS_MAP.put(ch, 0);
           }
           startCheat(cheat);
         }
       } else {
         CHEATS_MAP.put(cheat, 0);
       }
     }
   } else {
     super.insertString(offs, s, a);
   }
   mPosLock.unlock();
 }
 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
   if ((getLength() + str.length()) <= size) {
     super.insertString(offs, str, a);
   } else {
     System.err.println(
         "Tried to make field "
             + (getLength() + str.length())
             + " characters long when max length is "
             + size);
     Toolkit.getDefaultToolkit().beep();
   }
 }
예제 #27
0
  /**
   * Parse the line to determine the appropriate highlighting.
   *
   * @param content the content to parse
   * @param line the line number
   * @throws BadLocationException if offsets are invalid
   */
  protected void applyHighlighting(String content, int line) throws BadLocationException {
    int startOffset = m_RootElement.getElement(line).getStartOffset();
    int endOffset = m_RootElement.getElement(line).getEndOffset() - 1;

    int lineLength = endOffset - startOffset;
    int contentLength = content.length();

    if (endOffset >= contentLength) endOffset = contentLength - 1;

    // check for multi line comments
    // (always set the comment attribute for the entire line)

    if (getMultiLineComment()) {
      if (endingMultiLineComment(content, startOffset, endOffset)
          || isMultiLineComment()
          || startingMultiLineComment(content, startOffset, endOffset)) {
        m_Self.setCharacterAttributes(
            startOffset, endOffset - startOffset + 1, DEFAULT_COMMENT, false);
        return;
      }
    }

    // set normal attributes for the line

    m_Self.setCharacterAttributes(startOffset, lineLength, DEFAULT_NORMAL, true);

    // check for single line comment

    int index = content.indexOf(getSingleLineCommentStart(), startOffset);

    if ((index > -1) && (index < endOffset)) {
      m_Self.setCharacterAttributes(index, endOffset - index + 1, DEFAULT_COMMENT, false);
      endOffset = index - 1;
    }

    // check for tokens

    checkForTokens(content, startOffset, endOffset);
  }
예제 #28
0
 private void addLineBreaksToHexDump(byte[] id, byte[] data) {
   // add linefeeds to the dump
   int lnCount = _hexDumpArea.getText().length() / 48;
   int rest = _hexDumpArea.getText().length() % 48;
   for (int i = 1; i <= lnCount; i++) {
     int pos = i * 67 - 20;
     try {
       int idx = i - 1;
       String ansci =
           idx == 0
               ? (Util.toAnsci(id, 0, id.length) + Util.toAnsci(data, 0, 16 - id.length))
               : Util.toAnsci(data, idx * 16 - id.length, idx * 16 + 16 - id.length);
       _hexStyledDoc.replace(pos, 1, "   " + ansci + "\n", _hexStyledDoc.getStyle("base"));
       // _hexStyledDoc.remove(pos,1);
       // _hexStyledDoc.insertString(pos, "\n", _hexStyledDoc.getStyle("base"));
     } catch (BadLocationException e1) {
       // TODO Auto-generated catch block
       e1.printStackTrace();
     }
   }
   // rest
   if (rest != 0) {
     try {
       int pos = lnCount * 67 + rest;
       String space = "";
       int spaceCount = 48 - rest;
       while (spaceCount-- > 0) space += " ";
       String ansci =
           lnCount == 0
               ? (Util.toAnsci(id, 0, id.length) + Util.toAnsci(data, 0, data.length - id.length))
               : Util.toAnsci(data, lnCount * 16 - id.length, data.length - id.length);
       _hexStyledDoc.insertString(pos, space + "  " + ansci, _hexStyledDoc.getStyle("base"));
     } catch (BadLocationException e1) {
       // TODO Auto-generated catch block
       e1.printStackTrace();
     }
   }
 }
예제 #29
0
    @Subscribe
    public void displayChatMessage(ChatEvent ev) {
        ReceivedChatMessage fm = createReceivedMessage(ev);
        formattedMessages.addLast(fm);

        if (client.getState() == JFrame.ICONIFIED) {
            messageReceivedWhileIconified = true;
        } else {
            setForceFocus();
        }

        DefaultStyledDocument doc = new DefaultStyledDocument();
        int offset = 0;
        try {
            for (ReceivedChatMessage msg : formattedMessages) {
                SimpleAttributeSet attrs = new SimpleAttributeSet();
                ColorConstants.setForeground(attrs, msg.color);
                String nick = msg.nickname;
                String text = msg.ev.getText();
                doc.insertString(offset, nick + ": ", attrs);
                offset += nick.length() + 2;

                Color textColor = client.getTheme().getTextColor();
                if (textColor == null) {
                    attrs = null;
                } else {
                    attrs = new SimpleAttributeSet();
                    ColorConstants.setForeground(attrs, client.getTheme().getTextColor());
                }
                doc.insertString(offset, text + "\n", attrs);
                offset += text.length() + 1;
            }
        } catch (BadLocationException e) {
            logger.error(e.getMessage(), e); //should never happen
        }
        messagesPane.setDocument(doc);
        repaint();
    }
예제 #30
0
 public void write(Writer out, Document doc, int pos, int len, Map<String, String> copiedImgs)
     throws IOException, BadLocationException {
   Debug.log(9, "SikuliEditorKit.write %d %d", pos, len);
   DefaultStyledDocument sdoc = (DefaultStyledDocument) doc;
   int i = pos;
   String absPath;
   while (i < pos + len) {
     Element e = sdoc.getCharacterElement(i);
     int start = e.getStartOffset(), end = e.getEndOffset();
     if (e.getName().equals(StyleConstants.ComponentElementName)) {
       // A image argument to be filled
       AttributeSet attr = e.getAttributes();
       Component com = StyleConstants.getComponent(attr);
       out.write(com.toString());
       if (copiedImgs != null
           && (com instanceof EditorPatternButton || com instanceof EditorPatternLabel)) {
         if (com instanceof EditorPatternButton) {
           absPath = ((EditorPatternButton) com).getFilename();
         } else {
           absPath = ((EditorPatternLabel) com).getFile();
         }
         String fname = (new File(absPath)).getName();
         copiedImgs.put(fname, absPath);
         Debug.log(3, "save image for copy&paste: " + fname + " -> " + absPath);
       }
     } else {
       if (start < pos) {
         start = pos;
       }
       if (end > pos + len) {
         end = pos + len;
       }
       out.write(doc.getText(start, end - start));
     }
     i = end;
   }
   out.close();
 }