diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index b84d8ef19a71..19fba7722ca2 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -1,6 +1,5 @@ - diff --git a/platform/icons/src/general/downloadPlugin.png b/platform/icons/src/general/downloadPlugin.png new file mode 100644 index 000000000000..7dde20a414b2 Binary files /dev/null and b/platform/icons/src/general/downloadPlugin.png differ diff --git a/platform/icons/src/general/downloadPlugin@2x.png b/platform/icons/src/general/downloadPlugin@2x.png new file mode 100644 index 000000000000..6aa080e902a2 Binary files /dev/null and b/platform/icons/src/general/downloadPlugin@2x.png differ diff --git a/platform/icons/src/general/uninstallPlugin.png b/platform/icons/src/general/uninstallPlugin.png new file mode 100644 index 000000000000..019973d325f8 Binary files /dev/null and b/platform/icons/src/general/uninstallPlugin.png differ diff --git a/platform/icons/src/general/uninstallPlugin@2x.png b/platform/icons/src/general/uninstallPlugin@2x.png new file mode 100644 index 000000000000..c29c7637a385 Binary files /dev/null and b/platform/icons/src/general/uninstallPlugin@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index 721de87c5fc2..ee1fc7ba708d 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -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(){ diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java index a3f63a379e45..25769a38fa7d 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java @@ -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); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginColumnInfo.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginColumnInfo.java index fcdfad772957..c9427cf50379 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginColumnInfo.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginColumnInfo.java @@ -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; - } - } - } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java index 620c73ce3edf..9d07c000ea9d 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java @@ -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()); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java index 60ca69217b89..5ab37c12cda8 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java @@ -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)); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java index 3b6be6e8174f..a55cfa752988 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java @@ -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; } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index 3ca7083cf587..73256852b19c 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -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(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 list) { @@ -368,7 +368,7 @@ public class InstalledPluginsTableModel extends PluginTableModel { private class EnabledPluginInfo extends ColumnInfo { 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); + } } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.form b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.form new file mode 100644 index 000000000000..5a3e4f7c36c6 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.form @@ -0,0 +1,145 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java new file mode 100644 index 000000000000..6a29616a8e17 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java @@ -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("" + plugin.getName() + ""); + 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; + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java index f1dc4e14671b..591798ae8b70 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java @@ -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 { protected boolean isSortByName() { return COLUMN_NAME == columnIdx; } - + protected boolean isSortByDownloads() { return columnIdx == COLUMN_DOWNLOADS; } @@ -319,48 +317,4 @@ class PluginManagerColumnInfo extends ColumnInfo { 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)); - } - } - } - } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.form b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.form index 5381a96eb3b0..d93a0d06c113 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.form +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.form @@ -50,24 +50,19 @@ - - + - + - - - - - - - + + + @@ -82,6 +77,14 @@ + + + + + + + + diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index b099fe7735a7..f2fca6ba66b2 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -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("

Change Notes

"); - 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("

Vendor

"); - - if (!isEmptyOrSpaces(vendor)) { - sb.append(vendor); - } - if (!isEmptyOrSpaces(vendorUrl)) { - sb.append("
").append(composeHref(vendorUrl)); - } - if (!isEmptyOrSpaces(vendorEmail)) { - sb.append("
").append(composeHref("mailto:" + vendorEmail)); - } - } - - String pluginDescriptorUrl = pluginDescriptor.getUrl(); - if (!isEmptyOrSpaces(pluginDescriptorUrl)) { - sb.append("

Plugin homepage

").append(composeHref(pluginDescriptorUrl)); - } - - String version = pluginDescriptor.getVersion(); - if (!isEmptyOrSpaces(version)) { - sb.append("

Version

").append(version); - } - - String size = plugin instanceof PluginNode ? ((PluginNode)plugin).getSize() : null; - if (!isEmptyOrSpaces(size)) { - sb.append("

Size

").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("

Change Notes

"); + 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("

Vendor

"); + + if (!isEmptyOrSpaces(vendor)) { + sb.append(vendor); + } + if (!isEmptyOrSpaces(vendorUrl)) { + sb.append("
").append(composeHref(vendorUrl)); + } + if (!isEmptyOrSpaces(vendorEmail)) { + sb.append("
") + .append(HTML_PREFIX) + .append("mailto:").append(vendorEmail) + .append("\">").append(vendorEmail).append(HTML_SUFFIX); + } + } + + String pluginDescriptorUrl = plugin.getUrl(); + if (!isEmptyOrSpaces(pluginDescriptorUrl)) { + sb.append("

Plugin homepage

").append(composeHref(pluginDescriptorUrl)); + } + + String size = plugin instanceof PluginNode ? ((PluginNode)plugin).getSize() : null; + if (!isEmptyOrSpaces(size)) { + sb.append("

Size

").append(PluginManagerColumnInfo.getFormattedSize(size)); + } + } + + setTextValue(sb, filter, descriptionTextArea); } private static void setTextValue(@Nullable StringBuilder text, @Nullable String filter, JEditorPane pane) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java index 4010f46f0ac5..d5e320a77837 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java @@ -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 1) { + setColumnWidth(1, new JCheckBox().getPreferredSize().width + 4); + } } public void setColumnWidth(final int columnIndex, final int width) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form new file mode 100644 index 000000000000..f55d64c2662d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form @@ -0,0 +1,144 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java new file mode 100644 index 000000000000..20b2fc419fdc --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java @@ -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(); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RatesPanel.java b/platform/platform-impl/src/com/intellij/ide/plugins/RatesPanel.java new file mode 100644 index 000000000000..5f995a6b5a2c --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/RatesPanel.java @@ -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); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/UninstallPluginAction.java b/platform/platform-impl/src/com/intellij/ide/plugins/UninstallPluginAction.java new file mode 100644 index 000000000000..f66614869c28 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/UninstallPluginAction.java @@ -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 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); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java index 99739effdde8..e37e1ade39f9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java @@ -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 { private final List 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 { 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); } } } diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index 6bff65a37c2e..69c4a09beb3a 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -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