From f9612bcdbdff39ef4204b8770bb36a00cddfd66c Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 3 Aug 2015 17:06:21 +0200 Subject: [PATCH 1/8] Updatable boards support and libraries notification --- .../UpdatableBoardsLibsFakeURLsHandler.java | 45 ++++ .../BuiltInCoreIsNewerCheck.java | 9 +- .../contributions/ContributionsSelfCheck.java | 83 +++++++ .../libraries/ui/LibraryManagerUI.java | 10 +- .../contributions/ui/InstallerJDialog.java | 13 ++ .../cc/arduino/view/NotificationPopup.form | 123 ++++++++++ .../cc/arduino/view/NotificationPopup.java | 218 ++++++++++++++++++ app/src/processing/app/Base.java | 50 ++-- arduino-core/src/cc/arduino/Constants.java | 4 +- build/build.xml | 2 + build/shared/lib/theme/close.png | Bin 0 -> 375 bytes 11 files changed, 522 insertions(+), 35 deletions(-) create mode 100644 app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java create mode 100644 app/src/cc/arduino/contributions/ContributionsSelfCheck.java create mode 100644 app/src/cc/arduino/view/NotificationPopup.form create mode 100644 app/src/cc/arduino/view/NotificationPopup.java create mode 100644 build/shared/lib/theme/close.png diff --git a/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java b/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java new file mode 100644 index 000000000..050c4b3f6 --- /dev/null +++ b/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java @@ -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"); + } + +} diff --git a/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java b/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java index 683c00125..800756c19 100644 --- a/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java +++ b/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java @@ -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(); + } } }); } diff --git a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java new file mode 100644 index 000000000..bb5c13d39 --- /dev/null +++ b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java @@ -0,0 +1,83 @@ +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._; + +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; + + 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; + } + + @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(_("Some {0}libraries{1} may be updated"), "", ""); + } else if (updatableLibraries <= 0 && updatablePlatforms > 0) { + text = I18n.format(_("Some {0}boards{1} may be updated"), "", ""); + } else { + text = I18n.format(_("Some {0}boards{1} and some {2}libraries{3} may be updated"), "", "", "", ""); + } + + SwingUtilities.invokeLater(() -> { + new NotificationPopup(base.getActiveEditor(), hyperlinkListener, _("Updates available"), text).setVisible(true); + }); + } + + private void updateLibrariesIndex() { + try { + libraryInstaller.updateIndex(); + } catch (Exception e) { + // ignore + } + } + + private void updateContributionIndex() { + try { + contributionInstaller.updateIndex(); + } catch (Exception e) { + // ignore + } + } +} diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java index bcfdba5da..921980310 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java +++ b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java @@ -125,7 +125,7 @@ public class LibraryManagerUI extends InstallerJDialog { @Override public void updateIndexFilter(String[] filters, Predicate... additionalFilters) { if (additionalFilters.length == 1) { - additionalFilters = new Predicate[] { additionalFilters[0], typeFilter }; + additionalFilters = new Predicate[]{additionalFilters[0], typeFilter}; } super.updateIndexFilter(filters, additionalFilters); } @@ -191,18 +191,14 @@ public class LibraryManagerUI extends InstallerJDialog { }; } - 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; diff --git a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java index bc69af2c4..255d6f407 100644 --- a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java +++ b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java @@ -276,6 +276,19 @@ public abstract class InstallerJDialog 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. */ diff --git a/app/src/cc/arduino/view/NotificationPopup.form b/app/src/cc/arduino/view/NotificationPopup.form new file mode 100644 index 000000000..48daea67e --- /dev/null +++ b/app/src/cc/arduino/view/NotificationPopup.form @@ -0,0 +1,123 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/cc/arduino/view/NotificationPopup.java b/app/src/cc/arduino/view/NotificationPopup.java new file mode 100644 index 000000000..e3034dda7 --- /dev/null +++ b/app/src/cc/arduino/view/NotificationPopup.java @@ -0,0 +1,218 @@ +/* + * 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 cc.arduino.Constants; +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; + private final Timer autoCloseAfterTimeout; + + public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, String titleText, String message) { + super(parent, false); + initComponents(); + + updateLocation(parent); + parentMovedListener = new ComponentAdapter() { + @Override + public void componentMoved(ComponentEvent e) { + updateLocation(parent); + } + }; + parent.addComponentListener(parentMovedListener); + + title.setText(titleText); + text.setText("" + message.replace("\n", "
") + ""); + + text.addHyperlinkListener(hyperlinkListener); + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + parent.removeComponentListener(parentMovedListener); + } + }); + + autoCloseAfterTimeout = new Timer(Constants.NOTIFICATION_POPUP_AUTOCLOSE_DELAY, (e) -> close()); + autoCloseAfterTimeout.start(); + + text.addHyperlinkListener(e -> { + if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { + return; + } + close(); + }); + + Base.registerWindowCloseKeys(getRootPane(), e -> close()); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + close(); + } + }); + } + + 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 + parent.getWidth() - getWidth(), parentY + parent.getHeight() - getHeight()); + } + + private void close() { + if (autoCloseAfterTimeout.isRunning()) { + autoCloseAfterTimeout.stop(); + } + + 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + title = new javax.swing.JLabel(); + javax.swing.JLabel jLabel1 = 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); + setResizable(false); + + title.setFont(title.getFont().deriveFont(title.getFont().getStyle() | java.awt.Font.BOLD)); + + jLabel1.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "arduino_small.png").toFile().getAbsolutePath())); + + 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); + + 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); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 264, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(title, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(24, 24, 24) + .addComponent(closeButton)))) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(title)) + .addComponent(closeButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //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, "title", "test 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.JEditorPane text; + private javax.swing.JLabel title; + // End of variables declaration//GEN-END:variables + +} diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 6655c94f3..088b14b9e 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -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; @@ -62,6 +61,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 +93,7 @@ public class Base { public static SplashScreenHelper splashScreenHelper = new SplashScreenHelper(SplashScreen.getSplashScreen()); public static Map FIND_DIALOG_STATE = new HashMap(); + private Timer selfCheckTimer; // set to true after the first time the menu is built. // so that the errors while building don't show up again. @@ -117,7 +118,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 boardsCustomMenus; - private volatile Action openBoardsManager; private List programmerMenus; private final PdeKeywords pdeKeywords; @@ -481,6 +481,11 @@ public class Base { new Thread(new BuiltInCoreIsNewerCheck(this)).start(); + selfCheckTimer = new Timer(false); + ContributionInstaller contributionInstaller = new ContributionInstaller(BaseNoGui.indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()); + LibraryInstaller libraryInstaller = new LibraryInstaller(BaseNoGui.librariesIndexer, BaseNoGui.getPlatform()); + selfCheckTimer.schedule(new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), BaseNoGui.indexer, contributionInstaller, BaseNoGui.librariesIndexer, libraryInstaller), Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD); + } else if (parser.isNoOpMode()) { // Do nothing (intended for only changing preferences) System.exit(0); @@ -1165,11 +1170,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,7 +1258,7 @@ public class Base { } } - private void openManageLibrariesDialog() { + public void openLibraryManager(String dropdownItem) { @SuppressWarnings("serial") LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.getPlatform()) { @Override @@ -1267,6 +1268,9 @@ public class Base { rebuildProgrammerMenu(); onBoardOrPortChange(); setIndexer(BaseNoGui.librariesIndexer); + if (StringUtils.isNotEmpty(dropdownItem)) { + selectDropdownItemByClassName(dropdownItem); + } } }; managerUI.setLocationRelativeTo(activeEditor); @@ -1280,7 +1284,7 @@ public class Base { rebuildExamplesMenu(Editor.examplesMenu); } - private void openInstallBoardDialog(final String filterText) throws Exception { + public void openBoardsManager(final String filterText, String dropdownItem) throws Exception { // Create dialog for contribution manager @SuppressWarnings("serial") ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.getPlatform()) { @@ -1290,10 +1294,12 @@ public class Base { rebuildBoardsMenu(); rebuildProgrammerMenu(); setIndexer(BaseNoGui.indexer); + if (StringUtils.isNotEmpty(dropdownItem)) { + selectDropdownItemByClassName(dropdownItem); + } if (StringUtils.isNotEmpty(filterText)) { setFilterText(filterText); } - } }; managerUI.setLocationRelativeTo(activeEditor); @@ -1316,21 +1322,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 +2370,7 @@ public class Base { } public List getEditors() { - return new LinkedList(editors); - } - - public Action getOpenBoardsManager() { - return openBoardsManager; + return new LinkedList<>(editors); } public PdeKeywords getPdeKeywords() { @@ -2377,4 +2380,5 @@ public class Base { public List getRecentSketchesMenuItems() { return recentSketchesMenuItems; } + } diff --git a/arduino-core/src/cc/arduino/Constants.java b/arduino-core/src/cc/arduino/Constants.java index 5b0e4436f..48f355736 100644 --- a/arduino-core/src/cc/arduino/Constants.java +++ b/arduino-core/src/cc/arduino/Constants.java @@ -44,6 +44,9 @@ 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; + static { String extenalPackageIndexUrl = System.getProperty("PACKAGE_INDEX_URL"); if (extenalPackageIndexUrl != null && !"".equals(extenalPackageIndexUrl)) { @@ -53,5 +56,4 @@ public class Constants { } } - } diff --git a/build/build.xml b/build/build.xml index b3bc4fd1c..c8ecf2942 100644 --- a/build/build.xml +++ b/build/build.xml @@ -136,6 +136,8 @@ + + diff --git a/build/shared/lib/theme/close.png b/build/shared/lib/theme/close.png new file mode 100644 index 0000000000000000000000000000000000000000..8041c8bded93008efa4c75a7a940e7033e58f010 GIT binary patch literal 375 zcmV--0f_#IP)RohMdIb@JrJLOJN(H^~X0sVc5aSeQ zBPiGd!_1kZKlJ-X`M&SD-&iw0lue4R>$XKvtN{Lk`w8?l&+`>r^K|G`%;5D;rcID< z59#et^DfaS(DZByKzVH2M)NM1z)6yDilRKAQDaTfz%g8w<$ESD8Un^#mu30<0nI?u zC1}3H8hdcI1%q#BVAP8mIHxdn8$l4fp@+4u>ubp5t9x;dzx{lD-{)A@KmO4l!SA^v Vtxt1zu#x}(002ovPDHLkV1ga_t1$oo literal 0 HcmV?d00001 From c61c39f5d96967cf7b7f066d59c822831e511102 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Aug 2015 09:10:40 +0200 Subject: [PATCH 2/8] Canceling self check timer when opening boards/libs manager --- app/src/processing/app/Base.java | 7 ++++++- .../contributions/packages/ContributionInstaller.java | 11 ++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 088b14b9e..760f86a34 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1259,6 +1259,9 @@ public class Base { } public void openLibraryManager(String dropdownItem) { + if (selfCheckTimer != null) { + selfCheckTimer.cancel(); + } @SuppressWarnings("serial") LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.getPlatform()) { @Override @@ -1285,7 +1288,9 @@ public class Base { } public void openBoardsManager(final String filterText, String dropdownItem) throws Exception { - // Create dialog for contribution manager + if (selfCheckTimer != null) { + selfCheckTimer.cancel(); + } @SuppressWarnings("serial") ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.getPlatform()) { @Override diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java index 52cdf1c64..5925a340b 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java @@ -322,15 +322,8 @@ public class ContributionInstaller { File tmpFile = new File(outputFile.getAbsolutePath() + ".tmp"); downloader.download(url, tmpFile, progress, statusText); - // 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; } From b3baa27435cbd563afd9237075b3a02e7d61f679 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Aug 2015 09:22:30 +0200 Subject: [PATCH 3/8] ContributionInstaller.onProgress is now a collaborator: ProgressListener --- .../packages/ui/ContributionManagerUI.java | 7 +--- app/src/processing/app/Base.java | 7 ++-- .../contributions/ProgressListener.java | 38 +++++++++++++++++++ .../packages/ContributionInstaller.java | 20 ++++++---- 4 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 arduino-core/src/cc/arduino/contributions/ProgressListener.java diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java index 025cef5f2..fcf1bd775 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java @@ -118,12 +118,7 @@ public class ContributionManagerUI extends InstallerJDialog { } // Create ConstributionInstaller tied with the provided index - installer = new ContributionInstaller(indexer, platform, new GPGDetachedSignatureVerifier()) { - @Override - public void onProgress(Progress progress) { - setProgress(progress); - } - }; + installer = new ContributionInstaller(indexer, platform, new GPGDetachedSignatureVerifier(), this::setProgress); } public void setProgress(Progress progress) { diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 760f86a34..b8d14a849 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -341,17 +341,18 @@ 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()) { + ContributionInstaller installer = new ContributionInstaller(indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier(), new ProgressListener() { private String lastStatus = ""; @Override - protected void onProgress(Progress progress) { + public void onProgress(Progress progress) { if (!lastStatus.equals(progress.getStatus())) { System.out.println(progress.getStatus()); } lastStatus = progress.getStatus(); } - }; + }); + List downloadedPackageIndexFiles = installer.updateIndex(); installer.deleteUnknownFiles(downloadedPackageIndexFiles); indexer.parseIndex(); diff --git a/arduino-core/src/cc/arduino/contributions/ProgressListener.java b/arduino-core/src/cc/arduino/contributions/ProgressListener.java new file mode 100644 index 000000000..f1b8d32b0 --- /dev/null +++ b/arduino-core/src/cc/arduino/contributions/ProgressListener.java @@ -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); + +} diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java index 5925a340b..8a66b1073 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java @@ -32,6 +32,7 @@ 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; @@ -64,16 +65,23 @@ public class ContributionInstaller { private final DownloadableContributionsDownloader downloader; private final Platform platform; private final SignatureVerifier signatureVerifier; + private final ProgressListener progressListener; public ContributionInstaller(ContributionsIndexer contributionsIndexer, Platform platform, SignatureVerifier signatureVerifier) { + this(contributionsIndexer, platform, signatureVerifier, progress -> { + }); + } + + public ContributionInstaller(ContributionsIndexer contributionsIndexer, Platform platform, SignatureVerifier signatureVerifier, ProgressListener progressListener) { this.platform = platform; this.signatureVerifier = signatureVerifier; + this.progressListener = progressListener; File stagingFolder = contributionsIndexer.getStagingFolder(); indexer = contributionsIndexer; downloader = new DownloadableContributionsDownloader(stagingFolder) { @Override protected void onProgress(Progress progress) { - ContributionInstaller.this.onProgress(progress); + progressListener.onProgress(progress); } }; } @@ -132,7 +140,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 +160,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 +176,7 @@ public class ContributionInstaller { progress.stepDone(); progress.setStatus(tr("Installation completed!")); - onProgress(progress); + progressListener.onProgress(progress); return errors; } @@ -328,10 +336,6 @@ public class ContributionInstaller { return outputFile; } - protected void onProgress(Progress progress) { - // Empty - } - public void deleteUnknownFiles(List downloadedPackageIndexFiles) throws IOException { File preferencesFolder = indexer.getIndexFile(".").getParentFile(); File[] additionalPackageIndexFiles = preferencesFolder.listFiles(new PackageIndexFilenameFilter(Constants.DEFAULT_INDEX_FILE_NAME)); From dc93bb93d025babbd6774648639edc538b701fa7 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Aug 2015 11:01:00 +0200 Subject: [PATCH 4/8] ProgressListener is now a method arg (was an instance arg) --- .../contributions/ContributionsSelfCheck.java | 6 ++- .../libraries/ui/LibraryManagerUI.java | 13 ++----- .../packages/ui/ContributionManagerUI.java | 6 +-- app/src/processing/app/Base.java | 37 +++++------------- .../GzippedJsonDownloaderTest.java | 2 +- .../contributions/JsonDownloaderTest.java | 2 +- .../ConsoleProgressListener.java | 15 +++++++ .../DownloadableContributionsDownloader.java | 14 +++---- .../contributions/GZippedJsonDownloader.java | 6 +-- .../arduino/contributions/JsonDownloader.java | 4 +- .../contributions/NoopProgressListener.java | 12 ++++++ .../libraries/LibraryInstaller.java | 39 +++++++------------ .../packages/ContributionInstaller.java | 37 ++++++------------ 13 files changed, 86 insertions(+), 107 deletions(-) create mode 100644 arduino-core/src/cc/arduino/contributions/ConsoleProgressListener.java create mode 100644 arduino-core/src/cc/arduino/contributions/NoopProgressListener.java diff --git a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java index bb5c13d39..4819b2137 100644 --- a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java +++ b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java @@ -24,6 +24,7 @@ public class ContributionsSelfCheck extends TimerTask { private final ContributionInstaller contributionInstaller; private final LibrariesIndexer librariesIndexer; private final LibraryInstaller libraryInstaller; + private final ProgressListener progressListener; public ContributionsSelfCheck(Base base, HyperlinkListener hyperlinkListener, ContributionsIndexer contributionsIndexer, ContributionInstaller contributionInstaller, LibrariesIndexer librariesIndexer, LibraryInstaller libraryInstaller) { this.base = base; @@ -32,6 +33,7 @@ public class ContributionsSelfCheck extends TimerTask { this.contributionInstaller = contributionInstaller; this.librariesIndexer = librariesIndexer; this.libraryInstaller = libraryInstaller; + this.progressListener = new NoopProgressListener(); } @Override @@ -67,7 +69,7 @@ public class ContributionsSelfCheck extends TimerTask { private void updateLibrariesIndex() { try { - libraryInstaller.updateIndex(); + libraryInstaller.updateIndex(progressListener); } catch (Exception e) { // ignore } @@ -75,7 +77,7 @@ public class ContributionsSelfCheck extends TimerTask { private void updateContributionIndex() { try { - contributionInstaller.updateIndex(); + contributionInstaller.updateIndex(progressListener); } catch (Exception e) { // ignore } diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java index 921980310..6bb146037 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java +++ b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java @@ -183,12 +183,7 @@ public class LibraryManagerUI extends InstallerJDialog { 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); - } - }; + installer = new LibraryInstaller(indexer, platform); } public void selectDropdownItemByClassName(String dropdownItem) { @@ -216,7 +211,7 @@ public class LibraryManagerUI extends InstallerJDialog { installerThread = new Thread(() -> { try { setProgressVisible(true, ""); - installer.updateIndex(); + installer.updateIndex(this::setProgress); onIndexesUpdated(); } catch (Exception e) { throw new RuntimeException(e); @@ -233,7 +228,7 @@ public class LibraryManagerUI extends InstallerJDialog { 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) { @@ -260,7 +255,7 @@ public class LibraryManagerUI extends InstallerJDialog { 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) { diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java index fcf1bd775..6ec32a406 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java @@ -118,7 +118,7 @@ public class ContributionManagerUI extends InstallerJDialog { } // Create ConstributionInstaller tied with the provided index - installer = new ContributionInstaller(indexer, platform, new GPGDetachedSignatureVerifier(), this::setProgress); + installer = new ContributionInstaller(indexer, platform, new GPGDetachedSignatureVerifier()); } public void setProgress(Progress progress) { @@ -146,7 +146,7 @@ public class ContributionManagerUI extends InstallerJDialog { installerThread = new Thread(() -> { try { setProgressVisible(true, ""); - List downloadedPackageIndexFiles = installer.updateIndex(); + List downloadedPackageIndexFiles = installer.updateIndex(this::setProgress); installer.deleteUnknownFiles(downloadedPackageIndexFiles); onIndexesUpdated(); } catch (Exception e) { @@ -165,7 +165,7 @@ public class ContributionManagerUI extends InstallerJDialog { List 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)); } diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index b8d14a849..fa5573b18 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -33,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; @@ -341,19 +340,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(), new ProgressListener() { - private String lastStatus = ""; + ProgressListener progressListener = new ConsoleProgressListener(); + ContributionInstaller installer = new ContributionInstaller(indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()); - @Override - public void onProgress(Progress progress) { - if (!lastStatus.equals(progress.getStatus())) { - System.out.println(progress.getStatus()); - } - lastStatus = progress.getStatus(); - } - }); - - List downloadedPackageIndexFiles = installer.updateIndex(); + List downloadedPackageIndexFiles = installer.updateIndex(progressListener); installer.deleteUnknownFiles(downloadedPackageIndexFiles); indexer.parseIndex(); indexer.syncWithFilesystem(BaseNoGui.getHardwareFolder()); @@ -378,7 +368,7 @@ public class Base { ContributedPlatform installed = indexer.getInstalled(boardToInstallParts[0], boardToInstallParts[1]); if (!selected.isReadOnly()) { - installer.install(selected); + installer.install(selected, progressListener); } if (installed != null && !installed.isReadOnly()) { @@ -389,22 +379,13 @@ public class Base { } 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(); + LibraryInstaller installer = new LibraryInstaller(indexer, BaseNoGui.getPlatform()); indexer.parseIndex(); BaseNoGui.onBoardOrPortChange(); indexer.setSketchbookLibrariesFolder(BaseNoGui.getSketchbookLibrariesFolder()); indexer.setLibrariesFolders(BaseNoGui.getLibrariesPath()); - installer.updateIndex(); + installer.updateIndex(progressListener); for (String library : parser.getLibraryToInstall().split(",")) { String[] libraryToInstallParts = library.split(":"); @@ -426,9 +407,9 @@ public class Base { ContributedLibrary installed = indexer.getIndex().getInstalled(libraryToInstallParts[0]); if (selected.isReadOnly()) { - installer.remove(installed); + installer.remove(installed, progressListener); } else { - installer.install(selected, installed); + installer.install(selected, installed, progressListener); } } diff --git a/app/test/cc/arduino/contributions/GzippedJsonDownloaderTest.java b/app/test/cc/arduino/contributions/GzippedJsonDownloaderTest.java index a762b6801..e1e231acd 100644 --- a/app/test/cc/arduino/contributions/GzippedJsonDownloaderTest.java +++ b/app/test/cc/arduino/contributions/GzippedJsonDownloaderTest.java @@ -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(); diff --git a/app/test/cc/arduino/contributions/JsonDownloaderTest.java b/app/test/cc/arduino/contributions/JsonDownloaderTest.java index 98cefef49..ebf3c0913 100644 --- a/app/test/cc/arduino/contributions/JsonDownloaderTest.java +++ b/app/test/cc/arduino/contributions/JsonDownloaderTest.java @@ -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(); diff --git a/arduino-core/src/cc/arduino/contributions/ConsoleProgressListener.java b/arduino-core/src/cc/arduino/contributions/ConsoleProgressListener.java new file mode 100644 index 000000000..c45299484 --- /dev/null +++ b/arduino-core/src/cc/arduino/contributions/ConsoleProgressListener.java @@ -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(); + } +} diff --git a/arduino-core/src/cc/arduino/contributions/DownloadableContributionsDownloader.java b/arduino-core/src/cc/arduino/contributions/DownloadableContributionsDownloader.java index 5b6309285..8bbcbc227 100644 --- a/arduino-core/src/cc/arduino/contributions/DownloadableContributionsDownloader.java +++ b/arduino-core/src/cc/arduino/contributions/DownloadableContributionsDownloader.java @@ -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 - } - } diff --git a/arduino-core/src/cc/arduino/contributions/GZippedJsonDownloader.java b/arduino-core/src/cc/arduino/contributions/GZippedJsonDownloader.java index b4994d8d7..df7eee420 100644 --- a/arduino-core/src/cc/arduino/contributions/GZippedJsonDownloader.java +++ b/arduino-core/src/cc/arduino/contributions/GZippedJsonDownloader.java @@ -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); } } diff --git a/arduino-core/src/cc/arduino/contributions/JsonDownloader.java b/arduino-core/src/cc/arduino/contributions/JsonDownloader.java index da01ff95b..88f9e7783 100644 --- a/arduino-core/src/cc/arduino/contributions/JsonDownloader.java +++ b/arduino-core/src/cc/arduino/contributions/JsonDownloader.java @@ -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 } diff --git a/arduino-core/src/cc/arduino/contributions/NoopProgressListener.java b/arduino-core/src/cc/arduino/contributions/NoopProgressListener.java new file mode 100644 index 000000000..68649ecda --- /dev/null +++ b/arduino-core/src/cc/arduino/contributions/NoopProgressListener.java @@ -0,0 +1,12 @@ +package cc.arduino.contributions; + +import cc.arduino.utils.Progress; + +public class NoopProgressListener implements ProgressListener { + + @Override + public void onProgress(Progress progress) { + + } + +} diff --git a/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java b/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java index c2afad7dc..48c1fc4a2 100644 --- a/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java @@ -31,9 +31,9 @@ package cc.arduino.contributions.libraries; 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; @@ -67,15 +67,10 @@ 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 void updateIndex(ProgressListener progressListener) throws Exception { final MultiStepProgress progress = new MultiStepProgress(2); // Step 1: Download index @@ -83,7 +78,7 @@ public class LibraryInstaller { 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.download(tmpFile, progress, tr("Downloading libraries index..."), progressListener); } catch (InterruptedException e) { // Download interrupted... just exit return; @@ -99,10 +94,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 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 +107,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 +119,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 +132,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 void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException { if (lib == null || lib.isReadOnly()) { return; } @@ -155,22 +150,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 - } } diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java index 8a66b1073..72622022b 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java @@ -37,7 +37,6 @@ 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; @@ -65,28 +64,16 @@ public class ContributionInstaller { private final DownloadableContributionsDownloader downloader; private final Platform platform; private final SignatureVerifier signatureVerifier; - private final ProgressListener progressListener; public ContributionInstaller(ContributionsIndexer contributionsIndexer, Platform platform, SignatureVerifier signatureVerifier) { - this(contributionsIndexer, platform, signatureVerifier, progress -> { - }); - } - - public ContributionInstaller(ContributionsIndexer contributionsIndexer, Platform platform, SignatureVerifier signatureVerifier, ProgressListener progressListener) { this.platform = platform; this.signatureVerifier = signatureVerifier; - this.progressListener = progressListener; File stagingFolder = contributionsIndexer.getStagingFolder(); indexer = contributionsIndexer; - downloader = new DownloadableContributionsDownloader(stagingFolder) { - @Override - protected void onProgress(Progress progress) { - progressListener.onProgress(progress); - } - }; + downloader = new DownloadableContributionsDownloader(stagingFolder); } - public List install(ContributedPlatform contributedPlatform) throws Exception { + public List install(ContributedPlatform contributedPlatform, ProgressListener progressListener) throws Exception { List errors = new LinkedList<>(); if (contributedPlatform.isInstalled()) { throw new Exception("Platform is already installed!"); @@ -112,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 @@ -120,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) { @@ -282,11 +269,11 @@ public class ContributionInstaller { return errors; } - public List updateIndex() throws Exception { + public List updateIndex(ProgressListener progressListener) throws Exception { MultiStepProgress progress = new MultiStepProgress(1); List downloadedPackageIndexFilesAccumulator = new LinkedList<>(); - downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, Constants.PACKAGE_INDEX_URL); + downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, Constants.PACKAGE_INDEX_URL, progressListener); Set packageIndexURLs = new HashSet<>(); String additionalURLs = PreferencesData.get(Constants.PREF_BOARDS_MANAGER_ADDITIONAL_URLS, ""); @@ -295,7 +282,7 @@ public class ContributionInstaller { } for (String packageIndexURL : packageIndexURLs) { - downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, packageIndexURL); + downloadIndexAndSignature(progress, downloadedPackageIndexFilesAccumulator, packageIndexURL, progressListener); } progress.stepDone(); @@ -303,11 +290,11 @@ public class ContributionInstaller { return downloadedPackageIndexFilesAccumulator; } - private void downloadIndexAndSignature(MultiStepProgress progress, List downloadedPackagedIndexFilesAccumulator, String packageIndexUrl) throws Exception { - File packageIndex = download(progress, packageIndexUrl); + private void downloadIndexAndSignature(MultiStepProgress progress, List 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()); @@ -322,13 +309,13 @@ 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); Files.deleteIfExists(outputFile.toPath()); Files.move(tmpFile.toPath(), outputFile.toPath()); From 2daf330c093f5415651aeb7fb4a70a0ab7e7466d Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Aug 2015 11:35:29 +0200 Subject: [PATCH 5/8] LibraryInstaller and ContributionInstaller are now singletons: members of Base, they get passed to dependents, thus allowing a synchronized method execution, needed to avoid race conditions when accessing files --- .../libraries/ui/LibraryManagerUI.java | 18 +++---- .../packages/ui/ContributionManagerUI.java | 16 +++--- app/src/processing/app/Base.java | 49 +++++++------------ arduino-core/src/cc/arduino/Constants.java | 11 +++++ .../libraries/LibraryInstaller.java | 22 ++------- .../packages/ContributionInstaller.java | 8 +-- 6 files changed, 50 insertions(+), 74 deletions(-) diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java index 6bb146037..9fa9f3145 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java +++ b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java @@ -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 { private final JComboBox typeChooser; - private final Platform platform; - private LibrariesIndexer indexer; + private final LibrariesIndexer indexer; + private final LibraryInstaller installer; private Predicate typeFilter; @Override @@ -90,9 +89,10 @@ public class LibraryManagerUI extends InstallerJDialog { }; } - 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); @@ -130,9 +130,7 @@ public class LibraryManagerUI extends InstallerJDialog { super.updateIndexFilter(filters, additionalFilters); } - public void setIndexer(LibrariesIndexer indexer) { - this.indexer = indexer; - + public void updateUI() { DropdownItem previouslySelectedCategory = (DropdownItem) categoryChooser.getSelectedItem(); DropdownItem previouslySelectedType = (DropdownItem) typeChooser.getSelectedItem(); @@ -181,9 +179,6 @@ public class LibraryManagerUI extends InstallerJDialog { } filterField.setEnabled(contribModel.getRowCount() > 0); - - // Create LibrariesInstaller tied with the provided index - installer = new LibraryInstaller(indexer, platform); } public void selectDropdownItemByClassName(String dropdownItem) { @@ -194,7 +189,6 @@ public class LibraryManagerUI extends InstallerJDialog { progressBar.setValue(progress); } - private LibraryInstaller installer; private Thread installerThread = null; @Override diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java index 6ec32a406..49ef97618 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java @@ -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 previouslySelectedCategory = (DropdownItem) categoryChooser.getSelectedItem(); categoryChooser.removeActionListener(categoryChooserActionListener); @@ -116,9 +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()); } public void setProgress(Progress progress) { @@ -129,7 +126,6 @@ public class ContributionManagerUI extends InstallerJDialog { * Installer methods follows */ - private ContributionInstaller installer; private Thread installerThread = null; @Override diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index fa5573b18..0e6329710 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -92,6 +92,8 @@ public class Base { public static SplashScreenHelper splashScreenHelper = new SplashScreenHelper(SplashScreen.getSplashScreen()); public static Map FIND_DIALOG_STATE = new HashMap(); + private final ContributionInstaller contributionInstaller; + private final LibraryInstaller libraryInstaller; private Timer selfCheckTimer; // set to true after the first time the menu is built. @@ -302,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,10 +346,9 @@ public class Base { if (parser.isInstallBoard()) { ContributionsIndexer indexer = new ContributionsIndexer(BaseNoGui.getSettingsFolder(), BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()); ProgressListener progressListener = new ConsoleProgressListener(); - ContributionInstaller installer = new ContributionInstaller(indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()); - List downloadedPackageIndexFiles = installer.updateIndex(progressListener); - installer.deleteUnknownFiles(downloadedPackageIndexFiles); + List downloadedPackageIndexFiles = contributionInstaller.updateIndex(progressListener); + contributionInstaller.deleteUnknownFiles(downloadedPackageIndexFiles); indexer.parseIndex(); indexer.syncWithFilesystem(BaseNoGui.getHardwareFolder()); @@ -368,11 +372,11 @@ public class Base { ContributedPlatform installed = indexer.getInstalled(boardToInstallParts[0], boardToInstallParts[1]); if (!selected.isReadOnly()) { - installer.install(selected, progressListener); + contributionInstaller.install(selected, progressListener); } if (installed != null && !installed.isReadOnly()) { - installer.remove(installed); + contributionInstaller.remove(installed); } System.exit(0); @@ -380,12 +384,11 @@ public class Base { } else if (parser.isInstallLibrary()) { LibrariesIndexer indexer = new LibrariesIndexer(BaseNoGui.getSettingsFolder(), new ContributionsIndexer(BaseNoGui.getSettingsFolder(), BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier())); ProgressListener progressListener = new ConsoleProgressListener(); - LibraryInstaller installer = new LibraryInstaller(indexer, BaseNoGui.getPlatform()); indexer.parseIndex(); BaseNoGui.onBoardOrPortChange(); indexer.setSketchbookLibrariesFolder(BaseNoGui.getSketchbookLibrariesFolder()); indexer.setLibrariesFolders(BaseNoGui.getLibrariesPath()); - installer.updateIndex(progressListener); + libraryInstaller.updateIndex(progressListener); for (String library : parser.getLibraryToInstall().split(",")) { String[] libraryToInstallParts = library.split(":"); @@ -407,9 +410,9 @@ public class Base { ContributedLibrary installed = indexer.getIndex().getInstalled(libraryToInstallParts[0]); if (selected.isReadOnly()) { - installer.remove(installed, progressListener); + libraryInstaller.remove(installed, progressListener); } else { - installer.install(selected, installed, progressListener); + libraryInstaller.install(selected, installed, progressListener); } } @@ -464,8 +467,6 @@ public class Base { new Thread(new BuiltInCoreIsNewerCheck(this)).start(); selfCheckTimer = new Timer(false); - ContributionInstaller contributionInstaller = new ContributionInstaller(BaseNoGui.indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()); - LibraryInstaller libraryInstaller = new LibraryInstaller(BaseNoGui.librariesIndexer, BaseNoGui.getPlatform()); selfCheckTimer.schedule(new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), BaseNoGui.indexer, contributionInstaller, BaseNoGui.librariesIndexer, libraryInstaller), Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD); } else if (parser.isNoOpMode()) { @@ -682,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; @@ -791,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 @@ -1245,21 +1232,21 @@ public class Base { selfCheckTimer.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 @@ -1274,13 +1261,13 @@ public class Base { selfCheckTimer.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); } @@ -1290,7 +1277,7 @@ public class Base { } }; managerUI.setLocationRelativeTo(activeEditor); - managerUI.setIndexer(BaseNoGui.indexer); + managerUI.updateUI(); managerUI.setVisible(true); // Installer dialog is modal, waits here until closed diff --git a/arduino-core/src/cc/arduino/Constants.java b/arduino-core/src/cc/arduino/Constants.java index 48f355736..098caab97 100644 --- a/arduino-core/src/cc/arduino/Constants.java +++ b/arduino-core/src/cc/arduino/Constants.java @@ -47,6 +47,9 @@ public class Constants { 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)) { @@ -54,6 +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"; } } diff --git a/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java b/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java index 48c1fc4a2..c01b56f20 100644 --- a/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java @@ -29,6 +29,7 @@ package cc.arduino.contributions.libraries; +import cc.arduino.Constants; import cc.arduino.contributions.DownloadableContributionsDownloader; import cc.arduino.contributions.GZippedJsonDownloader; import cc.arduino.contributions.ProgressListener; @@ -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; @@ -70,14 +58,14 @@ public class LibraryInstaller { downloader = new DownloadableContributionsDownloader(stagingFolder); } - public void updateIndex(ProgressListener progressListener) 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 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 @@ -97,7 +85,7 @@ public class LibraryInstaller { rescanLibraryIndex(progress, progressListener); } - public void install(ContributedLibrary lib, ContributedLibrary replacedLib, ProgressListener progressListener) 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; @@ -141,7 +129,7 @@ public class LibraryInstaller { rescanLibraryIndex(progress, progressListener); } - public void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException { + public synchronized void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException { if (lib == null || lib.isReadOnly()) { return; } diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java index 72622022b..24712c896 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java @@ -73,7 +73,7 @@ public class ContributionInstaller { downloader = new DownloadableContributionsDownloader(stagingFolder); } - public List install(ContributedPlatform contributedPlatform, ProgressListener progressListener) throws Exception { + public synchronized List install(ContributedPlatform contributedPlatform, ProgressListener progressListener) throws Exception { List errors = new LinkedList<>(); if (contributedPlatform.isInstalled()) { throw new Exception("Platform is already installed!"); @@ -229,7 +229,7 @@ public class ContributionInstaller { } } - public List remove(ContributedPlatform contributedPlatform) { + public synchronized List remove(ContributedPlatform contributedPlatform) { if (contributedPlatform == null || contributedPlatform.isReadOnly()) { return new LinkedList<>(); } @@ -269,7 +269,7 @@ public class ContributionInstaller { return errors; } - public List updateIndex(ProgressListener progressListener) throws Exception { + public synchronized List updateIndex(ProgressListener progressListener) throws Exception { MultiStepProgress progress = new MultiStepProgress(1); List downloadedPackageIndexFilesAccumulator = new LinkedList<>(); @@ -323,7 +323,7 @@ public class ContributionInstaller { return outputFile; } - public void deleteUnknownFiles(List downloadedPackageIndexFiles) throws IOException { + public synchronized void deleteUnknownFiles(List downloadedPackageIndexFiles) throws IOException { File preferencesFolder = indexer.getIndexFile(".").getParentFile(); File[] additionalPackageIndexFiles = preferencesFolder.listFiles(new PackageIndexFilenameFilter(Constants.DEFAULT_INDEX_FILE_NAME)); if (additionalPackageIndexFiles == null) { From 0bb7fd7e8b40e4caf49a02859015a5b67bb50a49 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Aug 2015 12:00:00 +0200 Subject: [PATCH 6/8] Cancelling ContributionsSelfCheck will prevent indexes from being updated. Opening boards/libs manager when NotificationPopup is shown will close it --- .../contributions/ContributionsSelfCheck.java | 26 ++++++++++++++++++- .../cc/arduino/view/NotificationPopup.java | 2 +- app/src/processing/app/Base.java | 14 +++++----- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java index 4819b2137..527b8e1ea 100644 --- a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java +++ b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java @@ -26,6 +26,9 @@ public class ContributionsSelfCheck extends TimerTask { 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; @@ -34,6 +37,7 @@ public class ContributionsSelfCheck extends TimerTask { this.librariesIndexer = librariesIndexer; this.libraryInstaller = libraryInstaller; this.progressListener = new NoopProgressListener(); + this.cancelled = false; } @Override @@ -62,12 +66,29 @@ public class ContributionsSelfCheck extends TimerTask { text = I18n.format(_("Some {0}boards{1} and some {2}libraries{3} may be updated"), "", "", "", ""); } + if (cancelled) { + return; + } + SwingUtilities.invokeLater(() -> { - new NotificationPopup(base.getActiveEditor(), hyperlinkListener, _("Updates available"), text).setVisible(true); + notificationPopup = new NotificationPopup(base.getActiveEditor(), hyperlinkListener, _("Updates available"), 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) { @@ -76,6 +97,9 @@ public class ContributionsSelfCheck extends TimerTask { } private void updateContributionIndex() { + if (cancelled) { + return; + } try { contributionInstaller.updateIndex(progressListener); } catch (Exception e) { diff --git a/app/src/cc/arduino/view/NotificationPopup.java b/app/src/cc/arduino/view/NotificationPopup.java index e3034dda7..7119672bd 100644 --- a/app/src/cc/arduino/view/NotificationPopup.java +++ b/app/src/cc/arduino/view/NotificationPopup.java @@ -98,7 +98,7 @@ public class NotificationPopup extends JDialog { setLocation(parentX + parent.getWidth() - getWidth(), parentY + parent.getHeight() - getHeight()); } - private void close() { + public void close() { if (autoCloseAfterTimeout.isRunning()) { autoCloseAfterTimeout.stop(); } diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 0e6329710..7cc5c2a89 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -94,7 +94,7 @@ public class Base { public static Map FIND_DIALOG_STATE = new HashMap(); private final ContributionInstaller contributionInstaller; private final LibraryInstaller libraryInstaller; - private Timer selfCheckTimer; + 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. @@ -466,8 +466,8 @@ public class Base { new Thread(new BuiltInCoreIsNewerCheck(this)).start(); - selfCheckTimer = new Timer(false); - selfCheckTimer.schedule(new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), BaseNoGui.indexer, contributionInstaller, BaseNoGui.librariesIndexer, libraryInstaller), Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD); + 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) @@ -1228,8 +1228,8 @@ public class Base { } public void openLibraryManager(String dropdownItem) { - if (selfCheckTimer != null) { - selfCheckTimer.cancel(); + if (contributionsSelfCheck != null) { + contributionsSelfCheck.cancel(); } @SuppressWarnings("serial") LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.librariesIndexer, libraryInstaller) { @@ -1257,8 +1257,8 @@ public class Base { } public void openBoardsManager(final String filterText, String dropdownItem) throws Exception { - if (selfCheckTimer != null) { - selfCheckTimer.cancel(); + if (contributionsSelfCheck != null) { + contributionsSelfCheck.cancel(); } @SuppressWarnings("serial") ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.indexer, contributionInstaller) { From a43757d5c3b7b343ecac9c4885441ef5dc5ef116 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Aug 2015 15:50:50 +0200 Subject: [PATCH 7/8] Update notification: UX feedback --- .../contributions/ContributionsSelfCheck.java | 8 +- .../cc/arduino/view/NotificationPopup.form | 84 +++++------------ .../cc/arduino/view/NotificationPopup.java | 91 ++++++------------- 3 files changed, 56 insertions(+), 127 deletions(-) diff --git a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java index 527b8e1ea..83491108e 100644 --- a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java +++ b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java @@ -59,11 +59,11 @@ public class ContributionsSelfCheck extends TimerTask { String text; if (updatableLibraries > 0 && updatablePlatforms <= 0) { - text = I18n.format(_("Some {0}libraries{1} may be updated"), "", ""); + text = I18n.format(_("
Update available for some of your {0}libraries{1}"), "", ""); } else if (updatableLibraries <= 0 && updatablePlatforms > 0) { - text = I18n.format(_("Some {0}boards{1} may be updated"), "", ""); + text = I18n.format(_("
Update available for some of your {0}boards{1}"), "", ""); } else { - text = I18n.format(_("Some {0}boards{1} and some {2}libraries{3} may be updated"), "", "", "", ""); + text = I18n.format(_("
Update available for some of your {0}boards{1} and {2}libraries{3}"), "", "", "", ""); } if (cancelled) { @@ -71,7 +71,7 @@ public class ContributionsSelfCheck extends TimerTask { } SwingUtilities.invokeLater(() -> { - notificationPopup = new NotificationPopup(base.getActiveEditor(), hyperlinkListener, _("Updates available"), text); + notificationPopup = new NotificationPopup(base.getActiveEditor(), hyperlinkListener, text); notificationPopup.setVisible(true); }); } diff --git a/app/src/cc/arduino/view/NotificationPopup.form b/app/src/cc/arduino/view/NotificationPopup.form index 48daea67e..5e6f68cc1 100644 --- a/app/src/cc/arduino/view/NotificationPopup.form +++ b/app/src/cc/arduino/view/NotificationPopup.form @@ -7,7 +7,13 @@ + + + + + + @@ -23,74 +29,24 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - + - - - - + + + + + @@ -103,6 +59,11 @@ + + + + + @@ -118,6 +79,11 @@ + + + + + diff --git a/app/src/cc/arduino/view/NotificationPopup.java b/app/src/cc/arduino/view/NotificationPopup.java index 7119672bd..8938afa38 100644 --- a/app/src/cc/arduino/view/NotificationPopup.java +++ b/app/src/cc/arduino/view/NotificationPopup.java @@ -29,7 +29,6 @@ package cc.arduino.view; -import cc.arduino.Constants; import processing.app.Base; import processing.app.BaseNoGui; @@ -43,9 +42,8 @@ import java.nio.file.Paths; public class NotificationPopup extends JDialog { private final ComponentAdapter parentMovedListener; - private final Timer autoCloseAfterTimeout; - public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, String titleText, String message) { + public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, String message) { super(parent, false); initComponents(); @@ -58,10 +56,15 @@ public class NotificationPopup extends JDialog { }; parent.addComponentListener(parentMovedListener); - title.setText(titleText); - text.setText("" + message.replace("\n", "
") + ""); + text.setText("" + message + ""); text.addHyperlinkListener(hyperlinkListener); + text.addHyperlinkListener(e -> { + if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { + return; + } + close(); + }); addWindowListener(new WindowAdapter() { @Override @@ -70,24 +73,17 @@ public class NotificationPopup extends JDialog { } }); - autoCloseAfterTimeout = new Timer(Constants.NOTIFICATION_POPUP_AUTOCLOSE_DELAY, (e) -> close()); - autoCloseAfterTimeout.start(); - - text.addHyperlinkListener(e -> { - if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { - return; - } - close(); - }); - Base.registerWindowCloseKeys(getRootPane(), e -> close()); - addMouseListener(new MouseAdapter() { + MouseAdapter closeOnClick = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { close(); } - }); + }; + addMouseListener(closeOnClick); + text.addMouseListener(closeOnClick); + icon.addMouseListener(closeOnClick); } private void updateLocation(Frame parent) { @@ -95,14 +91,10 @@ public class NotificationPopup extends JDialog { int parentX = Double.valueOf(parentLocation.getX()).intValue(); int parentY = Double.valueOf(parentLocation.getY()).intValue(); - setLocation(parentX + parent.getWidth() - getWidth(), parentY + parent.getHeight() - getHeight()); + setLocation(parentX, parentY + parent.getHeight() - getHeight()); } public void close() { - if (autoCloseAfterTimeout.isRunning()) { - autoCloseAfterTimeout.stop(); - } - dispatchEvent(new WindowEvent(NotificationPopup.this, WindowEvent.WINDOW_CLOSING)); } @@ -115,8 +107,7 @@ public class NotificationPopup extends JDialog { // //GEN-BEGIN:initComponents private void initComponents() { - title = new javax.swing.JLabel(); - javax.swing.JLabel jLabel1 = new javax.swing.JLabel(); + icon = new javax.swing.JLabel(); text = new javax.swing.JEditorPane(); closeButton = new javax.swing.JButton(); @@ -125,16 +116,21 @@ public class NotificationPopup extends JDialog { 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); - title.setFont(title.getFont().deriveFont(title.getFont().getStyle() | java.awt.Font.BOLD)); - - jLabel1.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "arduino_small.png").toFile().getAbsolutePath())); + 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); @@ -145,41 +141,8 @@ public class NotificationPopup extends JDialog { closeButtonActionPerformed(evt); } }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 264, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - .addGroup(layout.createSequentialGroup() - .addComponent(title, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(24, 24, 24) - .addComponent(closeButton)))) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(title)) - .addComponent(closeButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + getContentPane().add(closeButton); + closeButton.setBounds(328, 0, 22, 22); pack(); }// //GEN-END:initComponents @@ -196,7 +159,7 @@ public class NotificationPopup extends JDialog { /* Create and display the dialog */ EventQueue.invokeLater(new Runnable() { public void run() { - NotificationPopup dialog = new NotificationPopup(new JFrame(), System.out::println, "title", "test test test test test test test test test\n" + + NotificationPopup dialog = new NotificationPopup(new JFrame(), System.out::println, "test 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 @@ -211,8 +174,8 @@ public class NotificationPopup extends JDialog { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton closeButton; + private javax.swing.JLabel icon; private javax.swing.JEditorPane text; - private javax.swing.JLabel title; // End of variables declaration//GEN-END:variables } From 5b0ad4fadacbc30ed528cf805ca68d865c0a952d Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 5 Aug 2015 11:12:57 +0200 Subject: [PATCH 8/8] Switched to I18N.tr method (_ is deprecated) --- .../cc/arduino/contributions/ContributionsSelfCheck.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java index 83491108e..176049944 100644 --- a/app/src/cc/arduino/contributions/ContributionsSelfCheck.java +++ b/app/src/cc/arduino/contributions/ContributionsSelfCheck.java @@ -14,7 +14,7 @@ import javax.swing.*; import javax.swing.event.HyperlinkListener; import java.util.TimerTask; -import static processing.app.I18n._; +import static processing.app.I18n.tr; public class ContributionsSelfCheck extends TimerTask { @@ -59,11 +59,11 @@ public class ContributionsSelfCheck extends TimerTask { String text; if (updatableLibraries > 0 && updatablePlatforms <= 0) { - text = I18n.format(_("
Update available for some of your {0}libraries{1}"), "", ""); + text = I18n.format(tr("
Update available for some of your {0}libraries{1}"), "", ""); } else if (updatableLibraries <= 0 && updatablePlatforms > 0) { - text = I18n.format(_("
Update available for some of your {0}boards{1}"), "", ""); + text = I18n.format(tr("
Update available for some of your {0}boards{1}"), "", ""); } else { - text = I18n.format(_("
Update available for some of your {0}boards{1} and {2}libraries{3}"), "", "", "", ""); + text = I18n.format(tr("
Update available for some of your {0}boards{1} and {2}libraries{3}"), "", "", "", ""); } if (cancelled) {