예제 #1
0
  @Override
  public final void mousePressed(final MouseEvent e) {
    if (!isEnabled() || !isFocusable()) return;

    requestFocusInWindow();
    cursor(true);

    if (SwingUtilities.isMiddleMouseButton(e)) copy();

    final boolean marking = e.isShiftDown();
    final boolean nomark = !text.marked();
    if (SwingUtilities.isLeftMouseButton(e)) {
      final int c = e.getClickCount();
      if (c == 1) {
        // selection mode
        if (marking && nomark) text.startMark();
        rend.select(scroll.pos(), e.getPoint(), marking);
      } else if (c == 2) {
        text.selectWord();
      } else {
        text.selectLine();
      }
    } else if (nomark) {
      rend.select(scroll.pos(), e.getPoint(), false);
    }
  }
예제 #2
0
 @Override
 public final void setFont(final Font f) {
   super.setFont(f);
   if (rend != null) {
     rend.setFont(f);
     rend.repaint();
   }
 }
예제 #3
0
 /**
  * Displays the currently edited text area.
  *
  * @param align vertical alignment
  */
 final void showCursor(final int align) {
   // updates the visible area
   final int p = scroll.pos();
   final int y = rend.cursorY();
   final int m = y + rend.fontH() * 3 - getHeight();
   if (p < m || p > y) {
     scroll.pos(align == 0 ? y : align == 1 ? y - getHeight() / 2 : m);
     rend.repaint();
   }
 }
예제 #4
0
  /**
   * Sets the output text.
   *
   * @param t output text
   * @param s text size
   */
  public final void setText(final byte[] t, final int s) {
    // remove invalid characters and compare old with new string
    int ns = 0;
    final int ts = text.size();
    final byte[] tt = text.text();
    boolean eq = true;
    for (int r = 0; r < s; ++r) {
      final byte b = t[r];
      // support characters, highlighting codes, tabs and newlines
      if (b >= ' ' || b <= TokenBuilder.MARK || b == 0x09 || b == 0x0A) {
        t[ns++] = t[r];
      }
      eq &= ns < ts && ns < s && t[ns] == tt[ns];
    }
    eq &= ns == ts;

    // new text is different...
    if (!eq) {
      text = new BaseXTextTokens(Arrays.copyOf(t, ns));
      rend.setText(text);
      scroll.pos(0);
    }
    if (undo != null) undo.store(t.length != ns ? Arrays.copyOf(t, ns) : t, 0);
    SwingUtilities.invokeLater(calc);
  }
예제 #5
0
 /**
  * Displays the search term.
  *
  * @param y vertical position
  */
 final void scroll(final int y) {
   // updates the visible area
   final int p = scroll.pos();
   final int m = y + rend.fontH() * 3 - getHeight();
   if (y != 0 && (p < m || p > y)) scroll.pos(y - getHeight() / 2);
   repaint();
 }
예제 #6
0
  @Override
  public void keyTyped(final KeyEvent e) {
    if (undo == null || control(e) || DELNEXT.is(e) || DELPREV.is(e) || ESCAPE.is(e)) return;

    text.pos(text.cursor());
    // string to be added
    String ch = String.valueOf(e.getKeyChar());

    // remember if marked text is to be deleted
    boolean del = true;
    final byte[] txt = text.text();
    if (TAB.is(e)) {
      if (text.marked()) {
        // check if lines are to be indented
        final int s = Math.min(text.pos(), text.start());
        final int l = Math.max(text.pos(), text.start()) - 1;
        for (int p = s; p <= l && p < txt.length; p++) del &= txt[p] != '\n';
        if (!del) {
          text.indent(s, l, e.isShiftDown());
          ch = null;
        }
      } else {
        boolean c = true;
        for (int p = text.pos() - 1; p >= 0 && c; p--) {
          final byte b = txt[p];
          c = ws(b);
          if (b == '\n') break;
        }
        if (c) ch = "  ";
      }
    }

    // delete marked text
    if (text.marked() && del) text.delete();

    if (ENTER.is(e)) {
      // adopt indentation from previous line
      final StringBuilder sb = new StringBuilder(1).append(e.getKeyChar());
      int s = 0;
      for (int p = text.pos() - 1; p >= 0; p--) {
        final byte b = txt[p];
        if (b == '\n') break;
        if (b == '\t') {
          s += 2;
        } else if (b == ' ') {
          s++;
        } else {
          s = 0;
        }
      }
      for (int p = 0; p < s; p++) sb.append(' ');
      ch = sb.toString();
    }

    if (ch != null) text.add(ch);
    text.setCaret();
    rend.calc();
    showCursor(2);
    e.consume();
  }
