Add title to MultipleFileMergeDialog
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 25 Feb 2011 09:46:34 +0000 (12:46 +0300)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Thu, 10 Mar 2011 16:09:01 +0000 (19:09 +0300)
MultipleFileMergeDialog.myDescriptionLabel above the table with unmerged files. Description may be null.

Overload AbstractVcsHelper.showMergeDialog with optional description.

Set the description in Git update processes to clarify, where these unmerged files came from - during update, before update, during unstash, etc.

platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java
platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java
platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.form
platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java
plugins/git4idea/src/git4idea/merge/GitMergeConflictResolver.java
plugins/git4idea/src/git4idea/rebase/GitRebaser.java
plugins/git4idea/src/git4idea/update/GitMergeUpdater.java
plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java
plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java
plugins/git4idea/src/git4idea/update/GitUpdateProcess.java
plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java

index 947747b150ed1216d9ec0cc5ba93f05a51c992ee..5cb11bac7de500499ec449d8cc54d82a819c04b0 100644 (file)
@@ -93,15 +93,26 @@ public abstract class AbstractVcsHelper {
                                                int maxCount,
                                                final String title);
 
-  @NotNull
-  public abstract List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider);
-
   /**
    * Shows the multiple file merge dialog for resolving conflicts in the specified set of virtual files.
    * Assumes all files are under the same VCS.
    *
    * @param files the files to show in the merge dialog.
-   * @return the files for which the merge was actually performed.
+   * @param provider MergeProvider to be used for merging.
+   * @param description Optional description text (may be HTML) to be shown at the top of the merge dialog.
+   * @return changed files for which the merge was actually performed.
+   */
+  public abstract @NotNull List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @Nullable String description);
+
+  /**
+   * {@link #showMergeDialog(java.util.List, com.intellij.openapi.vcs.merge.MergeProvider)} without description.
+   */
+  @NotNull
+  public abstract List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider);
+
+  /**
+   * {@link #showMergeDialog(java.util.List, com.intellij.openapi.vcs.merge.MergeProvider)} without description and with default merge provider
+   * for the current VCS.
    */
   @NotNull
   public abstract List<VirtualFile> showMergeDialog(List<VirtualFile> files);
index c8eef7b16c22cf58af40c0a4c65e0da98d82e364..f46c662b9b15a590d3b22a2e0b8d658f9c92f81b 100644 (file)
@@ -631,10 +631,17 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
     }
   }
 
+  @Override
   @NotNull
   public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider) {
+    return showMergeDialog(files, provider, null);
+  }
+
+  @Override
+  @NotNull
+  public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @Nullable String description) {
     if (files.isEmpty()) return Collections.emptyList();
-    final MultipleFileMergeDialog fileMergeDialog = new MultipleFileMergeDialog(myProject, files, provider);
+    final MultipleFileMergeDialog fileMergeDialog = new MultipleFileMergeDialog(myProject, files, provider, description);
     fileMergeDialog.show();
     return fileMergeDialog.getProcessedFiles();
   }
index 42a22f7790fb2a65449f792cf68d021e61d31580..38e9bfe42b08262b1e14b1c18cf8b5e0adaca7ac 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.vcs.merge.MultipleFileMergeDialog">
-  <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
       <xy x="20" y="20" width="500" height="400"/>
@@ -11,7 +11,7 @@
       <grid id="5c044" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="0" left="0" bottom="0" right="0"/>
         <constraints>
-          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties/>
         <border type="none"/>
@@ -47,9 +47,9 @@
           </component>
         </children>
       </grid>
-      <scrollpane class="com.intellij.ui.components.JBScrollPane" id="9f9b5">
+      <scrollpane id="9f9b5" class="com.intellij.ui.components.JBScrollPane">
         <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties/>
         <border type="none"/>
           </component>
         </children>
       </scrollpane>
+      <grid id="b4733" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="5" left="5" bottom="5" right="5"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="f8ecf" class="com.intellij.ui.components.JBLabel" binding="myDescriptionLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+          </component>
+        </children>
+      </grid>
     </children>
   </grid>
 </form>
index 3add8dd4eb3c9b0f881038db429b6a5686cc8be2..cef84e7057037f0b1be903f01d2f50fb82e071ec 100644 (file)
@@ -38,6 +38,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.projectImport.ProjectOpenProcessor;
 import com.intellij.ui.ColoredTableCellRenderer;
 import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.ui.components.JBLabel;
 import com.intellij.ui.table.TableView;
 import com.intellij.util.ui.ColumnInfo;
 import com.intellij.util.ui.ListTableModel;
