Esempio n. 1
0
  public static void adjustTopLevelGroups(BaseApplicationPlugin idePlugin) {
    addPlace(ProjectPaneActionGroups.NODE_ACTIONS, ActionPlace.PROJECT_PANE_SNODE);
    addPlace(ProjectPaneActionGroups.MODEL_ACTIONS, ActionPlace.PROJECT_PANE_SMODEL);
    addPlace(ProjectPaneActionGroups.PROJECT_PANE_MODULE_ACTIONS, ActionPlace.PROJECT_PANE_MODULE);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_LANGUAGE_ACTIONS, ActionPlace.PROJECT_PANE_LANGUAGE);
    addPlace(ProjectPaneActionGroups.PROJECT_PANE_DEVKIT_ACTIONS, ActionPlace.PROJECT_PANE_DEVKIT);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_PROJECT_ACTIONS, ActionPlace.PROJECT_PANE_PROJECT);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_SOLUTION_ACTIONS, ActionPlace.PROJECT_PANE_SOLUTION);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_GENERATOR_ACTIONS, ActionPlace.PROJECT_PANE_GENERATOR);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_TRANSIENT_MODULES_ACTIONS,
        ActionPlace.PROJECT_PANE_TRANSIENT_MODULES);
    addPlace(ProjectPaneActionGroups.PACKAGE_ACTIONS, ActionPlace.PROJECT_PANE_PACKAGE);
    addPlace(ProjectPaneActionGroups.NAMESPACE_ACTIONS, ActionPlace.PROJECT_PANE_NAMESPACE);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_RUNTIME_FOLDER_ACTIONS,
        ActionPlace.PROJECT_PANE_RUNTIME_FOLDER);
    addPlace(
        ProjectPaneActionGroups.PROJECT_PANE_ACCESSORIES_ACTIONS,
        ActionPlace.PROJECT_PANE_ACCESSORIES);
    addPlace(ProjectPaneActionGroups.PROJECT_NEW_ACTIONS, ActionPlace.PROJECT_PANE_PROJECT);
    addPlace(ProjectPaneActionGroups.SOLUTION_NEW_ACTIONS, ActionPlace.PROJECT_PANE_SOLUTION);
    addPlace(ProjectPaneActionGroups.LANGUAGE_NEW_ACTIONS, ActionPlace.PROJECT_PANE_LANGUAGE);
    addPlace(ProjectPaneActionGroups.GENERATOR_NEW_ACTIONS, ActionPlace.PROJECT_PANE_GENERATOR);

    addPlace(ProjectPaneActionGroups.PROJECT_PANE_FILE_ACTIONS, ActionPlace.PROJECT_PANE_FILE);
    addPlace(ProjectPaneActionGroups.PROJECT_PANE_FOLDER_ACTIONS, ActionPlace.PROJECT_PANE_FOLDER);

    addPlace(ModuleActions_ActionGroup.ID, ActionPlace.MODULE_DEPENDENCIES);

    DefaultActionGroup editorPopupGroup =
        ActionUtils.getDefaultGroup(EditorComponent.EDITOR_POPUP_MENU_ACTIONS);
    List<AnAction> actionList = Arrays.asList(editorPopupGroup.getChildren(null));
    BaseGroup.addPlaceToActionList(actionList, ActionPlace.EDITOR, null);

    DefaultActionGroup editorActionsGroup =
        ActionUtils.getDefaultGroup(MPSActions.EDITOR_ACTIONS_GROUP);
    actionList = Arrays.asList(editorActionsGroup.getChildren(null));
    BaseGroup.addPlaceToActionList(actionList, ActionPlace.EDITOR, null);

    List<BaseGroup> mainMenuGroups = new ArrayList<BaseGroup>();
    DefaultActionGroup mainMenuGroup = ActionUtils.getDefaultGroup(IdeActions.GROUP_MAIN_MENU);
    ActionManagerEx manager = ActionManagerEx.getInstanceEx();
    for (String id : manager.getActionIds("")) {
      AnAction action = manager.getAction(id);
      if (!(action instanceof BaseGroup)) continue;
      BaseGroup group = ((BaseGroup) action);
      if (ActionUtils.contains(mainMenuGroup, group)) {
        mainMenuGroups.add(group);
      }
    }

    for (BaseGroup group : mainMenuGroups) {
      group.addPlace(null, null);
    }
  }
