MergeDialogCustomizer to customize titles and messages in the MultipleFileMergeDialog.

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.
This commit is contained in:
Kirill Likhodedov
2011-03-20 13:25:18 +03:00
parent e8adc64f09
commit 7c6249e890
7 changed files with 136 additions and 25 deletions
@@ -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.
@@ -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");
}
}
}
@@ -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();
}
@@ -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);
@@ -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;
}
}
}
@@ -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";
}
}
}
@@ -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;
}