From 06cb6a6d50656f7fe1d481fa4d3301968a9aeb31 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 25 Feb 2011 12:46:34 +0300 Subject: [PATCH] Add title to MultipleFileMergeDialog 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. --- .../openapi/vcs/AbstractVcsHelper.java | 19 +++++++++++---- .../vcs/impl/AbstractVcsHelperImpl.java | 9 ++++++- .../vcs/merge/MultipleFileMergeDialog.form | 24 +++++++++++++++---- .../vcs/merge/MultipleFileMergeDialog.java | 8 ++++++- .../merge/GitMergeConflictResolver.java | 9 +++---- .../src/git4idea/rebase/GitRebaser.java | 3 ++- .../src/git4idea/update/GitMergeUpdater.java | 3 ++- .../src/git4idea/update/GitRebaseUpdater.java | 2 +- .../git4idea/update/GitStashChangesSaver.java | 3 ++- .../src/git4idea/update/GitUpdateProcess.java | 4 ++-- .../zmlx/hg4idea/test/HgMockVcsHelper.java | 6 +++++ 11 files changed, 70 insertions(+), 20 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java index 947747b150ed..5cb11bac7de5 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java @@ -93,15 +93,26 @@ public abstract class AbstractVcsHelper { int maxCount, final String title); - @NotNull - public abstract List showMergeDialog(List 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 showMergeDialog(List files, MergeProvider provider, @Nullable String description); + + /** + * {@link #showMergeDialog(java.util.List, com.intellij.openapi.vcs.merge.MergeProvider)} without description. + */ + @NotNull + public abstract List showMergeDialog(List 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 showMergeDialog(List files); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java index c8eef7b16c22..f46c662b9b15 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java @@ -631,10 +631,17 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper { } } + @Override @NotNull public List showMergeDialog(List files, MergeProvider provider) { + return showMergeDialog(files, provider, null); + } + + @Override + @NotNull + public List showMergeDialog(List 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(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.form b/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.form index 42a22f7790fb..38e9bfe42b08 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.form +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.form @@ -1,6 +1,6 @@
- + @@ -11,7 +11,7 @@ - + @@ -47,9 +47,9 @@ - + - + @@ -60,6 +60,22 @@ + + + + + + + + + + + + + + + + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java index 3add8dd4eb3c..cef84e705703 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java @@ -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 myTable; + private JBLabel myDescriptionLabel; private final MergeProvider myProvider; private final MergeSession myMergeSession; private final List myFiles; @@ -105,7 +107,7 @@ public class MultipleFileMergeDialog extends DialogWrapper { } }; - public MultipleFileMergeDialog(Project project, final List files, final MergeProvider provider) { + public MultipleFileMergeDialog(Project project, final List 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(files); myProvider = provider; + if (!StringUtil.isEmptyOrSpaces(description)) { + myDescriptionLabel.setText(description); + } + List columns = new ArrayList(); Collections.addAll(columns, NAME_COLUMN, TYPE_COLUMN); if (myProvider instanceof MergeProvider2) { diff --git a/plugins/git4idea/src/git4idea/merge/GitMergeConflictResolver.java b/plugins/git4idea/src/git4idea/merge/GitMergeConflictResolver.java index 2e170eb6603e..5bc4c9421fb6 100644 --- a/plugins/git4idea/src/git4idea/merge/GitMergeConflictResolver.java +++ b/plugins/git4idea/src/git4idea/merge/GitMergeConflictResolver.java @@ -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 finalUnmergedFiles = unmergedFiles; UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { final MergeProvider mergeProvider = myReverseMerge ? myVcs.getReverseMergeProvider() : myVcs.getMergeProvider(); - myVcsHelper.showMergeDialog(new ArrayList(finalUnmergedFiles), mergeProvider); + myVcsHelper.showMergeDialog(new ArrayList(finalUnmergedFiles), mergeProvider, myMergeDialogTitle); } }); diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java index c377cee0820f..2014895e7f04 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java @@ -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 continue rebase.
You also may abort rebase 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 continue rebase.
You also may abort rebase to restore the original branch and stop rebasing.") { @Override protected boolean proceedIfNothingToMerge() { return continueRebase(root, "--continue"); } diff --git a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java index 14b30cf0490d..4488d49414a0 100644 --- a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java @@ -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; diff --git a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java index a45ce0f7667e..826a3aebe2a6 100644 --- a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java @@ -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 continue rebase.
You also may abort rebase 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 continue rebase.
You also may abort rebase to restore the original branch and stop rebasing.") { @Override protected boolean proceedIfNothingToMerge() throws VcsException { return myRebaser.continueRebase(myRoot); } diff --git a/plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java b/plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java index 9474225bfee5..f05c76b7c01a 100644 --- a/plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java +++ b/plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java @@ -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", "
" + GitUIUtil.stringifyErrors(handler.errors())); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index cdcfcf330f3e..c7fe916571a7 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -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 continue rebase.
You also may abort rebase to restore the original branch and stop rebasing.") { @Override protected boolean proceedIfNothingToMerge() { return rebaser.continueRebase(rebasingRoots); diff --git a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java index fff46294849d..ede5ec819023 100644 --- a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java +++ b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java @@ -109,6 +109,12 @@ public class HgMockVcsHelper extends AbstractVcsHelper { String title) { } + @NotNull + @Override + public List showMergeDialog(List files, MergeProvider provider, @Nullable String description) { + return null; + } + @NotNull @Override public List showMergeDialog(List files, MergeProvider provider) {