예제 #7
0
 @Override
 public final void setEnabled(final boolean e) {
   super.setEnabled(e);
   rend.setEnabled(e);
   scroll.setEnabled(e);
   cursor(e);
 }
예제 #8
0
 /** Redoes the text. */
 final void redo() {
   if (undo == null) return;
   text = new BaseXTextTokens(undo.next());
   rend.setText(text);
   text.pos(undo.cursor());
   text.setCaret();
 }
예제 #9
0
  @Override
  public final void mouseDragged(final MouseEvent e) {
    if (!SwingUtilities.isLeftMouseButton(e)) return;

    // selection mode
    rend.select(scroll.pos(), e.getPoint(), true);
    final int y = Math.max(20, Math.min(e.getY(), getHeight() - 20));
    if (y != e.getY()) scroll.pos(scroll.pos() + e.getY() - y);
  }
예제 #10
0
 /**
  * Moves the error marker. {@code -1} removes the marker.
  *
  * @param s start of optional error mark
  */
 public final void error(final int s) {
   text.error(s);
   rend.repaint();
 }
예제 #11
0
 /**
  * Sets a new keyword.
  *
  * @param key new keyword
  * @return old keyword
  */
 String keyword(final String key) {
   return rend.keyword(key);
 }
예제 #12
0
  @Override
  public void keyPressed(final KeyEvent e) {
    if (modifier(e)) return;

    // operations that change the focus are put first..
    if (PREVTAB.is(e)) {
      transferFocusBackward();
      return;
    }
    if (NEXTTAB.is(e)) {
      transferFocus();
      return;
    }
    if (FIND.is(e)) {
      if (find != null) find.requestFocusInWindow();
      return;
    }

    // re-animate cursor
    cursor(true);

    // operations without cursor movement...
    final int fh = rend.fontH();
    if (SCROLLDOWN.is(e)) {
      scroll.pos(scroll.pos() + fh);
      return;
    }
    if (SCROLLUP.is(e)) {
      scroll.pos(scroll.pos() - fh);
      return;
    }
    if (COPY1.is(e) || COPY2.is(e)) {
      copy();
      return;
    }

    // set cursor position and reset last column
    text.pos(text.cursor());
    if (!PREVLINE.is(e) && !NEXTLINE.is(e)) lastCol = -1;

    if (FINDNEXT.is(e) || FINDNEXT2.is(e)) {
      scroll(rend.find(true, true));
      return;
    }
    if (FINDPREV.is(e) || FINDPREV2.is(e)) {
      scroll(rend.find(false, true));
      return;
    }
    if (SELECTALL.is(e)) {
      selectAll();
      return;
    }

    // necessary on Macs as the shift button is pressed for REDO
    final boolean marking =
        e.isShiftDown()
            && !DELNEXT.is(e)
            && !DELPREV.is(e)
            && !PASTE2.is(e)
            && !COMMENT.is(e)
            && !DELLINE.is(e)
            && !REDOSTEP.is(e);
    final boolean nomark = !text.marked();
    if (marking && nomark) text.startMark();
    boolean down = true;
    boolean consumed = true;

    // operations that consider the last text mark..
    final byte[] txt = text.text();
    if (NEXTWORD.is(e)) {
      text.nextToken(marking);
    } else if (PREVWORD.is(e)) {
      text.prevToken(marking);
      down = false;
    } else if (TEXTSTART.is(e)) {
      if (!marking) text.noMark();
      text.pos(0);
      down = false;
    } else if (TEXTEND.is(e)) {
      if (!marking) text.noMark();
      text.pos(text.size());
    } else if (LINESTART.is(e)) {
      text.bol(marking);
      down = false;
    } else if (LINEEND.is(e)) {
      text.eol(marking);
    } else if (NEXTPAGE.is(e)) {
      down(getHeight() / fh, marking);
    } else if (PREVPAGE.is(e)) {
      up(getHeight() / fh, marking);
      down = false;
    } else if (NEXT.is(e)) {
      text.next(marking);
    } else if (PREV.is(e)) {
      text.prev(marking);
      down = false;
    } else if (PREVLINE.is(e)) {
      up(1, marking);
      down = false;
    } else if (NEXTLINE.is(e)) {
      down(1, marking);
    } else if (FINDERROR.is(e)) {
      final int p = text.error();
      if (p != -1) setCaret(p);
    } else {
      consumed = false;
    }

    if (marking) {
      // refresh scroll position
      text.endMark();
      text.checkMark();
    } else if (undo != null) {
      // edit operations...
      if (CUT1.is(e) || CUT2.is(e)) {
        cut();
      } else if (PASTE1.is(e) || PASTE2.is(e)) {
        paste();
      } else if (UNDOSTEP.is(e)) {
        undo();
      } else if (REDOSTEP.is(e)) {
        redo();
      } else if (COMMENT.is(e)) {
        text.comment(rend.getSyntax());
      } else if (DELLINE.is(e)) {
        text.deleteLine();
      } else if (DELLINEEND.is(e) || DELNEXTWORD.is(e) || DELNEXT.is(e)) {
        if (nomark) {
          if (text.pos() == text.size()) return;
          text.startMark();
          if (DELNEXTWORD.is(e)) {
            text.nextToken(true);
          } else if (DELLINEEND.is(e)) {
            text.eol(true);
          } else {
            text.next(true);
          }
          text.endMark();
        }
        undo.cursor(text.cursor());
        text.delete();
      } else if (DELLINESTART.is(e) || DELPREVWORD.is(e) || DELPREV.is(e)) {
        if (nomark) {
          if (text.pos() == 0) return;
          text.startMark();
          if (DELPREVWORD.is(e)) {
            text.prevToken(true);
          } else if (DELLINESTART.is(e)) {
            text.bol(true);
          } else {
            text.prev();
          }
          text.endMark();
        }
        undo.cursor(text.cursor());
        text.delete();
        down = false;
      } else {
        consumed = false;
      }
    }
    if (consumed) e.consume();

    text.setCaret();
    if (txt != text.text()) rend.calc();
    showCursor(down ? 2 : 0);
  }
예제 #13
0
 /**
  * Finds the current keyword.
  *
  * @return {@code true} if the keyword was found
  */
 final boolean find() {
   final int p = rend.find(true, false);
   scroll(p);
   return p != 0;
 }
예제 #14
0
 /**
  * Finds the next/previous occurrence of the current keyword.
  *
  * @param forward forward search
  */
 final void find(final boolean forward) {
   scroll(rend.find(forward, true));
 }
예제 #15
0
 @Override
 public final void mouseWheelMoved(final MouseWheelEvent e) {
   scroll.pos(scroll.pos() + e.getUnitsToScroll() * 20);
   rend.repaint();
 }
예제 #16
0
 @Override
 public void actionPerformed(final ActionEvent e) {
   rend.cursor(!rend.cursor());
   rend.repaint();
 }
예제 #17
0
 /**
  * Sets a syntax highlighter.
  *
  * @param s syntax reference
  */
 public final void setSyntax(final BaseXSyntax s) {
   rend.setSyntax(s);
 }
예제 #18
0
 /** Finishes a command. */
 void finish() {
   text.setCaret();
   rend.calc();
   showCursor(2);
   release(false);
 }
예제 #19
0
 /** Selects the whole text. */
 final void selectAll() {
   text.selectAll();
   text.setCaret();
   rend.repaint();
 }
예제 #20
0
 /**
  * Handles the cursor thread; interrupts the old thread as soon as new one has been started.
  *
  * @param start start/stop flag
  */
 final void cursor(final boolean start) {
   cursor.stop();
   if (start) cursor.start();
   rend.cursor(start);
   rend.repaint();
 }
예제 #21
0
 @Override
 public void mouseReleased(final MouseEvent e) {
   if (SwingUtilities.isLeftMouseButton(e)) rend.stopSelect();
 }
예제 #22
0
 @Override
 public void run() {
   rend.calc();
   rend.repaint();
 }
예제 #23
0
 /**
  * Returns the cursor coordinates.
  *
  * @return line/column
  */
 public final String pos() {
   final int[] pos = rend.pos();
   return pos[0] + " : " + pos[1];
 }