private int selectionSpan(SelectionModel sm, int orientation) {
   if (orientation == SwingConstants.VERTICAL) {
     return sm.getLastSelectedRow() - sm.getFirstSelectedRow() + 1;
   } else {
     return sm.getLastSelectedColumn() - sm.getFirstSelectedColumn() + 1;
   }
 }
    public void actionPerformed(ActionEvent e) {
      JGrid grid = (JGrid) e.getSource();
      SelectionModel sm = grid.getSelectionModel();
      anchorRow = sm.getAnchorRow();
      leadRow = sm.getLeadRow();
      anchorColumn = sm.getAnchorColumn();
      leadColumn = sm.getLeadColumn();

      int oldAnchorRow = anchorRow;
      int oldAnchorColumn = anchorColumn;

      if (grid.isEditing() && !grid.getCurrentCellEditor().stopCellEditing()) {
        return;
      }

      if (!inSelection) {
        moveWithinGridRange(grid, dx, dy, extend);
        if (!extend) {
          grid.changeSelection(anchorRow, anchorColumn, false, extend);
        } else {
          grid.changeSelection(leadRow, leadColumn, false, extend);
        }
      } else {
        if (moveWithinSelectedRange(grid, dx, dy, false)) {
          grid.changeSelection(anchorRow, anchorColumn, true, true);
        } else {
          grid.changeSelection(anchorRow, anchorColumn, false, false);
        }
      }
    }
  private void updateCursorHighlighting(boolean scroll) {
    hideBalloon();

    if (myCursorHighlighter != null) {
      HighlightManager.getInstance(mySearchResults.getProject())
          .removeSegmentHighlighter(mySearchResults.getEditor(), myCursorHighlighter);
      myCursorHighlighter = null;
    }

    final FindResult cursor = mySearchResults.getCursor();
    Editor editor = mySearchResults.getEditor();
    SelectionModel selection = editor.getSelectionModel();
    if (cursor != null) {
      Set<RangeHighlighter> dummy = new HashSet<RangeHighlighter>();
      highlightRange(
          cursor, new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, 0), dummy);
      if (!dummy.isEmpty()) {
        myCursorHighlighter = dummy.iterator().next();
      }

      if (scroll) {
        if (mySearchResults.getFindModel().isGlobal()) {
          FoldingModel foldingModel = editor.getFoldingModel();
          final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();

          foldingModel.runBatchFoldingOperation(
              new Runnable() {
                @Override
                public void run() {
                  for (FoldRegion region : allRegions) {
                    if (!region.isValid()) continue;
                    if (cursor.intersects(TextRange.create(region))) {
                      region.setExpanded(true);
                    }
                  }
                }
              });
          selection.setSelection(cursor.getStartOffset(), cursor.getEndOffset());

          editor.getCaretModel().moveToOffset(cursor.getEndOffset());
          editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
        } else {
          if (!SearchResults.insideVisibleArea(editor, cursor)) {
            LogicalPosition pos = editor.offsetToLogicalPosition(cursor.getStartOffset());
            editor.getScrollingModel().scrollTo(pos, ScrollType.CENTER);
          }
        }
      }
      editor
          .getScrollingModel()
          .runActionOnScrollingFinished(
              new Runnable() {
                @Override
                public void run() {
                  showReplacementPreview();
                }
              });
    }
  }
 private int compare(int i, SelectionModel sm, int orientation) {
   int min = 0;
   int max = 0;
   if (orientation == SwingConstants.VERTICAL) {
     min = sm.getFirstSelectedRow();
     max = sm.getLastSelectedRow();
   } else {
     min = sm.getFirstSelectedColumn();
     max = sm.getLastSelectedColumn();
   }
   return compare(i, min, max + 1);
 }
  public static void pasteTransferableAsBlock(
      Editor editor, @Nullable Producer<Transferable> producer) {
    String text = getStringContent(producer);
    if (text == null) return;

    int caretLine = editor.getCaretModel().getLogicalPosition().line;
    int originalCaretLine = caretLine;
    int selectedLinesCount = 0;

    final SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasBlockSelection()) {
      final LogicalPosition start = selectionModel.getBlockStart();
      final LogicalPosition end = selectionModel.getBlockEnd();
      assert start != null;
      assert end != null;
      LogicalPosition caret =
          new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column));
      selectedLinesCount = Math.abs(end.line - start.line);
      caretLine = caret.line;

      deleteSelectedText(editor);
      editor.getCaretModel().moveToLogicalPosition(caret);
    }

    LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition();

    String[] lines = LineTokenizer.tokenize(text.toCharArray(), false);
    if (lines.length > 1 || selectedLinesCount == 0) {
      int longestLineLength = 0;
      for (int i = 0; i < lines.length; i++) {
        String line = lines[i];
        longestLineLength = Math.max(longestLineLength, line.length());
        editor
            .getCaretModel()
            .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
        insertStringAtCaret(editor, line, false, true);
      }
      caretToRestore =
          new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength);
    } else {
      for (int i = 0; i <= selectedLinesCount; i++) {
        editor
            .getCaretModel()
            .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
        insertStringAtCaret(editor, text, false, true);
      }
      caretToRestore =
          new LogicalPosition(originalCaretLine, caretToRestore.column + text.length());
    }

    editor.getCaretModel().moveToLogicalPosition(caretToRestore);
    zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount);
  }
    public void actionPerformed(ActionEvent e) {
      JGrid grid = (JGrid) e.getSource();
      if (toLimit) {
        if (vertically) {
          int rowCount = grid.getRowCount();
          this.dx = 0;
          this.dy = forwards ? rowCount : -rowCount;
        } else {
          int colCount = grid.getColumnCount();
          this.dx = forwards ? colCount : -colCount;
          this.dy = 0;
        }
      } else {
        if (!(grid.getParent().getParent() instanceof JScrollPane)) {
          return;
        }

        Dimension delta = grid.getParent().getSize();
        SelectionModel sm = grid.getSelectionModel();

        int start = 0;
        if (vertically) {
          start = (extend) ? sm.getLeadRow() : sm.getAnchorRow();
        } else {
          start = (extend) ? sm.getLeadColumn() : sm.getAnchorColumn();
        }

        if (vertically) {
          Rectangle r = grid.getCellBounds(start, 0);
          r.y += forwards ? delta.height : -delta.height;
          this.dx = 0;
          int newRow = grid.rowAtPoint(r.getLocation());
          if (newRow == -1 && forwards) {
            newRow = grid.getRowCount();
          }
          this.dy = newRow - start;
        } else {
          Rectangle r = grid.getCellBounds(0, start);
          r.x += forwards ? delta.width : -delta.width;
          int newColumn = grid.columnAtPoint(r.getLocation());
          if (newColumn == -1 && forwards) {
            newColumn = grid.getColumnCount();
          }
          this.dx = newColumn - start;
          this.dy = 0;
        }
      }
      super.actionPerformed(e);
    }
  @Test
  public void ensureValueIsUpdatedByCorrectSelectionModelWhenSelectionModelIsChanged() {
    box.getItems().addAll("Apple", "Orange", "Banana");
    SelectionModel sm1 = box.getSelectionModel();
    sm1.select(1);
    assertEquals("Orange", box.getValue());
    SingleSelectionModel sm2 = new ChoiceBox.ChoiceBoxSelectionModel(box);
    box.setSelectionModel(sm2);

    sm1.select(2); // value should not change as we are using old SM
    assertEquals("Orange", box.getValue());

    sm2.select(0); // value should change, as we are using new SM
    assertEquals("Apple", box.getValue());
  }
  private void updateInSelectionHighlighters() {
    if (mySearchResults.getEditor() == null) return;
    final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel();
    int[] starts = selectionModel.getBlockSelectionStarts();
    int[] ends = selectionModel.getBlockSelectionEnds();

    final HashSet<RangeHighlighter> toRemove = new HashSet<RangeHighlighter>();
    Set<RangeHighlighter> toAdd = new HashSet<RangeHighlighter>();
    for (RangeHighlighter highlighter : myHighlighters) {
      boolean intersectsWithSelection = false;
      for (int i = 0; i < starts.length; ++i) {
        TextRange selectionRange = new TextRange(starts[i], ends[i]);
        intersectsWithSelection =
            selectionRange.intersects(highlighter.getStartOffset(), highlighter.getEndOffset())
                && selectionRange.getEndOffset() != highlighter.getStartOffset()
                && highlighter.getEndOffset() != selectionRange.getStartOffset();
        if (intersectsWithSelection) break;
      }

      final Object userData = highlighter.getUserData(IN_SELECTION_KEY);
      if (userData != null) {
        if (!intersectsWithSelection) {
          if (userData == IN_SELECTION2) {
            HighlightManager.getInstance(mySearchResults.getProject())
                .removeSegmentHighlighter(mySearchResults.getEditor(), highlighter);
            toRemove.add(highlighter);
          } else {
            highlighter.putUserData(IN_SELECTION_KEY, null);
          }
        }
      } else if (intersectsWithSelection) {
        TextRange cursor = mySearchResults.getCursor();
        if (cursor != null
            && highlighter.getStartOffset() == cursor.getStartOffset()
            && highlighter.getEndOffset() == cursor.getEndOffset()) continue;
        final RangeHighlighter toAnnotate =
            highlightRange(
                new TextRange(highlighter.getStartOffset(), highlighter.getEndOffset()),
                new TextAttributes(null, null, Color.WHITE, EffectType.ROUNDED_BOX, 0),
                toAdd);
        highlighter.putUserData(IN_SELECTION_KEY, IN_SELECTION1);
        toAnnotate.putUserData(IN_SELECTION_KEY, IN_SELECTION2);
      }
    }
    myHighlighters.removeAll(toRemove);
    myHighlighters.addAll(toAdd);
  }
 public void actionPerformed(ActionEvent e) {
   JGrid grid = (JGrid) e.getSource();
   if (!grid.hasFocus()) {
     CellEditor cellEditor = grid.getCurrentCellEditor();
     if (cellEditor != null && !cellEditor.stopCellEditing()) {
       return;
     }
     grid.requestFocus();
   }
   SelectionModel selectionModel = grid.getSelectionModel();
   int anchorRow = selectionModel.getAnchorRow();
   int anchorColumn = selectionModel.getAnchorColumn();
   grid.editCellAt(anchorRow, anchorColumn, null);
   Component editorComp = grid.getEditorComponent();
   if (editorComp != null) {
     editorComp.requestFocus();
   }
 }
  public static int insertStringAtCaret(
      Editor editor,
      @NotNull String s,
      boolean toProcessOverwriteMode,
      boolean toMoveCaret,
      int caretShift) {
    final SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasSelection()) {
      editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart(), true);
    }

    // There is a possible case that particular soft wraps become hard wraps if the caret is located
    // at soft wrap-introduced virtual
    // space, hence, we need to give editor a chance to react accordingly.
    editor.getSoftWrapModel().beforeDocumentChangeAtCaret();
    int oldOffset = editor.getCaretModel().getOffset();

    String filler = calcStringToFillVirtualSpace(editor);
    if (filler.length() > 0) {
      s = filler + s;
    }

    Document document = editor.getDocument();
    if (editor.isInsertMode() || !toProcessOverwriteMode) {
      if (selectionModel.hasSelection()) {
        oldOffset = selectionModel.getSelectionStart();
        document.replaceString(
            selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), s);
      } else {
        document.insertString(oldOffset, s);
      }
    } else {
      deleteSelectedText(editor);
      int lineNumber = editor.getCaretModel().getLogicalPosition().line;
      if (lineNumber >= document.getLineCount()) {
        return insertStringAtCaret(editor, s, false, toMoveCaret);
      }

      int endOffset = document.getLineEndOffset(lineNumber);
      document.replaceString(oldOffset, Math.min(endOffset, oldOffset + s.length()), s);
    }

    int offset = oldOffset + filler.length() + caretShift;
    if (toMoveCaret) {
      editor.getCaretModel().moveToOffset(offset, true);
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
      selectionModel.removeSelection();
    } else if (editor.getCaretModel().getOffset()
        != oldOffset) { // handling the case when caret model tracks document changes
      editor.getCaretModel().moveToOffset(oldOffset);
    }

    return offset;
  }
  /**
   * Instantiates a new Decision Theory selection model.
   *
   * @param model the underlying model
   * @param sampleSize the sample size
   */
  public DTSelectionModel(
      Model model, double sampleSize, BIC bic, TreeDistancesCache distancesCache) {
    super(model, sampleSize);

    double minBIC = bic.get(bic.getBestModel()).getValue();
    double sum = 0.0;
    for (SelectionModel selectionModel : bic.getSelectionModels()) {
      double distance =
          distancesCache.getDistance(model.getTree(), selectionModel.getModel().getTree());
      if (distance > 0) {
        double power = Math.log(distance) - selectionModel.getValue() + minBIC;
        if (power > -30) {
          sum += Math.exp(power);
        }
      }
    }

    this.value = sum;
  }
  public void performReplaceAll(Editor e) {
    if (!ReadonlyStatusHandler.ensureDocumentWritable(e.getProject(), e.getDocument())) return;
    if (mySearchResults.getFindModel() != null) {
      final FindModel copy = new FindModel();
      copy.copyFrom(mySearchResults.getFindModel());

      final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel();

      final int offset;
      if ((!selectionModel.hasSelection() && !selectionModel.hasBlockSelection())
          || copy.isGlobal()) {
        copy.setGlobal(true);
        offset = 0;
      } else {
        offset = selectionModel.getBlockSelectionStarts()[0];
      }
      FindUtil.replace(e.getProject(), e, offset, copy, this);
    }
  }
  public static void typeInStringAtCaretHonorBlockSelection(
      final Editor editor, final String str, final boolean toProcessOverwriteMode)
      throws ReadOnlyFragmentModificationException {
    Document doc = editor.getDocument();
    final SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasBlockSelection()) {
      RangeMarker guard = selectionModel.getBlockSelectionGuard();
      if (guard != null) {
        DocumentEvent evt = new MockDocumentEvent(doc, editor.getCaretModel().getOffset());
        ReadOnlyFragmentModificationException e =
            new ReadOnlyFragmentModificationException(evt, guard);
        EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
      } else {
        final LogicalPosition start = selectionModel.getBlockStart();
        final LogicalPosition end = selectionModel.getBlockEnd();
        assert start != null;
        assert end != null;

        int column = Math.min(start.column, end.column);
        int startLine = Math.min(start.line, end.line);
        int endLine = Math.max(start.line, end.line);
        deleteBlockSelection(editor);
        for (int i = startLine; i <= endLine; i++) {
          editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, column));
          insertStringAtCaret(editor, str, toProcessOverwriteMode, true);
        }
        selectionModel.setBlockSelection(
            new LogicalPosition(startLine, column + str.length()),
            new LogicalPosition(endLine, column + str.length()));
      }
    } else {
      insertStringAtCaret(editor, str, toProcessOverwriteMode, true);
    }
  }
