mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
move PKGS tool window code into a new core module
GitOrigin-RevId: 25a7c51e5465f533e852a01bf321f61d3903c839
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2afb98118d
commit
4a00935dc5
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@@ -794,6 +794,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/xdebugger-api/intellij.platform.debugger.iml" filepath="$PROJECT_DIR$/platform/xdebugger-api/intellij.platform.debugger.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/xdebugger-impl/intellij.platform.debugger.impl.iml" filepath="$PROJECT_DIR$/platform/xdebugger-impl/intellij.platform.debugger.impl.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/xdebugger-testFramework/intellij.platform.debugger.testFramework.iml" filepath="$PROJECT_DIR$/platform/xdebugger-testFramework/intellij.platform.debugger.testFramework.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/dependencies-toolwindow/intellij.platform.dependenciesToolwindow.iml" filepath="$PROJECT_DIR$/platform/dependencies-toolwindow/intellij.platform.dependenciesToolwindow.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/build-scripts/dev-server/intellij.platform.devBuildServer.iml" filepath="$PROJECT_DIR$/platform/build-scripts/dev-server/intellij.platform.devBuildServer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/diagnostic/intellij.platform.diagnostic.iml" filepath="$PROJECT_DIR$/platform/diagnostic/intellij.platform.diagnostic.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/diagnostic/telemetry/intellij.platform.diagnostic.telemetry.iml" filepath="$PROJECT_DIR$/platform/diagnostic/telemetry/intellij.platform.diagnostic.telemetry.iml" />
|
||||
|
||||
@@ -101,6 +101,7 @@ private val PLATFORM_IMPLEMENTATION_MODULES = persistentListOf(
|
||||
"intellij.platform.core.ui",
|
||||
"intellij.platform.credentialStore",
|
||||
"intellij.platform.credentialStore.ui",
|
||||
"intellij.platform.dependenciesToolwindow",
|
||||
"intellij.platform.rd.community",
|
||||
"intellij.platform.ml.impl",
|
||||
"intellij.remoteDev.util",
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide" />
|
||||
<orderEntry type="module" module-name="intellij.platform.util.ui" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.core.ui" />
|
||||
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,8 @@
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg height="13" viewBox="0 0 13 13" width="13" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="m0-1h14v14h-14z"/>
|
||||
<path d="m6.5.375 6.125 3.40277778-6.125 3.40277778-6.125-3.40277778zm4.9 5.44444444 1.225.68055556-6.125 3.40277778-6.125-3.40277778 1.225-.68055556 4.9 2.72222223zm0 2.72222223 1.225.68055555-6.125 3.40277778-6.125-3.40277778 1.225-.68055555 4.9 2.72222223z"
|
||||
fill="#6e6e6e"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 603 B |
@@ -0,0 +1,5 @@
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg height="13" viewBox="0 0 13 13" width="13" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m6.5.375 6.125 3.40277778-6.125 3.40277778-6.125-3.40277778zm4.9 5.44444444 1.225.68055556-6.125 3.40277778-6.125-3.40277778 1.225-.68055556 4.9 2.72222223zm0 2.72222223 1.225.68055555-6.125 3.40277778-6.125-3.40277778 1.225-.68055555 4.9 2.72222223z"
|
||||
fill="#afb1b3" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 530 B |
@@ -0,0 +1 @@
|
||||
toolwindow.stripe.Dependencies=Dependencies
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.dependencytoolwindow
|
||||
|
||||
import com.intellij.ide.ui.LafManager
|
||||
import com.intellij.ide.ui.LafManagerListener
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.extensions.ExtensionPointListener
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.extensions.PluginDescriptor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.wm.ToolWindowManager
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import com.intellij.util.messages.Topic
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Runnable
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.channels.ProducerScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
val <T : Any> ExtensionPointName<T>.extensionsFlow: Flow<List<T>>
|
||||
get() = callbackFlow {
|
||||
val listener = object : ExtensionPointListener<T> {
|
||||
override fun extensionAdded(extension: T, pluginDescriptor: PluginDescriptor) {
|
||||
trySendBlocking(extensions.toList())
|
||||
}
|
||||
|
||||
override fun extensionRemoved(extension: T, pluginDescriptor: PluginDescriptor) {
|
||||
trySendBlocking(extensions.toList())
|
||||
}
|
||||
}
|
||||
send(extensions.toList())
|
||||
addExtensionPointListener(listener)
|
||||
awaitClose { removeExtensionPointListener(listener) }
|
||||
}
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
internal class DependencyToolwindowLifecycleScope : CoroutineScope, Disposable {
|
||||
internal val dispatcher =
|
||||
AppExecutorUtil.getAppExecutorService().asCoroutineDispatcher()
|
||||
|
||||
private val supervisor = SupervisorJob()
|
||||
|
||||
override val coroutineContext = SupervisorJob() + CoroutineName(this::class.qualifiedName!!) + dispatcher
|
||||
|
||||
override fun dispose() {
|
||||
cancel("Disposing ${this::class.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getLifecycleScope(project: Project): DependencyToolwindowLifecycleScope = project.service()
|
||||
|
||||
fun <L : Any, K> Project.messageBusFlow(
|
||||
topic: Topic<L>,
|
||||
initialValue: (suspend () -> K)? = null,
|
||||
listener: suspend ProducerScope<K>.() -> L
|
||||
): Flow<K> {
|
||||
return callbackFlow {
|
||||
initialValue?.let { send(it()) }
|
||||
val connection = messageBus.simpleConnect()
|
||||
connection.subscribe(topic, listener())
|
||||
awaitClose { connection.disconnect() }
|
||||
}
|
||||
}
|
||||
|
||||
internal val Project.lookAndFeelFlow: Flow<LafManager>
|
||||
get() = messageBusFlow(LafManagerListener.TOPIC, { LafManager.getInstance()!! }) {
|
||||
LafManagerListener { trySend(it) }
|
||||
}
|
||||
|
||||
internal fun DependenciesToolWindowTabProvider.isAvailableFlow(project: Project): Flow<Boolean> {
|
||||
return callbackFlow {
|
||||
val sub = addIsAvailableChangesListener(project) { trySend(it) }
|
||||
awaitClose { sub.unsubscribe() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.dependencytoolwindow
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.content.Content
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
interface DependenciesToolWindowTabProvider {
|
||||
companion object {
|
||||
private val extensionPointName = ExtensionPointName<DependenciesToolWindowTabProvider>("com.intellij.dependenciesToolWindow.tabProvider")
|
||||
|
||||
internal fun availableTabsFlow(project: Project): Flow<List<DependenciesToolWindowTabProvider>> {
|
||||
return extensionPointName.extensionsFlow.flatMapLatest { extensions ->
|
||||
channelFlow {
|
||||
send(extensions.filter { it.isAvailable(project) })
|
||||
extensions.map { extension -> extension.isAvailableFlow(project) }
|
||||
.merge()
|
||||
.onEach {
|
||||
val element = extensions.filter { it.isAvailable(project) }
|
||||
send(element)
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun extensions(project: Project): List<DependenciesToolWindowTabProvider> {
|
||||
return extensionPointName.extensionList.filter { it.isAvailable(project) }
|
||||
}
|
||||
}
|
||||
|
||||
fun provideTab(project: Project): Content
|
||||
|
||||
fun isAvailable(project: Project): Boolean
|
||||
|
||||
fun addIsAvailableChangesListener(project: Project, callback: (Boolean) -> Unit): Subscription
|
||||
|
||||
fun interface Subscription {
|
||||
/**
|
||||
* Stops the listeners that generated this subscription.
|
||||
*/
|
||||
fun unsubscribe()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet")
|
||||
|
||||
package com.intellij.dependencytoolwindow
|
||||
|
||||
import com.intellij.DynamicBundle
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.startup.ProjectPostStartupActivity
|
||||
import com.intellij.openapi.wm.RegisterToolWindowTask
|
||||
import com.intellij.openapi.wm.ToolWindow
|
||||
import com.intellij.openapi.wm.ToolWindowManager
|
||||
import com.intellij.openapi.wm.ex.ToolWindowEx
|
||||
import com.intellij.ui.content.Content
|
||||
import com.intellij.ui.content.ContentManager
|
||||
import com.intellij.ui.content.ContentManagerEvent
|
||||
import com.intellij.ui.content.ContentManagerListener
|
||||
import icons.PlatformDependencyToolwindowIcons
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
import java.util.function.Supplier
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class DependencyToolWindowFactory : ProjectPostStartupActivity {
|
||||
companion object {
|
||||
const val toolWindowId = "Dependencies"
|
||||
|
||||
private fun getToolWindow(project: Project) = ToolWindowManager.getInstance(project).getToolWindow(toolWindowId)
|
||||
|
||||
fun activateToolWindow(project: Project, tab: Content? = null, action: () -> Unit) {
|
||||
val toolWindow = getToolWindow(project) ?: return
|
||||
toolWindow.activate(action, true, true)
|
||||
tab?.let { toolWindow.contentManager.setSelectedContent(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun execute(project: Project) {
|
||||
withContext(Dispatchers.toolWindowManager(project)) {
|
||||
DependenciesToolWindowTabProvider.availableTabsFlow(project)
|
||||
.filter { it.isNotEmpty() }
|
||||
.take(1)
|
||||
.map {
|
||||
RegisterToolWindowTask.closable(
|
||||
id = toolWindowId,
|
||||
stripeTitle = DependencyToolWindowBundle.messagePointer("toolwindow.stripe.Dependencies"),
|
||||
icon = PlatformDependencyToolwindowIcons.ArtifactSmall
|
||||
)
|
||||
}
|
||||
.map { toolWindowTask -> ToolWindowManager.getInstance(project).registerToolWindow(toolWindowTask) }
|
||||
.collect { toolWindow -> initializeToolWindow(toolWindow, project) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeToolWindow(toolWindow: ToolWindow, project: Project) {
|
||||
toolWindow.contentManager.addSelectionChangedListener { event ->
|
||||
if (toolWindow is ToolWindowEx) {
|
||||
toolWindow.setAdditionalGearActions(null)
|
||||
(event.content.component as? HasToolWindowActions)
|
||||
?.also { toolWindow.setAdditionalGearActions(it.gearActions) }
|
||||
}
|
||||
toolWindow.setTitleActions(emptyList())
|
||||
(event.content.component as? HasToolWindowActions)
|
||||
?.titleActions
|
||||
?.also { toolWindow.setTitleActions(it.toList()) }
|
||||
}
|
||||
|
||||
toolWindow.isAvailable = false
|
||||
toolWindow.contentManager.removeAllContents(true)
|
||||
|
||||
DependenciesToolWindowTabProvider.availableTabsFlow(project)
|
||||
.flowOn(getLifecycleScope(project).dispatcher)
|
||||
.map { it.map { provider -> provider.provideTab(project) } }
|
||||
.onEach { change ->
|
||||
val removedContent = toolWindow.contentManager.contents.filter { it !in change }.toSet()
|
||||
val newContent = change.filter { it !in toolWindow.contentManager.contents }
|
||||
val contentOrder = (toolWindow.contentManager.contents.toList() - removedContent + newContent)
|
||||
.sortedBy { it.toolwindowTitle }
|
||||
.mapIndexed { index, content -> content to index }
|
||||
.toMap()
|
||||
removedContent.forEach { toolWindow.contentManager.removeContent(it, true) }
|
||||
newContent.forEach { content ->
|
||||
contentOrder.get(content)?.let { order -> toolWindow.contentManager.addContent(content, order) }
|
||||
?: toolWindow.contentManager.addContent(content)
|
||||
}
|
||||
toolWindow.isAvailable = change.isNotEmpty()
|
||||
}
|
||||
.flowOn(Dispatchers.EDT)
|
||||
.launchIn(getLifecycleScope(project))
|
||||
|
||||
project.lookAndFeelFlow
|
||||
.onEach {
|
||||
toolWindow.contentManager.component.invalidate()
|
||||
toolWindow.contentManager.component.repaint()
|
||||
}
|
||||
.flowOn(Dispatchers.EDT)
|
||||
.launchIn(getLifecycleScope(project))
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
private fun SelectionChangedListener(action: (ContentManagerEvent) -> Unit): ContentManagerListener {
|
||||
return object : ContentManagerListener {
|
||||
override fun selectionChanged(event: ContentManagerEvent) {
|
||||
action(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ContentManager.addSelectionChangedListener(action: (ContentManagerEvent) -> Unit): ContentManagerListener {
|
||||
return SelectionChangedListener(action).also(::addContentManagerListener)
|
||||
}
|
||||
|
||||
private const val BUNDLE_NAME = "messages.dependenciesToolwindow"
|
||||
|
||||
private object DependencyToolWindowBundle : DynamicBundle(BUNDLE_NAME) {
|
||||
@Nls
|
||||
fun messagePointer(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg params: Any): Supplier<String> {
|
||||
return getLazyMessage(key, *params)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnusedReceiverParameter")
|
||||
private fun Dispatchers.toolWindowManager(project: Project): CoroutineDispatcher = object : CoroutineDispatcher() {
|
||||
override fun dispatch(context: CoroutineContext, block: Runnable) = ToolWindowManager.getInstance(project).invokeLater(block)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.dependencytoolwindow
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
|
||||
interface HasToolWindowActions {
|
||||
val gearActions: ActionGroup?
|
||||
val titleActions: List<AnAction>
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package icons;
|
||||
|
||||
import com.intellij.ui.IconManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* NOTE THIS FILE IS AUTO-GENERATED
|
||||
* DO NOT EDIT IT BY HAND, run "Generate icon classes" configuration instead
|
||||
*/
|
||||
public final class PlatformDependencyToolwindowIcons {
|
||||
private static @NotNull Icon load(@NotNull String path, int cacheKey, int flags) {
|
||||
return IconManager.getInstance().loadRasterizedIcon(path, PlatformDependencyToolwindowIcons.class.getClassLoader(), cacheKey, flags);
|
||||
}
|
||||
/** 13x13 */ public static final @NotNull Icon ArtifactSmall = load("icons/artifactSmall.svg", 1537187804, 2);
|
||||
}
|
||||
@@ -63,6 +63,7 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.configurationStore.impl" scope="RUNTIME" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="imageio-tiff" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.credentialStore.ui" scope="RUNTIME" />
|
||||
<orderEntry type="module" module-name="intellij.platform.dependenciesToolwindow" scope="RUNTIME" />
|
||||
<orderEntry type="library" name="StreamEx" level="project" />
|
||||
<orderEntry type="library" name="jediterm-pty" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<idea-plugin>
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="com.intellij.dependenciesToolWindow.tabProvider"
|
||||
interface="com.intellij.dependencytoolwindow.DependenciesToolWindowTabProvider"
|
||||
dynamic="true"/>
|
||||
</extensionPoints>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<applicationService serviceInterface="com.intellij.openapi.project.impl.ProjectStoreFactory"
|
||||
serviceImplementation="com.intellij.configurationStore.PlatformLangProjectStoreFactory"
|
||||
@@ -1536,6 +1541,7 @@
|
||||
|
||||
<postStartupActivity implementation="com.intellij.lang.documentation.ide.impl.DocumentationAutoPopup"/>
|
||||
<postStartupActivity implementation="com.intellij.codeInsight.documentation.DocumentationSettingsListener"/>
|
||||
<backgroundPostStartupActivity implementation="com.intellij.dependencytoolwindow.DependencyToolWindowFactory"/>
|
||||
<lang.documentation implementation="com.intellij.lang.documentation.symbol.impl.DefaultTargetSymbolDocumentationTargetProvider"/>
|
||||
<lang.documentationLinkHandler implementation="com.intellij.lang.documentation.psi.PsiDocumentationLinkHandler"/>
|
||||
<projectService serviceInterface="com.intellij.lang.documentation.ide.IdeDocumentationTargetProvider"
|
||||
|
||||
@@ -67,5 +67,6 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.statistics" />
|
||||
<orderEntry type="module" module-name="intellij.platform.util.ui" />
|
||||
<orderEntry type="module" module-name="intellij.repository.search" />
|
||||
<orderEntry type="module" module-name="intellij.platform.dependenciesToolwindow" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -16,10 +16,6 @@ Supports Maven and Gradle projects.
|
||||
interface="com.jetbrains.packagesearch.intellij.plugin.extensibility.ProjectModuleOperationProvider"
|
||||
dynamic="true"/>
|
||||
|
||||
<extensionPoint qualifiedName="com.intellij.packagesearch.dependenciesToolwindowTabProvider"
|
||||
interface="com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.DependenciesToolwindowTabProvider"
|
||||
dynamic="true"/>
|
||||
|
||||
<extensionPoint qualifiedName="com.intellij.packagesearch.coroutineProjectModuleOperationProvider"
|
||||
interface="com.jetbrains.packagesearch.intellij.plugin.extensibility.CoroutineProjectModuleOperationProvider"
|
||||
dynamic="true"/>
|
||||
@@ -84,10 +80,10 @@ Supports Maven and Gradle projects.
|
||||
<packagesearch.flowModuleChangesSignalProvider
|
||||
implementation="com.jetbrains.packagesearch.intellij.plugin.extensibility.ExternalProjectSignalProvider"/>
|
||||
|
||||
<packagesearch.dependenciesToolwindowTabProvider
|
||||
<dependenciesToolWindow.tabProvider
|
||||
implementation="com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackagesListPanelProvider"/>
|
||||
|
||||
<packagesearch.dependenciesToolwindowTabProvider
|
||||
<dependenciesToolWindow.tabProvider
|
||||
implementation="com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.RepositoryManagementPanelProvider"/>
|
||||
|
||||
<projectService
|
||||
@@ -129,8 +125,6 @@ Supports Maven and Gradle projects.
|
||||
|
||||
<statistics.validation.customValidationRule implementation="com.jetbrains.packagesearch.intellij.plugin.fus.TopPackageIdValidationRule"/>
|
||||
|
||||
<backgroundPostStartupActivity implementation="com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackageSearchToolWindowFactory"/>
|
||||
|
||||
<!--suppress PluginXmlCapitalization -->
|
||||
<notificationGroup displayType="BALLOON"
|
||||
id="packagesearch.notification"
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
package com.jetbrains.packagesearch.intellij.plugin.actions
|
||||
|
||||
import com.intellij.dependencytoolwindow.DependencyToolWindowFactory
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.psi.PsiDirectory
|
||||
@@ -30,7 +32,7 @@ import com.intellij.psi.util.PsiUtilBase
|
||||
import com.jetbrains.packagesearch.PackageSearchIcons
|
||||
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle
|
||||
import com.jetbrains.packagesearch.intellij.plugin.extensibility.CoroutineProjectModuleOperationProvider
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackageSearchToolWindowFactory
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackagesListPanelProvider
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.ModuleModel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.TargetModules
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.packageSearchProjectService
|
||||
@@ -69,7 +71,7 @@ class AddDependencyAction : AnAction(
|
||||
|
||||
val selectedModule = findSelectedModule(e, modules) ?: return
|
||||
|
||||
PackageSearchToolWindowFactory.activateToolWindow(project) {
|
||||
DependencyToolWindowFactory.activateToolWindow(project, project.service<PackagesListPanelProvider.PanelContainer>().packageManagementPanel) {
|
||||
project.pkgsUiStateModifier.setTargetModules(TargetModules.One(selectedModule))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jetbrains.packagesearch.intellij.plugin.data
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
||||
import com.intellij.dependencytoolwindow.DependencyToolWindowFactory
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.components.Service
|
||||
@@ -26,7 +27,6 @@ import com.intellij.psi.PsiManager
|
||||
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle
|
||||
import com.jetbrains.packagesearch.intellij.plugin.PluginEnvironment
|
||||
import com.jetbrains.packagesearch.intellij.plugin.extensibility.ProjectModule
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackageSearchToolWindowFactory
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.KnownRepositories
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.ModuleModel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.ProjectDataProvider
|
||||
@@ -61,7 +61,6 @@ import com.jetbrains.packagesearch.intellij.plugin.util.whileLoading
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
@@ -71,11 +70,9 @@ import kotlinx.coroutines.flow.combineTransform
|
||||
import kotlinx.coroutines.flow.consumeAsFlow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -170,7 +167,7 @@ internal class PackageSearchProjectService(private val project: Project) {
|
||||
val projectModulesStateFlow = projectModulesSharedFlow.stateIn(project.lifecycleScope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
val isAvailable
|
||||
get() = projectModulesStateFlow.value.isNotEmpty() || !isComputationAllowed
|
||||
get() = projectModulesStateFlow.value.isNotEmpty()
|
||||
|
||||
private val knownRepositoriesFlow = timer(1.hours)
|
||||
.mapLatestTimedWithLoading("knownRepositoriesFlow", knownRepositoriesLoadingFlow) { dataProvider.fetchKnownRepositories() }
|
||||
@@ -306,7 +303,7 @@ internal class PackageSearchProjectService(private val project: Project) {
|
||||
var controller: BackgroundLoadingBarController? = null
|
||||
|
||||
project.toolWindowManagerFlow
|
||||
.filter { it.id == PackageSearchToolWindowFactory.ToolWindowId }
|
||||
.filter { it.id == DependencyToolWindowFactory.toolWindowId }
|
||||
.take(1)
|
||||
.onEach { canShowLoadingBar.emit(true) }
|
||||
.launchIn(project.lifecycleScope)
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.jetbrains.packagesearch.intellij.plugin.intentions
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.dependencytoolwindow.DependencyToolWindowFactory
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Iconable
|
||||
@@ -25,7 +27,7 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.jetbrains.packagesearch.PackageSearchIcons
|
||||
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackageSearchToolWindowFactory
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackagesListPanelProvider
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.pkgsUiStateModifier
|
||||
|
||||
class PackageSearchUnresolvedReferenceQuickFix(private val ref: PsiReference) : IntentionAction, LowPriorityAction, Iconable {
|
||||
@@ -34,7 +36,7 @@ class PackageSearchUnresolvedReferenceQuickFix(private val ref: PsiReference) :
|
||||
Regex("(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.)*\\p{Lu}\\p{javaJavaIdentifierPart}+")
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
PackageSearchToolWindowFactory.activateToolWindow(project) {
|
||||
DependencyToolWindowFactory.activateToolWindow(project, project.service<PackagesListPanelProvider.PanelContainer>().packageManagementPanel) {
|
||||
project.pkgsUiStateModifier.setSearchQuery(ref.canonicalText)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,12 @@ package com.jetbrains.packagesearch.intellij.plugin.ui.services
|
||||
|
||||
import com.intellij.buildsystem.model.unified.UnifiedCoordinates
|
||||
import com.intellij.buildsystem.model.unified.UnifiedDependency
|
||||
import com.intellij.dependencytoolwindow.DependencyToolWindowFactory
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackageSearchToolWindowFactory
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.PackagesListPanelProvider
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.ModuleModel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.TargetModules
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.lifecycleScope
|
||||
@@ -31,7 +32,7 @@ import com.jetbrains.packagesearch.intellij.plugin.util.pkgsUiStateModifier
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class DependencyNavigationService(private val project: Project) {
|
||||
internal class DependencyNavigationService(private val project: Project) {
|
||||
|
||||
/**
|
||||
* Open the Dependency toolwindows at the selected [module] if found and searches for the first
|
||||
@@ -83,7 +84,7 @@ class DependencyNavigationService(private val project: Project) {
|
||||
|
||||
private fun onSuccess(moduleModel: ModuleModel, dependency: UnifiedDependency): NavigationResult.Success {
|
||||
project.lifecycleScope.launch(Dispatchers.EDT) {
|
||||
PackageSearchToolWindowFactory.activateToolWindow(project) {
|
||||
DependencyToolWindowFactory.activateToolWindow(project, project.service<PackagesListPanelProvider.PanelContainer>().packageManagementPanel) {
|
||||
project.pkgsUiStateModifier.setTargetModules(TargetModules.from(moduleModel))
|
||||
project.pkgsUiStateModifier.setDependency(dependency)
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.content.Content
|
||||
import com.jetbrains.packagesearch.intellij.plugin.extensibility.Subscription
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.extensionsFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
interface DependenciesToolwindowTabProvider {
|
||||
|
||||
companion object {
|
||||
|
||||
private val extensionPointName: ExtensionPointName<DependenciesToolwindowTabProvider>
|
||||
get() = ExtensionPointName.create("com.intellij.packagesearch.dependenciesToolwindowTabProvider")
|
||||
|
||||
internal fun availableTabsFlow(project: Project): Flow<List<DependenciesToolwindowTabProvider>> =
|
||||
extensionPointName.extensionsFlow.flatMapLatest { extensions ->
|
||||
channelFlow {
|
||||
send(extensions.filter { it.isAvailable(project) })
|
||||
extensions.map { extension -> extension.isAvailableFlow(project) }
|
||||
.merge()
|
||||
.onEach {
|
||||
val element = extensions.filter { it.isAvailable(project) }
|
||||
send(element)
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun extensions(project: Project) =
|
||||
extensionPointName.extensions.toList().filter { it.isAvailable(project) }
|
||||
}
|
||||
|
||||
fun provideTab(project: Project): Content
|
||||
|
||||
fun isAvailable(project: Project): Boolean
|
||||
|
||||
fun addIsAvailableChangesListener(project: Project, callback: (Boolean) -> Unit): Subscription
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.startup.ProjectPostStartupActivity
|
||||
import com.intellij.openapi.wm.RegisterToolWindowTask
|
||||
import com.intellij.openapi.wm.ToolWindowManager
|
||||
import com.jetbrains.packagesearch.PackageSearchIcons
|
||||
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class PackageSearchToolWindowFactory : ProjectPostStartupActivity {
|
||||
companion object {
|
||||
internal val ToolWindowId = PackageSearchBundle.message("toolwindow.stripe.Dependencies")
|
||||
|
||||
private fun getToolWindow(project: Project) = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId)
|
||||
|
||||
fun activateToolWindow(project: Project, action: () -> Unit) {
|
||||
getToolWindow(project)?.activate(action, true, true)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun execute(project: Project) {
|
||||
withContext(Dispatchers.toolWindowManager(project)) {
|
||||
DependenciesToolwindowTabProvider.availableTabsFlow(project)
|
||||
.filter { it.isNotEmpty() }
|
||||
.take(1)
|
||||
.map {
|
||||
RegisterToolWindowTask.closable(
|
||||
ToolWindowId,
|
||||
PackageSearchBundle.messagePointer("toolwindow.stripe.Dependencies"),
|
||||
PackageSearchIcons.ArtifactSmall
|
||||
)
|
||||
}
|
||||
.map { toolWindowTask -> ToolWindowManager.getInstance(project).registerToolWindow(toolWindowTask) }
|
||||
.collect { toolWindow -> toolWindow.initialize(project) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,23 @@
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow
|
||||
|
||||
import com.intellij.dependencytoolwindow.DependenciesToolWindowTabProvider
|
||||
import com.intellij.dependencytoolwindow.DependenciesToolWindowTabProvider.Subscription
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.Service.Level
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.content.Content
|
||||
import com.intellij.ui.content.ContentFactory
|
||||
import com.jetbrains.packagesearch.intellij.plugin.extensibility.Subscription
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels.management.PackageManagementPanel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.lifecycleScope
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.packageSearchProjectService
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
class PackagesListPanelProvider : DependenciesToolwindowTabProvider {
|
||||
internal class PackagesListPanelProvider : DependenciesToolWindowTabProvider {
|
||||
|
||||
@Service(Level.PROJECT)
|
||||
private class PanelContainer(private val project: Project) {
|
||||
internal class PanelContainer(private val project: Project) {
|
||||
val packageManagementPanel by lazy { PackageManagementPanel(project).initialize(ContentFactory.getInstance()) }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow
|
||||
|
||||
import com.intellij.dependencytoolwindow.DependenciesToolWindowTabProvider
|
||||
import com.intellij.dependencytoolwindow.DependenciesToolWindowTabProvider.Subscription
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.Service.Level
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.content.Content
|
||||
import com.intellij.ui.content.ContentFactory
|
||||
import com.jetbrains.packagesearch.intellij.plugin.extensibility.Subscription
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels.repositories.RepositoryManagementPanel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.FeatureFlags
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.lifecycleScope
|
||||
@@ -18,7 +19,7 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
class RepositoryManagementPanelProvider : DependenciesToolwindowTabProvider {
|
||||
class RepositoryManagementPanelProvider : DependenciesToolWindowTabProvider {
|
||||
|
||||
@Service(Level.PROJECT)
|
||||
private class PanelContainer(private val project: Project) {
|
||||
|
||||
@@ -19,71 +19,13 @@ package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.DataProvider
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.wm.ToolWindow
|
||||
import com.intellij.openapi.wm.ToolWindowManager
|
||||
import com.intellij.openapi.wm.ex.ToolWindowEx
|
||||
import com.intellij.ui.content.Content
|
||||
import com.intellij.ui.content.ContentFactory
|
||||
import com.intellij.util.castSafelyTo
|
||||
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels.HasToolWindowActions
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels.PackageSearchPanelBase
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels.SimpleToolWindowWithToolWindowActionsPanel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels.SimpleToolWindowWithTwoToolbarsPanel
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.updateAndRepaint
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.addSelectionChangedListener
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.lifecycleScope
|
||||
import com.jetbrains.packagesearch.intellij.plugin.util.lookAndFeelFlow
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.JComponent
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
internal fun ToolWindow.initialize(project: Project) {
|
||||
title = PackageSearchBundle.message("toolwindow.stripe.Dependencies")
|
||||
|
||||
contentManager.addSelectionChangedListener { event ->
|
||||
if (this is ToolWindowEx) {
|
||||
setAdditionalGearActions(null)
|
||||
event.content.component.castSafelyTo<HasToolWindowActions>()
|
||||
?.also { setAdditionalGearActions(it.gearActions) }
|
||||
}
|
||||
setTitleActions(emptyList())
|
||||
event.content.component.castSafelyTo<HasToolWindowActions>()
|
||||
?.titleActions
|
||||
?.also { setTitleActions(it.toList()) }
|
||||
}
|
||||
|
||||
isAvailable = false
|
||||
contentManager.removeAllContents(true)
|
||||
|
||||
DependenciesToolwindowTabProvider.availableTabsFlow(project)
|
||||
.flowOn(project.lifecycleScope.coroutineDispatcher)
|
||||
.map { it.map { it.provideTab(project) } }
|
||||
.onEach { change ->
|
||||
val removedContent = contentManager.contents.filter { it !in change }
|
||||
val newContent = change.filter { it !in contentManager.contents }
|
||||
removedContent.forEach { contentManager.removeContent(it, true) }
|
||||
newContent.forEach { contentManager.addContent(it) }
|
||||
isAvailable = change.isNotEmpty()
|
||||
}
|
||||
.flowOn(Dispatchers.EDT)
|
||||
.launchIn(project.lifecycleScope)
|
||||
|
||||
project.lookAndFeelFlow
|
||||
.onEach { contentManager.component.updateAndRepaint() }
|
||||
.flowOn(Dispatchers.EDT)
|
||||
.launchIn(project.lifecycleScope)
|
||||
}
|
||||
|
||||
internal fun PackageSearchPanelBase.initialize(contentFactory: ContentFactory): Content {
|
||||
val panelContent = content // should be executed before toolbars
|
||||
@@ -93,20 +35,30 @@ internal fun PackageSearchPanelBase.initialize(contentFactory: ContentFactory):
|
||||
val titleActions = titleActions
|
||||
|
||||
return if (topToolbar == null) {
|
||||
createSimpleToolWindowWithToolWindowActionsPanel(title, panelContent, toolbar, gearActions, titleActions, contentFactory, this)
|
||||
} else contentFactory.createContent(
|
||||
toolbar?.let {
|
||||
SimpleToolWindowWithTwoToolbarsPanel(
|
||||
it,
|
||||
topToolbar,
|
||||
gearActions,
|
||||
titleActions,
|
||||
panelContent
|
||||
)
|
||||
},
|
||||
title,
|
||||
false
|
||||
).apply { isCloseable = false }
|
||||
createSimpleToolWindowWithToolWindowActionsPanel(
|
||||
title = title,
|
||||
content = panelContent,
|
||||
toolbar = toolbar,
|
||||
gearActions = gearActions,
|
||||
titleActions = titleActions,
|
||||
contentFactory = contentFactory,
|
||||
provider = this
|
||||
)
|
||||
} else {
|
||||
contentFactory.createContent(
|
||||
toolbar?.let {
|
||||
SimpleToolWindowWithTwoToolbarsPanel(
|
||||
it,
|
||||
topToolbar,
|
||||
gearActions,
|
||||
titleActions,
|
||||
panelContent
|
||||
)
|
||||
},
|
||||
title,
|
||||
false
|
||||
).apply { isCloseable = false }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun createSimpleToolWindowWithToolWindowActionsPanel(
|
||||
@@ -114,12 +66,17 @@ internal fun createSimpleToolWindowWithToolWindowActionsPanel(
|
||||
content: JComponent,
|
||||
toolbar: JComponent?,
|
||||
gearActions: ActionGroup?,
|
||||
titleActions: Array<AnAction>?,
|
||||
titleActions: List<AnAction>,
|
||||
contentFactory: ContentFactory,
|
||||
provider: DataProvider
|
||||
): Content {
|
||||
val createContent = contentFactory.createContent(null, title, false)
|
||||
val actionsPanel = SimpleToolWindowWithToolWindowActionsPanel(gearActions, titleActions, false, provider = provider)
|
||||
val actionsPanel = SimpleToolWindowWithToolWindowActionsPanel(
|
||||
gearActions = gearActions,
|
||||
titleActions = titleActions,
|
||||
vertical = false,
|
||||
provider = provider
|
||||
)
|
||||
actionsPanel.setProvideQuickActions(true)
|
||||
actionsPanel.setContent(content)
|
||||
toolbar?.let { actionsPanel.toolbar = it }
|
||||
@@ -130,16 +87,3 @@ internal fun createSimpleToolWindowWithToolWindowActionsPanel(
|
||||
return createContent
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
internal fun Dispatchers.toolWindowManager(project: Project): CoroutineDispatcher = object : CoroutineDispatcher() {
|
||||
|
||||
private val executor = ToolWindowManager.getInstance(project)
|
||||
|
||||
override fun dispatch(context: CoroutineContext, block: Runnable) = executor.invokeLater(block)
|
||||
}
|
||||
|
||||
fun DependenciesToolwindowTabProvider.isAvailableFlow(project: Project) =
|
||||
callbackFlow {
|
||||
val sub = addIsAvailableChangesListener(project) { trySend(it) }
|
||||
awaitClose { sub.unsubscribe() }
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2000-2022 JetBrains s.r.o. and contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
|
||||
internal interface HasToolWindowActions {
|
||||
|
||||
val gearActions: ActionGroup?
|
||||
val titleActions: Array<AnAction>?
|
||||
}
|
||||
@@ -32,11 +32,11 @@ internal abstract class PackageSearchPanelBase(@Nls val title: String) : DataPro
|
||||
|
||||
internal val gearActions: ActionGroup? by lazy { buildGearActions() }
|
||||
|
||||
internal val titleActions: Array<AnAction>? by lazy { buildTitleActions() }
|
||||
internal val titleActions: List<AnAction> by lazy(::buildTitleActions)
|
||||
|
||||
protected abstract fun build(): JComponent
|
||||
protected open fun buildToolbar(): JComponent? = null
|
||||
protected open fun buildTopToolbar(): JComponent? = null
|
||||
protected open fun buildGearActions(): ActionGroup? = null
|
||||
protected open fun buildTitleActions(): Array<AnAction>? = null
|
||||
protected open fun buildTitleActions(): List<AnAction> = emptyList()
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels
|
||||
|
||||
import com.intellij.dependencytoolwindow.HasToolWindowActions
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.DataProvider
|
||||
@@ -23,7 +24,7 @@ import com.intellij.openapi.ui.SimpleToolWindowPanel
|
||||
|
||||
internal class SimpleToolWindowWithToolWindowActionsPanel(
|
||||
override val gearActions: ActionGroup?,
|
||||
override val titleActions: Array<AnAction>?,
|
||||
override val titleActions: List<AnAction>,
|
||||
vertical: Boolean = false,
|
||||
borderless: Boolean = false,
|
||||
val provider: DataProvider
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.panels
|
||||
|
||||
import com.intellij.dependencytoolwindow.HasToolWindowActions
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.DataProvider
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.ui.switcher.QuickActionProvider
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import com.jetbrains.packagesearch.intellij.plugin.ui.PackageSearchUI
|
||||
@@ -37,7 +37,7 @@ internal class SimpleToolWindowWithTwoToolbarsPanel(
|
||||
private val leftToolbar: JComponent,
|
||||
private val topToolbar: JComponent,
|
||||
override val gearActions: ActionGroup?,
|
||||
override val titleActions: Array<AnAction>?,
|
||||
override val titleActions: List<AnAction>,
|
||||
val content: JComponent
|
||||
) : JPanel(), QuickActionProvider, DataProvider, HasToolWindowActions {
|
||||
|
||||
|
||||
@@ -192,10 +192,12 @@ internal class PackageManagementPanel(
|
||||
togglePackageDetailsAction
|
||||
)
|
||||
|
||||
override fun buildTitleActions(): Array<AnAction> = arrayOf(togglePackageDetailsAction)
|
||||
override fun buildTitleActions(): List<AnAction> = listOf(togglePackageDetailsAction)
|
||||
|
||||
override fun getData(dataId: String) = when {
|
||||
PkgsToDAAction.PACKAGES_LIST_PANEL_DATA_KEY.`is`(dataId) -> dataModelStateFlow.value
|
||||
else -> null
|
||||
override fun getData(dataId: String): PackageModel.Installed? {
|
||||
return when {
|
||||
PkgsToDAAction.PACKAGES_LIST_PANEL_DATA_KEY.`is`(dataId) -> dataModelStateFlow.value
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,22 +159,6 @@ internal val Project.lookAndFeelFlow: Flow<LafManager>
|
||||
LafManagerListener { trySend(it) }
|
||||
}
|
||||
|
||||
val <T : Any> ExtensionPointName<T>.extensionsFlow: Flow<List<T>>
|
||||
get() = callbackFlow {
|
||||
val listener = object : ExtensionPointListener<T> {
|
||||
override fun extensionAdded(extension: T, pluginDescriptor: PluginDescriptor) {
|
||||
trySendBlocking(extensions.toList())
|
||||
}
|
||||
|
||||
override fun extensionRemoved(extension: T, pluginDescriptor: PluginDescriptor) {
|
||||
trySendBlocking(extensions.toList())
|
||||
}
|
||||
}
|
||||
send(extensions.toList())
|
||||
addExtensionPointListener(listener)
|
||||
awaitClose { removeExtensionPointListener(listener) }
|
||||
}
|
||||
|
||||
fun Project.hasKotlinModules(): Boolean = ModuleManager.getInstance(this).modules.any { it.hasKotlinFacet() }
|
||||
|
||||
internal fun Module.hasKotlinFacet(): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user