diff --git a/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java b/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java index 84162fffbe10..0ec64a0a9704 100644 --- a/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java +++ b/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java @@ -16,4 +16,5 @@ public final class JavaUIIcons { } /** 16x16 */ public static final @NotNull Icon IdeaUltimatePromoSmall = load("icons/idea-ultimate-promo-small.svg", -1976155593, 0); /** 40x40 */ public static final @NotNull Icon IdeaUltimatePromo = load("icons/idea-ultimate-promo.svg", -28146501, 0); + /** 16x16 */ public static final @NotNull Icon SpringPromo = load("icons/spring-promo.svg", -1690195316, 0); } diff --git a/java/idea-ui/resources/JavaUIIconsMapping.json b/java/idea-ui/resources/JavaUIIconsMapping.json new file mode 100644 index 000000000000..9be25952cbb4 --- /dev/null +++ b/java/idea-ui/resources/JavaUIIconsMapping.json @@ -0,0 +1,7 @@ +{ + "icons": { + "newui": { + "spring-promo.svg": "icons/spring-promo.svg" + } + } +} \ No newline at end of file diff --git a/java/idea-ui/resources/icons/newui/icon-robots.txt b/java/idea-ui/resources/icons/newui/icon-robots.txt new file mode 100644 index 000000000000..f21601437b7f --- /dev/null +++ b/java/idea-ui/resources/icons/newui/icon-robots.txt @@ -0,0 +1 @@ +skip: * \ No newline at end of file diff --git a/java/idea-ui/resources/icons/newui/spring-promo.svg b/java/idea-ui/resources/icons/newui/spring-promo.svg new file mode 100644 index 000000000000..3720dbba641d --- /dev/null +++ b/java/idea-ui/resources/icons/newui/spring-promo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/java/idea-ui/resources/icons/newui/spring-promo_dark.svg b/java/idea-ui/resources/icons/newui/spring-promo_dark.svg new file mode 100644 index 000000000000..dd6f33231b14 --- /dev/null +++ b/java/idea-ui/resources/icons/newui/spring-promo_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/java/idea-ui/resources/icons/spring-promo.svg b/java/idea-ui/resources/icons/spring-promo.svg new file mode 100644 index 000000000000..b311081854eb --- /dev/null +++ b/java/idea-ui/resources/icons/spring-promo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/java/idea-ui/resources/messages/JavaUiBundle.properties b/java/idea-ui/resources/messages/JavaUiBundle.properties index 40abc7d10f10..ddf0e41f92fa 100644 --- a/java/idea-ui/resources/messages/JavaUiBundle.properties +++ b/java/idea-ui/resources/messages/JavaUiBundle.properties @@ -711,4 +711,11 @@ action.PromoEndpoints.text=Endpoints action.PromoDatabase.text=Database action.PromoKubernetes.text=Kubernetes action.PromoPersistence.text=Persistence -action.PromoProfiler.text=IntelliJ Profiler \ No newline at end of file +action.PromoProfiler.text=IntelliJ Profiler + +feature.spring.wizard.description=Spring Boot integration is available in IntelliJ IDEA Ultimate +feature.spring.description.html=Use a rich set of built-in developer tools and support for the Spring framework in both Java and Kotlin code, including Spring MVC, Spring Data, Spring Security, and Spring Cloud: +feature.spring.run.config=Dedicated run configuration +feature.spring.config.files=Rich configuration files support +feature.spring.data=JPA and SQL code assistance +feature.spring.navigation=Advanced navigation and visualization diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index 8c20973ca7bd..e25b635f0749 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -3,6 +3,7 @@ package com.intellij.ide.projectWizard; import com.intellij.diagnostic.PluginException; import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider; +import com.intellij.icons.AllIcons; import com.intellij.ide.JavaUiBundle; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.frameworkSupport.FrameworkRole; @@ -554,8 +555,9 @@ public final class ProjectTypeStep extends ModuleWizardStep implements SettingsS myContext.setProjectBuilder(builder); step.updateStep(); + JComponent component = step.getComponent(); - if (isNewWizard()) { + if (isNewWizard() && !(builder instanceof PromoModuleBuilder)) { component = new JBScrollPane(component); component.setBorder(JBUI.Borders.empty()); } @@ -932,6 +934,17 @@ public final class ProjectTypeStep extends ModuleWizardStep implements SettingsS }); } + @Override + public Component getListCellRendererComponent(JList list, + TemplatesGroup value, + int index, + boolean isSelected, + boolean cellHasFocus) { + Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + myNextStepLabel.setIcon(value.isPromo() ? AllIcons.Ultimate.Lock : null); + return component; + } + @Override protected JComponent createItemComponent() { JComponent component = super.createItemComponent(); diff --git a/java/idea-ui/src/com/intellij/ide/ultimatepromo/PromoSpringModuleBuilder.kt b/java/idea-ui/src/com/intellij/ide/ultimatepromo/PromoSpringModuleBuilder.kt new file mode 100644 index 000000000000..c06a60709353 --- /dev/null +++ b/java/idea-ui/src/com/intellij/ide/ultimatepromo/PromoSpringModuleBuilder.kt @@ -0,0 +1,78 @@ +// 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.ultimatepromo + +import com.intellij.icons.AllIcons +import com.intellij.ide.JavaUiBundle +import com.intellij.ide.util.projectWizard.* +import com.intellij.ide.wizard.withVisualPadding +import com.intellij.java.ui.icons.JavaUIIcons +import com.intellij.openapi.Disposable +import com.intellij.openapi.extensions.PluginId +import com.intellij.openapi.module.ModuleType +import com.intellij.openapi.module.StdModuleTypes +import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.* +import com.intellij.openapi.util.NlsSafe +import javax.swing.Icon +import javax.swing.JComponent + +@NlsSafe +private const val SPRING_NAME = "Spring" +private const val SPRING_PLUGIN_ID = "com.intellij.spring" + +internal class PromoSpringModuleBuilder: ModuleBuilder(), PromoModuleBuilder { + override fun getModuleType(): ModuleType<*> = StdModuleTypes.JAVA + override fun getWeight(): Int = JVM_WEIGHT + + override fun getBuilderId(): String = "promo-spring" + override fun getNodeIcon(): Icon = JavaUIIcons.SpringPromo + override fun getPresentableName(): String = SPRING_NAME + override fun getDescription(): String = JavaUiBundle.message("feature.spring.wizard.description") + + override fun modifyProjectTypeStep(settingsStep: SettingsStep): ModuleWizardStep? = null + + override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?): ModuleWizardStep { + return object : ModuleWizardStep() { + private val panel: JComponent = PromoPages.build( + PromoFeaturePage( + JavaUIIcons.IdeaUltimatePromo, + PluginAdvertiserService.ideaUltimate, + JavaUiBundle.message("feature.spring.description.html"), + listOf( + PromoFeatureListItem( + AllIcons.RunConfigurations.Application, + JavaUiBundle.message("feature.spring.run.config") + ), + PromoFeatureListItem( + AllIcons.FileTypes.Properties, + JavaUiBundle.message("feature.spring.config.files") + ), + PromoFeatureListItem( + AllIcons.Nodes.DataTables, + JavaUiBundle.message("feature.spring.data") + ), + PromoFeatureListItem( + AllIcons.FileTypes.Diagram, + JavaUiBundle.message("feature.spring.navigation") + ) + ), + FeaturePromoBundle.message("free.trial.hint"), + SPRING_PLUGIN_ID + ), + FUSEventSource.NEW_PROJECT_WIZARD + ).withVisualPadding() + + override fun updateDataModel(): Unit = Unit + override fun getComponent(): JComponent = panel + override fun validate(): Boolean { + FUSEventSource.NEW_PROJECT_WIZARD.openDownloadPageAndLog(null, PluginAdvertiserService.ideaUltimate.downloadUrl, + PluginId.getId(SPRING_PLUGIN_ID)) + + return false + } + + override fun updateStep() { + FUSEventSource.NEW_PROJECT_WIZARD.logPluginSuggested(null, PluginId.getId(SPRING_PLUGIN_ID)) + } + } + } +} \ No newline at end of file diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java index 482ee9fb6ba8..411643da61bc 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java @@ -3,6 +3,7 @@ package com.intellij.ide.util.newProjectWizard; import com.intellij.ide.projectWizard.ProjectCategory; import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.ide.util.projectWizard.PromoModuleBuilder; import com.intellij.internal.statistic.utils.PluginInfo; import com.intellij.internal.statistic.utils.PluginInfoDetectorKt; import com.intellij.openapi.util.Comparing; @@ -121,4 +122,8 @@ public final class TemplatesGroup implements Comparable { public void setPluginInfo(PluginInfo pluginInfo) { myPluginInfo = pluginInfo; } + + public boolean isPromo() { + return myModuleBuilder instanceof PromoModuleBuilder; + } } diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 8ab8d0674528..1f7ea6f7c4a4 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -2449,6 +2449,8 @@ + + diff --git a/java/java-impl/src/META-INF/community-integration.xml b/java/java-impl/src/META-INF/community-integration.xml index ea61da89cb40..cdc616f6e275 100644 --- a/java/java-impl/src/META-INF/community-integration.xml +++ b/java/java-impl/src/META-INF/community-integration.xml @@ -7,6 +7,8 @@ provider="com.intellij.ide.ultimatepromo.PromoDatabaseConfigurableProvider" bundle="messages.FeaturePromoBundle" key="promo.configurable.database"/> + + diff --git a/platform/icons/src/PlatformIconMappings.json b/platform/icons/src/PlatformIconMappings.json index ad1eef3a096c..889da5370130 100644 --- a/platform/icons/src/PlatformIconMappings.json +++ b/platform/icons/src/PlatformIconMappings.json @@ -823,6 +823,9 @@ "createNewProjectTab.svg": "welcome/createNewProjectTab.svg", "fromVCSTab.svg": "welcome/fromVCSTab.svg", "open.svg": "welcome/open.svg" + }, + "ultimate": { + "lock.svg": "ultimate/lock.svg" } } } \ No newline at end of file diff --git a/platform/icons/src/expui/ultimate/lock.svg b/platform/icons/src/expui/ultimate/lock.svg new file mode 100644 index 000000000000..b490a3af6f08 --- /dev/null +++ b/platform/icons/src/expui/ultimate/lock.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/platform/icons/src/expui/ultimate/lock_dark.svg b/platform/icons/src/expui/ultimate/lock_dark.svg new file mode 100644 index 000000000000..ca289eb723f3 --- /dev/null +++ b/platform/icons/src/expui/ultimate/lock_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/platform/icons/src/ultimate/lock.svg b/platform/icons/src/ultimate/lock.svg index b490a3af6f08..fa17e7ef987a 100644 --- a/platform/icons/src/ultimate/lock.svg +++ b/platform/icons/src/ultimate/lock.svg @@ -1,11 +1,7 @@ - - - - - - - - - - + + + + + + diff --git a/platform/icons/src/ultimate/lock_dark.svg b/platform/icons/src/ultimate/lock_dark.svg index ca289eb723f3..bd4b55db07dc 100644 --- a/platform/icons/src/ultimate/lock_dark.svg +++ b/platform/icons/src/ultimate/lock_dark.svg @@ -1,11 +1,4 @@ - - - - - - - - - - + + + diff --git a/platform/lang-core/src/com/intellij/ide/util/projectWizard/PromoModuleBuilder.java b/platform/lang-core/src/com/intellij/ide/util/projectWizard/PromoModuleBuilder.java new file mode 100644 index 000000000000..aaf39f1f9b08 --- /dev/null +++ b/platform/lang-core/src/com/intellij/ide/util/projectWizard/PromoModuleBuilder.java @@ -0,0 +1,5 @@ +// 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.util.projectWizard; + +public interface PromoModuleBuilder { +} diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/FUSEventSource.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/FUSEventSource.kt index 92a1ff9a5b7c..f8d79f85e1a3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/FUSEventSource.kt +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/FUSEventSource.kt @@ -17,7 +17,7 @@ class PluginAdvertiserUsageCollector : CounterUsagesCollector() { private const val FUS_GROUP_ID = "plugins.advertiser" -private val GROUP = EventLogGroup(FUS_GROUP_ID, 8) +private val GROUP = EventLogGroup(FUS_GROUP_ID, 9) private val SOURCE_FIELD = EventFields.Enum( "source", @@ -91,6 +91,7 @@ enum class FUSEventSource { PLUGINS_SUGGESTED_GROUP, ACTIONS, SETTINGS, + NEW_PROJECT_WIZARD, @Deprecated("Use PLUGINS_SEARCH instead") SEARCH; diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/promoPages.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/promoPages.kt index 71d646ed625c..f5f54b04e825 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/promoPages.kt +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/promoPages.kt @@ -4,12 +4,10 @@ package com.intellij.openapi.updateSettings.impl.pluginsAdvertisement import com.intellij.icons.AllIcons import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI import com.intellij.openapi.extensions.PluginId +import com.intellij.openapi.ui.DialogPanel import com.intellij.openapi.util.NlsContexts import com.intellij.ui.ClientProperty -import com.intellij.ui.dsl.builder.BottomGap -import com.intellij.ui.dsl.builder.RightGap -import com.intellij.ui.dsl.builder.RowLayout -import com.intellij.ui.dsl.builder.panel +import com.intellij.ui.dsl.builder.* import com.intellij.util.ui.JBFont import javax.swing.Icon import javax.swing.JComponent @@ -30,7 +28,11 @@ class PromoFeatureListItem( ) object PromoPages { - fun build(page: PromoFeaturePage): JComponent { + fun build(page: PromoFeaturePage): DialogPanel { + return build(page, FUSEventSource.SETTINGS) + } + + fun build(page: PromoFeaturePage, source: FUSEventSource): DialogPanel { val panel = panel { row { icon(page.productIcon) @@ -45,7 +47,7 @@ object PromoPages { cell() text(page.descriptionHtml) { - FUSEventSource.SETTINGS.learnMoreAndLog(null, it.url.toExternalForm(), page.pluginId?.let(PluginId::getId)) + source.learnMoreAndLog(null, it.url.toExternalForm(), page.pluginId?.let(PluginId::getId)) } }.layout(RowLayout.PARENT_GRID) diff --git a/platform/util/ui/src/com/intellij/icons/AllIcons.java b/platform/util/ui/src/com/intellij/icons/AllIcons.java index b32c816286ac..e1703b868899 100644 --- a/platform/util/ui/src/com/intellij/icons/AllIcons.java +++ b/platform/util/ui/src/com/intellij/icons/AllIcons.java @@ -1209,7 +1209,7 @@ public class AllIcons { } public static final class Ultimate { - /** 16x16 */ public static final @NotNull Icon Lock = load("ultimate/lock.svg", 26662807, 2); + /** 16x16 */ public static final @NotNull Icon Lock = load("ultimate/lock.svg", 2079176291, 2); /** 16x16 */ public static final @NotNull Icon LockWhite = load("ultimate/lockWhite.svg", -1751542808, 0); } diff --git a/platform/util/ui/src/com/intellij/icons/ExpUiIcons.java b/platform/util/ui/src/com/intellij/icons/ExpUiIcons.java index e021cb552901..a6c81470e758 100644 --- a/platform/util/ui/src/com/intellij/icons/ExpUiIcons.java +++ b/platform/util/ui/src/com/intellij/icons/ExpUiIcons.java @@ -701,6 +701,10 @@ public final class ExpUiIcons { /** 20x20 */ public static final @NotNull Icon Web_20x20 = load("expui/toolwindow/web@20x20.svg", 1824952426, 2); } + public static final class Ultimate { + /** 16x16 */ public static final @NotNull Icon Lock = load("expui/ultimate/lock.svg", 26662807, 2); + } + public static final class Vcs { /** 16x16 */ public static final @NotNull Icon BranchLabel = load("expui/vcs/branchLabel.svg", 2143717139, 2); /** 16x16 */ public static final @NotNull Icon Changelist = load("expui/vcs/changelist.svg", -1628126378, 2);