diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/NewProjectWizardModuleBuilder.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/NewProjectWizardModuleBuilder.kt index 1809b9393ce..385891159a8 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/NewProjectWizardModuleBuilder.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/NewProjectWizardModuleBuilder.kt @@ -1,8 +1,10 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard +import com.intellij.ide.RecentProjectsManager import com.intellij.ide.projectWizard.ProjectSettingsStep import com.intellij.ide.util.projectWizard.* import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationNamesInfo import com.intellij.openapi.module.ModifiableModuleModel import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.module.ModuleType @@ -20,14 +22,13 @@ import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.tools.projectWizard.core.Failure -import org.jetbrains.kotlin.tools.projectWizard.core.Success +import org.jetbrains.kotlin.tools.projectWizard.core.* import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidators import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult -import org.jetbrains.kotlin.tools.projectWizard.core.isSuccess -import org.jetbrains.kotlin.tools.projectWizard.core.onFailure +import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase import org.jetbrains.kotlin.tools.projectWizard.plugins.Plugins +import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.ProjectTemplatesPlugin import org.jetbrains.kotlin.tools.projectWizard.wizard.service.IdeaServices @@ -37,6 +38,7 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep.FirstWizardS import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.runWithProgressBar import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.SecondStepWizardComponent import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import java.io.File import java.nio.file.Paths import javax.swing.JComponent import com.intellij.openapi.module.Module as IdeaModule @@ -117,7 +119,6 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() { override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep { updateProjectNameAndPomDate(settingsStep) - return when (wizard.buildSystemType) { BuildSystemType.Jps -> { KotlinModuleSettingStep( @@ -149,8 +150,8 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() { ProjectTemplatesPlugin::template.settingValue.suggestedProjectName.decapitalize() } settingsStep.moduleNameLocationSettings?.apply { - val projectParentDirectory = moduleContentRoot.let { Paths.get(it).parent.toString() } - moduleName = ProjectWizardUtil.findNonExistingFileName(projectParentDirectory, suggestedProjectName, "") + moduleName = wizard.projectName!! + moduleContentRoot = wizard.projectPath!!.toString() } settingsStep.safeAs()?.bindModuleSettings() @@ -184,7 +185,7 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() { abstract class WizardStep(protected val wizard: IdeWizard, private val phase: GenerationPhase) : ModuleWizardStep() { override fun updateDataModel() = Unit // model is updated on every UI action override fun validate(): Boolean = - when (val result = wizard.context.read{ with(wizard) { validate(setOf(phase)) } }) { + when (val result = wizard.context.read { with(wizard) { validate(setOf(phase)) } }) { is Success<*> -> true is Failure -> { throw ConfigurationException(result.asHtml(), KotlinNewProjectWizardBundle.message("error.validation")) @@ -214,6 +215,7 @@ class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, Generatio init { runPreparePhase() + initDefaultProjectNameAndPathValues() component.onInit() } @@ -222,6 +224,26 @@ class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, Generatio ProgressManager.getInstance().progressIndicator.text = task.title ?: "" } } + + private fun initDefaultProjectNameAndPathValues() { + val suggestedProjectParentLocation = suggestProjectLocation() + val suggestedProjectName = ProjectWizardUtil.findNonExistingFileName(suggestedProjectParentLocation, "untitled", "") + wizard.context.writeSettings { + StructurePlugin::name.reference.setValue(suggestedProjectName) + StructurePlugin::projectPath.reference.setValue(suggestedProjectParentLocation / suggestedProjectName) + } + } + + // copied from com.intellij.ide.util.projectWizard.WizardContext.getProjectFileDirectory + private fun suggestProjectLocation(): String { + val lastProjectLocation = RecentProjectsManager.getInstance().lastProjectCreationLocation + if (lastProjectLocation != null) { + return lastProjectLocation.replace('/', File.separatorChar) + } + val userHome = SystemProperties.getUserHome() + val productName = ApplicationNamesInfo.getInstance().lowercaseProductName + return userHome.replace('/', File.separatorChar) + File.separator + productName.replace(" ", "") + "Projects" + } } class ModuleNewWizardSecondStep( diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/PomWizardStepComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/PomWizardStepComponent.kt index a4157e2d8d0..c49165eeb31 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/PomWizardStepComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/PomWizardStepComponent.kt @@ -13,19 +13,19 @@ class PomWizardStepComponent(context: Context) : WizardStepComponent(context) { private val groupIdComponent = StringSettingComponent( StructurePlugin::groupId.reference, context, - showLabel = true + needLabel = true ).asSubComponent() private val artifactIdComponent = StringSettingComponent( StructurePlugin::artifactId.reference, context, - showLabel = true + needLabel = true ).asSubComponent() private val versionComponent = StringSettingComponent( StructurePlugin::version.reference, context, - showLabel = true + needLabel = true ).asSubComponent() diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/FirstWizardStepComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/FirstWizardStepComponent.kt index b07b1cf4d68..440c90003bc 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/FirstWizardStepComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/FirstWizardStepComponent.kt @@ -1,15 +1,21 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep import TemplateTag +import com.intellij.ide.plugins.newui.VerticalLayout import com.intellij.util.ui.JBUI import org.jetbrains.kotlin.tools.projectWizard.core.Context import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference +import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin +import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.ProjectTemplatesPlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.applyProjectTemplate import org.jetbrains.kotlin.tools.projectWizard.projectTemplates.ProjectTemplate import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.* +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.PathSettingComponent +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingsList +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.StringSettingComponent import java.awt.BorderLayout import javax.swing.Box import javax.swing.BoxLayout @@ -17,11 +23,18 @@ import javax.swing.JComponent import java.awt.Component as AwtComponent class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.context) { + private val nameAndLocationComponent = SettingsList( + listOf( + StructurePlugin::name.reference, + StructurePlugin::projectPath.reference + ), + wizard.context + ).asSubComponent() private val buildSystemSubStep = BuildSystemSubStep(wizard.context).asSubComponent() private val templatesSubStep = TemplatesSubStep(wizard.context).asSubComponent() override val component: JComponent = panel { - add(templatesSubStep.component, BorderLayout.CENTER) + add(nameAndLocationComponent.component, BorderLayout.CENTER) add(buildSystemSubStep.component, BorderLayout.SOUTH) } } diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt index 98ae74e946b..dd4d9aca331 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt @@ -23,7 +23,8 @@ object DefaultSettingComponent { @Suppress("UNCHECKED_CAST") fun > create( setting: SettingReference, - context: Context + context: Context, + needLabel: Boolean = true ): SettingComponent = when (setting.type) { VersionSettingType::class -> VersionSettingComponent( @@ -33,22 +34,26 @@ object DefaultSettingComponent { BooleanSettingType::class -> BooleanSettingComponent( setting as SettingReference, - context + context, + needLabel ) as SettingComponent DropDownSettingType::class -> DropdownSettingComponent( setting as SettingReference>, - context + context, + needLabel ) as SettingComponent StringSettingType::class -> StringSettingComponent( setting as SettingReference, - context + context, + needLabel ) as SettingComponent PathSettingType::class -> PathSettingComponent( setting as SettingReference, - context + context, + needLabel ) as SettingComponent else -> TODO(setting.type.qualifiedName!!) } @@ -94,7 +99,8 @@ class VersionSettingComponent( class DropdownSettingComponent( reference: SettingReference>, - context: Context + context: Context, + needLabel: Boolean = true ) : UIComponentDelegatingSettingComponent>( reference, context @@ -106,14 +112,15 @@ class DropdownSettingComponent( filter = { value -> context.read { setting.type.filter(this, reference, value) } }, - labelText = setting.title, + labelText = setting.title.takeIf { needLabel }, onValueUpdate = { newValue -> value = newValue } ).asSubComponent() } class BooleanSettingComponent( reference: SettingReference, - context: Context + context: Context, + needLabel: Boolean = true ) : UIComponentDelegatingSettingComponent( reference, context @@ -130,7 +137,7 @@ class BooleanSettingComponent( class StringSettingComponent( reference: SettingReference, context: Context, - showLabel: Boolean = true + needLabel: Boolean = true ) : UIComponentDelegatingSettingComponent( reference, context @@ -138,7 +145,7 @@ class StringSettingComponent( override val uiComponent = TextFieldComponent( context = context, initialValue = null, - labelText = if (showLabel) setting.title else null, + labelText = setting.title.takeIf { needLabel }, validator = setting.validator, onValueUpdate = { newValue -> value = newValue } ).asSubComponent() @@ -146,14 +153,15 @@ class StringSettingComponent( class PathSettingComponent( reference: SettingReference, - context: Context + context: Context, + needLabel: Boolean = true ) : UIComponentDelegatingSettingComponent( reference, context ) { override val uiComponent = PathFieldComponent( context = context, - labelText = setting.title, + labelText = setting.title.takeIf { needLabel }, validator = settingValidator { path -> setting.validator.validate(this, path) }, onValueUpdate = { newValue -> value = newValue } ).asSubComponent() diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/SettingsList.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/SettingsList.kt index 07082198f62..e0f0a11bd83 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/SettingsList.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/SettingsList.kt @@ -1,14 +1,13 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting -import com.intellij.ui.components.panels.VerticalLayout +import com.intellij.ui.layout.panel +import com.intellij.util.ui.components.BorderLayoutPanel import org.jetbrains.kotlin.tools.projectWizard.core.Context import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult import org.jetbrains.kotlin.tools.projectWizard.core.entity.isSpecificError import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.FocusableComponent -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.PanelWithStatusText -import javax.swing.JComponent interface ErrorAwareComponent { fun findComponentWithError(error: ValidationResult.ValidationError): FocusableComponent? @@ -18,16 +17,15 @@ class SettingsList( settings: List>, private val context: Context ) : DynamicComponent(context), ErrorAwareComponent { - private val panel = PanelWithStatusText(VerticalLayout(5), "This module has no settings to configure") + private val ui = BorderLayoutPanel() - var settingComponents: List> = emptyList() - private set + private var settingComponents: List> = emptyList() init { setSettings(settings) } - override val component: JComponent = panel + override val component get() = ui override fun onInit() { super.onInit() @@ -35,12 +33,18 @@ class SettingsList( } fun setSettings(settings: List>) { - panel.isStatusTextVisible = settings.isEmpty() - panel.removeAll() + ui.removeAll() settingComponents = settings.map { setting -> - DefaultSettingComponent.create(setting, context) + DefaultSettingComponent.create(setting, context, needLabel = false) } - settingComponents.forEach { setting -> setting.onInit(); panel.add(setting.component) } + ui.addToCenter(panel { + settingComponents.forEach { settingComponent -> + settingComponent.onInit() + row(settingComponent.setting.title + ":") { + settingComponent.component(growX) + } + } + }) } override fun findComponentWithError(error: ValidationResult.ValidationError) = read { diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/StructurePlugin.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/StructurePlugin.kt index df9b469b84d..b50689971a3 100644 --- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/StructurePlugin.kt +++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/StructurePlugin.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version import java.nio.file.Paths class StructurePlugin(context: Context) : Plugin(context) { - val projectPath by valueSetting("Root path", GenerationPhase.PROJECT_GENERATION, pathParser) { + val projectPath by pathSetting("Root path", GenerationPhase.PROJECT_GENERATION) { defaultValue = value(Paths.get(".")) } val name by stringSetting("Name", GenerationPhase.PROJECT_GENERATION)