lighter progress indicator, moved to core

This commit is contained in:
Alexey Kudravtsev
2013-05-31 16:32:02 +04:00
parent 2039075ee0
commit 3beaf7fc91
6 changed files with 313 additions and 177 deletions
@@ -0,0 +1,232 @@
/*
* Copyright 2000-2013 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.progress.util;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.impl.ModalityStateEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.containers.DoubleArrayList;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class AbstractProgressIndicatorBase extends UserDataHolderBase implements ProgressIndicator {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressIndicatorBase");
private volatile String myText;
private volatile double myFraction;
private volatile String myText2;
private volatile boolean myCanceled;
private volatile boolean myRunning;
private volatile boolean myIndeterminate;
protected Stack<String> myTextStack;
protected DoubleArrayList myFractionStack;
protected Stack<String> myText2Stack;
protected volatile int myNonCancelableCount;
protected ProgressIndicator myModalityProgress;
private volatile ModalityState myModalityState = ModalityState.NON_MODAL;
@Override
public synchronized void start() {
LOG.assertTrue(!isRunning(), "Attempt to start ProgressIndicator which is already running");
myText = "";
myFraction = 0;
myText2 = "";
myCanceled = false;
myRunning = true;
}
@Override
public void stop() {
LOG.assertTrue(myRunning, "stop() should be called only if start() called before");
myRunning = false;
}
@Override
public boolean isRunning() {
return myRunning;
}
@Override
public void cancel() {
myCanceled = true;
}
@Override
public boolean isCanceled() {
return myCanceled;
}
@Override
public void checkCanceled() {
if (isCanceled() && isCancelable()) {
throw new ProcessCanceledException();
}
}
@Override
public void setText(final String text) {
myText = text;
}
@Override
public String getText() {
return myText;
}
@Override
public void setText2(final String text) {
myText2 = text;
}
@Override
public String getText2() {
return myText2;
}
@Override
public double getFraction() {
return myFraction;
}
@Override
public void setFraction(final double fraction) {
myFraction = fraction;
}
@Override
public synchronized void pushState() {
if (myTextStack == null) myTextStack = new Stack<String>(2);
myTextStack.push(myText);
if (myFractionStack == null) myFractionStack = new DoubleArrayList(2);
myFractionStack.add(myFraction);
if (myText2Stack == null) myText2Stack = new Stack<String>(2);
myText2Stack.push(myText2);
}
@Override
public synchronized void popState() {
LOG.assertTrue(!myTextStack.isEmpty());
String oldText = myTextStack.pop();
double oldFraction = myFractionStack.remove(myFractionStack.size() - 1);
String oldText2 = myText2Stack.pop();
setText(oldText);
setFraction(oldFraction);
setText2(oldText2);
}
@Override
public void startNonCancelableSection() {
myNonCancelableCount++;
}
@Override
public void finishNonCancelableSection() {
myNonCancelableCount--;
}
protected boolean isCancelable() {
return myNonCancelableCount == 0;
}
@Override
public final boolean isModal() {
return myModalityProgress != null;
}
@Override
@NotNull
public final ModalityState getModalityState() {
return myModalityState;
}
@Override
public void setModalityProgress(ProgressIndicator modalityProgress) {
LOG.assertTrue(!isRunning());
myModalityProgress = modalityProgress;
ModalityState currentModality = ApplicationManager.getApplication().getCurrentModalityState();
myModalityState = myModalityProgress != null ? ((ModalityStateEx)currentModality).appendProgress(myModalityProgress) : currentModality;
}
@Override
public boolean isIndeterminate() {
return myIndeterminate;
}
@Override
public void setIndeterminate(final boolean indeterminate) {
myIndeterminate = indeterminate;
}
@NonNls
@Override
public String toString() {
return "ProgressIndicator " + System.identityHashCode(this) + ": running="+isRunning()+"; canceled="+isCanceled();
}
@Override
public boolean isPopupWasShown() {
return true;
}
@Override
public boolean isShowing() {
return isModal();
}
public synchronized void initStateFrom(@NotNull final ProgressIndicator indicator) {
myRunning = indicator.isRunning();
myCanceled = indicator.isCanceled();
myFraction = indicator.getFraction();
myIndeterminate = indicator.isIndeterminate();
myText = indicator.getText();
myText2 = indicator.getText2();
myFraction = indicator.getFraction();
}
@NotNull
public Stack<String> getTextStack() {
if (myTextStack == null) myTextStack = new Stack<String>(2);
return myTextStack;
}
@NotNull
public DoubleArrayList getFractionStack() {
if (myFractionStack == null) myFractionStack = new DoubleArrayList(2);
return myFractionStack;
}
@NotNull
public Stack<String> getText2Stack() {
if (myText2Stack == null) myText2Stack = new Stack<String>(2);
return myText2Stack;
}
public int getNonCancelableCount() {
return myNonCancelableCount;
}
}
@@ -0,0 +1,49 @@
/*
* Copyright 2000-2013 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.progress.util;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
public class FindUsagesIndicator extends AbstractProgressIndicatorBase {
public boolean switchTooManyUsagesStatus() {
return tooManyUsagesStatus.get() == TooManyUsagesStatus.FEW_USAGES &&
tooManyUsagesStatus.compareAndSet(TooManyUsagesStatus.FEW_USAGES, TooManyUsagesStatus.WARNING_DIALOG_SHOWN);
}
public void userResponded() {
waitWhileUserClick.countDown();
tooManyUsagesStatus.set(TooManyUsagesStatus.USER_RESPONDED);
}
public enum TooManyUsagesStatus {
FEW_USAGES, WARNING_DIALOG_SHOWN, USER_RESPONDED
}
private final AtomicReference<TooManyUsagesStatus> tooManyUsagesStatus = new AtomicReference<TooManyUsagesStatus>(TooManyUsagesStatus.FEW_USAGES);
private final CountDownLatch waitWhileUserClick = new CountDownLatch(1);
public void pauseProcessingIfTooManyUsages() {
if (tooManyUsagesStatus.get() == TooManyUsagesStatus.WARNING_DIALOG_SHOWN) {
try {
waitWhileUserClick.await(1, TimeUnit.SECONDS);
}
catch (InterruptedException ignored) {
}
}
}
}
@@ -26,7 +26,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ProgressWrapper extends ProgressIndicatorBase {
public class ProgressWrapper extends AbstractProgressIndicatorBase {
private final ProgressIndicator myOriginal;
private ProgressWrapper(@NotNull ProgressIndicator original) {
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.daemon.impl;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase;
import com.intellij.openapi.util.TraceableDisposable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
@@ -24,7 +24,7 @@ import org.jetbrains.annotations.TestOnly;
/**
* @author cdr
*/
public class DaemonProgressIndicator extends ProgressIndicatorBase {
public class DaemonProgressIndicator extends AbstractProgressIndicatorBase {
private static boolean debug;
private final TraceableDisposable myTraceableDisposable = new TraceableDisposable(debug ? new Throwable() : null);
@@ -58,7 +58,6 @@ public class DaemonProgressIndicator extends ProgressIndicatorBase {
public void start() {
assert !isCanceled() : "canceled";
assert !isRunning() : "running";
assert !wasStarted() : "was started";
super.start();
}
@@ -32,7 +32,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -128,7 +127,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
private void doQueue(Project project, Document document, Object reason) {
synchronized (documentsToCommit) {
ProgressIndicatorEx indicator = new DaemonProgressIndicator();
ProgressIndicator indicator = new DaemonProgressIndicator();
CommitTask newTask = new CommitTask(document, project, indicator, reason);
markRemovedFromDocsToCommit(newTask);
@@ -273,7 +272,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
log("Abandon and proceed to next",task, false);
return;
}
if (task.removed) {
return; // document has been marked as removed, e.g. by synchronous commit
}
@@ -15,46 +15,23 @@
*/
package com.intellij.openapi.progress.util;
import com.intellij.openapi.application.ApplicationManager;
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.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.TaskInfo;
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.DoubleArrayList;
import com.intellij.util.containers.Stack;
import com.intellij.util.containers.WeakList;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class ProgressIndicatorBase extends UserDataHolderBase implements ProgressIndicatorEx {
public class ProgressIndicatorBase extends AbstractProgressIndicatorBase implements ProgressIndicatorEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressIndicatorBase");
private volatile String myText;
private volatile double myFraction;
private volatile String myText2;
private volatile boolean myCanceled;
private volatile boolean myRunning;
private volatile boolean myIndeterminate;
private Stack<String> myTextStack;
private DoubleArrayList myFractionStack;
private Stack<String> myText2Stack;
private volatile int myNonCancelableCount;
private ProgressIndicator myModalityProgress;
private volatile ModalityState myModalityState = ModalityState.NON_MODAL;
private volatile boolean myModalityEntered;
private volatile List<ProgressIndicatorEx> myStateDelegates;
@@ -114,16 +91,10 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
@Override
public void start() {
synchronized (this) {
LOG.assertTrue(!isRunning(), "Attempt to start ProgressIndicator which is already running");
myText = "";
myFraction = 0;
myText2 = "";
myCanceled = false;
myRunning = true;
myWasStarted = true;
super.start();
delegateRunningChange(START_ACTION);
}
myWasStarted = true;
enterModality();
}
@@ -148,9 +119,7 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
@Override
public void stop() {
LOG.assertTrue(myRunning, "stop() should be called only if start() called before");
myRunning = false;
super.stop();
delegateRunningChange(STOP_ACTION);
exitModality();
}
@@ -173,14 +142,10 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
}
}
@Override
public boolean isRunning() {
return myRunning;
}
@Override
public void cancel() {
myCanceled = true;
super.cancel();
ProgressManagerImpl.canceled();
@@ -226,23 +191,16 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
}
}
@Override
public boolean isCanceled() {
return myCanceled;
}
@Override
public final void checkCanceled() {
if (isCanceled() && isCancelable()) {
throw new ProcessCanceledException();
}
super.checkCanceled();
delegate(CHECK_CANCELED_ACTION);
}
@Override
public void setText(final String text) {
myText = text;
super.setText(text);
delegateProgressChange(new IndicatorAction() {
@Override
@@ -252,14 +210,10 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
});
}
@Override
public String getText() {
return myText;
}
@Override
public void setText2(final String text) {
myText2 = text;
super.setText2(text);
delegateProgressChange(new IndicatorAction() {
@Override
@@ -269,19 +223,11 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
});
}
@Override
public String getText2() {
return myText2;
}
@Override
public double getFraction() {
return myFraction;
}
@Override
public void setFraction(final double fraction) {
myFraction = fraction;
super.setFraction(fraction);
delegateProgressChange(new IndicatorAction() {
@Override
@@ -293,75 +239,35 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
@Override
public synchronized void pushState() {
if (myTextStack == null) myTextStack = new Stack<String>(2);
myTextStack.push(myText);
if (myFractionStack == null) myFractionStack = new DoubleArrayList(2);
myFractionStack.add(myFraction);
if (myText2Stack == null) myText2Stack = new Stack<String>(2);
myText2Stack.push(myText2);
super.pushState();
delegateProgressChange(PUSH_ACTION);
}
@Override
public synchronized void popState() {
LOG.assertTrue(!myTextStack.isEmpty());
String oldText = myTextStack.pop();
double oldFraction = myFractionStack.remove(myFractionStack.size() - 1);
String oldText2 = myText2Stack.pop();
setText(oldText);
setFraction(oldFraction);
setText2(oldText2);
super.popState();
delegateProgressChange(POP_ACTION);
}
@Override
public void startNonCancelableSection() {
myNonCancelableCount++;
super.startNonCancelableSection();
delegateProgressChange(STARTNC_ACTION);
}
@Override
public void finishNonCancelableSection() {
myNonCancelableCount--;
super.finishNonCancelableSection();
delegateProgressChange(FINISHNC_ACTION);
}
protected boolean isCancelable() {
return myNonCancelableCount == 0;
}
@Override
public final boolean isModal() {
return myModalityProgress != null;
}
@Override
@NotNull
public final ModalityState getModalityState() {
return myModalityState;
}
@Override
public void setModalityProgress(ProgressIndicator modalityProgress) {
LOG.assertTrue(!isRunning());
myModalityProgress = modalityProgress;
ModalityState currentModality = ApplicationManager.getApplication().getCurrentModalityState();
myModalityState = myModalityProgress != null ? ((ModalityStateEx)currentModality).appendProgress(myModalityProgress) : currentModality;
}
@Override
public boolean isIndeterminate() {
return myIndeterminate;
}
@Override
public void setIndeterminate(final boolean indeterminate) {
myIndeterminate = indeterminate;
super.setIndeterminate(indeterminate);
delegateProgressChange(new IndicatorAction() {
@Override
@@ -418,75 +324,26 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
}
@Override
@NotNull
public Stack<String> getTextStack() {
if (myTextStack == null) myTextStack = new Stack<String>(2);
return myTextStack;
}
@Override
@NotNull
public DoubleArrayList getFractionStack() {
if (myFractionStack == null) myFractionStack = new DoubleArrayList(2);
return myFractionStack;
}
@Override
@NotNull
public Stack<String> getText2Stack() {
if (myText2Stack == null) myText2Stack = new Stack<String>(2);
return myText2Stack;
}
@Override
public int getNonCancelableCount() {
return myNonCancelableCount;
}
@Override
public boolean isModalityEntered() {
return myModalityEntered;
}
@Override
public synchronized void initStateFrom(@NotNull final ProgressIndicatorEx indicator) {
super.initStateFrom(indicator);
myModalityEntered = indicator.isModalityEntered();
myNonCancelableCount = indicator.getNonCancelableCount();
myTextStack = new Stack<String>(indicator.getTextStack());
myText2Stack = new Stack<String>(indicator.getText2Stack());
myFractionStack = new DoubleArrayList(indicator.getFractionStack());
}
@Override
public boolean wasStarted() {
return myWasStarted;
}
@Override
public synchronized void initStateFrom(@NotNull final ProgressIndicatorEx indicator) {
myRunning = indicator.isRunning();
myCanceled = indicator.isCanceled();
myModalityEntered = indicator.isModalityEntered();
myFraction = indicator.getFraction();
myIndeterminate = indicator.isIndeterminate();
myNonCancelableCount = indicator.getNonCancelableCount();
myTextStack = new Stack<String>(indicator.getTextStack());
myText = indicator.getText();
myText2Stack = new Stack<String>(indicator.getText2Stack());
myText2 = indicator.getText2();
myFractionStack = new DoubleArrayList(indicator.getFractionStack());
myFraction = indicator.getFraction();
}
@NonNls
@Override
public String toString() {
return "ProgressIndicator " + System.identityHashCode(this) + ": running="+isRunning()+"; canceled="+isCanceled();
}
@Override
public boolean isPopupWasShown() {
return true;
}
@Override
public boolean isShowing() {
return isModal();
}
}