Wizard: move pom settings to the first phase

This commit is contained in:
Ilya Kirillov
2020-03-17 23:06:36 +03:00
parent c71972afc9
commit 0dc0c41842
13 changed files with 172 additions and 133 deletions
@@ -1,7 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard package org.jetbrains.kotlin.tools.projectWizard.wizard
import com.intellij.ide.RecentProjectsManager import com.intellij.ide.RecentProjectsManager
import com.intellij.ide.projectWizard.ProjectSettingsStep
import com.intellij.ide.util.projectWizard.* import com.intellij.ide.util.projectWizard.*
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationNamesInfo import com.intellij.openapi.application.ApplicationNamesInfo
@@ -15,13 +14,11 @@ import com.intellij.openapi.roots.ui.configuration.ModulesProvider
import com.intellij.openapi.ui.Messages import com.intellij.openapi.ui.Messages
import com.intellij.util.SystemProperties import com.intellij.util.SystemProperties
import org.jetbrains.kotlin.idea.configuration.ExperimentalFeatures import org.jetbrains.kotlin.idea.configuration.ExperimentalFeatures
import org.jetbrains.kotlin.idea.framework.KotlinModuleSettingStep
import org.jetbrains.kotlin.idea.framework.KotlinTemplatesFactory import org.jetbrains.kotlin.idea.framework.KotlinTemplatesFactory
import org.jetbrains.kotlin.idea.projectWizard.ProjectCreationStats import org.jetbrains.kotlin.idea.projectWizard.ProjectCreationStats
import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats
import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.tools.projectWizard.core.* import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidators 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.entity.ValidationResult
@@ -30,16 +27,14 @@ import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.Plugins import org.jetbrains.kotlin.tools.projectWizard.plugins.Plugins
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType 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 import org.jetbrains.kotlin.tools.projectWizard.wizard.service.IdeaServices
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.PomWizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.asHtml import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.asHtml
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep.FirstWizardStepComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep.FirstWizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.runWithProgressBar import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.runWithProgressBar
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.SecondStepWizardComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.SecondStepWizardComponent
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.File import java.io.File
import java.nio.file.Paths import javax.swing.JButton
import javax.swing.JComponent import javax.swing.JComponent
import com.intellij.openapi.module.Module as IdeaModule import com.intellij.openapi.module.Module as IdeaModule
@@ -60,7 +55,6 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
companion object { companion object {
const val MODULE_BUILDER_ID = "kotlin.newProjectWizard.builder" const val MODULE_BUILDER_ID = "kotlin.newProjectWizard.builder"
private const val DEFAULT_GROUP_ID = "me.user"
private val projectNameValidator = StringValidators.shouldBeValidIdentifier("Project name", setOf('-', '_')) private val projectNameValidator = StringValidators.shouldBeValidIdentifier("Project name", setOf('-', '_'))
private const val INVALID_PROJECT_NAME_MESSAGE = "Invalid project name" private const val INVALID_PROJECT_NAME_MESSAGE = "Invalid project name"
} }
@@ -68,7 +62,7 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
override fun isAvailable(): Boolean = ExperimentalFeatures.NewWizard.isEnabled override fun isAvailable(): Boolean = ExperimentalFeatures.NewWizard.isEnabled
private var wizardContext: WizardContext? = null private var wizardContext: WizardContext? = null
private var pomValuesAreSet: Boolean = false private var finishButtonClicked: Boolean = false
override fun getModuleType(): ModuleType<*> = NewProjectWizardModuleType() override fun getModuleType(): ModuleType<*> = NewProjectWizardModuleType()
override fun getParentGroup(): String = KotlinTemplatesFactory.KOTLIN_PARENT_GROUP_NAME override fun getParentGroup(): String = KotlinTemplatesFactory.KOTLIN_PARENT_GROUP_NAME
@@ -78,7 +72,7 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
modulesProvider: ModulesProvider modulesProvider: ModulesProvider
): Array<ModuleWizardStep> { ): Array<ModuleWizardStep> {
this.wizardContext = wizardContext this.wizardContext = wizardContext
return arrayOf(ModuleNewWizardSecondStep(wizard, uiEditorUsagesStats)) return arrayOf(ModuleNewWizardSecondStep(wizard, uiEditorUsagesStats, wizardContext))
} }
override fun commit( override fun commit(
@@ -114,19 +108,15 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
} }
} }
override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep { private fun clickFinishButton() {
updateProjectNameAndPomDate(settingsStep) if (finishButtonClicked) return
return when (wizard.buildSystemType) { finishButtonClicked = true
BuildSystemType.Jps -> { wizardContext?.getActionButtonWithText("Finish", "Next")?.doClick()
KotlinModuleSettingStep( }
JvmPlatforms.defaultJvmPlatform,
this, override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep? {
settingsStep, clickFinishButton()
wizardContext return null
)
}
else -> PomWizardStep(settingsStep, wizard)
}
} }
override fun validateModuleName(moduleName: String): Boolean { override fun validateModuleName(moduleName: String): Boolean {
@@ -141,42 +131,10 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
} }
} }
private fun updateProjectNameAndPomDate(settingsStep: SettingsStep) {
if (pomValuesAreSet) return
val suggestedProjectName = wizard.context.read {
ProjectTemplatesPlugin::template.settingValue.suggestedProjectName.decapitalize()
}
settingsStep.moduleNameLocationSettings?.apply {
moduleName = wizard.projectName!!
moduleContentRoot = wizard.projectPath!!.toString()
}
settingsStep.safeAs<ProjectSettingsStep>()?.bindModuleSettings()
wizard.artifactId = suggestedProjectName
wizard.groupId = suggestGroupId()
pomValuesAreSet = true
}
private fun suggestGroupId(): String {
val username = SystemProperties.getUserName() ?: return DEFAULT_GROUP_ID
if (!username.matches("[\\w\\s]+".toRegex())) return DEFAULT_GROUP_ID
val usernameAsGroupId = username.trim().toLowerCase().split("\\s+".toRegex()).joinToString(separator = ".")
return "me.$usernameAsGroupId"
}
override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?) = override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?) =
ModuleNewWizardFirstStep(wizard) ModuleNewWizardFirstStep(wizard)
override fun setName(name: String) {
wizard.projectName = name
}
override fun setModuleFilePath(path: String) = Unit override fun setModuleFilePath(path: String) = Unit
override fun setContentEntryPath(moduleRootPath: String) {
wizard.projectPath = Paths.get(moduleRootPath)
}
} }
abstract class WizardStep(protected val wizard: IdeWizard, private val phase: GenerationPhase) : ModuleWizardStep() { abstract class WizardStep(protected val wizard: IdeWizard, private val phase: GenerationPhase) : ModuleWizardStep() {
@@ -195,29 +153,13 @@ abstract class WizardStep(protected val wizard: IdeWizard, private val phase: Ge
} }
} }
private class PomWizardStep(
originalSettingStep: SettingsStep,
wizard: IdeWizard
) : WizardStep(wizard, GenerationPhase.PROJECT_GENERATION) {
private val pomWizardStepComponent = PomWizardStepComponent(wizard.context)
init {
originalSettingStep.addSettingsComponent(component)
pomWizardStepComponent.onInit()
}
override fun getComponent(): JComponent = pomWizardStepComponent.component
}
class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, GenerationPhase.FIRST_STEP) { class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, GenerationPhase.FIRST_STEP) {
private val component = FirstWizardStepComponent(wizard) private val component = FirstWizardStepComponent(wizard)
override fun getComponent(): JComponent = component.component override fun getComponent(): JComponent = component.component
init { init {
runPreparePhase() runPreparePhase()
initDefaultProjectNameAndPathValues() initDefaultValues()
component.onInit() component.onInit()
} }
@@ -227,15 +169,31 @@ class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, Generatio
} }
} }
private fun initDefaultProjectNameAndPathValues() { override fun handleErrors(error: ValidationResult.ValidationError) {
component.navigateTo(error)
}
private fun initDefaultValues() {
val suggestedProjectParentLocation = suggestProjectLocation() val suggestedProjectParentLocation = suggestProjectLocation()
val suggestedProjectName = ProjectWizardUtil.findNonExistingFileName(suggestedProjectParentLocation, "untitled", "") val suggestedProjectName = ProjectWizardUtil.findNonExistingFileName(suggestedProjectParentLocation, "untitled", "")
wizard.context.writeSettings { wizard.context.writeSettings {
StructurePlugin::name.reference.setValue(suggestedProjectName) StructurePlugin::name.reference.setValue(suggestedProjectName)
StructurePlugin::projectPath.reference.setValue(suggestedProjectParentLocation / suggestedProjectName) StructurePlugin::projectPath.reference.setValue(suggestedProjectParentLocation / suggestedProjectName)
StructurePlugin::artifactId.reference.setValue(suggestedProjectName)
if (StructurePlugin::groupId.reference.notRequiredSettingValue == null) {
StructurePlugin::groupId.reference.setValue(suggestGroupId())
}
} }
} }
private fun suggestGroupId(): String {
val username = SystemProperties.getUserName() ?: return DEFAULT_GROUP_ID
if (!username.matches("[\\w\\s]+".toRegex())) return DEFAULT_GROUP_ID
val usernameAsGroupId = username.trim().toLowerCase().split("\\s+".toRegex()).joinToString(separator = ".")
return "me.$usernameAsGroupId"
}
// copied from com.intellij.ide.util.projectWizard.WizardContext.getProjectFileDirectory // copied from com.intellij.ide.util.projectWizard.WizardContext.getProjectFileDirectory
private fun suggestProjectLocation(): String { private fun suggestProjectLocation(): String {
val lastProjectLocation = RecentProjectsManager.getInstance().lastProjectCreationLocation val lastProjectLocation = RecentProjectsManager.getInstance().lastProjectCreationLocation
@@ -246,11 +204,16 @@ class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, Generatio
val productName = ApplicationNamesInfo.getInstance().lowercaseProductName val productName = ApplicationNamesInfo.getInstance().lowercaseProductName
return userHome.replace('/', File.separatorChar) + File.separator + productName.replace(" ", "") + "Projects" return userHome.replace('/', File.separatorChar) + File.separator + productName.replace(" ", "") + "Projects"
} }
companion object {
private const val DEFAULT_GROUP_ID = "me.user"
}
} }
class ModuleNewWizardSecondStep( class ModuleNewWizardSecondStep(
wizard: IdeWizard, wizard: IdeWizard,
uiEditorUsagesStats: UiEditorUsageStats uiEditorUsagesStats: UiEditorUsageStats,
private val wizardContext: WizardContext
) : WizardStep(wizard, GenerationPhase.SECOND_STEP) { ) : WizardStep(wizard, GenerationPhase.SECOND_STEP) {
private val component = SecondStepWizardComponent(wizard, uiEditorUsagesStats) private val component = SecondStepWizardComponent(wizard, uiEditorUsagesStats)
override fun getComponent(): JComponent = component.component override fun getComponent(): JComponent = component.component
@@ -259,7 +222,22 @@ class ModuleNewWizardSecondStep(
component.onInit() component.onInit()
} }
override fun getPreferredFocusedComponent(): JComponent? {
wizardContext.getActionButtonWithText("Next")?.apply {
text = "Finish"
updateUI()
}
return super.getPreferredFocusedComponent()
}
override fun handleErrors(error: ValidationResult.ValidationError) { override fun handleErrors(error: ValidationResult.ValidationError) {
component.navigateTo(error) component.navigateTo(error)
} }
} }
private fun WizardContext.getActionButtonWithText(text: String, alternativeText: String? = null): JButton? =
wizard?.cancelButton?.parent?.components?.find { child ->
child.safeAs<JButton>()?.let { button ->
button.text == text || alternativeText != null && button.text == alternativeText
} == true
} as? JButton
@@ -22,6 +22,10 @@ abstract class Component : Displayable, ErrorNavigatable {
this@Component.subComponents += it this@Component.subComponents += it
} }
protected fun clearSubComponents() {
subComponents.clear()
}
override fun navigateTo(error: ValidationResult.ValidationError) { override fun navigateTo(error: ValidationResult.ValidationError) {
subComponents.forEach { it.navigateTo(error) } subComponents.forEach { it.navigateTo(error) }
} }
@@ -1,40 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui
import com.intellij.ui.components.panels.VerticalLayout
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.StringSettingComponent
import javax.swing.Box
import javax.swing.JSeparator
import javax.swing.SwingConstants
class PomWizardStepComponent(context: Context) : WizardStepComponent(context) {
private val groupIdComponent = StringSettingComponent(
StructurePlugin::groupId.reference,
context,
needLabel = true
).asSubComponent()
private val artifactIdComponent = StringSettingComponent(
StructurePlugin::artifactId.reference,
context,
needLabel = true
).asSubComponent()
private val versionComponent = StringSettingComponent(
StructurePlugin::version.reference,
context,
needLabel = true
).asSubComponent()
override val component = panel(VerticalLayout(0)) {
add(Box.createVerticalStrut(10))
add(JSeparator(SwingConstants.HORIZONTAL))
add(Box.createVerticalStrut(10))
add(groupIdComponent.component)
add(artifactIdComponent.component)
add(versionComponent.component)
}
}
@@ -11,7 +11,7 @@ abstract class SubStep(
protected abstract fun buildContent(): JComponent protected abstract fun buildContent(): JComponent
final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel { customPanel {
add(buildContent(), BorderLayout.CENTER) add(buildContent(), BorderLayout.CENTER)
} }
} }
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent 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.FocusableComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.customPanel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.IdeaBasedComponentValidator import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.IdeaBasedComponentValidator
import java.awt.BorderLayout import java.awt.BorderLayout
import javax.swing.JComponent import javax.swing.JComponent
@@ -57,7 +57,7 @@ abstract class UIComponent<V : Any>(
} }
final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel { customPanel {
labelText?.let { add(label("$it:"), BorderLayout.NORTH) } labelText?.let { add(label("$it:"), BorderLayout.NORTH) }
add(uiComponent, BorderLayout.CENTER) add(uiComponent, BorderLayout.CENTER)
} }
@@ -1,8 +1,14 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import com.intellij.icons.AllIcons
import com.intellij.ui.JBColor import com.intellij.ui.JBColor
import com.intellij.ui.TitledSeparator
import com.intellij.ui.layout.panel
import com.intellij.util.io.size
import com.intellij.util.ui.JBUI import com.intellij.util.ui.JBUI
import com.intellij.util.ui.components.BorderLayoutPanel
import org.jetbrains.kotlin.tools.projectWizard.core.Context import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.path
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference 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.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
@@ -12,6 +18,8 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.JComponent import javax.swing.JComponent
class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.context) { class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.context) {
@@ -28,6 +36,7 @@ class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.c
class ProjectSettingsComponent(context: Context) : DynamicComponent(context) { class ProjectSettingsComponent(context: Context) : DynamicComponent(context) {
private val projectTemplateComponent = ProjectTemplateSettingComponent(context).asSubComponent() private val projectTemplateComponent = ProjectTemplateSettingComponent(context).asSubComponent()
private val buildSystemSetting = BuildSystemTypeSettingComponent(context).asSubComponent() private val buildSystemSetting = BuildSystemTypeSettingComponent(context).asSubComponent()
private val buildSystemAdditionalSettingsComponent = BuildSystemAdditionalSettingsComponent(context).asSubComponent()
private val nameAndLocationComponent = TitledComponentsList( private val nameAndLocationComponent = TitledComponentsList(
listOf( listOf(
@@ -40,12 +49,89 @@ class ProjectSettingsComponent(context: Context) : DynamicComponent(context) {
).asSubComponent() ).asSubComponent()
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
nameAndLocationComponent.component.apply { panel {
row {
nameAndLocationComponent.component(growX)
}
row {
buildSystemAdditionalSettingsComponent.component(growX)
}
}.apply {
border = JBUI.Borders.empty(10) border = JBUI.Borders.empty(10)
} }
} }
private var locationWasUpdatedByHand: Boolean = false
private var artifactIdWasUpdatedByHand: Boolean = false
override fun onValueUpdated(reference: SettingReference<*, *>?) {
super.onValueUpdated(reference)
when (reference?.path) {
StructurePlugin::name.path -> {
tryUpdateLocationByProjectName()
tryArtifactIdByProjectName()
}
StructurePlugin::artifactId.path -> {
artifactIdWasUpdatedByHand = true
}
StructurePlugin::projectPath.path -> {
locationWasUpdatedByHand = true
}
}
}
private fun tryUpdateLocationByProjectName() {
if (!locationWasUpdatedByHand) {
val location = read { StructurePlugin::projectPath.settingValue }
if (location.parent != null) modify {
StructurePlugin::projectPath.reference.setValue(location.parent.resolve(StructurePlugin::name.settingValue))
locationWasUpdatedByHand = false
}
}
}
private fun tryArtifactIdByProjectName() {
if (!artifactIdWasUpdatedByHand) modify {
StructurePlugin::artifactId.reference.setValue(StructurePlugin::name.settingValue)
artifactIdWasUpdatedByHand = false
}
}
} }
class BuildSystemAdditionalSettingsComponent(context: Context) : DynamicComponent(context) {
private val settingsList = TitledComponentsList(
listOf(
StructurePlugin::groupId.reference.createSettingComponent(context),
StructurePlugin::artifactId.reference.createSettingComponent(context),
StructurePlugin::version.reference.createSettingComponent(context)
),
context
).asSubComponent()
override val component: JComponent = HideableSection("Artifact Coordinates", settingsList.component)
}
@Suppress("SpellCheckingInspection")
private class HideableSection(text: String, private val component: JComponent) : BorderLayoutPanel() {
private val titledSeparator = TitledSeparator(text)
private var isExpanded = false
init {
addToTop(titledSeparator)
addToCenter(component)
update(isExpanded)
addMouseListener(object : MouseAdapter() {
override fun mouseReleased(e: MouseEvent) = update(!isExpanded)
})
}
private fun update(isExpanded: Boolean) {
this.isExpanded = isExpanded
component.isVisible = this.isExpanded
titledSeparator.label.icon = if (this.isExpanded) AllIcons.General.ArrowDown else AllIcons.General.ArrowRight
}
}
class ProjectPreviewComponent(context: Context) : DynamicComponent(context) { class ProjectPreviewComponent(context: Context) : DynamicComponent(context) {
private val modulesEditorComponent = ModulesEditorComponent( private val modulesEditorComponent = ModulesEditorComponent(
@@ -5,7 +5,6 @@ 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.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Sourceset
import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.* import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
@@ -62,7 +61,7 @@ class ModuleSettingsSubStep(
ModuleSettingsComponent(wizard.context, uiEditorUsagesStats).asSubComponent() ModuleSettingsComponent(wizard.context, uiEditorUsagesStats).asSubComponent()
private val nothingSelectedComponent = NothingSelectedComponent().asSubComponent() private val nothingSelectedComponent = NothingSelectedComponent().asSubComponent()
private val panel = panel { private val panel = customPanel {
add(nothingSelectedComponent.component, BorderLayout.CENTER) add(nothingSelectedComponent.component, BorderLayout.CENTER)
} }
@@ -62,7 +62,7 @@ class SourcesetDependenciesSettingsComponent(
} }
} }
override val component = panel { override val component = customPanel {
add(toolbarDecorator.createPanelWithPopupHandler(sourcesetDependenciesList), BorderLayout.CENTER) add(toolbarDecorator.createPanelWithPopupHandler(sourcesetDependenciesList), BorderLayout.CENTER)
} }
} }
@@ -76,7 +76,7 @@ private class ChooseModuleDialog(modules: List<Module>, parent: JComponent) : Di
} }
).bordered(needTopEmptyBorder = false, needBottomEmptyBorder = false) ).bordered(needTopEmptyBorder = false, needBottomEmptyBorder = false)
override fun createCenterPanel() = panel { override fun createCenterPanel() = customPanel {
preferredSize = Dimension(preferredSize.width, 300) preferredSize = Dimension(preferredSize.width, 300)
add( add(
label("Please select the modules to add as dependencies:") label("Please select the modules to add as dependencies:")
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ProjectKind import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ProjectKind
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.customPanel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
import java.awt.BorderLayout import java.awt.BorderLayout
@@ -74,7 +74,7 @@ class ModulesEditorComponent(
) else null ) else null
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel { customPanel {
if (needBorder) { if (needBorder) {
border = BorderFactory.createLineBorder(JBColor.border()) border = BorderFactory.createLineBorder(JBColor.border())
} }
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownCom
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.PathFieldComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.PathFieldComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.customPanel
import java.awt.BorderLayout import java.awt.BorderLayout
import java.awt.event.ItemEvent import java.awt.event.ItemEvent
import java.nio.file.Path import java.nio.file.Path
@@ -87,9 +87,9 @@ class VersionSettingComponent(
override val validationIndicator = null override val validationIndicator = null
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel { customPanel {
add( add(
panel { customPanel {
add(settingLabel, BorderLayout.CENTER) add(settingLabel, BorderLayout.CENTER)
}, },
BorderLayout.WEST BorderLayout.WEST
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting
import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.kotlin.tools.projectWizard.core.Context 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.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType
@@ -33,5 +34,16 @@ abstract class UIComponentDelegatingSettingComponent<V : Any, T : SettingType<V>
uiComponent.focusOn() uiComponent.focusOn()
} }
override fun onValueUpdated(reference: SettingReference<*, *>?) {
super.onValueUpdated(reference)
if (reference == this.reference) {
ApplicationManager.getApplication().invokeLater {
if (uiComponent.getUiValue() != value) {
value?.let(uiComponent::updateUiValue)
}
}
}
}
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { uiComponent.component } override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { uiComponent.component }
} }
@@ -40,7 +40,7 @@ internal inline fun label(text: String, bold: Boolean = false, init: JBLabel.()
init() init()
} }
inline fun panel(layout: LayoutManager = BorderLayout(), init: JPanel.() -> Unit = {}) = JPanel(layout).apply(init) inline fun customPanel(layout: LayoutManager = BorderLayout(), init: JPanel.() -> Unit = {}) = JPanel(layout).apply(init)
inline fun borderPanel(init: BorderLayoutPanel.() -> Unit = {}) = BorderLayoutPanel().apply(init) inline fun borderPanel(init: BorderLayoutPanel.() -> Unit = {}) = BorderLayoutPanel().apply(init)
@@ -13,24 +13,24 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import java.nio.file.Paths import java.nio.file.Paths
class StructurePlugin(context: Context) : Plugin(context) { class StructurePlugin(context: Context) : Plugin(context) {
val projectPath by pathSetting("Location", GenerationPhase.PROJECT_GENERATION) { val projectPath by pathSetting("Location", GenerationPhase.FIRST_STEP) {
defaultValue = value(Paths.get(".")) defaultValue = value(Paths.get("."))
} }
val name by stringSetting("Name", GenerationPhase.PROJECT_GENERATION) { val name by stringSetting("Name", GenerationPhase.FIRST_STEP) {
shouldNotBeBlank() shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Name", Module.ALLOWED_SPECIAL_CHARS_IN_MODULE_NAMES)) validate(StringValidators.shouldBeValidIdentifier("Name", Module.ALLOWED_SPECIAL_CHARS_IN_MODULE_NAMES))
} }
val groupId by stringSetting("Group ID", GenerationPhase.PROJECT_GENERATION) { val groupId by stringSetting("Group ID", GenerationPhase.FIRST_STEP) {
isSavable = true isSavable = true
shouldNotBeBlank() shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Group ID", setOf('.', '_'))) validate(StringValidators.shouldBeValidIdentifier("Group ID", setOf('.', '_')))
} }
val artifactId by stringSetting("Artifact ID", GenerationPhase.PROJECT_GENERATION) { val artifactId by stringSetting("Artifact ID", GenerationPhase.FIRST_STEP) {
shouldNotBeBlank() shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Artifact ID", setOf('_'))) validate(StringValidators.shouldBeValidIdentifier("Artifact ID", setOf('_')))
} }
val version by stringSetting("Version", GenerationPhase.PROJECT_GENERATION) { val version by stringSetting("Version", GenerationPhase.FIRST_STEP) {
shouldNotBeBlank() shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Version", setOf('_', '-', '.'))) validate(StringValidators.shouldBeValidIdentifier("Version", setOf('_', '-', '.')))
defaultValue = value("1.0-SNAPSHOT") defaultValue = value("1.0-SNAPSHOT")