Esempio n. 2
0
 private void unregisterActions() {
   // unregister Tool actions
   String[] oldIds = myActionManager.getActionIds(Tool.ACTION_ID_PREFIX);
   for (int i = 0; i < oldIds.length; i++) {
     String oldId = oldIds[i];
     myActionManager.unregisterAction(oldId);
   }
 }
  public boolean processAction(final InputEvent e, ActionProcessor processor) {
    ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
    final Project project = PlatformDataKeys.PROJECT.getData(myContext.getDataContext());
    final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
    List<AnActionEvent> nonDumbAwareAction = new ArrayList<AnActionEvent>();
    for (final AnAction action : myContext.getActions()) {
      final Presentation presentation = myPresentationFactory.getPresentation(action);

      // Mouse modifiers are 0 because they have no any sense when action is invoked via keyboard
      final AnActionEvent actionEvent =
          processor.createEvent(
              e,
              myContext.getDataContext(),
              ActionPlaces.MAIN_MENU,
              presentation,
              ActionManager.getInstance());

      ActionUtil.performDumbAwareUpdate(action, actionEvent, true);

      if (dumb && !action.isDumbAware()) {
        if (Boolean.FALSE.equals(
            presentation.getClientProperty(ActionUtil.WOULD_BE_ENABLED_IF_NOT_DUMB_MODE))) {
          continue;
        }

        nonDumbAwareAction.add(actionEvent);
        continue;
      }

      if (!presentation.isEnabled()) {
        continue;
      }

      processor.onUpdatePassed(e, action, actionEvent);

      ((DataManagerImpl.MyDataContext) myContext.getDataContext())
          .setEventCount(IdeEventQueue.getInstance().getEventCount(), this);
      actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext(), actionEvent);
      Component component =
          PlatformDataKeys.CONTEXT_COMPONENT.getData(actionEvent.getDataContext());
      if (component != null && !component.isShowing()) {
        return true;
      }

      processor.performAction(e, action, actionEvent);
      actionManager.fireAfterActionPerformed(action, actionEvent.getDataContext(), actionEvent);
      return true;
    }

    if (!nonDumbAwareAction.isEmpty()) {
      showDumbModeWarningLaterIfNobodyConsumesEvent(
          e, nonDumbAwareAction.toArray(new AnActionEvent[nonDumbAwareAction.size()]));
    }

    return false;
  }
 public NamespaceMakeActions_ActionGroup() {
   super("NamespaceMakeActions", ID);
   this.setIsInternal(false);
   this.setPopup(false);
   {
     LabelledAnchor action = new LabelledAnchor(NamespaceMakeActions_ActionGroup.LABEL_ID_make);
     ActionManagerEx manager = ActionManagerEx.getInstanceEx();
     manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
     NamespaceMakeActions_ActionGroup.this.addAction(action);
   }
 }
 public GenerateOptions_ActionGroup() {
   super("GenerateOptions", ID);
   this.setIsInternal(false);
   this.setPopup(false);
   GenerateOptions_ActionGroup.this.addAction("jetbrains.mps.ide.make.actions.Options_Action");
   {
     LabelledAnchor action =
         new LabelledAnchor(GenerateOptions_ActionGroup.LABEL_ID_saveTransientModels);
     ActionManagerEx manager = ActionManagerEx.getInstanceEx();
     manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide.make"));
     GenerateOptions_ActionGroup.this.addAction(action);
   }
   GenerateOptions_ActionGroup.this.addAction(
       "jetbrains.mps.ide.make.actions.CheckModelsBeforeGeneration_Action");
 }
  public HighlightManagerImpl(Project project) {
    myProject = project;
    ActionManagerEx.getInstanceEx().addAnActionListener(new MyAnActionListener(), myProject);

    DocumentListener documentListener =
        new DocumentAdapter() {
          @Override
          public void documentChanged(DocumentEvent event) {
            Document document = event.getDocument();
            Editor[] editors = EditorFactory.getInstance().getEditors(document);
            for (Editor editor : editors) {
              Map<RangeHighlighter, HighlightInfo> map = getHighlightInfoMap(editor, false);
              if (map == null) return;

              ArrayList<RangeHighlighter> highlightersToRemove = new ArrayList<RangeHighlighter>();
              for (RangeHighlighter highlighter : map.keySet()) {
                HighlightInfo info = map.get(highlighter);
                if (!info.editor.getDocument().equals(document)) continue;
                if (BitUtil.isSet(info.flags, HIDE_BY_TEXT_CHANGE)) {
                  highlightersToRemove.add(highlighter);
                }
              }

              for (RangeHighlighter highlighter : highlightersToRemove) {
                removeSegmentHighlighter(editor, highlighter);
              }
            }
          }
        };
    EditorFactory.getInstance()
        .getEventMulticaster()
        .addDocumentListener(documentListener, myProject);
  }
 private void installSubcomponents() {
   int decorationStyle = getWindowDecorationStyle();
   if (decorationStyle == JRootPane.FRAME) {
     createActions();
     myMenuBar = createMenuBar();
     if (myRootPane instanceof IdeRootPane) {
       myIdeMenu = new IdeMenuBar(ActionManagerEx.getInstanceEx(), DataManager.getInstance());
       add(myIdeMenu);
     }
     add(myMenuBar);
     createButtons();
     add(myIconifyButton);
     add(myToggleButton);
     add(myCloseButton);
   } else if (decorationStyle == JRootPane.PLAIN_DIALOG
       || decorationStyle == JRootPane.INFORMATION_DIALOG
       || decorationStyle == JRootPane.ERROR_DIALOG
       || decorationStyle == JRootPane.COLOR_CHOOSER_DIALOG
       || decorationStyle == JRootPane.FILE_CHOOSER_DIALOG
       || decorationStyle == JRootPane.QUESTION_DIALOG
       || decorationStyle == JRootPane.WARNING_DIALOG) {
     createActions();
     createButtons();
     add(myCloseButton);
   }
 }
  public final IdeFrameImpl allocateFrame(final Project project) {
    LOG.assertTrue(!myProject2Frame.containsKey(project));

    final IdeFrameImpl frame;
    if (myProject2Frame.containsKey(null)) {
      frame = myProject2Frame.get(null);
      myProject2Frame.remove(null);
      myProject2Frame.put(project, frame);
      frame.setProject(project);
    } else {
      frame =
          new IdeFrameImpl(
              (ApplicationInfoEx) ApplicationInfo.getInstance(),
              ActionManagerEx.getInstanceEx(),
              UISettings.getInstance(),
              DataManager.getInstance(),
              ApplicationManager.getApplication());
      final Rectangle bounds = ProjectFrameBounds.getInstance(project).getBounds();
      if (bounds != null) {
        frame.setBounds(bounds);
      } else if (myFrameBounds != null) {
        frame.setBounds(myFrameBounds);
      }
      frame.setExtendedState(myFrameExtendedState);
      frame.setProject(project);
      myProject2Frame.put(project, frame);
      frame.setVisible(true);
    }

    frame.addWindowListener(myActivationListener);

    myEventDispatcher.getMulticaster().frameCreated(frame);

    return frame;
  }
  @Before
  public void setUp() {
    MockApplication application = new MyMockApplicationEx(parent);
    ActionManagerEx manager = Mockito.mock(ActionManagerEx.class);
    ActionToolbar actionToolbar = Mockito.mock(ActionToolbar.class);
    Mockito.when(actionToolbar.getComponent()).thenReturn(new JComponent() {});
    Mockito.when(
            manager.createActionToolbar(
                Mockito.anyString(), Mockito.any(ActionGroup.class), Mockito.anyBoolean()))
        .thenReturn(actionToolbar);
    Mockito.when(
            manager.createActionToolbar(
                Mockito.anyString(),
                Mockito.any(ActionGroup.class),
                Mockito.anyBoolean(),
                Mockito.anyBoolean()))
        .thenReturn(actionToolbar);
    application.addComponent(ActionManager.class, manager);
    ApplicationManager.setApplication(application, parent);

    XDebugSession session = Mockito.mock(XDebugSession.class);
    Mockito.when(handler.getProcess()).thenReturn(mockProcess);
    Mockito.when(mockProcess.getXDebugSession()).thenReturn(session);
  }
