vcs: non-modal: Add "Rollback File" action that only works with selection to the...
authorKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Mon, 21 Dec 2020 10:53:45 +0000 (13:53 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Mon, 21 Dec 2020 22:32:19 +0000 (22:32 +0000)
GitOrigin-RevId: 2d79458fa1d70b10cd4112d7d1ccea2bbbf8ef48

platform/platform-resources-en/src/messages/ActionsBundle.properties
platform/vcs-api/vcs-api-core/resources/messages/VcsBundle.properties
platform/vcs-impl/resources/META-INF/VcsActions.xml
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsTopHitProvider.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackFilesAction.kt [new file with mode: 0644]
plugins/git4idea/resources/META-INF/plugin.xml
plugins/hg4idea/src/META-INF/plugin.xml

index bcee0d9a5bc8afb2b160bc11db55eead2d6ca839..90e0531870ed213a03a35efa296af8d7c037a1ef 100644 (file)
@@ -1381,6 +1381,7 @@ action.ChangesView.Refresh.description=Refresh VCS changes
 action.ChangesView.NewChangeList.text=New Changelist...
 action.ChangesView.NewChangeList.description=Create new changelist
 action.ChangesView.Revert.text=_Rollback\u2026
+action.ChangesView.RevertFiles.text=_Rollback File\u2026
 action.ChangesView.RemoveChangeList.text=Delete Changelist
 action.ChangesView.RemoveChangeList.description=Remove changelist and move all changes to another
 action.ChangesView.RemoveChangeList.text.template=Delete {0,choice,0#Changelist|2#Changelists}
index 42f85bf7e876b5e404b3308875e69865bca62e94..ce93004a66db16a3fa65a482d95c3b5d32d012c5 100644 (file)
@@ -80,6 +80,7 @@ diff.title.local.with.number=Local ({0})
 message.title.annotate=Annotate
 action.name.checkin.directory={0} {1,choice,1#Directory|2#Directories}
 action.name.checkin.file={0} {1,choice,1#File|2#Files}
+action.for.file.with.dialog.text={0} {1,choice,1#File|2#Files}\u2026
 column.name.revision.list.author=Author
 column.name.revisions.list.filter=Date
 column.name.revisions.list.branch=Branch
index fe2f84707c3dc8d35bebd2c33adef2f68e5ce717..daa9141dfae7df204583889eff9d4aec81151acf 100644 (file)
 
     <action id="ChangesView.Revert" class="com.intellij.openapi.vcs.changes.actions.RollbackAction"
             icon="AllIcons.Actions.Rollback"/>
+    <action id="ChangesView.RevertFiles" class="com.intellij.openapi.vcs.changes.actions.RollbackFilesAction"/>
 
     <group id="ChangesView.ViewOptions"/>
 
     <group id="ChangesViewPopupMenu">
       <reference ref="CheckinFiles"/>
       <reference ref="ChangesView.Revert"/>
+      <reference ref="ChangesView.RevertFiles"/>
       <reference ref="ChangesView.Move"/>
       <reference ref="Diff.ShowDiff"/>
       <reference ref="EditSource"/>
       <reference ref="ChangesView.ApplyPatch"/>
       <reference ref="ChangesView.ApplyPatchFromClipboard"/>
       <reference ref="ChangesView.Revert"/>
+      <reference ref="ChangesView.RevertFiles"/>
       <reference ref="ChangesView.Refresh"/>
       <reference ref="ChangesView.NewChangeList"/>
       <reference ref="ChangesView.RemoveChangeList"/>
index a33cd626043067479c795a6ff57656b59bccfcaf..728bdb6a6c82b91d8dfe04bd9ee0921c3d50b289 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.vcs.actions;
 
 import com.intellij.ide.ActionsTopHitProvider;
@@ -20,6 +20,8 @@ public class VcsTopHitProvider extends ActionsTopHitProvider {
      {"comm", "commit ", "ChangesView.ToggleCommitUi"},
      {"reve", "revert ", "ChangesView.Revert"},
      {"roll", "rollback ", "ChangesView.Revert"},
+     {"reve", "revert ", "ChangesView.RevertFiles"},
+     {"roll", "rollback ", "ChangesView.RevertFiles"},
      {"compare", "compare ", "Compare.SameVersion"},
      {"create p", "create patch ", "ChangesView.CreatePatch"},
      {"pat", "patch ", "ChangesView.CreatePatch"},
index e0afbb6d16501c97685d09929363086b6e5343f9..af6f173c45558ca478a7760501ae70fb15d82af5 100644 (file)
@@ -2,7 +2,10 @@
 
 package com.intellij.openapi.vcs.changes.actions;
 
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.UpdateInBackground;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -28,10 +31,11 @@ import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
 
+import static com.intellij.openapi.actionSystem.ActionPlaces.CHANGES_VIEW_POPUP;
 import static com.intellij.openapi.ui.Messages.getQuestionIcon;
 import static com.intellij.openapi.ui.Messages.showYesNoDialog;
 import static com.intellij.openapi.util.text.StringUtil.ELLIPSIS;
-import static com.intellij.openapi.util.text.StringUtil.removeEllipsisSuffix;
+import static com.intellij.openapi.vcs.actions.AbstractCommonCheckinActionKt.isProjectUsesNonModalCommit;
 import static com.intellij.util.containers.ContainerUtil.*;
 import static com.intellij.util.containers.UtilKt.notNullize;
 import static com.intellij.util.ui.UIUtil.removeMnemonic;
@@ -42,13 +46,14 @@ import static java.util.Objects.requireNonNull;
 public class RollbackAction extends AnAction implements DumbAware, UpdateInBackground {
   @Override
   public void update(@NotNull AnActionEvent e) {
-    Project project = e.getData(CommonDataKeys.PROJECT);
-    boolean visible = project != null && ProjectLevelVcsManager.getInstance(project).hasActiveVcss();
-    e.getPresentation().setEnabledAndVisible(visible);
-    if (!visible) return;
+    e.getPresentation().setEnabledAndVisible(false);
+
+    Project project = e.getProject();
+    if (project == null || !ProjectLevelVcsManager.getInstance(project).hasActiveVcss()) return;
+    if (isProjectUsesNonModalCommit(e) && CHANGES_VIEW_POPUP.equals(e.getPlace())) return;
 
     Change[] leadSelection = e.getData(VcsDataKeys.CHANGE_LEAD_SELECTION);
-    boolean isEnabled =
+    boolean hasDataToRollback =
       !ArrayUtil.isEmpty(leadSelection) ||
       Boolean.TRUE.equals(e.getData(VcsDataKeys.HAVE_LOCALLY_DELETED)) ||
       Boolean.TRUE.equals(e.getData(VcsDataKeys.HAVE_MODIFIED_WITHOUT_EDITING)) ||
@@ -57,7 +62,8 @@ public class RollbackAction extends AnAction implements DumbAware, UpdateInBackg
       hasReversibleFiles(e) ||
       currentChangelistNotEmpty(project);
 
-    e.getPresentation().setEnabled(isEnabled);
+    e.getPresentation().setVisible(true);
+    e.getPresentation().setEnabled(hasDataToRollback);
     e.getPresentation().setText(getRollbackOperationName(project) + ELLIPSIS);
   }
 
@@ -77,16 +83,9 @@ public class RollbackAction extends AnAction implements DumbAware, UpdateInBackg
 
   @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
-    Project project = e.getData(CommonDataKeys.PROJECT);
-    if (project == null) {
-      return;
-    }
-    final String title = ActionPlaces.CHANGES_VIEW_TOOLBAR.equals(e.getPlace())
-                         ? null
-                         : VcsBundle.message("error.cant.perform.operation.now",
-                                             removeEllipsisSuffix(removeMnemonic(getRollbackOperationName(project))));
-    if (ChangeListManager.getInstance(project).isFreezedWithNotification(title)) return;
+    if (!RollbackFilesAction.checkClmActive(e)) return;
 
+    Project project = requireNonNull(e.getProject());
     List<FilePath> missingFiles = e.getData(ChangesListView.MISSING_FILES_DATA_KEY);
     Collection<Change> changes = getChanges(e);
     LinkedHashSet<VirtualFile> modifiedWithoutEditing = getModifiedWithoutEditing(e, project);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackFilesAction.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackFilesAction.kt
new file mode 100644 (file)
index 0000000..638ae8a
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.openapi.vcs.changes.actions
+
+import com.intellij.openapi.actionSystem.ActionPlaces.CHANGES_VIEW_TOOLBAR
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.fileEditor.FileDocumentManager
+import com.intellij.openapi.project.DumbAwareAction
+import com.intellij.openapi.util.text.StringUtil.removeEllipsisSuffix
+import com.intellij.openapi.vcs.VcsBundle.message
+import com.intellij.openapi.vcs.VcsDataKeys
+import com.intellij.openapi.vcs.actions.isProjectUsesNonModalCommit
+import com.intellij.openapi.vcs.changes.ChangeListManager
+import com.intellij.openapi.vcs.changes.ui.ChangesListView
+import com.intellij.openapi.vcs.changes.ui.RollbackChangesDialog
+import com.intellij.util.ui.UIUtil.removeMnemonic
+import com.intellij.vcsUtil.RollbackUtil.getRollbackOperationName
+import kotlin.streams.toList
+
+class RollbackFilesAction : DumbAwareAction() {
+  override fun update(e: AnActionEvent) {
+    e.presentation.isEnabledAndVisible = false
+
+    if (!e.isProjectUsesNonModalCommit()) return
+    val project = e.project ?: return
+    val changesView = e.getData(ChangesListView.DATA_KEY) ?: return
+    val changes = changesView.selectedChanges.limit(2).toList()
+
+    with(e.presentation) {
+      isVisible = true
+      isEnabled = changes.isNotEmpty()
+      text = message("action.for.file.with.dialog.text", getRollbackOperationName(project), changes.size)
+    }
+  }
+
+  override fun actionPerformed(e: AnActionEvent) {
+    if (!checkClmActive(e)) return
+
+    val project = e.project!!
+    val changes = e.getData(VcsDataKeys.CHANGES)!!.toList()
+
+    FileDocumentManager.getInstance().saveAllDocuments()
+    RollbackChangesDialog.rollbackChanges(project, changes)
+  }
+
+  companion object {
+    @JvmStatic
+    fun checkClmActive(e: AnActionEvent): Boolean {
+      val project = e.project ?: return false
+      val title =
+        if (CHANGES_VIEW_TOOLBAR == e.place) null
+        else message("error.cant.perform.operation.now", removeEllipsisSuffix(removeMnemonic(getRollbackOperationName(project))))
+
+      return !ChangeListManager.getInstance(project).isFreezedWithNotification(title)
+    }
+  }
+}
\ No newline at end of file
index 57e77158e7e3d6eacc32cba6d079d79839e1a038..c9d14327cc9b910d03ddec6503bd90214025ca68 100644 (file)
       <reference ref="Git.FileActions"/>
       <reference ref="Show.Current.Revision"/>
       <reference ref="ChangesView.Revert" />
+      <reference ref="ChangesView.RevertFiles" />
       <separator/>
       <reference ref="Git.ResolveConflicts" />
       <separator/>
index 9fd9648329cca2b2919b1dfe540f1229d8655dae..1f92def75c70098537a6b3e949b5b0d146f79f04 100644 (file)
@@ -93,6 +93,7 @@
       <action id="hg4idea.add" class="com.intellij.openapi.vcs.changes.actions.ScheduleForAdditionWithIgnoredFilesConfirmationAction"
               icon="AllIcons.General.Add" use-shortcut-of="ChangesView.AddUnversioned"/>
       <reference ref="ChangesView.Revert"/>
+      <reference ref="ChangesView.RevertFiles"/>
       <separator/>
 
       <reference ref="Compare.SameVersion"/>