MergeDialogCustomizer to customize titles and messages in the MultipleFileMergeDialog.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Sun, 20 Mar 2011 10:25:18 +0000 (13:25 +0300)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Sun, 20 Mar 2011 10:25:18 +0000 (13:25 +0300)
1. MergeDialogCustomizer to define description shown in the MultipleFileMergeDialog and titles above columns in the 3-way merge tool.
2. AbstractVcsHelper.showMergeDialog receive a MergeDialogCustomizer.
3. Define the customizer while unstashing during update.
4. Fix swapped local/server columns in the merge tool when unstashing during update.

platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java
platform/vcs-api/src/com/intellij/openapi/vcs/merge/MergeDialogCustomizer.java [new file with mode: 0644]
platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java
platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java
plugins/git4idea/src/git4idea/merge/GitMergeConflictResolver.java
plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java
plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java

index 5cb11bac7de500499ec449d8cc54d82a819c04b0..053cbb880d1bf67736da7726b551e671ed639f8e 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.openapi.vcs.annotate.FileAnnotation;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vcs.history.VcsFileRevision;
 import com.intellij.openapi.vcs.history.VcsHistoryProvider;
+import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
 import com.intellij.openapi.vcs.merge.MergeProvider;
 import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
 import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
@@ -99,10 +100,10 @@ public abstract class AbstractVcsHelper {
    *
    * @param files the files to show in the merge dialog.
    * @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.
+   * @param mergeDialogCustomizer custom container of titles, descriptions and messages for 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);
+  public abstract @NotNull List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @NotNull MergeDialogCustomizer mergeDialogCustomizer);
 
   /**
    * {@link #showMergeDialog(java.util.List, com.intellij.openapi.vcs.merge.MergeProvider)} without description.
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/merge/MergeDialogCustomizer.java b/platform/vcs-api/src/com/intellij/openapi/vcs/merge/MergeDialogCustomizer.java
new file mode 100644 (file)
index 0000000..cced656
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vcs.merge;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.VcsBundle;
+import com.intellij.openapi.vcs.history.VcsRevisionNumber;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * Provides custom titles and messages used in MultipleFileMergeDialog and DiffTool invoked from it.
+ * @author Kirill Likhodedov
+ */
+public class MergeDialogCustomizer {
+
+  /**
+   * @param files files that have conflicted changes and are shown in the dialog.
+   * @return description that is shows above the list of conflicted files. Null (which is equivalent to empty) by default.
+   */
+  public @Nullable String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
+    return null;
+  }
+
+  /**
+   * @param file file that is merged.
+   * @return title of the merge dialog invoked for a 3-way merge of a file.
+   */
+  public @Nullable String getMergeWindowTitle(VirtualFile file) {
+    return VcsBundle.message("multiple.file.merge.request.title", FileUtil.toSystemDependentName(file.getPresentableUrl()));
+  }
+
+  /**
+   * @param file file that is merged.
+   * @return title that is shown above the left panel in the 3-way merge dialog. "Local changes" by default.
+   */
+  public @Nullable String getLeftPanelTitle(VirtualFile file) {
+    return VcsBundle.message("merge.version.title.local.changes");
+  }
+
+  /**
+   * @param file file that is merged.
+   * @return title that is shown above the center panel in the 3-way merge dialog. "Merge result" by default.
+   */
+  public @Nullable String getCenterPanelTitle(VirtualFile file) {
+    return VcsBundle.message("merge.version.title.merge.result");
+  }
+
+  /**
+   * @param file file that is merged.
+   * @param lastRevisionNumber
+   * @return title that is shown above the right panel in the 3-way merge dialog. "Changes from server" with the revision number by default.
+   */
+  public @Nullable String getRightPanelTitle(VirtualFile file, VcsRevisionNumber lastRevisionNumber) {
+    if (lastRevisionNumber != null) {
+      return VcsBundle.message("merge.version.title.last.version.number", lastRevisionNumber.asString());
+    } else {
+      return VcsBundle.message("merge.version.title.last.version");
+    }
+  }
+
+}
index f46c662b9b15a590d3b22a2e0b8d658f9c92f81b..a61e17ad48768439809fc22ad84dab9a3f7a18f6 100644 (file)
@@ -53,6 +53,7 @@ import com.intellij.openapi.vcs.changes.committed.*;
 import com.intellij.openapi.vcs.changes.ui.*;
 import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx;
 import com.intellij.openapi.vcs.history.*;
+import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
 import com.intellij.openapi.vcs.merge.MergeProvider;
 import com.intellij.openapi.vcs.merge.MultipleFileMergeDialog;
 import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
@@ -634,14 +635,14 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
   @Override
   @NotNull
   public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider) {
-    return showMergeDialog(files, provider, null);
+    return showMergeDialog(files, provider, new MergeDialogCustomizer());
   }
 
   @Override
   @NotNull
