diff --git a/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java b/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java
index 60e026f93b3e..b1d095ac5870 100644
--- a/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java
+++ b/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java
@@ -17,15 +17,18 @@ package com.intellij.util.concurrency;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Getter;
+import com.intellij.openapi.util.Pair;
import com.intellij.util.AsynchConsumer;
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
/**
*
QueueProcessor processes elements which are being added to a queue via {@link #add(Object)} and {@link #addFirst(Object)} methods.
@@ -48,6 +51,7 @@ public class QueueProcessor {
private final ThreadToUse myThreadToUse;
private final Condition> myDeathCondition;
+ private final Map myModalityState;
/**
* Constructs a QueueProcessor with the given processor and autostart setting.
@@ -65,6 +69,7 @@ public class QueueProcessor {
myStarted = autostart;
myThreadToUse = threadToUse;
myDeathCondition = deathCondition;
+ myModalityState = new HashMap();
myContinuationContext = new Runnable() {
@Override
@@ -85,6 +90,11 @@ public class QueueProcessor {
this(wrappingProcessor(processor), autostart, ThreadToUse.POOLED, deathCondition);
}
+ public void add(T t, ModalityState state) {
+ myModalityState.put(new MyOverrideEquals(t), state);
+ doAdd(t, false);
+ }
+
private static PairConsumer wrappingProcessor(final Consumer processor) {
return new PairConsumer() {
@Override
@@ -176,7 +186,12 @@ public class QueueProcessor {
};
final Application application = ApplicationManager.getApplication();
if (ThreadToUse.AWT.equals(myThreadToUse)) {
- application.invokeLater(runnable);
+ final ModalityState state = myModalityState.remove(new MyOverrideEquals(item));
+ if (state != null) {
+ application.invokeLater(runnable, state);
+ } else {
+ application.invokeLater(runnable);
+ }
} else {
application.executeOnPooledThread(runnable);
}
@@ -193,4 +208,22 @@ public class QueueProcessor {
AWT,
POOLED
}
+
+ private static class MyOverrideEquals {
+ private final Object myDelegate;
+
+ private MyOverrideEquals(Object delegate) {
+ myDelegate = delegate;
+ }
+
+ @Override
+ public int hashCode() {
+ return myDelegate.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return ((MyOverrideEquals) obj).myDelegate == myDelegate;
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java
index 0b38bee82dd0..dd2c56c12d81 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java
@@ -17,16 +17,21 @@
package com.intellij.openapi.progress;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Getter;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PairConsumer;
import com.intellij.util.concurrency.QueueProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Map;
+
/**
* Runs backgroundable tasks one by one.
* To add a task to the queue use {@link #run(com.intellij.openapi.progress.Task.Backgroundable)}
@@ -39,7 +44,7 @@ import org.jetbrains.annotations.Nullable;
public class BackgroundTaskQueue {
private static final Logger LOG = Logger.getInstance(BackgroundTaskQueue.class.getName());
//private final Project myProject;
- private final QueueProcessor myProcessor;
+ private final QueueProcessor>> myProcessor;
private Boolean myForcedTestMode;
public BackgroundTaskQueue(@Nullable Project project, @NotNull String title) {
@@ -48,7 +53,7 @@ public class BackgroundTaskQueue {
public BackgroundTaskQueue(@Nullable final Project project, @NotNull String title, final Boolean forcedHeadlessMode) {
final boolean headless = forcedHeadlessMode != null ? forcedHeadlessMode : ApplicationManager.getApplication().isHeadlessEnvironment();
- myProcessor = new QueueProcessor(headless ?
+ myProcessor = new QueueProcessor>>(headless ?
new BackgroundableHeadlessRunner() : new BackgroundableUnderProgressRunner(title, project), true,
headless ? QueueProcessor.ThreadToUse.POOLED : QueueProcessor.ThreadToUse.AWT, new Condition