stub for ordered scopes problem
[idea/community.git] / platform / core-api / src / com / intellij / openapi / progress / ProgressManager.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.progress;
17
18 import com.intellij.openapi.components.ServiceManager;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.util.Computable;
21 import com.intellij.openapi.util.ThrowableComputable;
22 import org.jetbrains.annotations.Nls;
23 import org.jetbrains.annotations.NotNull;
24 import org.jetbrains.annotations.Nullable;
25
26 import javax.swing.*;
27
28 public abstract class ProgressManager {
29   static {
30     ProgressIndicatorProvider.ourInstance = new ProgressIndicatorProvider() {
31       @Override
32       public ProgressIndicator getProgressIndicator() {
33         ProgressManager manager = ProgressManager.getInstance();
34         return manager != null ? manager.getProgressIndicator() : null;
35       }
36
37       @Override
38       protected void doCheckCanceled() throws ProcessCanceledException {
39         ProgressManager manager = ProgressManager.getInstance();
40         if (manager != null) {
41           manager.doCheckCanceled();
42         }
43       }
44
45       @Override
46       public NonCancelableSection startNonCancelableSection() {
47         ProgressManager manager = ProgressManager.getInstance();
48         return manager != null ? manager.startNonCancelableSection() : NonCancelableSection.EMPTY;
49       }
50     };
51   }
52
53   private static ProgressManager ourInstance;
54
55   public static ProgressManager getInstance() {
56     if (ourInstance == null) {
57       ourInstance = ServiceManager.getService(ProgressManager.class);
58     }
59     return ourInstance;
60   }
61
62   public abstract boolean hasProgressIndicator();
63   public abstract boolean hasModalProgressIndicator();
64   public abstract boolean hasUnsafeProgressIndicator();
65
66   public abstract void runProcess(@NotNull Runnable process, ProgressIndicator progress) throws ProcessCanceledException;
67   public abstract <T> T runProcess(@NotNull Computable<T> process, ProgressIndicator progress) throws ProcessCanceledException;
68
69   public ProgressIndicator getProgressIndicator() {
70     return myThreadIndicator.get();
71   }
72
73   protected static volatile boolean ourNeedToCheckCancel = false;
74   public static void checkCanceled() throws ProcessCanceledException {
75     // smart optimization! There's a thread started in ProgressManagerImpl, that set's this flag up once in 10 milliseconds
76     if (ourNeedToCheckCancel) {
77       getInstance().doCheckCanceled();
78       ourNeedToCheckCancel = false;
79     }
80   }
81
82   public static void progress(final String text) throws ProcessCanceledException {
83     progress(text, "");
84   }
85
86   public static void progress2(@NotNull final String text) throws ProcessCanceledException {
87     final ProgressIndicator pi = getInstance().getProgressIndicator();
88     if (pi != null) {
89       pi.checkCanceled();
90       pi.setText2(text);
91     }
92   }
93
94   public static void progress(final String text, @Nullable String text2) throws ProcessCanceledException {
95     final ProgressIndicator pi = getInstance().getProgressIndicator();
96     if (pi != null) {
97       pi.checkCanceled();
98       pi.setText(text);
99       pi.setText2(text2 == null ? "" : text2);
100     }
101   }
102
103   protected abstract void doCheckCanceled() throws ProcessCanceledException;
104
105   public abstract void executeNonCancelableSection(@NotNull Runnable runnable);
106   public abstract NonCancelableSection startNonCancelableSection();
107
108   public abstract void setCancelButtonText(String cancelButtonText);
109
110
111   /**
112    * Runs the specified operation in a background thread and shows a modal progress dialog in the
113    * main thread while the operation is executing.
114    *
115    * @param process       the operation to execute.
116    * @param progressTitle the title of the progress window.
117    * @param canBeCanceled whether "Cancel" button is shown on the progress window.
118    * @param project       the project in the context of which the operation is executed.
119    * @return true if the operation completed successfully, false if it was cancelled.
120    */
121   public abstract boolean runProcessWithProgressSynchronously(@NotNull Runnable process,
122                                                               @NotNull @Nls String progressTitle,
123                                                               boolean canBeCanceled,
124                                                               @Nullable Project project);
125
126   /**
127    * Runs the specified operation in a background thread and shows a modal progress dialog in the
128    * main thread while the operation is executing.
129    *
130    * @param process       the operation to execute.
131    * @param progressTitle the title of the progress window.
132    * @param canBeCanceled whether "Cancel" button is shown on the progress window.
133    * @param project       the project in the context of which the operation is executed.
134    * @return true result of operation
135    * @throws E exception thrown by process
136    */
137   public abstract <T, E extends Exception> T runProcessWithProgressSynchronously(@NotNull ThrowableComputable<T, E> process,
138                                                               @NotNull @Nls String progressTitle,
139                                                               boolean canBeCanceled,
140                                                               @Nullable Project project) throws E;
141
142   /**
143    * Runs the specified operation in a background thread and shows a modal progress dialog in the
144    * main thread while the operation is executing.
145    *
146    * @param process         the operation to execute.
147    * @param progressTitle   the title of the progress window.
148    * @param canBeCanceled   whether "Cancel" button is shown on the progress window.
149    * @param project         the project in the context of which the operation is executed.
150    * @param parentComponent the component which will be used to calculate the progress window ancestor
151    * @return true if the operation completed successfully, false if it was cancelled.
152    */
153   public abstract boolean runProcessWithProgressSynchronously(@NotNull Runnable process,
154                                                               @NotNull @Nls String progressTitle,
155                                                               boolean canBeCanceled,
156                                                               @Nullable Project project,
157                                                               @Nullable JComponent parentComponent);
158
159   /**
160    * Runs a specified <code>process</code> in a background thread and shows a progress dialog, which can be made non-modal by pressing
161    * background button. Upon successful termination of the process a <code>successRunnable</code> will be called in Swing UI thread and
162    * <code>canceledRunnable</code> will be called if terminated on behalf of the user by pressing either cancel button, while running in
163    * a modal state or stop button if running in background.
164    *
165    * @param project          the project in the context of which the operation is executed.
166    * @param progressTitle    the title of the progress window.
167    * @param process          the operation to execute.
168    * @param successRunnable  a callback to be called in Swing UI thread upon normal termination of the process.
169    * @param canceledRunnable a callback to be called in Swing UI thread if the process have been canceled by the user.
170    * @deprecated use {@link #run(com.intellij.openapi.progress.Task)}
171    */
172   public abstract void runProcessWithProgressAsynchronously(@NotNull Project project,
173                                                             @NotNull @Nls String progressTitle,
174                                                             @NotNull Runnable process,
175                                                             @Nullable Runnable successRunnable,
176                                                             @Nullable Runnable canceledRunnable);
177   /**
178    * Runs a specified <code>process</code> in a background thread and shows a progress dialog, which can be made non-modal by pressing
179    * background button. Upon successful termination of the process a <code>successRunnable</code> will be called in Swing UI thread and
180    * <code>canceledRunnable</code> will be called if terminated on behalf of the user by pressing either cancel button, while running in
181    * a modal state or stop button if running in background.
182    *
183    * @param project          the project in the context of which the operation is executed.
184    * @param progressTitle    the title of the progress window.
185    * @param process          the operation to execute.
186    * @param successRunnable  a callback to be called in Swing UI thread upon normal termination of the process.
187    * @param canceledRunnable a callback to be called in Swing UI thread if the process have been canceled by the user.
188    * @param option           progress indicator behavior controller.
189    * @deprecated use {@link #run(com.intellij.openapi.progress.Task)}
190    */
191   public abstract void runProcessWithProgressAsynchronously(@NotNull Project project,
192                                                             @NotNull @Nls String progressTitle,
193                                                             @NotNull Runnable process,
194                                                             @Nullable Runnable successRunnable,
195                                                             @Nullable Runnable canceledRunnable,
196                                                             @NotNull PerformInBackgroundOption option);
197
198   /**
199    * Runs a specified <code>task</code> in either background/foreground thread and shows a progress dialog.
200    *
201    * @param task task to run (either {@link com.intellij.openapi.progress.Task.Modal}
202    *             or {@link com.intellij.openapi.progress.Task.Backgroundable}).
203    */
204   public abstract void run(@NotNull Task task);
205
206   public abstract void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task, @NotNull ProgressIndicator progressIndicator);
207
208   protected static final ThreadLocal<ProgressIndicator> myThreadIndicator = new ThreadLocal<ProgressIndicator>();
209   public void executeProcessUnderProgress(@NotNull Runnable process, ProgressIndicator progress) throws ProcessCanceledException {
210     ProgressIndicator oldIndicator = null;
211
212     boolean set = progress != null && progress != (oldIndicator = myThreadIndicator.get());
213     if (set) {
214       myThreadIndicator.set(progress);
215     }
216
217     try {
218       process.run();
219     }
220     finally {
221       if (set) {
222         myThreadIndicator.set(oldIndicator);
223       }
224     }
225   }
226 }