private void notifyBatchFoldingProcessingDone(final boolean moveCaretFromCollapsedRegion) {
    rebuild();

    for (FoldingListener listener : myListeners) {
      listener.onFoldProcessingEnd();
    }

    myEditor.updateCaretCursor();
    myEditor.recalculateSizeAndRepaint();
    myEditor.getGutterComponentEx().updateSize();
    myEditor.getGutterComponentEx().repaint();

    for (Caret caret : myEditor.getCaretModel().getAllCarets()) {
      // There is a possible case that caret position is already visual position aware. But visual
      // position depends on number of folded
      // logical lines as well, hence, we can't be sure that target logical position defines correct
      // visual position because fold
      // regions have just changed. Hence, we use 'raw' logical position instead.
      LogicalPosition caretPosition = caret.getLogicalPosition().withoutVisualPositionInfo();
      int caretOffset = myEditor.logicalPositionToOffset(caretPosition);
      int selectionStart = caret.getSelectionStart();
      int selectionEnd = caret.getSelectionEnd();

      LogicalPosition positionToUse = null;
      int offsetToUse = -1;

      FoldRegion collapsed = myFoldTree.fetchOutermost(caretOffset);
      LogicalPosition savedPosition = caret.getUserData(SAVED_CARET_POSITION);
      if (savedPosition != null) {
        int savedOffset = myEditor.logicalPositionToOffset(savedPosition);
        FoldRegion collapsedAtSaved = myFoldTree.fetchOutermost(savedOffset);
        if (collapsedAtSaved == null) {
          positionToUse = savedPosition;
        } else {
          offsetToUse = collapsedAtSaved.getStartOffset();
        }
      }

      if (collapsed != null && positionToUse == null) {
        positionToUse = myEditor.offsetToLogicalPosition(collapsed.getStartOffset());
      }

      if (moveCaretFromCollapsedRegion && caret.isUpToDate()) {
        if (offsetToUse >= 0) {
          caret.moveToOffset(offsetToUse);
        } else if (positionToUse != null) {
          caret.moveToLogicalPosition(positionToUse);
        } else {
          caret.moveToLogicalPosition(caretPosition);
        }
      }

      caret.putUserData(SAVED_CARET_POSITION, savedPosition);

      if (isOffsetInsideCollapsedRegion(selectionStart)
          || isOffsetInsideCollapsedRegion(selectionEnd)) {
        caret.removeSelection();
      } else if (selectionStart < myEditor.getDocument().getTextLength()) {
        caret.setSelection(selectionStart, selectionEnd);
      }
    }

    if (mySavedCaretShift > 0) {
      final ScrollingModel scrollingModel = myEditor.getScrollingModel();
      scrollingModel.disableAnimation();
      scrollingModel.scrollVertically(
          myEditor.visibleLineToY(myEditor.getCaretModel().getVisualPosition().line)
              - mySavedCaretShift);
      scrollingModel.enableAnimation();
    }
  }
