diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java deleted file mode 100644 index 54cd56718..000000000 --- a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 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 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.contributions.ui.listeners.DelegatingKeyListener; -import cc.arduino.utils.ReverseComparator; -import processing.app.Base; - -import javax.swing.*; -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 java.awt.*; -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 static processing.app.I18n.format; -import static processing.app.I18n.tr; - -@SuppressWarnings("serial") -public class ContributedLibraryTableCell extends InstallerTableCell { - - private final JPanel panel; - private final JButton installButton; - private final Component installButtonPlaceholder; - private JComboBox downgradeChooser; - private final JComboBox versionToInstallChooser; - private final JButton downgradeButton; - private final JPanel buttonsPanel; - private final JPanel inactiveButtonsPanel; - private final JLabel statusLabel; - - public ContributedLibraryTableCell() { - { - installButton = new JButton(tr("Install")); - installButton.addActionListener(e -> onInstall(editorValue.getSelected(), editorValue.getInstalled())); - int width = installButton.getPreferredSize().width; - installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1)); - } - - downgradeButton = new JButton(tr("Install")); - downgradeButton.addActionListener(e -> { - ContributedLibrary selected = (ContributedLibrary) downgradeChooser.getSelectedItem(); - onInstall(selected, editorValue.getInstalled()); - }); - - 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()); - versionToInstallChooser.addItemListener(e -> editorValue.select((ContributedLibrary) versionToInstallChooser.getSelectedItem())); - - 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 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 Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, - boolean hasFocus, int row, - int column) { - parentTable = table; - setEnabled(false); - Component component = getUpdatedCellComponent(value, isSelected, row, false); - if (row % 2 == 0) { - component.setBackground(new Color(236, 241, 241)); //#ecf1f1 - } else { - component.setBackground(new Color(255, 255, 255)); - } - - int height = new Double(component.getPreferredSize().getHeight()).intValue(); - if (table.getRowHeight(row) < height) { - table.setRowHeight(row, height); - } - - return component; - } - - private ContributedLibraryReleases editorValue; - private JTable parentTable; - - @Override - public Object getCellEditorValue() { - return editorValue; - } - - @Override - public Component getTableCellEditorComponent(JTable table, Object value, - boolean isSelected, int row, - int column) { - parentTable = table; - editorValue = (ContributedLibraryReleases) value; - 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())); - - downgradeChooser.removeAllItems(); - 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(downgradeChooser::addItem); - uninstalledPreviousReleases.forEach(downgradeChooser::addItem); - - downgradeChooser.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1)); - downgradeButton.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1)); - - versionToInstallChooser.removeAllItems(); - uninstalledReleases.forEach(versionToInstallChooser::addItem); - versionToInstallChooser.setVisible(installed == null && uninstalledReleases.size() > 1); - - Component component = getUpdatedCellComponent(value, true, row, !installedBuiltIn.isEmpty()); - component.setBackground(new Color(218, 227, 227)); //#dae3e3 - return component; - } - - private Component getUpdatedCellComponent(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 panel; - } - - 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()); - } - - return 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(); - } - buttonsPanel.setVisible(enabled); - inactiveButtonsPanel.setVisible(!enabled); - } - - public void enable(boolean enabled) { - installButton.setEnabled(enabled); - } - - public void setStatus(String status) { - statusLabel.setText(status); - } - - public void invalidate() { - panel.invalidate(); - } - -} 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..f2299ac52 --- /dev/null +++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellEditor.java @@ -0,0 +1,159 @@ +/* + * 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.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.swing.JComboBox; +import javax.swing.JTable; + +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 ContributedLibraryTableCellJPanel 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 ContributedLibraryTableCellJPanel(table, value, true); + 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.setBackground(new Color(218, 227, 227)); // #dae3e3 + return editorCell; + } + + @Override + public void setEnabled(boolean enabled) { + editorCell.setButtonsVisible(enabled); + } + + public void setStatus(String status) { + editorCell.statusLabel.setText(status); + } + + protected void onRemove(ContributedLibrary selected) { + // Empty + } + + protected void onInstall(ContributedLibrary selected, + ContributedLibrary installed) { + // Empty + } + +} diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellJPanel.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellJPanel.java new file mode 100644 index 000000000..59087b6b0 --- /dev/null +++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellJPanel.java @@ -0,0 +1,244 @@ +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 ContributedLibraryTableCellJPanel extends JPanel { + + final JButton installButton; + final Component installButtonPlaceholder; + final JComboBox downgradeChooser; + final JComboBox versionToInstallChooser; + final JButton downgradeButton; + final JPanel buttonsPanel; + final JPanel inactiveButtonsPanel; + final JLabel statusLabel; + + public ContributedLibraryTableCellJPanel(JTable parentTable, Object value, + boolean isSelected) { + super(); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + 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()); + + makeNewDescription(); + + 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)); + + 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)); + + add(inactiveButtonsPanel); + + add(Box.createVerticalStrut(15)); + + ContributedLibraryReleases releases = (ContributedLibraryReleases) value; + JTextPane description = makeNewDescription(); + + // 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 + InstallerTableCell + .setJTextPaneDimensionToFitContainedText(description, + parentTable.getBounds().width); + + if (isSelected) { + setBackground(parentTable.getSelectionBackground()); + setForeground(parentTable.getSelectionForeground()); + } else { + setBackground(parentTable.getBackground()); + setForeground(parentTable.getForeground()); + } + } + + private JTextPane makeNewDescription() { + if (getComponentCount() > 0) { + 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)); + add(description, 0); + return description; + } + + public void setButtonsVisible(boolean enabled) { + installButton.setEnabled(enabled); + buttonsPanel.setVisible(enabled); + inactiveButtonsPanel.setVisible(!enabled); + } +} diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java new file mode 100644 index 000000000..bc4b3ffd9 --- /dev/null +++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellRenderer.java @@ -0,0 +1,63 @@ +/* + * 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 java.awt.Color; +import java.awt.Component; + +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; + +@SuppressWarnings("serial") +public class ContributedLibraryTableCellRenderer implements TableCellRenderer { + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, + boolean hasFocus, int row, + int column) { + ContributedLibraryTableCellJPanel cell = new ContributedLibraryTableCellJPanel(table, + value, isSelected); + cell.setButtonsVisible(false); + + if (row % 2 == 0) { + cell.setBackground(new Color(236, 241, 241)); // #ecf1f1 + } else { + cell.setBackground(new Color(255, 255, 255)); + } + + int height = new Double(cell.getPreferredSize().getHeight()).intValue(); + if (table.getRowHeight(row) < height) { + table.setRowHeight(row, height); + } + + return cell; + } + +} diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java b/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java index 79917e0b1..40bd655ad 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java +++ b/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java @@ -41,20 +41,20 @@ import java.util.function.Predicate; import java.util.stream.Stream; @SuppressWarnings("serial") -public class LibrariesIndexTableModel extends FilteredAbstractTableModel { - - public final static int DESCRIPTION_COL = 0; +public class LibrariesIndexTableModel + extends FilteredAbstractTableModel { private final List contributions = new ArrayList<>(); - private final String[] columnNames = {"Description"}; + private final String[] columnNames = { "Description" }; - private final Class[] columnTypes = {ContributedPlatform.class}; + private final Class[] columnTypes = { ContributedPlatform.class }; Predicate selectedCategoryFilter = null; String selectedFilters[] = null; - public void updateIndexFilter(String filters[], Stream> additionalFilters) { + public void updateIndexFilter(String filters[], + Stream> additionalFilters) { selectedCategoryFilter = additionalFilters.reduce(Predicate::and).get(); selectedFilters = filters; update(); @@ -67,7 +67,7 @@ public class LibrariesIndexTableModel extends FilteredAbstractTableModeltrue if all the strings in set are contained in - * string. + * string. */ private boolean stringContainsAll(String string, String filters[]) { if (string == null) { @@ -120,9 +120,7 @@ public class LibrariesIndexTableModel extends FilteredAbstractTableModel { @@ -60,18 +71,14 @@ public class LibraryManagerUI extends InstallerJDialog { return new LibrariesIndexTableModel(); } - private LibrariesIndexTableModel getContribModel() { - return (LibrariesIndexTableModel) contribModel; - } - @Override - protected InstallerTableCell createCellRenderer() { - return new ContributedLibraryTableCell(); + protected TableCellRenderer createCellRenderer() { + return new ContributedLibraryTableCellRenderer(); } @Override protected InstallerTableCell createCellEditor() { - return new ContributedLibraryTableCell() { + return new ContributedLibraryTableCellEditor() { @Override protected void onInstall(ContributedLibrary selectedLibrary, ContributedLibrary installedLibrary) { if (selectedLibrary.isReadOnly()) { diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformReleases.java b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformReleases.java new file mode 100644 index 000000000..3c356749e --- /dev/null +++ b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformReleases.java @@ -0,0 +1,103 @@ +/* + * 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.packages.ui; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator; +import cc.arduino.contributions.filters.InstalledPredicate; +import cc.arduino.contributions.packages.ContributedPackage; +import cc.arduino.contributions.packages.ContributedPlatform; + +public class ContributedPlatformReleases { + + public final ContributedPackage packager; + public final String arch; + public final List releases; + public final List versions; + public ContributedPlatform selected = null; + + public ContributedPlatformReleases(ContributedPlatform platform) { + packager = platform.getParentPackage(); + arch = platform.getArchitecture(); + releases = new LinkedList<>(); + versions = new LinkedList<>(); + add(platform); + } + + public boolean shouldContain(ContributedPlatform platform) { + if (platform.getParentPackage() != packager) + return false; + return platform.getArchitecture().equals(arch); + } + + public void add(ContributedPlatform platform) { + releases.add(platform); + String version = platform.getParsedVersion(); + if (version != null) { + versions.add(version); + } + selected = getLatest(); + } + + public ContributedPlatform getInstalled() { + List installedReleases = releases.stream() + .filter(new InstalledPredicate()).collect(Collectors.toList()); + Collections + .sort(installedReleases, + new DownloadableContributionBuiltInAtTheBottomComparator()); + + if (installedReleases.isEmpty()) { + return null; + } + + return installedReleases.get(0); + } + + public ContributedPlatform getLatest() { + return ContributionIndexTableModel.getLatestOf(releases); + } + + public ContributedPlatform getSelected() { + return selected; + } + + public void select(ContributedPlatform value) { + for (ContributedPlatform plat : releases) { + if (plat == value) { + selected = plat; + return; + } + } + } +} \ No newline at end of file diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java deleted file mode 100644 index 04dc4d8f2..000000000 --- a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * 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.packages.ui; - -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.packages.ContributedBoard; -import cc.arduino.contributions.packages.ContributedHelp; -import cc.arduino.contributions.packages.ContributedPlatform; -import cc.arduino.contributions.ui.InstallerTableCell; -import cc.arduino.contributions.ui.listeners.DelegatingKeyListener; -import cc.arduino.utils.ReverseComparator; -import processing.app.Base; - -import javax.swing.*; -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 java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Collections; -import java.util.LinkedList; -import java.util.stream.Collectors; - -import static processing.app.I18n.format; -import static processing.app.I18n.tr; - -@SuppressWarnings("serial") -public class ContributedPlatformTableCell extends InstallerTableCell { - - private final JPanel panel; - private final JButton installButton; - private final JButton removeButton; - private final Component removeButtonPlaceholder; - private final Component installButtonPlaceholder; - private JComboBox downgradeChooser; - private final JComboBox versionToInstallChooser; - private final JButton downgradeButton; - private final JPanel buttonsPanel; - private final JPanel inactiveButtonsPanel; - private final JLabel statusLabel; - - public ContributedPlatformTableCell() { - { - installButton = new JButton(tr("Install")); - installButton.addActionListener(e -> onInstall(editorValue.getSelected(), editorValue.getInstalled())); - int width = installButton.getPreferredSize().width; - installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1)); - } - - { - removeButton = new JButton(tr("Remove")); - removeButton.addActionListener(e -> onRemove(editorValue.getInstalled())); - int width = removeButton.getPreferredSize().width; - removeButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1)); - } - - downgradeButton = new JButton(tr("Install")); - downgradeButton.addActionListener(e -> { - ContributedPlatform selected = (ContributedPlatform) downgradeChooser.getSelectedItem(); - onInstall(selected, editorValue.getInstalled()); - }); - - 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()); - versionToInstallChooser.addItemListener(e -> editorValue.select((ContributedPlatform) versionToInstallChooser.getSelectedItem())); - - 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(removeButton); - 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 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(ContributedPlatform contributedPlatform) { - // Empty - } - - protected void onInstall(ContributedPlatform contributedPlatform, ContributedPlatform installed) { - // Empty - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, - boolean hasFocus, int row, - int column) { - parentTable = table; - setEnabled(false); - Component component = getUpdatedCellComponent(value, isSelected, row, false); - if (row % 2 == 0) { - component.setBackground(new Color(236, 241, 241)); //#ecf1f1 - } else { - component.setBackground(new Color(255, 255, 255)); - } - - int height = new Double(component.getPreferredSize().getHeight()).intValue(); - if (table.getRowHeight(row) < height) { - table.setRowHeight(row, height); - } - - return component; - } - - private ContributionIndexTableModel.ContributedPlatformReleases editorValue; - private JTable parentTable; - - @Override - public Object getCellEditorValue() { - return editorValue; - } - - @Override - public Component getTableCellEditorComponent(JTable table, Object value, - boolean isSelected, int row, - int column) { - parentTable = table; - editorValue = (ContributionIndexTableModel.ContributedPlatformReleases) value; - setEnabled(true); - - final ContributedPlatform installed = editorValue.getInstalled(); - - java.util.List releases = new LinkedList<>(editorValue.releases); - java.util.List uninstalledReleases = releases.stream().filter(new InstalledPredicate().negate()).collect(Collectors.toList()); - - java.util.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())); - - downgradeChooser.removeAllItems(); - downgradeChooser.addItem(tr("Select version")); - - final java.util.List uninstalledPreviousReleases = new LinkedList<>(); - final java.util.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(downgradeChooser::addItem); - uninstalledPreviousReleases.forEach(downgradeChooser::addItem); - - downgradeChooser.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1)); - downgradeButton.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1)); - - versionToInstallChooser.removeAllItems(); - uninstalledReleases.forEach(versionToInstallChooser::addItem); - versionToInstallChooser.setVisible(installed == null && uninstalledReleases.size() > 1); - - Component component = getUpdatedCellComponent(value, true, row, !installedBuiltIn.isEmpty()); - component.setBackground(new Color(218, 227, 227)); //#dae3e3 - return component; - } - - private Component getUpdatedCellComponent(Object value, boolean isSelected, int row, boolean hasBuiltInRelease) { - ContributionIndexTableModel.ContributedPlatformReleases releases = (ContributionIndexTableModel.ContributedPlatformReleases) value; - - JTextPane description = makeNewDescription(panel); - - //FIXME: happens on macosx, don't know why - if (releases == null) { - return panel; - } - - ContributedPlatform selected = releases.getSelected(); - ContributedPlatform installed = releases.getInstalled(); - - boolean removable, installable, upgradable; - if (installed == null) { - installable = true; - removable = false; - upgradable = false; - } else { - installable = false; - removable = !installed.isReadOnly() && !hasBuiltInRelease; - 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)); - removeButton.setVisible(removable); - removeButtonPlaceholder.setVisible(!removable); - - String desc = ""; - desc += "" + selected.getName() + ""; - if (installed != null && installed.isReadOnly()) { - desc += " Built-In "; - } - - String author = selected.getParentPackage().getMaintainer(); - if (author != null && !author.isEmpty()) { - desc += " " + format("by {0}", author); - } - if (installed != null) { - desc += " " + format(tr("version {0}"), installed.getParsedVersion()) + " INSTALLED"; - } - desc += "
"; - - desc += tr("Boards included in this package:") + "
"; - for (ContributedBoard board : selected.getBoards()) { - desc += board.getName() + ", "; - } - if (desc.lastIndexOf(',') != -1) { - desc = desc.substring(0, desc.lastIndexOf(',')) + ".
"; - } - - ContributedHelp help = null; - if (selected.getHelp() != null) { - help = selected.getHelp(); - } else if (selected.getParentPackage().getHelp() != null) { - help = selected.getParentPackage().getHelp(); - } - if (help != null) { - String url = help.getOnline(); - if (url != null && !url.isEmpty()) { - desc += " " + format("Online help
", url); - } - } - - String url = selected.getParentPackage().getWebsiteURL(); - if (url != null && !url.isEmpty()) { - desc += " " + format("More info", url); - } - - 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()); - } - - return 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(); - } - buttonsPanel.setVisible(enabled); - inactiveButtonsPanel.setVisible(!enabled); - } - - public void enable(boolean enabled) { - installButton.setEnabled(enabled); - removeButton.setEnabled(enabled); - } - - public void setStatus(String status) { - statusLabel.setText(status); - } - - public void invalidate() { - panel.invalidate(); - } - -} diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellEditor.java b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellEditor.java new file mode 100644 index 000000000..cc3cfbb63 --- /dev/null +++ b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellEditor.java @@ -0,0 +1,153 @@ +/* + * 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.packages.ui; + +import static processing.app.I18n.tr; + +import java.awt.Color; +import java.awt.Component; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.swing.JTable; + +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.packages.ContributedPlatform; +import cc.arduino.contributions.ui.InstallerTableCell; +import cc.arduino.utils.ReverseComparator; + +@SuppressWarnings("serial") +public class ContributedPlatformTableCellEditor extends InstallerTableCell { + + private ContributedPlatformTableCellJPanel cell; + private ContributedPlatformReleases value; + + @Override + public Object getCellEditorValue() { + return value; + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object _value, + boolean isSelected, int row, + int column) { + value = (ContributedPlatformReleases) _value; + + cell = new ContributedPlatformTableCellJPanel(); + cell.installButton.addActionListener(e -> onInstall(value.getSelected(), + value.getInstalled())); + cell.removeButton.addActionListener(e -> onRemove(value.getInstalled())); + cell.downgradeButton.addActionListener(e -> { + ContributedPlatform selected = (ContributedPlatform) cell.downgradeChooser + .getSelectedItem(); + onInstall(selected, value.getInstalled()); + }); + cell.versionToInstallChooser.addItemListener(e -> value + .select((ContributedPlatform) cell.versionToInstallChooser + .getSelectedItem())); + + setEnabled(true); + + final ContributedPlatform installed = value.getInstalled(); + + List releases = new LinkedList<>(value.releases); + 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())); + + cell.downgradeChooser.removeAllItems(); + cell.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(cell.downgradeChooser::addItem); + uninstalledPreviousReleases.forEach(cell.downgradeChooser::addItem); + + boolean downgradeVisible = installed != null + && (!uninstalledPreviousReleases.isEmpty() + || uninstalledNewerReleases.size() > 1); + cell.downgradeChooser.setVisible(downgradeVisible); + cell.downgradeButton.setVisible(downgradeVisible); + + cell.versionToInstallChooser.removeAllItems(); + uninstalledReleases.forEach(cell.versionToInstallChooser::addItem); + cell.versionToInstallChooser + .setVisible(installed == null && uninstalledReleases.size() > 1); + + cell.update(table, _value, true, !installedBuiltIn.isEmpty()); + cell.setBackground(new Color(218, 227, 227)); // #dae3e3 + return cell; + } + + @Override + public void setEnabled(boolean enabled) { + cell.setButtonsVisible(enabled); + } + + public void setStatus(String status) { + cell.statusLabel.setText(status); + } + + protected void onRemove(ContributedPlatform contributedPlatform) { + // Empty + } + + protected void onInstall(ContributedPlatform contributedPlatform, + ContributedPlatform installed) { + // Empty + } + +} diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellJPanel.java b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellJPanel.java new file mode 100644 index 000000000..7ed3b4480 --- /dev/null +++ b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellJPanel.java @@ -0,0 +1,287 @@ +/* + * 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.packages.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.packages.ContributedBoard; +import cc.arduino.contributions.packages.ContributedHelp; +import cc.arduino.contributions.packages.ContributedPlatform; +import cc.arduino.contributions.ui.InstallerTableCell; +import processing.app.Base; + +@SuppressWarnings("serial") +public class ContributedPlatformTableCellJPanel extends JPanel { + + final JButton installButton; + final JButton removeButton; + final Component removeButtonPlaceholder; + final Component installButtonPlaceholder; + final JComboBox downgradeChooser; + final JComboBox versionToInstallChooser; + final JButton downgradeButton; + final JPanel buttonsPanel; + final JPanel inactiveButtonsPanel; + final JLabel statusLabel; + + public ContributedPlatformTableCellJPanel() { + super(); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + { + installButton = new JButton(tr("Install")); + int width = installButton.getPreferredSize().width; + installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1)); + } + + { + removeButton = new JButton(tr("Remove")); + int width = removeButton.getPreferredSize().width; + removeButtonPlaceholder = 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()); + + makeNewDescription(); + + 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(removeButton); + buttonsPanel.add(Box.createHorizontalStrut(5)); + buttonsPanel.add(Box.createHorizontalStrut(15)); + + 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)); + + add(inactiveButtonsPanel); + + add(Box.createVerticalStrut(15)); + } + + void update(JTable parentTable, Object value, boolean isSelected, + boolean hasBuiltInRelease) { + ContributedPlatformReleases releases = (ContributedPlatformReleases) value; + + JTextPane description = makeNewDescription(); + + // FIXME: happens on macosx, don't know why + if (releases == null) { + return; + } + + ContributedPlatform selected = releases.getSelected(); + ContributedPlatform installed = releases.getInstalled(); + + boolean removable, installable, upgradable; + if (installed == null) { + installable = true; + removable = false; + upgradable = false; + } else { + installable = false; + removable = !installed.isReadOnly() && !hasBuiltInRelease; + 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)); + removeButton.setVisible(removable); + removeButtonPlaceholder.setVisible(!removable); + + String desc = ""; + desc += "" + selected.getName() + ""; + if (installed != null && installed.isReadOnly()) { + desc += " Built-In "; + } + + String author = selected.getParentPackage().getMaintainer(); + if (author != null && !author.isEmpty()) { + desc += " " + format("by {0}", author); + } + if (installed != null) { + desc += " " + + format(tr("version {0}"), installed.getParsedVersion()) + + " INSTALLED"; + } + desc += "
"; + + desc += tr("Boards included in this package:") + "
"; + for (ContributedBoard board : selected.getBoards()) { + desc += board.getName() + ", "; + } + if (desc.lastIndexOf(',') != -1) { + desc = desc.substring(0, desc.lastIndexOf(',')) + ".
"; + } + + ContributedHelp help = null; + if (selected.getHelp() != null) { + help = selected.getHelp(); + } else if (selected.getParentPackage().getHelp() != null) { + help = selected.getParentPackage().getHelp(); + } + if (help != null) { + String url = help.getOnline(); + if (url != null && !url.isEmpty()) { + desc += " " + format("Online help
", url); + } + } + + String url = selected.getParentPackage().getWebsiteURL(); + if (url != null && !url.isEmpty()) { + desc += " " + format("More info", url); + } + + 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) { + setBackground(parentTable.getSelectionBackground()); + setForeground(parentTable.getSelectionForeground()); + } else { + setBackground(parentTable.getBackground()); + setForeground(parentTable.getForeground()); + } + } + + private JTextPane makeNewDescription() { + if (getComponentCount() > 0) { + 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()); + } + }); + add(description, 0); + return description; + } + + public void setButtonsVisible(boolean enabled) { + installButton.setEnabled(enabled); + removeButton.setEnabled(enabled); + buttonsPanel.setVisible(enabled); + inactiveButtonsPanel.setVisible(!enabled); + } + +} diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellRenderer.java b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellRenderer.java new file mode 100644 index 000000000..cc4b1d0c1 --- /dev/null +++ b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCellRenderer.java @@ -0,0 +1,63 @@ +/* + * 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.packages.ui; + +import java.awt.Color; +import java.awt.Component; + +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; + +@SuppressWarnings("serial") +public class ContributedPlatformTableCellRenderer implements TableCellRenderer { + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, + boolean hasFocus, int row, + int column) { + ContributedPlatformTableCellJPanel cell = new ContributedPlatformTableCellJPanel(); + cell.setButtonsVisible(false); + cell.update(table, value, isSelected, false); + + if (row % 2 == 0) { + cell.setBackground(new Color(236, 241, 241)); // #ecf1f1 + } else { + cell.setBackground(new Color(255, 255, 255)); + } + + int height = new Double(cell.getPreferredSize().getHeight()).intValue(); + if (table.getRowHeight(row) < height) { + table.setRowHeight(row, height); + } + + return cell; + } + +} diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java b/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java index 212c8617d..283df1067 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java @@ -29,8 +29,6 @@ package cc.arduino.contributions.packages.ui; -import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator; -import cc.arduino.contributions.filters.InstalledPredicate; import cc.arduino.contributions.packages.ContributedBoard; import cc.arduino.contributions.packages.ContributedPackage; import cc.arduino.contributions.packages.ContributedPlatform; @@ -38,89 +36,30 @@ import cc.arduino.contributions.ui.FilteredAbstractTableModel; import processing.app.BaseNoGui; import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @SuppressWarnings("serial") -public class ContributionIndexTableModel extends FilteredAbstractTableModel { - - public final static int DESCRIPTION_COL = 0; - - public static class ContributedPlatformReleases { - public final ContributedPackage packager; - public final String arch; - public final List releases; - public final List versions; - public ContributedPlatform selected = null; - - public ContributedPlatformReleases(ContributedPlatform platform) { - this.packager = platform.getParentPackage(); - this.arch = platform.getArchitecture(); - this.releases = new LinkedList<>(); - this.versions = new LinkedList<>(); - add(platform); - } - - public boolean shouldContain(ContributedPlatform platform) { - if (platform.getParentPackage() != packager) - return false; - return platform.getArchitecture().equals(arch); - } - - public void add(ContributedPlatform platform) { - releases.add(platform); - String version = platform.getParsedVersion(); - if (version != null) { - versions.add(version); - } - selected = getLatest(); - } - - public ContributedPlatform getInstalled() { - List installedReleases = releases.stream().filter(new InstalledPredicate()).collect(Collectors.toList()); - Collections.sort(installedReleases, new DownloadableContributionBuiltInAtTheBottomComparator()); - - if (installedReleases.isEmpty()) { - return null; - } - - return installedReleases.get(0); - } - - public ContributedPlatform getLatest() { - return getLatestOf(releases); - } - - public ContributedPlatform getSelected() { - return selected; - } - - public void select(ContributedPlatform value) { - for (ContributedPlatform plat : releases) { - if (plat == value) { - selected = plat; - return; - } - } - } - } +public class ContributionIndexTableModel + extends FilteredAbstractTableModel { private final List contributions = new ArrayList<>(); + private final String[] columnNames = { "Description" }; + private final Class[] columnTypes = { ContributedPlatform.class }; - private final String[] columnNames = {"Description"}; - - private final Class[] columnTypes = {ContributedPlatform.class}; - - public void updateIndexFilter(String[] filters, Stream> additionalFilters) { + public void updateIndexFilter(String[] filters, + Stream> additionalFilters) { contributions.clear(); - Predicate filter = additionalFilters.reduce(Predicate::and).get(); + Predicate filter = additionalFilters + .reduce(Predicate::and).get(); for (ContributedPackage pack : BaseNoGui.indexer.getPackages()) { for (ContributedPlatform platform : pack.getPlatforms()) { - String compoundTargetSearchText = platform.getName() + "\n" + platform.getBoards().stream().map(ContributedBoard::getName).collect(Collectors.joining(" ")); + String compoundTargetSearchText = platform.getName() + "\n" + + platform.getBoards().stream() + .map(ContributedBoard::getName) + .collect(Collectors.joining(" ")); if (!filter.test(platform)) { continue; } @@ -139,7 +78,7 @@ public class ContributionIndexTableModel extends FilteredAbstractTableModeltrue if all the strings in set are contained in - * string. + * string. */ private boolean stringContainsAll(String string, String set[]) { if (set == null) @@ -184,9 +123,7 @@ public class ContributionIndexTableModel extends FilteredAbstractTableModel previouslySelectedCategory = (DropdownItem) categoryChooser.getSelectedItem(); + DropdownItem previouslySelectedCategory = (DropdownItem) categoryChooser + .getSelectedItem(); categoryChooser.removeActionListener(categoryChooserActionListener); @@ -138,7 +143,8 @@ public class ContributionManagerUI extends InstallerJDialog { installerThread = new Thread(() -> { try { setProgressVisible(true, ""); - List downloadedPackageIndexFiles = installer.updateIndex(this::setProgress); + List downloadedPackageIndexFiles = installer + .updateIndex(this::setProgress); installer.deleteUnknownFiles(downloadedPackageIndexFiles); onIndexesUpdated(); } catch (Exception e) { @@ -148,11 +154,14 @@ public class ContributionManagerUI extends InstallerJDialog { } }); installerThread.setName("ContributionManager Update Thread"); - installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage)); + installerThread + .setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler( + this, noConnectionErrorMessage)); installerThread.start(); } - public void onInstallPressed(final ContributedPlatform platformToInstall, final ContributedPlatform platformToRemove) { + public void onInstallPressed(final ContributedPlatform platformToInstall, + final ContributedPlatform platformToRemove) { clearErrorMessage(); installerThread = new Thread(() -> { List errors = new LinkedList<>(); @@ -173,15 +182,24 @@ public class ContributionManagerUI extends InstallerJDialog { } }); installerThread.setName("ContributionManager Install Thread"); - installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage)); + installerThread + .setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler( + this, noConnectionErrorMessage)); installerThread.start(); } - public void onRemovePressed(final ContributedPlatform platform, boolean showWarning) { + public void onRemovePressed(final ContributedPlatform platform, + boolean showWarning) { clearErrorMessage(); if (showWarning) { - int chosenOption = JOptionPane.showConfirmDialog(this, I18n.format(tr("Do you want to remove {0}?\nIf you do so you won't be able to use {0} any more."), platform.getName()), tr("Please confirm boards deletion"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + int chosenOption = JOptionPane + .showConfirmDialog(this, + I18n.format(tr("Do you want to remove {0}?\nIf you do so you won't be able to use {0} any more."), + platform.getName()), + tr("Please confirm boards deletion"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); if (chosenOption != JOptionPane.YES_OPTION) { return; } @@ -199,7 +217,9 @@ public class ContributionManagerUI extends InstallerJDialog { } }); installerThread.setName("ContributionManager Remove Thread"); - installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage)); + installerThread + .setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler( + this, noConnectionErrorMessage)); installerThread.start(); } diff --git a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java index 255d6f407..9de0dc136 100644 --- a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java +++ b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java @@ -29,21 +29,43 @@ package cc.arduino.contributions.ui; -import cc.arduino.contributions.ui.listeners.AbstractKeyListener; -import processing.app.Base; -import processing.app.Theme; +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 +89,7 @@ public abstract class InstallerJDialog extends JDialog { abstract protected FilteredAbstractTableModel createContribModel(); - abstract protected InstallerTableCell createCellRenderer(); + abstract protected TableCellRenderer createCellRenderer(); abstract protected InstallerTableCell createCellEditor(); @@ -142,7 +164,7 @@ public abstract class InstallerJDialog extends JDialog { { TableColumnModel tcm = contribTable.getColumnModel(); - TableColumn col = tcm.getColumn(DESCRIPTION_COL); + TableColumn col = tcm.getColumn(0); col.setCellRenderer(createCellRenderer()); col.setCellEditor(createCellEditor()); col.setResizable(true); 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);