/* * Copyright 2000-2016 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; import com.intellij.openapi.application.CachedSingletonsRegistry; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.ThrowableComputable; import gnu.trove.THashSet; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Set; public abstract class ProgressManager extends ProgressIndicatorProvider { private static ProgressManager ourInstance = CachedSingletonsRegistry.markCachedField(ProgressManager.class); @NotNull @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") public static ProgressManager getInstance() { ProgressManager result = ourInstance; if (result == null) { ourInstance = result = ServiceManager.getService(ProgressManager.class); } return result; } public abstract boolean hasProgressIndicator(); public abstract boolean hasModalProgressIndicator(); public abstract boolean hasUnsafeProgressIndicator(); /** * Runs given process synchronously (in calling thread). */ public abstract void runProcess(@NotNull Runnable process, ProgressIndicator progress) throws ProcessCanceledException; /** * Runs given process synchronously (in calling thread). */ public abstract <T> T runProcess(@NotNull Computable<T> process, ProgressIndicator progress) throws ProcessCanceledException; @Override public ProgressIndicator getProgressIndicator() { return null; } public static void progress(@NotNull String text) throws ProcessCanceledException { progress(text, ""); } public static void progress2(@NotNull final String text) throws ProcessCanceledException { final ProgressIndicator pi = getInstance().getProgressIndicator(); if (pi != null) { pi.checkCanceled(); pi.setText2(text); } } public static void progress(@NotNull String text, @Nullable String text2) throws ProcessCanceledException { final ProgressIndicator pi = getInstance().getProgressIndicator(); if (pi != null) { pi.checkCanceled(); pi.setText(text); pi.setText2(text2 == null ? "" : text2); } } public abstract void executeNonCancelableSection(@NotNull Runnable runnable); /** * to be removed in 2017.2 */ @Deprecated public abstract void setCancelButtonText(String cancelButtonText); /** * Runs the specified operation in a background thread and shows a modal progress dialog in the * main thread while the operation is executing. * * @param process the operation to execute. * @param progressTitle the title of the progress window. * @param canBeCanceled whether "Cancel" button is shown on the progress window. * @param project the project in the context of which the operation is executed. * @return true if the operation completed successfully, false if it was cancelled. */ public abstract boolean runProcessWithProgressSynchronously(@NotNull Runnable process, @NotNull @Nls(capitalization = Nls.Capitalization.Title) String progressTitle, boolean canBeCanceled, @Nullable Project project); /** * Runs the specified operation in a background thread and shows a modal progress dialog in the * main thread while the operation is executing. * * @param process the operation to execute. * @param progressTitle the title of the progress window. * @param canBeCanceled whether "Cancel" button is shown on the progress window. * @param project the project in the context of which the operation is executed. * @return true result of operation * @throws E exception thrown by process */ public abstract <T, E extends Exception> T runProcessWithProgressSynchronously(@NotNull ThrowableComputable<T, E> process, @NotNull @Nls(capitalization = Nls.Capitalization.Title) String progressTitle, boolean canBeCanceled, @Nullable Project project) throws E; /** * Runs the specified operation in a background thread and shows a modal progress dialog in the * main thread while the operation is executing. * * @param process the operation to execute. * @param progressTitle the title of the progress window. * @param canBeCanceled whether "Cancel" button is shown on the progress window. * @param project the project in the context of which the operation is executed. * @param parentComponent the component which will be used to calculate the progress window ancestor * @return true if the operation completed successfully, false if it was cancelled. */ public abstract boolean runProcessWithProgressSynchronously(@NotNull Runnable process, @NotNull @Nls(capitalization = Nls.Capitalization.Title) String progressTitle, boolean canBeCanceled, @Nullable Project project, @Nullable JComponent parentComponent); /** * Runs a specified {@code process} in a background thread and shows a progress dialog, which can be made non-modal by pressing * background button. Upon successful termination of the process a {@code successRunnable} will be called in Swing UI thread and * {@code canceledRunnable} will be called if terminated on behalf of the user by pressing either cancel button, while running in * a modal state or stop button if running in background. * * @param project the project in the context of which the operation is executed. * @param progressTitle the title of the progress window. * @param process the operation to execute. * @param successRunnable a callback to be called in Swing UI thread upon normal termination of the process. * @param canceledRunnable a callback to be called in Swing UI thread if the process have been canceled by the user. * @deprecated use {@link #run(Task)} */ public abstract void runProcessWithProgressAsynchronously(@NotNull Project project, @NotNull @Nls String progressTitle, @NotNull Runnable process, @Nullable Runnable successRunnable, @Nullable Runnable canceledRunnable); /** * Runs a specified {@code process} in a background thread and shows a progress dialog, which can be made non-modal by pressing * background button. Upon successful termination of the process a {@code successRunnable} will be called in Swing UI thread and * {@code canceledRunnable} will be called if terminated on behalf of the user by pressing either cancel button, while running in * a modal state or stop button if running in background. * * @param project the project in the context of which the operation is executed. * @param progressTitle the title of the progress window. * @param process the operation to execute. * @param successRunnable a callback to be called in Swing UI thread upon normal termination of the process. * @param canceledRunnable a callback to be called in Swing UI thread if the process have been canceled by the user. * @param option progress indicator behavior controller. * @deprecated use {@link #run(Task)} */ public abstract void runProcessWithProgressAsynchronously(@NotNull Project project, @NotNull @Nls String progressTitle, @NotNull Runnable process, @Nullable Runnable successRunnable, @Nullable Runnable canceledRunnable, @NotNull PerformInBackgroundOption option); /** * Runs a specified {@code task} in either background/foreground thread and shows a progress dialog. * * @param task task to run (either {@link Task.Modal} or {@link Task.Backgroundable}). */ public abstract void run(@NotNull Task task); /** * Runs a specified computation with a modal progress dialog. */ public <T, E extends Exception> T run(@NotNull Task.WithResult<T, E> task) throws E { run((Task)task); return task.getResult(); } public abstract void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task, @NotNull ProgressIndicator progressIndicator); protected void indicatorCanceled(@NotNull ProgressIndicator indicator) { } public static void canceled(@NotNull ProgressIndicator indicator) { getInstance().indicatorCanceled(indicator); } @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") public static void checkCanceled() throws ProcessCanceledException { ProgressManager instance = ourInstance; if (instance != null) { instance.doCheckCanceled(); } } /** * @param progress an indicator to use, {@code null} means reuse current progress */ public abstract void executeProcessUnderProgress(@NotNull Runnable process, @Nullable ProgressIndicator progress) throws ProcessCanceledException; public static void assertNotCircular(@NotNull ProgressIndicator original) { Set<ProgressIndicator> wrappedParents = null; for (ProgressIndicator i = original; i instanceof WrappedProgressIndicator; i = ((WrappedProgressIndicator)i).getOriginalProgressIndicator()) { if (wrappedParents == null) wrappedParents = new THashSet<>(); if (!wrappedParents.add(i)) { throw new IllegalArgumentException(i + " wraps itself"); } } } /** * This method attempts to run provided action synchronously in a read action, so that, if possible, it wouldn't impact any pending, * executing or future write actions (for this to work effectively the action should invoke {@link ProgressManager#checkCanceled()} or * {@link ProgressIndicator#checkCanceled()} often enough). * It returns {@code true} if action was executed successfully. It returns {@code false} if the action was not * executed successfully, i.e. if: * <ul> * <li>write action was in progress when the method was called</li> * <li>write action was pending when the method was called</li> * <li>action started to execute, but was aborted using {@link ProcessCanceledException} when some other thread initiated * write action</li> * </ul> * @param action the code to execute under read action * @param indicator progress indicator that should be cancelled if a write action is about to start. Can be null. * @since 171.* */ public abstract boolean runInReadActionWithWriteActionPriority(@NotNull final Runnable action, @Nullable ProgressIndicator indicator); public abstract boolean isInNonCancelableSection(); }