IDEA-214866 Plugins Update dialog

GitOrigin-RevId: 2f7d41a5ea45c1148c4172b75de6aaa7fe3f2d66
This commit is contained in:
Alexander Lobas
2019-12-19 18:01:36 +00:00
committed by intellij-monorepo-bot
parent f61a1eeac0
commit e6de8d8c64
12 changed files with 442 additions and 49 deletions
@@ -64,6 +64,8 @@ import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import static java.lang.System.out;
/**
* @author Alexander Lobas
*/
@@ -104,9 +106,6 @@ public class PluginManagerConfigurable
private SearchResultPanel myMarketplaceSearchPanel;
private SearchResultPanel myInstalledSearchPanel;
private LinkListener<IdeaPluginDescriptor> myNameListener;
private LinkListener<String> mySearchListener;
private final LinkLabel<Object> myUpdateAll = new LinkLabel<>("Update All", null);
private final JLabel myUpdateCounter = new CountComponent();
private final CountIcon myCountIcon = new CountIcon();
@@ -198,13 +197,6 @@ public class PluginManagerConfigurable
});
myPluginModel.setPluginUpdatesService(myPluginUpdatesService);
myNameListener = (aSource, aLinkData) -> {
// TODO: unused
};
mySearchListener = (aSource, aLinkData) -> {
// TODO: unused
};
createMarketplaceTab();
createInstalledTab();
@@ -359,8 +351,7 @@ public class PluginManagerConfigurable
protected JComponent createPluginsPanel(@NotNull Consumer<? super PluginsGroupComponent> selectionListener) {
MultiSelectionEventHandler eventHandler = new MultiSelectionEventHandler();
myMarketplacePanel =
new PluginsGroupComponentWithProgress(new PluginListLayout(), eventHandler, myNameListener,
PluginManagerConfigurable.this.mySearchListener,
new PluginsGroupComponentWithProgress(new PluginListLayout(), eventHandler,
d -> new ListPluginComponent(myPluginModel, d, mySearchListener, true));
myMarketplacePanel.setSelectionListener(selectionListener);
@@ -623,10 +614,8 @@ public class PluginManagerConfigurable
marketplaceController.setSearchResultEventHandler(eventHandler);
PluginsGroupComponentWithProgress panel =
new PluginsGroupComponentWithProgress(new PluginListLayout(), eventHandler, myNameListener,
PluginManagerConfigurable.this.mySearchListener,
descriptor -> new ListPluginComponent(myPluginModel, descriptor, mySearchListener,
true));
new PluginsGroupComponentWithProgress(new PluginListLayout(), eventHandler,
descriptor -> new ListPluginComponent(myPluginModel, descriptor, mySearchListener, true));
panel.setSelectionListener(selectionListener);
registerCopyProvider(panel);
@@ -775,8 +764,7 @@ public class PluginManagerConfigurable
protected JComponent createPluginsPanel(@NotNull Consumer<? super PluginsGroupComponent> selectionListener) {
MultiSelectionEventHandler eventHandler = new MultiSelectionEventHandler();
myInstalledPanel =
new PluginsGroupComponent(new PluginListLayout(), eventHandler, myNameListener,
PluginManagerConfigurable.this.mySearchListener,
new PluginsGroupComponent(new PluginListLayout(), eventHandler,
descriptor -> new ListPluginComponent(myPluginModel, descriptor, mySearchListener, false));
myInstalledPanel.setSelectionListener(selectionListener);
@@ -922,8 +910,7 @@ public class PluginManagerConfigurable
installedController.setSearchResultEventHandler(eventHandler);
PluginsGroupComponent panel =
new PluginsGroupComponent(new PluginListLayout(), eventHandler, myNameListener,
PluginManagerConfigurable.this.mySearchListener,
new PluginsGroupComponent(new PluginListLayout(), eventHandler,
descriptor -> new ListPluginComponent(myPluginModel, descriptor, mySearchListener, false));
panel.setSelectionListener(selectionListener);
@@ -157,6 +157,16 @@ public class BaselinePanel extends NonOpaquePanel {
add(component, null);
}
public void removeButtons() {
List<Component> buttons = new ArrayList<>(myButtonComponents);
myButtonComponents.clear();
myButtonEnableStates = null;
for (Component button : buttons) {
remove(button);
}
}
public void setProgressComponent(@Nullable ListPluginComponent pluginComponent, @NotNull JComponent progressComponent) {
assert myProgressComponent == null;
myProgressComponent = progressComponent;
@@ -54,7 +54,7 @@ public class InstallPluginInfo {
if (myPluginModel == null) {
MyPluginModel.finishInstall(myDescriptor);
closeStatusBarIndicator();
if (success && restartRequired) {
if (success && !cancel && restartRequired) {
ApplicationManager.getApplication().invokeLater(() -> PluginManagerConfigurable.shutdownOrRestartApp());
}
}
@@ -45,6 +45,7 @@ public class ListPluginComponent extends JPanel {
private final boolean myMarketplace;
public IdeaPluginDescriptor myPlugin;
private boolean myUninstalled;
private boolean myOnlyUpdateMode;
public IdeaPluginDescriptor myUpdateDescriptor;
private final JLabel myNameComponent = new JLabel();
@@ -149,7 +150,8 @@ public class ListPluginComponent extends JPanel {
else {
myLayout.addButtonComponent(myInstallButton = new InstallButton(false));
myInstallButton.addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, null, ModalityState.stateForComponent(myInstallButton)));
myInstallButton
.addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, null, ModalityState.stateForComponent(myInstallButton)));
myInstallButton.setEnabled(PluginManagerCore.getPlugin(myPlugin.getPluginId()) == null, "Installed");
ColorButton.setWidth72(myInstallButton);
}
@@ -295,6 +297,17 @@ public class ListPluginComponent extends JPanel {
}
}
public void setOnlyUpdateMode(@Nullable IdeaPluginDescriptor descriptor) {
myOnlyUpdateMode = true;
if (myEnableDisableButton != null) {
myLayout.removeButtonComponent(myEnableDisableButton);
myEnableDisableButton = null;
}
setUpdateDescriptor(descriptor);
}
public void setUpdateDescriptor(@Nullable IdeaPluginDescriptor descriptor) {
if (myUpdateDescriptor == null && descriptor == null) {
return;
@@ -337,9 +350,11 @@ public class ListPluginComponent extends JPanel {
}
if (myUpdateButton == null) {
myLayout.addButtonComponent(myUpdateButton = new UpdateButton(), 0);
myUpdateButton.addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton)));
myUpdateButton.addActionListener(
e -> myPluginModel.installOrUpdatePlugin(myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton)));
}
else {
myUpdateButton.setEnabled(true);
myUpdateButton.setVisible(true);
}
if (myAlignButton != null) {
@@ -350,9 +365,7 @@ public class ListPluginComponent extends JPanel {
doLayout();
}
public void setListeners(@NotNull LinkListener<? super IdeaPluginDescriptor> listener,
@NotNull LinkListener<String> searchListener,
@NotNull EventHandler eventHandler) {
public void setListeners(@NotNull EventHandler eventHandler) {
myEventHandler = eventHandler;
eventHandler.addAll(this);
}
@@ -520,7 +533,7 @@ public class ListPluginComponent extends JPanel {
}
public void updatePlugin() {
if (!myMarketplace && myUpdateButton != null && myUpdateButton.isVisible()) {
if (!myMarketplace && myUpdateButton != null && myUpdateButton.isVisible() && myUpdateButton.isEnabled()) {
myUpdateButton.doClick();
}
}
@@ -533,6 +546,18 @@ public class ListPluginComponent extends JPanel {
return myMarketplace;
}
public boolean isRestartEnabled() {
return myRestartButton != null && myRestartButton.isVisible();
}
public boolean isUpdatedWithoutRestart() {
return myUpdateButton != null && myUpdateButton.isVisible() && !myUpdateButton.isEnabled();
}
public boolean underProgress() {
return myIndicator != null;
}
public void close() {
if (myIndicator != null) {
MyPluginModel.removeProgress(myPlugin, myIndicator);
@@ -581,7 +606,7 @@ public class ListPluginComponent extends JPanel {
for (int i = 0; i < size; i++) {
JButton button = selection.get(i).myUpdateButton;
if (button == null || !button.isVisible()) {
if (button == null || !button.isVisible() || !button.isEnabled()) {
updateButtons = null;
break;
}
@@ -595,6 +620,10 @@ public class ListPluginComponent extends JPanel {
}
}
if (myOnlyUpdateMode) {
return;
}
Pair<Boolean, IdeaPluginDescriptor[]> result = getSelectionNewState(selection);
group.add(new MyAnAction(result.first ? "Enable" : "Disable", null, KeyEvent.VK_SPACE) {
@Override
@@ -663,7 +692,7 @@ public class ListPluginComponent extends JPanel {
boolean update = true;
for (ListPluginComponent component : selection) {
JButton button = component.myUpdateButton;
if (button == null || !button.isVisible()) {
if (button == null || !button.isVisible() || !button.isEnabled()) {
update = false;
break;
}
@@ -680,6 +709,9 @@ public class ListPluginComponent extends JPanel {
}
}
else if (!restart && !update) {
if (myOnlyUpdateMode) {
return;
}
if (keyCode == KeyEvent.VK_SPACE) {
if (selection.size() == 1) {
myPluginModel.changeEnableDisable(selection.get(0).myPlugin);
@@ -422,10 +422,11 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginM
});
}
public void toBackground() {
public boolean toBackground() {
for (InstallPluginInfo info : myInstallingInfos.values()) {
info.toBackground(myStatusBar);
}
return !myInstallingInfos.isEmpty();
}
@NotNull
@@ -187,10 +187,12 @@ public class PluginDetailsPageComponent extends MultiPanel {
myNameAndButtons.addButtonComponent(myRestartButton = new RestartButton(myPluginModel));
myNameAndButtons.addButtonComponent(myUpdateButton = new UpdateButton());
myUpdateButton.addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton)));
myUpdateButton.addActionListener(
e -> myPluginModel.installOrUpdatePlugin(myPlugin, myUpdateDescriptor, ModalityState.stateForComponent(myUpdateButton)));
myNameAndButtons.addButtonComponent(myInstallButton = new InstallButton(true));
myInstallButton.addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, null, ModalityState.stateForComponent(myInstallButton)));
myInstallButton
.addActionListener(e -> myPluginModel.installOrUpdatePlugin(myPlugin, null, ModalityState.stateForComponent(myInstallButton)));
myEnableDisableButton = new JButton();
myEnableDisableButton.addActionListener(e -> myPluginModel.changeEnableDisable(myPlugin));
@@ -216,6 +218,12 @@ public class PluginDetailsPageComponent extends MultiPanel {
}
}
public void setOnlyUpdateMode() {
myNameAndButtons.removeButtons();
myPanel.setBorder(JBUI.Borders.empty(15, 20, 0, 0));
myEmptyPanel.setBorder(null);
}
private void createMetricsPanel(@NotNull JPanel centerPanel) {
// text field without horizontal margins
myVersion = new JTextField();
@@ -5,7 +5,6 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManagerConfigurable;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBPanelWithEmptyText;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.OpaquePanel;
import com.intellij.ui.scale.JBUIScale;
@@ -28,20 +27,14 @@ import java.util.function.Consumer;
*/
public class PluginsGroupComponent extends JBPanelWithEmptyText {
private final EventHandler myEventHandler;
private final LinkListener<IdeaPluginDescriptor> myListener;
private final LinkListener<String> mySearchListener;
private final Function<? super IdeaPluginDescriptor, ? extends ListPluginComponent> myFunction;
private final List<UIPluginGroup> myGroups = new ArrayList<>();
public PluginsGroupComponent(@NotNull LayoutManager layout,
@NotNull EventHandler eventHandler,
@NotNull LinkListener<IdeaPluginDescriptor> listener,
@NotNull LinkListener<String> searchListener,
@NotNull Function<? super IdeaPluginDescriptor, ? extends ListPluginComponent> function) {
super(layout);
myEventHandler = eventHandler;
myListener = listener;
mySearchListener = searchListener;
myFunction = function;
myEventHandler.connect(this);
@@ -195,13 +188,16 @@ public class PluginsGroupComponent extends JBPanelWithEmptyText {
return -1;
}
private void addToGroup(@NotNull PluginsGroup group, @NotNull List<? extends IdeaPluginDescriptor> descriptors, int index, int eventIndex) {
private void addToGroup(@NotNull PluginsGroup group,
@NotNull List<? extends IdeaPluginDescriptor> descriptors,
int index,
int eventIndex) {
for (IdeaPluginDescriptor descriptor : descriptors) {
ListPluginComponent pluginComponent = myFunction.fun(descriptor);
group.ui.plugins.add(pluginComponent);
add(pluginComponent, index);
myEventHandler.addCell(pluginComponent, eventIndex);
pluginComponent.setListeners(myListener, mySearchListener, myEventHandler);
pluginComponent.setListeners(myEventHandler);
if (index != -1) {
index++;
}
@@ -233,7 +229,7 @@ public class PluginsGroupComponent extends JBPanelWithEmptyText {
group.ui.plugins.add(index, pluginComponent);
add(pluginComponent, uiIndex);
myEventHandler.addCell(pluginComponent, anchor);
pluginComponent.setListeners(myListener, mySearchListener, myEventHandler);
pluginComponent.setListeners(myEventHandler);
}
public void removeGroup(@NotNull PluginsGroup group) {
@@ -3,7 +3,6 @@ package com.intellij.ide.plugins.newui;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.Function;
import com.intellij.util.ui.AsyncProcessIcon;
import org.jetbrains.annotations.NotNull;
@@ -20,10 +19,8 @@ public class PluginsGroupComponentWithProgress extends PluginsGroupComponent {
public PluginsGroupComponentWithProgress(@NotNull LayoutManager layout,
@NotNull EventHandler eventHandler,
@NotNull LinkListener<IdeaPluginDescriptor> listener,
@NotNull LinkListener<String> searchListener,
@NotNull Function<? super IdeaPluginDescriptor, ? extends ListPluginComponent> function) {
super(layout, eventHandler, listener, searchListener, function);
super(layout, eventHandler, function);
myIcon.setOpaque(false);
myIcon.setPaintPassiveIcon(false);
add(myIcon);
@@ -58,7 +58,7 @@ public final class PluginDownloader {
private boolean myShownErrors;
private PluginDownloader(IdeaPluginDescriptor descriptor, String url, BuildNumber buildNumber) {
private PluginDownloader(@NotNull IdeaPluginDescriptor descriptor, @NotNull String url, @Nullable BuildNumber buildNumber) {
myPluginId = descriptor.getPluginId();
myPluginName = descriptor.getName();
myProductCode = descriptor.getProductCode();
@@ -0,0 +1,360 @@
// 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.
package com.intellij.openapi.updateSettings.impl;
import com.intellij.CommonBundle;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManagerConfigurable;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.PluginManagerMain;
import com.intellij.ide.plugins.newui.*;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.OpaquePanel;
import com.intellij.util.LineSeparator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBDimension;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;
/**
* @author Alexander Lobas
*/
public class PluginUpdateDialog extends DialogWrapper {
private final Collection<PluginDownloader> myDownloaders;
private final MyPluginModel myPluginModel = new MyPluginModel() {
};
private final PluginsGroupComponent myPluginsPanel;
private final PluginsGroup myGroup;
private final PluginDetailsPageComponent myDetailsPage;
private final Action myIgnoreAction;
public PluginUpdateDialog(@NotNull Collection<PluginDownloader> uploadedPlugins) {
super(true);
setTitle("Plugin Updates");
myDownloaders = uploadedPlugins;
myIgnoreAction = new AbstractAction(
IdeBundle.message(uploadedPlugins.size() == 1 ? "updates.ignore.update.button" : "updates.ignore.updates.button")) {
@Override
public void actionPerformed(ActionEvent e) {
close(CANCEL_EXIT_CODE);
ignorePlugins(ContainerUtil.map(myGroup.ui.plugins, component -> component.myUpdateDescriptor));
}
};
myPluginModel.setTopController(new Configurable.TopComponentController() {
@Override
public void setLeftComponent(@Nullable Component component) {
}
@Override
public void showProgress(boolean start) {
}
});
myPluginModel.setPluginUpdatesService(new PluginUpdatesService() {
@Override
public void finishUpdate(@NotNull IdeaPluginDescriptor descriptor) {
updateButtons();
}
@Override
public void finishUpdate() {
updateButtons();
}
});
myDetailsPage = new PluginDetailsPageComponent(myPluginModel, emptyListener(), false) {
@Override
public void showProgress() {
}
};
myDetailsPage.setOnlyUpdateMode();
MultiSelectionEventHandler eventHandler = new MultiSelectionEventHandler();
myPluginsPanel = new PluginsGroupComponent(new PluginListLayout(), eventHandler, descriptor -> createListComponent(descriptor));
PluginManagerConfigurable.registerCopyProvider(myPluginsPanel);
myPluginsPanel.setSelectionListener(__ -> {
List<ListPluginComponent> selection = myPluginsPanel.getSelection();
int size = selection.size();
myDetailsPage.showPlugin(size == 1 ? selection.get(0) : null, size > 1);
});
myGroup = new PluginsGroup("Plugin updates available");
for (PluginDownloader plugin : uploadedPlugins) {
myGroup.descriptors.add(plugin.getDescriptor());
}
myGroup.sortByName();
myPluginsPanel.addGroup(myGroup);
setOKButtonText(false, false);
setCancelButtonText(IdeBundle.message("updates.remind.later.button"));
init();
JRootPane rootPane = getPeer().getRootPane();
if (rootPane != null) {
rootPane.setPreferredSize(new JBDimension(800, 600));
}
}
private void updateButtons() {
int count = myGroup.ui.plugins.size();
int restart = 0;
int progress = 0;
int updatedWithoutRestart = 0;
for (ListPluginComponent plugin : myGroup.ui.plugins) {
if (plugin.isRestartEnabled()) {
restart++;
}
else if (plugin.underProgress()) {
progress++;
}
else if (plugin.isUpdatedWithoutRestart()) {
updatedWithoutRestart++;
}
}
setOKButtonText(restart + progress > 0, updatedWithoutRestart == count);
getCancelAction().setEnabled(restart + updatedWithoutRestart < count);
myIgnoreAction.setEnabled(restart + progress + updatedWithoutRestart == 0);
}
private void setOKButtonText(boolean restart, boolean close) {
if (close) {
setOKButtonText("Close");
}
else {
String action = ApplicationManager.getApplication().isRestartCapable() ? "Restart" : "Shutdown";
setOKButtonText(restart ? action + " IDE" : "Update All and " + action);
}
}
@Override
protected void doOKAction() {
super.doOKAction();
List<PluginDownloader> toDownloads = new ArrayList<>();
List<IdeaPluginDescriptor> toIgnore = new ArrayList<>();
int index = 0;
boolean restart = false;
for (PluginDownloader downloader : myDownloaders) {
ListPluginComponent component = myGroup.ui.plugins.get(index++);
if (component.isRestartEnabled() || component.underProgress()) {
restart = true;
}
else if (!component.isUpdatedWithoutRestart()) {
toDownloads.add(downloader);
toIgnore.add(component.myUpdateDescriptor);
}
}
boolean background = myPluginModel.toBackground();
if (toDownloads.size() != myDownloaders.size() || background) {
if (!toIgnore.isEmpty()) {
ignorePlugins(toIgnore);
}
if (!background && restart) {
ApplicationManager.getApplication().invokeLater(() -> ApplicationManagerEx.getApplicationEx().restart(true));
}
return;
}
new Task.Backgroundable(null, IdeBundle.message("update.notifications.title"), true, PerformInBackgroundOption.DEAF) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final List<PluginDownloader> downloaders = UpdateInstaller.downloadPluginUpdates(toDownloads, indicator);
if (!downloaders.isEmpty()) {
ApplicationManager.getApplication().invokeLater(() -> {
final PluginUpdateResult result = UpdateInstaller.installDownloadedPluginUpdates(downloaders, getContentPanel(), true);
if (result.getPluginsInstalled().size() > 0) {
if (result.getRestartRequired()) {
PluginManagerMain.notifyPluginsUpdated(null);
}
else {
String message;
if (result.getPluginsInstalled().size() == 1) {
final IdeaPluginDescriptor installedPlugin = result.getPluginsInstalled().get(0);
message = "Updated " + installedPlugin.getName() + " plugin to version " + installedPlugin.getVersion();
}
else {
message = "Updated " + result.getPluginsInstalled() + " plugins";
}
UpdateChecker.NOTIFICATIONS.createNotification(message, NotificationType.INFORMATION).notify(myProject);
}
}
});
}
}
}.queue();
}
@Override
public void doCancelAction() {
super.doCancelAction();
if (myPluginModel.toBackground()) {
return;
}
for (ListPluginComponent plugin : myGroup.ui.plugins) {
if (plugin.isRestartEnabled()) {
ApplicationManager.getApplication().invokeLater(() -> PluginManagerConfigurable.shutdownOrRestartApp());
return;
}
}
}
@NotNull
@Override
protected Action[] createLeftSideActions() {
return ContainerUtil.ar(myIgnoreAction);
}
@NotNull
@Override
protected DialogStyle getStyle() {
return DialogStyle.COMPACT;
}
@Override
protected String getDimensionServiceKey() {
return "#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog";
}
@NotNull
private ListPluginComponent createListComponent(IdeaPluginDescriptor updateDescriptor) {
IdeaPluginDescriptor descriptor = PluginManagerCore.getPlugin(updateDescriptor.getPluginId());
assert descriptor != null;
ListPluginComponent component = new ListPluginComponent(myPluginModel, descriptor, emptyListener(), false) {
@Override
public void showProgress() {
super.showProgress();
updateButtons();
}
};
component.setOnlyUpdateMode(updateDescriptor);
return component;
}
@Nullable
@Override
protected JComponent createCenterPanel() {
OnePixelSplitter splitter = new OnePixelSplitter(false, 0.45f) {
@Override
protected Divider createDivider() {
Divider divider = super.createDivider();
divider.setBackground(PluginManagerConfigurable.SEARCH_FIELD_BORDER_COLOR);
return divider;
}
};
JPanel leftPanel = new JPanel(new BorderLayout());
leftPanel.add(PluginManagerConfigurable.createScrollPane(myPluginsPanel, true));
OpaquePanel titlePanel = new OpaquePanel(new BorderLayout(), PluginManagerConfigurable.MAIN_BG_COLOR);
titlePanel.setBorder(JBUI.Borders.empty(6, 10));
leftPanel.add(titlePanel, BorderLayout.SOUTH);
JLabel titleComponent = new JLabel("Plugins can be updated later in " + CommonBundle.settingsTitle() + " | Plugins");
titleComponent.setForeground(PluginsGroupComponent.SECTION_HEADER_FOREGROUND);
titlePanel.add(titleComponent);
((JComponent)myGroup.ui.panel).setBorder(JBUI.Borders.empty(6, 10));
splitter.setFirstComponent(leftPanel);
splitter.setSecondComponent(myDetailsPage);
return splitter;
}
private static Set<String> myIgnoredPluginsWithVersions;
private static final String DISABLED_UPDATE = "plugin_disabled_updates.txt";
@NotNull
private static File getDisabledUpdateFile() {
return new File(PathManager.getConfigPath(), DISABLED_UPDATE);
}
@NotNull
private static Set<String> getIgnoredPlugins() {
if (myIgnoredPluginsWithVersions == null) {
myIgnoredPluginsWithVersions = new HashSet<>();
if (!ApplicationManager.getApplication().isUnitTestMode()) {
try {
File file = getDisabledUpdateFile();
if (file.isFile()) {
myIgnoredPluginsWithVersions.addAll(FileUtil.loadLines(file));
}
}
catch (IOException e) {
Logger.getInstance(UpdateChecker.class).error(e);
}
}
}
return myIgnoredPluginsWithVersions;
}
private static void ignorePlugins(@NotNull List<IdeaPluginDescriptor> descriptors) {
Set<String> ignoredPlugins = getIgnoredPlugins();
for (IdeaPluginDescriptor descriptor : descriptors) {
ignoredPlugins.add(getIdVersionValue(descriptor));
}
try {
FileUtil
.writeToFile(getDisabledUpdateFile(), StringUtil.join(ignoredPlugins, LineSeparator.getSystemLineSeparator().getSeparatorString()));
}
catch (IOException e) {
Logger.getInstance(UpdateChecker.class).error(e);
}
}
public static boolean isIgnored(@NotNull IdeaPluginDescriptor descriptor) {
Set<String> plugins = getIgnoredPlugins();
if (plugins.isEmpty()) {
return false;
}
return plugins.contains(getIdVersionValue(descriptor));
}
@NotNull
private static String getIdVersionValue(@NotNull IdeaPluginDescriptor descriptor) {
return descriptor.getPluginId().getIdString() + "+" + descriptor.getVersion();
}
@NotNull
private static <T> LinkListener<T> emptyListener() {
return (__, ___) -> {
};
}
}
@@ -147,7 +147,8 @@ object UpdateChecker {
val updatedPlugins: Collection<PluginDownloader>?
val externalUpdates: Collection<ExternalUpdate>?
try {
updatedPlugins = checkPluginsUpdate(indicator, incompatiblePlugins, buildNumber)
updatedPlugins = checkPluginsUpdate(indicator, incompatiblePlugins,
buildNumber)?.filter { downloader -> !PluginUpdateDialog.isIgnored(downloader.descriptor) }
externalUpdates = checkExternalUpdates(showDialog, updateSettings, indicator)
}
catch (e: IOException) {
@@ -395,7 +396,7 @@ object UpdateChecker {
if (updatedPlugins != null && !updatedPlugins.isEmpty()) {
updateFound = true
val runnable = { PluginUpdateInfoDialog(updatedPlugins, showSettingsLink).show() }
val runnable = { PluginUpdateDialog(updatedPlugins).show() }
ourShownNotifications.remove(NotificationUniqueType.PLUGINS)?.forEach { it.expire() }
@@ -968,6 +968,7 @@ updates.incompatible.plugins.found={0,choice,1#Plugin|2#Plugins} incompatible wi
updates.download.and.restart.button=Up&date and Restart
updates.apply.manually.button=Up&date Manually
updates.ignore.update.button=&Ignore This Update
updates.ignore.updates.button=&Ignore These Updates
updates.remind.later.button=&Remind Me Later
updates.new.version.available=<b>A new version of {0} is <a href=\"{1}\">available</a>!</b>
updates.current.version=Current version: