diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java index b5964ec64263..428703d6f7e2 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java +++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java @@ -55,8 +55,12 @@ public interface ProgressIndicator { void popState(); + /** use {@link ProgressManager#executeNonCancelableSection(Runnable)} instead */ + @Deprecated void startNonCancelableSection(); + /** use {@link ProgressManager#executeNonCancelableSection(Runnable)} instead */ + @Deprecated void finishNonCancelableSection(); boolean isModal(); diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java index e8ebdf19cfd2..5570c924ff8f 100644 --- a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java +++ b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java @@ -58,7 +58,6 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements private Stack myTextStack; private DoubleArrayList myFractionStack; private Stack myText2Stack; - private volatile int myNonCancelableCount; ProgressIndicator myModalityProgress; private volatile ModalityState myModalityState = ModalityState.NON_MODAL; @@ -102,9 +101,10 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements } void stopSystemActivity() { - if (myMacActivity != null) { - synchronized (myMacActivity) { - MacUtil.matrixHasYou(myMacActivity); + Object macActivity = myMacActivity; + if (macActivity != null) { + synchronized (macActivity) { + MacUtil.matrixHasYou(macActivity); myMacActivity = null; } } @@ -209,16 +209,14 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements @Override public void startNonCancelableSection() { - myNonCancelableCount++; } @Override public void finishNonCancelableSection() { - myNonCancelableCount--; } protected boolean isCancelable() { - return myNonCancelableCount == 0; + return !ProgressManager.getInstance().isInNonCancelableSection(); } @Override @@ -285,8 +283,6 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements if (indicator instanceof ProgressIndicatorStacked) { ProgressIndicatorStacked stacked = (ProgressIndicatorStacked)indicator; - myNonCancelableCount = stacked.getNonCancelableCount(); - myTextStack = new Stack<>(stacked.getTextStack()); myText2Stack = new Stack<>(stacked.getText2Stack()); @@ -319,6 +315,6 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements @Override public int getNonCancelableCount() { - return myNonCancelableCount; + return ProgressManager.getInstance().isInNonCancelableSection() ? 1 : 0; } } diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorStacked.java b/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorStacked.java index 09f21405bba4..37e253a70c2e 100644 --- a/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorStacked.java +++ b/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorStacked.java @@ -16,6 +16,7 @@ package com.intellij.openapi.progress.util; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.util.containers.DoubleArrayList; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; @@ -32,5 +33,7 @@ public interface ProgressIndicatorStacked extends ProgressIndicator { @NotNull Stack getText2Stack(); + /** use {@link ProgressManager#executeNonCancelableSection(Runnable)} instead of manually checking counters*/ + @Deprecated int getNonCancelableCount(); } diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java index 6c8031809500..19e7d997fbf8 100644 --- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java +++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java @@ -20,10 +20,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.progress.EmptyProgressIndicator; -import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.progress.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; @@ -140,79 +137,81 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { throw new IncorrectOperationException("Must not modify PSI inside save listener"); } final PomModelAspect aspect = transaction.getTransactionAspect(); - startTransaction(transaction); + ProgressManager.getInstance().executeNonCancelableSection(()->{ + startTransaction(transaction); - Pair block = getBlockingTransaction(aspect, transaction); - if (block != null) { - block.getSecond().getAccumulatedEvent().beforeNestedTransaction(); - } + Pair block = getBlockingTransaction(aspect, transaction); + if (block != null) { + block.getSecond().getAccumulatedEvent().beforeNestedTransaction(); + } - List throwables = new ArrayList<>(0); - DebugUtil.performPsiModification(null, ()->{ - try{ - Stack> blockedAspects = myBlockedAspects.get(); - blockedAspects.push(Pair.create(aspect, transaction)); - - final PomModelEvent event; + List throwables = new ArrayList<>(0); + DebugUtil.performPsiModification(null, ()->{ try{ - transaction.run(); - event = transaction.getAccumulatedEvent(); - } - catch (ProcessCanceledException e) { - throw e; - } - catch(Exception e){ - throwables.add(e); - return; - } - finally{ - blockedAspects.pop(); - } - if(block != null){ - block.getSecond().getAccumulatedEvent().merge(event); - return; - } + Stack> blockedAspects = myBlockedAspects.get(); + blockedAspects.push(Pair.create(aspect, transaction)); - { // update - final Set changedAspects = event.getChangedAspects(); - final Collection dependants = new LinkedHashSet<>(); - for (final PomModelAspect pomModelAspect : changedAspects) { - dependants.addAll(getAllDependants(pomModelAspect)); + final PomModelEvent event; + try{ + transaction.run(); + event = transaction.getAccumulatedEvent(); } - for (final PomModelAspect modelAspect : dependants) { - if (!changedAspects.contains(modelAspect)) { - modelAspect.update(event); + catch (ProcessCanceledException e) { + throw e; + } + catch(Exception e){ + throwables.add(e); + return; + } + finally{ + blockedAspects.pop(); + } + if(block != null){ + block.getSecond().getAccumulatedEvent().merge(event); + return; + } + + { // update + final Set changedAspects = event.getChangedAspects(); + final Collection dependants = new LinkedHashSet<>(); + for (final PomModelAspect pomModelAspect : changedAspects) { + dependants.addAll(getAllDependants(pomModelAspect)); + } + for (final PomModelAspect modelAspect : dependants) { + if (!changedAspects.contains(modelAspect)) { + modelAspect.update(event); + } } } - } - for (final PomModelListener listener : myListeners) { - final Set changedAspects = event.getChangedAspects(); - for (PomModelAspect modelAspect : changedAspects) { - if (listener.isAspectChangeInteresting(modelAspect)) { - listener.modelChanged(event); - break; + for (final PomModelListener listener : myListeners) { + final Set changedAspects = event.getChangedAspects(); + for (PomModelAspect modelAspect : changedAspects) { + if (listener.isAspectChangeInteresting(modelAspect)) { + listener.modelChanged(event); + break; + } } } } - } - catch (ProcessCanceledException e) { - throw e; - } - catch (Throwable t) { - throwables.add(t); - } - finally { - try { - commitTransaction(transaction); - } catch (ProcessCanceledException e) { throw e; } catch (Throwable t) { throwables.add(t); } - if (!throwables.isEmpty()) CompoundRuntimeException.throwIfNotEmpty(throwables); - } + finally { + try { + commitTransaction(transaction); + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Throwable t) { + throwables.add(t); + } + if (!throwables.isEmpty()) CompoundRuntimeException.throwIfNotEmpty(throwables); + } + }); }); } @@ -261,7 +260,6 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { containingFileByTree.getViewProvider().contentsSynchronized(); } - if (progressIndicator != null) progressIndicator.finishNonCancelableSection(); } private void reparseParallelTrees(PsiFile changedFile, PsiToDocumentSynchronizer synchronizer) { @@ -328,8 +326,6 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { } private void startTransaction(@NotNull PomTransaction transaction) { - final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); - if(progressIndicator != null) progressIndicator.startNonCancelableSection(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiElement changeScope = transaction.getChangeScope(); diff --git a/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java b/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java index 8e7594b5ead0..2d17b4c01602 100644 --- a/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java +++ b/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java @@ -102,12 +102,10 @@ public class DelegatingProgressIndicator implements WrappedProgressIndicator, St @Override public void startNonCancelableSection() { - myIndicator.startNonCancelableSection(); } @Override public void finishNonCancelableSection() { - myIndicator.finishNonCancelableSection(); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java index e1bf083b67f3..0a4698e3b90f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java @@ -140,20 +140,6 @@ public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBa delegateProgressChange(ProgressIndicator::popState); } - @Override - public void startNonCancelableSection() { - super.startNonCancelableSection(); - - delegateProgressChange(ProgressIndicator::startNonCancelableSection); - } - - @Override - public void finishNonCancelableSection() { - super.finishNonCancelableSection(); - - delegateProgressChange(ProgressIndicator::finishNonCancelableSection); - } - @Override protected boolean isReuseable() { return myReusable; diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index 701ea6c3e7e0..185d1aed1d87 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -22,12 +22,16 @@ import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.application.impl.ModalityStateEx; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.TaskInfo; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.ex.ProgressIndicatorEx; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.messages.Topic; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -64,7 +68,7 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro @FunctionalInterface public interface Listener { - void progressWindowCreated(ProgressWindow pw); + void progressWindowCreated(@NotNull ProgressWindow pw); } public static final Topic TOPIC = Topic.create("progress window", Listener.class); @@ -102,15 +106,7 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro Disposer.register(this, myDialog); - addStateDelegate(new AbstractProgressIndicatorExBase() { - @Override - public void cancel() { - super.cancel(); - if (myDialog != null) { - myDialog.cancel(); - } - } - }); + addStateDelegate(new MyDelegate()); ApplicationManager.getApplication().getMessageBus().syncPublisher(TOPIC).progressWindowCreated(this); if (myProject != null) { @@ -237,22 +233,6 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro } } - @Override - public void startNonCancelableSection() { - if (isCancelable()) { - enableCancel(false); - } - super.startNonCancelableSection(); - } - - @Override - public void finishNonCancelableSection() { - super.finishNonCancelableSection(); - if (isCancelable()) { - enableCancel(true); - } - } - @Override public void setIndeterminate(boolean indeterminate) { super.setIndeterminate(indeterminate); @@ -366,7 +346,7 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro return myDialog != null && myDialog.myPopup != null && myDialog.myPopup.isShowing(); } - private void enableCancel(boolean enable) { + private void enableCancelButton(boolean enable) { if (myDialog != null) { myDialog.enableCancelButtonIfNeeded(enable); } @@ -376,4 +356,44 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro public String toString() { return getTitle() + " " + System.identityHashCode(this) + ": running="+isRunning()+"; canceled="+isCanceled(); } + + private class MyDelegate extends AbstractProgressIndicatorBase implements ProgressIndicatorEx { + @Override + public void cancel() { + super.cancel(); + if (myDialog != null) { + myDialog.cancel(); + } + } + + @Override + public void checkCanceled() { + super.checkCanceled(); + // assume checkCanceled() would be called from the correct thread + enableCancelButton(!ProgressManager.getInstance().isInNonCancelableSection()); + } + + @Override + public void addStateDelegate(@NotNull ProgressIndicatorEx delegate) { + throw new IncorrectOperationException(); + } + + @Override + public void finish(@NotNull TaskInfo task) { + } + + @Override + public boolean isFinished(@NotNull TaskInfo task) { + return true; + } + + @Override + public boolean wasStarted() { + return false; + } + + @Override + public void processFinish() { + } + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt index 374f667defea..355940fee984 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt @@ -8,6 +8,7 @@ import com.intellij.openapi.application.ex.ApplicationInfoEx import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.util.BuildNumber import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.io.FileUtil @@ -69,8 +70,8 @@ object UpdateInstaller { var installed = false - try { - indicator.startNonCancelableSection() + + ProgressManager.getInstance().executeNonCancelableSection { for (downloader in readyToInstall) { try { downloader.install() @@ -81,10 +82,6 @@ object UpdateInstaller { } } } - finally { - indicator.finishNonCancelableSection() - } - return installed } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java index bc44afe22786..523be597e3e6 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java @@ -27,10 +27,7 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.diagnostic.DefaultLogger; import com.intellij.openapi.progress.*; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; -import com.intellij.openapi.progress.util.ProgressIndicatorUtils; -import com.intellij.openapi.progress.util.ProgressWrapper; -import com.intellij.openapi.progress.util.ReadTask; +import com.intellij.openapi.progress.util.*; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.testFramework.BombedProgressIndicator; @@ -216,11 +213,11 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { private volatile Throwable exception; public void testProgressManagerCheckCanceledDoesNotDelegateToProgressIndicatorIfThereAreNoCanceledIndicators() { final long warmupEnd = System.currentTimeMillis() + 1000; - final long end = warmupEnd + 10000; checkCanceledCalled = false; final ProgressIndicatorBase myIndicator = new ProgressIndicatorBase(); taskCanceled = taskSucceeded = false; exception = null; + final long end = warmupEnd + 10000; Future future = ((ProgressManagerImpl)ProgressManager.getInstance()).runProcessWithProgressAsynchronously( new Task.Backgroundable(getProject(), "Xxx") { @Override @@ -777,4 +774,39 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { future.get(1, TimeUnit.SECONDS); } } + + public void testDuringProgressManagerExecuteNonCancelableSectionTheIndicatorIsCancelableShouldReturnFalse() { + MyAbstractProgressIndicator progress = new MyAbstractProgressIndicator(); + ProgressManager.getInstance().executeProcessUnderProgress(() -> { + assertTrue(!progress.isCanceled()); + assertTrue(progress.isCancelable()); + try { + ProgressManager.getInstance().executeNonCancelableSection(()->{ + assertFalse(progress.isCancelable()); + progress.cancel(); + assertTrue(progress.isCanceled()); + progress.checkCanceled(); + }); + } + catch (ProcessCanceledException e) { + e.printStackTrace(); + fail("must not throw"); + } + + try { + progress.checkCanceled(); + fail("PCE must have been thrown"); + } + catch (ProcessCanceledException ignored) { + + } + }, progress); + } + + private static class MyAbstractProgressIndicator extends AbstractProgressIndicatorBase { + @Override + public boolean isCancelable() { + return super.isCancelable(); + } + } } diff --git a/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java b/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java index d8ca4ffb527b..66381bbbffe7 100644 --- a/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java +++ b/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java @@ -191,12 +191,10 @@ public class MacUtil { return null; } - public static void matrixHasYou(Object activity) { - if (activity != null) { - ID processInfo = invoke("NSProcessInfo", "processInfo"); - invoke(processInfo, "endActivity:", activity); - cfRelease((ID)activity); - } + public static void matrixHasYou(@NotNull Object activity) { + ID processInfo = invoke("NSProcessInfo", "processInfo"); + invoke(processInfo, "endActivity:", activity); + cfRelease((ID)activity); } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java index 6a59a56a09c5..8705c1036e93 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java @@ -435,11 +435,6 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD } private void rollbackChangesAfterShelve(@NotNull Collection changes) { - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - progressIndicator.startNonCancelableSection(); - } - final String operationName = UIUtil.removeMnemonic(RollbackChangesDialog.operationNameByChanges(myProject, changes)); boolean modalContext = ApplicationManager.getApplication().isDispatchThread() && LaterInvocator.isInModalContext(); new RollbackWorker(myProject, operationName, modalContext). diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RollbackWorker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RollbackWorker.java index bccb9884e222..96d7a5037b83 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RollbackWorker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RollbackWorker.java @@ -77,67 +77,69 @@ public class RollbackWorker { boolean rollbackRangesExcludedFromCommit, @Nullable Runnable afterVcsRefreshInAwt, @Nullable String localHistoryActionName) { - ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(myProject); - Collection affectedChangelists = changeListManager.getAffectedLists(changes); + ProgressManager.getInstance().executeNonCancelableSection(()->{ + ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(myProject); + Collection affectedChangelists = changeListManager.getAffectedLists(changes); - final LocalHistoryAction action = LocalHistory.getInstance().startAction(myOperationName); + final LocalHistoryAction action = LocalHistory.getInstance().startAction(myOperationName); - final Runnable afterRefresh = () -> { - action.finish(); - LocalHistory.getInstance().putSystemLabel(myProject, notNull(localHistoryActionName, myOperationName), -1); + final Runnable afterRefresh = () -> { + action.finish(); + LocalHistory.getInstance().putSystemLabel(myProject, notNull(localHistoryActionName, myOperationName), -1); - InvokeAfterUpdateMode updateMode = myInvokedFromModalContext ? - InvokeAfterUpdateMode.SYNCHRONOUS_CANCELLABLE : - InvokeAfterUpdateMode.SILENT; - changeListManager.invokeAfterUpdate(() -> { - for (LocalChangeList list : affectedChangelists) { - changeListManager.scheduleAutomaticEmptyChangeListDeletion(list); - } - - if (afterVcsRefreshInAwt != null) { - afterVcsRefreshInAwt.run(); - } - }, updateMode, "Refresh changelists after update", ModalityState.current()); - }; - - List otherChanges = revertPartialChanges(changes, rollbackRangesExcludedFromCommit); - if (otherChanges.isEmpty()) { - WaitForProgressToShow.runOrInvokeLaterAboveProgress(afterRefresh, null, myProject); - return; - } - - final Runnable rollbackAction = new MyRollbackRunnable(otherChanges, deleteLocallyAddedFiles, afterRefresh); - - if (ApplicationManager.getApplication().isDispatchThread() && !myInvokedFromModalContext) { - ProgressManager.getInstance().run(new Task.Backgroundable(myProject, myOperationName, true, - new PerformInBackgroundOption() { - @Override - public boolean shouldStartInBackground() { - return VcsConfiguration.getInstance(myProject).PERFORM_ROLLBACK_IN_BACKGROUND; - } - - @Override - public void processSentToBackground() { - VcsConfiguration.getInstance(myProject).PERFORM_ROLLBACK_IN_BACKGROUND = true; - } - }) { - public void run(@NotNull ProgressIndicator indicator) { - rollbackAction.run(); + InvokeAfterUpdateMode updateMode = myInvokedFromModalContext ? + InvokeAfterUpdateMode.SYNCHRONOUS_CANCELLABLE : + InvokeAfterUpdateMode.SILENT; + changeListManager.invokeAfterUpdate(() -> { + for (LocalChangeList list : affectedChangelists) { + changeListManager.scheduleAutomaticEmptyChangeListDeletion(list); } - }); - } - else if (myInvokedFromModalContext) { - ProgressManager.getInstance().run(new Task.Modal(myProject, myOperationName, true) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - rollbackAction.run(); + + if (afterVcsRefreshInAwt != null) { + afterVcsRefreshInAwt.run(); } - }); - } - else { - rollbackAction.run(); - } - changeListManager.showLocalChangesInvalidated(); + }, updateMode, "Refresh changelists after update", ModalityState.current()); + }; + + List otherChanges = revertPartialChanges(changes, rollbackRangesExcludedFromCommit); + if (otherChanges.isEmpty()) { + WaitForProgressToShow.runOrInvokeLaterAboveProgress(afterRefresh, null, myProject); + return; + } + + final Runnable rollbackAction = new MyRollbackRunnable(otherChanges, deleteLocallyAddedFiles, afterRefresh); + + if (ApplicationManager.getApplication().isDispatchThread() && !myInvokedFromModalContext) { + ProgressManager.getInstance().run(new Task.Backgroundable(myProject, myOperationName, true, + new PerformInBackgroundOption() { + @Override + public boolean shouldStartInBackground() { + return VcsConfiguration.getInstance(myProject).PERFORM_ROLLBACK_IN_BACKGROUND; + } + + @Override + public void processSentToBackground() { + VcsConfiguration.getInstance(myProject).PERFORM_ROLLBACK_IN_BACKGROUND = true; + } + }) { + public void run(@NotNull ProgressIndicator indicator) { + rollbackAction.run(); + } + }); + } + else if (myInvokedFromModalContext) { + ProgressManager.getInstance().run(new Task.Modal(myProject, myOperationName, true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + rollbackAction.run(); + } + }); + } + else { + rollbackAction.run(); + } + changeListManager.showLocalChangesInvalidated(); + }); } @NotNull @@ -214,13 +216,14 @@ public class RollbackWorker { } if (myIndicator != null) { - myIndicator.startNonCancelableSection(); myIndicator.setIndeterminate(true); myIndicator.setText2(""); myIndicator.setText(VcsBundle.message("progress.text.synchronizing.files")); } - doRefresh(myProject, changesToRefresh); + ProgressManager.getInstance().executeNonCancelableSection(()->{ + doRefresh(myProject, changesToRefresh); + }); AbstractVcsHelper.getInstance(myProject).showErrors(myExceptions, myOperationName); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java index a865ec901d39..7fea7fd8b512 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java @@ -15,6 +15,7 @@ package org.zmlx.hg4idea.provider.update; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.FilePath; @@ -51,29 +52,27 @@ public class HgUpdateEnvironment implements UpdateEnvironment { List exceptions = new LinkedList<>(); - boolean result = true; + boolean[] result = {true}; for (FilePath contentRoot : contentRoots) { if (indicator != null) { indicator.checkCanceled(); - indicator.startNonCancelableSection(); } VirtualFile repository = ProjectLevelVcsManager.getInstance(project).getVcsRootFor(contentRoot); if (repository == null) { continue; } - try { - HgUpdater updater = new HgRegularUpdater(project, repository, updateConfiguration); - result &= updater.update(updatedFiles, indicator, exceptions); - } catch (VcsException e) { - //TODO include module name where exception occurred - exceptions.add(e); - } - if (indicator != null) { - indicator.finishNonCancelableSection(); - } + ProgressManager.getInstance().executeNonCancelableSection(()->{ + try { + HgUpdater updater = new HgRegularUpdater(project, repository, updateConfiguration); + result[0] &= updater.update(updatedFiles, indicator, exceptions); + } catch (VcsException e) { + //TODO include module name where exception occurred + exceptions.add(e); + } + }); } - return new UpdateSessionAdapter(exceptions, !result); + return new UpdateSessionAdapter(exceptions, !result[0]); } public Configurable createConfigurable(Collection contentRoots) {