diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
deleted file mode 100644
index d26b689040a5..000000000000
--- a/.idea/dbnavigator.xml
+++ /dev/null
@@ -1,460 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/ide-startup/importSettings/resources/messages/ImportSettingsBundle.properties b/plugins/ide-startup/importSettings/resources/messages/ImportSettingsBundle.properties
index f2ddce7c72a6..6a393f91ecaf 100644
--- a/plugins/ide-startup/importSettings/resources/messages/ImportSettingsBundle.properties
+++ b/plugins/ide-startup/importSettings/resources/messages/ImportSettingsBundle.properties
@@ -46,6 +46,7 @@ onboarding.wizard.getting-ready=Getting Ready\u2026
plugin-installation.progress.text-with-details={0} / {1}
plugin-installation.progress.determining-plugins-to-download=Determining plugins to download
+plugin-installation.progress.downloading=Установка {0}...
settings.category.ui.name=UI settings
settings.category.ui.description=Includes theme, editor font, toolbar, and notifications
@@ -66,6 +67,7 @@ transfer.settings.message=Importing from {0}\u2026
import.settings.title = Importing settings\u2026
import.settings.ok = Import Settings
import.settings.back = Back
+import.settings.back.ru = Назад
import.settings.sync.ok = Sync Settings
import.settings.sync.import.once = Import Once
@@ -112,6 +114,7 @@ plugin.description.go = Поддержка языка Go
plugin.description.fileWatchers = Автоматический запуск внешних инструментов при изменении файлов
plugin.description.makefile = Подсветка синтаксиса и навигация для Makefile
plugin.description.protocolBuffers = Поддержка Protocol Buffers для сериализации данных
+plugin.description.easyp = Линтинг и форматирование proto файлов с помощью easyp
plugin.description.kilocode = Kilo Code AI Агент
plugin.description.continue = Open-source AI ассистент для кода
plugin.description.docker = Поддержка Docker для управления контейнерами
diff --git a/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/chooser/ui/OpenIdeStartupWizardService.kt b/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/chooser/ui/OpenIdeStartupWizardService.kt
index 7b3e0f5edc05..6e4101dd7602 100644
--- a/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/chooser/ui/OpenIdeStartupWizardService.kt
+++ b/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/chooser/ui/OpenIdeStartupWizardService.kt
@@ -16,21 +16,26 @@ package com.intellij.ide.startup.importSettings.chooser.ui
import com.intellij.icons.AllIcons
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
import com.intellij.ide.startup.importSettings.OpenIdePluginIcons
-import com.intellij.ide.startup.importSettings.StartupImportIcons
import com.intellij.ide.startup.importSettings.data.*
+import com.intellij.ide.startup.importSettings.openide.utils.PluginInstallationUtil
+import com.intellij.ide.startup.importSettings.transfer.ProgressIndicatorAdapter
+import com.intellij.ide.startup.importSettings.transfer.TransferSettingsProgressIndicator
import com.intellij.java.ui.icons.JavaUIIcons
+import com.intellij.openapi.application.EDT
+import com.intellij.openapi.application.ModalityState
+import com.intellij.openapi.application.asContextElement
+import com.intellij.openapi.application.ex.ApplicationManagerEx
+import com.intellij.util.IconUtil
import com.jetbrains.rd.util.lifetime.Lifetime
-import com.jetbrains.rd.util.reactive.IVoidSource
-import com.jetbrains.rd.util.reactive.OptProperty
import com.jetbrains.rd.util.reactive.Property
+import com.jetbrains.rd.util.reactive.Signal
+import kotlinx.coroutines.*
-class OpenIdeStartupWizardService : StartupWizardService {
+class OpenIdeStartupWizardService(private val coroutineScope: CoroutineScope) : StartupWizardService {
override val isActive = true
- override val shouldClose: IVoidSource
- get() = object : IVoidSource {
- override fun advise(lifetime: Lifetime, handler: (Unit) -> Unit) {
- }
- }
+ private val _shouldClose = Signal()
+ override val shouldClose: Signal
+ get() = _shouldClose
override fun getKeymapService(): KeymapService {
TODO("Not yet implemented")
@@ -45,6 +50,25 @@ class OpenIdeStartupWizardService : StartupWizardService {
return object : PluginService {
override val pluginGroups: List
get() = listOf(
+ WizardPluginGroupImpl(
+ id = "ai",
+ name = "AI",
+ icon = AllIcons.Actions.Lightning,
+ plugins = listOf(
+ WizardPluginImpl(
+ id = "ai.kilocode.jetbrains",
+ icon = AllIcons.Plugins.PluginLogo,
+ name = "Kilo Code",
+ description = ImportSettingsBundle.message("plugin.description.kilocode"),
+ ),
+ WizardPluginImpl(
+ id = "com.github.continuedev.continueintellijextension",
+ icon = AllIcons.Plugins.PluginLogo,
+ name = "Continue",
+ description = ImportSettingsBundle.message("plugin.description.continue"),
+ ),
+ )
+ ),
WizardPluginGroupImpl(
id = "java-kotlin",
name = "Java / Kotlin",
@@ -170,24 +194,11 @@ class OpenIdeStartupWizardService : StartupWizardService {
name = "Protocol Buffers",
description = ImportSettingsBundle.message("plugin.description.protocolBuffers"),
),
- )
- ),
- WizardPluginGroupImpl(
- id = "ai",
- name = "AI",
- icon = AllIcons.Actions.Lightning,
- plugins = listOf(
WizardPluginImpl(
- id = "ai.kilocode.jetbrains",
+ id = "com.github.easyptech.easyp",
icon = AllIcons.Plugins.PluginLogo,
- name = "Kilo Code",
- description = ImportSettingsBundle.message("plugin.description.kilocode"),
- ),
- WizardPluginImpl(
- id = "com.github.continuedev.continueintellijextension",
- icon = AllIcons.Plugins.PluginLogo,
- name = "Continue",
- description = ImportSettingsBundle.message("plugin.description.continue"),
+ name = "easyp",
+ description = ImportSettingsBundle.message("plugin.description.easyp"),
),
)
),
@@ -210,11 +221,34 @@ class OpenIdeStartupWizardService : StartupWizardService {
}
override fun install(lifetime: Lifetime, ids: List): PluginImportProgress {
- return object : PluginImportProgress {
- override val icon = Property(AllIcons.Plugins.PluginLogo)
- override val progressMessage = Property(null)
- override val progress = OptProperty()
+ val progressIndicator = TransferSettingsProgressIndicator()
+ val progressAdapter = ProgressIndicatorAdapter(progressIndicator)
+ val iconProperty = Property(AllIcons.Plugins.PluginLogo)
+ coroutineScope.launch {
+ var needRestart = false
+ try {
+ needRestart = PluginInstallationUtil.installPlugins(ids, progressAdapter) { icon ->
+ iconProperty.set(IconUtil.resizeSquared(icon, 64))
+ }
+ } catch (e: CancellationException) {
+ throw e
+ } catch (_: Exception) {
+ } finally {
+ withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
+ if (needRestart) {
+ ApplicationManagerEx.getApplicationEx().restart(true)
+ } else {
+ _shouldClose.fire(Unit)
+ }
+ }
+ }
+ }
+
+ return object : PluginImportProgress {
+ override val icon = iconProperty
+ override val progressMessage = progressIndicator.progressMessage
+ override val progress = progressIndicator.progress
}
}
diff --git a/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/openide/utils/PluginInstallationUtil.kt b/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/openide/utils/PluginInstallationUtil.kt
new file mode 100644
index 000000000000..1cfbe9ae6ccd
--- /dev/null
+++ b/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/openide/utils/PluginInstallationUtil.kt
@@ -0,0 +1,119 @@
+// OpenIDE Project
+// Copyright (C) 2026 “Open Development Platform” Ltd. (https://openide.ru)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License version 3 or later as published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see http://www.gnu.org/licenses/.
+package com.intellij.ide.startup.importSettings.openide.utils
+
+import com.intellij.ide.plugins.IdeaPluginDescriptor
+import com.intellij.ide.plugins.PluginManagerCore
+import com.intellij.ide.plugins.marketplace.MarketplaceRequests
+import com.intellij.ide.startup.importSettings.ImportSettingsBundle
+import com.intellij.ide.startup.importSettings.openide.service.PluginIconService
+import com.intellij.openapi.application.EDT
+import com.intellij.openapi.application.ModalityState
+import com.intellij.openapi.application.asContextElement
+import com.intellij.openapi.extensions.PluginId
+import com.intellij.openapi.progress.ProgressIndicator
+import com.intellij.openapi.updateSettings.impl.PluginDownloader
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import javax.swing.Icon
+
+object PluginInstallationUtil {
+
+ /**
+ * Installs plugins by their IDs.
+ * @param onIconLoaded callback to update icon when plugin icon is loaded
+ * @return true if IDE restart is required after installation
+ */
+ @Suppress("DEPRECATION")
+ suspend fun installPlugins(
+ pluginIds: List,
+ progressIndicator: ProgressIndicator,
+ onIconLoaded: ((Icon) -> Unit)? = null,
+ ): Boolean {
+ if (progressIndicator.isCanceled || pluginIds.isEmpty()) {
+ return false
+ }
+
+ val idsToInstall = pluginIds
+ .map { PluginId.Companion.getId(it) }
+ .filter { !PluginManagerCore.isPluginInstalled(it) }
+
+ if (idsToInstall.isEmpty()) {
+ progressIndicator.fraction = 1.0
+ return false
+ }
+
+ progressIndicator.text = ImportSettingsBundle.message("plugin-installation.progress.determining-plugins-to-download")
+ progressIndicator.fraction = 0.05
+
+ val pluginsToInstall: List = withContext(Dispatchers.IO) {
+ MarketplaceRequests.Companion.loadLastCompatiblePluginDescriptors(idsToInstall.toSet(), null, true)
+ }
+
+ if (pluginsToInstall.isEmpty()) {
+ progressIndicator.fraction = 1.0
+ return false
+ }
+
+ var shouldRestart = false
+ val progressPerPlugin = 0.9 / pluginsToInstall.size.coerceAtLeast(1)
+ var currentProgress = 0.1
+
+ for (plugin in pluginsToInstall) {
+ if (progressIndicator.isCanceled) break
+
+ progressIndicator.text = ImportSettingsBundle.message("plugin-installation.progress.downloading", plugin.name)
+
+ // Load and set plugin icon
+ if (onIconLoaded != null) {
+ try {
+ val icon = PluginIconService.Companion.getInstance().loadIcon(plugin.pluginId.idString)
+ if (icon != null) {
+ withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
+ onIconLoaded(icon)
+ }
+ }
+ }
+ catch (_: Exception) {
+ }
+ }
+
+ try {
+ val downloader = PluginDownloader.createDownloader(plugin).withErrorsConsumer { problem ->
+ }
+
+ withContext(Dispatchers.IO) {
+ downloader.prepareToInstall(null)
+ }
+
+ val appliedWithoutRestart = withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
+ downloader.installDynamically(null)
+ }
+
+ if (!appliedWithoutRestart) {
+ shouldRestart = true
+ }
+ }
+ catch (_: Exception) {
+ }
+
+ currentProgress += progressPerPlugin
+ progressIndicator.fraction = currentProgress.coerceAtMost(0.99)
+ }
+
+ progressIndicator.fraction = 1.0
+ progressIndicator.text = null
+ return shouldRestart
+ }
+}
\ No newline at end of file
diff --git a/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/wizard/pluginChooser/WizardPluginsPage.kt b/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/wizard/pluginChooser/WizardPluginsPage.kt
index d16f6e407b89..9fa5b1c475d5 100644
--- a/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/wizard/pluginChooser/WizardPluginsPage.kt
+++ b/plugins/ide-startup/importSettings/src/com/intellij/ide/startup/importSettings/wizard/pluginChooser/WizardPluginsPage.kt
@@ -103,7 +103,7 @@ internal class WizardPluginsPage(
})
}
- private val backAction = controller.createButton(ImportSettingsBundle.message("import.settings.back"), goBackAction ?: {})
+ private val backAction = controller.createButton(ImportSettingsBundle.message("import.settings.back.ru"), goBackAction ?: {})
private val continueAction = controller.createDefaultButton(continueButtonTextOverride ?: ImportSettingsBundle.message("plugins.page.ok.button.continue.without")) {
val ids = getSelected().map { it.plugin.id }.toList()