Implement global notification for configurations update of gradle scripts
For 193: it will be a simple notification at the bottom of the IDEA window For 201: a floating notification in the editor is implemented near "Load Gradle Changes" icon ^KT-34443 Fixed
This commit is contained in:
@@ -53,3 +53,5 @@ notification.title.script.configuration.has.been.changed=Script configurations h
|
||||
notification.text.script.configuration.has.been.changed=Gradle Project needs to be imported to load changes.
|
||||
action.label.import.project=Import Project
|
||||
action.label.enable.auto.import=Enable Auto-Import
|
||||
action.text.load.script.configurations=Load Script Configurations
|
||||
action.description.load.script.configurations=Gradle Kotlin DSL script configuration has been changed. Load changes to get script code insight without loading the external Gradle project.
|
||||
|
||||
@@ -7,10 +7,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.notification.*
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
|
||||
@@ -25,4 +32,77 @@ fun runPartialGradleImport(project: Project) {
|
||||
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private val kotlinDslNotificationGroupId = "Gradle Kotlin DSL Scripts"
|
||||
private var Project.notificationPanel: ScriptConfigurationChangedNotification?
|
||||
by UserDataProperty<Project, ScriptConfigurationChangedNotification>(Key.create("load.script.configuration.panel"))
|
||||
|
||||
|
||||
fun showNotificationForProjectImport(project: Project, callback: () -> Unit) {
|
||||
val existingPanel = project.notificationPanel
|
||||
if (existingPanel != null) {
|
||||
existingPanel.update(callback)
|
||||
return
|
||||
}
|
||||
|
||||
val notificationGroup = NotificationGroup.findRegisteredGroup(kotlinDslNotificationGroupId)
|
||||
if (notificationGroup == null) {
|
||||
NotificationsConfiguration.getNotificationsConfiguration().register(
|
||||
kotlinDslNotificationGroupId, NotificationDisplayType.STICKY_BALLOON, false
|
||||
)
|
||||
}
|
||||
|
||||
val notification = ScriptConfigurationChangedNotification(project, callback)
|
||||
project.notificationPanel = notification
|
||||
notification.notify(project)
|
||||
}
|
||||
|
||||
fun hideNotificationForProjectImport(project: Project): Boolean {
|
||||
if (project.notificationPanel == null) return false
|
||||
project.notificationPanel?.expire()
|
||||
return true
|
||||
}
|
||||
|
||||
private class ScriptConfigurationChangedNotification(val project: Project, onClick: () -> Unit) :
|
||||
Notification(
|
||||
kotlinDslNotificationGroupId,
|
||||
KotlinIcons.LOAD_SCRIPT_CONFIGURATION,
|
||||
KotlinIdeaGradleBundle.message("notification.title.script.configuration.has.been.changed"),
|
||||
null,
|
||||
KotlinIdeaGradleBundle.message("notification.text.script.configuration.has.been.changed"),
|
||||
NotificationType.INFORMATION,
|
||||
null
|
||||
) {
|
||||
|
||||
init {
|
||||
//NotificationGroup.findRegisteredGroup(s) ?: NotificationGroup.balloonGroup(s)
|
||||
|
||||
addAction(LoadConfigurationAction(onClick))
|
||||
addAction(NotificationAction.createSimple(KotlinIdeaGradleBundle.message("action.label.enable.auto.import")) {
|
||||
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
|
||||
val projectSettings = gradleSettings.getLinkedProjectsSettings()
|
||||
.filterIsInstance<GradleProjectSettings>()
|
||||
.firstOrNull()
|
||||
if (projectSettings != null) {
|
||||
projectSettings.isUseAutoImport = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun update(onClick: () -> Unit) {
|
||||
actions.filterIsInstance<LoadConfigurationAction>().forEach { it.onClick = onClick }
|
||||
}
|
||||
|
||||
override fun expire() {
|
||||
super.expire()
|
||||
|
||||
project.notificationPanel = null
|
||||
}
|
||||
|
||||
private class LoadConfigurationAction(var onClick: () -> Unit) : AnAction(KotlinIdeaGradleBundle.message("action.label.import.project")) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
onClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
-4
@@ -7,13 +7,29 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.diff.util.DiffUtil
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.testFramework.LightVirtualFileBase
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleIncrementalResolverPolicy
|
||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.plugins.gradle.service.project.GradlePartialResolverPolicy
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.util.function.Predicate
|
||||
|
||||
fun runPartialGradleImport(project: Project) {
|
||||
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
|
||||
@@ -25,9 +41,62 @@ fun runPartialGradleImport(project: Project) {
|
||||
projectSettings.externalProjectPath,
|
||||
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
|
||||
.projectResolverPolicy(
|
||||
GradleIncrementalResolverPolicy {
|
||||
it is KotlinDslScriptModelResolver
|
||||
}
|
||||
GradlePartialResolverPolicy(Predicate<GradleProjectResolverExtension?> { it is KotlinDslScriptModelResolver })
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private var Project.notificationPanel: Boolean?
|
||||
by UserDataProperty<Project, Boolean>(Key.create("load.script.configuration.panel"))
|
||||
|
||||
|
||||
fun showNotificationForProjectImport(project: Project, callback: () -> Unit) {
|
||||
project.notificationPanel = true
|
||||
(ActionManager.getInstance().getAction("LoadConfigurationAction") as LoadConfigurationAction).onClick = callback
|
||||
}
|
||||
|
||||
fun hideNotificationForProjectImport(project: Project): Boolean {
|
||||
project.notificationPanel = false
|
||||
return true
|
||||
}
|
||||
|
||||
class LoadConfigurationAction : AnAction(
|
||||
KotlinIdeaGradleBundle.message("action.text.load.script.configurations"),
|
||||
KotlinIdeaGradleBundle.message("action.description.load.script.configurations"),
|
||||
KotlinIcons.LOAD_SCRIPT_CONFIGURATION
|
||||
) {
|
||||
|
||||
var onClick = {}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
onClick()
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
ensureValidActionVisibility(e)
|
||||
|
||||
e.presentation.description = KotlinIdeaGradleBundle.message("action.description.load.script.configurations")
|
||||
}
|
||||
|
||||
private fun ensureValidActionVisibility(e: AnActionEvent) {
|
||||
if (e.project?.notificationPanel != true) {
|
||||
e.presentation.isVisible = false
|
||||
return
|
||||
}
|
||||
val editor = e.getData(CommonDataKeys.EDITOR) ?: return
|
||||
when {
|
||||
DiffUtil.isDiffEditor(editor) -> e.presentation.isVisible = false
|
||||
!editor.isScriptEditor() -> e.presentation.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun Editor.isScriptEditor(): Boolean {
|
||||
val documentManager = FileDocumentManager.getInstance()
|
||||
val virtualFile = documentManager.getFile(document)
|
||||
if (virtualFile is LightVirtualFileBase) return false
|
||||
if (virtualFile == null || !virtualFile.isValid) return false
|
||||
|
||||
val project = project ?: return false
|
||||
return virtualFile.findScriptDefinition(project) != null
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationNotificationFactory
|
||||
|
||||
class GradleScriptConfigurationNotificationFactory : ScriptConfigurationNotificationFactory {
|
||||
override fun showNotification(file: VirtualFile, project: Project, onClick: () -> Unit): Boolean {
|
||||
if (isGradleKotlinScript(file) && isGradleImportCanBeUsed(project)) {
|
||||
showNotificationForProjectImport(project, onClick)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hideNotification(file: VirtualFile, project: Project): Boolean {
|
||||
return hideNotificationForProjectImport(project)
|
||||
}
|
||||
|
||||
private fun isGradleImportCanBeUsed(project: Project): Boolean {
|
||||
val gradleVersion = getGradleVersion(project)
|
||||
if (gradleVersion != null && kotlinDslScriptsModelImportSupported(gradleVersion)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user