Example #14
0
 private void makeSelectionForTaskDetailsTree(
     Set<PlotNameDto> plotTempSet,
     SelectionModel<PlotNameDto> plotNameSelectionModel,
     List<TaskDataDto> result) {
   if (!plotTempSet.isEmpty()) {
     for (PlotNameDto plotName : plotTempSet) {
       for (TaskDataDto td : result) {
         if (plotName.getTest().getTaskName().equals(td.getTaskName())) {
           plotNameSelectionModel.setSelected(new PlotNameDto(td, plotName.getPlotName()), true);
         }
       }
     }
   }
 }
Example #15
0
  /** Tests select responses to ctrl clicks that should result in select toggling */
  public void testCtrlSelectToggle() {
    FileTreeNode root = mockTree.getModel().getRoot();

    // Render the tree.
    mockTree.renderTree(-1);

    SignalEvent ctrlSignalEvent = new MockSignalEvent(true, false);

    // Select a bunch of nodes at the same tier.
    FileTreeNode AD1 = getNodeByPath(0);
    assertNotNull("Node did not get rendered!", AD1.getRenderedTreeNode());
    assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    JsoArray<FileTreeNode> expectedSelects = JsoArray.create();

    // Select the first top level dir.
    mockSelectionModel.selectNode(AD1, ctrlSignalEvent);
    expectedSelects.add(AD1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select the second top level dir
    FileTreeNode BD1 = getNodeByPath(1);
    mockSelectionModel.selectNode(BD1, ctrlSignalEvent);
    expectedSelects.add(BD1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(BD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select the first file.
    FileTreeNode AF1 = getNodeByPath(3);
    assertNotNull("Node did not get rendered!", AF1.getRenderedTreeNode());
    assertFalse(AF1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(AF1, ctrlSignalEvent);
    expectedSelects.add(AF1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Now toggle the second dir.
    mockSelectionModel.selectNode(BD1, ctrlSignalEvent);
    expectedSelects.remove(BD1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertFalse(BD1.getRenderedTreeNode().isSelected(resources.treeCss()));
  }
  /**
   * Emulates pressing <code>Enter</code> at current caret position.
   *
   * @param editor target editor
   * @param project target project
   * @param shifts two-elements array which is expected to be filled with the following info: 1. The
   *     first element holds added lines number; 2. The second element holds added symbols number;
   */
  private static void emulateEnter(
      @NotNull final Editor editor, @NotNull Project project, int[] shifts) {
    final DataContext dataContext = prepareContext(editor.getComponent(), project);
    int caretOffset = editor.getCaretModel().getOffset();
    Document document = editor.getDocument();
    SelectionModel selectionModel = editor.getSelectionModel();
    int startSelectionOffset = 0;
    int endSelectionOffset = 0;
    boolean restoreSelection = selectionModel.hasSelection();
    if (restoreSelection) {
      startSelectionOffset = selectionModel.getSelectionStart();
      endSelectionOffset = selectionModel.getSelectionEnd();
      selectionModel.removeSelection();
    }
    int textLengthBeforeWrap = document.getTextLength();
    int lineCountBeforeWrap = document.getLineCount();

    DataManager.getInstance()
        .saveInDataContext(dataContext, WRAP_LONG_LINE_DURING_FORMATTING_IN_PROGRESS_KEY, true);
    CommandProcessor commandProcessor = CommandProcessor.getInstance();
    try {
      Runnable command =
          new Runnable() {
            @Override
            public void run() {
              EditorActionManager.getInstance()
                  .getActionHandler(IdeActions.ACTION_EDITOR_ENTER)
                  .execute(editor, dataContext);
            }
          };
      if (commandProcessor.getCurrentCommand() == null) {
        commandProcessor.executeCommand(editor.getProject(), command, WRAP_LINE_COMMAND_NAME, null);
      } else {
        command.run();
      }
    } finally {
      DataManager.getInstance()
          .saveInDataContext(dataContext, WRAP_LONG_LINE_DURING_FORMATTING_IN_PROGRESS_KEY, null);
    }
    int symbolsDiff = document.getTextLength() - textLengthBeforeWrap;
    if (restoreSelection) {
      int newSelectionStart = startSelectionOffset;
      int newSelectionEnd = endSelectionOffset;
      if (startSelectionOffset >= caretOffset) {
        newSelectionStart += symbolsDiff;
      }
      if (endSelectionOffset >= caretOffset) {
        newSelectionEnd += symbolsDiff;
      }
      selectionModel.setSelection(newSelectionStart, newSelectionEnd);
    }
    shifts[0] = document.getLineCount() - lineCountBeforeWrap;
    shifts[1] = symbolsDiff;
  }
  public static void deleteSelectedText(Editor editor) {
    SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasBlockSelection()) deleteBlockSelection(editor);
    if (!selectionModel.hasSelection()) return;

    int selectionStart = selectionModel.getSelectionStart();
    int selectionEnd = selectionModel.getSelectionEnd();

    editor.getCaretModel().moveToOffset(selectionStart);
    selectionModel.removeSelection();
    editor.getDocument().deleteString(selectionStart, selectionEnd);
    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
  }
  public static void deleteBlockSelection(Editor editor) {
    SelectionModel selectionModel = editor.getSelectionModel();
    if (!selectionModel.hasBlockSelection()) return;

    LogicalPosition blockStart = selectionModel.getBlockStart();
    LogicalPosition blockEnd = selectionModel.getBlockEnd();
    if (blockStart == null || blockEnd == null) {
      return;
    }

    int startLine = blockStart.line;
    int endLine = blockEnd.line;

    int[] starts = selectionModel.getBlockSelectionStarts();
    int[] ends = selectionModel.getBlockSelectionEnds();

    for (int i = starts.length - 1; i >= 0; i--) {
      editor.getDocument().deleteString(starts[i], ends[i]);
    }

    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);

    zeroWidthBlockSelectionAtCaretColumn(editor, startLine, endLine);
  }
Example #19
0
  /** Tests select responses to ctrl clicks across tiers in the tree. */
  public void testCtrlSelectAcrossTiers() {
    FileTreeNode root = mockTree.getModel().getRoot();

    // Render the tree.
    mockTree.renderTree(-1);

    SignalEvent ctrlSignalEvent = new MockSignalEvent(true, false);

    // Select a bunch of nodes at the same tier.
    FileTreeNode AD1 = getNodeByPath(0);
    assertNotNull("Node did not get rendered!", AD1.getRenderedTreeNode());
    assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    JsoArray<FileTreeNode> expectedSelects = JsoArray.create();

    // Select the first top level dir.
    mockSelectionModel.selectNode(AD1, ctrlSignalEvent);
    expectedSelects.add(AD1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select the second top level dir
    FileTreeNode BD1 = getNodeByPath(1);
    mockSelectionModel.selectNode(BD1, ctrlSignalEvent);
    expectedSelects.add(BD1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(BD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select deeper. We should not allow cross depth selecting and should
    // replace it with just the new select.
    FileTreeNode AF2 = getNodeByPath(0, 0);
    assertNotNull("Node did not get rendered!", AF2.getRenderedTreeNode());
    assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(AF2, ctrlSignalEvent);
    expectedSelects.clear();
    expectedSelects.add(AF2);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select another peer node.
    FileTreeNode CF2 = getNodeByPath(0, 2);
    assertNotNull("Node did not get rendered!", CF2.getRenderedTreeNode());
    assertFalse(CF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(CF2, ctrlSignalEvent);
    expectedSelects.add(CF2);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(CF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select another peer node.
    FileTreeNode BF2 = getNodeByPath(0, 1);
    assertNotNull("Node did not get rendered!", BF2.getRenderedTreeNode());
    assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(BF2, ctrlSignalEvent);
    // We need to enforce sort order. AF2, BF2, CF2.
    expectedSelects.splice(1, 0, BF2);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(BF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(CF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Ensure that if we ctrl click back higher in the stack that we clear the
    // selected list.
    FileTreeNode AF1 = getNodeByPath(3);
    assertNotNull("Node did not get rendered!", AF1.getRenderedTreeNode());
    assertFalse(AF1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(AF1, ctrlSignalEvent);
    expectedSelects.clear();
    expectedSelects.add(AF1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF1.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(CF2.getRenderedTreeNode().isSelected(resources.treeCss()));
  }
Example #20
0
  /** Tests select responses to shift clicks that should do range selects. */
  public void testShiftSelect() {
    FileTreeNode root = mockTree.getModel().getRoot();

    // Render the tree.
    mockTree.renderTree(-1);

    SignalEvent shiftSignalEvent = new MockSignalEvent(false, true);

    FileTreeNode AD1 = getNodeByPath(0);
    assertNotNull("Node did not get rendered!", AD1.getRenderedTreeNode());
    assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    JsoArray<FileTreeNode> expectedSelects = JsoArray.create();

    // Select the first top level dir.
    mockSelectionModel.selectNode(AD1, shiftSignalEvent);
    expectedSelects.add(AD1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AD1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Shift select the last top level file.
    FileTreeNode BF1 = getNodeByPath(4);
    mockSelectionModel.selectNode(BF1, shiftSignalEvent);
    expectedSelects.add(getNodeByPath(1));
    expectedSelects.add(getNodeByPath(2));
    expectedSelects.add(getNodeByPath(3));
    expectedSelects.add(getNodeByPath(4));
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(BF1.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(getNodeByPath(2).getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(getNodeByPath(3).getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select the last file. It should zero the shift selection.
    mockSelectionModel.selectNode(BF1, shiftSignalEvent);
    expectedSelects.clear();
    expectedSelects.add(BF1);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(BF1.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(getNodeByPath(0).getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(getNodeByPath(1).getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(getNodeByPath(2).getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(getNodeByPath(3).getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select deeper. We should not allow cross depth selecting and
    // should replace it with just the new select.
    FileTreeNode AF2 = getNodeByPath(0, 0);
    assertNotNull("Node did not get rendered!", AF2.getRenderedTreeNode());
    assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(AF2, shiftSignalEvent);
    expectedSelects.clear();
    expectedSelects.add(AF2);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(BF1.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select the adjacent peer node.
    FileTreeNode BF2 = getNodeByPath(0, 1);
    assertNotNull("Node did not get rendered!", BF2.getRenderedTreeNode());
    assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(BF2, shiftSignalEvent);
    expectedSelects.add(BF2);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(BF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Select the last peer node.
    FileTreeNode DF2 = getNodeByPath(0, 3);
    assertNotNull("Node did not get rendered!", DF2.getRenderedTreeNode());
    assertFalse(DF2.getRenderedTreeNode().isSelected(resources.treeCss()));

    // Change the select.
    mockSelectionModel.selectNode(DF2, shiftSignalEvent);
    expectedSelects.add(getNodeByPath(0, 2));
    expectedSelects.add(getNodeByPath(0, 3));
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(DF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertTrue(getNodeByPath(0, 2).getRenderedTreeNode().isSelected(resources.treeCss()));

    // Ensure that if we shift click the last one we clear the selected list.
    mockSelectionModel.selectNode(DF2, shiftSignalEvent);
    expectedSelects.clear();
    expectedSelects.add(DF2);
    checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes());
    assertTrue(DF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss()));
    assertFalse(getNodeByPath(0, 2).getRenderedTreeNode().isSelected(resources.treeCss()));
  }
  public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
    myProject = project;
    myFile = file.getViewProvider().getPsi(file.getViewProvider().getBaseLanguage());
    myEditor = editor;

    PsiElement context = myFile.getContext();

    if (context != null && (context.textContains('\'') || context.textContains('\"'))) {
      String s = context.getText();
      if (StringUtil.startsWith(s, "\"") || StringUtil.startsWith(s, "\'")) {
        myFile = context.getContainingFile();
        myEditor = editor instanceof EditorWindow ? ((EditorWindow) editor).getDelegate() : editor;
      }
    }

    myDocument = myEditor.getDocument();
    if (!FileDocumentManager.getInstance().requestWriting(myDocument, project)) {
      return;
    }

    PsiDocumentManager.getInstance(project).commitDocument(myDocument);

    FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.comment.line");

    myCodeStyleManager = CodeStyleManager.getInstance(myProject);

    final SelectionModel selectionModel = myEditor.getSelectionModel();

    boolean hasSelection = selectionModel.hasSelection();
    myStartOffset = selectionModel.getSelectionStart();
    myEndOffset = selectionModel.getSelectionEnd();

    FoldRegion fold = myEditor.getFoldingModel().getCollapsedRegionAtOffset(myStartOffset);
    if (fold != null
        && fold.shouldNeverExpand()
        && fold.getStartOffset() == myStartOffset
        && fold.getEndOffset() == myEndOffset) {
      // Foldings that never expand are automatically selected, so the fact it is selected must not
      // interfer with commenter's logic
      hasSelection = false;
    }

    if (myDocument.getTextLength() == 0) return;

    while (true) {
      int lastLineEnd = myDocument.getLineEndOffset(myDocument.getLineNumber(myEndOffset));
      FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(lastLineEnd);
      if (collapsedAt != null) {
        final int endOffset = collapsedAt.getEndOffset();
        if (endOffset <= myEndOffset) {
          break;
        }
        myEndOffset = endOffset;
      } else {
        break;
      }
    }

    boolean wholeLinesSelected =
        !hasSelection
            || myStartOffset
                    == myDocument.getLineStartOffset(myDocument.getLineNumber(myStartOffset))
                && myEndOffset
                    == myDocument.getLineEndOffset(myDocument.getLineNumber(myEndOffset - 1)) + 1;

    boolean startingNewLineComment =
        !hasSelection
            && isLineEmpty(myDocument.getLineNumber(myStartOffset))
            && !Comparing.equal(
                IdeActions.ACTION_COMMENT_LINE,
                ActionManagerEx.getInstanceEx().getPrevPreformedActionId());
    doComment();

    if (startingNewLineComment) {
      final Commenter commenter = myCommenters[0];
      if (commenter != null) {
        String prefix;
        if (commenter instanceof SelfManagingCommenter) {
          prefix =
              ((SelfManagingCommenter) commenter)
                  .getCommentPrefix(
                      myStartLine,
                      myDocument,
                      myCommenterStateMap.get((SelfManagingCommenter) commenter));
          if (prefix == null) prefix = ""; // TODO
        } else {
          prefix = commenter.getLineCommentPrefix();
          if (prefix == null) prefix = commenter.getBlockCommentPrefix();
        }

        int lineStart = myDocument.getLineStartOffset(myStartLine);
        lineStart = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), lineStart, " \t");
        lineStart += prefix.length();
        lineStart = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), lineStart, " \t");
        if (lineStart > myDocument.getTextLength()) lineStart = myDocument.getTextLength();
        myEditor.getCaretModel().moveToOffset(lineStart);
        myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
      }
    } else {
      if (!hasSelection) {
        // Don't tweak caret position if we're already located on the last document line.
        LogicalPosition position = myEditor.getCaretModel().getLogicalPosition();
        if (position.line < myDocument.getLineCount() - 1) {
          int verticalShift =
              1
                  + myEditor.getSoftWrapModel().getSoftWrapsForLine(position.line).size()
                  - position.softWrapLinesOnCurrentLogicalLine;
          myEditor.getCaretModel().moveCaretRelatively(0, verticalShift, false, false, true);
        }
      } else {
        if (wholeLinesSelected) {
          selectionModel.setSelection(myStartOffset, selectionModel.getSelectionEnd());
        }
      }
    }
  }
  public void moveCaretRelatively(
      int columnShift,
      int lineShift,
      boolean withSelection,
      boolean blockSelection,
      boolean scrollToCaret) {
    assertIsDispatchThread();
    SelectionModel selectionModel = myEditor.getSelectionModel();
    int selectionStart = selectionModel.getLeadSelectionOffset();
    LogicalPosition blockSelectionStart =
        selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : getLogicalPosition();
    EditorSettings editorSettings = myEditor.getSettings();
    VisualPosition visualCaret = getVisualPosition();

    int desiredX = myDesiredX;
    if (columnShift == 0) {
      if (myDesiredX < 0) {
        desiredX = myEditor.visualPositionToXY(visualCaret).x;
      }
    } else {
      myDesiredX = desiredX = -1;
    }

    int newLineNumber = visualCaret.line + lineShift;
    int newColumnNumber = visualCaret.column + columnShift;
    if (desiredX >= 0 && !ApplicationManager.getApplication().isUnitTestMode()) {
      newColumnNumber =
          myEditor.xyToVisualPosition(
                  new Point(desiredX, Math.max(0, newLineNumber) * myEditor.getLineHeight()))
              .column;
    }

    Document document = myEditor.getDocument();
    if (!editorSettings.isVirtualSpace()
        && columnShift == 0
        && getLogicalPosition().softWrapLinesOnCurrentLogicalLine <= 0) {
      newColumnNumber = myEditor.getLastColumnNumber();
    } else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == 1) {
      int lastLine = document.getLineCount() - 1;
      if (lastLine < 0) lastLine = 0;
      if (EditorModificationUtil.calcAfterLineEnd(myEditor) >= 0
          && newLineNumber
              < myEditor.logicalToVisualPosition(new LogicalPosition(lastLine, 0)).line) {
        newColumnNumber = 0;
        newLineNumber++;
      }
    } else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == -1) {
      if (newColumnNumber < 0 && newLineNumber > 0) {
        newLineNumber--;
        newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber);
      }
    }

    if (newColumnNumber < 0) newColumnNumber = 0;

    // There is a possible case that caret is located at the first line and user presses 'Shift+Up'.
    // We want to select all text
    // from the document start to the current caret position then. So, we have a dedicated flag for
    // tracking that.
    boolean selectToDocumentStart = false;
    if (newLineNumber < 0) {
      selectToDocumentStart = true;
      newLineNumber = 0;

      // We want to move caret to the first column if it's already located at the first line and
      // 'Up' is pressed.
      newColumnNumber = 0;
      desiredX = -1;
    }

    VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber);
    int lastColumnNumber = newColumnNumber;
    if (!editorSettings.isCaretInsideTabs() && !myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
      LogicalPosition log =
          myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber));
      int offset = myEditor.logicalPositionToOffset(log);
      if (offset >= document.getTextLength()) {
        int lastOffsetColumn = myEditor.offsetToVisualPosition(document.getTextLength()).column;
        // We want to move caret to the last column if if it's located at the last line and 'Down'
        // is pressed.
        newColumnNumber = lastColumnNumber = Math.max(lastOffsetColumn, newColumnNumber);
        desiredX = -1;
      }
      CharSequence text = document.getCharsSequence();
      if (offset >= 0 && offset < document.getTextLength()) {
        if (text.charAt(offset) == '\t' && (columnShift <= 0 || offset == myOffset)) {
          if (columnShift <= 0) {
            newColumnNumber = myEditor.offsetToVisualPosition(offset).column;
          } else {
            SoftWrap softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset + 1);
            // There is a possible case that tabulation symbol is the last document symbol
            // represented on a visual line before
            // soft wrap. We can't just use column from 'offset + 1' because it would point on a
            // next visual line.
            if (softWrap == null) {
              newColumnNumber = myEditor.offsetToVisualPosition(offset + 1).column;
            } else {
              newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber);
            }
          }
        }
      }
    }

    pos = new VisualPosition(newLineNumber, newColumnNumber);
    if (columnShift != 0 && lineShift == 0 && myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
      LogicalPosition logical = myEditor.visualToLogicalPosition(pos);
      int softWrapOffset = myEditor.logicalPositionToOffset(logical);
      if (columnShift >= 0) {
        moveToOffset(softWrapOffset);
      } else {
        int line = myEditor.offsetToVisualLine(softWrapOffset - 1);
        moveToVisualPosition(
            new VisualPosition(line, EditorUtil.getLastVisualLineColumnNumber(myEditor, line)));
      }
    } else {
      moveToVisualPosition(pos);
      if (!editorSettings.isVirtualSpace() && columnShift == 0) {
        myEditor.setLastColumnNumber(lastColumnNumber);
      }
    }

    if (withSelection) {
      if (blockSelection) {
        selectionModel.setBlockSelection(blockSelectionStart, getLogicalPosition());
      } else {
        if (selectToDocumentStart) {
          selectionModel.setSelection(selectionStart, 0);
        } else if (pos.line >= myEditor.getVisibleLineCount()) {
          if (selectionStart < document.getTextLength()) {
            selectionModel.setSelection(selectionStart, document.getTextLength());
          }
        } else {
          selectionModel.setSelection(selectionStart, getVisualPosition(), getOffset());
        }
      }
    } else {
      selectionModel.removeSelection();
    }

    if (scrollToCaret) {
      myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
    }

    if (desiredX >= 0) {
      myDesiredX = desiredX;
    }

    EditorActionUtil.selectNonexpandableFold(myEditor);
  }
  private void dumpEditorMarkupAndSelection(PrintStream dumpStream) {
    dumpStream.println(mySearchResults.getFindModel());
    if (myReplacementPreviewText != null) {
      dumpStream.println("--");
      dumpStream.println("Replacement Preview: " + myReplacementPreviewText);
    }
    dumpStream.println("--");

    Editor editor = mySearchResults.getEditor();

    RangeHighlighter[] highlighters = editor.getMarkupModel().getAllHighlighters();
    List<Pair<Integer, Character>> ranges = new ArrayList<Pair<Integer, Character>>();
    for (RangeHighlighter highlighter : highlighters) {
      ranges.add(new Pair<Integer, Character>(highlighter.getStartOffset(), '['));
      ranges.add(new Pair<Integer, Character>(highlighter.getEndOffset(), ']'));
    }

    SelectionModel selectionModel = editor.getSelectionModel();

    if (selectionModel.getSelectionStart() != selectionModel.getSelectionEnd()) {
      ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionStart(), '<'));
      ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionEnd(), '>'));
    }
    ranges.add(new Pair<Integer, Character>(-1, '\n'));
    ranges.add(new Pair<Integer, Character>(editor.getDocument().getTextLength() + 1, '\n'));
    ContainerUtil.sort(
        ranges,
        new Comparator<Pair<Integer, Character>>() {
          @Override
          public int compare(Pair<Integer, Character> pair, Pair<Integer, Character> pair2) {
            int res = pair.first - pair2.first;
            if (res == 0) {

              Character c1 = pair.second;
              Character c2 = pair2.second;
              if (c1 == '<' && c2 == '[') {
                return 1;
              } else if (c1 == '[' && c2 == '<') {
                return -1;
              }
              return c1.compareTo(c2);
            }
            return res;
          }
        });

    Document document = editor.getDocument();
    for (int i = 0; i < ranges.size() - 1; ++i) {
      Pair<Integer, Character> pair = ranges.get(i);
      Pair<Integer, Character> pair1 = ranges.get(i + 1);
      dumpStream.print(
          pair.second
              + document.getText(
                  TextRange.create(
                      Math.max(pair.first, 0), Math.min(pair1.first, document.getTextLength()))));
    }
    dumpStream.println("\n--");

    if (NotFound) {
      dumpStream.println("Not Found");
      dumpStream.println("--");
      NotFound = false;
    }

    for (RangeHighlighter highlighter : highlighters) {
      dumpStream.println(highlighter + " : " + highlighter.getTextAttributes());
    }
    dumpStream.println("------------");
  }
  public final void move(Editor editor, final PsiFile file) {
    myMover.beforeMove(editor, myInfo, myIsDown);
    final Document document = editor.getDocument();
    final int start =
        StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.startLine);
    final int end = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.endLine);
    myInfo.range1 = document.createRangeMarker(start, end);

    String textToInsert = document.getCharsSequence().subSequence(start, end).toString();
    if (!StringUtil.endsWithChar(textToInsert, '\n')) textToInsert += '\n';

    final int start2 = document.getLineStartOffset(myInfo.toMove2.startLine);
    final int end2 = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove2.endLine);
    String textToInsert2 = document.getCharsSequence().subSequence(start2, end2).toString();
    if (!StringUtil.endsWithChar(textToInsert2, '\n')) textToInsert2 += '\n';
    myInfo.range2 = document.createRangeMarker(start2, end2);
    if (myInfo.range1.getStartOffset() < myInfo.range2.getStartOffset()) {
      myInfo.range1.setGreedyToLeft(true);
      myInfo.range1.setGreedyToRight(false);
      myInfo.range2.setGreedyToLeft(true);
      myInfo.range2.setGreedyToRight(true);
    } else {
      myInfo.range1.setGreedyToLeft(true);
      myInfo.range1.setGreedyToRight(true);
      myInfo.range2.setGreedyToLeft(true);
      myInfo.range2.setGreedyToRight(false);
    }

    final CaretModel caretModel = editor.getCaretModel();
    final int caretRelativePos = caretModel.getOffset() - start;
    final SelectionModel selectionModel = editor.getSelectionModel();
    final int selectionStart = selectionModel.getSelectionStart();
    final int selectionEnd = selectionModel.getSelectionEnd();
    final boolean hasSelection = selectionModel.hasSelection();

    // to prevent flicker
    caretModel.moveToOffset(0);

    // There is a possible case that the user performs, say, method move. It's also possible that
    // one (or both) of moved methods
    // are folded. We want to preserve their states then. The problem is that folding processing is
    // based on PSI element pointers
    // and the pointers behave as following during move up/down:
    //     method1() {}
    //     method2() {}
    // Pointer for the fold region from method1 points to 'method2()' now and vice versa (check
    // range markers processing on
    // document change for further information). I.e. information about fold regions statuses holds
    // the data swapped for
    // 'method1' and 'method2'. Hence, we want to apply correct 'collapsed' status.
    FoldRegion topRegion = null;
    FoldRegion bottomRegion = null;
    for (FoldRegion foldRegion : editor.getFoldingModel().getAllFoldRegions()) {
      if (!foldRegion.isValid()
          || (!contains(myInfo.range1, foldRegion) && !contains(myInfo.range2, foldRegion))) {
        continue;
      }
      if (contains(myInfo.range1, foldRegion) && !contains(topRegion, foldRegion)) {
        topRegion = foldRegion;
      } else if (contains(myInfo.range2, foldRegion) && !contains(bottomRegion, foldRegion)) {
        bottomRegion = foldRegion;
      }
    }

    document.insertString(myInfo.range1.getStartOffset(), textToInsert2);
    document.deleteString(
        myInfo.range1.getStartOffset() + textToInsert2.length(), myInfo.range1.getEndOffset());

    document.insertString(myInfo.range2.getStartOffset(), textToInsert);
    int s = myInfo.range2.getStartOffset() + textToInsert.length();
    int e = myInfo.range2.getEndOffset();
    if (e > s) {
      document.deleteString(s, e);
    }

    final Project project = file.getProject();
    PsiDocumentManager.getInstance(project).commitAllDocuments();

    // Swap fold regions status if necessary.
    if (topRegion != null && bottomRegion != null) {
      final FoldRegion finalTopRegion = topRegion;
      final FoldRegion finalBottomRegion = bottomRegion;
      editor
          .getFoldingModel()
          .runBatchFoldingOperation(
              new Runnable() {
                @Override
                public void run() {
                  boolean topExpanded = finalTopRegion.isExpanded();
                  finalTopRegion.setExpanded(finalBottomRegion.isExpanded());
                  finalBottomRegion.setExpanded(topExpanded);
                }
              });
    }
    CodeFoldingManager.getInstance(project).allowFoldingOnCaretLine(editor);

    if (hasSelection) {
      restoreSelection(editor, selectionStart, selectionEnd, start, myInfo.range2.getStartOffset());
    }

    caretModel.moveToOffset(myInfo.range2.getStartOffset() + caretRelativePos);
    if (myInfo.indentTarget) {
      indentLinesIn(editor, file, document, project, myInfo.range2);
    }
    if (myInfo.indentSource) {
      indentLinesIn(editor, file, document, project, myInfo.range1);
    }

    myMover.afterMove(editor, file, myInfo, myIsDown);
    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
  }
Example #25
0
  private static void doPaste(
      final Editor editor,
      final Project project,
      final PsiFile file,
      final Document document,
      final Producer<Transferable> producer) {
    Transferable content = null;

    if (producer != null) {
      content = producer.produce();
    } else {
      CopyPasteManager manager = CopyPasteManager.getInstance();
      if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
        content = manager.getContents();
        if (content != null) {
          manager.stopKillRings();
        }
      }
    }

    if (content != null) {
      String text = null;
      try {
        text = (String) content.getTransferData(DataFlavor.stringFlavor);
      } catch (Exception e) {
        editor.getComponent().getToolkit().beep();
      }
      if (text == null) return;

      final CodeInsightSettings settings = CodeInsightSettings.getInstance();

      final Map<CopyPastePostProcessor, TextBlockTransferableData> extraData =
          new HashMap<CopyPastePostProcessor, TextBlockTransferableData>();
      for (CopyPastePostProcessor processor :
          Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) {
        TextBlockTransferableData data = processor.extractTransferableData(content);
        if (data != null) {
          extraData.put(processor, data);
        }
      }

      text = TextBlockTransferable.convertLineSeparators(text, "\n", extraData.values());

      final CaretModel caretModel = editor.getCaretModel();
      final SelectionModel selectionModel = editor.getSelectionModel();
      final int col = caretModel.getLogicalPosition().column;

      // There is a possible case that we want to perform paste while there is an active selection
      // at the editor and caret is located
      // inside it (e.g. Ctrl+A is pressed while caret is not at the zero column). We want to insert
      // the text at selection start column
      // then, hence, inserted block of text should be indented according to the selection start as
      // well.
      final int blockIndentAnchorColumn;
      final int caretOffset = caretModel.getOffset();
      if (selectionModel.hasSelection() && caretOffset >= selectionModel.getSelectionStart()) {
        blockIndentAnchorColumn =
            editor.offsetToLogicalPosition(selectionModel.getSelectionStart()).column;
      } else {
        blockIndentAnchorColumn = col;
      }

      // We assume that EditorModificationUtil.insertStringAtCaret() is smart enough to remove
      // currently selected text (if any).

      RawText rawText = RawText.fromTransferable(content);
      String newText = text;
      for (CopyPastePreProcessor preProcessor :
          Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) {
        newText = preProcessor.preprocessOnPaste(project, file, editor, newText, rawText);
      }
      int indentOptions =
          text.equals(newText) ? settings.REFORMAT_ON_PASTE : CodeInsightSettings.REFORMAT_BLOCK;
      text = newText;

      if (LanguageFormatting.INSTANCE.forContext(file) == null
          && indentOptions != CodeInsightSettings.NO_REFORMAT) {
        indentOptions = CodeInsightSettings.INDENT_BLOCK;
      }

      final String _text = text;
      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  EditorModificationUtil.insertStringAtCaret(editor, _text, false, true);
                }
              });

      int length = text.length();
      int offset = caretModel.getOffset() - length;
      if (offset < 0) {
        length += offset;
        offset = 0;
      }
      final RangeMarker bounds = document.createRangeMarker(offset, offset + length);

      caretModel.moveToOffset(bounds.getEndOffset());
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
      selectionModel.removeSelection();

      final Ref<Boolean> indented = new Ref<Boolean>(Boolean.FALSE);
      for (Map.Entry<CopyPastePostProcessor, TextBlockTransferableData> e : extraData.entrySet()) {
        //noinspection unchecked
        e.getKey()
            .processTransferableData(project, editor, bounds, caretOffset, indented, e.getValue());
      }

      boolean pastedTextContainsWhiteSpacesOnly =
          CharArrayUtil.shiftForward(document.getCharsSequence(), bounds.getStartOffset(), " \n\t")
              >= bounds.getEndOffset();

      VirtualFile virtualFile = file.getVirtualFile();
      if (!pastedTextContainsWhiteSpacesOnly
          && (virtualFile == null
              || !SingleRootFileViewProvider.isTooLargeForIntelligence(virtualFile))) {
        final int indentOptions1 = indentOptions;
        ApplicationManager.getApplication()
            .runWriteAction(
                new Runnable() {
                  @Override
                  public void run() {
                    switch (indentOptions1) {
                      case CodeInsightSettings.INDENT_BLOCK:
                        if (!indented.get()) {
                          indentBlock(
                              project,
                              editor,
                              bounds.getStartOffset(),
                              bounds.getEndOffset(),
                              blockIndentAnchorColumn);
                        }
                        break;

                      case CodeInsightSettings.INDENT_EACH_LINE:
                        if (!indented.get()) {
                          indentEachLine(
                              project, editor, bounds.getStartOffset(), bounds.getEndOffset());
                        }
                        break;

                      case CodeInsightSettings.REFORMAT_BLOCK:
                        indentEachLine(
                            project,
                            editor,
                            bounds.getStartOffset(),
                            bounds
                                .getEndOffset()); // this is needed for example when inserting a
                                                  // comment before method
                        reformatBlock(
                            project, editor, bounds.getStartOffset(), bounds.getEndOffset());
                        break;
                    }
                  }
                });
      }

      if (bounds.isValid()) {
        caretModel.moveToOffset(bounds.getEndOffset());
        editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
        selectionModel.removeSelection();
        editor.putUserData(EditorEx.LAST_PASTED_REGION, TextRange.create(bounds));
      }
    }
  }
  @Nullable
  @Override
  public TextBlockTransferableData collectTransferableData(
      PsiFile file, Editor editor, int[] startOffsets, int[] endOffsets) {
    if (!Registry.is("editor.richcopy.enable")) {
      return null;
    }

    try {
      for (TextWithMarkupBuilder builder : myBuilders) {
        builder.reset();
      }
      SelectionModel selectionModel = editor.getSelectionModel();
      if (selectionModel.hasBlockSelection()) {
        return null; // unsupported legacy mode
      }

      RichCopySettings settings = RichCopySettings.getInstance();
      List<Caret> carets = editor.getCaretModel().getAllCarets();
      Caret firstCaret = carets.get(0);
      final int indentSymbolsToStrip;
      final int firstLineStartOffset;
      if (settings.isStripIndents() && carets.size() == 1) {
        Pair<Integer, Integer> p =
            calcIndentSymbolsToStrip(
                editor.getDocument(), firstCaret.getSelectionStart(), firstCaret.getSelectionEnd());
        firstLineStartOffset = p.first;
        indentSymbolsToStrip = p.second;
      } else {
        firstLineStartOffset = firstCaret.getSelectionStart();
        indentSymbolsToStrip = 0;
      }
      logInitial(editor, startOffsets, endOffsets, indentSymbolsToStrip, firstLineStartOffset);
      CharSequence text = editor.getDocument().getCharsSequence();
      EditorColorsScheme schemeToUse = settings.getColorsScheme(editor.getColorsScheme());
      EditorHighlighter highlighter =
          HighlighterFactory.createHighlighter(
              file.getVirtualFile(), schemeToUse, file.getProject());
      highlighter.setText(text);
      MarkupModel markupModel =
          DocumentMarkupModel.forDocument(editor.getDocument(), file.getProject(), false);
      Context context = new Context(text, schemeToUse, indentSymbolsToStrip);
      int shift = 0;
      int endOffset = 0;
      Caret prevCaret = null;

      for (Caret caret : carets) {
        int caretSelectionStart = caret.getSelectionStart();
        int caretSelectionEnd = caret.getSelectionEnd();
        int startOffsetToUse;
        if (caret == firstCaret) {
          startOffsetToUse = firstLineStartOffset;
        } else {
          startOffsetToUse = caretSelectionStart;
          assert prevCaret != null;
          String prevCaretSelectedText = prevCaret.getSelectedText();
          // Block selection fills short lines by white spaces.
          int fillStringLength =
              prevCaretSelectedText == null
                  ? 0
                  : prevCaretSelectedText.length()
                      - (prevCaret.getSelectionEnd() - prevCaret.getSelectionStart());
          int endLineOffset = endOffset + shift + fillStringLength;
          context.builder.addText(endLineOffset, endLineOffset + 1);
          shift++; // Block selection ends '\n' at line end
          shift += fillStringLength;
        }
        shift += endOffset - caretSelectionStart;
        endOffset = caretSelectionEnd;
        context.reset(shift);
        prevCaret = caret;
        if (endOffset <= startOffsetToUse) {
          continue;
        }
        MarkupIterator markupIterator =
            new MarkupIterator(
                text,
                new CompositeRangeIterator(
                    schemeToUse,
                    new HighlighterRangeIterator(highlighter, startOffsetToUse, endOffset),
                    new MarkupModelRangeIterator(
                        markupModel, schemeToUse, startOffsetToUse, endOffset)),
                schemeToUse);
        try {
          context.iterate(markupIterator, endOffset);
        } finally {
          markupIterator.dispose();
        }
      }
      SyntaxInfo syntaxInfo = context.finish();
      logSyntaxInfo(syntaxInfo);

      for (TextWithMarkupBuilder builder : myBuilders) {
        builder.build(syntaxInfo);
      }
    } catch (Exception e) {
      // catching the exception so that the rest of copy/paste functionality can still work fine
      LOG.error(e);
    }
    return null;
  }