mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
plugins: highlight ready to update plugins
This commit is contained in:
@@ -18,6 +18,7 @@ package com.intellij.ide.plugins;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.ui.LightColors;
|
||||
import com.intellij.ui.SideBorder;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -144,9 +145,12 @@ class AvailablePluginColumnInfo extends PluginManagerColumnInfo {
|
||||
myPanel.setToolTipText(IdeBundle.message("plugin.download.status.tooltip"));
|
||||
}
|
||||
else if (pluginNode.getStatus() == PluginNode.STATUS_INSTALLED) {
|
||||
final boolean hasNewerVersion = InstalledPluginsTableModel.hasNewerVersion(pluginNode.getPluginId());
|
||||
if (!isSelected) myNameLabel.setForeground(FileStatus.COLOR_MODIFIED);
|
||||
myStatusLabel.setText("[Installed]");
|
||||
myPanel.setToolTipText(IdeBundle.message("plugin.is.already.installed.status.tooltip"));
|
||||
if (hasNewerVersion) {
|
||||
if (!isSelected) myPanel.setBackground(LightColors.BLUE);
|
||||
}
|
||||
myStatusLabel.setText("[Installed" + (hasNewerVersion ? ": Ready to update" : "") + "]");
|
||||
}
|
||||
}
|
||||
return myPanel;
|
||||
|
||||
+9
-88
@@ -15,26 +15,21 @@
|
||||
*/
|
||||
package com.intellij.ide.plugins;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.util.net.HTTPProxySettingsDialog;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
@@ -43,12 +38,11 @@ import java.util.LinkedHashSet;
|
||||
*/
|
||||
public class AvailablePluginsManagerMain extends PluginManagerMain {
|
||||
private PluginManagerMain installed;
|
||||
private PluginManagerUISettings myUISettings;
|
||||
private JButton myHttpProxySettingsButton = new JButton(IdeBundle.message("button.http.proxy.settings"));
|
||||
|
||||
public AvailablePluginsManagerMain(PluginManagerMain installed, PluginManagerUISettings uiSettings) {
|
||||
super(uiSettings);
|
||||
this.installed = installed;
|
||||
myUISettings = uiSettings;
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -90,13 +84,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
|
||||
if (!inToolbar) {
|
||||
actionGroup.add(new ActionInstallPlugin(this, installed));
|
||||
}
|
||||
actionGroup.add(new AnAction("Reload list of plugins", "Reload list of plugins", IconLoader.getIcon("/vcs/refresh.png")) {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
loadAvailablePlugins();
|
||||
myFilter.setFilter("");
|
||||
}
|
||||
});
|
||||
actionGroup.add(new RefreshAction());
|
||||
if (inToolbar) {
|
||||
actionGroup.add(new MyFilterCategoryAction());
|
||||
actionGroup.add(new SortByNameAction());
|
||||
@@ -104,76 +92,9 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
|
||||
return actionGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new thread which downloads new list of plugins from the site in
|
||||
* the background and updates a list of plugins in the table.
|
||||
*/
|
||||
private void loadPluginsFromHostInBackground() {
|
||||
setDownloadStatus(true);
|
||||
|
||||
new com.intellij.util.concurrency.SwingWorker() {
|
||||
ArrayList<IdeaPluginDescriptor> list = null;
|
||||
Exception error;
|
||||
|
||||
public Object construct() {
|
||||
try {
|
||||
list = RepositoryHelper.process(null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
error = e;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void finished() {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
if (list != null) {
|
||||
modifyPluginsList(list);
|
||||
setDownloadStatus(false);
|
||||
pluginsModel.setSortMode(myUISettings.AVAILABLE_SORT_MODE);
|
||||
}
|
||||
else if (error != null) {
|
||||
LOG.info(error);
|
||||
setDownloadStatus(false);
|
||||
if (0 == Messages.showOkCancelDialog(
|
||||
IdeBundle.message("error.list.of.plugins.was.not.loaded", error.getMessage()),
|
||||
IdeBundle.message("title.plugins"),
|
||||
CommonBundle.message("button.retry"), CommonBundle.getCancelButtonText(), Messages.getErrorIcon())) {
|
||||
loadPluginsFromHostInBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void setDownloadStatus(boolean status) {
|
||||
pluginTable.setPaintBusy(status);
|
||||
}
|
||||
|
||||
private void loadAvailablePlugins() {
|
||||
ArrayList<IdeaPluginDescriptor> list;
|
||||
try {
|
||||
// If we already have a file with downloaded plugins from the last time,
|
||||
// then read it, load into the list and start the updating process.
|
||||
// Otherwise just start the process of loading the list and save it
|
||||
// into the persistent config file for later reading.
|
||||
File file = new File(PathManager.getPluginsPath(), RepositoryHelper.extPluginsFile);
|
||||
if (file.exists()) {
|
||||
RepositoryContentHandler handler = new RepositoryContentHandler();
|
||||
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
parser.parse(file, handler);
|
||||
list = handler.getPluginsList();
|
||||
modifyPluginsList(list);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Nothing to do, just ignore - if nothing can be read from the local
|
||||
// file just start downloading of plugins' list from the site.
|
||||
}
|
||||
loadPluginsFromHostInBackground();
|
||||
@Override
|
||||
protected void propagateUpdates(ArrayList<IdeaPluginDescriptor> list) {
|
||||
installed.modifyPluginsList(list); //propagate updates
|
||||
}
|
||||
|
||||
private class MyFilterCategoryAction extends ComboBoxAction {
|
||||
|
||||
+8
-2
@@ -43,7 +43,8 @@ import java.util.Set;
|
||||
*/
|
||||
public class InstalledPluginsManagerMain extends PluginManagerMain {
|
||||
|
||||
public InstalledPluginsManagerMain() {
|
||||
public InstalledPluginsManagerMain(PluginManagerUISettings uiSettings) {
|
||||
super(uiSettings);
|
||||
init();
|
||||
final JButton button = new JButton("Browse JetBrains repository");
|
||||
button.setMnemonic('b');
|
||||
@@ -56,6 +57,10 @@ public class InstalledPluginsManagerMain extends PluginManagerMain {
|
||||
myActionsPanel.add(button, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void propagateUpdates(ArrayList<IdeaPluginDescriptor> list) {
|
||||
}
|
||||
|
||||
private PluginManagerConfigurable createAvailableConfigurable() {
|
||||
return new PluginManagerConfigurable(PluginManagerUISettings.getInstance(), true) {
|
||||
@Override
|
||||
@@ -97,7 +102,8 @@ public class InstalledPluginsManagerMain extends PluginManagerMain {
|
||||
|
||||
@Override
|
||||
protected ActionGroup getActionGroup(boolean inToolbar) {
|
||||
DefaultActionGroup actionGroup = new DefaultActionGroup();
|
||||
final DefaultActionGroup actionGroup = new DefaultActionGroup();
|
||||
actionGroup.add(new RefreshAction());
|
||||
if (!inToolbar) {
|
||||
actionGroup.add(new ActionUninstallPlugin(this, pluginTable));
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.ex.ApplicationInfoEx;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.updateSettings.impl.UpdateSettings;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -191,8 +192,10 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
|
||||
private static void updateExistingPluginInfo(IdeaPluginDescriptor descr, IdeaPluginDescriptor existing) {
|
||||
int state = StringUtil.compareVersionNumbers(descr.getVersion(), existing.getVersion());
|
||||
final PluginId pluginId = existing.getPluginId();
|
||||
if (state > 0 && !PluginManager.isIncompatible(descr) && !updatedPlugins.contains(descr.getPluginId())) {
|
||||
NewVersions2Plugins.put(existing.getPluginId(), 1);
|
||||
NewVersions2Plugins.put(pluginId, 1);
|
||||
UpdateSettings.getInstance().myOutdatedPlugins.add(pluginId.getIdString());
|
||||
|
||||
final IdeaPluginDescriptorImpl plugin = (IdeaPluginDescriptorImpl)existing;
|
||||
plugin.setDownloadsCount(descr.getDownloads());
|
||||
@@ -202,8 +205,9 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
plugin.setUrl(descr.getUrl());
|
||||
|
||||
} else {
|
||||
if (NewVersions2Plugins.remove(existing.getPluginId()) != null) {
|
||||
updatedPlugins.add(existing.getPluginId());
|
||||
UpdateSettings.getInstance().myOutdatedPlugins.remove(pluginId.getIdString());
|
||||
if (NewVersions2Plugins.remove(pluginId) != null) {
|
||||
updatedPlugins.add(pluginId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,7 +405,8 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
if (descriptor.isDeleted()) {
|
||||
myNameLabel.setIcon(IconLoader.getIcon("/actions/clean.png"));
|
||||
}
|
||||
else if (hasNewerVersion(myPluginDescriptor.getPluginId())) {
|
||||
else if (hasNewerVersion(myPluginDescriptor.getPluginId()) ||
|
||||
UpdateSettings.getInstance().myOutdatedPlugins.contains(myPluginDescriptor.getPluginId().getIdString())) {
|
||||
myNameLabel.setIcon(IconLoader.getIcon("/nodes/pluginobsolete.png"));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -97,7 +97,7 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc
|
||||
}
|
||||
|
||||
protected PluginManagerMain createPanel() {
|
||||
return new InstalledPluginsManagerMain();
|
||||
return new InstalledPluginsManagerMain(myUISettings);
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
|
||||
@@ -15,21 +15,24 @@
|
||||
*/
|
||||
package com.intellij.ide.plugins;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.ui.search.SearchUtil;
|
||||
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.FilterComponent;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.SpeedSearchBase;
|
||||
import com.intellij.ui.TableUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -41,7 +44,10 @@ import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.text.html.HTMLDocument;
|
||||
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
@@ -82,6 +88,12 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
private ActionToolbar myActionToolbar;
|
||||
|
||||
protected final MyPluginsFilter myFilter = new MyPluginsFilter();
|
||||
protected PluginManagerUISettings myUISettings;
|
||||
|
||||
public PluginManagerMain(
|
||||
PluginManagerUISettings uiSettings) {
|
||||
myUISettings = uiSettings;
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
myDescriptionTextArea.addHyperlinkListener(new MyHyperlinkListener());
|
||||
@@ -148,7 +160,7 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
return pluginsModel.dependent(pluginDescriptor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void modifyPluginsList(ArrayList<IdeaPluginDescriptor> list) {
|
||||
IdeaPluginDescriptor[] selected = pluginTable.getSelectedObjects();
|
||||
if (pluginsList == null) {
|
||||
@@ -169,6 +181,81 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
return main;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new thread which downloads new list of plugins from the site in
|
||||
* the background and updates a list of plugins in the table.
|
||||
*/
|
||||
protected void loadPluginsFromHostInBackground() {
|
||||
setDownloadStatus(true);
|
||||
|
||||
new com.intellij.util.concurrency.SwingWorker() {
|
||||
ArrayList<IdeaPluginDescriptor> list = null;
|
||||
Exception error;
|
||||
|
||||
public Object construct() {
|
||||
try {
|
||||
list = RepositoryHelper.process(null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
error = e;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void finished() {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
if (list != null) {
|
||||
modifyPluginsList(list);
|
||||
propagateUpdates(list);
|
||||
setDownloadStatus(false);
|
||||
pluginsModel.setSortMode(myUISettings.AVAILABLE_SORT_MODE);
|
||||
}
|
||||
else if (error != null) {
|
||||
LOG.info(error);
|
||||
setDownloadStatus(false);
|
||||
if (0 == Messages.showOkCancelDialog(
|
||||
IdeBundle.message("error.list.of.plugins.was.not.loaded", error.getMessage()),
|
||||
IdeBundle.message("title.plugins"),
|
||||
CommonBundle.message("button.retry"), CommonBundle.getCancelButtonText(), Messages.getErrorIcon())) {
|
||||
loadPluginsFromHostInBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
protected abstract void propagateUpdates(ArrayList<IdeaPluginDescriptor> list);
|
||||
|
||||
protected void setDownloadStatus(boolean status) {
|
||||
pluginTable.setPaintBusy(status);
|
||||
}
|
||||
|
||||
protected void loadAvailablePlugins() {
|
||||
ArrayList<IdeaPluginDescriptor> list;
|
||||
try {
|
||||
// If we already have a file with downloaded plugins from the last time,
|
||||
// then read it, load into the list and start the updating process.
|
||||
// Otherwise just start the process of loading the list and save it
|
||||
// into the persistent config file for later reading.
|
||||
File file = new File(PathManager.getPluginsPath(), RepositoryHelper.extPluginsFile);
|
||||
if (file.exists()) {
|
||||
RepositoryContentHandler handler = new RepositoryContentHandler();
|
||||
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
parser.parse(file, handler);
|
||||
list = handler.getPluginsList();
|
||||
modifyPluginsList(list);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Nothing to do, just ignore - if nothing can be read from the local
|
||||
// file just start downloading of plugins' list from the site.
|
||||
}
|
||||
loadPluginsFromHostInBackground();
|
||||
}
|
||||
|
||||
public static boolean downloadPlugins(final List<PluginNode> plugins, final List<IdeaPluginDescriptor> allPlugins) throws IOException {
|
||||
final boolean[] result = new boolean[1];
|
||||
try {
|
||||
@@ -180,7 +267,7 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if (e.getCause() != null && e.getCause() instanceof IOException) {
|
||||
throw(IOException)e.getCause();
|
||||
throw (IOException)e.getCause();
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
@@ -224,7 +311,6 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
|
||||
if (!pluginDescriptor.isBundled()) {
|
||||
description += "<h4>Vendor</h4>";
|
||||
//todo vendor section
|
||||
String vendor = pluginDescriptor.getVendor();
|
||||
if (!StringUtil.isEmpty(vendor)) {
|
||||
description += vendor;
|
||||
@@ -249,7 +335,7 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
|
||||
String version = pluginDescriptor.getVersion();
|
||||
if (!StringUtil.isEmpty(version)) {
|
||||
description +="<h4>Version</h4>" + version;
|
||||
description += "<h4>Version</h4>" + version;
|
||||
}
|
||||
|
||||
String size = plugin instanceof PluginNode ? ((PluginNode)plugin).getSize() : null;
|
||||
@@ -260,7 +346,8 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
|
||||
|
||||
setTextValue(description, myDescriptionTextArea);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setTextValue(null, myDescriptionTextArea);
|
||||
}
|
||||
}
|
||||
@@ -297,8 +384,9 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
}
|
||||
else {
|
||||
URL url = e.getURL();
|
||||
if( url != null )
|
||||
BrowserUtil.launchBrowser( url.toString() );
|
||||
if (url != null) {
|
||||
BrowserUtil.launchBrowser(url.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -392,4 +480,16 @@ public abstract class PluginManagerMain implements Disposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class RefreshAction extends AnAction {
|
||||
public RefreshAction() {
|
||||
super("Reload list of plugins", "Reload list of plugins", IconLoader.getIcon("/vcs/refresh.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
loadAvailablePlugins();
|
||||
myFilter.setFilter("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,12 +168,14 @@ public final class UpdateChecker {
|
||||
|
||||
if (!toUpdate.isEmpty()) {
|
||||
try {
|
||||
final UpdateSettings updateSettings = UpdateSettings.getInstance();
|
||||
final ArrayList<IdeaPluginDescriptor> process = RepositoryHelper.process(null);
|
||||
for (IdeaPluginDescriptor loadedPlugin : process) {
|
||||
final String idString = loadedPlugin.getPluginId().getIdString();
|
||||
final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString);
|
||||
if (installedPlugin != null) {
|
||||
if (StringUtil.compareVersionNumbers(loadedPlugin.getVersion(), installedPlugin.getVersion()) > 0) {
|
||||
updateSettings.myOutdatedPlugins.add(idString);
|
||||
final PluginDownloader downloader = PluginDownloader.createDownloader(loadedPlugin);
|
||||
if (downloader.prepareToInstall()) {
|
||||
downloaded.add(downloader);
|
||||
|
||||
+2
@@ -53,6 +53,8 @@ public class UpdateSettings implements PersistentStateComponent<Element>, UserUp
|
||||
@SuppressWarnings({"WeakerAccess", "CanBeFinal"})
|
||||
public JDOMExternalizableStringList myIgnoredBuildNumbers = new JDOMExternalizableStringList();
|
||||
|
||||
public JDOMExternalizableStringList myOutdatedPlugins = new JDOMExternalizableStringList();
|
||||
|
||||
public boolean CHECK_NEEDED = true;
|
||||
public long LAST_TIME_CHECKED = 0;
|
||||
public String UPDATE_CHANNEL_TYPE = ChannelStatus.RELEASE_CODE;
|
||||
|
||||
Reference in New Issue
Block a user