IDEA-128731, IDEA-129013 don't update system selection when selection is changed...
authorDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Thu, 28 Aug 2014 09:35:20 +0000 (13:35 +0400)
committerDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Thu, 28 Aug 2014 09:37:45 +0000 (13:37 +0400)
platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
platform/platform-impl/src/com/intellij/ui/EditorTextField.java

index ba0743b4cfb090cf6be173b7cf67478718d56b36..fc824844be6e672f2e04792b4c698c52233f7316 100644 (file)
@@ -198,6 +198,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
 
   /**
    * Selects the specified range of text.
+   * <p>
+   * System selection will be updated, if such feature is supported by current editor.
    *
    * @param startOffset the start offset of the text range to select.
    * @param endOffset   the end offset of the text range to select.
@@ -205,11 +207,22 @@ public interface Caret extends UserDataHolderEx, Disposable {
   void setSelection(int startOffset, int endOffset);
 
   /**
+   * Selects the specified range of text.
+   *
+   * @param startOffset the start offset of the text range to select.
+   * @param endOffset   the end offset of the text range to select.
+   * @param updateSystemSelection whether system selection should be updated (might not have any effect if current editor doesn't support such a feature)
+   */
+  void setSelection(int startOffset, int endOffset, boolean updateSystemSelection);
+
+  /**
    * Selects target range providing information about visual boundary of selection end.
    * <p/>
    * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
    * <p/>
    * Also, in column mode this method allows to create selection spanning virtual space after the line end.
+   * <p>
+   * System selection will be updated, if such feature is supported by current editor.
    *
    * @param startOffset     start selection offset
    * @param endPosition     end visual position of the text range to select (<code>null</code> argument means that
@@ -224,6 +237,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
    * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
    * <p/>
    * Also, in column mode this method allows to create selection spanning virtual space after the line end.
+   * <p>
+   * System selection will be updated, if such feature is supported by current editor.
    *
    * @param startPosition   start visual position of the text range to select (<code>null</code> argument means that
    *                        no specific visual position should be used)
@@ -235,6 +250,23 @@ public interface Caret extends UserDataHolderEx, Disposable {
   void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset);
 
   /**
+   * Selects target range based on its visual boundaries.
+   * <p/>
+   * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
+   * <p/>
+   * Also, in column mode this method allows to create selection spanning virtual space after the line end.
+   *
+   * @param startPosition   start visual position of the text range to select (<code>null</code> argument means that
+   *                        no specific visual position should be used)
+   * @param endPosition     end visual position of the text range to select (<code>null</code> argument means that
+   *                        no specific visual position should be used)
+   * @param startOffset     start selection offset
+   * @param endOffset       end selection offset
+   * @param updateSystemSelection whether system selection should be updated (might not have any effect if current editor doesn't support such a feature)
+   */
+  void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection);
+
+  /**
    * Removes the selection in the editor.
    */
   void removeSelection();
index df247d5be4019dd44c7df2b2f5df32a7aa4908a2..a5053923fa3188e43d229071e15304a597acecd0 100644 (file)
@@ -222,6 +222,8 @@ public interface CaretModel {
    * selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
    * <p>
    * If multiple carets are not supported, the behaviour is unspecified.
+   * <p>
+   * System selection will be updated, if such feature is supported by current editor.
    *
    * @see #supportsMultipleCarets()
    * @see #getCaretsAndSelections()
@@ -229,6 +231,20 @@ public interface CaretModel {
   void setCaretsAndSelections(@NotNull List<CaretState> caretStates);
 
   /**
+   * Sets the number of carets, their positions and selection ranges according to the provided data. Null values for caret position or
+   * selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
+   * <p>
+   * If multiple carets are not supported, the behaviour is unspecified.
+   * <p>
+   * System selection will be updated, if such feature is supported by current editor
+   * and corresponding invocation parameter is set to <code>true</code>.
+   *
+   * @see #supportsMultipleCarets()
+   * @see #getCaretsAndSelections()
+   */
+  void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection);
+
+  /**
    * Returns the current positions of all carets and their selections. The order of entries in the returned list does not necessarily
    * correspond to the order of {@link #getAllCarets()} method results. Passing the result of this method to
    * {@link #setCaretsAndSelections(java.util.List)} will restore the state of carets, including the internal caret order, in particular,
index d0288d71a9a23d0cc24d568f0ecf79fa61b3bb30..da44ae6c123c787dc702da3e84fa15bb21e2bf22 100644 (file)
@@ -212,13 +212,24 @@ public class CaretModelWindow implements CaretModel {
 
   @Override
   public void setCaretsAndSelections(@NotNull List<CaretState> caretStates) {
+    List<CaretState> convertedStates = convertCaretStates(caretStates);
+    myDelegate.setCaretsAndSelections(convertedStates);
+  }
+
+  @Override
+  public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
+    List<CaretState> convertedStates = convertCaretStates(caretStates);
+    myDelegate.setCaretsAndSelections(convertedStates, updateSystemSelection);
+  }
+
+  private List<CaretState> convertCaretStates(List<CaretState> caretStates) {
     List<CaretState> convertedStates = new ArrayList<CaretState>(caretStates.size());
     for (CaretState state : caretStates) {
       convertedStates.add(new CaretState(injectedToHost(state.getCaretPosition()),
                                          injectedToHost(state.getSelectionStart()),
                                          injectedToHost(state.getSelectionEnd())));
     }
-    myDelegate.setCaretsAndSelections(convertedStates);
+    return convertedStates;
   }
 
   private LogicalPosition injectedToHost(@Nullable LogicalPosition position) {
index e52fa66ccefc177f5762d7103ba8f4edf7d514ab..ec958fdc557a43a1f1b3275524ab52234c3ffb2c 100644 (file)
@@ -165,6 +165,12 @@ public class InjectedCaret implements Caret {
   }
 
   @Override
+  public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+    TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
+    myDelegate.setSelection(hostRange.getStartOffset(), hostRange.getEndOffset(), updateSystemSelection);
+  }
+
+  @Override
   public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
     TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
     myDelegate.setSelection(hostRange.getStartOffset(), endPosition, hostRange.getEndOffset());
@@ -177,6 +183,12 @@ public class InjectedCaret implements Caret {
   }
 
   @Override
+  public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection) {
+    TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
+    myDelegate.setSelection(startPosition, hostRange.getStartOffset(), endPosition, hostRange.getEndOffset(), updateSystemSelection);
+  }
+
+  @Override
   public void removeSelection() {
     myDelegate.removeSelection();
   }
index c769f92fff78d653b5e50b38c9561a1a8586e7ac..e2693b2c835fec1bfed3375b1c1ed2eee5477bd3 100644 (file)
@@ -1156,7 +1156,13 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
 
   @Override
   public void setSelection(int startOffset, int endOffset) {
-    doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false);
+    setSelection(startOffset, endOffset, true);
+  }
+
+  @Override
+  public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+    doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false,
+                   updateSystemSelection);
   }
 
   @Override
@@ -1173,16 +1179,22 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
 
   @Override
   public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
+    setSelection(startPosition, startOffset, endPosition, endOffset, true);
+  }
+
+  @Override
+  public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection) {
     VisualPosition startPositionToUse = startPosition == null ? myEditor.offsetToVisualPosition(startOffset) : startPosition;
     VisualPosition endPositionToUse = endPosition == null ? myEditor.offsetToVisualPosition(endOffset) : endPosition;
-    doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true);
+    doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true, updateSystemSelection);
   }
 
   private void doSetSelection(@NotNull final VisualPosition startPosition,
                               final int _startOffset,
                               @NotNull final VisualPosition endPosition,
                               final int _endOffset,
-                              final boolean visualPositionAware)
+                              final boolean visualPositionAware,
+                              final boolean updateSystemSelection)
   {
     myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
       public void run() {
@@ -1278,7 +1290,9 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
 
         myEditor.getSelectionModel().fireSelectionChanged(oldSelectionStart, oldSelectionEnd, startOffset, endOffset);
 
-        updateSystemSelection();
+        if (updateSystemSelection) {
+          updateSystemSelection();
+        }
       }
     });
   }
index 8d6608e63dd923ffd7e13df21e61ed9aeab51602..15a907e826e41c674f4351ed71ad4869f6d3aa14 100644 (file)
@@ -443,6 +443,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
 
   @Override
   public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates) {
+    setCaretsAndSelections(caretStates, true);
+  }
+
+  @Override
+  public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates, final boolean updateSystemSelection) {
     myEditor.assertIsDispatchThread();
     if (caretStates.isEmpty()) {
       throw new IllegalArgumentException("At least one caret should exist");
@@ -474,9 +479,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
             caret.moveToLogicalPosition(caretState.getCaretPosition());
           }
           if (caretState != null && caretState.getSelectionStart() != null && caretState.getSelectionEnd() != null) {
-            caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()), myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
-                               myEditor.logicalToVisualPosition(caretState.getSelectionEnd()), myEditor.logicalPositionToOffset(
-              caretState.getSelectionEnd()));
+            caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()),
+                               myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
+                               myEditor.logicalToVisualPosition(caretState.getSelectionEnd()),
+                               myEditor.logicalPositionToOffset(caretState.getSelectionEnd()),
+                               updateSystemSelection);
           }
         }
         int caretsToRemove = myCarets.size() - caretStates.size();
index 92ef12c46558590743de64cda156f257a8c26236..48ba57e150cff5eb952c38cbac46a7708539842e 100644 (file)
@@ -151,6 +151,12 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret {
   }
 
   @Override
+  public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+    // updating system selection is not supported currently for TextComponentEditor
+    setSelection(startOffset, endOffset);
+  }
+
+  @Override
   public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
     getSelectionModel().setSelection(startOffset, endPosition, endOffset);
   }
@@ -161,6 +167,13 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret {
   }
 
   @Override
+  public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset,
+                           boolean updateSystemSelection) {
+    // updating system selection is not supported currently for TextComponentEditor
+    setSelection(startPosition, startOffset, endPosition, endOffset);
+  }
+
+  @Override
   public void removeSelection() {
     getSelectionModel().removeSelection();
   }
index ac415f5f9409f5b9a2cb031becc3ffe9baf37c74..341c8ace35989388369a350bc5d4895f6071be67 100644 (file)
@@ -187,6 +187,11 @@ public class TextComponentCaretModel implements CaretModel {
     throw new UnsupportedOperationException("Multiple carets are not supported");
   }
 
+  @Override
+  public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
+    throw new UnsupportedOperationException("Multiple carets are not supported");
+  }
+
   @NotNull
   @Override
   public List<CaretState> getCaretsAndSelections() {
index 690e7c7d2820bda390dcf409e60905a7a747834a..14f0c95ec31b7cb3abb26c3eb2a99fe19a25d8cb 100644 (file)
@@ -287,7 +287,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
                                     new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
                                     new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
         }
-        caretModel.setCaretsAndSelections(states);
+        caretModel.setCaretsAndSelections(states, false);
       }
       else {
         LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
index c16f5f188cdcfeabdeb9b944ae48846514a70ba2..de39cc897c4b20b655c4905b9aa6ae3d30873763 100644 (file)
@@ -278,13 +278,18 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
   
   public void selectAll() {
     if (myEditor != null) {
-      myEditor.getSelectionModel().setSelection(0, myDocument.getTextLength());
+      doSelectAll(myEditor);
     }
     else {
       myWholeTextSelected = true;
     }
   }
 
+  private static void doSelectAll(@NotNull Editor editor) {
+    editor.getCaretModel().removeSecondaryCarets();
+    editor.getCaretModel().getPrimaryCaret().setSelection(0, editor.getDocument().getTextLength(), false);
+  }
+
   public void removeSelection() {
     if (myEditor != null) {
       myEditor.getSelectionModel().removeSelection();
@@ -514,7 +519,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
       editor.getSelectionModel().removeSelection();
     }
     else if (myWholeTextSelected) {
-      editor.getSelectionModel().setSelection(0, myDocument.getTextLength());
+      doSelectAll(editor);
     }
 
     editor.putUserData(SUPPLEMENTARY_KEY, myIsSupplementary);