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:
@@ -56,6 +56,7 @@ public interface KotlinIcons {
|
||||
Icon EXPECT = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/expect.svg");
|
||||
|
||||
Icon LAUNCH = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_launch_configuration.svg");
|
||||
Icon LOAD_SCRIPT_CONFIGURATION = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/loadScriptConfiguration.svg");
|
||||
|
||||
Icon JS = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_js.svg");
|
||||
Icon MPP = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_multiplatform_project.svg");
|
||||
|
||||
+3
-4
@@ -58,9 +58,8 @@ class DefaultScriptConfigurationNotificationFactory : ScriptConfigurationNotific
|
||||
withSelectedEditor(project) { manager ->
|
||||
val existingPanel = notificationPanel
|
||||
if (existingPanel != null) {
|
||||
notificationPanel?.let {
|
||||
manager.removeTopComponent(this, it)
|
||||
}
|
||||
existingPanel.onClick = onClick
|
||||
return@withSelectedEditor
|
||||
}
|
||||
|
||||
val panel = NewLoadConfigurationNotificationPanel(onClick, project)
|
||||
@@ -84,7 +83,7 @@ class DefaultScriptConfigurationNotificationFactory : ScriptConfigurationNotific
|
||||
by UserDataProperty<FileEditor, NewLoadConfigurationNotificationPanel>(Key.create("load.script.configuration.panel"))
|
||||
|
||||
private class NewLoadConfigurationNotificationPanel(
|
||||
val onClick: () -> Unit,
|
||||
var onClick: () -> Unit,
|
||||
project: Project
|
||||
) : EditorNotificationPanel() {
|
||||
|
||||
|
||||
+2
-3
@@ -191,17 +191,16 @@ internal class DefaultScriptConfigurationManager(project: Project) :
|
||||
if (postponeLoading) {
|
||||
ScriptConfigurationNotificationFactory.NOTIFICATION_FACTORY.getPoint(project).extensionList.firstOrNull {
|
||||
it.showNotification(virtualFile, project) {
|
||||
runAsyncLoaders(file, virtualFile, scriptDefinition, async, postponeLoading)
|
||||
runAsyncLoaders(file, virtualFile, scriptDefinition, async, isLoadingPostponed = true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
runAsyncLoaders(file, virtualFile, scriptDefinition, async, postponeLoading)
|
||||
runAsyncLoaders(file, virtualFile, scriptDefinition, async, isLoadingPostponed = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// в нотификации остается старый колбек - нужно перезаписывать колбек
|
||||
private fun runAsyncLoaders(
|
||||
file: KtFile,
|
||||
virtualFile: VirtualFile,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin.scripting.idea">
|
||||
<listener order="first" implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptListener"/>
|
||||
<loader order="first" implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptConfigurationLoader"/>
|
||||
<notificationFactory
|
||||
implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptConfigurationNotificationFactory"
|
||||
/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin.scripting.idea">
|
||||
<listener order="first" implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptListener"/>
|
||||
<loader order="first" implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptConfigurationLoader"/>
|
||||
<notificationFactory
|
||||
implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptConfigurationNotificationFactory"
|
||||
/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
@@ -29,7 +32,6 @@
|
||||
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinMPPGradleProjectTaskRunner" order="first, before gradle"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectSettingsDataService"/>
|
||||
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelsUpdater"/>
|
||||
|
||||
<registryKey key="kotlin.mpp.tests.force.gradle"
|
||||
description="Run multi-platform tests with Gradle runner even if the platform runner is used by default.
|
||||
@@ -44,5 +46,9 @@
|
||||
<action id="Kotlin.Gradle.ShowDslLogs" class="org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs"
|
||||
text="Show Kotlin Gradle DSL Logs" description="Show Kotlin Gradle DSL logs">
|
||||
</action>
|
||||
|
||||
<action id="LoadConfigurationAction" class="org.jetbrains.kotlin.idea.scripting.gradle.LoadConfigurationAction">
|
||||
<add-to-group group-id="ProjectRefreshActionGroup" anchor="first"/>
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.2 1L0 4.2H3.2V1Z" fill="#6E6E6E"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5V1H8V6.22036C7.65722 6.3498 7.32863 6.53708 7.00004 6.79995C5.4637 8.02898 5.47971 9.69698 5.49651 11.4482C5.49827 11.6313 5.50004 11.8154 5.50004 12V12H0V5H4Z" fill="#6E6E6E"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.6456 12.0171L15.6456 15.5887L14.3872 14.3294C13.6029 15.1298 12.4916 15.6024 11.2845 15.5391C9.29176 15.4347 7.71156 13.9053 7.4795 11.9901L8.84058 12.1084C9.10844 13.2651 10.1149 14.1538 11.3598 14.2191C12.1761 14.2619 12.9276 13.9418 13.4574 13.3998L12.0739 12.0171L15.6456 12.0171ZM11.708 7.45806C13.6743 7.5611 15.2389 9.05146 15.503 10.9309L14.1505 10.8131C13.8623 9.68563 12.8692 8.82621 11.6458 8.7621C10.7935 8.71743 10.012 9.06834 9.47952 9.65429L10.9131 11.0878L7.34133 11.0878L7.34133 7.51612L8.54986 8.7255C9.33683 7.89016 10.4722 7.39329 11.708 7.45806Z" fill="#389FD6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.2 1L0 4.2H3.2V1Z" fill="#AFB1B3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5V1H8V6.22036C7.65722 6.3498 7.32863 6.53708 7.00004 6.79995C5.4637 8.02898 5.47971 9.69698 5.49651 11.4482C5.49827 11.6313 5.50004 11.8154 5.50004 12V12H0V5H4Z" fill="#AFB1B3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.6456 12.0171L15.6456 15.5887L14.3872 14.3294C13.6029 15.1298 12.4916 15.6024 11.2845 15.5391C9.29176 15.4347 7.71156 13.9053 7.4795 11.9901L8.84058 12.1084C9.10844 13.2651 10.1149 14.1538 11.3598 14.2191C12.1761 14.2619 12.9276 13.9418 13.4574 13.3998L12.0739 12.0171L15.6456 12.0171ZM11.708 7.45806C13.6743 7.5611 15.2389 9.05146 15.503 10.9309L14.1505 10.8131C13.8623 9.68563 12.8692 8.82621 11.6458 8.7621C10.7935 8.71743 10.012 9.06834 9.47952 9.65429L10.9131 11.0878L7.34133 11.0878L7.34133 7.51612L8.54986 8.7255C9.33683 7.89016 10.4722 7.39329 11.708 7.45806Z" fill="#3592C4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
Reference in New Issue
Block a user