PY-78995: (WIP): Display banner for locked run configurations in free mode

(cherry picked from commit 63ad1943e856fa2e964839b908e639c0d58002f8)

IJ-CR-169869

GitOrigin-RevId: d6545a948a5b251e7ac16ecc5ecddee9221347a9
This commit is contained in:
Ilya.Kazakevich
2025-07-01 04:48:24 +02:00
committed by intellij-monorepo-bot
parent b8d5ea4acd
commit 4a50a7e84d
4 changed files with 50 additions and 7 deletions

View File

@@ -41,6 +41,7 @@ public final class PythonIcons {
/** 16x16 */ public static final @NotNull Icon Pandas = load("icons/com/jetbrains/pythonCore/python/pandas.svg", -1188443833, 2);
/** 16x16 */ public static final @NotNull Icon Polars = load("icons/com/jetbrains/pythonCore/python/polars.svg", 1700660876, 2);
/** 16x16 */ public static final @NotNull Icon Pycharm = load("icons/com/jetbrains/pythonCore/python/pycharm.svg", 2014186643, 0);
/** 32x32 */ public static final @NotNull Icon Pycharm32 = load("icons/com/jetbrains/pythonCore/python/pycharm32.svg", -1800877862, 0);
/** 16x16 */ public static final @NotNull Icon PythonClosed = load("icons/com/jetbrains/pythonCore/python/expui/pythonClosed.svg", "icons/com/jetbrains/pythonCore/python/pythonClosed.svg", -663368800, 0);
/** 16x16 */ public static final @NotNull Icon PythonConsole = load("icons/com/jetbrains/pythonCore/python/expui/pythonConsole.svg", "icons/com/jetbrains/pythonCore/python/pythonConsole.svg", 2125468440, 0);
/** 13x13 */ public static final @NotNull Icon PythonConsoleToolWindow = load("icons/com/jetbrains/pythonCore/python/expui/pythonConsoleToolWindow.svg", "icons/com/jetbrains/pythonCore/python/pythonConsoleToolWindow.svg", 1833337589, 2);

View File

@@ -0,0 +1,19 @@
<!-- Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.90918 24.0266L2.91005 29.9643C2.91005 31.089 3.82176 32.0004 4.94642 32.0004H10.6997C11.2941 32.0004 11.859 31.7406 12.2459 31.2894L28.6005 12.2087C28.9167 11.8395 29.0907 11.3694 29.0907 10.8833V4.94554C29.0907 3.82089 28.179 2.90918 27.0543 2.90918H21.3002C20.7058 2.90918 20.1409 3.16896 19.754 3.62016L3.39936 22.7009C3.08285 23.0701 2.90918 23.5402 2.90918 24.0266Z" fill="#00D886"/>
<path d="M2.90918 24.7403V29.9636C2.90918 31.0882 3.82089 31.9999 4.94554 31.9999H11.4919C11.5882 31.9999 11.6845 31.9929 11.7799 31.9796L30.2517 29.341C31.2551 29.1976 32.0001 28.3385 32.0001 27.325V19.4885C32.0001 18.3636 31.0881 17.4519 29.9631 17.4521L20.6939 17.4545C20.4751 17.4545 20.2578 17.4897 20.0504 17.5589L4.30147 22.8087C3.47005 23.0859 2.90918 23.8641 2.90918 24.7406V24.7403Z" fill="url(#paint0_linear_2571_1496)"/>
<path d="M0 2.03636V19.0205C0 19.8351 0.485527 20.5713 1.23404 20.8922L19.9793 28.9263C20.2327 29.0348 20.5059 29.0909 20.7817 29.0909H29.9636C31.0883 29.0909 32 28.1792 32 27.0545V18.0716C32 17.6692 31.8807 17.2759 31.6573 16.9411L20.9559 0.906764C20.578 0.340655 19.9427 0.000872727 19.2623 0.000872727L2.03636 0C0.911709 0 0 0.911709 0 2.03636Z" fill="url(#paint1_linear_2571_1496)"/>
<path d="M26 6H6V26H26V6Z" fill="black"/>
<path d="M8.9502 9.01968H12.2139C12.746 9.01968 13.2149 9.11743 13.6205 9.31292C14.026 9.50841 14.3373 9.78332 14.5546 10.1382C14.7754 10.4931 14.8859 10.9039 14.8859 11.3708C14.8859 11.8377 14.7736 12.2613 14.5493 12.6197C14.3285 12.9781 14.0117 13.2571 13.5989 13.456C13.1899 13.6515 12.7137 13.7493 12.1709 13.7493H10.4333V16.622H8.95078V9.01968H8.9502ZM12.1159 12.517C12.3658 12.517 12.5828 12.4716 12.7675 12.3811C12.9557 12.2869 13.1006 12.1551 13.2018 11.9846C13.3031 11.811 13.354 11.6099 13.354 11.3819C13.354 11.1538 13.3034 10.9507 13.2018 10.7846C13.1003 10.6142 12.9557 10.4838 12.7675 10.3936C12.5828 10.2994 12.3658 10.2526 12.1159 10.2526H10.4324V12.517H12.1159ZM19.1788 16.7526C18.4513 16.7526 17.7924 16.5822 17.2021 16.2421C16.6119 15.8979 16.1487 15.4275 15.8119 14.8303C15.4753 14.2296 15.3068 13.5596 15.3068 12.821C15.3068 12.0824 15.4753 11.4144 15.8119 10.8172C16.1484 10.2165 16.6119 9.7455 17.2021 9.40543C17.7921 9.06129 18.451 8.88965 19.1788 8.88965C19.7941 8.88965 20.3591 9.00369 20.8731 9.23176C21.3871 9.45983 21.8142 9.78012 22.1546 10.1929C22.4984 10.6022 22.7282 11.0726 22.8443 11.6047H21.2911C21.1896 11.3298 21.0378 11.0889 20.835 10.8824C20.6357 10.6726 20.3951 10.5112 20.1127 10.3992C19.8302 10.2872 19.5224 10.2307 19.1896 10.2307C18.7407 10.2307 18.3352 10.3427 17.9733 10.5673C17.6111 10.7919 17.3272 11.1014 17.1207 11.4959C16.9179 11.8869 16.8167 12.3288 16.8167 12.821C16.8167 13.3132 16.9179 13.7571 17.1207 14.1513C17.3269 14.5423 17.6111 14.8498 17.9733 15.0744C18.3352 15.299 18.7407 15.411 19.1896 15.411C19.5227 15.411 19.8305 15.3545 20.1127 15.2425C20.3949 15.1305 20.6357 14.9711 20.835 14.7646C21.0378 14.5548 21.1896 14.3119 21.2911 14.037H22.8443C22.7285 14.5691 22.4984 15.0415 22.1546 15.4543C21.8142 15.8636 21.3871 16.1819 20.8731 16.4099C20.3591 16.638 19.7941 16.752 19.1788 16.752V16.7526Z" fill="white"/>
<path d="M16 22H9V23H16V22Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_2571_1496" x1="3.81071" y1="32.3586" x2="30.6238" y2="19.9269" gradientUnits="userSpaceOnUse">
<stop offset="0.1" stop-color="#00D886"/>
<stop offset="0.59" stop-color="#F0EB18"/>
</linearGradient>
<linearGradient id="paint1_linear_2571_1496" x1="30.0093" y1="29.8889" x2="0.656584" y2="0.536147" gradientUnits="userSpaceOnUse">
<stop offset="0.3" stop-color="#F0EB18"/>
<stop offset="0.7" stop-color="#00C4F4"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -677,7 +677,7 @@ configurable.PyActiveSdkModuleConfigurable.python.interpreter.display.name=Pytho
configurable.PyActiveSdkModuleConfigurable.pycharm.interpreter.display.name=Interpreter
configurable.PyUserTypeRenderersConfigurable.display.name=Python Type Renderers
configurable.PyUserTypeRenderersConfigurable.pycharm.display.name=Type Renderers
configurable.PyUserTypeRenderersConfigurable.description= Define custom display formats for various data types across your application.
configurable.PyUserTypeRenderersConfigurable.description=Define custom display formats for various data types across your application.
configurable.plots.pycharm.display.name=Plots
flask.name=Flask
settings.default.remote.interpreter=Default Python Remote Interpreter
@@ -1689,3 +1689,6 @@ command.name.add.package.to.setup.py=Add a package to setup.py
python.sdk.conda.requirements.file.not.found=Conda Environment.yml file is not found
pycharm.free.mode.upgrade.title=Upgrade to PyCharm Pro
pycharm.free.mode.upgrade.body=Unlock the full potential of your IDE! Boost productivity<br/>, work faster, and be more efficient with powerful development tools.<ul><li>Support for JavaScript, TypeScript, React and others</li><li>Advances support for Django, Flask and FastAPI</li><li>Remote evelopment</li><li>Local and remote full-scale Jupyter notebooks</li></ul>
pycharm.free.mode.upgrade.button=Purchase Subscription

View File

@@ -11,7 +11,9 @@ import com.intellij.execution.runners.RunConfigurationWithSuppressedDefaultRunAc
import com.intellij.facet.impl.invalid.FacetIgnorer
import com.intellij.facet.impl.invalid.InvalidFacet
import com.intellij.icons.AllIcons
import com.intellij.ide.browsers.BrowserLauncher
import com.intellij.ide.plugins.PluginManager
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
import com.intellij.openapi.extensions.ExtensionNotApplicableException
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.options.SettingsEditor
@@ -19,10 +21,11 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.WriteExternalException
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.panel
import com.intellij.ui.dsl.builder.*
import com.intellij.util.PlatformUtils
import com.intellij.util.ui.JBFont
import com.jetbrains.python.PyBundle
import com.jetbrains.python.icons.PythonIcons
import org.jdom.Element
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
@@ -30,7 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger
import javax.swing.Icon
import javax.swing.JComponent
private class PythonLockedRunConfigurationEditor : SettingsEditor<PythonLockedRunConfiguration>() {
private class PythonLockedRunConfigurationEditor : SettingsEditor<PythonLockedRunConfiguration>(null, true) {
override fun resetEditorFrom(s: PythonLockedRunConfiguration) {}
@@ -38,7 +41,25 @@ private class PythonLockedRunConfigurationEditor : SettingsEditor<PythonLockedRu
protected override fun createEditor(): JComponent = panel {
row {
label(PyBundle.message("python.run.configuration.is.not.editable.in.this.mode")).align(AlignX.CENTER)
icon(PythonIcons.Python.Pycharm32).resizableColumn().align(AlignX.RIGHT + AlignY.TOP)
panel {
row {
@Suppress("DialogTitleCapitalization") // PyCharm Pro is literally how we want to see it
text(PyBundle.message("pycharm.free.mode.upgrade.title")).align(AlignY.BOTTOM).applyToComponent {
font = JBFont.h1()
}
}
row {
text(PyBundle.message("pycharm.free.mode.upgrade.body")).align(AlignY.TOP).applyToComponent { putClientProperty(DslComponentProperty.VERTICAL_COMPONENT_GAP, VerticalComponentGap(top = false, bottom = false)) }
}
row {
button(PyBundle.message("pycharm.free.mode.upgrade.button")) {
BrowserLauncher.instance.open("https://www.jetbrains.com/pycharm/buy/?section=commercial&billing=yearly")
}.applyToComponent {
putClientProperty(DarculaButtonUI.DEFAULT_STYLE_KEY, true)
}
}
}.resizableColumn().align(AlignX.LEFT)
}
}
}
@@ -136,8 +157,7 @@ private open class PythonLockedRunConfigurationTypeBase(val theId: String, @Nls
// Do not enable "lock" configs for non PyCharm or Idea (as it's capable of running the Python plugin) IDEs or if the Python plugin is enabled.
if ((!PlatformUtils.isPyCharm() && !PlatformUtils.isIntelliJ()) ||
PluginManager.getInstance().findEnabledPlugin(PluginId.getId("Pythonid")) != null ||
PlatformUtils.isDataSpell())
{
PlatformUtils.isDataSpell()) {
throw ExtensionNotApplicableException.create()
}
}