From f91f570d6ebf62c71742e99e7ac08a07ad4d17b3 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 2 Jan 2020 19:36:33 +0100 Subject: [PATCH] Show progress indicator while unloading plugins GitOrigin-RevId: 6d23a99fd8da419f98f150475f4027e281f4f8dc --- .../intellij/ide/plugins/DynamicPlugins.kt | 19 +++++++++++++++-- .../intellij/ide/plugins/PluginInstaller.java | 9 +++++--- .../plugins/PluginManagerConfigurable.java | 6 +++--- .../plugins/newui/ListPluginComponent.java | 6 +++--- .../ide/plugins/newui/MyPluginModel.java | 21 ++++++++++--------- .../newui/PluginDetailsPageComponent.java | 6 +++--- 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt b/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt index 9946058fdde1..cfae29bd3072 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.plugins import com.intellij.configurationStore.jdomSerializer @@ -20,9 +20,9 @@ import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl import com.intellij.openapi.keymap.impl.BundledKeymapBean import com.intellij.openapi.keymap.impl.BundledKeymapProvider import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.progress.util.PotemkinProgress import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.project.impl.ProjectImpl -import com.intellij.openapi.util.Computable import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.IconLoader import com.intellij.openapi.util.registry.Registry @@ -39,6 +39,7 @@ import com.intellij.util.ui.UIUtil import com.intellij.util.xmlb.BeanBinding import java.text.SimpleDateFormat import java.util.* +import javax.swing.JComponent interface DynamicPluginListener { @JvmDefault @@ -139,6 +140,20 @@ object DynamicPlugins { return containerDescriptor.components.isNullOrEmpty() } + @JvmStatic + @JvmOverloads + fun unloadPluginWithProgress(parentComponent: JComponent?, + pluginDescriptor: IdeaPluginDescriptorImpl, + disable: Boolean = false, + isUpdate: Boolean = false): Boolean { + var result = false + val indicator = PotemkinProgress("Unloading plugin ${pluginDescriptor.name}", null, parentComponent, null) + indicator.runInSwingThread { + result = unloadPlugin(pluginDescriptor, disable, isUpdate) + } + return result + } + @JvmStatic @JvmOverloads fun unloadPlugin(pluginDescriptor: IdeaPluginDescriptorImpl, disable: Boolean = false, isUpdate: Boolean = false): Boolean { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java index 4d6df8f9efe7..e850696788c8 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.plugins; import com.intellij.CommonBundle; @@ -105,8 +105,11 @@ public final class PluginInstaller { StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.DeleteCommand(pluginDescriptor.getPath())); } - public static boolean uninstallDynamicPlugin(IdeaPluginDescriptor pluginDescriptor, boolean isUpdate) { - boolean uninstalledWithoutRestart = DynamicPlugins.unloadPlugin((IdeaPluginDescriptorImpl)pluginDescriptor, false, isUpdate); + public static boolean uninstallDynamicPlugin(@Nullable JComponent parentComponent, IdeaPluginDescriptor pluginDescriptor, boolean isUpdate) { + boolean uninstalledWithoutRestart = parentComponent != null + ? DynamicPlugins.unloadPluginWithProgress(parentComponent, (IdeaPluginDescriptorImpl)pluginDescriptor, false, isUpdate) + : DynamicPlugins.unloadPlugin((IdeaPluginDescriptorImpl)pluginDescriptor, false, isUpdate); + if (uninstalledWithoutRestart) { FileUtil.delete(pluginDescriptor.getPath()); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java index ffa9bd1573c9..55a606c23313 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.plugins; import com.intellij.featureStatistics.FeatureUsageTracker; @@ -1638,7 +1638,7 @@ public class PluginManagerConfigurable @Override public void cancel() { - myPluginModel.removePluginsOnCancel(); + myPluginModel.removePluginsOnCancel(myCardPanel); } @Override @@ -1657,7 +1657,7 @@ public class PluginManagerConfigurable @Override public void reset() { - myPluginModel.removePluginsOnCancel(); + myPluginModel.removePluginsOnCancel(myCardPanel); } @NotNull diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/ListPluginComponent.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/ListPluginComponent.java index f0c394bed9bd..f7419c933078 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/ListPluginComponent.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/ListPluginComponent.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.plugins.newui; import com.intellij.icons.AllIcons; @@ -151,7 +151,7 @@ public class ListPluginComponent extends JPanel { myLayout.addButtonComponent(myInstallButton = new InstallButton(false)); myInstallButton - .addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, null, ModalityState.stateForComponent(myInstallButton))); + .addActionListener(e -> myPluginModel.installOrUpdatePlugin(this, myPlugin, null, ModalityState.stateForComponent(myInstallButton))); myInstallButton.setEnabled(PluginManagerCore.getPlugin(myPlugin.getPluginId()) == null, "Installed"); ColorButton.setWidth72(myInstallButton); } @@ -351,7 +351,7 @@ public class ListPluginComponent extends JPanel { if (myUpdateButton == null) { myLayout.addButtonComponent(myUpdateButton = new UpdateButton(), 0); myUpdateButton.addActionListener( - e -> myPluginModel.installOrUpdatePlugin(myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton))); + e -> myPluginModel.installOrUpdatePlugin(this, myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton))); } else { myUpdateButton.setEnabled(true); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java index 50e47d2134ad..c4a4590aa069 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.plugins.newui; import com.intellij.ide.IdeBundle; @@ -24,6 +24,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.awt.*; import java.io.IOException; import java.util.List; @@ -116,7 +117,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM /** * @return true if changes were applied without restart */ - public boolean apply(Component parent) throws ConfigurationException { + public boolean apply(JComponent parent) throws ConfigurationException { Map enabledMap = getEnabledMap(); List dependencies = new ArrayList<>(); @@ -148,7 +149,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM Set uninstallsRequiringRestart = new HashSet<>(); for (IdeaPluginDescriptor pluginDescriptor : myDynamicPluginsToUninstall) { - if (!PluginInstaller.uninstallDynamicPlugin(pluginDescriptor, false)) { + if (!PluginInstaller.uninstallDynamicPlugin(parent, pluginDescriptor, false)) { uninstallsRequiringRestart.add(pluginDescriptor.getPluginId()); } else { @@ -177,17 +178,17 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM myDynamicPluginsToInstall.clear(); myPluginsToRemoveOnCancel.clear(); - boolean enableDisableAppliedWithoutRestart = applyEnableDisablePlugins(enabledMap); + boolean enableDisableAppliedWithoutRestart = applyEnableDisablePlugins(parent, enabledMap); myDynamicPluginsToUninstall.clear(); return enableDisableAppliedWithoutRestart && uninstallsRequiringRestart.isEmpty() && !installsRequiringRestart; } - public void removePluginsOnCancel() { - myPluginsToRemoveOnCancel.forEach(pluginDescriptor -> PluginInstaller.uninstallDynamicPlugin(pluginDescriptor, false)); + public void removePluginsOnCancel(@Nullable JComponent parentComponent) { + myPluginsToRemoveOnCancel.forEach(pluginDescriptor -> PluginInstaller.uninstallDynamicPlugin(parentComponent, pluginDescriptor, false)); myPluginsToRemoveOnCancel.clear(); } - private boolean applyEnableDisablePlugins(Map enabledMap) { + private boolean applyEnableDisablePlugins(JComponent parentComponent, Map enabledMap) { List pluginDescriptorsToDisable = new ArrayList<>(); List pluginDescriptorsToEnable = new ArrayList<>(); @@ -235,7 +236,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM ContainerUtil.all(pluginDescriptorsToEnable, (plugin) -> DynamicPlugins.allowLoadUnloadWithoutRestart(plugin))) { boolean needRestart = false; for (IdeaPluginDescriptor descriptor : pluginDescriptorsToDisable) { - if (!DynamicPlugins.unloadPlugin((IdeaPluginDescriptorImpl)descriptor, true)) { + if (!DynamicPlugins.unloadPluginWithProgress(parentComponent, (IdeaPluginDescriptorImpl)descriptor, true)) { needRestart = true; break; } @@ -330,7 +331,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM return myInstallingWithUpdatesPlugins.contains(descriptor); } - void installOrUpdatePlugin(@NotNull IdeaPluginDescriptor descriptor, @Nullable IdeaPluginDescriptor updateDescriptor, @NotNull ModalityState modalityState) { + void installOrUpdatePlugin(@Nullable JComponent parentComponent, @NotNull IdeaPluginDescriptor descriptor, @Nullable IdeaPluginDescriptor updateDescriptor, @NotNull ModalityState modalityState) { if (!PluginManagerMain.checkThirdPartyPluginsAllowed(Collections.singletonList(descriptor))) { return; } @@ -342,7 +343,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM allowUninstallWithoutRestart = false; } else if (DynamicPlugins.allowLoadUnloadSynchronously(installedPluginDescriptor)) { - if (!PluginInstaller.uninstallDynamicPlugin(installedPluginDescriptor, true)) { + if (!PluginInstaller.uninstallDynamicPlugin(parentComponent, installedPluginDescriptor, true)) { allowUninstallWithoutRestart = false; } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.java index eff7d53df31f..37d087ed20dd 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.plugins.newui; import com.intellij.icons.AllIcons; @@ -188,11 +188,11 @@ public class PluginDetailsPageComponent extends MultiPanel { myNameAndButtons.addButtonComponent(myUpdateButton = new UpdateButton()); myUpdateButton.addActionListener( - e -> myPluginModel.installOrUpdatePlugin(myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton))); + e -> myPluginModel.installOrUpdatePlugin(this, myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton))); myNameAndButtons.addButtonComponent(myInstallButton = new InstallButton(true)); myInstallButton - .addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, null, ModalityState.stateForComponent(myInstallButton))); + .addActionListener(e -> myPluginModel.installOrUpdatePlugin(this, myPlugin, null, ModalityState.stateForComponent(myInstallButton))); myEnableDisableButton = new JButton(); myEnableDisableButton.addActionListener(e -> myPluginModel.changeEnableDisable(myPlugin));