-  public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @Nullable String description) {
+  public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @NotNull MergeDialogCustomizer mergeDialogCustomizer) {
     if (files.isEmpty()) return Collections.emptyList();
-    final MultipleFileMergeDialog fileMergeDialog = new MultipleFileMergeDialog(myProject, files, provider, description);
+    final MultipleFileMergeDialog fileMergeDialog = new MultipleFileMergeDialog(myProject, files, provider, mergeDialogCustomizer);
     fileMergeDialog.show();
     return fileMergeDialog.getProcessedFiles();
   }
index cef84e7057037f0b1be903f01d2f50fb82e071ec..6a5a28f0493b32207c2c6c35e5c33e5fc0937543 100644 (file)
@@ -34,6 +34,7 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsBundle;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
+import com.intellij.openapi.vcs.history.VcsRevisionNumber;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.projectImport.ProjectOpenProcessor;
 import com.intellij.ui.ColoredTableCellRenderer;
@@ -73,6 +74,7 @@ public class MultipleFileMergeDialog extends DialogWrapper {
   private final ProjectManagerEx myProjectManager;
   private final List<VirtualFile> myProcessedFiles = new ArrayList<VirtualFile>();
   private final Set<VirtualFile> myBinaryFiles = new HashSet<VirtualFile>();
+  private final MergeDialogCustomizer myMergeDialogCustomizer;
 
   private final VirtualFileRenderer myVirtualFileRenderer = new VirtualFileRenderer();
 
@@ -107,14 +109,16 @@ public class MultipleFileMergeDialog extends DialogWrapper {
       }
     };
 
