From 340ad7eadb30114daf2cbc5f06c4b38661823baf Mon Sep 17 00:00:00 2001 From: Vadim Salavatov Date: Thu, 12 Feb 2026 15:56:20 +0100 Subject: [PATCH] IJPL-232707 refactor: convert InstalledPluginsTabSearchResultPanel to Kotlin GitOrigin-RevId: bb6084265e7d23ed48e9a03943f98056202d1518 --- .../InstalledPluginsTabSearchResultPanel.kt | 285 ++++++++---------- 1 file changed, 134 insertions(+), 151 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTabSearchResultPanel.kt b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTabSearchResultPanel.kt index 2b7604f83606..e28c92d24644 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTabSearchResultPanel.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTabSearchResultPanel.kt @@ -1,216 +1,199 @@ // Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.ide.plugins; +package com.intellij.ide.plugins -import com.intellij.ide.IdeBundle; -import com.intellij.ide.impl.ProjectUtil; -import com.intellij.ide.plugins.marketplace.CheckErrorsResult; -import com.intellij.ide.plugins.marketplace.statistics.PluginManagerUsageCollector; -import com.intellij.ide.plugins.newui.ListPluginComponent; -import com.intellij.ide.plugins.newui.MyPluginModel; -import com.intellij.ide.plugins.newui.PluginModelAsyncOperationsExecutor; -import com.intellij.ide.plugins.newui.PluginModelFacade; -import com.intellij.ide.plugins.newui.PluginUiModel; -import com.intellij.ide.plugins.newui.PluginUiModelKt; -import com.intellij.ide.plugins.newui.PluginsGroup; -import com.intellij.ide.plugins.newui.PluginsGroupComponent; -import com.intellij.ide.plugins.newui.PluginsGroupComponentWithProgress; -import com.intellij.ide.plugins.newui.SearchQueryParser; -import com.intellij.ide.plugins.newui.SearchResultPanel; -import com.intellij.ide.plugins.newui.SearchUpDownPopupController; -import com.intellij.ide.plugins.newui.UiPluginManager; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.extensions.PluginId; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.containers.ContainerUtil; -import kotlinx.coroutines.CoroutineScope; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import static com.intellij.ide.plugins.PluginManagerConfigurablePanel.applyUpdates; -import static com.intellij.ide.plugins.PluginManagerConfigurablePanel.containsQuery; +import com.intellij.ide.IdeBundle +import com.intellij.ide.impl.ProjectUtil.getActiveProject +import com.intellij.ide.plugins.InstalledPluginsTab.InstalledSearchOptionAction +import com.intellij.ide.plugins.PluginManagerConfigurablePanel.LinkLabelButton +import com.intellij.ide.plugins.marketplace.statistics.PluginManagerUsageCollector.performInstalledTabSearch +import com.intellij.ide.plugins.marketplace.statistics.PluginManagerUsageCollector.updateAndGetSearchIndex +import com.intellij.ide.plugins.newui.MyPluginModel +import com.intellij.ide.plugins.newui.PluginModelAsyncOperationsExecutor +import com.intellij.ide.plugins.newui.PluginModelFacade +import com.intellij.ide.plugins.newui.PluginUiModel +import com.intellij.ide.plugins.newui.PluginsGroup +import com.intellij.ide.plugins.newui.PluginsGroupComponent +import com.intellij.ide.plugins.newui.PluginsGroupComponentWithProgress +import com.intellij.ide.plugins.newui.SearchQueryParser +import com.intellij.ide.plugins.newui.SearchResultPanel +import com.intellij.ide.plugins.newui.SearchUpDownPopupController +import com.intellij.ide.plugins.newui.UiPluginManager.Companion.getInstance +import com.intellij.ide.plugins.newui.calculateTags +import com.intellij.openapi.actionSystem.ActionManager +import com.intellij.openapi.actionSystem.DefaultActionGroup +import com.intellij.ui.SimpleTextAttributes +import com.intellij.ui.components.labels.LinkListener +import com.intellij.util.containers.ContainerUtil +import kotlinx.coroutines.CoroutineScope +import org.jetbrains.annotations.ApiStatus +import java.awt.event.ActionListener +import java.util.concurrent.atomic.AtomicBoolean +import java.util.function.Consumer +import java.util.function.Supplier @ApiStatus.Internal -class InstalledPluginsTabSearchResultPanel extends SearchResultPanel { - private final @NotNull Consumer mySelectionListener; - private final @Nullable Consumer mySearchInMarketplaceTabHandler; - private final @NotNull PluginModelFacade myPluginModelFacade; - private final @NotNull DefaultActionGroup mySearchActionGroup; - private final @NotNull Supplier myInstalledPanelSupplier; - - InstalledPluginsTabSearchResultPanel(@NotNull CoroutineScope coroutineScope, - SearchUpDownPopupController installedController, - PluginsGroupComponentWithProgress panel, - @NotNull DefaultActionGroup searchActionGroup, - @NotNull Supplier installedPanelSupplier, - @NotNull Consumer selectionListener, - @Nullable Consumer searchInMarketplaceTabHandler, - @NotNull PluginModelFacade pluginModelFacade) { - super(coroutineScope, installedController, panel, false); - mySearchActionGroup = searchActionGroup; - myInstalledPanelSupplier = installedPanelSupplier; - mySelectionListener = selectionListener; - mySearchInMarketplaceTabHandler = searchInMarketplaceTabHandler; - myPluginModelFacade = pluginModelFacade; - } - - @Override - protected void setupEmptyText() { - myPanel.getEmptyText().setText(IdeBundle.message("plugins.configurable.nothing.found")); - var query = getQuery(); +internal class InstalledPluginsTabSearchResultPanel( + coroutineScope: CoroutineScope, + installedController: SearchUpDownPopupController, + panel: PluginsGroupComponentWithProgress, + private val mySearchActionGroup: DefaultActionGroup, + private val myInstalledPanelSupplier: Supplier, + private val mySelectionListener: Consumer, + private val mySearchInMarketplaceTabHandler: Consumer?, + private val myPluginModelFacade: PluginModelFacade, +) : SearchResultPanel(coroutineScope, installedController, panel, false) { + override fun setupEmptyText() { + myPanel.getEmptyText().setText(IdeBundle.message("plugins.configurable.nothing.found")) + val query = query if (query.contains("/downloaded") || query.contains("/userInstalled") || query.contains("/outdated") || query.contains("/enabled") || query.contains("/disabled") || query.contains("/invalid") || - query.contains("/bundled") || query.contains("/updatedBundled")) { - return; + query.contains("/bundled") || query.contains("/updatedBundled") + ) { + return } if (mySearchInMarketplaceTabHandler != null) { - myPanel.getEmptyText().appendSecondaryText(IdeBundle.message("plugins.configurable.search.in.marketplace"), - SimpleTextAttributes.LINK_PLAIN_ATTRIBUTES, - e -> mySearchInMarketplaceTabHandler.accept(query)); + myPanel.getEmptyText().appendSecondaryText( + IdeBundle.message("plugins.configurable.search.in.marketplace"), + SimpleTextAttributes.LINK_PLAIN_ATTRIBUTES, + ActionListener { _ -> mySearchInMarketplaceTabHandler.accept(query) }) } } - @Override - public void setQuery(@NotNull String query) { - super.setQuery(query); - SearchQueryParser.Installed parser = new SearchQueryParser.Installed(query); - for (AnAction action : mySearchActionGroup.getChildren(ActionManager.getInstance())) { - ((InstalledPluginsTab.InstalledSearchOptionAction)action).setState(parser); + override fun setQuery(query: String) { + super.setQuery(query) + val parser = SearchQueryParser.Installed(query) + for (action in mySearchActionGroup.getChildren(ActionManager.getInstance())) { + (action as InstalledSearchOptionAction).setState(parser) } } - @Override - protected void handleQuery(@NotNull String query, @NotNull PluginsGroup result, @NotNull AtomicBoolean runQuery) { - int searchIndex = PluginManagerUsageCollector.updateAndGetSearchIndex(); - myPluginModelFacade.getModel().setInvalidFixCallback(null); - SearchQueryParser.Installed parser = new SearchQueryParser.Installed(query); - List descriptors = myPluginModelFacade.getModel().getInstalledDescriptors(); + override fun handleQuery(query: String, result: PluginsGroup, runQuery: AtomicBoolean) { + val searchIndex = updateAndGetSearchIndex() + myPluginModelFacade.getModel().setInvalidFixCallback(null) + val parser = SearchQueryParser.Installed(query) + val descriptors = myPluginModelFacade.getModel().installedDescriptors if (!parser.vendors.isEmpty()) { - for (Iterator I = descriptors.iterator(); I.hasNext(); ) { + val I = descriptors.iterator() + while (I.hasNext()) { if (!MyPluginModel.isVendor(I.next(), parser.vendors)) { - I.remove(); + I.remove() } } } if (!parser.tags.isEmpty()) { - String sessionId = myPluginModelFacade.getModel().getSessionId(); + val sessionId = myPluginModelFacade.getModel().sessionId - for (Iterator I = descriptors.iterator(); I.hasNext(); ) { - if (!ContainerUtil.intersects(PluginUiModelKt.calculateTags(I.next(), sessionId), parser.tags)) { - I.remove(); + val I = descriptors.iterator() + while (I.hasNext()) { + if (!ContainerUtil.intersects(I.next().calculateTags(sessionId), parser.tags)) { + I.remove() } } } - for (Iterator I = descriptors.iterator(); I.hasNext(); ) { - PluginUiModel descriptor = I.next(); + val I: MutableIterator = descriptors.iterator() + while (I.hasNext()) { + val descriptor = I.next() if (parser.attributes) { if (parser.enabled && - (!myPluginModelFacade.isEnabled(descriptor) || !myPluginModelFacade.getErrors(descriptor).isEmpty())) { - I.remove(); - continue; + (!myPluginModelFacade.isEnabled(descriptor) || !myPluginModelFacade.getErrors(descriptor).isEmpty()) + ) { + I.remove() + continue } if (parser.disabled && - (myPluginModelFacade.isEnabled(descriptor) || !myPluginModelFacade.getErrors(descriptor).isEmpty())) { - I.remove(); - continue; + (myPluginModelFacade.isEnabled(descriptor) || !myPluginModelFacade.getErrors(descriptor).isEmpty()) + ) { + I.remove() + continue } - boolean isBundledOrBundledUpdate = descriptor.isBundled() || descriptor.isBundledUpdate(); + val isBundledOrBundledUpdate = descriptor.isBundled || descriptor.isBundledUpdate if (parser.bundled && !isBundledOrBundledUpdate) { - I.remove(); - continue; + I.remove() + continue } - if (parser.updatedBundled && !descriptor.isBundledUpdate()) { - I.remove(); - continue; + if (parser.updatedBundled && !descriptor.isBundledUpdate) { + I.remove() + continue } if (parser.userInstalled && isBundledOrBundledUpdate) { - I.remove(); - continue; + I.remove() + continue } if (parser.invalid && myPluginModelFacade.getErrors(descriptor).isEmpty()) { - I.remove(); - continue; + I.remove() + continue } - if (parser.needUpdate && !UiPluginManager.getInstance().isNeedUpdate(descriptor.getPluginId())) { - I.remove(); - continue; + if (parser.needUpdate && !getInstance().isNeedUpdate(descriptor.pluginId)) { + I.remove() + continue } } - if (parser.searchQuery != null && !containsQuery(descriptor, parser.searchQuery)) { - I.remove(); + if (parser.searchQuery != null && !PluginManagerConfigurablePanel.containsQuery(descriptor, parser.searchQuery)) { + I.remove() } } - result.addModels(descriptors); - Map errors = UiPluginManager.getInstance() - .loadErrors(myPluginModelFacade.getModel().mySessionId.toString(), - ContainerUtil.map(descriptors, PluginUiModel::getPluginId)); - result.getPreloadedModel().setErrors(MyPluginModel.getErrors(errors)); - result.getPreloadedModel().setPluginInstallationStates(UiPluginManager.getInstance().getInstallationStatesSync()); - PluginManagerUsageCollector.performInstalledTabSearch( - ProjectUtil.getActiveProject(), parser, result.getModels(), searchIndex, null); + result.addModels(descriptors) + val errors = getInstance() + .loadErrors( + myPluginModelFacade.getModel().mySessionId.toString(), + descriptors.map(PluginUiModel::pluginId) + ) + result.getPreloadedModel().setErrors(MyPluginModel.getErrors(errors)) + result.getPreloadedModel().setPluginInstallationStates(getInstance().getInstallationStatesSync()) + performInstalledTabSearch( + getActiveProject(), parser, result.getModels(), searchIndex, null + ) if (!result.getModels().isEmpty()) { if (parser.invalid) { - myPluginModelFacade.getModel().setInvalidFixCallback(() -> { - PluginsGroup group = getGroup(); + myPluginModelFacade.getModel().setInvalidFixCallback(Runnable { + val group = group if (group.ui == null) { - myPluginModelFacade.getModel().setInvalidFixCallback(null); - return; + myPluginModelFacade.getModel().setInvalidFixCallback(null) + return@Runnable } - PluginsGroupComponent resultPanel = getPanel(); + val resultPanel = panel - for (PluginUiModel descriptor : new ArrayList<>(group.getModels())) { + for (descriptor in ArrayList(group.getModels())) { if (myPluginModelFacade.getErrors(descriptor).isEmpty()) { - resultPanel.removeFromGroup(group, descriptor); + resultPanel.removeFromGroup(group, descriptor) } } - group.titleWithCount(); - fullRepaint(); - + group.titleWithCount() + fullRepaint() if (group.getModels().isEmpty()) { - myPluginModelFacade.getModel().setInvalidFixCallback(null); - removeGroup(); + myPluginModelFacade.getModel().setInvalidFixCallback(null) + removeGroup() } - }); + }) } else if (parser.needUpdate) { - result.mainAction = new PluginManagerConfigurablePanel.LinkLabelButton<>(IdeBundle.message("plugin.manager.update.all"), null, (__, ___) -> { - result.mainAction.setEnabled(false); - - for (ListPluginComponent plugin : result.ui.plugins) { - plugin.updatePlugin(); - } - }); + result.mainAction = LinkLabelButton( + IdeBundle.message("plugin.manager.update.all"), + null, + LinkListener { _, _ -> + result.mainAction!!.setEnabled(false) + for (plugin in result.ui.plugins) { + plugin.updatePlugin() + } + }) } - PluginModelAsyncOperationsExecutor.INSTANCE.loadUpdates(getCoroutineScope(), updates -> { + PluginModelAsyncOperationsExecutor.loadUpdates(coroutineScope) { updates -> if (!ContainerUtil.isEmpty(updates)) { - myPostFillGroupCallback = () -> { - //noinspection unchecked - applyUpdates(myPanel, (Collection)updates); - mySelectionListener.accept(myInstalledPanelSupplier.get()); - mySelectionListener.accept(getPanel()); - }; + myPostFillGroupCallback = Runnable { + PluginManagerConfigurablePanel.applyUpdates(myPanel, updates) + mySelectionListener.accept(myInstalledPanelSupplier.get()) + mySelectionListener.accept(panel) + } } - return null; - }); + } } - updatePanel(runQuery); + updatePanel(runQuery) } }