Esempio n. 2
0
  private void moveToLogicalPosition(LogicalPosition pos, boolean locateBeforeSoftWrap) {
    assertIsDispatchThread();
    myDesiredX = -1;
    validateCallContext();
    int column = pos.column;
    int line = pos.line;
    int softWrapLinesBefore = pos.softWrapLinesBeforeCurrentLogicalLine;
    int softWrapLinesCurrent = pos.softWrapLinesOnCurrentLogicalLine;
    int softWrapColumns = pos.softWrapColumnDiff;

    Document doc = myEditor.getDocument();

    if (column < 0) {
      column = 0;
      softWrapColumns = 0;
    }
    if (line < 0) {
      line = 0;
      softWrapLinesBefore = 0;
      softWrapLinesCurrent = 0;
    }

    int lineCount = doc.getLineCount();
    if (lineCount == 0) {
      line = 0;
    } else if (line > lineCount - 1) {
      line = lineCount - 1;
      softWrapLinesBefore = 0;
      softWrapLinesCurrent = 0;
    }

    EditorSettings editorSettings = myEditor.getSettings();

    if (!editorSettings.isVirtualSpace()
        && line < lineCount
        && !myEditor.getSelectionModel().hasBlockSelection()) {
      int lineEndOffset = doc.getLineEndOffset(line);
      int lineEndColumnNumber = myEditor.offsetToLogicalPosition(lineEndOffset).column;
      if (column > lineEndColumnNumber) {
        column = lineEndColumnNumber;
        if (softWrapColumns != 0) {
          softWrapColumns -= column - lineEndColumnNumber;
        }
      }
    }

    ((FoldingModelImpl) myEditor.getFoldingModel()).flushCaretPosition();

    VerticalInfo oldInfo = myCaretInfo;
    LogicalPosition oldCaretPosition = myLogicalCaret;

    LogicalPosition logicalPositionToUse;
    if (pos.visualPositionAware) {
      logicalPositionToUse =
          new LogicalPosition(
              line,
              column,
              softWrapLinesBefore,
              softWrapLinesCurrent,
              softWrapColumns,
              pos.foldedLines,
              pos.foldingColumnDiff);
    } else {
      logicalPositionToUse = new LogicalPosition(line, column);
    }
    setCurrentLogicalCaret(logicalPositionToUse);

    final int offset = myEditor.logicalPositionToOffset(myLogicalCaret);

    FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(offset);

    if (collapsedAt != null && offset > collapsedAt.getStartOffset()) {
      Runnable runnable =
          new Runnable() {
            public void run() {
              FoldRegion[] allCollapsedAt =
                  ((FoldingModelImpl) myEditor.getFoldingModel()).fetchCollapsedAt(offset);
              for (FoldRegion foldRange : allCollapsedAt) {
                foldRange.setExpanded(true);
              }
            }
          };

      myEditor.getFoldingModel().runBatchFoldingOperation(runnable);
    }

    myEditor.setLastColumnNumber(myLogicalCaret.column);
    myVisibleCaret = myEditor.logicalToVisualPosition(myLogicalCaret);

    myOffset = myEditor.logicalPositionToOffset(myLogicalCaret);
    LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength());

    myVisualLineStart =
        myEditor.logicalPositionToOffset(
            myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0)));
    myVisualLineEnd =
        myEditor.logicalPositionToOffset(
            myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0)));

    myEditor.updateCaretCursor();
    requestRepaint(oldInfo);

    if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(myEditor)) {
      int lineToUse = myVisibleCaret.line - 1;
      if (lineToUse >= 0) {
        moveToVisualPosition(
            new VisualPosition(
                lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse)));
        return;
      }
    }

    if (!oldCaretPosition.toVisualPosition().equals(myLogicalCaret.toVisualPosition())) {
      CaretEvent event = new CaretEvent(myEditor, oldCaretPosition, myLogicalCaret);
      for (CaretListener listener : myCaretListeners) {
        listener.caretPositionChanged(event);
      }
    }
  }
  private void doNotifyBatchFoldingProcessingDone() {
    myFoldTree.rebuild();

    for (FoldingListener listener : myListeners) {
      listener.onFoldProcessingEnd();
    }

    myEditor.updateCaretCursor();
    myEditor.recalculateSizeAndRepaint();
    if (myEditor.getGutterComponentEx().isFoldingOutlineShown()) {
      myEditor.getGutterComponentEx().repaint();
    }

    LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition();
    // There is a possible case that caret position is already visual position aware. But visual
    // position depends on number of folded
    // logical lines as well, hence, we can't be sure that target logical position defines correct
    // visual position because fold
    // regions have just changed. Hence, we use 'raw' logical position instead.
    if (caretPosition.visualPositionAware) {
      caretPosition = new LogicalPosition(caretPosition.line, caretPosition.column);
    }
    int caretOffset = myEditor.logicalPositionToOffset(caretPosition);
    boolean hasBlockSelection = myEditor.getSelectionModel().hasBlockSelection();
    int selectionStart = myEditor.getSelectionModel().getSelectionStart();
    int selectionEnd = myEditor.getSelectionModel().getSelectionEnd();

    int column = -1;
    int line = -1;
    int offsetToUse = -1;

    FoldRegion collapsed = myFoldTree.fetchOutermost(caretOffset);
    if (myCaretPositionSaved) {
      int savedOffset =
          myEditor.logicalPositionToOffset(new LogicalPosition(mySavedCaretY, mySavedCaretX));
      FoldRegion collapsedAtSaved = myFoldTree.fetchOutermost(savedOffset);
      if (collapsedAtSaved == null) {
        column = mySavedCaretX;
        line = mySavedCaretY;
      } else {
        offsetToUse = collapsedAtSaved.getStartOffset();
      }
    }

    if (collapsed != null && column == -1) {
      line = collapsed.getDocument().getLineNumber(collapsed.getStartOffset());
      column = myEditor.offsetToLogicalPosition(collapsed.getStartOffset()).column;
    }

    boolean oldCaretPositionSaved = myCaretPositionSaved;

    if (offsetToUse >= 0) {
      myEditor.getCaretModel().moveToOffset(offsetToUse);
    } else if (column != -1) {
      myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(line, column));
    } else {
      myEditor.getCaretModel().moveToLogicalPosition(caretPosition);
    }

    myCaretPositionSaved = oldCaretPositionSaved;

    if (!hasBlockSelection && selectionStart < myEditor.getDocument().getTextLength()) {
      myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd);
    }

    if (mySavedCaretShift > 0) {
      myEditor.getScrollingModel().disableAnimation();
      int scrollTo =
          myEditor.visibleLineToY(myEditor.getCaretModel().getVisualPosition().line)
              - mySavedCaretShift;
      myEditor.getScrollingModel().scrollVertically(scrollTo);
      myEditor.getScrollingModel().enableAnimation();
    }
  }
