From 85b2298ca7e796c18df1f5cc655bfd2ef44264dc Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 5 May 2015 13:03:28 +0200 Subject: [PATCH] When IDE is started and built in core is newer than installed one and this check hasn't been notified before, show "please update" modal --- .../BuiltInCoreIsNewerCheck.java | 86 +++++++++++++++++++ .../filters/InstalledLibraryPredicate.java | 8 +- .../contributions/ui/InstallerJDialog.java | 12 ++- app/src/processing/app/Base.java | 35 ++++++-- .../src/processing/app/BaseNoGui.java | 2 +- 5 files changed, 125 insertions(+), 18 deletions(-) create mode 100644 app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java diff --git a/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java b/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java new file mode 100644 index 000000000..9ccde3e40 --- /dev/null +++ b/app/src/cc/arduino/contributions/BuiltInCoreIsNewerCheck.java @@ -0,0 +1,86 @@ +package cc.arduino.contributions; + +import cc.arduino.contributions.filters.BuiltInPredicate; +import cc.arduino.contributions.filters.InstalledPredicate; +import cc.arduino.contributions.packages.ContributedPackage; +import cc.arduino.contributions.packages.ContributedPlatform; +import cc.arduino.view.Event; +import com.google.common.base.Function; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import processing.app.Base; +import processing.app.BaseNoGui; +import processing.app.I18n; +import processing.app.PreferencesData; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.util.LinkedList; +import java.util.List; + +import static processing.app.I18n._; + +public class BuiltInCoreIsNewerCheck implements Runnable { + + private final Base base; + + public BuiltInCoreIsNewerCheck(Base base) { + this.base = base; + } + + @Override + public void run() { + try { + builtInPackageIsNewerCheck(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void builtInPackageIsNewerCheck() throws InterruptedException { + if (PreferencesData.getInteger("builtin_platform_is_newer", -1) >= BaseNoGui.REVISION) { + return; + } + + LinkedList contributedPlatforms = Lists.newLinkedList(Iterables.concat(Collections2.transform(BaseNoGui.indexer.getPackages(), new Function>() { + @Override + public List apply(ContributedPackage input) { + return input.getPlatforms(); + } + }))); + + List installedBuiltInPlatforms = new LinkedList(Collections2.filter(contributedPlatforms, Predicates.and(new InstalledPredicate(), new BuiltInPredicate()))); + if (installedBuiltInPlatforms.size() != 1) { + return; + } + final ContributedPlatform installedBuiltIn = installedBuiltInPlatforms.get(0); + + ContributedPlatform installedNotBuiltIn = BaseNoGui.indexer.getInstalled(installedBuiltIn.getParentPackage().getName(), installedBuiltIn.getArchitecture()); + if (installedNotBuiltIn == null) { + return; + } + + while (!base.hasActiveEditor()) { + Thread.sleep(100); + } + + if (VersionHelper.valueOf(installedBuiltIn.getParsedVersion()).greaterThan(VersionHelper.valueOf(installedNotBuiltIn.getParsedVersion()))) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + PreferencesData.setInteger("builtin_platform_is_newer", BaseNoGui.REVISION); + assert base.hasActiveEditor(); + int chosenOption = JOptionPane.showConfirmDialog(base.getActiveEditor(), I18n.format(_("The IDE includes an updated {0} package, but you're using an older one.\nDo you want to upgrade {0}?"), installedBuiltIn.getName()), I18n.format(_("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); + } + } + }); + } + } +} diff --git a/app/src/cc/arduino/contributions/libraries/filters/InstalledLibraryPredicate.java b/app/src/cc/arduino/contributions/libraries/filters/InstalledLibraryPredicate.java index 76b351b7f..70132389c 100644 --- a/app/src/cc/arduino/contributions/libraries/filters/InstalledLibraryPredicate.java +++ b/app/src/cc/arduino/contributions/libraries/filters/InstalledLibraryPredicate.java @@ -29,6 +29,7 @@ package cc.arduino.contributions.libraries.filters; +import cc.arduino.contributions.filters.InstalledPredicate; import cc.arduino.contributions.libraries.ContributedLibrary; import cc.arduino.contributions.libraries.LibrariesIndex; import com.google.common.base.Predicate; @@ -50,12 +51,7 @@ public class InstalledLibraryPredicate implements Predicate return true; } - Collection installed = Collections2.filter(index.find(input.getName()), new Predicate() { - @Override - public boolean apply(ContributedLibrary input) { - return input.isInstalled(); - } - }); + Collection installed = Collections2.filter(index.find(input.getName()), new InstalledPredicate()); return !installed.isEmpty(); } diff --git a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java index e60a6c45b..ec456cbac 100644 --- a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java +++ b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java @@ -41,10 +41,7 @@ import javax.swing.border.EmptyBorder; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowEvent; +import java.awt.event.*; import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; @@ -280,6 +277,13 @@ public abstract class InstallerJDialog extends JDialog { } }; + public void setFilterText(String filterText) { + for (FocusListener listener : filterField.getFocusListeners()) { + listener.focusGained(new FocusEvent(filterField, FocusEvent.FOCUS_GAINED)); + } + filterField.setText(filterText); + } + /** * Action performed when the Cancel button is pressed. */ diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 8f0335fa4..da5185c00 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -22,7 +22,7 @@ package processing.app; -import cc.arduino.DefaultUncaughtExceptionHandler; +import cc.arduino.contributions.BuiltInCoreIsNewerCheck; import cc.arduino.contributions.DownloadableContributionVersionComparator; import cc.arduino.contributions.VersionHelper; import cc.arduino.contributions.libraries.ContributedLibrary; @@ -36,7 +36,8 @@ 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.SplashScreenHelper; +import cc.arduino.view.*; +import cc.arduino.view.Event; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; @@ -111,6 +112,7 @@ 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; static public void main(String args[]) throws Exception { System.setProperty("awt.useSystemAAFontSettings", "on"); @@ -446,6 +448,9 @@ public class Base { if (PreferencesData.getBoolean("update.check")) { new UpdateCheck(this); } + + new Thread(new BuiltInCoreIsNewerCheck(this)).start(); + } else if (parser.isNoOpMode()) { // Do nothing (intended for only changing preferences) System.exit(0); @@ -1265,7 +1270,7 @@ public class Base { rebuildExamplesMenu(Editor.examplesMenu); } - private void openInstallBoardDialog() throws Exception { + private void openInstallBoardDialog(final String filterText) throws Exception { // Create dialog for contribution manager @SuppressWarnings("serial") ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor) { @@ -1274,6 +1279,10 @@ public class Base { BaseNoGui.initPackages(); rebuildBoardsMenu(); setIndexer(BaseNoGui.indexer); + if (StringUtils.isNotEmpty(filterText)) { + setFilterText(filterText); + } + } }; managerUI.setLocationRelativeTo(activeEditor); @@ -1294,18 +1303,22 @@ public class Base { JMenu boardMenu = new JMenu(_("Board")); boardMenu.putClientProperty("removeOnWindowDeactivation", true); MenuScroller.setScrollerFor(boardMenu); - @SuppressWarnings("serial") - Action runInstaller = new AbstractAction(_("Boards Manager...")) { + + openBoardsManager = new AbstractAction(_("Boards Manager...")) { public void actionPerformed(ActionEvent actionevent) { + String filterText = ""; + if (actionevent instanceof cc.arduino.view.Event) { + filterText = ((Event) actionevent).getPayload().get("filterText").toString(); + } try { - openInstallBoardDialog(); + openInstallBoardDialog(filterText); } catch (Exception e) { //TODO show error e.printStackTrace(); } } }; - boardMenu.add(new JMenuItem(runInstaller)); + boardMenu.add(new JMenuItem(openBoardsManager)); boardsCustomMenus.add(boardMenu); // If there are no platforms installed we are done @@ -2700,7 +2713,15 @@ public class Base { return activeEditor; } + public boolean hasActiveEditor() { + return activeEditor != null; + } + public List getEditors() { return new LinkedList(editors); } + + public Action getOpenBoardsManager() { + return openBoardsManager; + } } diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java index 7d4ca1e71..5891e2998 100644 --- a/arduino-core/src/processing/app/BaseNoGui.java +++ b/arduino-core/src/processing/app/BaseNoGui.java @@ -64,7 +64,7 @@ public class BaseNoGui { static File portableFolder = null; static final String portableSketchbookFolder = "sketchbook"; - static ContributionsIndexer indexer; + public static ContributionsIndexer indexer; static LibrariesIndexer librariesIndexer; // Returns a File object for the given pathname. If the pathname