diff --git a/python/pluginCore/resources/META-INF/plugin.xml b/python/pluginCore/resources/META-INF/plugin.xml index 472a250b34b7..06fc96e778d5 100644 --- a/python/pluginCore/resources/META-INF/plugin.xml +++ b/python/pluginCore/resources/META-INF/plugin.xml @@ -863,6 +863,13 @@ The Python plug-in provides smart editing for Python scripts. The feature set of + + + + + + + diff --git a/python/pluginResources/messages/PyBundle.properties b/python/pluginResources/messages/PyBundle.properties index d4aced987231..0c54a326650a 100644 --- a/python/pluginResources/messages/PyBundle.properties +++ b/python/pluginResources/messages/PyBundle.properties @@ -1528,6 +1528,9 @@ advertiser.package.supported.by.pro={0} is supported by PyCharm Professional advertiser.code.cells.supported.by.pro=Code cells are supported by PyCharm Professional action.PyInstallPackage.text=Install +action.PyInstallFromDiskPackage.text=Install From Disk\u2026 +action.InstallFromVcsPackageAction.text=Install From VCS\u2026 +action.PyManageReposAction.text=Manage Repositories action.PyDeletePackage.text=Uninstall action.PyUpdateToLatestPackage.text=Update to Latest action.PyChangeVersionPackage.text=Change Version diff --git a/python/src/com/jetbrains/python/packaging/toolwindow/PyPackagingToolWindowPanel.kt b/python/src/com/jetbrains/python/packaging/toolwindow/PyPackagingToolWindowPanel.kt index 5e0d03f21b77..a983101537f7 100644 --- a/python/src/com/jetbrains/python/packaging/toolwindow/PyPackagingToolWindowPanel.kt +++ b/python/src/com/jetbrains/python/packaging/toolwindow/PyPackagingToolWindowPanel.kt @@ -28,7 +28,6 @@ import com.jetbrains.python.packaging.toolwindow.model.PyPackagesViewData import com.jetbrains.python.packaging.toolwindow.modules.PyPackagesModuleController import com.jetbrains.python.packaging.toolwindow.packages.PyPackageSearchTextField import com.jetbrains.python.packaging.toolwindow.packages.PyPackagesListController -import com.jetbrains.python.packaging.toolwindow.ui.PyPackageCustomInstallComponents import com.jetbrains.python.packaging.toolwindow.ui.PyPackagesUiComponents import com.jetbrains.python.packaging.utils.PyPackageCoroutine import kotlinx.coroutines.Dispatchers @@ -105,14 +104,11 @@ class PyPackagingToolWindowPanel(private val project: Project) : SimpleToolWindo actionGroup.add(DumbAwareAction.create(message("python.toolwindow.packages.reload.repositories.action"), AllIcons.Actions.Refresh) { service.reloadPackages() }) - actionGroup.add(DumbAwareAction.create(message("python.toolwindow.packages.manage.repositories.action"), AllIcons.General.GearPlain) { - service.manageRepositories() - }) + + actionGroup.add(ActionManager.getInstance().getAction("PyPackageToolbarAdditional")) val actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.TOOLWINDOW_CONTENT, actionGroup, true) actionToolbar.targetComponent = this - - mainPanel = PyPackagesUiComponents.borderPanel { val topToolbar = PyPackagesUiComponents.boxPanel { border = SideBorder(NamedColorUtil.getBoundsColor(), SideBorder.BOTTOM) @@ -122,7 +118,6 @@ class PyPackagingToolWindowPanel(private val project: Project) : SimpleToolWindo add(searchTextField) actionToolbar.component.maximumSize = Dimension(70, actionToolbar.component.maximumSize.height) add(actionToolbar.component) - add(PyPackageCustomInstallComponents.createInstallFromLocationLink(project)) } add(topToolbar, BorderLayout.NORTH) add(splitter!!, BorderLayout.CENTER) diff --git a/python/src/com/jetbrains/python/packaging/toolwindow/actions/InstallFromDiskPackageAction.kt b/python/src/com/jetbrains/python/packaging/toolwindow/actions/InstallFromDiskPackageAction.kt new file mode 100644 index 000000000000..a744ae02a6d5 --- /dev/null +++ b/python/src/com/jetbrains/python/packaging/toolwindow/actions/InstallFromDiskPackageAction.kt @@ -0,0 +1,53 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.jetbrains.python.packaging.toolwindow.actions + +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory +import com.intellij.openapi.project.DumbAwareAction +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.TextFieldWithBrowseButton +import com.intellij.ui.components.dialog +import com.intellij.ui.dsl.builder.* +import com.jetbrains.python.PyBundle.message +import com.jetbrains.python.packaging.common.PythonLocalPackageSpecification +import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService +import com.jetbrains.python.packaging.utils.PyPackageCoroutine + +internal class InstallFromDiskPackageAction : DumbAwareAction() { + override fun actionPerformed(e: AnActionEvent) { + val project = e.project ?: return + + val service = PyPackagingToolWindowService.getInstance(project) + val specification = showInstallFromDiscDialog(project) ?: return + PyPackageCoroutine.launch(project) { + service.installPackage(specification) + } + } + + private fun showInstallFromDiscDialog(project: Project): PythonLocalPackageSpecification? { + val service = PyPackagingToolWindowService.getInstance(project) + var editable = false + + val textField = TextFieldWithBrowseButton().apply { + addBrowseFolderListener(message("python.toolwindow.packages.add.package.path.selector"), "", service.project, + FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor()) + } + val panel = panel { + row(message("python.toolwindow.packages.add.package.path")) { + cell(textField) + .columns(COLUMNS_MEDIUM) + .align(AlignX.FILL) + } + row { + checkBox(message("python.toolwindow.packages.add.package.as.editable")) + .bindSelected({ editable }, { editable = it }) + } + } + + val shouldInstall = dialog(message("python.toolwindow.packages.add.package.dialog.title"), panel, project = service.project, resizable = true).showAndGet() + return if (shouldInstall) PythonLocalPackageSpecification(textField.text, textField.text, editable) else null + } + + override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT +} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/packaging/toolwindow/actions/InstallFromVcsPackageAction.kt b/python/src/com/jetbrains/python/packaging/toolwindow/actions/InstallFromVcsPackageAction.kt new file mode 100644 index 000000000000..e358659827be --- /dev/null +++ b/python/src/com/jetbrains/python/packaging/toolwindow/actions/InstallFromVcsPackageAction.kt @@ -0,0 +1,65 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.jetbrains.python.packaging.toolwindow.actions + +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.project.DumbAwareAction +import com.intellij.ui.components.dialog +import com.intellij.ui.dsl.builder.* +import com.jetbrains.python.PyBundle.message +import com.jetbrains.python.packaging.common.PythonVcsPackageSpecification +import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService +import com.jetbrains.python.packaging.utils.PyPackageCoroutine + +internal class InstallFromVcsPackageAction : DumbAwareAction() { + override fun actionPerformed(e: AnActionEvent) { + val project = e.project ?: return + + val service = PyPackagingToolWindowService.getInstance(project) + val specification = showInstallFromVcsDialog(service) ?: return + PyPackageCoroutine.launch(project) { + service.installPackage(specification) + } + } + + private fun showInstallFromVcsDialog(service: PyPackagingToolWindowService): PythonVcsPackageSpecification? { + var editable = false + var link = "" + val systems = listOf(message("python.toolwindow.packages.add.package.vcs.git"), + message("python.toolwindow.packages.add.package.vcs.svn"), + message("python.toolwindow.packages.add.package.vcs.hg"), + message("python.toolwindow.packages.add.package.vcs.bzr")) + var vcs = systems.first() + + val panel = panel { + row { + comboBox(systems) + .bindItem({ vcs }, { vcs = it!! }) + textField() + .columns(COLUMNS_MEDIUM) + .bindText({ link }, { link = it }) + .align(AlignX.FILL) + } + row { + checkBox(message("python.toolwindow.packages.add.package.as.editable")) + .bindSelected({ editable }, { editable = it }) + } + } + + val shouldInstall = dialog(message("python.toolwindow.packages.add.package.dialog.title"), panel, project = service.project, resizable = true).showAndGet() + if (shouldInstall) { + val prefix = when (vcs) { + message("python.toolwindow.packages.add.package.vcs.git") -> "git+" + message("python.toolwindow.packages.add.package.vcs.svn") -> "svn+" + message("python.toolwindow.packages.add.package.vcs.hg") -> "hg+" + message("python.toolwindow.packages.add.package.vcs.bzr") -> "bzr+" + else -> throw IllegalStateException("Unknown VCS") + } + + return PythonVcsPackageSpecification(link, link, prefix, editable) + } + return null + } + + override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT +} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/packaging/toolwindow/actions/PyManageReposAction.kt b/python/src/com/jetbrains/python/packaging/toolwindow/actions/PyManageReposAction.kt new file mode 100644 index 000000000000..b070e09c92b1 --- /dev/null +++ b/python/src/com/jetbrains/python/packaging/toolwindow/actions/PyManageReposAction.kt @@ -0,0 +1,18 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.jetbrains.python.packaging.toolwindow.actions + +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.project.DumbAwareAction +import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService + +internal class PyManageReposAction : DumbAwareAction() { + override fun actionPerformed(e: AnActionEvent) { + val project = e.project ?: return + + val service = PyPackagingToolWindowService.getInstance(project) + service.manageRepositories() + } + + override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT +} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/packaging/toolwindow/ui/PyPackageCustomInstallComponents.kt b/python/src/com/jetbrains/python/packaging/toolwindow/ui/PyPackageCustomInstallComponents.kt deleted file mode 100644 index c44121a49e71..000000000000 --- a/python/src/com/jetbrains/python/packaging/toolwindow/ui/PyPackageCustomInstallComponents.kt +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.jetbrains.python.packaging.toolwindow.ui - -import com.intellij.openapi.components.service -import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory -import com.intellij.openapi.project.Project -import com.intellij.openapi.ui.TextFieldWithBrowseButton -import com.intellij.ui.components.DropDownLink -import com.intellij.ui.components.dialog -import com.intellij.ui.dsl.builder.* -import com.jetbrains.python.PyBundle.message -import com.jetbrains.python.packaging.common.PythonLocalPackageSpecification -import com.jetbrains.python.packaging.common.PythonVcsPackageSpecification -import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService -import com.jetbrains.python.packaging.utils.PyPackageCoroutine -import org.jetbrains.annotations.Nls - -object PyPackageCustomInstallComponents { - private val fromVcsText: String - get() = message("python.toolwindow.packages.add.package.from.vcs") - private val fromDiscText: String - get() = message("python.toolwindow.packages.add.package.from.disc") - - fun createInstallFromLocationLink(project: Project): DropDownLink<@Nls String> { - return DropDownLink(message("python.toolwindow.packages.add.package.action"), - listOf(fromVcsText, fromDiscText)) { - val service = project.service() - - val specification = when (it) { - fromDiscText -> showInstallFromDiscDialog(service) - fromVcsText -> showInstallFromVcsDialog(service) - else -> throw IllegalStateException("Unknown operation") - } - if (specification != null) { - PyPackageCoroutine.launch(project) { - service.installPackage(specification) - } - } - } - - } - - private fun showInstallFromVcsDialog(service: PyPackagingToolWindowService): PythonVcsPackageSpecification? { - var editable = false - var link = "" - val systems = listOf(message("python.toolwindow.packages.add.package.vcs.git"), - message("python.toolwindow.packages.add.package.vcs.svn"), - message("python.toolwindow.packages.add.package.vcs.hg"), - message("python.toolwindow.packages.add.package.vcs.bzr")) - var vcs = systems.first() - - val panel = panel { - row { - comboBox(systems) - .bindItem({ vcs }, { vcs = it!! }) - textField() - .columns(COLUMNS_MEDIUM) - .bindText({ link }, { link = it }) - .align(AlignX.FILL) - } - row { - checkBox(message("python.toolwindow.packages.add.package.as.editable")) - .bindSelected({ editable }, { editable = it }) - } - } - - val shouldInstall = dialog(message("python.toolwindow.packages.add.package.dialog.title"), panel, project = service.project, resizable = true).showAndGet() - if (shouldInstall) { - val prefix = when (vcs) { - message("python.toolwindow.packages.add.package.vcs.git") -> "git+" - message("python.toolwindow.packages.add.package.vcs.svn") -> "svn+" - message("python.toolwindow.packages.add.package.vcs.hg") -> "hg+" - message("python.toolwindow.packages.add.package.vcs.bzr") -> "bzr+" - else -> throw IllegalStateException("Unknown VCS") - } - - return PythonVcsPackageSpecification(link, link, prefix, editable) - } - return null - } - - private fun showInstallFromDiscDialog(service: PyPackagingToolWindowService): PythonLocalPackageSpecification? { - var editable = false - - val textField = TextFieldWithBrowseButton().apply { - addBrowseFolderListener(message("python.toolwindow.packages.add.package.path.selector"), "", service.project, - FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor()) - } - val panel = panel { - row(message("python.toolwindow.packages.add.package.path")) { - cell(textField) - .columns(COLUMNS_MEDIUM) - .align(AlignX.FILL) - } - row { - checkBox(message("python.toolwindow.packages.add.package.as.editable")) - .bindSelected({ editable }, { editable = it }) - } - } - - val shouldInstall = dialog(message("python.toolwindow.packages.add.package.dialog.title"), panel, project = service.project, resizable = true).showAndGet() - return if (shouldInstall) PythonLocalPackageSpecification(textField.text, textField.text, editable) else null - } -} \ No newline at end of file