@@ -63,6 +64,7 @@ public class MultipleFileMergeDialog extends DialogWrapper {
   private JButton myAcceptTheirsButton;
   private JButton myMergeButton;
   private TableView<VirtualFile> myTable;
+  private JBLabel myDescriptionLabel;
   private final MergeProvider myProvider;
   private final MergeSession myMergeSession;
   private final List<VirtualFile> myFiles;
@@ -105,7 +107,7 @@ public class MultipleFileMergeDialog extends DialogWrapper {
       }
     };
 
-  public MultipleFileMergeDialog(Project project, final List<VirtualFile> files, final MergeProvider provider) {
+  public MultipleFileMergeDialog(Project project, final List<VirtualFile> files, final MergeProvider provider, String description) {
     super(project, false);
     myProject = project;
     myProjectManager = ProjectManagerEx.getInstanceEx();
@@ -113,6 +115,10 @@ public class MultipleFileMergeDialog extends DialogWrapper {
     myFiles = new ArrayList<VirtualFile>(files);
     myProvider = provider;
 
+    if (!StringUtil.isEmptyOrSpaces(description)) {
+      myDescriptionLabel.setText(description);
+    }
+
     List<ColumnInfo> columns = new ArrayList<ColumnInfo>();
     Collections.addAll(columns, NAME_COLUMN, TYPE_COLUMN);
     if (myProvider instanceof MergeProvider2) {
index 2e170eb6603e5c535d45214efbc472aa6f80b15f..5bc4c9421fb6b8d7a5ef79c76c821ba87dbea60f 100644 (file)
@@ -29,6 +29,7 @@ import com.intellij.util.ui.UIUtil;
 import git4idea.GitVcs;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.event.HyperlinkEvent;
 import java.util.ArrayList;
@@ -43,17 +44,19 @@ public class GitMergeConflictResolver {
   private final boolean myReverseMerge;
   private final String myErrorNotificationTitle;
   private final String myErrorNotificationAdditionalDescription;
+  @Nullable private final String myMergeDialogTitle;
   private final AbstractVcsHelper myVcsHelper;
   private final GitVcs myVcs;
 
   /**
    * @param reverseMerge specify if reverse merge provider has to be used for merging - it is the case of rebase or stash.
    */
-  public GitMergeConflictResolver(@NotNull Project project, boolean reverseMerge, @NonNls String errorNotificationTitle, @NotNull String errorNotificationAdditionalDescription) {
+  public GitMergeConflictResolver(@NotNull Project project, boolean reverseMerge, @Nullable String mergeDialogTitle, @NonNls String errorNotificationTitle, @NotNull String errorNotificationAdditionalDescription) {
     myProject = project;
     myReverseMerge = reverseMerge;
     myErrorNotificationTitle = errorNotificationTitle;
     myErrorNotificationAdditionalDescription = errorNotificationAdditionalDescription;
+    myMergeDialogTitle = mergeDialogTitle;
     myVcsHelper = AbstractVcsHelper.getInstance(project);
     myVcs = GitVcs.getInstance(project);
   }
@@ -75,13 +78,11 @@ public class GitMergeConflictResolver {
       if (unmergedFiles.isEmpty()) {
         return proceedIfNothingToMerge();
       } else {
-        // TODO add descriptive message to the dialog:
-        // You must resolve all conflicts before you continue rebase
         final Collection<VirtualFile> finalUnmergedFiles = unmergedFiles;
         UIUtil.invokeAndWaitIfNeeded(new Runnable() {
           @Override public void run() {
             final MergeProvider mergeProvider = myReverseMerge ? myVcs.getReverseMergeProvider() : myVcs.getMergeProvider();
-            myVcsHelper.showMergeDialog(new ArrayList<VirtualFile>(finalUnmergedFiles), mergeProvider);
+            myVcsHelper.showMergeDialog(new ArrayList<VirtualFile>(finalUnmergedFiles), mergeProvider, myMergeDialogTitle);
           }
         });
 
index c377cee0820f5d9c53e98aad024ea51b33fbc3d7..2014895e7f043ec05621ec60ec63ad428b968e36 100644 (file)
@@ -77,7 +77,8 @@ public class GitRebaser {
 
       @Override protected void onFailure() {
         if (rebaseConflictDetector.isMergeConflict()) {
-          result.set(new GitMergeConflictResolver(myProject, true, "Can't continue rebase", "Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing.") {
+          result.set(new GitMergeConflictResolver(myProject, true, "Merge conflicts detected. Resolve them before continuing rebase.",
+                                                  "Can't continue rebase", "Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing.") {
             @Override protected boolean proceedIfNothingToMerge() {
               return continueRebase(root, "--continue");
             }
index 14b30cf0490df690776dab08b128ff936aee057c..4488d49414a0aa55d466c1fcdfaab6595c74a05c 100644 (file)
@@ -83,7 +83,8 @@ public class GitMergeUpdater extends GitUpdater {
       @Override protected void onFailure() {
         final MergeError error = mergeError.get();
         if (error == MergeError.CONFLICT) {
-          final boolean allMerged = new GitMergeConflictResolver(myProject, true, "Can't update", "") {
+          final boolean allMerged = new GitMergeConflictResolver(myProject, true, "Merge conflicts detected. Resolve them before continuing update.",
+                                                                 "Can't update", "") {
             @Override protected boolean proceedIfNothingToMerge() throws VcsException {
               merger.mergeCommit(myRoot);
               return true;
index a45ce0f7667e39b228bb3b5919658a687dea2d96..826a3aebe2a61c0cc968267b9aabb7ac9a1a7c24 100644 (file)
@@ -65,7 +65,7 @@ public class GitRebaseUpdater extends GitUpdater {
 
       @Override protected void onFailure() {
         if (rebaseConflictDetector.isMergeConflict()) {
-          final boolean allMerged = new GitMergeConflictResolver(myProject, true, "Can't continue rebase", "Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing.") {
+          final boolean allMerged = new GitMergeConflictResolver(myProject, true, "Merge conflicts detected. Resolve them before continuing rebase.", "Can't continue rebase", "Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing.") {
             @Override protected boolean proceedIfNothingToMerge() throws VcsException {
               return myRebaser.continueRebase(myRoot);
             }
index 9474225bfee547915840c49b6ab0f1a621d70c07..f05c76b7c01a3efe2e0a44822cb34d89ffa1a428 100644 (file)
@@ -135,7 +135,8 @@ public class GitStashChangesSaver extends GitChangesSaver {
 
       @Override protected void onFailure() {
         if (conflict.get()) {
-          new GitMergeConflictResolver(myProject, true, "Can't update", "").mergeFiles(Collections.singleton(root));
+          new GitMergeConflictResolver(myProject, true, "Uncommitted changes that were stashed before update have conflicts with updated files.",
+                                       "Can't update", "").mergeFiles(Collections.singleton(root));
         } else {
           GitUIUtil.notifyImportantError(myProject, "Couldn't unstash", "<br/>" + GitUIUtil.stringifyErrors(handler.errors()));
         }
index cdcfcf330f3ee70dbfe22da589f163a3698c4d6a..c7fe916571a7c1e1b7224c8ba18a379ed2e878b0 100644 (file)
@@ -167,7 +167,7 @@ public class GitUpdateProcess {
       return false;
     }
 
-    return !new GitMergeConflictResolver(myProject, false, "Can't update", "") {
+    return !new GitMergeConflictResolver(myProject, false, "You have unfinished merge. These conflicts must be resolved before update.", "Can't update", "") {
       @Override protected boolean proceedAfterAllMerged() throws VcsException {
         myMerger.mergeCommit(mergingRoots);
         return true;
@@ -207,7 +207,7 @@ public class GitUpdateProcess {
       return false;
     }
 
-    return !new GitMergeConflictResolver(myProject, true, "Can't update",
+    return !new GitMergeConflictResolver(myProject, true, "You have unfinished rebase process. These conflicts must be resolved before update.", "Can't update",
                                          "Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing.") {
       @Override protected boolean proceedIfNothingToMerge() {
         return rebaser.continueRebase(rebasingRoots);
index fff46294849d221fb5f0ec5e32d70fae5f8f4e4f..ede5ec8190236af19be263533a7bb99bc891e8ac 100644 (file)
@@ -109,6 +109,12 @@ public class HgMockVcsHelper extends AbstractVcsHelper {
                                       String title) {
   }
 
+  @NotNull
+  @Override
+  public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @Nullable String description) {
+    return null;
+  }
+
   @NotNull
   @Override
   public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider) {