-  public MultipleFileMergeDialog(Project project, final List<VirtualFile> files, final MergeProvider provider, String description) {
+  public MultipleFileMergeDialog(Project project, final List<VirtualFile> files, final MergeProvider provider, MergeDialogCustomizer mergeDialogCustomizer) {
     super(project, false);
     myProject = project;
     myProjectManager = ProjectManagerEx.getInstanceEx();
     myProjectManager.blockReloadingProjectOnExternalChanges();
     myFiles = new ArrayList<VirtualFile>(files);
     myProvider = provider;
+    myMergeDialogCustomizer = mergeDialogCustomizer;
 
+    final String description = myMergeDialogCustomizer.getMultipleFileMergeDescription(files);
     if (!StringUtil.isEmptyOrSpaces(description)) {
       myDescriptionLabel.setText(description);
     }
@@ -297,18 +301,14 @@ public class MultipleFileMergeDialog extends DialogWrapper {
       MergeRequest request = diffRequestFactory
         .createMergeRequest(leftText, rightText, originalText, file, myProject, ActionButtonPresentation.APPLY,
                             ActionButtonPresentation.CANCEL_WITH_PROMPT);
-      String lastVersionTitle;
-      if (mergeData.LAST_REVISION_NUMBER != null) {
-        lastVersionTitle = VcsBundle.message("merge.version.title.last.version.number", mergeData.LAST_REVISION_NUMBER.asString());
-      }
-      else {
-        lastVersionTitle = VcsBundle.message("merge.version.title.last.version");
-      }
-      request.setVersionTitles(
-        new String[]{VcsBundle.message("merge.version.title.local.changes"), VcsBundle.message("merge.version.title.merge.result"),
-          lastVersionTitle});
-      request
-        .setWindowTitle(VcsBundle.message("multiple.file.merge.request.title", FileUtil.toSystemDependentName(file.getPresentableUrl())));
+      final VcsRevisionNumber lastRevisionNumber = mergeData.LAST_REVISION_NUMBER;
+      request.setVersionTitles(new String[] {
+        myMergeDialogCustomizer.getLeftPanelTitle(file),
+        myMergeDialogCustomizer.getCenterPanelTitle(file),
+        myMergeDialogCustomizer.getRightPanelTitle(file, lastRevisionNumber)
+      });
+      request.setWindowTitle(myMergeDialogCustomizer.getMergeWindowTitle(file));
+
       DiffManager.getInstance().getDiffTool().show(request);
       if (request.getResult() == DialogWrapper.OK_EXIT_CODE) {
         markFileProcessed(file, MergeSession.Resolution.Merged);
index df26b354f90a82942963d1f4afc27e48d6a73817..faf90fe1c310d629bda28643b5fbcab400f1c603 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vcs.AbstractVcsHelper;
 import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
 import com.intellij.openapi.vcs.merge.MergeProvider;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ui.UIUtil;
@@ -45,7 +46,7 @@ public class GitMergeConflictResolver {
   private final boolean myReverseMerge;
   private final @NotNull String myErrorNotificationTitle;
   private final @NotNull String myErrorNotificationAdditionalDescription;
-  private final @Nullable String myMergeDialogTitle;
+  private final @NotNull MergeDialogCustomizer myMergeDialogCustomizer;
   private final AbstractVcsHelper myVcsHelper;
   private final GitVcs myVcs;
 
@@ -53,11 +54,15 @@ public class GitMergeConflictResolver {
    * @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, @Nullable String mergeDialogTitle, @NotNull String errorNotificationTitle, @NotNull String errorNotificationAdditionalDescription) {
+    this(project, reverseMerge, new SimpleMergeDialogCustomizer(mergeDialogTitle), errorNotificationTitle, errorNotificationAdditionalDescription);
+  }
+
+  public GitMergeConflictResolver(@NotNull Project project, boolean reverseMerge, @NotNull MergeDialogCustomizer mergeDialogCustomizer, @NotNull String errorNotificationTitle, @NotNull String errorNotificationAdditionalDescription) {
     myProject = project;
     myReverseMerge = reverseMerge;
     myErrorNotificationTitle = errorNotificationTitle;
     myErrorNotificationAdditionalDescription = errorNotificationAdditionalDescription;
-    myMergeDialogTitle = mergeDialogTitle;
+    myMergeDialogCustomizer = mergeDialogCustomizer;
     myVcsHelper = AbstractVcsHelper.getInstance(project);
     myVcs = GitVcs.getInstance(project);
   }
@@ -113,7 +118,7 @@ public class GitMergeConflictResolver {
         UIUtil.invokeAndWaitIfNeeded(new Runnable() {
           @Override public void run() {
             final MergeProvider mergeProvider = myReverseMerge ? myVcs.getReverseMergeProvider() : myVcs.getMergeProvider();
-            myVcsHelper.showMergeDialog(new ArrayList<VirtualFile>(finalUnmergedFiles), mergeProvider, myMergeDialogTitle);
+            myVcsHelper.showMergeDialog(new ArrayList<VirtualFile>(finalUnmergedFiles), mergeProvider, myMergeDialogCustomizer);
           }
         });
 
@@ -174,4 +179,17 @@ public class GitMergeConflictResolver {
       }
     }
   }
+
+  private static class SimpleMergeDialogCustomizer extends MergeDialogCustomizer {
+    private final String myMergeDialogTitle;
+
+    public SimpleMergeDialogCustomizer(String mergeDialogTitle) {
+      myMergeDialogTitle = mergeDialogTitle;
+    }
+
+    @Override
+    public String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
+      return myMergeDialogTitle;
+    }
+  }
 }
index c45bda3cc27f9d2a0707afbabccac9e83ad1bcb6..9cf6e5bf170564bf5920e6dbd748c47683396739 100644 (file)
@@ -28,6 +28,8 @@ import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vcs.changes.ContentRevision;
 import com.intellij.openapi.vcs.changes.LocalChangeList;
+import com.intellij.openapi.vcs.history.VcsRevisionNumber;
+import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
 import git4idea.GitUtil;
@@ -211,9 +213,7 @@ public class GitStashChangesSaver extends GitChangesSaver {
 
   private class UnstashConflictResolver extends GitMergeConflictResolver {
     public UnstashConflictResolver() {
-      super(GitStashChangesSaver.this.myProject, true,
-            "Uncommitted changes that were stashed before update have conflicts with updated files.", "Local changes were not restored",
-            "");
+      super(GitStashChangesSaver.this.myProject, false, new UnstashMergeDialogCustomizer(), "Local changes were not restored", "");
     }
 
     @Override
@@ -239,5 +239,18 @@ public class GitStashChangesSaver extends GitChangesSaver {
           }
       }));
     }
+
+  }
+
+  private static class UnstashMergeDialogCustomizer extends MergeDialogCustomizer {
+    @Override
+    public String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
+      return "Uncommitted changes that were stashed before update have conflicts with updated files.";
+    }
+
+    @Override
+    public String getRightPanelTitle(VirtualFile file, VcsRevisionNumber lastRevisionNumber) {
+      return "Changes from stash";
+    }
   }
 }
index ede5ec8190236af19be263533a7bb99bc891e8ac..ccfa7538b3aa93e23efba50ac3c26c37643940eb 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.vcs.annotate.FileAnnotation;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vcs.history.VcsFileRevision;
 import com.intellij.openapi.vcs.history.VcsHistoryProvider;
+import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
 import com.intellij.openapi.vcs.merge.MergeProvider;
 import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
 import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
@@ -111,7 +112,7 @@ public class HgMockVcsHelper extends AbstractVcsHelper {
 
   @NotNull
   @Override
-  public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @Nullable String description) {
+  public List<VirtualFile> showMergeDialog(List<VirtualFile> files, MergeProvider provider, @NotNull MergeDialogCustomizer mergeDialogCustomizer) {
     return null;
   }