From 5ca49db3ebd73f1ee1ff9f5e81e1512ab5d82d7b Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 23 Sep 2011 15:56:40 +0400 Subject: [PATCH] init project under one progress, open it under another --- .../openapi/progress/ProgressManager.java | 17 ++ .../progress/impl/ProgressManagerImpl.java | 29 ++- .../project/impl/ProjectManagerImpl.java | 216 ++++++------------ 3 files changed, 114 insertions(+), 148 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/platform-api/src/com/intellij/openapi/progress/ProgressManager.java index 14772809ad63..c6d8eec6eb4c 100644 --- a/platform/platform-api/src/com/intellij/openapi/progress/ProgressManager.java +++ b/platform/platform-api/src/com/intellij/openapi/progress/ProgressManager.java @@ -17,6 +17,7 @@ package com.intellij.openapi.progress; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.ThrowableComputable; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -102,6 +103,22 @@ public abstract class ProgressManager { 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 Exception exception thrown by process + */ + public abstract T runProcessWithProgressSynchronously(@NotNull ThrowableComputable process, + @NotNull @Nls String progressTitle, + boolean canBeCanceled, + @Nullable Project project) throws Exception; + /** * Runs the specified operation in a background thread and shows a modal progress dialog in the * main thread while the operation is executing. diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index 296674fc61a0..546a8ad2235f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -24,8 +24,7 @@ import com.intellij.openapi.progress.*; import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.progress.util.SmoothProgressAdapter; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.*; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.psi.PsiLock; @@ -229,6 +228,30 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ return runProcessWithProgressSynchronously(process, progressTitle, canBeCanceled, project, null); } + @Override + public T runProcessWithProgressSynchronously(@NotNull final ThrowableComputable process, + @NotNull @Nls String progressTitle, + boolean canBeCanceled, + @Nullable Project project) throws Exception { + + final Ref result = new Ref(); + final Ref exceptionRef = new Ref(); + Task.Modal task = new Task.Modal(project, progressTitle, canBeCanceled) { + public void run(@NotNull ProgressIndicator indicator) { + try { + T compute = process.compute(); + result.set(compute); + } + catch (Exception e) { + exceptionRef.set(e); + } + } + }; + runProcessWithProgressSynchronously(task, null); + if (!exceptionRef.isNull()) throw exceptionRef.get(); + return result.get(); + } + public boolean runProcessWithProgressSynchronously(@NotNull final Runnable process, @NotNull String progressTitle, boolean canBeCanceled, @@ -242,7 +265,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ return runProcessWithProgressSynchronously(task, parentComponent); } - private static boolean runProcessWithProgressSynchronously(final Task task, final JComponent parentComponent) { + private static boolean runProcessWithProgressSynchronously(final Task task, @Nullable final JComponent parentComponent) { final long start = System.currentTimeMillis(); long time = 0; final boolean result = ((ApplicationEx)ApplicationManager.getApplication()) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index 4e19e5647c91..3bdf1736d438 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -402,35 +402,32 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt myOpenProjects.add(project); cacheOpenProjects(); - - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - public void run() { - fireProjectOpened(project); - } - }); + fireProjectOpened(project); final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(project); - boolean ok; - ProgressIndicator indicator = myProgressManager.getProgressIndicator(); - - if (indicator == null) { - ok = myProgressManager.runProcessWithProgressSynchronously(new Runnable() { - public void run() { - startupManager.runStartupActivities(); - } - }, ProjectBundle.message("project.load.progress"), true, project); - } - else { - try { + boolean ok = myProgressManager.runProcessWithProgressSynchronously(new Runnable() { + public void run() { startupManager.runStartupActivities(); - ok = true; + + // dumb mode should start before post-startup activities + // only when startCacheUpdate is called from UI thread, we can guarantee that + // when the method returns, the application has entered dumb mode + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + public void run() { + startupManager.startCacheUpdate(); + } + }); + + startupManager.runPostStartupActivitiesFromExtensions(); + + UIUtil.invokeLaterIfNeeded(new Runnable() { + public void run() { + startupManager.runPostStartupActivities(); + } + }); } - catch (Throwable e) { - LOG.info(e); - ok = false; - } - } + }, ProjectBundle.message("project.load.progress"), true, project); if (!ok) { closeProject(project, false, false); @@ -438,24 +435,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt return false; } - // dumb mode should start before post-startup activities - // only when startCacheUpdate is called from UI thread, we can guarantee that - // when the method returns, the application has entered dumb mode - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - public void run() { - startupManager.startCacheUpdate(); - } - }); - - startupManager.runPostStartupActivitiesFromExtensions(); - - UIUtil.invokeLaterIfNeeded(new Runnable() { - public void run() { - startupManager.runPostStartupActivities(); - } - }); - - if (!application.isHeadlessEnvironment() && !application.isUnitTestMode()) { // should be invoked last StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { @@ -476,67 +455,16 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt myOpenProjectsArrayCache = myOpenProjects.toArray(new Project[myOpenProjects.size()]); } - public Project loadAndOpenProject(@NotNull final String filePath) throws IOException, JDOMException, InvalidDataException { - final Ref projectRef = new Ref(); - final Ref exceptionRef = new Ref(); - myProgressManager.runProcessWithProgressSynchronously(new Runnable() { - @Override - public void run() { - try { - final Project project = convertAndLoadProject(filePath, new Ref()); - if (project == null) { - return; - } - - if (!openProject(project)) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - Disposer.dispose(project); - } - }); - - return; - } - - projectRef.set(project); - } - catch (StateStorageException e) { - exceptionRef.set(new IOException(e.getMessage())); - } - catch (IOException e) { - exceptionRef.set(e); - } - } - }, ProjectBundle.message("project.load.progress"), true, null); - - if (!exceptionRef.isNull()) { - throw exceptionRef.get(); - } - return projectRef.get(); - } - - @Nullable - public Project convertAndLoadProject(String filePath, Ref cancelled) throws IOException { - final Ref conversionResult = new Ref(); - final String fp = canonicalize(filePath); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - conversionResult.set(ConversionService.getInstance().convert(fp)); - } - }); - if (conversionResult.get().openingIsCanceled()) { - cancelled.set(true); + public Project loadAndOpenProject(@NotNull final String filePath) throws IOException { + final Project project = convertAndLoadProject(filePath, new Ref()); + if (project == null) { return null; } - final Project project = loadProjectWithProgress(filePath, new Ref()); - if (project == null) return null; - - if (!conversionResult.get().conversionNotNeeded()) { - StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() { + if (!openProject(project)) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { - conversionResult.get().postStartupActivity(project); + Disposer.dispose(project); } }); } @@ -544,57 +472,55 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt } @Nullable - public Project loadProjectWithProgress(final String filePath, final Ref canceled) throws IOException { - final IOException[] io = {null}; - final StateStorageException[] stateStorage = {null}; - - if (filePath != null) { - refreshProjectFiles(filePath); - } - final Project[] project = new Project[1]; - canceled.set(false); - Runnable runnable = new Runnable() { - public void run() { - try { - project[0] = doLoadProject(filePath); - } - catch (IOException e) { - io[0] = e; - } - catch (StateStorageException e) { - stateStorage[0] = e; - } - catch (ProcessCanceledException e) { - canceled.set(true); - throw e; - } - } - }; - if (ProgressManager.getInstance().getProgressIndicator() == null) { - myProgressManager.runProcessWithProgressSynchronously(runnable, ProjectBundle.message("project.load.progress"), true, null); - } - else { - runnable.run(); + public Project convertAndLoadProject(String filePath, Ref cancelled) throws IOException { + final String fp = canonicalize(filePath); + final ConversionResult conversionResult = ConversionService.getInstance().convert(fp); + if (conversionResult.openingIsCanceled()) { + cancelled.set(true); + return null; } - if (canceled.get() || project[0] == null) { - if (project[0] != null) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - Disposer.dispose(project[0]); - } - }); - } + final Project project = loadProjectWithProgress(filePath); + if (project == null) return null; + + if (!conversionResult.conversionNotNeeded()) { + StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() { + public void run() { + conversionResult.postStartupActivity(project); + } + }); + } + return project; + } + + @Nullable + private Project loadProjectWithProgress(final @NotNull String filePath) throws IOException { + + refreshProjectFiles(filePath); + Project project = null; + try { + project = myProgressManager.runProcessWithProgressSynchronously(new ThrowableComputable() { + @Nullable + public Project compute() throws Exception { + return doLoadProject(filePath); + } + }, ProjectBundle.message("project.load.progress"), true, null); + } + catch (StateStorageException e) { + throw new IOException(e); + } + catch (IOException e) { + throw e; + } + catch (Exception ignore) { + // ignore + } + + if (project == null) { notifyProjectOpenFailed(); } - if (io[0] != null) throw io[0]; - if (stateStorage[0] != null) throw stateStorage[0]; - - if (project[0] == null || canceled.get()) { - return null; - } - return project [0]; + return project; } private static void refreshProjectFiles(final String filePath) {