diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java index 4d94ede1240e..6b961d8e1e5e 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java +++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java @@ -176,6 +176,14 @@ public abstract class ProgressManager extends ProgressIndicatorProvider { */ public abstract void run(@NotNull Task task); + /** + * Runs a specified computation with a modal progress dialog. + */ + public T run(@NotNull Task.WithResult 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) { } diff --git a/platform/core-api/src/com/intellij/openapi/progress/Task.java b/platform/core-api/src/com/intellij/openapi/progress/Task.java index cdcabcf31941..dd64a8ed8582 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/Task.java +++ b/platform/core-api/src/com/intellij/openapi/progress/Task.java @@ -270,4 +270,33 @@ public abstract class Task implements TaskInfo, Progressive { return myShowWhenFocused; } } + + public abstract static class WithResult extends Task.Modal { + private final Ref myResult = Ref.create(); + private final Ref myError = Ref.create(); + + public WithResult(@Nullable Project project, @Nls(capitalization = Nls.Capitalization.Title) @NotNull String title, boolean canBeCancelled) { + super(project, title, canBeCancelled); + } + + @Override + public final void run(@NotNull ProgressIndicator indicator) { + try { + myResult.set(compute(indicator)); + } + catch (Throwable t) { + myError.set(t); + } + } + + protected abstract T compute(@NotNull ProgressIndicator indicator) throws E; + + @SuppressWarnings("unchecked") + public T getResult() throws E { + Throwable t = myError.get(); + ExceptionUtil.rethrowUnchecked(t); + if (t != null) throw (E)t; + return myResult.get(); + } + } } \ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationUtil.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationUtil.java index 3ef73a61e10e..2b2784d5004a 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationUtil.java +++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -52,21 +52,32 @@ public class ApplicationUtil { * Allows to interrupt a process which does not performs checkCancelled() calls by itself. * Note that the process may continue to run in background indefinitely - so avoid using this method unless absolutely needed. */ - public static T runWithCheckCanceled(@NotNull final Callable callable, - @NotNull final ProgressIndicator indicator) throws Exception { - return runWithCheckCanceled(callable, indicator, PooledThreadExecutor.INSTANCE); + public static T runWithCheckCanceled(@NotNull final Computable computable, @NotNull ProgressIndicator indicator) { + try { + return runWithCheckCanceled(new Callable() { + @Override + public T call() throws Exception { + return computable.compute(); + } + }, indicator); + } + catch (RuntimeException e) { + throw e; + } + catch (Exception e) { + throw new RuntimeException(e); + } } /** * Allows to interrupt a process which does not performs checkCancelled() calls by itself. * Note that the process may continue to run in background indefinitely - so avoid using this method unless absolutely needed. */ - public static T runWithCheckCanceled(@NotNull final Callable callable, - @NotNull final ProgressIndicator indicator, @NotNull ExecutorService executorService) throws Exception { + public static T runWithCheckCanceled(@NotNull final Callable callable, @NotNull final ProgressIndicator indicator) throws Exception { final Ref result = Ref.create(); final Ref error = Ref.create(); - Future future = executorService.submit(new Runnable() { + Future future = PooledThreadExecutor.INSTANCE.submit(new Runnable() { @Override public void run() { ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() { @@ -108,4 +119,4 @@ public class ApplicationUtil { return this; } } -} +} \ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java index 3ee37a57c6bb..9012dc726695 100644 --- a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java +++ b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java @@ -27,9 +27,9 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; @@ -38,7 +38,6 @@ import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.openapi.vfs.encoding.EncodingRegistry; import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.ArrayUtil; -import com.intellij.util.ExceptionUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.Nls; @@ -50,13 +49,11 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; -import java.util.concurrent.Callable; public final class LoadTextUtil { @Nls private static final String AUTO_DETECTED_FROM_BOM = "auto-detected from BOM"; - private LoadTextUtil() { - } + private LoadTextUtil() { } @NotNull private static Pair convertLineSeparators(@NotNull CharBuffer buffer) { @@ -248,7 +245,7 @@ public final class LoadTextUtil { * it is considered to be an external change if requestor is null. * See {@link com.intellij.openapi.vfs.VirtualFileEvent#getRequestor} * @param newModificationStamp new modification stamp or -1 if no special value should be set @return Writer - * @throws java.io.IOException if an I/O error occurs + * @throws IOException if an I/O error occurs * @see VirtualFile#getModificationStamp() */ public static void write(@Nullable Project project, @@ -371,35 +368,23 @@ public final class LoadTextUtil { Application app = ApplicationManager.getApplication(); if (app != null && app.isDispatchThread() && !app.isWriteAccessAllowed() && !ourDecompileProgressStarted) { - final Ref result = Ref.create(ArrayUtil.EMPTY_CHAR_SEQUENCE); - final Ref error = Ref.create(); - ourDecompileProgressStarted = true; try { - ProgressManager.getInstance().run(new Task.Modal(null, "Decompiling " + file.getName(), true) { + text = ProgressManager.getInstance().run(new Task.WithResult(null, "Decompiling " + file.getName(), true) { @Override - public void run(@NotNull ProgressIndicator indicator) { - indicator.setIndeterminate(true); - try { - result.set(ApplicationUtil.runWithCheckCanceled(new Callable() { - @Override - public CharSequence call() { - return decompiler.decompile(file); - } - }, indicator)); - } - catch (Throwable t) { - error.set(t); - } + protected CharSequence compute(@NotNull ProgressIndicator indicator) { + return ApplicationUtil.runWithCheckCanceled(new Computable() { + @Override + public CharSequence compute() { + return decompiler.decompile(file); + } + }, indicator); } }); } finally { ourDecompileProgressStarted = false; } - - ExceptionUtil.rethrowUnchecked(error.get()); - text = result.get(); } else { text = decompiler.decompile(file); @@ -409,7 +394,8 @@ public final class LoadTextUtil { return text; } - throw new IllegalArgumentException("Attempt to load text for binary file which doesn't have a decompiler plugged in: " + file.getPresentableUrl() + ". File type: " + fileType.getName()); + throw new IllegalArgumentException("Attempt to load text for binary file which doesn't have a decompiler plugged in: " + + file.getPresentableUrl() + ". File type: " + fileType.getName()); } try {