new UI for plugins

This commit is contained in:
Konstantin Bulenkov
2014-01-31 17:35:44 +01:00
parent 7f5bcecf3c
commit 09437d8d48
25 changed files with 1098 additions and 260 deletions
-1
View File
@@ -1,6 +1,5 @@
<component name="CopyrightManager">
<settings default="apache 2 license">
<module2copyright />
<LanguageOptions name="__TEMPLATE__">
<option name="addBlankAfter" value="false" />
</LanguageOptions>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -28,6 +28,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.net.IOExceptionDialog;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.IOException;
@@ -84,10 +85,10 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
@Override
public void actionPerformed(AnActionEvent e) {
install();
install(null);
}
public void install() {
public void install(@Nullable final Runnable onSuccess) {
IdeaPluginDescriptor[] selection = getPluginTable().getSelectedObjects();
if (userConfirm(selection)) {
@@ -158,6 +159,9 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
PluginManagerMain.notifyPluginsWereInstalled(list.size() == 1 ? list.get(0).getName() : null, null);
}
}
if (onSuccess != null) {
onSuccess.run();
}
}
};
PluginManagerMain.downloadPlugins(list, pluginTableModel.getAllPlugins(), onInstallRunnable, new Runnable(){
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,6 +72,10 @@ public class ActionUninstallPlugin extends AnAction implements DumbAware {
}
public void actionPerformed(AnActionEvent e) {
uninstall(host, pluginTable);
}
public static void uninstall(PluginManagerMain host, PluginTable pluginTable) {
String message;
IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects();
@@ -96,11 +100,11 @@ public class ActionUninstallPlugin extends AnAction implements DumbAware {
actualDelete = (Messages.showYesNoDialog(host.getMainPanel(), message, promptTitle, Messages.getQuestionIcon()) == Messages.YES);
}
if (actualDelete) uninstallPlugin(pluginDescriptor);
if (actualDelete) uninstallPlugin(pluginDescriptor, host, pluginTable);
}
}
private void uninstallPlugin(IdeaPluginDescriptorImpl descriptor) {
private static void uninstallPlugin(IdeaPluginDescriptorImpl descriptor, PluginManagerMain host, PluginTable pluginTable) {
PluginId pluginId = descriptor.getPluginId();
descriptor.setDeleted(true);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,111 +15,19 @@
*/
package com.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
/**
* User: anna
* Date: 10/13/11
* @author anna
* @author Konstantin Bulenkov
*/
class AvailablePluginColumnInfo extends PluginManagerColumnInfo {
public AvailablePluginColumnInfo(AvailablePluginsTableModel model) {
super(PluginManagerColumnInfo.COLUMN_NAME, model);
}
@Override
public TableCellRenderer getRenderer(final IdeaPluginDescriptor pluginDescriptor) {
return new AvailableTableRenderer(pluginDescriptor);
return new PluginsTableRenderer(pluginDescriptor);
}
private static class AvailableTableRenderer extends DefaultTableCellRenderer {
private static final int LEFT_MARGIN = new JLabel().getFontMetrics(UIUtil.getLabelFont()).stringWidth(" ");
private final JLabel myNameLabel = new JLabel();
private final JLabel myStatusLabel = new JLabel();
private final JLabel myCategoryLabel = new JLabel();
private final JPanel myPanel = new JPanel(new GridBagLayout());
private final IdeaPluginDescriptor myPluginDescriptor;
public AvailableTableRenderer(IdeaPluginDescriptor pluginDescriptor) {
myPluginDescriptor = pluginDescriptor;
myNameLabel.setFont(getNameFont());
final Font smallFont = UIUtil.getLabelFont(UIUtil.FontSize.SMALL);
myStatusLabel.setFont(smallFont);
myCategoryLabel.setFont(smallFont);
myPanel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
final GridBagConstraints gn = new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0,0), 0,0);
myPanel.add(myNameLabel, gn);
myPanel.add(myStatusLabel, gn);
gn.weightx = 1;
gn.fill = GridBagConstraints.HORIZONTAL;
myPanel.add(Box.createHorizontalBox(), gn);
gn.fill = GridBagConstraints.NONE;
gn.weightx = 0;
myPanel.add(myCategoryLabel, gn);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component orig = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (myPluginDescriptor != null) {
final PluginNode pluginNode = (PluginNode)myPluginDescriptor;
myNameLabel.setText(myPluginDescriptor.getName());
final Color fg = orig.getForeground();
final Color bg = orig.getBackground();
final Color grayedFg = isSelected ? fg : new JBColor(Color.DARK_GRAY, Gray._128);
myNameLabel.setForeground(fg);
myStatusLabel.setForeground(grayedFg);
myPanel.setBackground(bg);
myNameLabel.setBackground(bg);
myNameLabel.setIcon(AllIcons.Nodes.Plugin);
String category = myPluginDescriptor.getCategory();
if (category != null) {
myCategoryLabel.setText(category);
myCategoryLabel.setForeground(grayedFg);
}
final IdeaPluginDescriptor installed = PluginManager.getPlugin(pluginNode.getPluginId());
if (isDownloaded(pluginNode) || (installed != null && InstalledPluginsTableModel.wasUpdated(installed.getPluginId()))) {
if (!isSelected) myNameLabel.setForeground(FileStatus.ADDED.getColor());
myStatusLabel.setText("[Downloaded]");
myPanel.setToolTipText(IdeBundle.message("plugin.download.status.tooltip"));
myStatusLabel.setBorder(BorderFactory.createEmptyBorder(0, LEFT_MARGIN, 0, 0));
}
else if (pluginNode.getStatus() == PluginNode.STATUS_INSTALLED) {
PluginId pluginId = pluginNode.getPluginId();
final boolean hasNewerVersion = InstalledPluginsTableModel.hasNewerVersion(pluginId);
if (!isSelected) myNameLabel.setForeground(FileStatus.MODIFIED.getColor());
if (hasNewerVersion) {
if (!isSelected){
myNameLabel.setForeground(JBColor.RED);
}
myNameLabel.setIcon(AllIcons.Nodes.Pluginobsolete);
}
myStatusLabel.setText("v." + pluginNode.getInstalledVersion() + (hasNewerVersion ? (" -> " + pluginNode.getVersion()) : ""));
myStatusLabel.setBorder(BorderFactory.createEmptyBorder(0, LEFT_MARGIN, 0, 0));
}
}
return myPanel;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -93,16 +93,16 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
pluginsModel = model;
pluginTable = new PluginTable(pluginsModel);
pluginTable.getTableHeader().setReorderingAllowed(false);
pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DOWNLOADS, 70);
pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DATE, 80);
pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_RATE, 80);
//pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DOWNLOADS, 70);
//pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DATE, 80);
//pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_RATE, 80);
return ScrollPaneFactory.createScrollPane(pluginTable);
}
@Override
protected void installTableActions(final PluginTable pluginTable) {
super.installTableActions(pluginTable);
protected void installTableActions() {
super.installTableActions();
new DoubleClickListener() {
@Override
protected boolean onDoubleClick(MouseEvent e) {
@@ -140,7 +140,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
}
}
if (enabled) {
new ActionInstallPlugin(this, installed).install();
new ActionInstallPlugin(this, installed).install(null);
}
return true;
}
@@ -158,12 +158,22 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
super.reset();
}
@Override
protected PluginManagerMain getAvailable() {
return this;
}
@Override
protected PluginManagerMain getInstalled() {
return installed;
}
@Override
protected ActionGroup getActionGroup(boolean inToolbar) {
DefaultActionGroup actionGroup = new DefaultActionGroup();
actionGroup.add(new RefreshAction());
actionGroup.add(Separator.getInstance());
actionGroup.add(new ActionInstallPlugin(this, installed));
actionGroup.add(new ActionInstallPlugin(getAvailable(), getInstalled()));
if (inToolbar) {
actionGroup.add(new SortByStatusAction("Sort Installed First"));
actionGroup.add(new MyFilterRepositoryAction());
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,9 +52,10 @@ public class AvailablePluginsTableModel extends PluginTableModel {
public AvailablePluginsTableModel() {
super.columns = new ColumnInfo[] {
new AvailablePluginColumnInfo(this),
new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_DOWNLOADS, this),
new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_RATE, this),
new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_DATE, this)/*,
//new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_DOWNLOADS, this),
//new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_RATE, this),
//new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_DATE, this)
/*,
new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_CATEGORY, this)*/};
setSortKey(new RowSorter.SortKey(getNameColumn(), SortOrder.ASCENDING));
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -206,7 +206,8 @@ public class InstalledPluginsManagerMain extends PluginManagerMain {
pluginTable = new PluginTable(pluginsModel);
pluginTable.setTableHeader(null);
JScrollPane installedScrollPane = ScrollPaneFactory.createScrollPane(pluginTable);
JScrollPane installedScrollPane = ScrollPaneFactory.createScrollPane(pluginTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pluginTable.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final int column = InstalledPluginsTableModel.getCheckboxColumn();
@@ -227,20 +228,33 @@ public class InstalledPluginsManagerMain extends PluginManagerMain {
pluginTable.repaint();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), JComponent.WHEN_FOCUSED);
pluginTable.setExpandableItemsEnabled(false);
return installedScrollPane;
}
@Override
protected PluginManagerMain getAvailable() {
return this;
}
@Override
protected PluginManagerMain getInstalled() {
return this;
}
@Override
protected ActionGroup getActionGroup(boolean inToolbar) {
final DefaultActionGroup actionGroup = new DefaultActionGroup();
actionGroup.add(new RefreshAction());
actionGroup.add(Separator.getInstance());
actionGroup.add(new ActionInstallPlugin(this, this));
actionGroup.add(new ActionUninstallPlugin(this, pluginTable));
if (inToolbar) {
actionGroup.add(new SortByStatusAction("Sort by Status"));
//actionGroup.add(new SortByStatusAction("Sort by Status"));
actionGroup.add(new MyFilterEnabledAction());
//actionGroup.add(new MyFilterBundleAction());
} else {
actionGroup.add(new RefreshAction());
actionGroup.add(Separator.getInstance());
actionGroup.add(new ActionInstallPlugin(getAvailable(), getInstalled()));
actionGroup.add(new UninstallPluginAction(this, pluginTable));
}
return actionGroup;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
public InstalledPluginsTableModel() {
super.columns = new ColumnInfo[]{new EnabledPluginInfo(), new MyPluginManagerColumnInfo()};
super.columns = new ColumnInfo[]{new MyPluginManagerColumnInfo(), new EnabledPluginInfo()};
view = new ArrayList<IdeaPluginDescriptor>(Arrays.asList(PluginManager.getPlugins()));
view.addAll(myInstalled);
reset(view);
@@ -117,11 +117,11 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}
public static int getCheckboxColumn() {
return 0;
return 1;
}
public int getNameColumn() {
return 1;
return 0;
}
private void reset(final List<IdeaPluginDescriptor> list) {
@@ -368,7 +368,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
private class EnabledPluginInfo extends ColumnInfo<IdeaPluginDescriptor, Boolean> {
public EnabledPluginInfo() {
super(IdeBundle.message("plugin.manager.enable.column.title"));
super(/*IdeBundle.message("plugin.manager.enable.column.title")*/"");
}
public Boolean valueOf(IdeaPluginDescriptor ideaPluginDescriptor) {
@@ -431,6 +431,11 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}
};
}
@Override
public int getWidth(JTable table) {
return new JCheckBox().getPreferredSize().width;
}
}
private void warnAboutMissedDependencies(final Boolean newVal, final IdeaPluginDescriptor... ideaPluginDescriptors) {
@@ -637,7 +642,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
@Override
public TableCellRenderer getRenderer(final IdeaPluginDescriptor pluginDescriptor) {
return new InstalledPluginsTableRenderer(pluginDescriptor);
return new PluginsTableRenderer(pluginDescriptor);
}
@Override
@@ -702,5 +707,10 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}
};
}
@Override
public int getWidth(JTable table) {
return super.getWidth(table);
}
}
}
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.plugins.PluginHeaderPanel">
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="e654" class="com.intellij.ui.components.JBLabel" binding="myCategory">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="CATEGORY"/>
</properties>
</component>
<hspacer id="a85a3">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="a9eec">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="48afa" class="com.intellij.ui.components.JBLabel" binding="myName">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Name name name"/>
</properties>
</component>
<grid id="79c3d" binding="myDownloadsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<hspacer id="7f4">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="9456a" class="com.intellij.ide.plugins.RatesPanel" binding="myRating">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="55a8f" class="com.intellij.ui.components.JBLabel" binding="myDownloads">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="777 downloads"/>
</properties>
</component>
</children>
</grid>
<grid id="11cd7" binding="myVersionInfoPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="bfda6" class="com.intellij.ui.components.JBLabel" binding="myUpdated">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Updated: 11/12/13"/>
</properties>
</component>
<component id="1845c" class="com.intellij.ui.components.JBLabel" binding="myVersion">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="v 1.2.3"/>
</properties>
</component>
<hspacer id="5a6c2">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
<grid id="5bca5" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children/>
</grid>
<grid id="13a9c" binding="myButtonPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="2" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<vspacer id="c9483">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="d0aa4" class="javax.swing.JButton" binding="myInstallButton" custom-create="true" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Install"/>
</properties>
</component>
<hspacer id="71c7f">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</grid>
</form>
@@ -0,0 +1,279 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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
*
* http://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.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.GraphicsUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Konstantin Bulenkov
*/
public class PluginHeaderPanel {
private IdeaPluginDescriptor myPlugin;
@Nullable
private final PluginManagerMain myManager;
private final JTable myPluginTable;
private JBLabel myCategory;
private JBLabel myName;
private JBLabel myDownloads;
private RatesPanel myRating;
private JBLabel myUpdated;
private JButton myInstallButton;
private JBLabel myVersion;
private JPanel myRoot;
private JPanel myButtonPanel;
private JPanel myDownloadsPanel;
private JPanel myVersionInfoPanel;
enum ACTION_ID {UPDATE, INSTALL, UNINSTALL, RESTART}
private ACTION_ID myActionId = ACTION_ID.INSTALL;
public PluginHeaderPanel(@Nullable PluginManagerMain manager, JTable pluginTable) {
myManager = manager;
myPluginTable = pluginTable;
final Font font = myName.getFont();
myName.setFont(new Font(font.getFontName(), font.getStyle(), font.getSize() + 2));
final JBColor greyed = new JBColor(Gray._130, Gray._200);
myCategory.setForeground(greyed);
myDownloads.setForeground(greyed);
myUpdated.setForeground(greyed);
myVersion.setForeground(greyed);
final Font smallFont = new Font(font.getFontName(), font.getStyle(), font.getSize() - 1);
myCategory.setFont(smallFont);
myVersion.setFont(smallFont);
myDownloads.setFont(smallFont);
myUpdated.setFont(smallFont);
myRoot.setVisible(false);
}
public void setPlugin(IdeaPluginDescriptor plugin) {
myPlugin = plugin;
myRoot.setVisible(true);
myCategory.setVisible(true);
myDownloadsPanel.setVisible(true);
myButtonPanel.setVisible(true);
myUpdated.setVisible(true);
//data
myName.setText("<html><body>" + plugin.getName() + "</body></html>");
myCategory.setText(plugin.getCategory() == null ? "UNKNOWN" : plugin.getCategory().toUpperCase());
if (plugin instanceof PluginNode) {
final PluginNode node = (PluginNode)plugin;
myRating.setRate(node.getRating());
myDownloads.setText(node.getDownloads() + " downloads");
myVersion.setText(" ver " + node.getVersion());
myUpdated.setText("Updated " + DateFormatUtil.formatDate(node.getDate()));
switch (node.getStatus()) {
case PluginNode.STATUS_INSTALLED:
myActionId = InstalledPluginsTableModel.hasNewerVersion(plugin.getPluginId()) ? ACTION_ID.UPDATE : ACTION_ID.UNINSTALL;
break;
case PluginNode.STATUS_DOWNLOADED:
myActionId = ACTION_ID.RESTART;
break;
default:
myActionId = ACTION_ID.INSTALL;
}
} else {
myActionId = null;
myVersionInfoPanel.remove(myUpdated);
myCategory.setVisible(false);
myDownloadsPanel.setVisible(false);
final String version = plugin.getVersion();
myVersion.setText("Version: " + (version == null ? "N/A" : version));
myUpdated.setVisible(false);
if (!plugin.isBundled()) {
myActionId = ((IdeaPluginDescriptorImpl)plugin).isDeleted() ? ACTION_ID.RESTART : ACTION_ID.UNINSTALL;
}
if (myActionId == ACTION_ID.RESTART && myManager != null && !myManager.isRequireShutdown()) {
myActionId = null;
}
}
if (myManager == null || myActionId == null || (myManager.getInstalled() != myManager.getAvailable() && myActionId == ACTION_ID.UNINSTALL)) {
myActionId = ACTION_ID.INSTALL;
myButtonPanel.setVisible(false);
}
myRoot.revalidate();
((JComponent)myInstallButton.getParent()).revalidate();
myInstallButton.revalidate();
((JComponent)myVersion.getParent()).revalidate();
myVersion.revalidate();
}
private void createUIComponents() {
myInstallButton = new JButton() {
{
setOpaque(false);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public Dimension getPreferredSize() {
final FontMetrics metrics = getFontMetrics(getFont());
final int textWidth = metrics.stringWidth(getText());
final int width = 8 + 16 + 4 + textWidth + 8;
final int height = 2 + Math.max(16, metrics.getHeight()) + 2;
return new Dimension(width, height);
}
@Override
public void paint(Graphics g2) {
final Graphics2D g = (Graphics2D)g2;
final GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
final int w = g.getClipBounds().width;
final int h = g.getClipBounds().height;
g.setPaint(getBackgroundBorderPaint());
g.fillRoundRect(0, 0, w, h, 7, 7);
g.setPaint(getBackgroundPaint());
g.fillRoundRect(1, 1, w - 2, h - 2, 6, 6);
g.setColor(getButtonForeground());
g.drawString(getText(), 8 + 16 + 4, getBaseline(w, h));
getIcon().paintIcon(this, g, 8, (getHeight() - getIcon().getIconHeight()) / 2);
config.restore();
}
private Color getButtonForeground() {
switch (myActionId) {
case UPDATE: return Color.BLACK;
case INSTALL: return Color.WHITE;
case UNINSTALL: return Gray._0;
case RESTART:
break;
}
return new JBColor(Gray._80, JBColor.WHITE);
}
private Paint getBackgroundPaint() {
switch (myActionId) {
case UPDATE: return new Color(209, 190, 114);
case INSTALL: return new Color(0x4DA864);
case UNINSTALL: return Gray._240;
case RESTART:
break;
}
return Gray._238;
}
private Paint getBackgroundBorderPaint() {
switch (myActionId) {
case UPDATE: return new JBColor(new Color(164, 145, 82), Gray._85);
case INSTALL: return new JBColor(new Color(0x337043), Gray._80);
case UNINSTALL: return Gray._220;
case RESTART:
}
return Gray._208;
}
@Override
public String getText() {
switch (myActionId) {
case UPDATE: return "Update plugin";
case INSTALL: return "Install plugin";
case UNINSTALL: return "Uninstall plugin";
case RESTART: return "Restart " + ApplicationNamesInfo.getInstance().getFullProductName();
}
return super.getText();
}
@Override
public Icon getIcon() {
switch (myActionId) {
case UPDATE: return AllIcons.Actions.Refresh;
case INSTALL: return AllIcons.General.DownloadPlugin;
case UNINSTALL: return AllIcons.Actions.Delete;
case RESTART: return AllIcons.Actions.Restart;
}
return super.getIcon();
}
};
myInstallButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
switch (myActionId) {
case UPDATE:
break;
case INSTALL:
new ActionInstallPlugin(myManager.getAvailable(), myManager.getInstalled()).install(new Runnable() {
@Override
public void run() {
setPlugin(myPlugin);
}
});
break;
case UNINSTALL:
//try {
UninstallPluginAction.uninstall(myManager.getInstalled(), myPlugin);
//}
//catch (IOException e1) {
// e1.printStackTrace();
//}
break;
case RESTART:
if (myManager != null) {
myManager.apply();
}
break;
}
setPlugin(myPlugin);
}
});
}
public JBLabel getCategory() {
return myCategory;
}
public JBLabel getName() {
return myName;
}
public JBLabel getDownloads() {
return myDownloads;
}
public RatesPanel getRating() {
return myRating;
}
public JBLabel getUpdated() {
return myUpdated;
}
public JButton getInstallButton() {
return myInstallButton;
}
public JPanel getPanel() {
return myRoot;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,9 @@
*/
package com.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.LightColors;
import com.intellij.util.text.DateFormatUtil;
@@ -101,7 +99,7 @@ class PluginManagerColumnInfo extends ColumnInfo<IdeaPluginDescriptor, String> {
protected boolean isSortByName() {
return COLUMN_NAME == columnIdx;
}
protected boolean isSortByDownloads() {
return columnIdx == COLUMN_DOWNLOADS;
}
@@ -319,48 +317,4 @@ class PluginManagerColumnInfo extends ColumnInfo<IdeaPluginDescriptor, String> {
return myLabel;
}
}
//waiting for rates available in IDEA
private static class RatesPanel extends JPanel {
public static int MAX_RATE = 5;
private static final Icon STAR = AllIcons.Ide.Rating;
private static final Icon STAR3 = AllIcons.Ide.Rating1;
private static final Icon STAR4 = AllIcons.Ide.Rating2;
private static final Icon STAR5 = AllIcons.Ide.Rating3;
private static final Icon STAR6 = AllIcons.Ide.Rating4;
private static final Icon[] STARs = new Icon[]{IconLoader.getDisabledIcon(STAR), STAR3, STAR3, STAR4, STAR4, STAR5, STAR5, STAR6, STAR6, STAR};
private JLabel[] myLabels = new JLabel[MAX_RATE];
private RatesPanel() {
super(new GridBagLayout());
GridBagConstraints gc =
new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0);
for (int i = 0, myLabelsLength = myLabels.length; i < myLabelsLength; i++) {
myLabels[i] = new JLabel();
myLabels[i].setOpaque(false);
add(myLabels[i], gc);
}
}
public void setRate(String rating) {
final Double dblRating = Double.valueOf(rating);
final int intRating = dblRating.intValue();
for (int i = 0; i < intRating; i++) {
myLabels[i].setIcon(STAR);
}
if (intRating < MAX_RATE) {
myLabels[intRating].setIcon(STARs[((Double)(dblRating * 10)).intValue() % 10]);
for (int i = 1 + intRating; i < MAX_RATE; i++) {
myLabels[i].setIcon(IconLoader.getDisabledIcon(STAR));
}
}
}
}
}
@@ -50,24 +50,19 @@
</properties>
<border type="empty"/>
<children>
<grid id="7d113" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<grid id="7d113" binding="myInfoPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<splitpane position="right"/>
</constraints>
<properties/>
<border type="none">
<size top="0" left="0" bottom="0" right="0"/>
<size top="2" left="4" bottom="2" right="4"/>
</border>
<children>
<scrollpane id="8853a" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<verticalScrollBarPolicy value="22"/>
</properties>
<border type="none"/>
<constraints border-constraint="Center"/>
<properties/>
<border type="empty"/>
<children>
<component id="db08a" class="javax.swing.JEditorPane" binding="myDescriptionTextArea">
<constraints/>
@@ -82,6 +77,14 @@
</component>
</children>
</scrollpane>
<grid id="a6a17" binding="myHeader" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints border-constraint="North"/>
<properties/>
<border type="empty">
<size top="2" left="4" bottom="2" right="4"/>
</border>
<children/>
</grid>
</children>
</grid>
<grid id="83ed3" binding="myTablePanel" layout-manager="BorderLayout" hgap="0" vgap="0">
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,10 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.*;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
@@ -48,11 +51,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.BorderUIResource;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
@@ -93,6 +99,9 @@ public abstract class PluginManagerMain implements Disposable {
private JPanel myTablePanel;
protected JPanel myActionsPanel;
private JPanel myHeader;
private PluginHeaderPanel myPluginHeaderPanel;
private JPanel myInfoPanel;
protected PluginTableModel pluginsModel;
@@ -112,19 +121,28 @@ public abstract class PluginManagerMain implements Disposable {
protected void init() {
GuiUtils.replaceJSplitPaneWithIDEASplitter(main);
myDescriptionTextArea.setEditorKit(new HTMLEditorKit());
myDescriptionTextArea.setEditable(false);
myDescriptionTextArea.addHyperlinkListener(new MyHyperlinkListener());
JScrollPane installedScrollPane = createTable();
installTableActions(pluginTable);
myPluginHeaderPanel = new PluginHeaderPanel(this, getPluginTable());
myHeader.setBackground(UIUtil.getTextFieldBackground());
myHeader.add(myPluginHeaderPanel.getPanel(), BorderLayout.CENTER);
installTableActions();
myTablePanel.add(installedScrollPane, BorderLayout.CENTER);
myToolbarPanel.setLayout(new BorderLayout());
myActionToolbar = ActionManager.getInstance().createActionToolbar("PluginManaer", getActionGroup(true), true);
myActionToolbar = ActionManager.getInstance().createActionToolbar("PluginManager", getActionGroup(true), true);
final JComponent component = myActionToolbar.getComponent();
myToolbarPanel.add(component, BorderLayout.WEST);
myToolbarPanel.add(myFilter, BorderLayout.EAST);
myToolbarPanel.add(component, BorderLayout.CENTER);
myToolbarPanel.add(myFilter, BorderLayout.WEST);
//Border border = UIManager.getBorder("Table.scrollPaneBorder");
//if (border == null) {
Border border = new BorderUIResource.LineBorderUIResource(Gray._220, 1);
//}
myInfoPanel.setBorder(border);
}
protected abstract JScrollPane createTable();
@@ -159,13 +177,10 @@ public abstract class PluginManagerMain implements Disposable {
return pluginsModel;
}
protected void installTableActions(final PluginTable pluginTable) {
protected void installTableActions() {
pluginTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
final IdeaPluginDescriptor[] descriptors = pluginTable.getSelectedObjects();
pluginInfoUpdate(descriptors != null && descriptors.length == 1 ? descriptors[0] : null,
myFilter.getFilter(), myDescriptionTextArea);
myActionToolbar.updateActionsImmediately();
refresh();
}
});
@@ -174,6 +189,16 @@ public abstract class PluginManagerMain implements Disposable {
new MySpeedSearchBar(pluginTable);
}
public void refresh() {
final IdeaPluginDescriptor[] descriptors = pluginTable.getSelectedObjects();
pluginInfoUpdate(descriptors != null && descriptors.length == 1 ? descriptors[0] : null,
myFilter.getFilter(), myDescriptionTextArea, myPluginHeaderPanel, this);
myActionToolbar.updateActionsImmediately();
final JComponent parent = (JComponent)myHeader.getParent();
parent.revalidate();
parent.repaint();
}
public void setRequireShutdown(boolean val) {
requireShutdown |= val;
}
@@ -195,6 +220,9 @@ public abstract class PluginManagerMain implements Disposable {
protected abstract ActionGroup getActionGroup(boolean inToolbar);
protected abstract PluginManagerMain getAvailable();
protected abstract PluginManagerMain getInstalled();
public JPanel getMainPanel() {
return main;
}
@@ -337,61 +365,62 @@ public abstract class PluginManagerMain implements Disposable {
requireShutdown = false;
}
public static void pluginInfoUpdate(Object plugin, @Nullable String filter, @NotNull JEditorPane descriptionTextArea) {
if (plugin instanceof IdeaPluginDescriptor) {
IdeaPluginDescriptor pluginDescriptor = (IdeaPluginDescriptor)plugin;
StringBuilder sb = new StringBuilder();
public static void pluginInfoUpdate(IdeaPluginDescriptor plugin,
@Nullable String filter,
@NotNull JEditorPane descriptionTextArea,
@NotNull PluginHeaderPanel header, PluginManagerMain manager) {
String description = pluginDescriptor.getDescription();
if (!isEmptyOrSpaces(description)) {
sb.append(description);
}
String changeNotes = pluginDescriptor.getChangeNotes();
if (!isEmptyOrSpaces(changeNotes)) {
sb.append("<h4>Change Notes</h4>");
sb.append(changeNotes);
}
if (!pluginDescriptor.isBundled()) {
String vendor = pluginDescriptor.getVendor();
String vendorEmail = pluginDescriptor.getVendorEmail();
String vendorUrl = pluginDescriptor.getVendorUrl();
if (!isEmptyOrSpaces(vendor) || !isEmptyOrSpaces(vendorEmail) || !isEmptyOrSpaces(vendorUrl)) {
sb.append("<h4>Vendor</h4>");
if (!isEmptyOrSpaces(vendor)) {
sb.append(vendor);
}
if (!isEmptyOrSpaces(vendorUrl)) {
sb.append("<br>").append(composeHref(vendorUrl));
}
if (!isEmptyOrSpaces(vendorEmail)) {
sb.append("<br>").append(composeHref("mailto:" + vendorEmail));
}
}
String pluginDescriptorUrl = pluginDescriptor.getUrl();
if (!isEmptyOrSpaces(pluginDescriptorUrl)) {
sb.append("<h4>Plugin homepage</h4>").append(composeHref(pluginDescriptorUrl));
}
String version = pluginDescriptor.getVersion();
if (!isEmptyOrSpaces(version)) {
sb.append("<h4>Version</h4>").append(version);
}
String size = plugin instanceof PluginNode ? ((PluginNode)plugin).getSize() : null;
if (!isEmptyOrSpaces(size)) {
sb.append("<h4>Size</h4>").append(PluginManagerColumnInfo.getFormattedSize(size));
}
}
setTextValue(sb, filter, descriptionTextArea);
}
else {
if (plugin == null) {
setTextValue(null, filter, descriptionTextArea);
header.getPanel().setVisible(false);
return;
}
StringBuilder sb = new StringBuilder();
header.setPlugin(plugin);
String description = plugin.getDescription();
if (!isEmptyOrSpaces(description)) {
sb.append(description);
}
String changeNotes = plugin.getChangeNotes();
if (!isEmptyOrSpaces(changeNotes)) {
sb.append("<h4>Change Notes</h4>");
sb.append(changeNotes);
}
if (!plugin.isBundled()) {
String vendor = plugin.getVendor();
String vendorEmail = plugin.getVendorEmail();
String vendorUrl = plugin.getVendorUrl();
if (!isEmptyOrSpaces(vendor) || !isEmptyOrSpaces(vendorEmail) || !isEmptyOrSpaces(vendorUrl)) {
sb.append("<h4>Vendor</h4>");
if (!isEmptyOrSpaces(vendor)) {
sb.append(vendor);
}
if (!isEmptyOrSpaces(vendorUrl)) {
sb.append("<br>").append(composeHref(vendorUrl));
}
if (!isEmptyOrSpaces(vendorEmail)) {
sb.append("<br>")
.append(HTML_PREFIX)
.append("mailto:").append(vendorEmail)
.append("\">").append(vendorEmail).append(HTML_SUFFIX);
}
}
String pluginDescriptorUrl = plugin.getUrl();
if (!isEmptyOrSpaces(pluginDescriptorUrl)) {
sb.append("<h4>Plugin homepage</h4>").append(composeHref(pluginDescriptorUrl));
}
String size = plugin instanceof PluginNode ? ((PluginNode)plugin).getSize() : null;
if (!isEmptyOrSpaces(size)) {
sb.append("<h4>Size</h4>").append(PluginManagerColumnInfo.getFormattedSize(size));
}
}
setTextValue(sb, filter, descriptionTextArea);
}
private static void setTextValue(@Nullable StringBuilder text, @Nullable String filter, JEditorPane pane) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,10 +20,7 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.ui.SplitterProportionsData;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
@@ -47,7 +44,7 @@ public class PluginManagerUISettings implements PersistentStateComponent<Element
public int AVAILABLE_SORT_COLUMN_ORDER = SortOrder.ASCENDING.ordinal();
public int AVAILABLE_SORT_MODE = 0;
public int AVAILABLE_SORT_MODE = 1;
public boolean AVAILABLE_SORT_BY_STATUS = false;
public boolean INSTALLED_SORT_BY_STATUS = false;
public boolean UPDATE_IN_BACKGROUND = false;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,6 +82,9 @@ public class PluginTable extends JBTable {
return COPY;
}
});
if (model.getColumnCount() > 1) {
setColumnWidth(1, new JCheckBox().getPreferredSize().width + 4);
}
}
public void setColumnWidth(final int columnIndex, final int width) {
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.plugins.PluginsTableRenderer">
<grid id="27dc6" binding="myPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<xy x="20" y="20" width="500" height="148"/>
</constraints>
<properties/>
<border type="empty">
<size top="4" left="3" bottom="4" right="3"/>
</border>
<children>
<grid id="89d6b" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints border-constraint="West"/>
<properties>
<opaque value="false"/>
</properties>
<border type="empty">
<size top="0" left="3" bottom="0" right="6"/>
</border>
<children>
<component id="7f1f5" class="com.intellij.ui.components.JBLabel" binding="myStatus">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Status"/>
</properties>
</component>
</children>
</grid>
<grid id="cebe0" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints border-constraint="Center"/>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<grid id="80605" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints border-constraint="South"/>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="a2a1e" class="com.intellij.ui.components.JBLabel" binding="myCategory">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Category"/>
</properties>
</component>
<hspacer id="e204">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
<grid id="6aad3" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints border-constraint="North"/>
<properties>
<opaque value="false"/>
</properties>
<border type="empty">
<size top="0" left="0" bottom="2" right="0"/>
</border>
<children>
<component id="a5e28" class="com.intellij.ui.components.JBLabel" binding="myName">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Plugin Name"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<grid id="10578" binding="myRightPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints border-constraint="East"/>
<properties>
<opaque value="false"/>
</properties>
<border type="empty">
<size top="0" left="3" bottom="0" right="3"/>
</border>
<children>
<component id="eeabb" class="com.intellij.ui.components.JBLabel" binding="myDownloads">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Downloads"/>
</properties>
</component>
<component id="8265" class="com.intellij.ui.components.JBLabel" binding="myLastUpdated">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Last Updated"/>
</properties>
</component>
<vspacer id="10ec0">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="37969" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="274f0" class="com.intellij.ide.plugins.RatesPanel" binding="myRating" custom-create="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
</component>
<hspacer id="e5696">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>
@@ -0,0 +1,131 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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
*
* http://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.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.text.DecimalFormat;
/**
* @author Konstantin Bulenkov
*/
public class PluginsTableRenderer extends DefaultTableCellRenderer {
private JLabel myName;
private JLabel myStatus;
private RatesPanel myRating;
private JLabel myDownloads;
private JLabel myLastUpdated;
private JPanel myPanel;
private JLabel myCategory;
private JPanel myRightPanel;
private final IdeaPluginDescriptor myPluginDescriptor;
public PluginsTableRenderer(IdeaPluginDescriptor pluginDescriptor) {
myPluginDescriptor = pluginDescriptor;
final Font smallFont = UIUtil.getLabelFont(UIUtil.FontSize.MINI);
final Font miniFont = UIUtil.getLabelFont(UIUtil.FontSize.MINI);
myName.setFont(UIUtil.getLabelFont().deriveFont(UIUtil.getLabelFont().getSize() + 1.0f));
myStatus.setFont(smallFont);
myCategory.setFont(smallFont);
myDownloads.setFont(miniFont);
myStatus.setText("");
myCategory.setText("");
myLastUpdated.setFont(miniFont);
if (! (pluginDescriptor instanceof PluginNode)) {
myPanel.remove(myRightPanel);
}
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (myPluginDescriptor != null) {
myName.setText(myPluginDescriptor.getName() + " ");
final Color fg = UIUtil.getTableForeground(isSelected);
final Color bg = UIUtil.getTableBackground(isSelected);
final Color grayedFg = isSelected ? fg : new JBColor(Gray._130, Gray._200);
myName.setForeground(fg);
myStatus.setForeground(grayedFg);
myStatus.setIcon(AllIcons.Nodes.Plugin);
String category = myPluginDescriptor.getCategory();
myCategory.setForeground(grayedFg);
if (category != null) {
myCategory.setText(category.toUpperCase() + " ");
}
if (myPluginDescriptor.isBundled()) {
myCategory.setText(myCategory.getText() + "[Bundled]");
}
myPanel.setBackground(bg);
myLastUpdated.setForeground(grayedFg);
myLastUpdated.setText("");
myDownloads.setForeground(grayedFg);
myDownloads.setText("");
final PluginNode pluginNode = myPluginDescriptor instanceof PluginNode ? (PluginNode)myPluginDescriptor : null;
if (pluginNode != null) {
String downloads = pluginNode.getDownloads();
if (downloads.length() > 3) {
downloads = new DecimalFormat("#,###").format(Integer.parseInt(downloads));
}
myDownloads.setText(downloads);
myRating.setRate(pluginNode.getRating());
myLastUpdated.setText(DateFormatUtil.formatBetweenDates(pluginNode.getDate(), System.currentTimeMillis()));
}
final IdeaPluginDescriptor installed = PluginManager.getPlugin(myPluginDescriptor.getPluginId());
if ((pluginNode != null && PluginManagerColumnInfo.isDownloaded(pluginNode)) ||
(installed != null && InstalledPluginsTableModel.wasUpdated(installed.getPluginId()))) {
if (!isSelected) myName.setForeground(FileStatus.ADDED.getColor());
//todo[kb] set proper icon
//myStatus.setText("[Downloaded]");
//myPanel.setToolTipText(IdeBundle.message("plugin.download.status.tooltip"));
//myStatus.setBorder(BorderFactory.createEmptyBorder(0, LEFT_MARGIN, 0, 0));
}
else if (pluginNode != null && pluginNode.getStatus() == PluginNode.STATUS_INSTALLED) {
PluginId pluginId = pluginNode.getPluginId();
final boolean hasNewerVersion = InstalledPluginsTableModel.hasNewerVersion(pluginId);
if (!isSelected) myName.setForeground(FileStatus.MODIFIED.getColor());
if (hasNewerVersion) {
if (!isSelected) {
myName.setForeground(JBColor.RED);
}
myName.setIcon(AllIcons.Nodes.Pluginobsolete);
}
//todo[kb] set proper icon
//myStatus.setText("v." + pluginNode.getInstalledVersion() + (hasNewerVersion ? (" -> " + pluginNode.getVersion()) : ""));
}
}
return myPanel;
}
private void createUIComponents() {
myRating = new RatesPanel();
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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
*
* http://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.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.IconLoader;
import javax.swing.*;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class RatesPanel extends JPanel {
public static int MAX_RATE = 5;
private static final Icon STAR = AllIcons.Ide.Rating;
private static final Icon STAR3 = AllIcons.Ide.Rating1;
private static final Icon STAR4 = AllIcons.Ide.Rating2;
private static final Icon STAR5 = AllIcons.Ide.Rating3;
private static final Icon STAR6 = AllIcons.Ide.Rating4;
private static final Icon[] STARs = new Icon[]{IconLoader.getDisabledIcon(STAR), STAR3, STAR3, STAR4, STAR4, STAR5, STAR5, STAR6, STAR6, STAR};
private JLabel[] myLabels = new JLabel[MAX_RATE];
public RatesPanel() {
super(new GridBagLayout());
setOpaque(false);
GridBagConstraints gc =
new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0);
for (int i = 0, myLabelsLength = myLabels.length; i < myLabelsLength; i++) {
myLabels[i] = new JLabel();
myLabels[i].setOpaque(false);
add(myLabels[i], gc);
}
}
public void setRate(String rating) {
final Double dblRating = Double.valueOf(rating);
final int intRating = dblRating.intValue();
for (int i = 0; i < intRating; i++) {
myLabels[i].setIcon(STAR);
}
if (intRating < MAX_RATE) {
myLabels[intRating].setIcon(STARs[((Double)(dblRating * 10)).intValue() % 10]);
for (int i = 1 + intRating; i < MAX_RATE; i++) {
myLabels[i].setIcon(IconLoader.getDisabledIcon(STAR));
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(55, 11);
}
}
@@ -0,0 +1,124 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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
*
* http://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.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author Konstantin Bulenkov
*/
public class UninstallPluginAction extends AnAction implements DumbAware {
private final PluginTable pluginTable;
private final PluginManagerMain host;
public UninstallPluginAction(PluginManagerMain mgr, PluginTable table) {
super(IdeBundle.message("action.uninstall.plugin"), IdeBundle.message("action.uninstall.plugin"), AllIcons.Actions.Uninstall);
pluginTable = table;
host = mgr;
}
public void update(AnActionEvent e) {
Presentation presentation = e.getPresentation();
if (!pluginTable.isShowing()) {
presentation.setEnabled(false);
return;
}
IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects();
boolean enabled = (selection != null);
if (enabled) {
for (IdeaPluginDescriptor descriptor : selection) {
if (descriptor instanceof IdeaPluginDescriptorImpl) {
final IdeaPluginDescriptorImpl ideaPluginDescriptor = (IdeaPluginDescriptorImpl)descriptor;
if (ideaPluginDescriptor.isDeleted() || ideaPluginDescriptor.isBundled()) {
enabled = false;
break;
}
}
if (descriptor instanceof PluginNode) {
enabled = false;
break;
}
}
}
presentation.setEnabled(enabled);
}
public void actionPerformed(AnActionEvent e) {
uninstall(host, pluginTable.getSelectedObjects());
pluginTable.updateUI();
}
public static void uninstall(PluginManagerMain host, IdeaPluginDescriptor... selection) {
String message;
if (selection.length == 1) {
message = IdeBundle.message("prompt.uninstall.plugin", selection[0].getName());
}
else {
message = IdeBundle.message("prompt.uninstall.several.plugins", selection.length);
}
if (Messages.showYesNoDialog(host.getMainPanel(), message, IdeBundle.message("title.plugin.uninstall"), Messages.getQuestionIcon()) != Messages.YES) return;
for (IdeaPluginDescriptor descriptor : selection) {
IdeaPluginDescriptorImpl pluginDescriptor = (IdeaPluginDescriptorImpl)descriptor;
boolean actualDelete = true;
// Get the list of plugins which depend on this one. If this list is
// not empty - issue warning instead of simple prompt.
ArrayList<IdeaPluginDescriptorImpl> dependant = host.getDependentList(pluginDescriptor);
if (dependant.size() > 0) {
message = IdeBundle.message("several.plugins.depend.on.0.continue.to.remove", pluginDescriptor.getName());
actualDelete = (Messages.showYesNoDialog(host.getMainPanel(), message, IdeBundle.message("title.plugin.uninstall"), Messages.getQuestionIcon()) == Messages.YES);
}
if (actualDelete) {
uninstallPlugin(pluginDescriptor, host);
}
}
}
private static void uninstallPlugin(IdeaPluginDescriptorImpl descriptor, PluginManagerMain host) {
PluginId pluginId = descriptor.getPluginId();
descriptor.setDeleted(true);
try {
PluginInstaller.prepareToUninstall(pluginId);
final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().getInstalledPlugins();
final String pluginIdString = pluginId.getIdString();
while (installedPlugins.contains(pluginIdString)) {
installedPlugins.remove(pluginIdString);
}
host.setRequireShutdown(descriptor.isEnabled());
}
catch (IOException e1) {
PluginManagerMain.LOG.error(e1);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginHeaderPanel;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.PluginManagerMain;
import com.intellij.openapi.extensions.PluginId;
@@ -32,8 +33,8 @@ import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.Set;
/**
* @author anna
@@ -42,11 +43,13 @@ import java.util.List;
public class DetectedPluginsPanel extends OrderPanel<PluginDownloader> {
private final List<Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private static JEditorPane myDescriptionPanel = new JEditorPane();
private JEditorPane myDescriptionPanel = new JEditorPane();
private PluginHeaderPanel myHeader;
public DetectedPluginsPanel() {
super(PluginDownloader.class);
final JTable entryTable = getEntryTable();
myHeader = new PluginHeaderPanel(null, entryTable);
entryTable.setTableHeader(null);
entryTable.setDefaultRenderer(PluginDownloader.class, new ColoredTableCellRenderer() {
protected void customizeCellRenderer(final JTable table,
@@ -85,7 +88,7 @@ public class DetectedPluginsPanel extends OrderPanel<PluginDownloader> {
final PluginDownloader selection = getValueAt(selectedRow);
final IdeaPluginDescriptor descriptor = selection.getDescriptor();
if (descriptor != null) {
PluginManagerMain.pluginInfoUpdate(descriptor, null, myDescriptionPanel);
PluginManagerMain.pluginInfoUpdate(descriptor, null, myDescriptionPanel, myHeader , null);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -370,6 +370,7 @@ public class AllIcons {
public static final Icon Debug = IconLoader.getIcon("/general/debug.png"); // 16x16
public static final Icon DefaultKeymap = IconLoader.getIcon("/general/defaultKeymap.png"); // 32x32
public static final Icon Divider = IconLoader.getIcon("/general/divider.png"); // 2x19
public static final Icon DownloadPlugin = IconLoader.getIcon("/general/downloadPlugin.png"); // 16x16
public static final Icon Dropdown = IconLoader.getIcon("/general/dropdown.png"); // 16x16
public static final Icon EditColors = IconLoader.getIcon("/general/editColors.png"); // 16x16
public static final Icon EditItemInSection = IconLoader.getIcon("/general/editItemInSection.png"); // 16x16
@@ -480,6 +481,7 @@ public class AllIcons {
public static final Icon TodoDefault = IconLoader.getIcon("/general/todoDefault.png"); // 12x12
public static final Icon TodoImportant = IconLoader.getIcon("/general/todoImportant.png"); // 12x12
public static final Icon TodoQuestion = IconLoader.getIcon("/general/todoQuestion.png"); // 12x12
public static final Icon UninstallPlugin = IconLoader.getIcon("/general/uninstallPlugin.png"); // 16x16
public static final Icon Warning = IconLoader.getIcon("/general/warning.png"); // 16x16
public static final Icon WarningDecorator = IconLoader.getIcon("/general/warningDecorator.png"); // 16x16
public static final Icon WarningDialog = IconLoader.getIcon("/general/warningDialog.png"); // 32x32