예제 #1
0
 @Override
 public void execute(final Object arg) {
   rend.updateScrollbar();
   // update scrollbar to display value within valid range
   scroll.pos(scroll.pos());
   rend.repaint();
 }
예제 #2
0
 /**
  * Jumps to the current, next or previous search string.
  *
  * @param dir search direction
  * @param select select hit
  */
 protected final void jump(final SearchDir dir, final boolean select) {
   // updates the visible area
   final int y = rend.jump(dir, select);
   final int h = getHeight();
   final int p = scroll.pos();
   final int m = y + rend.fontHeight() * 3 - h;
   if (y != -1 && (p < m || p > y)) scroll.pos(y - h / 2);
   rend.repaint();
 }
예제 #3
0
 @Override
 public void execute(final Object algn) {
   // updates the visible area
   final int p = scroll.pos();
   final int y = rend.cursorY();
   final int m = y + rend.fontHeight() * 3 - getHeight();
   if (p < m || p > y) {
     final int align = (Integer) algn;
     scroll.pos(align == 0 ? y : align == 1 ? y - getHeight() / 2 : m);
   }
   rend.repaint();
 }
예제 #4
0
 @Override
 public final void setEnabled(final boolean enabled) {
   super.setEnabled(enabled);
   rend.setEnabled(enabled);
   scroll.setEnabled(enabled);
   caret(enabled);
 }
예제 #5
0
 @Override
 public final void setFont(final Font f) {
   super.setFont(f);
   if (rend != null) {
     rend.setFont(f);
     scrollCode.invokeLater(true);
   }
 }
예제 #6
0
 /**
  * Performs a search.
  *
  * @param sc search context
  * @param jump jump to next hit
  */
 final void search(final SearchContext sc, final boolean jump) {
   try {
     rend.search(sc);
     if (!sc.search.isEmpty()) gui.status.setText(Util.info(Text.STRINGS_FOUND_X, sc.nr()));
     if (jump) jump(SearchDir.CURRENT, false);
   } catch (final Exception ex) {
     final String msg = Util.message(ex).replaceAll(Prop.NL + ".*", "");
     gui.status.setError(Text.REGULAR_EXPR + Text.COLS + msg);
   }
 }
예제 #7
0
  @Override
  public void mouseReleased(final MouseEvent e) {
    if (linkListener == null) return;

    if (SwingUtilities.isLeftMouseButton(e)) {
      editor.endSelection();
      // evaluate link
      if (!editor.selected()) {
        final TextIterator iter = rend.jump(e.getPoint());
        final String link = iter.link();
        if (link != null) linkListener.linkClicked(link);
      }
    }
  }
예제 #8
0
 /**
  * Replaces the text.
  *
  * @param rc replace context
  */
 final void replace(final ReplaceContext rc) {
   try {
     final int[] select = rend.replace(rc);
     if (rc.text != null) {
       final boolean sel = editor.selected();
       setText(rc.text);
       editor.select(select[0], select[sel ? 1 : 0]);
       release(Action.CHECK);
     }
     gui.status.setText(Text.STRINGS_REPLACED);
   } catch (final Exception ex) {
     final String msg = Util.message(ex).replaceAll(Prop.NL + ".*", "");
     gui.status.setError(Text.REGULAR_EXPR + Text.COLS + msg);
   }
 }
예제 #9
0
  /** Code completion. */
  private void complete() {
    if (selected()) return;

    // find first character
    final int caret = editor.pos(), startPos = editor.completionStart();
    final String prefix = string(substring(editor.text(), startPos, caret));
    if (prefix.isEmpty()) return;

    // find insertion candidates
    final TreeMap<String, String> tmp = new TreeMap<>();
    for (final Entry<String, String> entry : REPLACE.entrySet()) {
      final String key = entry.getKey();
      if (key.startsWith(prefix)) tmp.put(key, entry.getValue());
    }

    if (tmp.size() == 1) {
      // insert single candidate
      complete(tmp.values().iterator().next(), startPos);
    } else if (!tmp.isEmpty()) {
      // show popup menu
      final JPopupMenu pm = new JPopupMenu();
      final ActionListener al =
          new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent ae) {
              complete(ae.getActionCommand().replaceAll("^.*?\\] ", ""), startPos);
            }
          };

      for (final Entry<String, String> entry : tmp.entrySet()) {
        final JMenuItem mi = new JMenuItem("[" + entry.getKey() + "] " + entry.getValue());
        pm.add(mi);
        mi.addActionListener(al);
      }
      pm.addSeparator();
      final JMenuItem mi = new JMenuItem(Text.INPUT + Text.COLS + prefix);
      mi.setEnabled(false);
      pm.add(mi);

      final int[] cursor = rend.cursor();
      pm.show(this, cursor[0], cursor[1]);

      // highlight first entry
      final MenuElement[] me = {pm, (JMenuItem) pm.getComponent(0)};
      MenuSelectionManager.defaultManager().setSelectedPath(me);
    }
  }
예제 #10
0
 @Override
 public void execute(final Object down) {
   rend.updateScrollbar();
   cursorCode.execute((Boolean) down ? 2 : 0);
 }
