blob: 132dd5b30ee40f875d09c900cd8712bcb6a5464d [file] [log] [blame]
/*
* Copyright 2000-2014 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.progress.ProgressIndicatorProvider;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.containers.ConcurrentHashSet;
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 ProgressIndicatorStacked {
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 myFinished;
private volatile boolean myIndeterminate;
private Stack<String> myTextStack;
private DoubleArrayList myFractionStack;
private Stack<String> myText2Stack;
private 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");
if (myFinished) {
if (myCanceled && !isReuseable()) {
if (ourReportedReuseExceptions.add(getClass())) {
LOG.error("Attempt to start ProgressIndicator which is cancelled and already stopped:" + this + "," + getClass());
}
}
myCanceled = false;
myFinished = false;
}
myText = "";
myFraction = 0;
myText2 = "";
myRunning = true;
}
private static final ConcurrentHashSet<Class> ourReportedReuseExceptions = new ConcurrentHashSet<Class>(2);
protected boolean isReuseable() {
return false;
}
@Override
public synchronized void stop() {
LOG.assertTrue(myRunning, "stop() should be called only if start() called before");
myRunning = false;
myFinished = true;
}
@Override
public boolean isRunning() {
return myRunning;
}
@Override
public void cancel() {
myCanceled = true;
ProgressIndicatorProvider.canceled();
}
@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();
}
@Override
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();
if (indicator instanceof ProgressIndicatorStacked) {
ProgressIndicatorStacked stacked = (ProgressIndicatorStacked)indicator;
myNonCancelableCount = stacked.getNonCancelableCount();
myTextStack = new Stack<String>(stacked.getTextStack());
myText2Stack = new Stack<String>(stacked.getText2Stack());
myFractionStack = new DoubleArrayList(stacked.getFractionStack());
}
}
@Override
@NotNull
public synchronized Stack<String> getTextStack() {
if (myTextStack == null) myTextStack = new Stack<String>(2);
return myTextStack;
}
@Override
@NotNull
public synchronized DoubleArrayList getFractionStack() {
if (myFractionStack == null) myFractionStack = new DoubleArrayList(2);
return myFractionStack;
}
@Override
@NotNull
public synchronized Stack<String> getText2Stack() {
if (myText2Stack == null) myText2Stack = new Stack<String>(2);
return myText2Stack;
}
@Override
public int getNonCancelableCount() {
return myNonCancelableCount;
}
}