Esempio n. 4
0
  public void moveToVisualPosition(@NotNull VisualPosition pos) {
    assertIsDispatchThread();
    validateCallContext();
    myDesiredX = -1;
    int column = pos.column;
    int line = pos.line;

    if (column < 0) column = 0;

    if (line < 0) line = 0;

    int lastLine = myEditor.getVisibleLineCount() - 1;
    if (lastLine <= 0) {
      lastLine = 0;
    }

    if (line > lastLine) {
      line = lastLine;
    }

    EditorSettings editorSettings = myEditor.getSettings();

    if (!editorSettings.isVirtualSpace() && line <= lastLine) {
      int lineEndColumn = EditorUtil.getLastVisualLineColumnNumber(myEditor, line);
      if (column > lineEndColumn) {
        column = lineEndColumn;
      }

      if (column < 0 && line > 0) {
        line--;
        column = EditorUtil.getLastVisualLineColumnNumber(myEditor, line);
      }
    }

    myVisibleCaret = new VisualPosition(line, column);

    VerticalInfo oldInfo = myCaretInfo;
    LogicalPosition oldPosition = myLogicalCaret;

    setCurrentLogicalCaret(myEditor.visualToLogicalPosition(myVisibleCaret));
    myOffset = myEditor.logicalPositionToOffset(myLogicalCaret);
    LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength());

    myVisualLineStart =
        myEditor.logicalPositionToOffset(
            myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0)));
    myVisualLineEnd =
        myEditor.logicalPositionToOffset(
            myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0)));

    ((FoldingModelImpl) myEditor.getFoldingModel()).flushCaretPosition();

    myEditor.setLastColumnNumber(myVisibleCaret.column);
    myEditor.updateCaretCursor();
    requestRepaint(oldInfo);

    if (oldPosition.column != myLogicalCaret.column || oldPosition.line != myLogicalCaret.line) {
      CaretEvent event = new CaretEvent(myEditor, oldPosition, myLogicalCaret);

      for (CaretListener listener : myCaretListeners) {
        listener.caretPositionChanged(event);
      }
    }
  }