diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java
new file mode 100644
index 000000000..b6f18a604
--- /dev/null
+++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java
@@ -0,0 +1,243 @@
+package cc.arduino.contributions.libraries.ui;
+
+import static processing.app.I18n.format;
+import static processing.app.I18n.tr;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Insets;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+import javax.swing.JTextPane;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.text.Document;
+import javax.swing.text.html.HTMLDocument;
+import javax.swing.text.html.StyleSheet;
+
+import cc.arduino.contributions.DownloadableContributionVersionComparator;
+import cc.arduino.contributions.libraries.ContributedLibrary;
+import cc.arduino.contributions.ui.InstallerTableCell;
+import processing.app.Base;
+
+public class ContributedLibraryTableCell {
+
+ protected final JPanel panel;
+ protected final JButton installButton;
+ protected final Component installButtonPlaceholder;
+ protected final JComboBox downgradeChooser;
+ protected final JComboBox versionToInstallChooser;
+ protected final JButton downgradeButton;
+ protected final JPanel buttonsPanel;
+ protected final JPanel inactiveButtonsPanel;
+ protected final JLabel statusLabel;
+
+ public ContributedLibraryTableCell() {
+ installButton = new JButton(tr("Install"));
+ int width = installButton.getPreferredSize().width;
+ installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1));
+
+ downgradeButton = new JButton(tr("Install"));
+
+ downgradeChooser = new JComboBox();
+ downgradeChooser.addItem("-");
+ downgradeChooser.setMaximumSize(downgradeChooser.getPreferredSize());
+ downgradeChooser.addItemListener(e -> {
+ Object selectVersionItem = downgradeChooser.getItemAt(0);
+ boolean disableDowngrade = (e.getItem() == selectVersionItem);
+ downgradeButton.setEnabled(!disableDowngrade);
+ });
+
+ versionToInstallChooser = new JComboBox();
+ versionToInstallChooser.addItem("-");
+ versionToInstallChooser
+ .setMaximumSize(versionToInstallChooser.getPreferredSize());
+
+ panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+
+ makeNewDescription(panel);
+
+ buttonsPanel = new JPanel();
+ buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
+ buttonsPanel.setOpaque(false);
+
+ buttonsPanel.add(Box.createHorizontalStrut(7));
+ buttonsPanel.add(downgradeChooser);
+ buttonsPanel.add(Box.createHorizontalStrut(5));
+ buttonsPanel.add(downgradeButton);
+
+ buttonsPanel.add(Box.createHorizontalGlue());
+
+ buttonsPanel.add(versionToInstallChooser);
+ buttonsPanel.add(Box.createHorizontalStrut(5));
+ buttonsPanel.add(installButton);
+ buttonsPanel.add(Box.createHorizontalStrut(5));
+ buttonsPanel.add(Box.createHorizontalStrut(15));
+
+ panel.add(buttonsPanel);
+
+ inactiveButtonsPanel = new JPanel();
+ inactiveButtonsPanel
+ .setLayout(new BoxLayout(inactiveButtonsPanel, BoxLayout.X_AXIS));
+ inactiveButtonsPanel.setOpaque(false);
+
+ int height = installButton.getMinimumSize().height;
+ inactiveButtonsPanel.add(Box.createVerticalStrut(height));
+ inactiveButtonsPanel.add(Box.createGlue());
+
+ statusLabel = new JLabel(" ");
+ inactiveButtonsPanel.add(statusLabel);
+ inactiveButtonsPanel.add(Box.createHorizontalStrut(15));
+
+ panel.add(inactiveButtonsPanel);
+
+ panel.add(Box.createVerticalStrut(15));
+ }
+
+ void update(JTable parentTable, Object value, boolean isSelected,
+ int row, boolean hasBuiltInRelease) {
+ ContributedLibraryReleases releases = (ContributedLibraryReleases) value;
+
+ JTextPane description = makeNewDescription(panel);
+
+ // FIXME: happens on macosx, don't know why
+ if (releases == null)
+ return;
+
+ ContributedLibrary selected = releases.getSelected();
+ ContributedLibrary installed = releases.getInstalled();
+
+ boolean installable, upgradable;
+ if (installed == null) {
+ installable = true;
+ upgradable = false;
+ } else {
+ installable = false;
+ upgradable = new DownloadableContributionVersionComparator()
+ .compare(selected, installed) > 0;
+ }
+ if (installable) {
+ installButton.setText(tr("Install"));
+ }
+ if (upgradable) {
+ installButton.setText(tr("Update"));
+ }
+ installButton.setVisible(installable || upgradable);
+ installButtonPlaceholder.setVisible(!(installable || upgradable));
+
+ String name = selected.getName();
+ String author = selected.getAuthor();
+ // String maintainer = selectedLib.getMaintainer();
+ String website = selected.getWebsite();
+ String sentence = selected.getSentence();
+ String paragraph = selected.getParagraph();
+ // String availableVer = selectedLib.getVersion();
+ // String url = selected.getUrl();
+
+ String midcolor = isSelected ? "#000000" : "#888888";
+
+ String desc = "
";
+
+ // Library name...
+ desc += format("{0}", name);
+ if (installed != null && installed.isReadOnly()) {
+ desc += " Built-In ";
+ }
+
+ // ...author...
+ desc += format("", midcolor);
+ if (author != null && !author.isEmpty()) {
+ desc += format(" by {0}", author);
+ }
+
+ // ...version.
+ if (installed != null) {
+ String installedVer = installed.getParsedVersion();
+ if (installedVer == null) {
+ desc += " " + tr("Version unknown");
+ } else {
+ desc += " " + format(tr("Version {0}"), installedVer);
+ }
+ }
+ desc += "";
+
+ if (installed != null) {
+ desc += " INSTALLED";
+ }
+
+ desc += "
";
+
+ // Description
+ if (sentence != null) {
+ desc += format("{0} ", sentence);
+ if (paragraph != null && !paragraph.isEmpty())
+ desc += format("{0}", paragraph);
+ desc += "
";
+ }
+ if (author != null && !author.isEmpty()) {
+ desc += format("More info", website);
+ }
+
+ desc += "";
+ description.setText(desc);
+ description.setBackground(Color.WHITE);
+
+ // for modelToView to work, the text area has to be sized. It doesn't
+ // matter if it's visible or not.
+
+ // See:
+ // http://stackoverflow.com/questions/3081210/how-to-set-jtextarea-to-have-height-that-matches-the-size-of-a-text-it-contains
+ int width = parentTable.getBounds().width;
+ InstallerTableCell.setJTextPaneDimensionToFitContainedText(description, width);
+
+ if (isSelected) {
+ panel.setBackground(parentTable.getSelectionBackground());
+ panel.setForeground(parentTable.getSelectionForeground());
+ } else {
+ panel.setBackground(parentTable.getBackground());
+ panel.setForeground(parentTable.getForeground());
+ }
+ }
+
+ private static JTextPane makeNewDescription(JPanel panel) {
+ if (panel.getComponentCount() > 0) {
+ panel.remove(0);
+ }
+ JTextPane description = new JTextPane();
+ description.setInheritsPopupMenu(true);
+ Insets margin = description.getMargin();
+ margin.bottom = 0;
+ description.setMargin(margin);
+ description.setContentType("text/html");
+ Document doc = description.getDocument();
+ if (doc instanceof HTMLDocument) {
+ HTMLDocument html = (HTMLDocument) doc;
+ StyleSheet stylesheet = html.getStyleSheet();
+ stylesheet.addRule("body { margin: 0; padding: 0;"
+ + "font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"
+ + "font-size: 100%;" + "font-size: 0.95em; }");
+ }
+ description.setOpaque(false);
+ description.setBorder(new EmptyBorder(4, 7, 7, 7));
+ description.setHighlighter(null);
+ description.setEditable(false);
+ description.addHyperlinkListener(e -> {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+ Base.openURL(e.getDescription());
+ }
+ });
+ // description.addKeyListener(new DelegatingKeyListener(parentTable));
+ panel.add(description, 0);
+ return description;
+ }
+
+
+}
diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellEditor.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellEditor.java
new file mode 100644
index 000000000..bb838c513
--- /dev/null
+++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellEditor.java
@@ -0,0 +1,187 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package cc.arduino.contributions.libraries.ui;
+
+import static processing.app.I18n.tr;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.swing.JComboBox;
+import javax.swing.JTable;
+import javax.swing.Timer;
+
+import cc.arduino.contributions.DownloadableContributionVersionComparator;
+import cc.arduino.contributions.VersionComparator;
+import cc.arduino.contributions.filters.BuiltInPredicate;
+import cc.arduino.contributions.filters.InstalledPredicate;
+import cc.arduino.contributions.libraries.ContributedLibrary;
+import cc.arduino.contributions.libraries.filters.OnlyUpstreamReleasePredicate;
+import cc.arduino.contributions.ui.InstallerTableCell;
+import cc.arduino.utils.ReverseComparator;
+
+@SuppressWarnings("serial")
+public class ContributedLibraryTableCellEditor extends InstallerTableCell {
+
+ private ContributedLibraryReleases editorValue;
+ private ContributedLibraryTableCell editorCell;
+
+ @Override
+ public Object getCellEditorValue() {
+ return editorValue;
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(JTable table, Object value,
+ boolean isSelected, int row,
+ int column) {
+ editorValue = (ContributedLibraryReleases) value;
+
+ editorCell = new ContributedLibraryTableCell();
+ editorCell.installButton
+ .addActionListener(e -> onInstall(editorValue.getSelected(),
+ editorValue.getInstalled()));
+ editorCell.downgradeButton.addActionListener(e -> {
+ JComboBox chooser = editorCell.downgradeChooser;
+ ContributedLibrary lib = (ContributedLibrary) chooser.getSelectedItem();
+ onInstall(lib, editorValue.getInstalled());
+ });
+ editorCell.versionToInstallChooser.addItemListener(e -> editorValue
+ .select((ContributedLibrary) editorCell.versionToInstallChooser
+ .getSelectedItem()));
+
+ setEnabled(true);
+
+ final ContributedLibrary installed = editorValue.getInstalled();
+
+ List releases = editorValue.getReleases().stream()
+ .filter(new OnlyUpstreamReleasePredicate())
+ .collect(Collectors.toList());
+ List uninstalledReleases = releases.stream()
+ .filter(new InstalledPredicate().negate()).collect(Collectors.toList());
+
+ List installedBuiltIn = releases.stream()
+ .filter(new InstalledPredicate()).filter(new BuiltInPredicate())
+ .collect(Collectors.toList());
+
+ if (installed != null && !installedBuiltIn.contains(installed)) {
+ uninstalledReleases.addAll(installedBuiltIn);
+ }
+
+ Collections.sort(uninstalledReleases, new ReverseComparator<>(
+ new DownloadableContributionVersionComparator()));
+
+ editorCell.downgradeChooser.removeAllItems();
+ editorCell.downgradeChooser.addItem(tr("Select version"));
+
+ final List uninstalledPreviousReleases = new LinkedList<>();
+ final List uninstalledNewerReleases = new LinkedList<>();
+
+ final VersionComparator versionComparator = new VersionComparator();
+ uninstalledReleases.stream().forEach(input -> {
+ if (installed == null
+ || versionComparator.greaterThan(installed.getParsedVersion(),
+ input.getParsedVersion())) {
+ uninstalledPreviousReleases.add(input);
+ } else {
+ uninstalledNewerReleases.add(input);
+ }
+ });
+ uninstalledNewerReleases.forEach(editorCell.downgradeChooser::addItem);
+ uninstalledPreviousReleases.forEach(editorCell.downgradeChooser::addItem);
+
+ editorCell.downgradeChooser
+ .setVisible(installed != null
+ && (!uninstalledPreviousReleases.isEmpty()
+ || uninstalledNewerReleases.size() > 1));
+ editorCell.downgradeButton
+ .setVisible(installed != null
+ && (!uninstalledPreviousReleases.isEmpty()
+ || uninstalledNewerReleases.size() > 1));
+
+ editorCell.versionToInstallChooser.removeAllItems();
+ uninstalledReleases.forEach(editorCell.versionToInstallChooser::addItem);
+ editorCell.versionToInstallChooser
+ .setVisible(installed == null && uninstalledReleases.size() > 1);
+
+ editorCell.update(table, value, true, row, !installedBuiltIn.isEmpty());
+ editorCell.panel.setBackground(new Color(218, 227, 227)); // #dae3e3
+ return editorCell.panel;
+ }
+
+ private final Timer enabler = new Timer(100, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ enable(true);
+ enabler.stop();
+ }
+ });
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ enable(false);
+ if (enabled) {
+ enabler.start();
+ } else {
+ enabler.stop();
+ }
+ editorCell.buttonsPanel.setVisible(enabled);
+ editorCell.inactiveButtonsPanel.setVisible(!enabled);
+ }
+
+ public void enable(boolean enabled) {
+ editorCell.installButton.setEnabled(enabled);
+ }
+
+ public void setStatus(String status) {
+ editorCell.statusLabel.setText(status);
+ }
+
+ public void invalidate() {
+ editorCell.panel.invalidate();
+ }
+
+
+ protected void onRemove(ContributedLibrary selected) {
+ // Empty
+ }
+
+ protected void onInstall(ContributedLibrary selected,
+ ContributedLibrary installed) {
+ // Empty
+ }
+
+}
diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java
index ae3b1f31c..5fae977de 100644
--- a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java
+++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java
@@ -29,279 +29,27 @@
package cc.arduino.contributions.libraries.ui;
-import static processing.app.I18n.format;
-import static processing.app.I18n.tr;
-
import java.awt.Color;
import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
import javax.swing.JTable;
-import javax.swing.JTextPane;
-import javax.swing.Timer;
-import javax.swing.border.EmptyBorder;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.text.Document;
-import javax.swing.text.html.HTMLDocument;
-import javax.swing.text.html.StyleSheet;
-
-import cc.arduino.contributions.DownloadableContributionVersionComparator;
-import cc.arduino.contributions.VersionComparator;
-import cc.arduino.contributions.filters.BuiltInPredicate;
-import cc.arduino.contributions.filters.InstalledPredicate;
-import cc.arduino.contributions.libraries.ContributedLibrary;
-import cc.arduino.contributions.libraries.filters.OnlyUpstreamReleasePredicate;
-import cc.arduino.contributions.ui.InstallerTableCell;
-import cc.arduino.utils.ReverseComparator;
-import processing.app.Base;
+import javax.swing.table.TableCellRenderer;
@SuppressWarnings("serial")
-public class ContributedLibraryTableCellRenderer extends InstallerTableCell {
-
- private class Cell {
- private final JPanel panel;
- private final JButton installButton;
- private final Component installButtonPlaceholder;
- private final JComboBox downgradeChooser;
- private final JComboBox versionToInstallChooser;
- private final JButton downgradeButton;
- private final JPanel buttonsPanel;
- private final JPanel inactiveButtonsPanel;
- private final JLabel statusLabel;
-
- public Cell() {
- installButton = new JButton(tr("Install"));
- int width = installButton.getPreferredSize().width;
- installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1));
-
- downgradeButton = new JButton(tr("Install"));
-
- downgradeChooser = new JComboBox();
- downgradeChooser.addItem("-");
- downgradeChooser.setMaximumSize(downgradeChooser.getPreferredSize());
- downgradeChooser.addItemListener(e -> {
- Object selectVersionItem = downgradeChooser.getItemAt(0);
- boolean disableDowngrade = (e.getItem() == selectVersionItem);
- downgradeButton.setEnabled(!disableDowngrade);
- });
-
- versionToInstallChooser = new JComboBox();
- versionToInstallChooser.addItem("-");
- versionToInstallChooser
- .setMaximumSize(versionToInstallChooser.getPreferredSize());
-
- panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-
- makeNewDescription(panel);
-
- buttonsPanel = new JPanel();
- buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
- buttonsPanel.setOpaque(false);
-
- buttonsPanel.add(Box.createHorizontalStrut(7));
- buttonsPanel.add(downgradeChooser);
- buttonsPanel.add(Box.createHorizontalStrut(5));
- buttonsPanel.add(downgradeButton);
-
- buttonsPanel.add(Box.createHorizontalGlue());
-
- buttonsPanel.add(versionToInstallChooser);
- buttonsPanel.add(Box.createHorizontalStrut(5));
- buttonsPanel.add(installButton);
- buttonsPanel.add(Box.createHorizontalStrut(5));
- buttonsPanel.add(Box.createHorizontalStrut(15));
-
- panel.add(buttonsPanel);
-
- inactiveButtonsPanel = new JPanel();
- inactiveButtonsPanel
- .setLayout(new BoxLayout(inactiveButtonsPanel, BoxLayout.X_AXIS));
- inactiveButtonsPanel.setOpaque(false);
-
- int height = installButton.getMinimumSize().height;
- inactiveButtonsPanel.add(Box.createVerticalStrut(height));
- inactiveButtonsPanel.add(Box.createGlue());
-
- statusLabel = new JLabel(" ");
- inactiveButtonsPanel.add(statusLabel);
- inactiveButtonsPanel.add(Box.createHorizontalStrut(15));
-
- panel.add(inactiveButtonsPanel);
-
- panel.add(Box.createVerticalStrut(15));
- }
-
- private void update(JTable parentTable, Object value, boolean isSelected,
- int row, boolean hasBuiltInRelease) {
- ContributedLibraryReleases releases = (ContributedLibraryReleases) value;
-
- JTextPane description = makeNewDescription(panel);
-
- // FIXME: happens on macosx, don't know why
- if (releases == null)
- return;
-
- ContributedLibrary selected = releases.getSelected();
- ContributedLibrary installed = releases.getInstalled();
-
- boolean installable, upgradable;
- if (installed == null) {
- installable = true;
- upgradable = false;
- } else {
- installable = false;
- upgradable = new DownloadableContributionVersionComparator()
- .compare(selected, installed) > 0;
- }
- if (installable) {
- installButton.setText(tr("Install"));
- }
- if (upgradable) {
- installButton.setText(tr("Update"));
- }
- installButton.setVisible(installable || upgradable);
- installButtonPlaceholder.setVisible(!(installable || upgradable));
-
- String name = selected.getName();
- String author = selected.getAuthor();
- // String maintainer = selectedLib.getMaintainer();
- String website = selected.getWebsite();
- String sentence = selected.getSentence();
- String paragraph = selected.getParagraph();
- // String availableVer = selectedLib.getVersion();
- // String url = selected.getUrl();
-
- String midcolor = isSelected ? "#000000" : "#888888";
-
- String desc = "";
-
- // Library name...
- desc += format("{0}", name);
- if (installed != null && installed.isReadOnly()) {
- desc += " Built-In ";
- }
-
- // ...author...
- desc += format("", midcolor);
- if (author != null && !author.isEmpty()) {
- desc += format(" by {0}", author);
- }
-
- // ...version.
- if (installed != null) {
- String installedVer = installed.getParsedVersion();
- if (installedVer == null) {
- desc += " " + tr("Version unknown");
- } else {
- desc += " " + format(tr("Version {0}"), installedVer);
- }
- }
- desc += "";
-
- if (installed != null) {
- desc += " INSTALLED";
- }
-
- desc += "
";
-
- // Description
- if (sentence != null) {
- desc += format("{0} ", sentence);
- if (paragraph != null && !paragraph.isEmpty())
- desc += format("{0}", paragraph);
- desc += "
";
- }
- if (author != null && !author.isEmpty()) {
- desc += format("More info", website);
- }
-
- desc += "";
- description.setText(desc);
- description.setBackground(Color.WHITE);
-
- // for modelToView to work, the text area has to be sized. It doesn't
- // matter if it's visible or not.
-
- // See:
- // http://stackoverflow.com/questions/3081210/how-to-set-jtextarea-to-have-height-that-matches-the-size-of-a-text-it-contains
- int width = parentTable.getBounds().width;
- setJTextPaneDimensionToFitContainedText(description, width);
-
- if (isSelected) {
- panel.setBackground(parentTable.getSelectionBackground());
- panel.setForeground(parentTable.getSelectionForeground());
- } else {
- panel.setBackground(parentTable.getBackground());
- panel.setForeground(parentTable.getForeground());
- }
- }
- }
-
- private static JTextPane makeNewDescription(JPanel panel) {
- if (panel.getComponentCount() > 0) {
- panel.remove(0);
- }
- JTextPane description = new JTextPane();
- description.setInheritsPopupMenu(true);
- Insets margin = description.getMargin();
- margin.bottom = 0;
- description.setMargin(margin);
- description.setContentType("text/html");
- Document doc = description.getDocument();
- if (doc instanceof HTMLDocument) {
- HTMLDocument html = (HTMLDocument) doc;
- StyleSheet stylesheet = html.getStyleSheet();
- stylesheet.addRule("body { margin: 0; padding: 0;"
- + "font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"
- + "font-size: 100%;" + "font-size: 0.95em; }");
- }
- description.setOpaque(false);
- description.setBorder(new EmptyBorder(4, 7, 7, 7));
- description.setHighlighter(null);
- description.setEditable(false);
- description.addHyperlinkListener(e -> {
- if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
- Base.openURL(e.getDescription());
- }
- });
- // description.addKeyListener(new DelegatingKeyListener(parentTable));
- panel.add(description, 0);
- return description;
- }
-
- protected void onRemove(ContributedLibrary selected) {
- // Empty
- }
-
- protected void onInstall(ContributedLibrary selected,
- ContributedLibrary installed) {
- // Empty
- }
+public class ContributedLibraryTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row,
int column) {
- Cell cell = new Cell();
+ ContributedLibraryTableCell cell = new ContributedLibraryTableCell();
cell.installButton.setEnabled(false);
cell.buttonsPanel.setVisible(false);
cell.inactiveButtonsPanel.setVisible(true);
+
cell.update(table, value, isSelected, row, false);
+
if (row % 2 == 0) {
cell.panel.setBackground(new Color(236, 241, 241)); // #ecf1f1
} else {
@@ -317,122 +65,4 @@ public class ContributedLibraryTableCellRenderer extends InstallerTableCell {
return cell.panel;
}
- private ContributedLibraryReleases editorValue;
- private Cell editorCell;
-
- @Override
- public Object getCellEditorValue() {
- return editorValue;
- }
-
- @Override
- public Component getTableCellEditorComponent(JTable table, Object value,
- boolean isSelected, int row,
- int column) {
- editorValue = (ContributedLibraryReleases) value;
-
- editorCell = new Cell();
- editorCell.installButton
- .addActionListener(e -> onInstall(editorValue.getSelected(),
- editorValue.getInstalled()));
- editorCell.downgradeButton.addActionListener(e -> {
- JComboBox chooser = editorCell.downgradeChooser;
- ContributedLibrary lib = (ContributedLibrary) chooser.getSelectedItem();
- onInstall(lib, editorValue.getInstalled());
- });
- editorCell.versionToInstallChooser.addItemListener(e -> editorValue
- .select((ContributedLibrary) editorCell.versionToInstallChooser
- .getSelectedItem()));
-
- setEnabled(true);
-
- final ContributedLibrary installed = editorValue.getInstalled();
-
- List releases = editorValue.getReleases().stream()
- .filter(new OnlyUpstreamReleasePredicate())
- .collect(Collectors.toList());
- List uninstalledReleases = releases.stream()
- .filter(new InstalledPredicate().negate()).collect(Collectors.toList());
-
- List installedBuiltIn = releases.stream()
- .filter(new InstalledPredicate()).filter(new BuiltInPredicate())
- .collect(Collectors.toList());
-
- if (installed != null && !installedBuiltIn.contains(installed)) {
- uninstalledReleases.addAll(installedBuiltIn);
- }
-
- Collections.sort(uninstalledReleases, new ReverseComparator<>(
- new DownloadableContributionVersionComparator()));
-
- editorCell.downgradeChooser.removeAllItems();
- editorCell.downgradeChooser.addItem(tr("Select version"));
-
- final List uninstalledPreviousReleases = new LinkedList<>();
- final List uninstalledNewerReleases = new LinkedList<>();
-
- final VersionComparator versionComparator = new VersionComparator();
- uninstalledReleases.stream().forEach(input -> {
- if (installed == null
- || versionComparator.greaterThan(installed.getParsedVersion(),
- input.getParsedVersion())) {
- uninstalledPreviousReleases.add(input);
- } else {
- uninstalledNewerReleases.add(input);
- }
- });
- uninstalledNewerReleases.forEach(editorCell.downgradeChooser::addItem);
- uninstalledPreviousReleases.forEach(editorCell.downgradeChooser::addItem);
-
- editorCell.downgradeChooser
- .setVisible(installed != null
- && (!uninstalledPreviousReleases.isEmpty()
- || uninstalledNewerReleases.size() > 1));
- editorCell.downgradeButton
- .setVisible(installed != null
- && (!uninstalledPreviousReleases.isEmpty()
- || uninstalledNewerReleases.size() > 1));
-
- editorCell.versionToInstallChooser.removeAllItems();
- uninstalledReleases.forEach(editorCell.versionToInstallChooser::addItem);
- editorCell.versionToInstallChooser
- .setVisible(installed == null && uninstalledReleases.size() > 1);
-
- editorCell.update(table, value, true, row, !installedBuiltIn.isEmpty());
- editorCell.panel.setBackground(new Color(218, 227, 227)); // #dae3e3
- return editorCell.panel;
- }
-
- private final Timer enabler = new Timer(100, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- enable(true);
- enabler.stop();
- }
- });
-
- @Override
- public void setEnabled(boolean enabled) {
- enable(false);
- if (enabled) {
- enabler.start();
- } else {
- enabler.stop();
- }
- editorCell.buttonsPanel.setVisible(enabled);
- editorCell.inactiveButtonsPanel.setVisible(!enabled);
- }
-
- public void enable(boolean enabled) {
- editorCell.installButton.setEnabled(enabled);
- }
-
- public void setStatus(String status) {
- editorCell.statusLabel.setText(status);
- }
-
- public void invalidate() {
- editorCell.panel.invalidate();
- }
-
}
diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java
index 64210818d..943c21fdd 100644
--- a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java
+++ b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java
@@ -29,16 +29,10 @@
package cc.arduino.contributions.libraries.ui;
-import cc.arduino.contributions.DownloadableContribution;
-import cc.arduino.contributions.libraries.ContributedLibrary;
-import cc.arduino.contributions.libraries.LibraryInstaller;
-import cc.arduino.contributions.libraries.LibraryTypeComparator;
-import cc.arduino.contributions.ui.*;
-import cc.arduino.utils.Progress;
-import processing.app.BaseNoGui;
+import static processing.app.I18n.tr;
-import javax.swing.*;
-import java.awt.*;
+import java.awt.Dialog;
+import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
@@ -46,7 +40,24 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.function.Predicate;
-import static processing.app.I18n.tr;
+import javax.swing.Box;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.table.TableCellRenderer;
+
+import cc.arduino.contributions.DownloadableContribution;
+import cc.arduino.contributions.libraries.ContributedLibrary;
+import cc.arduino.contributions.libraries.LibraryInstaller;
+import cc.arduino.contributions.libraries.LibraryTypeComparator;
+import cc.arduino.contributions.ui.DropdownAllItem;
+import cc.arduino.contributions.ui.DropdownItem;
+import cc.arduino.contributions.ui.FilteredAbstractTableModel;
+import cc.arduino.contributions.ui.InstallerJDialog;
+import cc.arduino.contributions.ui.InstallerJDialogUncaughtExceptionHandler;
+import cc.arduino.contributions.ui.InstallerTableCell;
+import cc.arduino.utils.Progress;
+import processing.app.BaseNoGui;
@SuppressWarnings("serial")
public class LibraryManagerUI extends InstallerJDialog {
@@ -65,13 +76,13 @@ public class LibraryManagerUI extends InstallerJDialog {
}
@Override
- protected InstallerTableCell createCellRenderer() {
+ protected TableCellRenderer createCellRenderer() {
return new ContributedLibraryTableCellRenderer();
}
@Override
protected InstallerTableCell createCellEditor() {
- return new ContributedLibraryTableCellRenderer() {
+ return new ContributedLibraryTableCellEditor() {
@Override
protected void onInstall(ContributedLibrary selectedLibrary, ContributedLibrary installedLibrary) {
if (selectedLibrary.isReadOnly()) {
diff --git a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java
index 255d6f407..14c53b025 100644
--- a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java
+++ b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java
@@ -29,21 +29,44 @@
package cc.arduino.contributions.ui;
-import cc.arduino.contributions.ui.listeners.AbstractKeyListener;
-import processing.app.Base;
-import processing.app.Theme;
+import static cc.arduino.contributions.packages.ui.ContributionIndexTableModel.DESCRIPTION_COL;
+import static processing.app.I18n.tr;
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.table.TableColumn;
-import javax.swing.table.TableColumnModel;
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
import java.util.function.Predicate;
import java.util.stream.Stream;
-import static cc.arduino.contributions.packages.ui.ContributionIndexTableModel.DESCRIPTION_COL;
-import static processing.app.I18n.tr;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
+import javax.swing.border.EmptyBorder;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+
+import cc.arduino.contributions.ui.listeners.AbstractKeyListener;
+import processing.app.Base;
+import processing.app.Theme;
public abstract class InstallerJDialog extends JDialog {
@@ -67,7 +90,7 @@ public abstract class InstallerJDialog extends JDialog {
abstract protected FilteredAbstractTableModel createContribModel();
- abstract protected InstallerTableCell createCellRenderer();
+ abstract protected TableCellRenderer createCellRenderer();
abstract protected InstallerTableCell createCellEditor();
diff --git a/app/src/cc/arduino/contributions/ui/InstallerTableCell.java b/app/src/cc/arduino/contributions/ui/InstallerTableCell.java
index e45655d2f..bbf62ebad 100644
--- a/app/src/cc/arduino/contributions/ui/InstallerTableCell.java
+++ b/app/src/cc/arduino/contributions/ui/InstallerTableCell.java
@@ -29,21 +29,21 @@
package cc.arduino.contributions.ui;
-import javax.swing.*;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+import javax.swing.AbstractCellEditor;
+import javax.swing.JTextPane;
import javax.swing.table.TableCellEditor;
-import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
-import java.awt.*;
-public abstract class InstallerTableCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
+public abstract class InstallerTableCell extends AbstractCellEditor implements TableCellEditor {
- public void setEnabled(boolean b) {
- }
+ abstract public void setEnabled(boolean b);
- public void setStatus(String s) {
- }
+ abstract public void setStatus(String s);
- protected void setJTextPaneDimensionToFitContainedText(JTextPane jTextPane, int width) {
+ public static void setJTextPaneDimensionToFitContainedText(JTextPane jTextPane, int width) {
Dimension minimumDimension = new Dimension(width, 10);
jTextPane.setPreferredSize(minimumDimension);
jTextPane.setSize(minimumDimension);