Skip to content
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ public ContributedLibraryTableCellJPanel(JTable parentTable, Object value,
}
}

// TODO Make this a method of Theme
private JTextPane makeNewDescription() {
if (getComponentCount() > 0) {
remove(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;

import javax.swing.Box;
Expand All @@ -50,6 +51,7 @@
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibraryInstaller;
import cc.arduino.contributions.libraries.LibraryTypeComparator;
import cc.arduino.contributions.libraries.ui.MultiLibraryInstallDialog.Result;
import cc.arduino.contributions.ui.DropdownAllItem;
import cc.arduino.contributions.ui.DropdownItem;
import cc.arduino.contributions.ui.FilteredAbstractTableModel;
Expand Down Expand Up @@ -84,7 +86,7 @@ protected void onInstall(ContributedLibrary selectedLibrary, ContributedLibrary
if (selectedLibrary.isReadOnly()) {
onRemovePressed(installedLibrary);
} else {
onInstallPressed(selectedLibrary, installedLibrary);
onInstallPressed(selectedLibrary);
}
}

Expand Down Expand Up @@ -219,12 +221,29 @@ protected void onUpdatePressed() {
installerThread.start();
}

public void onInstallPressed(final ContributedLibrary lib, final ContributedLibrary replaced) {
public void onInstallPressed(final ContributedLibrary lib) {
List<ContributedLibrary> deps = BaseNoGui.librariesIndexer.getIndex().resolveDependeciesOf(lib);
boolean depsInstalled = deps.stream().allMatch(l -> l.isInstalled() || l.getName().equals(lib.getName()));
Result installDeps;
if (!depsInstalled) {
MultiLibraryInstallDialog dialog;
dialog = new MultiLibraryInstallDialog(this, lib, deps);
dialog.setVisible(true);
installDeps = dialog.getInstallDepsResult();
if (installDeps == Result.CANCEL)
return;
} else {
installDeps = Result.NONE;
}
clearErrorMessage();
installerThread = new Thread(() -> {
try {
setProgressVisible(true, tr("Installing..."));
installer.install(lib, replaced, this::setProgress);
if (installDeps == Result.ALL) {
installer.install(deps, this::setProgress);
} else {
installer.install(lib, this::setProgress);
}
onIndexesUpdated(); // TODO: Do a better job in refreshing only the needed element
//getContribModel().updateLibrary(lib);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* This file is part of Arduino.
*
* Copyright 2017 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.format;
import static processing.app.I18n.tr;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;

import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.UnavailableContributedLibrary;
import processing.app.Base;
import processing.app.Theme;

public class MultiLibraryInstallDialog extends JDialog {

enum Result {
ALL, NONE, CANCEL
}

Result result = Result.CANCEL;

public MultiLibraryInstallDialog(Window parent, ContributedLibrary lib,
List<ContributedLibrary> dependencies) {
super(parent, format(tr("Dependencies for library {0}:{1}"), lib.getName(),
lib.getParsedVersion()),
ModalityType.APPLICATION_MODAL);
Container pane = getContentPane();
pane.setLayout(new BorderLayout());

pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST);
pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST);

{
JButton cancel = new JButton(tr("Cancel"));
cancel.addActionListener(ev -> {
result = Result.CANCEL;
setVisible(false);
});

JButton all = new JButton(tr("Install all"));
all.addActionListener(ev -> {
result = Result.ALL;
setVisible(false);
});

JButton none = new JButton(format(tr("Install '{0}' only"), lib.getName()));
none.addActionListener(ev -> {
result = Result.NONE;
setVisible(false);
});

Box buttonsBox = Box.createHorizontalBox();
buttonsBox.add(all);
buttonsBox.add(Box.createHorizontalStrut(5));
buttonsBox.add(none);
buttonsBox.add(Box.createHorizontalStrut(5));
buttonsBox.add(cancel);

JPanel buttonsPanel = new JPanel();
buttonsPanel.setBorder(new EmptyBorder(7, 10, 7, 10));
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
buttonsPanel.add(buttonsBox);

pane.add(buttonsPanel, BorderLayout.SOUTH);
}

{
String libName = format("<b>{0}:{1}</b>", lib.getName(),
lib.getParsedVersion());
String desc = format(tr("The library {0} needs some other library<br />dependencies currently not installed:"),
libName);
desc += "<br/><br/>";
for (ContributedLibrary l : dependencies) {
if (l.getName().equals(lib.getName()))
continue;
if (l.isInstalled())
continue;
if (l instanceof UnavailableContributedLibrary)
continue;
desc += format("- <b>{0}</b><br/>", l.getName());
}
desc += "<br/>";
desc += tr("Would you like to install also all the missing dependencies?");

JTextPane textArea = makeNewDescription();
textArea.setContentType("text/html");
textArea.setText(desc);

JPanel libsList = new JPanel();
libsList.setLayout(new BoxLayout(libsList, BoxLayout.Y_AXIS));
libsList.add(textArea);
libsList.setBorder(new EmptyBorder(7, 7, 7, 7));
pane.add(libsList, BorderLayout.NORTH);
}

pack();
setResizable(false);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

WindowEvent closing = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Base.registerWindowCloseKeys(getRootPane(), e -> dispatchEvent(closing));
}

// TODO Make this a method of Theme
private JTextPane makeNewDescription() {
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 s = html.getStyleSheet();
s.addRule("body { margin: 0; padding: 0;"
+ "font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"
+ "color: black;" + "font-size: " + 15 * Theme.getScale() / 100
+ "; }");
}
description.setOpaque(false);
description.setBorder(new EmptyBorder(4, 7, 7, 7));
description.setHighlighter(null);
description.setEditable(false);
add(description, 0);
return description;
}

public Result getInstallDepsResult() {
return result;
}
}
2 changes: 1 addition & 1 deletion app/src/processing/app/Base.java
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public Base(String[] args) throws Exception {
if (selected.isReadOnly()) {
libraryInstaller.remove(installed, progressListener);
} else {
libraryInstaller.install(selected, installed, progressListener);
libraryInstaller.install(selected, progressListener);
}
}

Expand Down
3 changes: 3 additions & 0 deletions arduino-core/src/cc/arduino/contributions/VersionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ public static Version valueOf(String ver) {
}
}

public static int compare(String a, String b) {
return valueOf(a).compareTo(valueOf(b));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@

package cc.arduino.contributions.libraries;

import cc.arduino.contributions.DownloadableContribution;
import processing.app.I18n;
import static processing.app.I18n.tr;

import java.util.Comparator;
import java.util.List;

import static processing.app.I18n.tr;
import cc.arduino.contributions.DownloadableContribution;
import cc.arduino.contributions.VersionHelper;
import processing.app.I18n;

public abstract class ContributedLibrary extends DownloadableContribution {

Expand All @@ -61,7 +62,7 @@ public abstract class ContributedLibrary extends DownloadableContribution {

public abstract List<String> getTypes();

public abstract List<ContributedLibraryReference> getRequires();
public abstract List<ContributedLibraryDependency> getRequires();

public static final Comparator<ContributedLibrary> CASE_INSENSITIVE_ORDER = (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName());

Expand Down Expand Up @@ -117,7 +118,7 @@ public String info() {
res += "\n";
res += " requires :\n";
if (getRequires() != null)
for (ContributedLibraryReference r : getRequires()) {
for (ContributedLibraryDependency r : getRequires()) {
res += " " + r;
}
res += "\n";
Expand All @@ -137,7 +138,7 @@ public boolean equals(Object obj) {
String thisVersion = getParsedVersion();
String otherVersion = other.getParsedVersion();

boolean versionEquals = (thisVersion != null && otherVersion != null
boolean versionEquals = (thisVersion != null
&& thisVersion.equals(otherVersion));

// Important: for legacy libs, versions are null. Two legacy libs must
Expand All @@ -147,9 +148,18 @@ public boolean equals(Object obj) {

String thisName = getName();
String otherName = other.getName();

boolean nameEquals = thisName == null || otherName == null || thisName.equals(otherName);
boolean nameEquals = thisName != null && thisName.equals(otherName);

return versionEquals && nameEquals;
}

public boolean isBefore(ContributedLibrary other) {
return VersionHelper.compare(getVersion(), other.getVersion()) < 0;
}

@Override
public int hashCode() {
String hashingData = "CONTRIBUTEDLIB" + getName() + getVersion();
return hashingData.hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,14 @@

package cc.arduino.contributions.libraries;

public abstract class ContributedLibraryReference {
public abstract class ContributedLibraryDependency {

public abstract String getName();

public abstract String getMaintainer();

public abstract String getVersion();
public abstract String getVersionRequired();

@Override
public String toString() {
return getName() + " " + getVersion() + " (" + getMaintainer() + ")";
return getName() + " " + getVersionRequired();
}
}
Loading