diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.kt b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.kt index 26bddadde068..90eda165a4d6 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.kt +++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.kt @@ -10,7 +10,6 @@ import com.intellij.ide.impl.ProjectUtil.isSameProject import com.intellij.ide.impl.ProjectUtil.updateLastProjectLocation import com.intellij.ide.projectWizard.NewProjectWizardCollector import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard -import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.command.CommandProcessor @@ -33,6 +32,7 @@ import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.wm.ToolWindowId import com.intellij.openapi.wm.ToolWindowManager import com.intellij.platform.ide.progress.ModalTaskOwner +import com.intellij.projectImport.ProjectOpenedCallback import com.intellij.ui.AppUIUtil import com.intellij.ui.IdeUICustomization import com.intellij.util.TimeoutUtil @@ -172,15 +172,20 @@ object NewProjectUtil { if (newProject !== projectToClose) { updateLastProjectLocation(projectFile) - var options = build().withProject(newProject) - val fileName = projectFile.fileName - if (fileName != null) { - options = options.withProjectName(fileName.toString()) + val moduleConfigurator = projectBuilder.createModuleConfigurator() + val options = OpenProjectTask { + project = newProject + projectName = projectFile.fileName.toString() + callback = ProjectOpenedCallback { _, module -> + ApplicationManager.getApplication().invokeLater { + moduleConfigurator?.accept(module) + } + } } TrustedPaths.getInstance().setProjectPathTrusted(projectDir, true) runBlockingModalWithRawProgressReporter( owner = ModalTaskOwner.guess(), - title = IdeUICustomization.getInstance().projectMessage("progress.title.project.loading.name", fileName.toString()), + title = IdeUICustomization.getInstance().projectMessage("progress.title.project.loading.name", options.projectName), ) { ProjectManagerEx.getInstanceEx().openProjectAsync(projectStoreBaseDir = projectDir, options = options) } diff --git a/platform/lang-core/api-dump-unreviewed.txt b/platform/lang-core/api-dump-unreviewed.txt index f726fda011ce..45e9ad2e185f 100644 --- a/platform/lang-core/api-dump-unreviewed.txt +++ b/platform/lang-core/api-dump-unreviewed.txt @@ -309,6 +309,7 @@ a:com.intellij.ide.util.projectWizard.ProjectBuilder - commit(com.intellij.openapi.project.Project):java.util.List - commit(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel):java.util.List - a:commit(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel,com.intellij.openapi.roots.ui.configuration.ModulesProvider):java.util.List +- createModuleConfigurator():java.util.function.Consumer - createProject(java.lang.String,java.lang.String):com.intellij.openapi.project.Project - isOpenProjectSettingsAfter():Z - isSuitableSdkType(com.intellij.openapi.projectRoots.SdkTypeId):Z diff --git a/platform/lang-core/src/com/intellij/ide/util/projectWizard/ProjectBuilder.java b/platform/lang-core/src/com/intellij/ide/util/projectWizard/ProjectBuilder.java index e6eb3579fdc6..f663f27f50ec 100644 --- a/platform/lang-core/src/com/intellij/ide/util/projectWizard/ProjectBuilder.java +++ b/platform/lang-core/src/com/intellij/ide/util/projectWizard/ProjectBuilder.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.function.Consumer; public abstract class ProjectBuilder { public boolean isUpdate() { @@ -45,4 +46,12 @@ public abstract class ProjectBuilder { public @Nullable Project createProject(String name, String path) { return ProjectManager.getInstance().createProject(name, path); } + + /** + * Configure project when it's added to workspace as module. + */ + @Nullable + public Consumer createModuleConfigurator() { + return null; + } } diff --git a/platform/lang-impl/api-dump-unreviewed.txt b/platform/lang-impl/api-dump-unreviewed.txt index 556e96cee3d9..d73ab6f1d60c 100644 --- a/platform/lang-impl/api-dump-unreviewed.txt +++ b/platform/lang-impl/api-dump-unreviewed.txt @@ -19013,6 +19013,7 @@ f:com.intellij.ide.util.projectWizard.WebTemplateProjectWizardStep - com.intellij.ide.wizard.AbstractNewProjectWizardStep - com.intellij.ide.util.projectWizard.WebTemplateProjectWizardData - (com.intellij.ide.wizard.NewProjectWizardBaseStep,com.intellij.ide.util.projectWizard.WebProjectTemplate):V +- createModuleConfigurator():java.util.function.Consumer - f:getParent():com.intellij.ide.wizard.NewProjectWizardBaseStep - getPeer():com.intellij.openapi.util.NotNullLazyValue - f:getTemplate():com.intellij.ide.util.projectWizard.WebProjectTemplate @@ -20835,6 +20836,7 @@ c:com.intellij.openapi.module.WebModuleBuilder - (com.intellij.ide.util.projectWizard.WebProjectTemplate):V - (com.intellij.ide.util.projectWizard.WebProjectTemplate,com.intellij.openapi.util.NotNullLazyValue):V - commitModule(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel):com.intellij.openapi.module.Module +- createModuleConfigurator():java.util.function.Consumer - getGroupName():java.lang.String - getModuleType():com.intellij.openapi.module.ModuleType - getNodeIcon():javax.swing.Icon diff --git a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebTemplateProjectWizardStep.kt b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebTemplateProjectWizardStep.kt index d0d7b55e59e8..c7a511b3ee10 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebTemplateProjectWizardStep.kt +++ b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebTemplateProjectWizardStep.kt @@ -3,6 +3,7 @@ package com.intellij.ide.util.projectWizard import com.intellij.ide.wizard.AbstractNewProjectWizardStep import com.intellij.ide.wizard.NewProjectWizardBaseStep +import com.intellij.openapi.module.Module import com.intellij.openapi.module.WebModuleBuilder import com.intellij.openapi.project.Project import com.intellij.openapi.util.NotNullLazyValue @@ -10,6 +11,7 @@ import com.intellij.platform.ProjectGeneratorPeer import com.intellij.ui.JBColor import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.Panel +import java.util.function.Consumer import javax.swing.JLabel class WebTemplateProjectWizardStep( @@ -39,13 +41,21 @@ class WebTemplateProjectWizardStep( } override fun setupProject(project: Project) { - val builder = WebModuleBuilder(template, peer) - builder.moduleFilePath = "${parent.path}/${parent.name}" - builder.contentEntryPath = "${parent.path}/${parent.name}" - builder.name = parent.name - builder.commitModule(project, null) + webModuleBuilder().commitModule(project, null) } - + + private fun webModuleBuilder(): WebModuleBuilder { + return WebModuleBuilder(template, peer).apply { + moduleFilePath = "${parent.path}/${parent.name}" + contentEntryPath = "${parent.path}/${parent.name}" + name = parent.name + } + } + + override fun createModuleConfigurator(): Consumer? { + return webModuleBuilder().createModuleConfigurator() + } + init { data.putUserData(WebTemplateProjectWizardData.KEY, this) } diff --git a/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt b/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt index 0c7934da8d1d..1c7bcf12c490 100644 --- a/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt +++ b/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt @@ -2,6 +2,7 @@ package com.intellij.ide.workspace import com.intellij.lang.LangBundle +import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.project.stateStore import com.intellij.projectImport.ProjectAttachProcessor @@ -16,7 +17,13 @@ internal class WorkspaceAttachProcessor : ProjectAttachProcessor() { return false } getCoroutineScope(project).launch { + val modules = ModuleManager.getInstance(project).modules.toSet() linkToWorkspace(project, projectDir.pathString) + if (callback != null) { + ModuleManager.getInstance(project).modules.subtract(modules).firstOrNull()?.let { + module -> callback.projectOpened(project, module) + } + } } return true } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java b/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java index 694ac7a0c106..d43c81cf8933 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.function.Consumer; /** * @author Dmitry Avdeev @@ -80,19 +81,30 @@ public class WebModuleBuilder extends ModuleBuilder { public @Nullable Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) { Module module = super.commitModule(project, model); if (module != null && myTemplate != null) { - doGenerate(myTemplate, module); + VirtualFile dir = getModuleDir(module); + myTemplate.generateProject(module.getProject(), dir, myGeneratorPeerLazyValue.getValue().getSettings(), module); } return module; } - private void doGenerate(@NotNull WebProjectTemplate template, @NotNull Module module) { + @Override + public @Nullable Consumer createModuleConfigurator() { + return module -> { + if (myTemplate != null) { + VirtualFile dir = getModuleDir(module); + myTemplate.configureModule(module, dir, myGeneratorPeerLazyValue.getValue().getSettings()); + } + }; + } + + private static @NotNull VirtualFile getModuleDir(@NotNull Module module) { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); VirtualFile dir = ProjectUtil.guessModuleDir(module); if (dir == null) { dir = ArrayUtil.getFirstElement(moduleRootManager.getContentRoots()); } assert dir != null : module.getProject(); - template.generateProject(module.getProject(), dir, myGeneratorPeerLazyValue.getValue().getSettings(), module); + return dir; } @Override diff --git a/platform/platform-impl/api-dump-unreviewed.txt b/platform/platform-impl/api-dump-unreviewed.txt index a003d69483fe..68ca139e7f58 100644 --- a/platform/platform-impl/api-dump-unreviewed.txt +++ b/platform/platform-impl/api-dump-unreviewed.txt @@ -10576,6 +10576,7 @@ a:com.intellij.ide.wizard.AbstractNewProjectWizardBuilder - ():V - cleanup():V - commitModule(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel):com.intellij.openapi.module.Module +- createModuleConfigurator():java.util.function.Consumer - pa:createStep(com.intellij.ide.util.projectWizard.WizardContext):com.intellij.ide.wizard.NewProjectWizardStep - f:getCustomOptionsStep(com.intellij.ide.util.projectWizard.WizardContext,com.intellij.openapi.Disposable):com.intellij.ide.util.projectWizard.ModuleWizardStep - getDescription():java.lang.String @@ -10732,6 +10733,7 @@ f:com.intellij.ide.wizard.NewProjectWizardChainStep - com.intellij.ide.wizard.AbstractNewProjectWizardStep - sf:Companion:com.intellij.ide.wizard.NewProjectWizardChainStep$Companion - (com.intellij.ide.wizard.NewProjectWizardStep):V +- createModuleConfigurator():java.util.function.Consumer - f:nextStep(kotlin.jvm.functions.Function1):com.intellij.ide.wizard.NewProjectWizardChainStep - setupProject(com.intellij.openapi.project.Project):V - setupUI(com.intellij.ui.dsl.builder.Panel):V @@ -10768,6 +10770,7 @@ com.intellij.ide.wizard.NewProjectWizardStep - sf:GENERATE_ONBOARDING_TIPS_NAME:java.lang.String - sf:GIT_PROPERTY_NAME:java.lang.String - sf:GROUP_ID_PROPERTY_NAME:java.lang.String +- createModuleConfigurator():java.util.function.Consumer - a:getContext():com.intellij.ide.util.projectWizard.WizardContext - a:getData():com.intellij.openapi.util.UserDataHolder - a:getKeywords():com.intellij.ide.wizard.NewProjectWizardStep$Keywords @@ -23270,6 +23273,7 @@ a:com.intellij.platform.DirectoryProjectConfigurator$AsyncDirectoryProjectConfig - f:configureProject(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile,com.intellij.openapi.util.Ref,Z):V - f:isEdtRequired():Z com.intellij.platform.DirectoryProjectGenerator +- configureModule(com.intellij.openapi.module.Module,com.intellij.openapi.vfs.VirtualFile,java.lang.Object):V - createLazyPeer():com.intellij.openapi.util.NotNullLazyValue - createPeer():com.intellij.platform.ProjectGeneratorPeer - a:generateProject(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile,java.lang.Object,com.intellij.openapi.module.Module):V diff --git a/platform/platform-impl/src/com/intellij/ide/wizard/AbstractNewProjectWizardBuilder.kt b/platform/platform-impl/src/com/intellij/ide/wizard/AbstractNewProjectWizardBuilder.kt index cddfece292ae..d25e6ae6653d 100644 --- a/platform/platform-impl/src/com/intellij/ide/wizard/AbstractNewProjectWizardBuilder.kt +++ b/platform/platform-impl/src/com/intellij/ide/wizard/AbstractNewProjectWizardBuilder.kt @@ -13,6 +13,7 @@ import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.module.ModuleType import com.intellij.openapi.project.Project import com.intellij.platform.backend.observation.trackActivityBlocking +import java.util.function.Consumer import javax.swing.Icon abstract class AbstractNewProjectWizardBuilder : ModuleBuilder() { @@ -49,6 +50,10 @@ abstract class AbstractNewProjectWizardBuilder : ModuleBuilder() { } } + override fun createModuleConfigurator(): Consumer? { + return panel!!.step.createModuleConfigurator() + } + override fun cleanup() { panel = null } diff --git a/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardChainStep.kt b/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardChainStep.kt index 8d9af56ef34e..64ef61a5a36a 100644 --- a/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardChainStep.kt +++ b/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardChainStep.kt @@ -1,8 +1,10 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.wizard +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.ui.dsl.builder.Panel +import java.util.function.Consumer /** @@ -45,6 +47,10 @@ class NewProjectWizardChainStep : AbstractNewProjectWi } } + override fun createModuleConfigurator(): Consumer? { + return steps.firstNotNullOfOrNull { it.createModuleConfigurator() } + } + companion object { fun S.nextStep(create: (S) -> NS): NewProjectWizardChainStep { diff --git a/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardStep.kt b/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardStep.kt index 39a619f7cadf..727ad87a4094 100644 --- a/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardStep.kt +++ b/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardStep.kt @@ -3,11 +3,13 @@ package com.intellij.ide.wizard import com.intellij.ide.util.projectWizard.WizardContext import com.intellij.openapi.module.ModifiableModuleModel +import com.intellij.openapi.module.Module import com.intellij.openapi.observable.properties.PropertyGraph import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.openapi.util.UserDataHolder import com.intellij.ui.dsl.builder.Panel +import java.util.function.Consumer /** * Defines vertical step in new project wizard. It is step which @@ -84,6 +86,8 @@ interface NewProjectWizardStep { */ fun setupProject(project: Project) {} + fun createModuleConfigurator(): Consumer? = null + /** * See related doc for [NewProjectWizardStep.keywords]. */ diff --git a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java index 2d78887e2f14..ed03619bc383 100644 --- a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java +++ b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java @@ -62,6 +62,13 @@ public interface DirectoryProjectGenerator { @NotNull T settings, @NotNull Module module); + /** + * Configure project when it's added to workspace as module. + */ + default void configureModule(@NotNull Module module, + @NotNull VirtualFile baseDir, + @NotNull T settings) { } + @NotNull ValidationResult validate(@NotNull String baseDirPath); }