boolean (@NotNull final MouseEvent e) { myInitialMouseEvent = e; if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && System.currentTimeMillis() - myMouseSelectionChangeTimestamp > Registry.intValue( "editor.mouseSelectionStateResetTimeout")) { resetMouseSelectionState(e); } int x = e.getX(); int y = e.getY(); if (x < 0) x = 0; if (y < 0) y = 0; final EditorMouseEventArea eventArea = getMouseEventArea(e); myMousePressArea = eventArea; if (eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA) { final FoldRegion range = myGutterComponent.findFoldingAnchorAt(x, y); if (range != null) { final boolean expansion = !range.isExpanded(); int scrollShift = y - getScrollingModel().getVerticalScrollOffset(); Runnable processor = new Runnable() { @Override public void run() { myFoldingModel.flushCaretShift(); range.setExpanded(expansion); if (e.isAltDown()) { for (FoldRegion region : myFoldingModel.getAllFoldRegions()) { if (region.getStartOffset() >= range.getStartOffset() && region.getEndOffset() <= range.getEndOffset()) { region.setExpanded(expansion); } } } } }; getFoldingModel().runBatchFoldingOperation(processor); y = myGutterComponent.getHeadCenterY(range); getScrollingModel().scrollVertically(y - scrollShift); myGutterComponent.updateSize(); validateMousePointer(e); e.consume(); return false; } } if (e.getSource() == myGutterComponent) { if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA || eventArea == EditorMouseEventArea.ANNOTATIONS_AREA || eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA) { if (tweakSelectionIfNecessary(e)) { mySelectionTweaked = true; } else { myGutterComponent.mousePressed(e); } if (e.isConsumed()) return false; } x = 0; } int oldSelectionStart = mySelectionModel.getLeadSelectionOffset(); final int oldStart = mySelectionModel.getSelectionStart(); final int oldEnd = mySelectionModel.getSelectionEnd(); boolean toggleCaret = e.getSource() != myGutterComponent && isToggleCaretEvent(e); boolean lastPressCreatedCaret = myLastPressCreatedCaret; if (e.getClickCount() == 1) { myLastPressCreatedCaret = false; } // Don't move caret on mouse press above gutter line markers area (a place where break points, 'override', 'implements' etc icons // are drawn) and annotations area. E.g. we don't want to change caret position if a user sets new break point (clicks // at 'line markers' area). if (e.getSource() != myGutterComponent || eventArea != EditorMouseEventArea.LINE_MARKERS_AREA && eventArea != EditorMouseEventArea.ANNOTATIONS_AREA) { LogicalPosition pos = getLogicalPositionForScreenPos(x, y, true); if (toggleCaret) { VisualPosition visualPosition = logicalToVisualPosition(pos); Caret caret = getCaretModel().getCaretAt(visualPosition); if (e.getClickCount() == 1) { if (caret == null) { myLastPressCreatedCaret = getCaretModel().addCaret(visualPosition) != null; } else { getCaretModel().removeCaret(caret); } } else if (e.getClickCount() == 3 && lastPressCreatedCaret) { getCaretModel().moveToLogicalPosition(pos); } } else if (myCaretModel.supportsMultipleCarets() && e.getSource() != myGutterComponent && isCreateRectangularSelectionEvent(e)) { mySelectionModel.setBlockSelection(myCaretModel.getLogicalPosition(), pos); } else { getCaretModel().removeSecondaryCarets(); getCaretModel().moveToLogicalPosition(pos); } } if (e.isPopupTrigger()) return false; requestFocus(); int caretOffset = getCaretModel().getOffset(); int newStart = mySelectionModel.getSelectionStart(); int newEnd = mySelectionModel.getSelectionEnd(); boolean isNavigation = oldStart == oldEnd && newStart == newEnd && oldStart != newStart; myMouseSelectedRegion = myFoldingModel.getFoldingPlaceholderAt(new Point(x, y)); myMousePressedInsideSelection = mySelectionModel.hasSelection() && caretOffset >= mySelectionModel.getSelectionStart() && caretOffset <= mySelectionModel.getSelectionEnd(); if (getMouseEventArea(e) == EditorMouseEventArea.LINE_NUMBERS_AREA && e.getClickCount() == 1) { mySelectionModel.selectLineAtCaret(); setMouseSelectionState(MOUSE_SELECTION_STATE_LINE_SELECTED); mySavedSelectionStart = mySelectionModel.getSelectionStart(); mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); return isNavigation; } if (e.isShiftDown() && !e.isControlDown() && !e.isAltDown()) { if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { if (caretOffset < mySavedSelectionStart) { mySelectionModel.setSelection(mySavedSelectionEnd, caretOffset); } else { mySelectionModel.setSelection(mySavedSelectionStart, caretOffset); } } else { int startToUse = oldSelectionStart; if (mySelectionModel.isUnknownDirection() && caretOffset > startToUse) { startToUse = Math.min(oldStart, oldEnd); } mySelectionModel.setSelection(startToUse, caretOffset); } } else { if (!myMousePressedInsideSelection && getSelectionModel().hasSelection()) { setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); mySelectionModel.setSelection(caretOffset, caretOffset); } else { if (!e.isPopupTrigger() && (eventArea == EditorMouseEventArea.EDITING_AREA || eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA) && (!toggleCaret || lastPressCreatedCaret)) { switch (e.getClickCount()) { case 2: selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords() && mySettings.isCamelWords()); break; case 3: if (HONOR_CAMEL_HUMPS_ON_TRIPLE_CLICK && mySettings.isCamelWords()) { // We want to differentiate between triple and quadruple clicks when 'select by camel humps' is on. The former // is assumed to select 'hump' while the later points to the whole word. selectWordAtCaret(false); break; } //noinspection fallthrough case 4: mySelectionModel.selectLineAtCaret(); setMouseSelectionState(MOUSE_SELECTION_STATE_LINE_SELECTED); mySavedSelectionStart = mySelectionModel.getSelectionStart(); mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); mySelectionModel.setUnknownDirection(true); break; } } } } return isNavigation; }