RIDER-102481 install plugins page
GitOrigin-RevId: 3252a49109ae0203b6224629da77fcbdf535bf45
@@ -109,12 +109,13 @@ enum class StartupWizardStage {
|
||||
ImportProgressPage,
|
||||
WizardThemePage,
|
||||
WizardKeymapPage,
|
||||
WizardPluginPage
|
||||
WizardPluginPage,
|
||||
WizardProgressPage
|
||||
}
|
||||
|
||||
object IdeStartupWizardCollector : CounterUsagesCollector() {
|
||||
|
||||
val GROUP = EventLogGroup("wizard.startup", 5)
|
||||
val GROUP = EventLogGroup("wizard.startup", 6)
|
||||
override fun getGroup() = GROUP
|
||||
|
||||
private val initialStartSucceeded = GROUP.registerEvent("initial_start_succeeded")
|
||||
|
||||
@@ -50,5 +50,6 @@
|
||||
<orderEntry type="library" name="jna" level="project" />
|
||||
<orderEntry type="library" name="sqlite" level="project" />
|
||||
<orderEntry type="library" name="classgraph" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.util.ui" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -81,9 +81,12 @@ wizard.button.continue = Continue
|
||||
|
||||
plugins.page.title = Featured Plugins
|
||||
plugins.page.ok.button.continue.without = Continue without Plugins
|
||||
plugins.page.ok.button.continue.installation = Continue installation
|
||||
plugins.page.ok.button.install = Install Plugins
|
||||
plugins.page.ok.button.finish = Finish
|
||||
plugins.page.ok.button.install = Install Selected
|
||||
plugins.page.choose.counter.no = No plugins selected for installation
|
||||
plugins.page.choose.counter.one = 1 plugin selected for installation
|
||||
plugins.page.choose.counter.multiple = {0} plugins selected for installation
|
||||
install.plugins.page.title = Installing Plugins\u2026
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 130 KiB |
@@ -6,18 +6,16 @@ import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.ImportSettingsController
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.OnboardingPage
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.ProgressCommentLabel
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.ProgressLabel
|
||||
import com.intellij.ide.startup.importSettings.data.DialogImportData
|
||||
import com.intellij.ide.startup.importSettings.data.ImportFromProduct
|
||||
import com.intellij.openapi.rd.createLifetime
|
||||
import com.intellij.openapi.ui.MessageDialogBuilder
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.platform.ide.bootstrap.StartupWizardStage
|
||||
import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.ui.scale.JBUIScale
|
||||
import com.intellij.ui.util.minimumWidth
|
||||
import com.intellij.ui.util.preferredWidth
|
||||
import com.intellij.util.ui.JBDimension
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.jetbrains.rd.util.lifetime.intersect
|
||||
import java.awt.*
|
||||
@@ -82,11 +80,11 @@ class ImportProgressPage(importFromProduct: DialogImportData, controller: Import
|
||||
|
||||
cn.gridx = 0
|
||||
cn.gridy = 1
|
||||
add(HLabel(from.item.name).label, cn)
|
||||
add(ProgressLabel(from.item.name).label, cn)
|
||||
|
||||
cn.gridx = 2
|
||||
cn.gridy = 1
|
||||
add(HLabel(to.item.name).label, cn)
|
||||
add(ProgressLabel(to.item.name).label, cn)
|
||||
|
||||
border = JBUI.Borders.emptyBottom(18)
|
||||
|
||||
@@ -94,7 +92,7 @@ class ImportProgressPage(importFromProduct: DialogImportData, controller: Import
|
||||
}
|
||||
|
||||
add(JPanel(VerticalLayout(JBUI.scale(8)).apply {
|
||||
val hLabel = CommentLabel("")
|
||||
val hLabel = ProgressCommentLabel("")
|
||||
|
||||
add(JProgressBar(0, 99).apply {
|
||||
importFromProduct.progress.progress.advise(lifetime) {
|
||||
@@ -104,12 +102,11 @@ class ImportProgressPage(importFromProduct: DialogImportData, controller: Import
|
||||
hLabel.text = if (it != null) "<center>$it</center>" else " "
|
||||
}
|
||||
|
||||
preferredWidth = JBUI.scale(280)
|
||||
preferredSize = Dimension(JBUI.scale (280), preferredSize.height)
|
||||
})
|
||||
|
||||
|
||||
add(hLabel.label.apply {
|
||||
font = JBFont.medium()
|
||||
foreground = JBUI.CurrentTheme.ContextHelp.FOREGROUND
|
||||
})
|
||||
}).apply {
|
||||
@@ -132,44 +129,4 @@ class ImportProgressPage(importFromProduct: DialogImportData, controller: Import
|
||||
}
|
||||
|
||||
override val content: JComponent = contentPage
|
||||
|
||||
private open class HLabel(txt: String) {
|
||||
var text: @NlsContexts.Label String = ""
|
||||
set(value) {
|
||||
@Suppress("HardCodedStringLiteral") // IDEA-338243
|
||||
if (field == value) return
|
||||
lbl.text = "<html><center>${value}</center></html>"
|
||||
field = value
|
||||
}
|
||||
|
||||
private val lbl = object : JLabel() {
|
||||
override fun getPreferredSize(): Dimension {
|
||||
val preferredSize = super.getPreferredSize()
|
||||
return getPref(preferredSize.height)
|
||||
}
|
||||
}
|
||||
|
||||
open fun getPref(prefH: Int): Dimension {
|
||||
return Dimension(0, prefH)
|
||||
}
|
||||
|
||||
val label: JComponent
|
||||
get() {
|
||||
return lbl
|
||||
}
|
||||
|
||||
init {
|
||||
lbl.isOpaque = false
|
||||
lbl.minimumWidth = 10
|
||||
lbl.horizontalAlignment = SwingConstants.CENTER
|
||||
lbl.verticalAlignment = SwingConstants.TOP
|
||||
text = txt
|
||||
}
|
||||
}
|
||||
|
||||
private class CommentLabel(txt: String) : HLabel(txt) {
|
||||
override fun getPref(prefH: Int): Dimension {
|
||||
return Dimension(0, Math.max(prefH, JBUI.scale(45)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.ui.dsl.builder.AlignY
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import com.intellij.ui.dsl.gridLayout.UnscaledGaps
|
||||
import com.intellij.ui.util.preferredWidth
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
import java.awt.*
|
||||
@@ -90,7 +89,8 @@ abstract class SettingChooserPage(private val provider: ActionsDataProvider<*>,
|
||||
}
|
||||
}.align(AlignY.TOP)
|
||||
}.apply {
|
||||
preferredWidth = JBUI.scale(200)
|
||||
preferredSize = Dimension(JBUI.scale(200), preferredSize.height)
|
||||
|
||||
border = JBUI.Borders.empty(20, 20, 0, 0)
|
||||
}, BorderLayout.WEST)
|
||||
|
||||
@@ -103,7 +103,6 @@ abstract class SettingChooserPage(private val provider: ActionsDataProvider<*>,
|
||||
add(st.component())
|
||||
}
|
||||
}
|
||||
|
||||
add(
|
||||
JBScrollPane(listPane).apply {
|
||||
viewport.isOpaque = false
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.intellij.ide.startup.importSettings.data.ActionsDataProvider
|
||||
import com.intellij.ide.startup.importSettings.data.DialogImportData
|
||||
import com.intellij.ide.startup.importSettings.data.SettingsContributor
|
||||
import com.intellij.ide.startup.importSettings.data.SettingsService
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
|
||||
interface ImportSettingsController : BaseController {
|
||||
companion object {
|
||||
@@ -35,7 +34,7 @@ private class ImportSettingsControllerImpl(dialog: OnboardingDialog, override va
|
||||
* what should we do here?
|
||||
*/
|
||||
/*skipImportAction.invoke()*/
|
||||
dialog.doClose(DialogWrapper.CANCEL_EXIT_CODE)
|
||||
dialog.dialogClose()
|
||||
}
|
||||
|
||||
settService.error.advise(lifetime) {
|
||||
@@ -61,6 +60,6 @@ private class ImportSettingsControllerImpl(dialog: OnboardingDialog, override va
|
||||
|
||||
|
||||
override fun skipImport() {
|
||||
dialog.doClose(DialogWrapper.CANCEL_EXIT_CODE)
|
||||
dialog.dialogClose()
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
package com.intellij.ide.startup.importSettings.chooser.ui
|
||||
|
||||
import com.intellij.ide.startup.importSettings.data.WizardProvider
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
|
||||
class OnboardingController private constructor(){
|
||||
@@ -66,9 +65,7 @@ class OnboardingController private constructor(){
|
||||
}
|
||||
|
||||
fun dialogClose() {
|
||||
if(dialog.isShowing && dialog.isVisible) {
|
||||
dialog.doClose(DialogWrapper.CANCEL_EXIT_CODE)
|
||||
}
|
||||
dialog.dialogClose()
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +91,7 @@ class OnboardingController private constructor(){
|
||||
}
|
||||
|
||||
dialog.title = title
|
||||
state = State.IMPORT
|
||||
state = State.WIZARD
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,13 @@ class OnboardingDialog(val cancelCallback: () -> Unit) : DialogWrapper(null, nul
|
||||
}
|
||||
}
|
||||
|
||||
fun doClose(code: Int) {
|
||||
fun dialogClose() {
|
||||
if(isShowing && isVisible) {
|
||||
doClose(CANCEL_EXIT_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doClose(code: Int) {
|
||||
tracker.onLeave()
|
||||
close(code)
|
||||
}
|
||||
|
||||
@@ -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.intellij.ide.startup.importSettings.chooser.ui
|
||||
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
import java.awt.Dimension
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.SwingConstants
|
||||
|
||||
open class ProgressLabel(txt: String) {
|
||||
var text: @NlsContexts.Label String = ""
|
||||
set(value) {
|
||||
@Suppress("HardCodedStringLiteral") // IDEA-338243
|
||||
if (field == value) return
|
||||
lbl.text = "<html><center>${value}</center></html>"
|
||||
field = value
|
||||
}
|
||||
|
||||
protected val lbl = object : JLabel() {
|
||||
override fun getPreferredSize(): Dimension {
|
||||
val preferredSize = super.getPreferredSize()
|
||||
return getPref(preferredSize.height)
|
||||
}
|
||||
}
|
||||
|
||||
open fun getPref(prefH: Int): Dimension {
|
||||
return Dimension(0, prefH)
|
||||
}
|
||||
|
||||
val label: JComponent
|
||||
get() {
|
||||
return lbl
|
||||
}
|
||||
|
||||
init {
|
||||
lbl.isOpaque = false
|
||||
lbl.minimumSize = Dimension(10, lbl.minimumSize.height)
|
||||
lbl.horizontalAlignment = SwingConstants.CENTER
|
||||
lbl.verticalAlignment = SwingConstants.TOP
|
||||
text = txt
|
||||
}
|
||||
}
|
||||
|
||||
class ProgressCommentLabel(txt: String) : ProgressLabel(txt) {
|
||||
init {
|
||||
lbl.font = JBFont.medium()
|
||||
}
|
||||
override fun getPref(prefH: Int): Dimension {
|
||||
return Dimension(0, Math.max(prefH, JBUI.scale(45)))
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@ package com.intellij.ide.startup.importSettings.chooser.ui
|
||||
|
||||
import com.intellij.ide.startup.importSettings.data.WizardService
|
||||
import com.intellij.ide.startup.importSettings.wizard.keymapChooser.KeymapChooserPage
|
||||
import com.intellij.ide.startup.importSettings.wizard.pluginChooser.PluginChooserPage
|
||||
import com.intellij.ide.startup.importSettings.wizard.pluginChooser.WizardPluginsPage
|
||||
import com.intellij.ide.startup.importSettings.wizard.pluginChooser.WizardProgressPage
|
||||
|
||||
interface WizardController : BaseController {
|
||||
companion object {
|
||||
@@ -19,7 +20,8 @@ interface WizardController : BaseController {
|
||||
fun goToThemePage()
|
||||
fun goToKeymapPage()
|
||||
fun goToPluginPage()
|
||||
|
||||
fun goToInstallPluginPage(ids: List<String>)
|
||||
fun skipPlugins()
|
||||
}
|
||||
|
||||
class WizardControllerImpl(dialog: OnboardingDialog,
|
||||
@@ -35,8 +37,22 @@ class WizardControllerImpl(dialog: OnboardingDialog,
|
||||
}
|
||||
|
||||
override fun goToPluginPage() {
|
||||
val page = PluginChooserPage(this)
|
||||
val page = WizardPluginsPage(this)
|
||||
dialog.changePage(page)
|
||||
}
|
||||
|
||||
override fun goToInstallPluginPage(ids: List<String>) {
|
||||
if(ids.isNotEmpty()) {
|
||||
val importProgress = service.getPluginService().install(ids)
|
||||
val page = WizardProgressPage(importProgress, this)
|
||||
dialog.changePage(page)
|
||||
} else {
|
||||
skipPlugins()
|
||||
}
|
||||
}
|
||||
|
||||
override fun skipPlugins() {
|
||||
service.getPluginService().skipPlugins()
|
||||
dialog.dialogClose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,15 @@ import com.intellij.ui.JBColor
|
||||
import com.intellij.ui.SeparatorComponent
|
||||
import com.intellij.ui.SeparatorOrientation
|
||||
import com.intellij.util.ui.JBUI
|
||||
import java.awt.FlowLayout
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import java.awt.GridBagConstraints
|
||||
import java.awt.GridBagLayout
|
||||
import javax.swing.JButton
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JPanel
|
||||
|
||||
class WizardPagePane(centralPane: JComponent, buttons: List<JButton>) : JPanel() {
|
||||
class WizardPagePane(centralPane: JComponent, buttons: List<JButton>, leftComponent: JComponent? = null) : JPanel() {
|
||||
init {
|
||||
layout = GridBagLayout()
|
||||
|
||||
@@ -29,7 +30,7 @@ class WizardPagePane(centralPane: JComponent, buttons: List<JButton>) : JPanel()
|
||||
|
||||
gbc.fill = GridBagConstraints.BOTH
|
||||
gbc.gridy = 1
|
||||
gbc.weighty = 2.0
|
||||
gbc.weighty = 1.0
|
||||
add(centralPane, gbc)
|
||||
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL
|
||||
@@ -37,15 +38,25 @@ class WizardPagePane(centralPane: JComponent, buttons: List<JButton>) : JPanel()
|
||||
gbc.weighty = 0.0
|
||||
add(SeparatorComponent(JBColor.namedColor("Borders.color", JBColor.BLACK), SeparatorOrientation.HORIZONTAL), gbc)
|
||||
|
||||
val buttonPane = JPanel(FlowLayout(FlowLayout.RIGHT)).apply {
|
||||
add(DialogWrapper.layoutButtonsPanel(buttons))
|
||||
border = JBUI.Borders.empty(3, 0, 3, 15)
|
||||
val buttonPane = object : JPanel(BorderLayout()) {
|
||||
override fun getPreferredSize(): Dimension {
|
||||
val preferredSize = super.getPreferredSize()
|
||||
return Dimension(preferredSize.width, JBUI.scale(57))
|
||||
}
|
||||
}.apply {
|
||||
leftComponent?.let {
|
||||
add(leftComponent, BorderLayout.CENTER)
|
||||
}
|
||||
|
||||
add(DialogWrapper.layoutButtonsPanel(buttons), BorderLayout.EAST)
|
||||
border = JBUI.Borders.empty(3, 0, 3, 20)
|
||||
preferredSize = Dimension(preferredSize.width, JBUI.scale(57))
|
||||
}
|
||||
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL
|
||||
gbc.gridy = 3
|
||||
gbc.weighty = 0.0
|
||||
|
||||
gbc.anchor = GridBagConstraints.SOUTH
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL
|
||||
add(buttonPane, gbc)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,10 @@ package com.intellij.ide.startup.importSettings.data
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.jetbrains.rd.util.lifetime.Lifetime
|
||||
import com.jetbrains.rd.util.reactive.*
|
||||
import com.jetbrains.rd.util.threading.coroutines.launch
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.Nls
|
||||
import java.util.*
|
||||
import javax.swing.Icon
|
||||
@@ -79,21 +83,43 @@ class PluginServiceImpl : PluginService {
|
||||
override val plugins: List<WizardPlugin> = listOf
|
||||
|
||||
override fun install(ids: List<String>): PluginImportProgress = TestPluginImportProgress(Lifetime.Eternal)
|
||||
override fun skipPlugins() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class TestPluginImportProgress(lifetime: Lifetime) : TestImportProgress(lifetime), PluginImportProgress {
|
||||
override val complete: Signal<PluginInstallationResult> = Signal()
|
||||
private val iconList = listOf(AllIcons.Plugins.PluginLogo,
|
||||
AllIcons.Plugins.PluginLogoDisabled,
|
||||
AllIcons.TransferSettings.RecentProjects,
|
||||
AllIcons.TransferSettings.Vscode,
|
||||
AllIcons.TransferSettings.Settings,
|
||||
AllIcons.TransferSettings.PluginsAndFeatures)
|
||||
|
||||
override val icon = Property(AllIcons.Plugins.PluginLogo)
|
||||
|
||||
private var index = 0
|
||||
init {
|
||||
lifetime.launch {
|
||||
launch(Dispatchers.Default) {
|
||||
while (true) {
|
||||
index = if (index < iconList.size - 1) index + 1 else 0
|
||||
icon.set(
|
||||
iconList[index]
|
||||
)
|
||||
delay(300L)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WizardPluginImpl(override val icon: Icon,
|
||||
override val name: String,
|
||||
override val description: String? = null,
|
||||
override val id: String = UUID.randomUUID().toString(),
|
||||
override val state: IProperty<WizardPlugin.State> = Property(WizardPlugin.State.UNCHECKED)) : WizardPlugin {
|
||||
|
||||
override val id: String = UUID.randomUUID().toString()) : WizardPlugin {
|
||||
}
|
||||
|
||||
|
||||
@Suppress("HardCodedStringLiteral")
|
||||
class TestKeymapService : KeymapService {
|
||||
override val keymaps: List<WizardKeymap> =
|
||||
|
||||
@@ -46,32 +46,18 @@ interface WizardTheme {
|
||||
interface PluginService {
|
||||
val plugins: List<WizardPlugin>
|
||||
fun install(ids: List<String>): PluginImportProgress
|
||||
fun skipPlugins()
|
||||
}
|
||||
|
||||
interface PluginImportProgress : ImportProgress {
|
||||
val complete: Signal<PluginInstallationResult>
|
||||
}
|
||||
|
||||
interface PluginInstallationResult {
|
||||
val icon: Icon
|
||||
val message: String
|
||||
val icon: IPropertyView<Icon>
|
||||
}
|
||||
|
||||
interface WizardPlugin {
|
||||
enum class State {
|
||||
IN_PROGRESS,
|
||||
INSTALLED,
|
||||
CHECKED,
|
||||
UNCHECKED,
|
||||
ERROR
|
||||
}
|
||||
|
||||
val id: String
|
||||
val icon: Icon
|
||||
val name: String
|
||||
val description: String?
|
||||
|
||||
val state: IProperty<State>
|
||||
}
|
||||
|
||||
interface KeymapService {
|
||||
|
||||
@@ -5,12 +5,8 @@ import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.OnboardingPage
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardController
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardPagePane
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.platform.ide.bootstrap.StartupWizardStage
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.ui.SeparatorComponent
|
||||
import com.intellij.ui.SeparatorOrientation
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
import java.awt.*
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
// 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.startup.importSettings.wizard.pluginChooser
|
||||
|
||||
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.OnboardingPage
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardController
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardPagePane
|
||||
import com.intellij.openapi.rd.createLifetime
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.platform.ide.bootstrap.StartupWizardStage
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.jetbrains.rd.util.lifetime.intersect
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Color
|
||||
import java.awt.Component
|
||||
import javax.swing.*
|
||||
|
||||
class PluginChooserPage(val controller: WizardController) : OnboardingPage {
|
||||
|
||||
override val stage: StartupWizardStage = StartupWizardStage.WizardPluginPage
|
||||
|
||||
private val lifetime = controller.lifetime.createNested().intersect(this.createLifetime())
|
||||
|
||||
private val pluginPanes = mutableListOf<WizardPluginPane>()
|
||||
|
||||
private val contentPage: JComponent
|
||||
override fun confirmExit(parentComponent: Component?): Boolean = true
|
||||
|
||||
private val pane = JPanel(BorderLayout(0, 0)).apply {
|
||||
add(JLabel(ImportSettingsBundle.message("choose.keymap.title")).apply {
|
||||
font = JBFont.h1()
|
||||
border = JBUI.Borders.empty(18, 20)
|
||||
|
||||
}, BorderLayout.NORTH)
|
||||
|
||||
val plugins = controller.service.getPluginService().plugins
|
||||
|
||||
val listPane = JPanel(VerticalLayout(JBUI.scale(4))).apply {
|
||||
isOpaque = false
|
||||
plugins.forEach {
|
||||
val pl = WizardPluginPane(it, lifetime)
|
||||
pluginPanes.add(pl)
|
||||
add(pl.pane)
|
||||
}
|
||||
border = JBUI.Borders.empty(10, 0)
|
||||
}
|
||||
add(
|
||||
JBScrollPane(listPane).apply {
|
||||
viewport.isOpaque = false
|
||||
isOpaque = true
|
||||
background = JBColor.namedColor("WelcomeScreen.Details.background", JBColor(Color.white, Color(0x313335)))
|
||||
horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
|
||||
border = JBUI.Borders.empty()
|
||||
}, BorderLayout.CENTER
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
val backAction = controller.createButton(ImportSettingsBundle.message("import.settings.back")) {
|
||||
controller.goToKeymapPage()
|
||||
}
|
||||
|
||||
val continueAction = controller.createDefaultButton(ImportSettingsBundle.message("wizard.button.continue")) {
|
||||
//controller.goToPluginPage()
|
||||
}
|
||||
|
||||
val buttons: List<JButton> = if (SystemInfo.isMac) {
|
||||
listOf(backAction, continueAction)
|
||||
}
|
||||
else listOf(continueAction, backAction)
|
||||
|
||||
|
||||
contentPage = WizardPagePane(pane, buttons)
|
||||
}
|
||||
|
||||
override val content: JComponent = contentPage
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,26 +2,29 @@
|
||||
package com.intellij.ide.startup.importSettings.wizard.pluginChooser
|
||||
|
||||
import com.intellij.ide.startup.importSettings.data.WizardPlugin
|
||||
import com.intellij.ui.AnimatedIcon
|
||||
import com.intellij.ui.components.JBCheckBox
|
||||
import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.ui.dsl.builder.HyperlinkEventAction
|
||||
import com.intellij.ui.dsl.builder.MAX_LINE_LENGTH_WORD_WRAP
|
||||
import com.intellij.ui.dsl.builder.components.DslLabel
|
||||
import com.intellij.ui.dsl.builder.components.DslLabelType
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import com.jetbrains.rd.util.lifetime.Lifetime
|
||||
import com.jetbrains.rd.util.reactive.IProperty
|
||||
import java.awt.GridBagConstraints
|
||||
import java.awt.GridBagLayout
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JEditorPane
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
|
||||
class WizardPluginPane(plugin: WizardPlugin, lifetime: Lifetime) {
|
||||
private var checkBox = CheckBoxComponent(plugin.state, lifetime)
|
||||
class WizardPluginPane(val plugin: WizardPlugin, changeHandler: () -> Unit) {
|
||||
private var checkBox = JBCheckBox().apply {
|
||||
addItemListener { e ->
|
||||
changeHandler()
|
||||
}
|
||||
isOpaque = false
|
||||
}
|
||||
|
||||
val selected: Boolean
|
||||
get() = checkBox.isSelected
|
||||
|
||||
val pane = JPanel(GridBagLayout()).apply {
|
||||
val c = GridBagConstraints()
|
||||
@@ -93,66 +96,4 @@ class WizardPluginPane(plugin: WizardPlugin, lifetime: Lifetime) {
|
||||
|
||||
return dslLabel
|
||||
}
|
||||
|
||||
internal class CheckBoxComponent(state: IProperty<WizardPlugin.State>, lifetime: Lifetime) : JPanel() {
|
||||
private val checkBox: JBCheckBox = JBCheckBox()
|
||||
private val progress: JLabel = JLabel(AnimatedIcon.Default.INSTANCE)
|
||||
private val error: JLabel = JLabel(com.intellij.icons.AllIcons.Ide.FatalError)
|
||||
|
||||
private val controls = listOf<JComponent>(checkBox, progress, error)
|
||||
|
||||
init {
|
||||
layout = VerticalLayout(0, 0)
|
||||
border = JBUI.Borders.empty()
|
||||
|
||||
isOpaque = false
|
||||
checkBox.isOpaque = false
|
||||
|
||||
|
||||
checkBox.isSelected = state.value == WizardPlugin.State.CHECKED
|
||||
checkBox.addItemListener { e ->
|
||||
state.set(if (checkBox.isSelected) WizardPlugin.State.CHECKED else WizardPlugin.State.UNCHECKED)
|
||||
}
|
||||
|
||||
add(checkBox)
|
||||
add(progress)
|
||||
add(error)
|
||||
|
||||
state.advise(lifetime) {
|
||||
when (it) {
|
||||
WizardPlugin.State.UNCHECKED -> {
|
||||
setVisibleControl(checkBox)
|
||||
checkBox.isSelected = false
|
||||
checkBox.isEnabled = true
|
||||
}
|
||||
WizardPlugin.State.CHECKED -> {
|
||||
setVisibleControl(checkBox)
|
||||
checkBox.isSelected = true
|
||||
checkBox.isEnabled = true
|
||||
}
|
||||
WizardPlugin.State.INSTALLED -> {
|
||||
setVisibleControl(checkBox)
|
||||
checkBox.isSelected = true
|
||||
checkBox.isEnabled = false
|
||||
}
|
||||
WizardPlugin.State.ERROR -> {
|
||||
setVisibleControl(error)
|
||||
}
|
||||
WizardPlugin.State.IN_PROGRESS -> {
|
||||
setVisibleControl(progress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setVisibleControl(component: JComponent) {
|
||||
component.isVisible = true
|
||||
|
||||
controls.forEach {
|
||||
if (it != component) {
|
||||
it.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// 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.startup.importSettings.wizard.pluginChooser
|
||||
|
||||
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.OnboardingPage
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardController
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardPagePane
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.platform.ide.bootstrap.StartupWizardStage
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import java.awt.Color
|
||||
import java.awt.Component
|
||||
import java.awt.Dimension
|
||||
import javax.swing.*
|
||||
|
||||
|
||||
class WizardPluginsPage(val controller: WizardController) : OnboardingPage {
|
||||
|
||||
private val pluginService = controller.service.getPluginService()
|
||||
|
||||
override val stage: StartupWizardStage = StartupWizardStage.WizardPluginPage
|
||||
|
||||
private val pluginPanes = mutableListOf<WizardPluginPane>()
|
||||
|
||||
private val contentPage: JComponent
|
||||
|
||||
private val leftLabel = JLabel().apply {
|
||||
border = JBUI.Borders.emptyLeft(26)
|
||||
foreground = UIUtil.getContextHelpForeground()
|
||||
}
|
||||
override fun confirmExit(parentComponent: Component?): Boolean = true
|
||||
|
||||
private fun getSelected(): List<WizardPluginPane> {
|
||||
return pluginPanes.filter { it.selected }.toList()
|
||||
}
|
||||
private fun changeHandler() {
|
||||
val selected = getSelected()
|
||||
when(selected.size) {
|
||||
0 -> {
|
||||
leftLabel.text = ImportSettingsBundle.message("plugins.page.choose.counter.no")
|
||||
continueAction.text = ImportSettingsBundle.message("plugins.page.ok.button.continue.without")
|
||||
}
|
||||
1 -> {
|
||||
leftLabel.text = ImportSettingsBundle.message("plugins.page.choose.counter.one")
|
||||
continueAction.text = ImportSettingsBundle.message("plugins.page.ok.button.install")
|
||||
}
|
||||
else -> {
|
||||
leftLabel.text = ImportSettingsBundle.message("plugins.page.choose.counter.multiple", selected.size)
|
||||
continueAction.text = ImportSettingsBundle.message("plugins.page.ok.button.install")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val pane = BorderLayoutPanel().apply {
|
||||
isOpaque = false
|
||||
addToTop(JLabel(ImportSettingsBundle.message("plugins.page.title")).apply {
|
||||
font = JBFont.h1()
|
||||
border = JBUI.Borders.empty(18, 20)
|
||||
})
|
||||
|
||||
val plugins = pluginService.plugins
|
||||
|
||||
val listPane = JPanel(VerticalLayout(JBUI.scale(4))).apply {
|
||||
isOpaque = false
|
||||
plugins.forEach {
|
||||
val pl = WizardPluginPane(it) { changeHandler() }
|
||||
pluginPanes.add(pl)
|
||||
add(pl.pane)
|
||||
}
|
||||
border = JBUI.Borders.empty(10, 0)
|
||||
}
|
||||
addToCenter(
|
||||
object : JPanel(){
|
||||
override fun getPreferredSize(): Dimension {
|
||||
val preferredSize = super.getPreferredSize()
|
||||
return Dimension(preferredSize.width, 0)
|
||||
}
|
||||
}.apply {
|
||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||
preferredSize = Dimension(preferredSize.width, 0)
|
||||
|
||||
add(JBScrollPane(listPane).apply {
|
||||
viewport.isOpaque = false
|
||||
isOpaque = true
|
||||
background = JBColor.namedColor("WelcomeScreen.Details.background", JBColor(Color.white, Color(0x313335)))
|
||||
horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
|
||||
border = JBUI.Borders.empty()
|
||||
minimumSize = Dimension(0, 0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private val backAction = controller.createButton(ImportSettingsBundle.message("import.settings.back")) {
|
||||
controller.goToKeymapPage()
|
||||
}
|
||||
|
||||
private val continueAction = controller.createDefaultButton(ImportSettingsBundle.message("plugins.page.ok.button.continue.without")) {
|
||||
val ids = getSelected().map { it.plugin.id }.toList()
|
||||
controller.goToInstallPluginPage(ids)
|
||||
}
|
||||
|
||||
init {
|
||||
val buttons: List<JButton> = if (SystemInfo.isMac) {
|
||||
listOf(backAction, continueAction)
|
||||
}
|
||||
else listOf(continueAction, backAction)
|
||||
|
||||
|
||||
contentPage = WizardPagePane(pane, buttons, leftLabel)
|
||||
|
||||
changeHandler()
|
||||
}
|
||||
|
||||
override val content: JComponent = contentPage
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.startup.importSettings.wizard.pluginChooser
|
||||
|
||||
import com.intellij.CommonBundle
|
||||
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.OnboardingPage
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.ProgressCommentLabel
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.WizardController
|
||||
import com.intellij.ide.startup.importSettings.data.PluginImportProgress
|
||||
import com.intellij.openapi.rd.createLifetime
|
||||
import com.intellij.openapi.ui.MessageDialogBuilder
|
||||
import com.intellij.platform.ide.bootstrap.StartupWizardStage
|
||||
import com.intellij.ui.components.panels.VerticalLayout
|
||||
import com.intellij.ui.scale.JBUIScale
|
||||
import com.intellij.util.ui.JBDimension
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.jetbrains.rd.util.lifetime.intersect
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
class WizardProgressPage(val progress: PluginImportProgress, val controller: WizardController) : OnboardingPage {
|
||||
override val stage: StartupWizardStage = StartupWizardStage.WizardProgressPage
|
||||
|
||||
private val lifetime = controller.lifetime.createNested().intersect(this.createLifetime())
|
||||
|
||||
private val icon = JLabel()
|
||||
private val msgLabel = ProgressCommentLabel("")
|
||||
private val jProgressBar = JProgressBar(0, 99).apply {
|
||||
preferredSize = Dimension(JBUI.scale (200), preferredSize.height)
|
||||
}
|
||||
|
||||
private val pane = JPanel(VerticalLayout(JBUI.scale(28))).apply {
|
||||
add(JLabel(ImportSettingsBundle.message("install.plugins.page.title")).apply {
|
||||
font = Font(font.fontName, Font.PLAIN, JBUIScale.scaleFontSize(24f))
|
||||
horizontalAlignment = SwingConstants.CENTER
|
||||
})
|
||||
add(icon.apply {
|
||||
horizontalAlignment = SwingConstants.CENTER
|
||||
})
|
||||
add(JPanel(VerticalLayout(JBUIScale.scale(8))).apply {
|
||||
add(jProgressBar)
|
||||
add(msgLabel.label)
|
||||
})
|
||||
}
|
||||
|
||||
override val content: JComponent = JPanel(GridBagLayout()).apply {
|
||||
preferredSize = JBDimension(640, 457)
|
||||
val gbc = GridBagConstraints()
|
||||
gbc.gridx = 0
|
||||
gbc.gridy = 0
|
||||
gbc.weightx = 1.0
|
||||
gbc.weighty = 1.0
|
||||
add(pane, gbc)
|
||||
border = JBUI.Borders.empty()
|
||||
}
|
||||
|
||||
init {
|
||||
progress.progress.advise(lifetime) {
|
||||
jProgressBar.value = it
|
||||
}
|
||||
progress.progressMessage.advise(lifetime) {
|
||||
msgLabel.text = if (it != null) "<center>$it</center>" else " "
|
||||
}
|
||||
|
||||
progress.icon.advise(lifetime) {
|
||||
icon.icon = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun confirmExit(parentComponent: Component?): Boolean {
|
||||
return MessageDialogBuilder.yesNo(ImportSettingsBundle.message("exit.confirm.title"),
|
||||
ImportSettingsBundle.message("exit.confirm.prompt"))
|
||||
.yesText(ImportSettingsBundle.message("stop.import"))
|
||||
.noText(CommonBundle.getCancelButtonText())
|
||||
.ask(parentComponent)
|
||||
}
|
||||
}
|
||||