Esempio n. 10
0
  void registerActions() {
    unregisterActions();

    // register
    HashSet registeredIds =
        new HashSet(); // to prevent exception if 2 or more targets have the same name

    Tool[] tools = getTools();
    for (int i = 0; i < tools.length; i++) {
      Tool tool = tools[i];
      String actionId = tool.getActionId();

      if (!registeredIds.contains(actionId)) {
        registeredIds.add(actionId);
        myActionManager.registerAction(actionId, new ToolAction(tool));
      }
    }
  }
  /**
   * @return <code>true</code> if and only if the passed event is already dispatched by the <code>
   *     IdeMouseEventDispatcher</code> and there is no need for any other processing of the event.
   *     If the method returns <code>false</code> then it means that the event should be delivered
   *     to normal event dispatching.
   */
  public boolean dispatchMouseEvent(MouseEvent e) {
    Component c = e.getComponent();

    // frame activation by mouse click
    if (e.getID() == MOUSE_PRESSED && c instanceof IdeFrame && !c.hasFocus()) {
      IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance();
      if (focusManager instanceof FocusManagerImpl) {
        Component at = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY());
        if (at != null && at.isFocusable()) {
          ((FocusManagerImpl) focusManager).setLastFocusedAtDeactivation((IdeFrame) c, at);
        }
      }
    }

    if (SystemInfo.isXWindow && e.isPopupTrigger() && e.getButton() != 3) {
      // we can do better than silly triggering popup on everything but left click
      resetPopupTrigger(e);
    }

    boolean ignore = false;
    if (!(e.getID() == MouseEvent.MOUSE_PRESSED
        || e.getID() == MouseEvent.MOUSE_RELEASED
        || e.getID() == MOUSE_CLICKED)) {
      ignore = true;
    }

    patchClickCount(e);

    if (e.isConsumed()
        || e.isPopupTrigger()
        || (e.getButton() > 3 ? e.getID() != MOUSE_PRESSED : e.getID() != MOUSE_RELEASED)
        || e.getClickCount() < 1
        || e.getButton() == MouseEvent.NOBUTTON) { // See #16995. It did happen
      ignore = true;
    }

    int modifiers = e.getModifiers();
    int modifiersEx = e.getModifiersEx();
    if (e.getID() == MOUSE_PRESSED) {
      myPressedModifiersStored = true;
      myModifiers = modifiers;
      myModifiersEx = modifiersEx;
    } else if (e.getID() == MOUSE_RELEASED) {
      if (myPressedModifiersStored) {
        myPressedModifiersStored = false;
        modifiers = myModifiers;
        modifiersEx = myModifiersEx;
      }
    }

    final JRootPane root = findRoot(e);
    if (root != null) {
      BlockState blockState = myRootPane2BlockedId.get(root);
      if (blockState != null) {
        if (SWING_EVENTS_PRIORITY.indexOf(blockState.currentEventId)
            < SWING_EVENTS_PRIORITY.indexOf(e.getID())) {
          blockState.currentEventId = e.getID();
          if (blockState.blockMode == IdeEventQueue.BlockMode.COMPLETE) {
            return true;
          } else {
            ignore = true;
          }
        } else {
          myRootPane2BlockedId.remove(root);
        }
      }
    }

    if (c == null) {
      throw new IllegalStateException("component cannot be null");
    }
    c = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY());

    if (c instanceof IdeGlassPaneImpl) {
      c = ((IdeGlassPaneImpl) c).getTargetComponentFor(e);
    }

    if (c == null) { // do nothing if component doesn't contains specified point
      return false;
    }

    if (isHorizontalScrolling(c, e)) {
      boolean done = doHorizontalScrolling(c, (MouseWheelEvent) e);
      if (done) return true;
    }

    if (ignore) return false;

    // avoid "cyclic component initialization error" in case of dialogs shown because of component
    // initialization failure
    if (!KeymapManagerImpl.ourKeymapManagerInitialized) {
      return false;
    }

    final MouseShortcut shortcut = new MouseShortcut(e.getButton(), modifiersEx, e.getClickCount());
    fillActionsList(c, shortcut, IdeKeyEventDispatcher.isModalContext(c));
    ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
    if (actionManager != null) {
      AnAction[] actions = myActions.toArray(new AnAction[myActions.size()]);
      for (AnAction action : actions) {
        DataContext dataContext = DataManager.getInstance().getDataContext(c);
        Presentation presentation = myPresentationFactory.getPresentation(action);
        AnActionEvent actionEvent =
            new AnActionEvent(
                e,
                dataContext,
                ActionPlaces.MAIN_MENU,
                presentation,
                ActionManager.getInstance(),
                modifiers);
        action.beforeActionPerformedUpdate(actionEvent);

        if (presentation.isEnabled()) {
          actionManager.fireBeforeActionPerformed(action, dataContext, actionEvent);
          final Component context = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);

          if (context != null && !context.isShowing()) continue;

          action.actionPerformed(actionEvent);
          e.consume();
        }
      }
      if (actions.length > 0 && e.isConsumed()) return true;
    }
    return e.getButton() > 3;
  }
 public LanguageActions_ActionGroup() {
   super("LanguageActions", ID);
   this.setIsInternal(false);
   this.setPopup(false);
   try {
     {
       LabelledAnchor action = new LabelledAnchor(LanguageActions_ActionGroup.LABEL_ID_newGroup);
       ActionManagerEx manager = ActionManagerEx.getInstanceEx();
       manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
       LanguageActions_ActionGroup.this.addAction(action);
     }
     {
       LabelledAnchor action =
           new LabelledAnchor(LanguageActions_ActionGroup.LABEL_ID_commonModule);
       ActionManagerEx manager = ActionManagerEx.getInstanceEx();
       manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
       LanguageActions_ActionGroup.this.addAction(action);
     }
     LanguageActions_ActionGroup.this.addSeparator();
     {
       LabelledAnchor action =
           new LabelledAnchor(LanguageActions_ActionGroup.LABEL_ID_find_usages);
       ActionManagerEx manager = ActionManagerEx.getInstanceEx();
       manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
       LanguageActions_ActionGroup.this.addAction(action);
     }
     {
       LabelledAnchor action =
           new LabelledAnchor(LanguageActions_ActionGroup.LABEL_ID_find_instances);
       ActionManagerEx manager = ActionManagerEx.getInstanceEx();
       manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
       LanguageActions_ActionGroup.this.addAction(action);
     }
     {
       LabelledAnchor action =
           new LabelledAnchor(LanguageActions_ActionGroup.LABEL_ID_find_javastub_usages);
       ActionManagerEx manager = ActionManagerEx.getInstanceEx();
       manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
       LanguageActions_ActionGroup.this.addAction(action);
     }
     LanguageActions_ActionGroup.this.addSeparator();
     {
       LabelledAnchor action = new LabelledAnchor(LanguageActions_ActionGroup.LABEL_ID_ex);
       ActionManagerEx manager = ActionManagerEx.getInstanceEx();
       manager.registerAction(action.getId(), action, PluginId.getId("jetbrains.mps.ide"));
       LanguageActions_ActionGroup.this.addAction(action);
     }
     LanguageActions_ActionGroup.this.addAction(
         "jetbrains.mps.ide.actions.ModuleProperties_Action");
   } catch (Throwable t) {
     LOG.error("User group error", t);
   }
 }
  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());
        }
      }
    }
  }