From 4910b06f2c1c4a0b2572f01a9681b238fc77bed7 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 19 Jan 2016 17:20:09 +0100 Subject: [PATCH] show "kotlin not configured" editor notification --- .../KotlinSetupSDKNotificationProvider.kt | 44 ++++++++++++++++--- ...rtedAbiVersionNotificationPanelProvider.kt | 16 ++++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt index 51e15e066f1..5c07442a28f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.ProjectTopics import com.intellij.openapi.fileEditor.FileEditor +import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.project.DumbAware import com.intellij.openapi.project.Project @@ -27,6 +28,9 @@ import com.intellij.openapi.roots.ModuleRootEvent import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootModificationUtil import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService +import com.intellij.openapi.ui.popup.JBPopupFactory +import com.intellij.openapi.ui.popup.PopupStep +import com.intellij.openapi.ui.popup.util.BaseListPopupStep import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiFile @@ -36,8 +40,10 @@ import com.intellij.ui.EditorNotifications import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider +import org.jetbrains.kotlin.idea.versions.createComponentActionLabel -// Code is very same to com.intellij.codeInsight.daemon.impl.SetupSDKNotificationProvider +// Code is partially copied from com.intellij.codeInsight.daemon.impl.SetupSDKNotificationProvider class KotlinSetupSDKNotificationProvider( private val myProject: Project, notifications: EditorNotifications) : EditorNotifications.Provider(), DumbAware { @@ -63,17 +69,21 @@ class KotlinSetupSDKNotificationProvider( } val module = ModuleUtilCore.findModuleForPsiElement(psiFile) ?: return null - if (ModuleRootManager.getInstance(module).sdk != null) { - return null + if (ModuleRootManager.getInstance(module).sdk == null) { + return createSetupSdkPanel(myProject, psiFile) } - return createPanel(myProject, psiFile) + if (!isModuleConfigured(module) && UnsupportedAbiVersionNotificationPanelProvider.collectBadRoots(module).isEmpty()) { + return createKotlinNotConfiguredPanel(module) + } + + return null } companion object { private val KEY = Key.create("Setup SDK") - private fun createPanel(project: Project, file: PsiFile): EditorNotificationPanel { + private fun createSetupSdkPanel(project: Project, file: PsiFile): EditorNotificationPanel { return EditorNotificationPanel().apply { setText(ProjectBundle.message("project.sdk.not.defined")) createActionLabel(ProjectBundle.message("project.sdk.setup")) { @@ -88,5 +98,29 @@ class KotlinSetupSDKNotificationProvider( } } } + + private fun createKotlinNotConfiguredPanel(module: Module): EditorNotificationPanel { + return EditorNotificationPanel().apply { + setText("Kotlin not configured") + val configurators = getApplicableConfigurators(module).toList() + if (!configurators.isEmpty()) { + createComponentActionLabel("Configure") { label -> + val step = object : BaseListPopupStep("Choose Configurator", configurators) { + override fun getTextFor(value: KotlinProjectConfigurator?): String { + return value?.presentableText ?: "" + } + + override fun onChosen(selectedValue: KotlinProjectConfigurator?, finalChoice: Boolean): PopupStep<*>? { + selectedValue?.let { + it.configure(module.project, emptyList()) + } + return null + } + } + JBPopupFactory.getInstance().createListPopup(step).showUnderneathOf(label) + } + } + } + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt b/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt index f801edadd2e..fdb1939bbfc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt @@ -107,20 +107,18 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec } private fun createShowPathsActionLabel(module: Module, answer: EditorNotificationPanel, labelText: String) { - val label: Ref = Ref.create() - val action = Runnable { + answer.createComponentActionLabel(labelText) { label -> DumbService.getInstance(project).tryRunReadActionInSmartMode({ val badRoots = collectBadRoots(module) assert(!badRoots.isEmpty()) { "This action should only be called when bad roots are present" } val listPopupModel = LibraryRootsPopupModel("Unsupported format", project, badRoots) val popup = JBPopupFactory.getInstance().createListPopup(listPopupModel) - popup.showUnderneathOf(label.get()) + popup.showUnderneathOf(label) null }, "Can't show all paths during index update") } - label.set(answer.createActionLabel(labelText, action)) } override fun getKey(): Key = KEY @@ -207,7 +205,7 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec OpenFileDescriptor(project, root).navigate(true) } - private fun collectBadRoots(module: Module): Collection { + fun collectBadRoots(module: Module): Collection { val badJVMRoots = getLibraryRootsWithAbiIncompatibleKotlinClasses(module) val badJSRoots = getLibraryRootsWithAbiIncompatibleForKotlinJs(module) @@ -217,3 +215,11 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec } } } + +fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) { + val label: Ref = Ref.create() + val action = Runnable { + callback(label.get()) + } + label.set(createActionLabel(labelText, action)) +}