예제 #11
0
  @Override
  public void keyPressed(final KeyEvent e) {
    // ignore modifier keys
    if (specialKey(e) || modifier(e)) return;

    // re-animate cursor
    caret(true);

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

    // set cursor position
    final boolean selected = editor.selected();
    final int pos = editor.pos();

    final boolean shift = e.isShiftDown();
    boolean down = true, consumed = true;

    // move caret
    int lc = Integer.MIN_VALUE;
    final byte[] txt = editor.text();
    if (NEXTWORD.is(e)) {
      editor.nextWord(shift);
    } else if (PREVWORD.is(e)) {
      editor.prevWord(shift);
      down = false;
    } else if (TEXTSTART.is(e)) {
      editor.textStart(shift);
      down = false;
    } else if (TEXTEND.is(e)) {
      editor.textEnd(shift);
    } else if (LINESTART.is(e)) {
      editor.lineStart(shift);
      down = false;
    } else if (LINEEND.is(e)) {
      editor.lineEnd(shift);
    } else if (PREVPAGE_RO.is(e) && !hist.active()) {
      lc = editor.linesUp(getHeight() / fh, false, lastCol);
      down = false;
    } else if (NEXTPAGE_RO.is(e) && !hist.active()) {
      lc = editor.linesDown(getHeight() / fh, false, lastCol);
    } else if (PREVPAGE.is(e) && !sc(e)) {
      lc = editor.linesUp(getHeight() / fh, shift, lastCol);
      down = false;
    } else if (NEXTPAGE.is(e) && !sc(e)) {
      lc = editor.linesDown(getHeight() / fh, shift, lastCol);
    } else if (NEXTLINE.is(e) && !MOVEDOWN.is(e)) {
      lc = editor.linesDown(1, shift, lastCol);
    } else if (PREVLINE.is(e) && !MOVEUP.is(e)) {
      lc = editor.linesUp(1, shift, lastCol);
      down = false;
    } else if (NEXTCHAR.is(e)) {
      editor.next(shift);
    } else if (PREVCHAR.is(e)) {
      editor.previous(shift);
      down = false;
    } else {
      consumed = false;
    }
    lastCol = lc == Integer.MIN_VALUE ? -1 : lc;

    // edit text
    if (hist.active()) {
      if (COMPLETE.is(e)) {
        complete();
        return;
      }

      if (MOVEDOWN.is(e)) {
        editor.move(true);
      } else if (MOVEUP.is(e)) {
        editor.move(false);
      } else if (DELLINE.is(e)) {
        editor.deleteLine();
      } else if (DELNEXTWORD.is(e)) {
        editor.deleteNext(true);
      } else if (DELLINEEND.is(e)) {
        editor.deleteNext(false);
      } else if (DELNEXT.is(e)) {
        editor.delete();
      } else if (DELPREVWORD.is(e)) {
        editor.deletePrev(true);
        down = false;
      } else if (DELLINESTART.is(e)) {
        editor.deletePrev(false);
        down = false;
      } else if (DELPREV.is(e)) {
        editor.deletePrev();
        down = false;
      } else {
        consumed = false;
      }
    }
    if (consumed) e.consume();

    final byte[] tmp = editor.text();
    if (txt != tmp) {
      // text has changed: add old text to history
      hist.store(tmp, pos, editor.pos());
      scrollCode.invokeLater(down);
    } else if (pos != editor.pos() || selected != editor.selected()) {
      // cursor position or selection state has changed
      cursorCode.invokeLater(down ? 2 : 0);
    }
  }
예제 #12
0
 /**
  * Selects the text at the specified position.
  *
  * @param point mouse position
  * @param start states if selection has just been started
  */
 private void select(final Point point, final boolean start) {
   editor.select(rend.jump(point).pos(), start);
   rend.repaint();
 }
예제 #13
0
 @Override
 public final void mouseWheelMoved(final MouseWheelEvent e) {
   scroll.pos(scroll.pos() + e.getUnitsToScroll() * 20);
   rend.repaint();
 }
예제 #14
0
 /** Selects the whole text. */
 private void selectAll() {
   editor.selectAll();
   rend.repaint();
 }
예제 #15
0
 /** Formats the selected text. */
 public final void format() {
   final int caret = editor.pos();
   if (editor.format(rend.getSyntax())) hist.store(editor.text(), caret, editor.pos());
   scrollCode.invokeLater(true);
 }
예제 #16
0
 /**
  * Sets the error marker.
  *
  * @param pos start of optional error mark
  */
 public final void error(final int pos) {
   editor.error(pos);
   rend.repaint();
 }
예제 #17
0
 /** Removes the error marker. */
 public final void resetError() {
   editor.error(-1);
   rend.repaint();
 }
예제 #18
0
 @Override
 public void actionPerformed(final ActionEvent e) {
   rend.caret(!rend.caret());
 }
예제 #19
0
 /**
  * Stops an old text cursor thread and, if requested, starts a new one.
  *
  * @param start start/stop flag
  */
 private void caret(final boolean start) {
   caretTimer.stop();
   if (start) caretTimer.start();
   rend.caret(start);
 }
예제 #20
0
 /**
  * Returns the line and column of the current caret position.
  *
  * @return line/column
  */
 public final int[] pos() {
   return rend.pos();
 }
예제 #21
0
 @Override
 public final void mouseMoved(final MouseEvent e) {
   if (linkListener == null) return;
   final TextIterator iter = rend.jump(e.getPoint());
   gui.cursor(iter.link() != null ? CURSORHAND : CURSORARROW);
 }
예제 #22
0
 /**
  * Sets a syntax highlighter.
  *
  * @param syntax syntax reference
  */
 public final void setSyntax(final Syntax syntax) {
   rend.setSyntax(syntax);
 }