package com.intellij.openapi.vcs.changes.patch;
import com.intellij.diff.DiffManager;
-import com.intellij.diff.DiffRequestFactory;
import com.intellij.diff.InvalidDiffRequestException;
import com.intellij.diff.merge.MergeRequest;
import com.intellij.diff.merge.MergeResult;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsApplicationSettings;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.ChangeListManager;
final ApplyPatchForBaseRevisionTexts mergeData = result.getMergeData();
if (mergeData == null) return status;
- if (mergeData.getBase() != null) {
- return showMergeDialog(project, file, mergeData.getBase(), mergeData.getPatched(), reverse, leftPanelTitle, rightPanelTitle);
+ final Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document == null) return ApplyPatchStatus.FAILURE;
+
+ String baseContent = toString(mergeData.getBase());
+ String localContent = toString(mergeData.getLocal());
+ String patchedContent = mergeData.getPatched();
+
+ if (localContent == null) return ApplyPatchStatus.FAILURE;
+
+ final Ref<Boolean> successRef = new Ref<Boolean>();
+ Consumer<MergeResult> callback = new Consumer<MergeResult>() {
+ @Override
+ public void consume(MergeResult result) {
+ FileDocumentManager.getInstance().saveDocument(document);
+ successRef.set(result != MergeResult.CANCEL);
+ }
+ };
+
+ try {
+ MergeRequest request;
+ if (baseContent != null) {
+ if (reverse) {
+ if (leftPanelTitle == null) leftPanelTitle = VcsBundle.message("patch.apply.conflict.patched.version");
+ if (rightPanelTitle == null) rightPanelTitle = VcsBundle.message("patch.apply.conflict.local.version");
+
+ List<String> contents = ContainerUtil.list(patchedContent, baseContent, localContent);
+ List<String> titles = ContainerUtil.list(leftPanelTitle, null, rightPanelTitle);
+
+ request = PatchDiffRequestFactory
+ .createMergeRequest(project, document, file, contents, null, titles, callback);
+ }
+ else {
+ request = PatchDiffRequestFactory
+ .createMergeRequest(project, document, file, baseContent, localContent, patchedContent, callback);
+ }
+ }
+ else {
+ request = PatchDiffRequestFactory.createBadMergeRequest(project, document, file, localContent, patchedContent, callback);
+ }
+
+ DiffManager.getInstance().showMerge(project, request);
+ return successRef.get() == Boolean.TRUE ? ApplyPatchStatus.SUCCESS : ApplyPatchStatus.FAILURE;
}
- else {
- return showBadMergeDialog(project, file, mergeData);
+ catch (InvalidDiffRequestException e) {
+ LOG.warn(e);
+ return ApplyPatchStatus.FAILURE;
}
}
});
}
- @NotNull
- private static ApplyPatchStatus showMergeDialog(@Nullable Project project,
- @NotNull VirtualFile file,
- @Nullable CharSequence content,
- @NotNull final String patchedContent,
- boolean reverse,
- @Nullable String leftPanelTitle,
- @Nullable String rightPanelTitle) {
- Document document = FileDocumentManager.getInstance().getDocument(file);
- if (content == null || document == null) {
- return ApplyPatchStatus.FAILURE;
- }
-
- List<String> titles = ContainerUtil.list(
- leftPanelTitle == null ? VcsBundle.message("patch.apply.conflict.local.version") : leftPanelTitle,
- rightPanelTitle == null ? VcsBundle.message("patch.apply.conflict.merged.version") : rightPanelTitle,
- VcsBundle.message("patch.apply.conflict.patched.version"));
- String windowTitle = VcsBundle.message("patch.apply.conflict.title", file.getPresentableUrl());
-
- final String leftText = document.getText();
- List<String> contents = ContainerUtil.list(reverse ? patchedContent : leftText,
- content.toString(),
- reverse ? leftText : patchedContent);
-
- final Ref<Boolean> successRef = new Ref<Boolean>();
- final Consumer<MergeResult> callback = new Consumer<MergeResult>() {
- @Override
- public void consume(MergeResult result) {
- successRef.set(result != MergeResult.CANCEL);
- }
- };
-
- try {
- MergeRequest request = DiffRequestFactory.getInstance()
- .createMergeRequest(project, file.getFileType(), document, contents, windowTitle, titles, callback);
-
- DiffManager.getInstance().showMerge(project, request);
-
- return successRef.get() == Boolean.TRUE ? ApplyPatchStatus.SUCCESS : ApplyPatchStatus.FAILURE;
- }
- catch (InvalidDiffRequestException e) {
- LOG.warn(e);
- return ApplyPatchStatus.FAILURE;
- }
- }
-
- @NotNull
- private static ApplyPatchStatus showBadMergeDialog(@Nullable Project project,
- @NotNull VirtualFile file,
- @NotNull final ApplyPatchForBaseRevisionTexts texts) {
- final Document document = FileDocumentManager.getInstance().getDocument(file);
- if (texts.getLocal() == null || document == null) return ApplyPatchStatus.FAILURE;
-
- final String fullPath = file.getParent() == null ? file.getPath() : file.getParent().getPath();
- final String windowTitle = "Result Of Patch Apply To " + file.getName() + " (" + fullPath + ")";
-
- final Ref<Boolean> successRef = new Ref<Boolean>();
- Consumer<MergeResult> callback = new Consumer<MergeResult>() {
- @Override
- public void consume(MergeResult result) {
- FileDocumentManager.getInstance().saveDocument(document);
- successRef.set(true);
- }
- };
-
- MergeRequest request = new ApplyPatchMergeRequest(project, document, file, texts.getLocal().toString(), texts.getPatched(), windowTitle,
- VcsBundle.message("diff.title.local"), "Patched (with problems)", callback);
-
- DiffManager.getInstance().showMerge(project, request);
-
- return successRef.get() == Boolean.TRUE ? ApplyPatchStatus.SUCCESS : ApplyPatchStatus.FAILURE;
+ @Nullable
+ private static String toString(@Nullable CharSequence charSequence) {
+ return charSequence != null ? StringUtil.convertLineSeparators(charSequence.toString()) : null;
}
}
package com.intellij.openapi.vcs.changes.patch;
import com.intellij.diff.DiffContentFactory;
+import com.intellij.diff.DiffRequestFactory;
+import com.intellij.diff.InvalidDiffRequestException;
import com.intellij.diff.chains.DiffRequestProducerException;
-import com.intellij.diff.contents.DiffContent;
import com.intellij.diff.contents.DocumentContent;
+import com.intellij.diff.merge.MergeRequest;
+import com.intellij.diff.merge.MergeResult;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.diff.requests.SimpleDiffRequest;
import com.intellij.diff.util.DiffUtil;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.UserDataHolder;
-import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PatchDiffRequestFactory {
@NotNull
- public static DiffRequest createFromChange(@Nullable Project project,
- @NotNull Change change,
- @NotNull String name,
- @NotNull UserDataHolder context,
- @NotNull ProgressIndicator indicator)
+ public static DiffRequest createDiffRequest(@Nullable Project project,
+ @NotNull Change change,
+ @NotNull String name,
+ @NotNull UserDataHolder context,
+ @NotNull ProgressIndicator indicator)
throws DiffRequestProducerException {
ChangeDiffRequestProducer proxyProducer = ChangeDiffRequestProducer.create(project, change);
if (proxyProducer == null) throw new DiffRequestProducerException("Can't show diff for '" + name + "'");
return proxyProducer.process(context, indicator);
}
- public static DiffRequest createConflict(@Nullable Project project,
- @Nullable VirtualFile file,
- @NotNull String afterTitle,
- @NotNull final Getter<ApplyPatchForBaseRevisionTexts> textsGetter,
- @NotNull String name,
- @NotNull UserDataHolder context,
- @NotNull ProgressIndicator indicator)
+ public static DiffRequest createConflictDiffRequest(@Nullable Project project,
+ @Nullable VirtualFile file,
+ @NotNull String afterTitle,
+ @NotNull final Getter<ApplyPatchForBaseRevisionTexts> textsGetter,
+ @NotNull String name,
+ @NotNull UserDataHolder context,
+ @NotNull ProgressIndicator indicator)
throws DiffRequestProducerException {
if (file == null) throw new DiffRequestProducerException("Can't show diff for '" + name + "'");
if (file.getFileType().isBinary()) throw new DiffRequestProducerException("Can't show diff for binary file '" + name + "'");
}, indicator.getModalityState());
ApplyPatchForBaseRevisionTexts texts = textsRef.get();
+ if (texts.getLocal() == null) throw new DiffRequestProducerException("Can't show diff for '" + file.getPresentableUrl() + "'");
+
if (texts.getBase() == null) {
- return createBadDiffRequest(project, file, texts);
+ String localContent = texts.getLocal().toString();
+ String patchedContent = texts.getPatched();
+
+ return createBadDiffRequest(project, file, localContent, patchedContent, null, null, null);
}
else {
- String path = FileUtil.toSystemDependentName(file.getPresentableUrl());
- FileType type = file.getFileType();
-
- String windowTitle = VcsBundle.message("patch.apply.conflict.title", path);
+ String localContent = texts.getLocal().toString();
+ String baseContent = texts.getBase().toString();
+ String patchedContent = texts.getPatched();
- DiffContentFactory contentFactory = DiffContentFactory.getInstance();
- DocumentContent localContent = contentFactory.createDocument(project, file);
- if (localContent == null) localContent = contentFactory.create(texts.getLocal().toString(), type);
- DocumentContent baseContent = contentFactory.create(texts.getBase().toString(), type);
- DocumentContent patchedContent = contentFactory.create(texts.getPatched(), type);
-
- return new SimpleDiffRequest(windowTitle, localContent, baseContent, patchedContent,
- "Current Version", "Base Version", afterTitle);
+ return createDiffRequest(project, file, ContainerUtil.list(localContent, baseContent, patchedContent), null,
+ ContainerUtil.list("Current Version", "Base Version", afterTitle));
}
}
@NotNull
- public static DiffRequest createBadDiffRequest(@Nullable Project project,
- @NotNull final VirtualFile file,
- @NotNull final ApplyPatchForBaseRevisionTexts texts) throws DiffRequestProducerException {
- if (texts.getLocal() == null) {
- throw new DiffRequestProducerException("Can't show diff for '" + file.getPresentableUrl() + "'");
- }
+ public static DiffRequest createDiffRequest(@Nullable Project project,
+ @Nullable VirtualFile file,
+ @NotNull List<String> contents,
+ @Nullable String windowTitle,
+ @NotNull List<String> titles) {
+ assert contents.size() == 3;
+ assert titles.size() == 3;
+
+ if (windowTitle == null) windowTitle = getPatchTitle(file);
+
+ String localTitle = StringUtil.notNullize(titles.get(0), VcsBundle.message("patch.apply.conflict.local.version"));
+ String baseTitle = StringUtil.notNullize(titles.get(1), "Base Version");
+ String patchedTitle = StringUtil.notNullize(titles.get(2), VcsBundle.message("patch.apply.conflict.patched.version"));
+
+ FileType fileType = file != null ? file.getFileType() : null;
+
+ DiffContentFactory contentFactory = DiffContentFactory.getInstance();
+ DocumentContent localContent = file != null ? contentFactory.createDocument(project, file) : null;
+ if (localContent == null) localContent = contentFactory.create(contents.get(0), fileType);
+ DocumentContent baseContent = contentFactory.create(contents.get(1), fileType);
+ DocumentContent patchedContent = contentFactory.create(contents.get(2), fileType);
+
+ return new SimpleDiffRequest(windowTitle, localContent, baseContent, patchedContent,
+ localTitle, baseTitle, patchedTitle);
+ }
- final String fullPath = file.getParent() == null ? file.getPath() : file.getParent().getPath();
- final String windowTitle = "Result Of Patch Apply To " + file.getName() + " (" + fullPath + ")";
- final List<String> titles = ContainerUtil.list(VcsBundle.message("diff.title.local"), "Patched (with problems)");
+ @NotNull
+ public static DiffRequest createBadDiffRequest(@Nullable Project project,
+ @Nullable VirtualFile file,
+ @NotNull String localContent,
+ @NotNull String patchedContent,
+ @Nullable String windowTitle,
+ @Nullable String localTitle,
+ @Nullable String patchedTitle) {
+ if (windowTitle == null) windowTitle = getBadPatchTitle(file);
+ if (localTitle == null) localTitle = VcsBundle.message("patch.apply.conflict.local.version");
+ if (patchedTitle == null) patchedTitle = "Patched (with problems)";
+
+ FileType fileType = file != null ? file.getFileType() : null;
final DiffContentFactory contentFactory = DiffContentFactory.getInstance();
- DocumentContent localContent = contentFactory.createDocument(project, file);
- if (localContent == null) localContent = contentFactory.create(texts.getLocal().toString(), file.getFileType());
- final DiffContent mergedContent = contentFactory.create(texts.getPatched(), file.getFileType());
+ DocumentContent leftContent = file != null ? contentFactory.createDocument(project, file) : null;
+ if (leftContent == null) leftContent = contentFactory.create(localContent, fileType);
+ DocumentContent rightContent = contentFactory.create(patchedContent, fileType);
- final List<DiffContent> contents = ContainerUtil.list(localContent, mergedContent);
-
- final DiffRequest request = new SimpleDiffRequest(windowTitle, contents, titles);
+ final DiffRequest request = new SimpleDiffRequest(windowTitle, leftContent, rightContent, localTitle, patchedTitle);
DiffUtil.addNotification(new ApplyPatchMergeTool.DiffIsApproximateNotification(), request);
return request;
}
+
+ @NotNull
+ public static MergeRequest createMergeRequest(@Nullable Project project,
+ @NotNull Document document,
+ @NotNull VirtualFile file,
+ @NotNull String baseContent,
+ @NotNull String localContent,
+ @NotNull String patchedContent,
+ @Nullable Consumer<MergeResult> callback)
+ throws InvalidDiffRequestException {
+ List<String> titles = ContainerUtil.list(null, null, null);
+ List<String> contents = ContainerUtil.list(localContent, baseContent, patchedContent);
+
+ return createMergeRequest(project, document, file, contents, null, titles, callback);
+ }
+
+ @NotNull
+ public static MergeRequest createBadMergeRequest(@Nullable Project project,
+ @NotNull Document document,
+ @NotNull VirtualFile file,
+ @NotNull String localContent,
+ @NotNull String patchedContent,
+ @Nullable Consumer<MergeResult> callback)
+ throws InvalidDiffRequestException {
+ return createBadMergeRequest(project, document, file, localContent, patchedContent, null, null, null, callback);
+ }
+
+ @NotNull
+ public static MergeRequest createMergeRequest(@Nullable Project project,
+ @NotNull Document document,
+ @Nullable VirtualFile file,
+ @NotNull List<String> contents,
+ @Nullable String windowTitle,
+ @NotNull List<String> titles,
+ @Nullable Consumer<MergeResult> callback)
+ throws InvalidDiffRequestException {
+ assert contents.size() == 3;
+ assert titles.size() == 3;
+
+ if (windowTitle == null) windowTitle = getPatchTitle(file);
+
+ String localTitle = StringUtil.notNullize(titles.get(0), VcsBundle.message("patch.apply.conflict.local.version"));
+ String baseTitle = StringUtil.notNullize(titles.get(1), VcsBundle.message("patch.apply.conflict.merged.version"));
+ String patchedTitle = StringUtil.notNullize(titles.get(2), VcsBundle.message("patch.apply.conflict.patched.version"));
+
+ List<String> actualTitles = ContainerUtil.list(localTitle, baseTitle, patchedTitle);
+
+ FileType fileType = file != null ? file.getFileType() : null;
+ return DiffRequestFactory.getInstance().createMergeRequest(project, fileType, document, contents, windowTitle, actualTitles, callback);
+ }
+
+ @NotNull
+ public static MergeRequest createBadMergeRequest(@Nullable Project project,
+ @NotNull Document document,
+ @Nullable VirtualFile file,
+ @NotNull String localContent,
+ @NotNull String patchedContent,
+ @Nullable String windowTitle,
+ @Nullable String localTitle,
+ @Nullable String patchedTitle,
+ @Nullable Consumer<MergeResult> callback)
+ throws InvalidDiffRequestException {
+ if (!DiffUtil.canMakeWritable(document)) {
+ throw new InvalidDiffRequestException("Output is read only" + (file != null ? " : '" + file.getPresentableUrl() +"'": ""));
+ }
+
+ if (windowTitle == null) windowTitle = getBadPatchTitle(file);
+ if (localTitle == null) localTitle = VcsBundle.message("patch.apply.conflict.local.version");
+ if (patchedTitle == null) patchedTitle = "Patched (with problems)";
+
+ return new ApplyPatchMergeRequest(project, document, localContent, patchedContent, windowTitle, localTitle, patchedTitle, callback);
+ }
+
+ @NotNull
+ private static String getPatchTitle(@Nullable VirtualFile file) {
+ if (file != null) {
+ return VcsBundle.message("patch.apply.conflict.title", getPresentablePath(file));
+ }
+ else {
+ return "Patch Conflict";
+ }
+ }
+
+
+ @NotNull
+ private static String getBadPatchTitle(@Nullable VirtualFile file) {
+ if (file != null) {
+ return "Result Of Patch Apply To " + getPresentablePath(file);
+ }
+ else {
+ return "Result Of Patch Apply";
+ }
+ }
+
+ @NotNull
+ private static String getPresentablePath(@NotNull VirtualFile file) {
+ String fullPath = file.getParent() == null ? file.getPath() : file.getParent().getPath();
+ return file.getName() + " (" + fullPath + ")";
+ }
}