diff --git a/app/src/processing/app/contrib/ContributionManager.java b/app/src/processing/app/contrib/ContributionManager.java index 1e00eb2f6..17c21ba6a 100644 --- a/app/src/processing/app/contrib/ContributionManager.java +++ b/app/src/processing/app/contrib/ContributionManager.java @@ -197,7 +197,10 @@ public class ContributionManager { /** * Non-blocking call to download and install a contribution in a new thread. - * + * Used when information about the progress of the download and install + * procedure is not of importance, such as if a contribution has to be + * installed at startup time. + * * @param url * Direct link to the contribution. * @param ad @@ -292,6 +295,92 @@ public class ContributionManager { } + /** + * Blocking call to download and install a set of libraries. Used when a list + * of libraries have to be installed while forcing the user to not modify + * anything and providing feedback via the console status area, such as when + * the user tries to run a sketch that imports uninstaled libraries. + * + * @param aList + * The list of AvailableContributions to be downloaded and installed. + */ + public static void downloadAndInstallOnImport(final Base base, + final ArrayList aList) { + + // To avoid the user from modifying stuff, since this function is only called + // during pre-processing + base.getActiveEditor().getTextArea().setEditable(false); + base.getActiveEditor().getConsole().clear(); + + ArrayList installedLibList = new ArrayList(); + + for (AvailableContribution ad : aList) { + if (ad.getType() != ContributionType.LIBRARY) + continue; + try { + URL url = new URL(ad.link); + String filename = url.getFile(); + filename = filename.substring(filename.lastIndexOf('/') + 1); + try { + + File contribZip = File.createTempFile("download", filename); + contribZip.setWritable(true); + + try { + // Use the console to let the user know what's happening + // The slightly complex if-else is required to let the user know when + // one install is completed and the next download has begun without + // interfereing with occur status messages that may arise in the meanwhile + String statusMsg = base.getActiveEditor().getStatusMessage(); + if (statusMsg.contains("has been installed")) + base.getActiveEditor().statusNotice(statusMsg + " " + + "Now downloading " + + ad.name); + else + base.getActiveEditor().statusNotice("Downloading " + ad.name + + "..."); + + download(url, contribZip, null); + + base.getActiveEditor() + .statusNotice("Installing " + ad.name + "..."); + LocalContribution contribution = ad.install(base, contribZip, + false, null); + + if (contribution != null) { + contribListing.replaceContribution(ad, contribution); + if (base.getActiveEditor() != null) + refreshInstalled(base.getActiveEditor()); + } + + contribZip.delete(); + + installedLibList.add(ad.name); + base.getActiveEditor().statusNotice(ad.name + + " has been installed."); + + } catch (Exception e) { + System.out.println("Error during download and install of " + + ad.getName()); + } + } catch (IOException e) { + System.err + .println("Could not write to temporary directory during download and install of " + + ad.getName()); + } + } catch (MalformedURLException e1) { + System.err.println("Error: The library " + ad.getName() + + " has a weird looking download link."); + } + } + base.getActiveEditor().getTextArea().setEditable(true); + base.getActiveEditor().statusEmpty(); + System.out.println("The following libraries have been installed:"); + for (String l : installedLibList) { + System.out.println(l); + } + } + static public void refreshInstalled(Editor e) { Iterator iter = e.getBase().getEditors().iterator(); diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index a77d7d945..95a38ad12 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -26,6 +26,7 @@ import processing.app.Toolkit; import processing.app.contrib.AvailableContribution; import processing.app.contrib.Contribution; import processing.app.contrib.ContributionListing; +import processing.app.contrib.ContributionManager; import processing.app.contrib.ToolContribution; import processing.app.syntax.JEditTextArea; import processing.app.syntax.PdeTextAreaDefaults; @@ -1872,9 +1873,11 @@ public class JavaEditor extends Editor { for (String[] importStatement : pieces) { importHeaders.add(importStatement[2]); } - ArrayList installLibsHeaders = getNotInstalledAvailableLibs(importHeaders); - for (Contribution c : installLibsHeaders) - System.out.println(c.getName()); + ArrayList installLibsHeaders = getNotInstalledAvailableLibs(importHeaders); + if (!installLibsHeaders.isEmpty()) { + ContributionManager.downloadAndInstallOnImport(base, + installLibsHeaders); + } } } } @@ -1885,9 +1888,9 @@ public class JavaEditor extends Editor { * but that are not installed. * @param importHeaders */ - private ArrayList getNotInstalledAvailableLibs(ArrayList importHeadersList) { + private ArrayList getNotInstalledAvailableLibs(ArrayList importHeadersList) { Map importMap = ContributionListing.getInstance().librariesByImportHeader; - ArrayList libList = new ArrayList(); + ArrayList libList = new ArrayList(); for (String importHeaders : importHeadersList) { int dot = importHeaders.lastIndexOf('.'); String entry = (dot == -1) ? importHeaders : importHeaders.substring(0, @@ -1903,14 +1906,14 @@ public class JavaEditor extends Editor { library = this.getMode().getLibrary(entry); if (library == null) { Contribution c = importMap.get(importHeaders); - if (c!=null) - libList.add(c);//System.out.println(importHeaders + "not found"); + if (c!=null && c instanceof AvailableContribution) + libList.add((AvailableContribution)c);//System.out.println(importHeaders + "not found"); } } catch (Exception e) { // Not gonna happen (hopefully) Contribution c = importMap.get(importHeaders); - if (c!=null) - libList.add(c);//System.out.println(importHeaders + "not found"); + if (c!=null && c instanceof AvailableContribution) + libList.add((AvailableContribution)c);//System.out.println(importHeaders + "not found"); } } return libList;