diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt
index 8bafbaa15dbe..de5b764be162 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt
@@ -79,7 +79,7 @@ sealed interface PluginAdvertiserService {
@Suppress("HardCodedStringLiteral", "DialogTitleCapitalization")
val pyCharmProfessional: SuggestedIde = SuggestedIde(
- name = "PyCharm",
+ name = "PyCharm Pro",
productCode = "PY",
defaultDownloadUrl = "https://www.jetbrains.com/pycharm/download/",
platformSpecificDownloadUrlTemplate = "https://www.jetbrains.com/pycharm/download/download-thanks.html?platform={type}",
diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/advertiser/PluginsAdvertiserTest.kt b/platform/platform-tests/testSrc/com/intellij/ide/plugins/advertiser/PluginsAdvertiserTest.kt
index f5b9415516fa..8347ee06a284 100644
--- a/platform/platform-tests/testSrc/com/intellij/ide/plugins/advertiser/PluginsAdvertiserTest.kt
+++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/advertiser/PluginsAdvertiserTest.kt
@@ -61,7 +61,7 @@ class PluginsAdvertiserTest {
fun suggestedIdeInPyCharmCommunity() = runBlocking {
preparePluginCache("*.js" to PluginData("JavaScript"))
val suggestion = getSuggestionData(projectRule.project, "PC", "foo.js", PlainTextFileType.INSTANCE)
- assertEquals(listOf("PyCharm"), suggestion!!.suggestedIdes.map { it.name })
+ assertEquals(listOf("PyCharm Pro"), suggestion!!.suggestedIdes.map { it.name })
}
@Test
diff --git a/python/ide/customization.shared/BUILD.bazel b/python/ide/customization.shared/BUILD.bazel
index f9a0b99b0f6b..c7b274bce458 100644
--- a/python/ide/customization.shared/BUILD.bazel
+++ b/python/ide/customization.shared/BUILD.bazel
@@ -9,11 +9,15 @@ jvm_resources(
jvm_library(
name = "customization.shared",
+ module_name = "intellij.pycharm.community.customization.shared",
visibility = ["//visibility:public"],
- srcs = glob([], allow_empty = True),
+ srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True),
+ deps = [
+ "//python/ide/impl",
+ "//platform/platform-impl:ide-impl",
+ ],
runtime_deps = [
":customization.shared_resources",
- "//python/ide/impl",
"//python/ide/implTraining/intellij.pycharm.community.ide.implTraining:pycharm-community-ide-implTraining",
"//platform/whatsNew",
]
diff --git a/python/ide/customization.shared/intellij.pycharm.community.customization.shared.iml b/python/ide/customization.shared/intellij.pycharm.community.customization.shared.iml
index 6be4b843f212..57f1d319c855 100644
--- a/python/ide/customization.shared/intellij.pycharm.community.customization.shared.iml
+++ b/python/ide/customization.shared/intellij.pycharm.community.customization.shared.iml
@@ -4,11 +4,13 @@
+
-
+
+
\ No newline at end of file
diff --git a/python/ide/customization.shared/src/com/intellij/pycharm/community/customization/shared/djangoPromoFeatureList.kt b/python/ide/customization.shared/src/com/intellij/pycharm/community/customization/shared/djangoPromoFeatureList.kt
new file mode 100644
index 000000000000..34d7bd58a831
--- /dev/null
+++ b/python/ide/customization.shared/src/com/intellij/pycharm/community/customization/shared/djangoPromoFeatureList.kt
@@ -0,0 +1,11 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.pycharm.community.customization.shared // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+import com.intellij.icons.AllIcons
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoFeatureListItem
+import com.intellij.pycharm.community.ide.impl.PyCharmCommunityCustomizationBundle
+
+val djangoPromoFeatureList: List = listOf(
+ PromoFeatureListItem(AllIcons.Actions.ReformatCode, PyCharmCommunityCustomizationBundle.message("feature.django.code")),
+ PromoFeatureListItem(AllIcons.FileTypes.Html, PyCharmCommunityCustomizationBundle.message("feature.django.djangoTemplates")),
+ PromoFeatureListItem(AllIcons.General.Web, PyCharmCommunityCustomizationBundle.message("feature.django.endpoints"))
+)
\ No newline at end of file
diff --git a/python/ide/customization.shared/src/com/intellij/pycharm/community/customization/shared/javaScriptPromoFeatureList.kt b/python/ide/customization.shared/src/com/intellij/pycharm/community/customization/shared/javaScriptPromoFeatureList.kt
new file mode 100644
index 000000000000..ed27823d253e
--- /dev/null
+++ b/python/ide/customization.shared/src/com/intellij/pycharm/community/customization/shared/javaScriptPromoFeatureList.kt
@@ -0,0 +1,12 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.pycharm.community.customization.shared // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+import com.intellij.icons.AllIcons
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.FeaturePromoBundle
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoFeatureListItem
+
+val javaScriptPromoFeatureList: List = listOf(
+ PromoFeatureListItem(AllIcons.Actions.ReformatCode, FeaturePromoBundle.message("feature.javascript.code")),
+ PromoFeatureListItem(AllIcons.Actions.SuggestedRefactoringBulb, FeaturePromoBundle.message("feature.javascript.refactor")),
+ @Suppress("DialogTitleCapitalization") // Properly capitalized, React and Vue are names.
+ PromoFeatureListItem(AllIcons.FileTypes.UiForm, FeaturePromoBundle.message("feature.javascript.frameworks"))
+)
\ No newline at end of file
diff --git a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/BUILD.bazel b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/BUILD.bazel
index 3c7392afdbea..48886254c52f 100644
--- a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/BUILD.bazel
+++ b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/BUILD.bazel
@@ -25,6 +25,7 @@ jvm_library(
"//platform/statistics",
"@lib//:http-client",
"//platform/core-ui",
+ "//python/ide/customization.shared",
],
runtime_deps = [":pycharm-community-ide-impl-promotion_resources"]
)
diff --git a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/intellij.pycharm.community.ide.impl.promotion.iml b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/intellij.pycharm.community.ide.impl.promotion.iml
index 90e38dc9c626..621f1f51abe6 100644
--- a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/intellij.pycharm.community.ide.impl.promotion.iml
+++ b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/intellij.pycharm.community.ide.impl.promotion.iml
@@ -20,5 +20,6 @@
+
\ No newline at end of file
diff --git a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/djangoProject.kt b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/djangoProject.kt
index ccc8e6dcc8d5..f953a49fcfe2 100644
--- a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/djangoProject.kt
+++ b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/djangoProject.kt
@@ -8,6 +8,7 @@ import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginAdver
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoFeaturePage
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoPages
import com.intellij.openapi.util.NlsSafe
+import com.intellij.pycharm.community.customization.shared.djangoPromoFeatureList
import com.intellij.pycharm.community.ide.impl.PyCharmCommunityCustomizationBundle
import com.jetbrains.python.icons.PythonIcons
import com.jetbrains.python.newProjectWizard.promotion.PromoProjectGenerator
diff --git a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/featurePages.kt b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/featurePages.kt
index d5468dcfdbcf..393469eb83af 100644
--- a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/featurePages.kt
+++ b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/featurePages.kt
@@ -4,13 +4,17 @@ package com.intellij.pycharm.community.ide.impl.promotion
import com.intellij.icons.AllIcons
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.*
import com.intellij.openapi.util.NlsContexts
+import com.intellij.pycharm.community.customization.shared.djangoPromoFeatureList
+import com.intellij.pycharm.community.customization.shared.javaScriptPromoFeatureList
import com.intellij.pycharm.community.ide.impl.PyCharmCommunityCustomizationBundle
import com.jetbrains.python.icons.PythonIcons
import javax.swing.JComponent
-private fun featurePage(@NlsContexts.Label title: String, items: List,
- source: PromoEventSource,
- topic: PromoTopic): JComponent {
+private fun featurePage(
+ @NlsContexts.Label title: String, items: List,
+ source: PromoEventSource,
+ topic: PromoTopic,
+): JComponent {
val page = PromoFeaturePage(
productIcon = PythonIcons.Python.Pycharm,
suggestedIde = PluginAdvertiserService.pyCharmProfessional,
@@ -39,7 +43,6 @@ internal fun databaseFeatures(source: PromoEventSource): JComponent = featurePag
)
internal fun javascriptFeatures(source: PromoEventSource, promoTopic: PromoTopic): JComponent {
- @Suppress("DialogTitleCapitalization")
return featurePage(
FeaturePromoBundle.message("feature.javascript.description.html",
"https://www.jetbrains.com/help/pycharm/javascript-specific-guidelines.html"),
@@ -59,7 +62,6 @@ internal fun djangoFeatures(source: PromoEventSource): JComponent {
)
}
-
internal fun jupyterFeatures(source: PromoEventSource): JComponent {
return featurePage(
PyCharmCommunityCustomizationBundle.message("feature.jupyter.description.html",
@@ -87,16 +89,4 @@ internal fun sshFeatures(source: PromoEventSource): JComponent {
source,
PromoTopic.RemoteSSH
)
-}
-
-internal val djangoPromoFeatureList = listOf(
- PromoFeatureListItem(AllIcons.Actions.ReformatCode, PyCharmCommunityCustomizationBundle.message("feature.django.code")),
- PromoFeatureListItem(AllIcons.FileTypes.Html, PyCharmCommunityCustomizationBundle.message("feature.django.djangoTemplates")),
- PromoFeatureListItem(AllIcons.General.Web, PyCharmCommunityCustomizationBundle.message("feature.django.endpoints"))
-)
-
-internal val javaScriptPromoFeatureList = listOf(
- PromoFeatureListItem(AllIcons.Actions.ReformatCode, FeaturePromoBundle.message("feature.javascript.code")),
- PromoFeatureListItem(AllIcons.Actions.SuggestedRefactoringBulb, FeaturePromoBundle.message("feature.javascript.refactor")),
- PromoFeatureListItem(AllIcons.FileTypes.UiForm, FeaturePromoBundle.message("feature.javascript.frameworks"))
-)
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/javaScriptProject.kt b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/javaScriptProject.kt
index c6a42934af2a..cae2a9ed0f14 100644
--- a/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/javaScriptProject.kt
+++ b/python/ide/impl/intellij.pycharm.community.ide.impl.promotion/src/com/intellij/pycharm/community/ide/impl/promotion/javaScriptProject.kt
@@ -8,6 +8,7 @@ import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginAdver
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoFeaturePage
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoPages
import com.intellij.openapi.util.NlsSafe
+import com.intellij.pycharm.community.customization.shared.javaScriptPromoFeatureList
import com.jetbrains.python.icons.PythonIcons
import com.jetbrains.python.newProjectWizard.promotion.PromoProjectGenerator
import javax.swing.Icon
diff --git a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/newProjectWizard/impl/PyV3NewProjectStepAction.kt b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/newProjectWizard/impl/PyV3NewProjectStepAction.kt
index 14ac16e4ad9a..6aa8afaddddb 100644
--- a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/newProjectWizard/impl/PyV3NewProjectStepAction.kt
+++ b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/newProjectWizard/impl/PyV3NewProjectStepAction.kt
@@ -32,7 +32,6 @@ internal class PyV3NewProjectStepAction : AbstractNewProjectStep ProjectSettingsStepBase(projectGenerator, callback)
}
-
override fun getActions(
generators: List>,
callback: AbstractCallback,
diff --git a/python/pluginResources/messages/PyBundle.properties b/python/pluginResources/messages/PyBundle.properties
index 13269d9896dc..c0dd996de414 100644
--- a/python/pluginResources/messages/PyBundle.properties
+++ b/python/pluginResources/messages/PyBundle.properties
@@ -1695,7 +1695,7 @@ python.uv.lockfile.out.of.sync=The lock file at `uv.lock` is out of sync
python.uv.update.lock=Update uv lock
pycharm.free.mode.upgrade.title=Upgrade to PyCharm Pro
-pycharm.free.mode.upgrade.body=Unlock the full potential of your IDE! Boost productivity,
work faster, and be more efficient with powerful development tools.- Support for JavaScript, TypeScript, React and others
- Advances support for Django, Flask and FastAPI
- Remote development
- Local and remote full-scale Jupyter notebooks
+pycharm.free.mode.upgrade.body=Unlock the full potential of your IDE! Boost productivity,
work faster and be more efficient with powerful development tools.- Support for JavaScript, TypeScript, React and others
- Advances support for Django, Flask and FastAPI
- Remote development
- Local and remote full-scale Jupyter notebooks
pycharm.free.mode.upgrade.button=Purchase Subscription
python.packaging.sync.packages=Syncing project dependencies
python.sdk.read.only=Python SDK ''{0}'' is read only and operation cannot be performed.
diff --git a/python/src/com/jetbrains/python/createPromoPanel.kt b/python/src/com/jetbrains/python/createPromoPanel.kt
index f03e5fafb403..fc2a10244948 100644
--- a/python/src/com/jetbrains/python/createPromoPanel.kt
+++ b/python/src/com/jetbrains/python/createPromoPanel.kt
@@ -1,19 +1,24 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python
+import com.intellij.ide.BrowserUtil
import com.intellij.ide.browsers.BrowserLauncher
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PromoFeatureListItem
import com.intellij.ui.dsl.builder.*
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.ui.JBFont
import com.jetbrains.python.icons.PythonIcons
+import org.jetbrains.annotations.Nls
import javax.swing.JPanel
/**
- * Panel that suggests user to buy Pro version
+ * Panel that suggests user to buy a Pro version.
+ * By default, it shows a "pycharm.free.mode.upgrade.body" promo text.
+ * Could be customized by passing descriptionHtml and features list. In this case, default text will be substituted to features list.
*/
@RequiresEdt
-internal fun createPromoPanel(): JPanel = panel {
+fun createPromoPanel(@Nls descriptionHtml: String? = null, features: List? = null): JPanel = panel {
row {
icon(PythonIcons.Python.Pycharm32).resizableColumn().align(AlignX.RIGHT + AlignY.TOP)
panel {
@@ -22,10 +27,30 @@ internal fun createPromoPanel(): JPanel = panel {
text(PyBundle.message("pycharm.free.mode.upgrade.title")).align(AlignY.BOTTOM).applyToComponent {
font = JBFont.h1()
}
+ }.topGap(TopGap.SMALL)
+
+ if (descriptionHtml != null) {
+ row {
+ text(descriptionHtml) { BrowserUtil.browse(it.url.toExternalForm()) }
+ }
}
- row {
- text(PyBundle.message("pycharm.free.mode.upgrade.body")).align(AlignY.TOP).applyToComponent { putClientProperty(DslComponentProperty.VERTICAL_COMPONENT_GAP, VerticalComponentGap(top = false, bottom = false)) }
+
+ if (features == null) {
+ row {
+ text(PyBundle.message("pycharm.free.mode.upgrade.body")).align(AlignY.TOP).applyToComponent {
+ putClientProperty(DslComponentProperty.VERTICAL_COMPONENT_GAP, VerticalComponentGap(top = true, bottom = false))
+ }
+ }.topGap(TopGap.SMALL)
}
+ else {
+ features.forEach { feature ->
+ row {
+ icon(feature.icon).gap(RightGap.SMALL).align(AlignY.TOP)
+ text(feature.title)
+ }
+ }
+ }
+
row {
button(PyBundle.message("pycharm.free.mode.upgrade.button")) {
BrowserLauncher.instance.open("https://www.jetbrains.com/pycharm/buy/?utm_source=product&utm_medium=referral&utm_campaign=pycharm&utm_content=pro_upgrade§ion=commercial&billing=yearly")