mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-30 19:52:13 +01:00
Merge pull request #3625 from ffissore/update-notifications
Update notifications
This commit is contained in:
commit
1461412049
45
app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java
Normal file
45
app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java
Normal file
@ -0,0 +1,45 @@
|
||||
package cc.arduino;
|
||||
|
||||
import processing.app.Base;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.net.URL;
|
||||
|
||||
public class UpdatableBoardsLibsFakeURLsHandler implements HyperlinkListener {
|
||||
|
||||
private static final String BOARDSMANAGER = "boardsmanager";
|
||||
private static final String LIBRARYMANAGER = "librarymanager";
|
||||
|
||||
private final Base base;
|
||||
|
||||
public UpdatableBoardsLibsFakeURLsHandler(Base base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent event) {
|
||||
if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
URL url = event.getURL();
|
||||
|
||||
if (BOARDSMANAGER.equals(url.getHost())) {
|
||||
try {
|
||||
base.openBoardsManager("", "DropdownUpdatableCoresItem");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (LIBRARYMANAGER.equals(url.getHost())) {
|
||||
base.openLibraryManager("DropdownUpdatableLibrariesItem");
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(url.getHost() + " is invalid");
|
||||
}
|
||||
|
||||
}
|
@ -92,10 +92,11 @@ public class BuiltInCoreIsNewerCheck implements Runnable {
|
||||
assert base.hasActiveEditor();
|
||||
int chosenOption = JOptionPane.showConfirmDialog(base.getActiveEditor(), I18n.format(tr("The IDE includes an updated {0} package, but you're using an older one.\nDo you want to upgrade {0}?"), installedBuiltIn.getName()), I18n.format(tr("A newer {0} package is available"), installedBuiltIn.getName()), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
|
||||
if (chosenOption == JOptionPane.YES_OPTION) {
|
||||
Action openBoardsManager = base.getOpenBoardsManager();
|
||||
Event event = new Event(base.getActiveEditor(), ActionEvent.ACTION_PERFORMED, installedBuiltIn.getName());
|
||||
event.getPayload().put("filterText", installedBuiltIn.getName());
|
||||
openBoardsManager.actionPerformed(event);
|
||||
try {
|
||||
base.openBoardsManager(installedBuiltIn.getName(), "");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
109
app/src/cc/arduino/contributions/ContributionsSelfCheck.java
Normal file
109
app/src/cc/arduino/contributions/ContributionsSelfCheck.java
Normal file
@ -0,0 +1,109 @@
|
||||
package cc.arduino.contributions;
|
||||
|
||||
import cc.arduino.contributions.libraries.LibrariesIndexer;
|
||||
import cc.arduino.contributions.libraries.LibraryInstaller;
|
||||
import cc.arduino.contributions.libraries.filters.UpdatableLibraryPredicate;
|
||||
import cc.arduino.contributions.packages.ContributionInstaller;
|
||||
import cc.arduino.contributions.packages.ContributionsIndexer;
|
||||
import cc.arduino.contributions.packages.filters.UpdatablePlatformPredicate;
|
||||
import cc.arduino.view.NotificationPopup;
|
||||
import processing.app.Base;
|
||||
import processing.app.I18n;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
public class ContributionsSelfCheck extends TimerTask {
|
||||
|
||||
private final Base base;
|
||||
private final HyperlinkListener hyperlinkListener;
|
||||
private final ContributionsIndexer contributionsIndexer;
|
||||
private final ContributionInstaller contributionInstaller;
|
||||
private final LibrariesIndexer librariesIndexer;
|
||||
private final LibraryInstaller libraryInstaller;
|
||||
private final ProgressListener progressListener;
|
||||
|
||||
private volatile boolean cancelled;
|
||||
private volatile NotificationPopup notificationPopup;
|
||||
|
||||
public ContributionsSelfCheck(Base base, HyperlinkListener hyperlinkListener, ContributionsIndexer contributionsIndexer, ContributionInstaller contributionInstaller, LibrariesIndexer librariesIndexer, LibraryInstaller libraryInstaller) {
|
||||
this.base = base;
|
||||
this.hyperlinkListener = hyperlinkListener;
|
||||
this.contributionsIndexer = contributionsIndexer;
|
||||
this.contributionInstaller = contributionInstaller;
|
||||
this.librariesIndexer = librariesIndexer;
|
||||
this.libraryInstaller = libraryInstaller;
|
||||
this.progressListener = new NoopProgressListener();
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
updateContributionIndex();
|
||||
updateLibrariesIndex();
|
||||
|
||||
long updatablePlatforms = contributionsIndexer.getPackages().stream()
|
||||
.flatMap(pack -> pack.getPlatforms().stream())
|
||||
.filter(new UpdatablePlatformPredicate(contributionsIndexer)).count();
|
||||
|
||||
long updatableLibraries = librariesIndexer.getInstalledLibraries().stream()
|
||||
.filter(new UpdatableLibraryPredicate(librariesIndexer))
|
||||
.count();
|
||||
|
||||
if (updatableLibraries <= 0 && updatablePlatforms <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String text;
|
||||
if (updatableLibraries > 0 && updatablePlatforms <= 0) {
|
||||
text = I18n.format(tr("<br/>Update available for some of your {0}libraries{1}"), "<a href=\"http://librarymanager\">", "</a>");
|
||||
} else if (updatableLibraries <= 0 && updatablePlatforms > 0) {
|
||||
text = I18n.format(tr("<br/>Update available for some of your {0}boards{1}"), "<a href=\"http://boardsmanager\">", "</a>");
|
||||
} else {
|
||||
text = I18n.format(tr("<br/>Update available for some of your {0}boards{1} and {2}libraries{3}"), "<a href=\"http://boardsmanager\">", "</a>", "<a href=\"http://librarymanager\">", "</a>");
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
notificationPopup = new NotificationPopup(base.getActiveEditor(), hyperlinkListener, text);
|
||||
notificationPopup.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
cancelled = true;
|
||||
if (notificationPopup != null) {
|
||||
notificationPopup.close();
|
||||
}
|
||||
return super.cancel();
|
||||
}
|
||||
|
||||
private void updateLibrariesIndex() {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
libraryInstaller.updateIndex(progressListener);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContributionIndex() {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
contributionInstaller.updateIndex(progressListener);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
@ -36,7 +36,6 @@ import cc.arduino.contributions.libraries.LibraryInstaller;
|
||||
import cc.arduino.contributions.libraries.LibraryTypeComparator;
|
||||
import cc.arduino.contributions.ui.*;
|
||||
import cc.arduino.utils.Progress;
|
||||
import processing.app.Platform;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@ -53,8 +52,8 @@ import static processing.app.I18n.tr;
|
||||
public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
|
||||
private final JComboBox typeChooser;
|
||||
private final Platform platform;
|
||||
private LibrariesIndexer indexer;
|
||||
private final LibrariesIndexer indexer;
|
||||
private final LibraryInstaller installer;
|
||||
private Predicate<ContributedLibrary> typeFilter;
|
||||
|
||||
@Override
|
||||
@ -90,9 +89,10 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
};
|
||||
}
|
||||
|
||||
public LibraryManagerUI(Frame parent, Platform platform) {
|
||||
public LibraryManagerUI(Frame parent, LibrariesIndexer indexer, LibraryInstaller installer) {
|
||||
super(parent, "Library Manager", Dialog.ModalityType.APPLICATION_MODAL, tr("Unable to reach Arduino.cc due to possible network issues."));
|
||||
this.platform = platform;
|
||||
this.indexer = indexer;
|
||||
this.installer = installer;
|
||||
|
||||
filtersContainer.add(new JLabel(tr("Topic")), 1);
|
||||
filtersContainer.remove(2);
|
||||
@ -125,14 +125,12 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
@Override
|
||||
public void updateIndexFilter(String[] filters, Predicate<ContributedLibrary>... additionalFilters) {
|
||||
if (additionalFilters.length == 1) {
|
||||
additionalFilters = new Predicate[] { additionalFilters[0], typeFilter };
|
||||
additionalFilters = new Predicate[]{additionalFilters[0], typeFilter};
|
||||
}
|
||||
super.updateIndexFilter(filters, additionalFilters);
|
||||
}
|
||||
|
||||
public void setIndexer(LibrariesIndexer indexer) {
|
||||
this.indexer = indexer;
|
||||
|
||||
public void updateUI() {
|
||||
DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
|
||||
DropdownItem<DownloadableContribution> previouslySelectedType = (DropdownItem<DownloadableContribution>) typeChooser.getSelectedItem();
|
||||
|
||||
@ -181,29 +179,16 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
}
|
||||
|
||||
filterField.setEnabled(contribModel.getRowCount() > 0);
|
||||
|
||||
// Create LibrariesInstaller tied with the provided index
|
||||
installer = new LibraryInstaller(indexer, platform) {
|
||||
@Override
|
||||
public void onProgress(Progress progress) {
|
||||
setProgress(progress);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public LibrariesIndexer getIndexer() {
|
||||
return indexer;
|
||||
public void selectDropdownItemByClassName(String dropdownItem) {
|
||||
selectDropdownItemByClassName(typeChooser, dropdownItem);
|
||||
}
|
||||
|
||||
public void setProgress(Progress progress) {
|
||||
progressBar.setValue(progress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Installer methods follows
|
||||
*/
|
||||
|
||||
private LibraryInstaller installer;
|
||||
private Thread installerThread = null;
|
||||
|
||||
@Override
|
||||
@ -220,7 +205,7 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
installerThread = new Thread(() -> {
|
||||
try {
|
||||
setProgressVisible(true, "");
|
||||
installer.updateIndex();
|
||||
installer.updateIndex(this::setProgress);
|
||||
onIndexesUpdated();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -237,7 +222,7 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
installerThread = new Thread(() -> {
|
||||
try {
|
||||
setProgressVisible(true, tr("Installing..."));
|
||||
installer.install(lib, replaced);
|
||||
installer.install(lib, replaced, this::setProgress);
|
||||
onIndexesUpdated(); // TODO: Do a better job in refreshing only the needed element
|
||||
//getContribModel().updateLibrary(lib);
|
||||
} catch (Exception e) {
|
||||
@ -264,7 +249,7 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
installerThread = new Thread(() -> {
|
||||
try {
|
||||
setProgressVisible(true, tr("Removing..."));
|
||||
installer.remove(lib);
|
||||
installer.remove(lib, this::setProgress);
|
||||
onIndexesUpdated(); // TODO: Do a better job in refreshing only the needed element
|
||||
//getContribModel().updateLibrary(lib);
|
||||
} catch (Exception e) {
|
||||
|
@ -30,14 +30,12 @@
|
||||
package cc.arduino.contributions.packages.ui;
|
||||
|
||||
import cc.arduino.contributions.DownloadableContribution;
|
||||
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
|
||||
import cc.arduino.contributions.packages.ContributedPlatform;
|
||||
import cc.arduino.contributions.packages.ContributionInstaller;
|
||||
import cc.arduino.contributions.packages.ContributionsIndexer;
|
||||
import cc.arduino.contributions.ui.*;
|
||||
import cc.arduino.utils.Progress;
|
||||
import processing.app.I18n;
|
||||
import processing.app.Platform;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@ -50,7 +48,8 @@ import static processing.app.I18n.tr;
|
||||
@SuppressWarnings("serial")
|
||||
public class ContributionManagerUI extends InstallerJDialog {
|
||||
|
||||
private final Platform platform;
|
||||
private final ContributionsIndexer indexer;
|
||||
private final ContributionInstaller installer;
|
||||
|
||||
@Override
|
||||
protected FilteredAbstractTableModel createContribModel() {
|
||||
@ -85,12 +84,13 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
};
|
||||
}
|
||||
|
||||
public ContributionManagerUI(Frame parent, Platform platform) {
|
||||
public ContributionManagerUI(Frame parent, ContributionsIndexer indexer, ContributionInstaller installer) {
|
||||
super(parent, tr("Boards Manager"), Dialog.ModalityType.APPLICATION_MODAL, tr("Unable to reach Arduino.cc due to possible network issues."));
|
||||
this.platform = platform;
|
||||
this.indexer = indexer;
|
||||
this.installer = installer;
|
||||
}
|
||||
|
||||
public void setIndexer(ContributionsIndexer indexer) {
|
||||
public void updateUI() {
|
||||
DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
|
||||
|
||||
categoryChooser.removeActionListener(categoryChooserActionListener);
|
||||
@ -116,14 +116,6 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
} else {
|
||||
categoryChooser.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
// Create ConstributionInstaller tied with the provided index
|
||||
installer = new ContributionInstaller(indexer, platform, new GPGDetachedSignatureVerifier()) {
|
||||
@Override
|
||||
public void onProgress(Progress progress) {
|
||||
setProgress(progress);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setProgress(Progress progress) {
|
||||
@ -134,7 +126,6 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
* Installer methods follows
|
||||
*/
|
||||
|
||||
private ContributionInstaller installer;
|
||||
private Thread installerThread = null;
|
||||
|
||||
@Override
|
||||
@ -151,7 +142,7 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
installerThread = new Thread(() -> {
|
||||
try {
|
||||
setProgressVisible(true, "");
|
||||
List<String> downloadedPackageIndexFiles = installer.updateIndex();
|
||||
List<String> downloadedPackageIndexFiles = installer.updateIndex(this::setProgress);
|
||||
installer.deleteUnknownFiles(downloadedPackageIndexFiles);
|
||||
onIndexesUpdated();
|
||||
} catch (Exception e) {
|
||||
@ -170,7 +161,7 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
List<String> errors = new LinkedList<>();
|
||||
try {
|
||||
setProgressVisible(true, tr("Installing..."));
|
||||
errors.addAll(installer.install(platformToInstall));
|
||||
errors.addAll(installer.install(platformToInstall, this::setProgress));
|
||||
if (platformToRemove != null && !platformToRemove.isReadOnly()) {
|
||||
errors.addAll(installer.remove(platformToRemove));
|
||||
}
|
||||
|
@ -276,6 +276,19 @@ public abstract class InstallerJDialog<T> extends JDialog {
|
||||
filterField.setText(filterText);
|
||||
}
|
||||
|
||||
public void selectDropdownItemByClassName(String dropdownItem) {
|
||||
selectDropdownItemByClassName(categoryChooser, dropdownItem);
|
||||
}
|
||||
|
||||
public void selectDropdownItemByClassName(JComboBox combo, String dropdownItem) {
|
||||
for (int i = 0; i < combo.getItemCount(); i++) {
|
||||
if (dropdownItem.equals(combo.getItemAt(i).getClass().getSimpleName())) {
|
||||
combo.setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action performed when the Cancel button is pressed.
|
||||
*/
|
||||
|
89
app/src/cc/arduino/view/NotificationPopup.form
Normal file
89
app/src/cc/arduino/view/NotificationPopup.form
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="alwaysOnTop" type="boolean" value="true"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="focusableWindowState" type="boolean" value="false"/>
|
||||
<Property name="undecorated" type="boolean" value="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[350, 70]"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
<Property name="size" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[350, 70]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,0,0,0,2,14"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="icon">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "arduino_small.png").toFile().getAbsolutePath())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
||||
<AbsoluteConstraints x="10" y="10" width="50" height="50"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JEditorPane" name="text">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
||||
<LineBorder roundedCorners="true" thickness="0"/>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="contentType" type="java.lang.String" value="text/html" noResource="true"/>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
||||
<AbsoluteConstraints x="70" y="10" width="270" height="50"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="closeButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "theme", "close.png").toFile().getAbsolutePath())" type="code"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="borderPainted" type="boolean" value="false"/>
|
||||
<Property name="hideActionText" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="closeButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
||||
<AbsoluteConstraints x="328" y="0" width="22" height="22"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
181
app/src/cc/arduino/view/NotificationPopup.java
Normal file
181
app/src/cc/arduino/view/NotificationPopup.java
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*/
|
||||
|
||||
package cc.arduino.view;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.BaseNoGui;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class NotificationPopup extends JDialog {
|
||||
|
||||
private final ComponentAdapter parentMovedListener;
|
||||
|
||||
public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, String message) {
|
||||
super(parent, false);
|
||||
initComponents();
|
||||
|
||||
updateLocation(parent);
|
||||
parentMovedListener = new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
updateLocation(parent);
|
||||
}
|
||||
};
|
||||
parent.addComponentListener(parentMovedListener);
|
||||
|
||||
text.setText("<html><body style=\"font-family:sans-serif;font-size:12pt\">" + message + "</body></html>");
|
||||
|
||||
text.addHyperlinkListener(hyperlinkListener);
|
||||
text.addHyperlinkListener(e -> {
|
||||
if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
|
||||
return;
|
||||
}
|
||||
close();
|
||||
});
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
parent.removeComponentListener(parentMovedListener);
|
||||
}
|
||||
});
|
||||
|
||||
Base.registerWindowCloseKeys(getRootPane(), e -> close());
|
||||
|
||||
MouseAdapter closeOnClick = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
close();
|
||||
}
|
||||
};
|
||||
addMouseListener(closeOnClick);
|
||||
text.addMouseListener(closeOnClick);
|
||||
icon.addMouseListener(closeOnClick);
|
||||
}
|
||||
|
||||
private void updateLocation(Frame parent) {
|
||||
Point parentLocation = parent.getLocation();
|
||||
|
||||
int parentX = Double.valueOf(parentLocation.getX()).intValue();
|
||||
int parentY = Double.valueOf(parentLocation.getY()).intValue();
|
||||
setLocation(parentX, parentY + parent.getHeight() - getHeight());
|
||||
}
|
||||
|
||||
public void close() {
|
||||
dispatchEvent(new WindowEvent(NotificationPopup.this, WindowEvent.WINDOW_CLOSING));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
icon = new javax.swing.JLabel();
|
||||
text = new javax.swing.JEditorPane();
|
||||
closeButton = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setAlwaysOnTop(true);
|
||||
setFocusable(false);
|
||||
setFocusableWindowState(false);
|
||||
setUndecorated(true);
|
||||
setPreferredSize(new java.awt.Dimension(350, 70));
|
||||
setResizable(false);
|
||||
setSize(new java.awt.Dimension(350, 70));
|
||||
getContentPane().setLayout(null);
|
||||
|
||||
icon.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "arduino_small.png").toFile().getAbsolutePath()));
|
||||
getContentPane().add(icon);
|
||||
icon.setBounds(10, 10, 50, 50);
|
||||
|
||||
text.setEditable(false);
|
||||
text.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 0, true));
|
||||
text.setContentType("text/html"); // NOI18N
|
||||
text.setOpaque(false);
|
||||
getContentPane().add(text);
|
||||
text.setBounds(70, 10, 270, 50);
|
||||
|
||||
closeButton.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "theme", "close.png").toFile().getAbsolutePath()));
|
||||
closeButton.setBorder(null);
|
||||
closeButton.setBorderPainted(false);
|
||||
closeButton.setHideActionText(true);
|
||||
closeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
closeButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
getContentPane().add(closeButton);
|
||||
closeButton.setBounds(328, 0, 22, 22);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
|
||||
close();
|
||||
}//GEN-LAST:event_closeButtonActionPerformed
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
|
||||
/* Create and display the dialog */
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
NotificationPopup dialog = new NotificationPopup(new JFrame(), System.out::println, "<a href='arduinoide://boardsmanager'>test</a> test test test test test test test test\n" +
|
||||
" test test test test test test test test test test test");
|
||||
dialog.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JLabel icon;
|
||||
private javax.swing.JEditorPane text;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
@ -22,10 +22,9 @@
|
||||
|
||||
package processing.app;
|
||||
|
||||
import cc.arduino.contributions.BuiltInCoreIsNewerCheck;
|
||||
import cc.arduino.contributions.DownloadableContributionVersionComparator;
|
||||
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
|
||||
import cc.arduino.contributions.VersionHelper;
|
||||
import cc.arduino.Constants;
|
||||
import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
|
||||
import cc.arduino.contributions.*;
|
||||
import cc.arduino.contributions.libraries.*;
|
||||
import cc.arduino.contributions.libraries.ui.LibraryManagerUI;
|
||||
import cc.arduino.contributions.packages.ContributedPlatform;
|
||||
@ -34,7 +33,6 @@ import cc.arduino.contributions.packages.ContributionsIndexer;
|
||||
import cc.arduino.contributions.packages.ui.ContributionManagerUI;
|
||||
import cc.arduino.files.DeleteFilesOnShutdown;
|
||||
import cc.arduino.packages.DiscoveryManager;
|
||||
import cc.arduino.utils.Progress;
|
||||
import cc.arduino.view.Event;
|
||||
import cc.arduino.view.JMenuUtils;
|
||||
import cc.arduino.view.SplashScreenHelper;
|
||||
@ -62,6 +60,7 @@ import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
@ -93,6 +92,9 @@ public class Base {
|
||||
|
||||
public static SplashScreenHelper splashScreenHelper = new SplashScreenHelper(SplashScreen.getSplashScreen());
|
||||
public static Map<String, Object> FIND_DIALOG_STATE = new HashMap<String, Object>();
|
||||
private final ContributionInstaller contributionInstaller;
|
||||
private final LibraryInstaller libraryInstaller;
|
||||
private ContributionsSelfCheck contributionsSelfCheck;
|
||||
|
||||
// set to true after the first time the menu is built.
|
||||
// so that the errors while building don't show up again.
|
||||
@ -117,7 +119,6 @@ public class Base {
|
||||
// are the same for all windows (since the board and serial port that are
|
||||
// actually used are determined by the preferences, which are shared)
|
||||
private List<JMenu> boardsCustomMenus;
|
||||
private volatile Action openBoardsManager;
|
||||
private List<JMenuItem> programmerMenus;
|
||||
|
||||
private final PdeKeywords pdeKeywords;
|
||||
@ -303,6 +304,9 @@ public class Base {
|
||||
this.pdeKeywords = new PdeKeywords();
|
||||
this.pdeKeywords.reload();
|
||||
|
||||
contributionInstaller = new ContributionInstaller(BaseNoGui.indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
|
||||
libraryInstaller = new LibraryInstaller(BaseNoGui.librariesIndexer, BaseNoGui.getPlatform());
|
||||
|
||||
parser.parseArgumentsPhase2();
|
||||
|
||||
for (String path : parser.getFilenames()) {
|
||||
@ -341,19 +345,10 @@ public class Base {
|
||||
|
||||
if (parser.isInstallBoard()) {
|
||||
ContributionsIndexer indexer = new ContributionsIndexer(BaseNoGui.getSettingsFolder(), BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
|
||||
ContributionInstaller installer = new ContributionInstaller(indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()) {
|
||||
private String lastStatus = "";
|
||||
ProgressListener progressListener = new ConsoleProgressListener();
|
||||
|
||||
@Override
|
||||
protected void onProgress(Progress progress) {
|
||||
if (!lastStatus.equals(progress.getStatus())) {
|
||||
System.out.println(progress.getStatus());
|
||||
}
|
||||
lastStatus = progress.getStatus();
|
||||
}
|
||||
};
|
||||
List<String> downloadedPackageIndexFiles = installer.updateIndex();
|
||||
installer.deleteUnknownFiles(downloadedPackageIndexFiles);
|
||||
List<String> downloadedPackageIndexFiles = contributionInstaller.updateIndex(progressListener);
|
||||
contributionInstaller.deleteUnknownFiles(downloadedPackageIndexFiles);
|
||||
indexer.parseIndex();
|
||||
indexer.syncWithFilesystem(BaseNoGui.getHardwareFolder());
|
||||
|
||||
@ -377,33 +372,23 @@ public class Base {
|
||||
ContributedPlatform installed = indexer.getInstalled(boardToInstallParts[0], boardToInstallParts[1]);
|
||||
|
||||
if (!selected.isReadOnly()) {
|
||||
installer.install(selected);
|
||||
contributionInstaller.install(selected, progressListener);
|
||||
}
|
||||
|
||||
if (installed != null && !installed.isReadOnly()) {
|
||||
installer.remove(installed);
|
||||
contributionInstaller.remove(installed);
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
|
||||
} else if (parser.isInstallLibrary()) {
|
||||
LibrariesIndexer indexer = new LibrariesIndexer(BaseNoGui.getSettingsFolder(), new ContributionsIndexer(BaseNoGui.getSettingsFolder(), BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()));
|
||||
LibraryInstaller installer = new LibraryInstaller(indexer, BaseNoGui.getPlatform()) {
|
||||
private String lastStatus = "";
|
||||
|
||||
@Override
|
||||
protected void onProgress(Progress progress) {
|
||||
if (!lastStatus.equals(progress.getStatus())) {
|
||||
System.out.println(progress.getStatus());
|
||||
}
|
||||
lastStatus = progress.getStatus();
|
||||
}
|
||||
};
|
||||
ProgressListener progressListener = new ConsoleProgressListener();
|
||||
indexer.parseIndex();
|
||||
BaseNoGui.onBoardOrPortChange();
|
||||
indexer.setSketchbookLibrariesFolder(BaseNoGui.getSketchbookLibrariesFolder());
|
||||
indexer.setLibrariesFolders(BaseNoGui.getLibrariesPath());
|
||||
installer.updateIndex();
|
||||
libraryInstaller.updateIndex(progressListener);
|
||||
|
||||
for (String library : parser.getLibraryToInstall().split(",")) {
|
||||
String[] libraryToInstallParts = library.split(":");
|
||||
@ -425,9 +410,9 @@ public class Base {
|
||||
|
||||
ContributedLibrary installed = indexer.getIndex().getInstalled(libraryToInstallParts[0]);
|
||||
if (selected.isReadOnly()) {
|
||||
installer.remove(installed);
|
||||
libraryInstaller.remove(installed, progressListener);
|
||||
} else {
|
||||
installer.install(selected, installed);
|
||||
libraryInstaller.install(selected, installed, progressListener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -481,6 +466,9 @@ public class Base {
|
||||
|
||||
new Thread(new BuiltInCoreIsNewerCheck(this)).start();
|
||||
|
||||
contributionsSelfCheck = new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), BaseNoGui.indexer, contributionInstaller, BaseNoGui.librariesIndexer, libraryInstaller);
|
||||
new Timer(false).schedule(contributionsSelfCheck, Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD);
|
||||
|
||||
} else if (parser.isNoOpMode()) {
|
||||
// Do nothing (intended for only changing preferences)
|
||||
System.exit(0);
|
||||
@ -695,13 +683,6 @@ public class Base {
|
||||
"jul", "aug", "sep", "oct", "nov", "dec"
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle creating a sketch folder, return its base .pde file
|
||||
* or null if the operation was canceled.
|
||||
*
|
||||
* @param shift whether shift is pressed, which will invert prompt setting
|
||||
* @param noPrompt disable prompt, no matter the setting
|
||||
*/
|
||||
protected File createNewUntitled() throws IOException {
|
||||
File newbieDir = null;
|
||||
String newbieName = null;
|
||||
@ -804,20 +785,13 @@ public class Base {
|
||||
activeEditor.handleOpenInternal(file);
|
||||
activeEditor.untitled = true;
|
||||
}
|
||||
// return true;
|
||||
|
||||
} catch (IOException e) {
|
||||
activeEditor.statusError(e);
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a sketch, replacing the sketch in the current window.
|
||||
*
|
||||
* @param path Location of the primary pde file for the sketch.
|
||||
*/
|
||||
public void handleOpenReplace(File file) {
|
||||
if (!activeEditor.checkModified()) {
|
||||
return; // sketch was modified, and user canceled
|
||||
@ -1165,11 +1139,7 @@ public class Base {
|
||||
importMenu.removeAll();
|
||||
|
||||
JMenuItem menu = new JMenuItem(tr("Manage Libraries..."));
|
||||
menu.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
openManageLibrariesDialog();
|
||||
}
|
||||
});
|
||||
menu.addActionListener(e -> openLibraryManager(""));
|
||||
importMenu.add(menu);
|
||||
importMenu.addSeparator();
|
||||
|
||||
@ -1257,20 +1227,26 @@ public class Base {
|
||||
}
|
||||
}
|
||||
|
||||
private void openManageLibrariesDialog() {
|
||||
public void openLibraryManager(String dropdownItem) {
|
||||
if (contributionsSelfCheck != null) {
|
||||
contributionsSelfCheck.cancel();
|
||||
}
|
||||
@SuppressWarnings("serial")
|
||||
LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.getPlatform()) {
|
||||
LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.librariesIndexer, libraryInstaller) {
|
||||
@Override
|
||||
protected void onIndexesUpdated() throws Exception {
|
||||
BaseNoGui.initPackages();
|
||||
rebuildBoardsMenu();
|
||||
rebuildProgrammerMenu();
|
||||
onBoardOrPortChange();
|
||||
setIndexer(BaseNoGui.librariesIndexer);
|
||||
updateUI();
|
||||
if (StringUtils.isNotEmpty(dropdownItem)) {
|
||||
selectDropdownItemByClassName(dropdownItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
managerUI.setLocationRelativeTo(activeEditor);
|
||||
managerUI.setIndexer(BaseNoGui.librariesIndexer);
|
||||
managerUI.updateUI();
|
||||
managerUI.setVisible(true);
|
||||
// Manager dialog is modal, waits here until closed
|
||||
|
||||
@ -1280,24 +1256,28 @@ public class Base {
|
||||
rebuildExamplesMenu(Editor.examplesMenu);
|
||||
}
|
||||
|
||||
private void openInstallBoardDialog(final String filterText) throws Exception {
|
||||
// Create dialog for contribution manager
|
||||
public void openBoardsManager(final String filterText, String dropdownItem) throws Exception {
|
||||
if (contributionsSelfCheck != null) {
|
||||
contributionsSelfCheck.cancel();
|
||||
}
|
||||
@SuppressWarnings("serial")
|
||||
ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.getPlatform()) {
|
||||
ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.indexer, contributionInstaller) {
|
||||
@Override
|
||||
protected void onIndexesUpdated() throws Exception {
|
||||
BaseNoGui.initPackages();
|
||||
rebuildBoardsMenu();
|
||||
rebuildProgrammerMenu();
|
||||
setIndexer(BaseNoGui.indexer);
|
||||
updateUI();
|
||||
if (StringUtils.isNotEmpty(dropdownItem)) {
|
||||
selectDropdownItemByClassName(dropdownItem);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(filterText)) {
|
||||
setFilterText(filterText);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
managerUI.setLocationRelativeTo(activeEditor);
|
||||
managerUI.setIndexer(BaseNoGui.indexer);
|
||||
managerUI.updateUI();
|
||||
managerUI.setVisible(true);
|
||||
// Installer dialog is modal, waits here until closed
|
||||
|
||||
@ -1316,21 +1296,22 @@ public class Base {
|
||||
boardMenu.putClientProperty("removeOnWindowDeactivation", true);
|
||||
MenuScroller.setScrollerFor(boardMenu);
|
||||
|
||||
openBoardsManager = new AbstractAction(tr("Boards Manager...")) {
|
||||
boardMenu.add(new JMenuItem(new AbstractAction(tr("Boards Manager...")) {
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
String filterText = "";
|
||||
if (actionevent instanceof cc.arduino.view.Event) {
|
||||
String dropdownItem = "";
|
||||
if (actionevent instanceof Event) {
|
||||
filterText = ((Event) actionevent).getPayload().get("filterText").toString();
|
||||
dropdownItem = ((Event) actionevent).getPayload().get("dropdownItem").toString();
|
||||
}
|
||||
try {
|
||||
openInstallBoardDialog(filterText);
|
||||
openBoardsManager(filterText, dropdownItem);
|
||||
} catch (Exception e) {
|
||||
//TODO show error
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
boardMenu.add(new JMenuItem(openBoardsManager));
|
||||
}));
|
||||
boardsCustomMenus.add(boardMenu);
|
||||
|
||||
// If there are no platforms installed we are done
|
||||
@ -2363,11 +2344,7 @@ public class Base {
|
||||
}
|
||||
|
||||
public List<Editor> getEditors() {
|
||||
return new LinkedList<Editor>(editors);
|
||||
}
|
||||
|
||||
public Action getOpenBoardsManager() {
|
||||
return openBoardsManager;
|
||||
return new LinkedList<>(editors);
|
||||
}
|
||||
|
||||
public PdeKeywords getPdeKeywords() {
|
||||
@ -2377,4 +2354,5 @@ public class Base {
|
||||
public List<JMenuItem> getRecentSketchesMenuItems() {
|
||||
return recentSketchesMenuItems;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class GzippedJsonDownloaderTest {
|
||||
|
||||
@Test
|
||||
public void testJsonDownload() throws Exception {
|
||||
new GZippedJsonDownloader(downloader, new URL("http://downloads.arduino.cc/libraries/library_index.json"), new URL("http://downloads.arduino.cc/libraries/library_index.json.gz")).download(tempFile, new MultiStepProgress(1), "");
|
||||
new GZippedJsonDownloader(downloader, new URL("http://downloads.arduino.cc/libraries/library_index.json"), new URL("http://downloads.arduino.cc/libraries/library_index.json.gz")).download(tempFile, new MultiStepProgress(1), "", new NoopProgressListener());
|
||||
|
||||
InputStream indexIn = new FileInputStream(tempFile);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
@ -38,7 +38,7 @@ public class JsonDownloaderTest {
|
||||
|
||||
@Test
|
||||
public void testJsonDownload() throws Exception {
|
||||
new JsonDownloader(downloader, new URL("http://downloads.arduino.cc/libraries/library_index.json")).download(tempFile, new MultiStepProgress(1), "");
|
||||
new JsonDownloader(downloader, new URL("http://downloads.arduino.cc/libraries/library_index.json")).download(tempFile, new MultiStepProgress(1), "", new NoopProgressListener());
|
||||
|
||||
InputStream indexIn = new FileInputStream(tempFile);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
@ -44,6 +44,12 @@ public class Constants {
|
||||
|
||||
public static final String LIBRARY_DEVELOPMENT_FLAG_FILE = ".development";
|
||||
|
||||
public static final long BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD = 60000;
|
||||
public static final int NOTIFICATION_POPUP_AUTOCLOSE_DELAY = 10000;
|
||||
|
||||
public static final String LIBRARY_INDEX_URL;
|
||||
public static final String LIBRARY_INDEX_URL_GZ;
|
||||
|
||||
static {
|
||||
String extenalPackageIndexUrl = System.getProperty("PACKAGE_INDEX_URL");
|
||||
if (extenalPackageIndexUrl != null && !"".equals(extenalPackageIndexUrl)) {
|
||||
@ -51,7 +57,14 @@ public class Constants {
|
||||
} else {
|
||||
PACKAGE_INDEX_URL = "http://downloads.arduino.cc/packages/package_index.json";
|
||||
}
|
||||
|
||||
String externalLibraryIndexUrl = System.getProperty("LIBRARY_INDEX_URL");
|
||||
if (externalLibraryIndexUrl != null && !"".equals(externalLibraryIndexUrl)) {
|
||||
LIBRARY_INDEX_URL = externalLibraryIndexUrl;
|
||||
} else {
|
||||
LIBRARY_INDEX_URL = "http://downloads.arduino.cc/libraries/library_index.json";
|
||||
}
|
||||
LIBRARY_INDEX_URL_GZ = "http://downloads.arduino.cc/libraries/library_index.json.gz";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package cc.arduino.contributions;
|
||||
|
||||
import cc.arduino.utils.Progress;
|
||||
|
||||
public class ConsoleProgressListener implements ProgressListener {
|
||||
private String lastStatus = "";
|
||||
|
||||
@Override
|
||||
public void onProgress(Progress progress) {
|
||||
if (!lastStatus.equals(progress.getStatus())) {
|
||||
System.out.println(progress.getStatus());
|
||||
}
|
||||
lastStatus = progress.getStatus();
|
||||
}
|
||||
}
|
@ -51,7 +51,7 @@ public class DownloadableContributionsDownloader {
|
||||
stagingFolder = _stagingFolder;
|
||||
}
|
||||
|
||||
public File download(DownloadableContribution contribution, Progress progress, final String statusText) throws Exception {
|
||||
public File download(DownloadableContribution contribution, Progress progress, final String statusText, ProgressListener progressListener) throws Exception {
|
||||
URL url = new URL(contribution.getUrl());
|
||||
Path outputFile = Paths.get(stagingFolder.getAbsolutePath(), contribution.getArchiveFileName());
|
||||
|
||||
@ -64,12 +64,12 @@ public class DownloadableContributionsDownloader {
|
||||
|
||||
// Need to download or resume downloading?
|
||||
if (!Files.isRegularFile(outputFile, LinkOption.NOFOLLOW_LINKS) || (Files.size(outputFile) < contribution.getSize())) {
|
||||
download(url, outputFile.toFile(), progress, statusText);
|
||||
download(url, outputFile.toFile(), progress, statusText, progressListener);
|
||||
}
|
||||
|
||||
// Test checksum
|
||||
progress.setStatus(tr("Verifying archive integrity..."));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
String checksum = contribution.getChecksum();
|
||||
if (hasChecksum(contribution)) {
|
||||
String algo = checksum.split(":")[0];
|
||||
@ -94,7 +94,7 @@ public class DownloadableContributionsDownloader {
|
||||
return algo != null && !algo.isEmpty();
|
||||
}
|
||||
|
||||
public void download(URL url, File tmpFile, Progress progress, String statusText) throws Exception {
|
||||
public void download(URL url, File tmpFile, Progress progress, String statusText, ProgressListener progressListener) throws Exception {
|
||||
FileDownloader downloader = new FileDownloader(url, tmpFile);
|
||||
downloader.addObserver((o, arg) -> {
|
||||
FileDownloader me = (FileDownloader) o;
|
||||
@ -106,7 +106,7 @@ public class DownloadableContributionsDownloader {
|
||||
}
|
||||
progress.setStatus(statusText + " " + msg);
|
||||
progress.setProgress(me.getProgress());
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
});
|
||||
downloader.download();
|
||||
if (!downloader.isCompleted()) {
|
||||
@ -114,8 +114,4 @@ public class DownloadableContributionsDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
protected void onProgress(Progress progress) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,14 +49,14 @@ public class GZippedJsonDownloader {
|
||||
this.gzippedUrl = gzippedUrl;
|
||||
}
|
||||
|
||||
public void download(File tmpFile, Progress progress, String statusText) throws Exception {
|
||||
public void download(File tmpFile, Progress progress, String statusText, ProgressListener progressListener) throws Exception {
|
||||
try {
|
||||
new JsonDownloader(downloader, gzippedUrl).download(tmpFile, progress, statusText);
|
||||
new JsonDownloader(downloader, gzippedUrl).download(tmpFile, progress, statusText, progressListener);
|
||||
File gzipTmpFile = new File(tmpFile.getParentFile(), GzipUtils.getCompressedFilename(tmpFile.getName()));
|
||||
tmpFile.renameTo(gzipTmpFile);
|
||||
decompress(gzipTmpFile, tmpFile);
|
||||
} catch (Exception e) {
|
||||
new JsonDownloader(downloader, url).download(tmpFile, progress, statusText);
|
||||
new JsonDownloader(downloader, url).download(tmpFile, progress, statusText, progressListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,9 +44,9 @@ public class JsonDownloader {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void download(File tmpFile, Progress progress, String statusText) throws Exception {
|
||||
public void download(File tmpFile, Progress progress, String statusText, ProgressListener progressListener) throws Exception {
|
||||
try {
|
||||
downloader.download(url, tmpFile, progress, statusText);
|
||||
downloader.download(url, tmpFile, progress, statusText, progressListener);
|
||||
} catch (InterruptedException e) {
|
||||
// Download interrupted... just exit
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package cc.arduino.contributions;
|
||||
|
||||
import cc.arduino.utils.Progress;
|
||||
|
||||
public class NoopProgressListener implements ProgressListener {
|
||||
|
||||
@Override
|
||||
public void onProgress(Progress progress) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import cc.arduino.utils.Progress;
|
||||
|
||||
public interface ProgressListener {
|
||||
|
||||
void onProgress(Progress progress);
|
||||
|
||||
}
|
@ -29,11 +29,12 @@
|
||||
|
||||
package cc.arduino.contributions.libraries;
|
||||
|
||||
import cc.arduino.Constants;
|
||||
import cc.arduino.contributions.DownloadableContributionsDownloader;
|
||||
import cc.arduino.contributions.GZippedJsonDownloader;
|
||||
import cc.arduino.contributions.ProgressListener;
|
||||
import cc.arduino.utils.ArchiveExtractor;
|
||||
import cc.arduino.utils.MultiStepProgress;
|
||||
import cc.arduino.utils.Progress;
|
||||
import processing.app.I18n;
|
||||
import processing.app.Platform;
|
||||
import processing.app.helpers.FileUtils;
|
||||
@ -46,19 +47,6 @@ import static processing.app.I18n.tr;
|
||||
|
||||
public class LibraryInstaller {
|
||||
|
||||
private static final String LIBRARY_INDEX_URL;
|
||||
private static final String LIBRARY_INDEX_URL_GZ;
|
||||
|
||||
static {
|
||||
String externalLibraryIndexUrl = System.getProperty("LIBRARY_INDEX_URL");
|
||||
if (externalLibraryIndexUrl != null && !"".equals(externalLibraryIndexUrl)) {
|
||||
LIBRARY_INDEX_URL = externalLibraryIndexUrl;
|
||||
} else {
|
||||
LIBRARY_INDEX_URL = "http://downloads.arduino.cc/libraries/library_index.json";
|
||||
}
|
||||
LIBRARY_INDEX_URL_GZ = "http://downloads.arduino.cc/libraries/library_index.json.gz";
|
||||
}
|
||||
|
||||
private final LibrariesIndexer indexer;
|
||||
private final DownloadableContributionsDownloader downloader;
|
||||
private final Platform platform;
|
||||
@ -67,23 +55,18 @@ public class LibraryInstaller {
|
||||
this.indexer = indexer;
|
||||
this.platform = platform;
|
||||
File stagingFolder = indexer.getStagingFolder();
|
||||
downloader = new DownloadableContributionsDownloader(stagingFolder) {
|
||||
@Override
|
||||
protected void onProgress(Progress progress) {
|
||||
LibraryInstaller.this.onProgress(progress);
|
||||
}
|
||||
};
|
||||
downloader = new DownloadableContributionsDownloader(stagingFolder);
|
||||
}
|
||||
|
||||
public void updateIndex() throws Exception {
|
||||
public synchronized void updateIndex(ProgressListener progressListener) throws Exception {
|
||||
final MultiStepProgress progress = new MultiStepProgress(2);
|
||||
|
||||
// Step 1: Download index
|
||||
File outputFile = indexer.getIndexFile();
|
||||
File tmpFile = new File(outputFile.getAbsolutePath() + ".tmp");
|
||||
try {
|
||||
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, new URL(LIBRARY_INDEX_URL), new URL(LIBRARY_INDEX_URL_GZ));
|
||||
gZippedJsonDownloader.download(tmpFile, progress, tr("Downloading libraries index..."));
|
||||
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, new URL(Constants.LIBRARY_INDEX_URL), new URL(Constants.LIBRARY_INDEX_URL_GZ));
|
||||
gZippedJsonDownloader.download(tmpFile, progress, tr("Downloading libraries index..."), progressListener);
|
||||
} catch (InterruptedException e) {
|
||||
// Download interrupted... just exit
|
||||
return;
|
||||
@ -99,10 +82,10 @@ public class LibraryInstaller {
|
||||
throw new Exception(tr("An error occurred while updating libraries index!"));
|
||||
|
||||
// Step 2: Rescan index
|
||||
rescanLibraryIndex(progress);
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
}
|
||||
|
||||
public void install(ContributedLibrary lib, ContributedLibrary replacedLib) throws Exception {
|
||||
public synchronized void install(ContributedLibrary lib, ContributedLibrary replacedLib, ProgressListener progressListener) throws Exception {
|
||||
if (lib.isInstalled()) {
|
||||
System.out.println(I18n.format(tr("Library is already installed: {0} version {1}"), lib.getName(), lib.getParsedVersion()));
|
||||
return;
|
||||
@ -112,7 +95,7 @@ public class LibraryInstaller {
|
||||
|
||||
// Step 1: Download library
|
||||
try {
|
||||
downloader.download(lib, progress, I18n.format(tr("Downloading library: {0}"), lib.getName()));
|
||||
downloader.download(lib, progress, I18n.format(tr("Downloading library: {0}"), lib.getName()), progressListener);
|
||||
} catch (InterruptedException e) {
|
||||
// Download interrupted... just exit
|
||||
return;
|
||||
@ -124,7 +107,7 @@ public class LibraryInstaller {
|
||||
|
||||
// Step 2: Unpack library on the correct location
|
||||
progress.setStatus(I18n.format(tr("Installing library: {0}"), lib.getName()));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
File libsFolder = indexer.getSketchbookLibrariesFolder();
|
||||
File tmpFolder = FileUtils.createTempFolderIn(libsFolder);
|
||||
try {
|
||||
@ -137,16 +120,16 @@ public class LibraryInstaller {
|
||||
|
||||
// Step 3: Remove replaced library and move installed one to the correct location
|
||||
// TODO: Fix progress bar...
|
||||
remove(replacedLib);
|
||||
remove(replacedLib, progressListener);
|
||||
File destFolder = new File(libsFolder, lib.getName().replaceAll(" ", "_"));
|
||||
tmpFolder.renameTo(destFolder);
|
||||
progress.stepDone();
|
||||
|
||||
// Step 4: Rescan index
|
||||
rescanLibraryIndex(progress);
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
}
|
||||
|
||||
public void remove(ContributedLibrary lib) throws IOException {
|
||||
public synchronized void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException {
|
||||
if (lib == null || lib.isReadOnly()) {
|
||||
return;
|
||||
}
|
||||
@ -155,22 +138,18 @@ public class LibraryInstaller {
|
||||
|
||||
// Step 1: Remove library
|
||||
progress.setStatus(I18n.format(tr("Removing library: {0}"), lib.getName()));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
FileUtils.recursiveDelete(lib.getInstalledFolder());
|
||||
progress.stepDone();
|
||||
|
||||
// Step 2: Rescan index
|
||||
rescanLibraryIndex(progress);
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
}
|
||||
|
||||
private void rescanLibraryIndex(MultiStepProgress progress) {
|
||||
private void rescanLibraryIndex(MultiStepProgress progress, ProgressListener progressListener) {
|
||||
progress.setStatus(tr("Updating list of installed libraries"));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
indexer.rescanLibraries();
|
||||
progress.stepDone();
|
||||
}
|
||||
|
||||
protected void onProgress(Progress progress) {
|
||||
// Empty
|
||||
}
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ package cc.arduino.contributions.packages;
|
||||
import cc.arduino.Constants;
|
||||
import cc.arduino.contributions.DownloadableContribution;
|
||||
import cc.arduino.contributions.DownloadableContributionsDownloader;
|
||||
import cc.arduino.contributions.ProgressListener;
|
||||
import cc.arduino.contributions.SignatureVerifier;
|
||||
import cc.arduino.filters.FileExecutablePredicate;
|
||||
import cc.arduino.utils.ArchiveExtractor;
|
||||
import cc.arduino.utils.MultiStepProgress;
|
||||
import cc.arduino.utils.Progress;
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.Executor;
|
||||
@ -70,15 +70,10 @@ public class ContributionInstaller {
|
||||
this.signatureVerifier = signatureVerifier;
|
||||
File stagingFolder = contributionsIndexer.getStagingFolder();
|
||||
indexer = contributionsIndexer;
|
||||
downloader = new DownloadableContributionsDownloader(stagingFolder) {
|
||||
@Override
|
||||
protected void onProgress(Progress progress) {
|
||||
ContributionInstaller.this.onProgress(progress);
|
||||
}
|
||||
};
|
||||
downloader = new DownloadableContributionsDownloader(stagingFolder);
|
||||
}
|
||||
|
||||
public List<String> install(ContributedPlatform contributedPlatform) throws Exception {
|
||||
public synchronized List<String> install(ContributedPlatform contributedPlatform, ProgressListener progressListener) throws Exception {
|
||||
List<String> errors = new LinkedList<>();
|
||||
if (contributedPlatform.isInstalled()) {
|
||||
throw new Exception("Platform is already installed!");
|
||||
@ -104,7 +99,7 @@ public class ContributionInstaller {
|
||||
// Download all
|
||||
try {
|
||||
// Download platform
|
||||
downloader.download(contributedPlatform, progress, tr("Downloading boards definitions."));
|
||||
downloader.download(contributedPlatform, progress, tr("Downloading boards definitions."), progressListener);
|
||||
progress.stepDone();
|
||||
|
||||
// Download tools
|
||||
@ -112,7 +107,7 @@ public class ContributionInstaller {
|
||||
for (ContributedTool tool : tools) {
|
||||
String msg = format(tr("Downloading tools ({0}/{1})."), i, tools.size());
|
||||
i++;
|
||||
downloader.download(tool.getDownloadableContribution(platform), progress, msg);
|
||||
downloader.download(tool.getDownloadableContribution(platform), progress, msg, progressListener);
|
||||
progress.stepDone();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@ -132,7 +127,7 @@ public class ContributionInstaller {
|
||||
int i = 1;
|
||||
for (ContributedTool tool : tools) {
|
||||
progress.setStatus(format(tr("Installing tools ({0}/{1})..."), i, tools.size()));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
i++;
|
||||
DownloadableContribution toolContrib = tool.getDownloadableContribution(platform);
|
||||
File destFolder = new File(toolsFolder, tool.getName() + File.separator + tool.getVersion());
|
||||
@ -152,7 +147,7 @@ public class ContributionInstaller {
|
||||
|
||||
// Unpack platform on the correct location
|
||||
progress.setStatus(tr("Installing boards..."));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
File platformFolder = new File(packageFolder, "hardware" + File.separator + contributedPlatform.getArchitecture());
|
||||
File destFolder = new File(platformFolder, contributedPlatform.getParsedVersion());
|
||||
Files.createDirectories(destFolder.toPath());
|
||||
@ -168,7 +163,7 @@ public class ContributionInstaller {
|
||||
progress.stepDone();
|
||||
|
||||
progress.setStatus(tr("Installation completed!"));
|
||||
onProgress(progress);
|
||||
progressListener.onProgress(progress);
|
||||
|
||||
return errors;
|
||||
}
|
||||
@ -234,7 +229,7 @@ public class ContributionInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> remove(ContributedPlatform contributedPlatform) {
|
||||
public synchronized List<String> remove(ContributedPlatform contributedPlatform) {
|
||||
if (contributedPlatform == null || contributedPlatform.isReadOnly()) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
@ -274,11 +269,11 @@ public class ContributionInstaller {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public List<String> updateIndex() throws Exception {
|
||||
public synchronized List<String> updateIndex(ProgressListener progressListener) throws Exception {
|
||||
MultiStepProgress progress = new MultiStepProgress(1);
|
||||
|
||||
List<String> downloadedPackageIndexFilesAccumulator = new LinkedList<>();
|
||||
downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, Constants.PACKAGE_INDEX_URL);
|
||||
downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, Constants.PACKAGE_INDEX_URL, progressListener);
|
||||
|
||||
Set<String> packageIndexURLs = new HashSet<>();
|
||||
String additionalURLs = PreferencesData.get(Constants.PREF_BOARDS_MANAGER_ADDITIONAL_URLS, "");
|
||||
@ -287,7 +282,7 @@ public class ContributionInstaller {
|
||||
}
|
||||
|
||||
for (String packageIndexURL : packageIndexURLs) {
|
||||
downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, packageIndexURL);
|
||||
downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, packageIndexURL, progressListener);
|
||||
}
|
||||
|
||||
progress.stepDone();
|
||||
@ -295,11 +290,11 @@ public class ContributionInstaller {
|
||||
return downloadedPackageIndexFilesAccumulator;
|
||||
}
|
||||
|
||||
private void downloadIndexAndSignature(MultiStepProgress progress, List<String> downloadedPackagedIndexFilesAccumulator, String packageIndexUrl) throws Exception {
|
||||
File packageIndex = download(progress, packageIndexUrl);
|
||||
private void downloadIndexAndSignature(MultiStepProgress progress, List<String> downloadedPackagedIndexFilesAccumulator, String packageIndexUrl, ProgressListener progressListener) throws Exception {
|
||||
File packageIndex = download(progress, packageIndexUrl, progressListener);
|
||||
downloadedPackagedIndexFilesAccumulator.add(packageIndex.getName());
|
||||
try {
|
||||
File packageIndexSignature = download(progress, packageIndexUrl + ".sig");
|
||||
File packageIndexSignature = download(progress, packageIndexUrl + ".sig", progressListener);
|
||||
boolean signatureVerified = signatureVerifier.isSigned(packageIndex);
|
||||
if (signatureVerified) {
|
||||
downloadedPackagedIndexFilesAccumulator.add(packageIndexSignature.getName());
|
||||
@ -314,32 +309,21 @@ public class ContributionInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
private File download(MultiStepProgress progress, String packageIndexUrl) throws Exception {
|
||||
private File download(MultiStepProgress progress, String packageIndexUrl, ProgressListener progressListener) throws Exception {
|
||||
String statusText = tr("Downloading platforms index...");
|
||||
URL url = new URL(packageIndexUrl);
|
||||
String[] urlPathParts = url.getFile().split("/");
|
||||
File outputFile = indexer.getIndexFile(urlPathParts[urlPathParts.length - 1]);
|
||||
File tmpFile = new File(outputFile.getAbsolutePath() + ".tmp");
|
||||
downloader.download(url, tmpFile, progress, statusText);
|
||||
downloader.download(url, tmpFile, progress, statusText, progressListener);
|
||||
|
||||
// Replace old index with the updated one
|
||||
if (outputFile.exists()) {
|
||||
if (!outputFile.delete()) {
|
||||
throw new Exception("An error occurred while updating platforms index! I can't delete file " + outputFile);
|
||||
}
|
||||
}
|
||||
if (!tmpFile.renameTo(outputFile)) {
|
||||
throw new Exception("An error occurred while updating platforms index! I can't rename file " + tmpFile);
|
||||
}
|
||||
Files.deleteIfExists(outputFile.toPath());
|
||||
Files.move(tmpFile.toPath(), outputFile.toPath());
|
||||
|
||||
return outputFile;
|
||||
}
|
||||
|
||||
protected void onProgress(Progress progress) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
public void deleteUnknownFiles(List<String> downloadedPackageIndexFiles) throws IOException {
|
||||
public synchronized void deleteUnknownFiles(List<String> downloadedPackageIndexFiles) throws IOException {
|
||||
File preferencesFolder = indexer.getIndexFile(".").getParentFile();
|
||||
File[] additionalPackageIndexFiles = preferencesFolder.listFiles(new PackageIndexFilenameFilter(Constants.DEFAULT_INDEX_FILE_NAME));
|
||||
if (additionalPackageIndexFiles == null) {
|
||||
|
@ -136,6 +136,8 @@
|
||||
<fileset dir="shared/tools" />
|
||||
</copy>
|
||||
|
||||
<copy file="shared/icons/48x48/apps/arduino.png" tofile="${target.path}/lib/arduino_small.png"/>
|
||||
|
||||
<antcall target="assemble-hardware" />
|
||||
|
||||
<copy file="../hardware/platform.keys.rewrite.txt" todir="${staging_folder}/work/${staging_hardware_folder}"/>
|
||||
|
BIN
build/shared/lib/theme/close.png
Normal file
BIN
build/shared/lib/theme/close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 375 B |
Loading…
x
Reference in New Issue
Block a user