diff --git a/platform/diff-api/src/com/intellij/diff/merge/MergeRequest.java b/platform/diff-api/src/com/intellij/diff/merge/MergeRequest.java index ce35a98dd8c2..792b0c8a0762 100644 --- a/platform/diff-api/src/com/intellij/diff/merge/MergeRequest.java +++ b/platform/diff-api/src/com/intellij/diff/merge/MergeRequest.java @@ -50,6 +50,10 @@ public abstract class MergeRequest implements UserDataHolder { public void resultRetargeted() { } + @RequiresEdt + public void onAssigned(boolean assigned) { + } + @Nullable @Override public T getUserData(@NotNull Key key) { diff --git a/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java b/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java index 40113120b6ac..eb4a52f399d9 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java @@ -117,6 +117,7 @@ public abstract class MergeRequestProcessor implements Disposable { setTitle(request.getTitle()); myRequest = request; + onAssigned(myRequest, true); myViewer = createViewerFor(request); initViewer(); installCallbackListener(myRequest); @@ -135,6 +136,7 @@ public abstract class MergeRequestProcessor implements Disposable { () -> { if (myDisposed) return; myRequest = mergeRequest; + onAssigned(myRequest, true); swapViewer(createViewerFor(mergeRequest)); installCallbackListener(myRequest); }, @@ -323,6 +325,10 @@ public abstract class MergeRequestProcessor implements Disposable { destroyViewer(); applyRequestResult(MergeResult.CANCEL); + + if (myRequest != null) { + onAssigned(myRequest, false); + } }); } @@ -372,6 +378,15 @@ public abstract class MergeRequestProcessor implements Disposable { }); } + private static void onAssigned(@NotNull MergeRequest request, boolean isAssigned) { + try { + request.onAssigned(isAssigned); + } + catch (Exception e) { + LOG.error(e); + } + } + // // Abstract // diff --git a/platform/diff-impl/src/com/intellij/diff/requests/BinaryMergeRequestImpl.java b/platform/diff-impl/src/com/intellij/diff/requests/BinaryMergeRequestImpl.java index 6904766a663e..9f298602265a 100644 --- a/platform/diff-impl/src/com/intellij/diff/requests/BinaryMergeRequestImpl.java +++ b/platform/diff-impl/src/com/intellij/diff/requests/BinaryMergeRequestImpl.java @@ -71,8 +71,6 @@ public class BinaryMergeRequestImpl extends BinaryMergeRequest { myContents = contents; myTitle = title; myTitles = contentTitles; - - onAssigned(true); } @NotNull @@ -107,58 +105,49 @@ public class BinaryMergeRequestImpl extends BinaryMergeRequest { @Override public void applyResult(@NotNull MergeResult result) { - try { - final byte[] applyContent; - switch (result) { - case CANCEL: - applyContent = MergeUtil.shouldRestoreOriginalContentOnCancel(this) ? myOriginalContent : null; - break; - case LEFT: - applyContent = ThreeSide.LEFT.select(myByteContents); - break; - case RIGHT: - applyContent = ThreeSide.RIGHT.select(myByteContents); - break; - case RESOLVED: - applyContent = null; - break; - default: - throw new IllegalArgumentException(result.toString()); - } - - if (applyContent != null) { - try { - VirtualFile file = myFile.getFile(); - if (!file.isValid()) { - throw new IOException(IdeBundle.message("error.file.not.found.message", file.getPresentableUrl())); - } - if (!DiffUtil.makeWritable(myProject, file)) { - throw new IOException(UIBundle.message("file.is.read.only.message.text", file.getPresentableUrl())); - } - - WriteCommandAction.writeCommandAction(null).run(() -> { - file.setBinaryContent(applyContent); - }); - } - catch (IOException e) { - LOG.warn(e); - Messages.showErrorDialog(myProject, e.getMessage(), DiffBundle.message("can.t.finish.merge.resolve")); - } - } - - MergeCallback.getCallback(this).applyResult(result); + final byte[] applyContent; + switch (result) { + case CANCEL: + applyContent = MergeUtil.shouldRestoreOriginalContentOnCancel(this) ? myOriginalContent : null; + break; + case LEFT: + applyContent = ThreeSide.LEFT.select(myByteContents); + break; + case RIGHT: + applyContent = ThreeSide.RIGHT.select(myByteContents); + break; + case RESOLVED: + applyContent = null; + break; + default: + throw new IllegalArgumentException(result.toString()); } - finally { - onAssigned(false); + + if (applyContent != null) { + try { + VirtualFile file = myFile.getFile(); + if (!file.isValid()) { + throw new IOException(IdeBundle.message("error.file.not.found.message", file.getPresentableUrl())); + } + if (!DiffUtil.makeWritable(myProject, file)) { + throw new IOException(UIBundle.message("file.is.read.only.message.text", file.getPresentableUrl())); + } + + WriteCommandAction.writeCommandAction(null).run(() -> { + file.setBinaryContent(applyContent); + }); + } + catch (IOException e) { + LOG.warn(e); + Messages.showErrorDialog(myProject, e.getMessage(), DiffBundle.message("can.t.finish.merge.resolve")); + } } + + MergeCallback.getCallback(this).applyResult(result); } @Override - public void resultRetargeted() { - onAssigned(false); - } - - private void onAssigned(boolean assigned) { + public void onAssigned(boolean assigned) { myFile.onAssigned(assigned); for (DiffContent content : myContents) { content.onAssigned(assigned); diff --git a/platform/diff-impl/src/com/intellij/diff/requests/TextMergeRequestImpl.java b/platform/diff-impl/src/com/intellij/diff/requests/TextMergeRequestImpl.java index 66cc713f2088..fd9567129eb9 100644 --- a/platform/diff-impl/src/com/intellij/diff/requests/TextMergeRequestImpl.java +++ b/platform/diff-impl/src/com/intellij/diff/requests/TextMergeRequestImpl.java @@ -57,8 +57,6 @@ public class TextMergeRequestImpl extends TextMergeRequest { myContents = contents; myTitles = contentTitles; myTitle = title; - - onAssigned(true); } @NotNull @@ -87,44 +85,35 @@ public class TextMergeRequestImpl extends TextMergeRequest { @Override public void applyResult(@NotNull MergeResult result) { - try { - final CharSequence applyContent; - switch (result) { - case CANCEL: - applyContent = MergeUtil.shouldRestoreOriginalContentOnCancel(this) ? myOriginalContent : null; - break; - case LEFT: - CharSequence leftContent = ThreeSide.LEFT.select(getContents()).getDocument().getImmutableCharSequence(); - applyContent = StringUtil.convertLineSeparators(leftContent.toString()); - break; - case RIGHT: - CharSequence rightContent = ThreeSide.RIGHT.select(getContents()).getDocument().getImmutableCharSequence(); - applyContent = StringUtil.convertLineSeparators(rightContent.toString()); - break; - case RESOLVED: - applyContent = null; - break; - default: - throw new IllegalArgumentException(result.toString()); - } - - if (applyContent != null) { - DiffUtil.executeWriteCommand(myOutput.getDocument(), myProject, null, () -> myOutput.getDocument().setText(applyContent)); - } - - MergeCallback.getCallback(this).applyResult(result); + final CharSequence applyContent; + switch (result) { + case CANCEL: + applyContent = MergeUtil.shouldRestoreOriginalContentOnCancel(this) ? myOriginalContent : null; + break; + case LEFT: + CharSequence leftContent = ThreeSide.LEFT.select(getContents()).getDocument().getImmutableCharSequence(); + applyContent = StringUtil.convertLineSeparators(leftContent.toString()); + break; + case RIGHT: + CharSequence rightContent = ThreeSide.RIGHT.select(getContents()).getDocument().getImmutableCharSequence(); + applyContent = StringUtil.convertLineSeparators(rightContent.toString()); + break; + case RESOLVED: + applyContent = null; + break; + default: + throw new IllegalArgumentException(result.toString()); } - finally { - onAssigned(false); + + if (applyContent != null) { + DiffUtil.executeWriteCommand(myOutput.getDocument(), myProject, null, () -> myOutput.getDocument().setText(applyContent)); } + + MergeCallback.getCallback(this).applyResult(result); } @Override - public void resultRetargeted() { - onAssigned(false); - } - - private void onAssigned(boolean assigned) { + public void onAssigned(boolean assigned) { myOutput.onAssigned(assigned); for (DocumentContent content : myContents) { content.onAssigned(assigned); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java b/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java index 40a6aa40925c..29a7ff22ece7 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java @@ -22,13 +22,17 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.util.ArrayUtil; import com.intellij.util.LineSeparator; import com.intellij.util.PathUtil; import com.intellij.util.TimeoutUtil; +import com.intellij.util.concurrency.annotations.RequiresEdt; import com.intellij.util.execution.ParametersListUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -204,16 +208,23 @@ public final class ExternalDiffToolUtil { execute(settings.getDiffExePath(), settings.getDiffParameters(), patterns); } + @RequiresEdt public static void executeMerge(@Nullable Project project, @NotNull ExternalDiffSettings settings, @NotNull ThreesideMergeRequest request, @Nullable JComponent parentComponent) throws IOException, ExecutionException { - boolean success = false; + request.onAssigned(true); try { - success = tryExecuteMerge(project, settings, request, parentComponent); + boolean success = false; + try { + success = tryExecuteMerge(project, settings, request, parentComponent); + } + finally { + request.applyResult(success ? MergeResult.RESOLVED : MergeResult.CANCEL); + } } finally { - request.applyResult(success ? MergeResult.RESOLVED : MergeResult.CANCEL); + request.onAssigned(false); } }