2828import java .awt .Frame ;
2929import java .awt .event .ActionEvent ;
3030import java .awt .event .ActionListener ;
31-
3231import java .io .*;
3332import java .text .SimpleDateFormat ;
3433import java .util .*;
4544
4645import processing .app .contrib .*;
4746import processing .core .*;
47+ import processing .data .StringDict ;
48+ import processing .data .StringList ;
4849
4950
5051/**
@@ -104,12 +105,9 @@ public class Base {
104105 PreferencesFrame preferencesFrame ;
105106
106107 // A single instance of the library manager window
107- ContributionManagerDialog libraryManagerFrame ;
108- ContributionManagerDialog toolManagerFrame ;
109- ContributionManagerDialog modeManagerFrame ;
110- ContributionManagerDialog exampleManagerFrame ;
111- ContributionManagerDialog updateManagerFrame ;
108+ ContributionManagerDialog contributionManagerFrame ;
112109
110+
113111 // Location for untitled items
114112 static File untitledFolder ;
115113
@@ -396,16 +394,8 @@ public Base(String[] args) throws Exception {
396394 }
397395 }
398396
399- libraryManagerFrame =
400- new ContributionManagerDialog (ContributionType .LIBRARY );
401- toolManagerFrame =
402- new ContributionManagerDialog (ContributionType .TOOL );
403- modeManagerFrame =
404- new ContributionManagerDialog (ContributionType .MODE );
405- exampleManagerFrame =
406- new ContributionManagerDialog (ContributionType .EXAMPLES );
407- updateManagerFrame =
408- new ContributionManagerDialog (null );
397+ contributionManagerFrame =
398+ new ContributionManagerDialog ();
409399
410400 // Make sure ThinkDifferent has library examples too
411401 nextMode .rebuildLibraryList ();
@@ -449,9 +439,7 @@ public Base(String[] args) throws Exception {
449439 }
450440
451441 // check for updates
452- if (Preferences .getBoolean ("update.check" )) { //$NON-NLS-1$
453- new UpdateCheck (this );
454- }
442+ new UpdateCheck (this );
455443 }
456444
457445
@@ -528,6 +516,60 @@ public List<ExamplesContribution> getExampleContribs() {
528516 }
529517
530518
519+ private List <Contribution > getInstalledContribs () {
520+ List <Contribution > contributions = new ArrayList <Contribution >();
521+
522+ List <ModeContribution > modeContribs = getModeContribs ();
523+ contributions .addAll (modeContribs );
524+
525+ for (ModeContribution modeContrib : modeContribs ) {
526+ Mode mode = modeContrib .getMode ();
527+ contributions .addAll (new ArrayList <Library >(mode .contribLibraries ));
528+ }
529+
530+ // TODO this duplicates code in Editor, but it's not editor-specific
531+ // List<ToolContribution> toolContribs =
532+ // ToolContribution.loadAll(Base.getSketchbookToolsFolder());
533+ // contributions.addAll(toolContribs);
534+ contributions .addAll (ToolContribution .loadAll (getSketchbookToolsFolder ()));
535+
536+ contributions .addAll (getExampleContribs ());
537+ return contributions ;
538+ }
539+
540+
541+ public byte [] getInstalledContribsInfo () {
542+ List <Contribution > contribs = getInstalledContribs ();
543+ StringList entries = new StringList ();
544+ for (Contribution c : contribs ) {
545+ String entry = c .getTypeName () + "=" +
546+ PApplet .urlEncode (String .format ("name=%s\n url=%s\n revision=%d\n version=%s" ,
547+ c .getName (), c .getUrl (),
548+ c .getVersion (), c .getPrettyVersion ()));
549+ entries .append (entry );
550+ }
551+ String joined =
552+ "id=" + Preferences .get ("update.id" ) + "&" + entries .join ("&" );
553+ // StringBuilder sb = new StringBuilder();
554+ // try {
555+ // // Truly ridiculous attempt to shove everything into a GET request.
556+ // // More likely to be seen as part of a grand plot.
557+ // ByteArrayOutputStream baos = new ByteArrayOutputStream();
558+ // GZIPOutputStream output = new GZIPOutputStream(baos);
559+ // PApplet.saveStream(output, new ByteArrayInputStream(joined.getBytes()));
560+ // output.close();
561+ // byte[] b = baos.toByteArray();
562+ // for (int i = 0; i < b.length; i++) {
563+ // sb.append(PApplet.hex(b[i], 2));
564+ // }
565+ // } catch (IOException e) {
566+ // e.printStackTrace();
567+ // }
568+ // return sb.toString();
569+ return joined .getBytes ();
570+ }
571+
572+
531573 // Because of variations in native windowing systems, no guarantees about
532574 // changes to the focused and active Windows can be made. Developers must
533575 // never assume that this Window is the focused or active Window until this
@@ -1415,36 +1457,36 @@ public void handlePrefs() {
14151457 * Show the library installer window.
14161458 */
14171459 public void handleOpenLibraryManager () {
1418- libraryManagerFrame .showFrame (activeEditor );
1460+ contributionManagerFrame .showFrame (activeEditor , ContributionType . LIBRARY );
14191461 }
14201462
14211463
14221464 /**
14231465 * Show the tool installer window.
14241466 */
14251467 public void handleOpenToolManager () {
1426- toolManagerFrame .showFrame (activeEditor );
1468+ contributionManagerFrame .showFrame (activeEditor , ContributionType . TOOL );
14271469 }
14281470
14291471
14301472 /**
14311473 * Show the mode installer window.
14321474 */
14331475 public void handleOpenModeManager () {
1434- modeManagerFrame .showFrame (activeEditor );
1476+ contributionManagerFrame .showFrame (activeEditor , ContributionType . MODE );
14351477 }
14361478
14371479
14381480 /**
14391481 * Show the examples installer window.
14401482 */
14411483 public void handleOpenExampleManager () {
1442- exampleManagerFrame .showFrame (activeEditor );
1484+ contributionManagerFrame .showFrame (activeEditor , ContributionType . EXAMPLES );
14431485 }
14441486
14451487
14461488 public void handleShowUpdates () {
1447- updateManagerFrame .showFrame (activeEditor );
1489+ contributionManagerFrame .showFrame (activeEditor , null );
14481490 }
14491491
14501492
@@ -2346,7 +2388,7 @@ static public byte[] loadBytesRaw(File file) throws IOException {
23462388 * Changed in 3.0a6 to return null (rather than empty hash) if no file,
23472389 * and changed return type to Map instead of HashMap.
23482390 */
2349- static public Map < String , String > readSettings (File inputFile ) {
2391+ static public StringDict readSettings (File inputFile ) {
23502392 if (!inputFile .exists ()) {
23512393 if (DEBUG ) System .err .println (inputFile + " does not exist." );
23522394 return null ;
@@ -2364,13 +2406,13 @@ static public Map<String, String> readSettings(File inputFile) {
23642406 * Parse a String array that contains attribute/value pairs separated
23652407 * by = (the equals sign). The # (hash) symbol is used to denote comments.
23662408 * Comments can be anywhere on a line. Blank lines are ignored.
2367- * In 3.0a6, no longer taking a blank HahMap as param; no cases in the main
2409+ * In 3.0a6, no longer taking a blank HashMap as param; no cases in the main
23682410 * PDE code of adding to a (Hash)Map. Also returning the Map instead of void.
23692411 * Both changes modify the method signature, but this was only used by the
23702412 * contrib classes.
23712413 */
2372- static public Map < String , String > readSettings (String filename , String [] lines ) {
2373- Map < String , String > settings = new HashMap <> ();
2414+ static public StringDict readSettings (String filename , String [] lines ) {
2415+ StringDict settings = new StringDict ();
23742416 for (String line : lines ) {
23752417 // Remove comments
23762418 int commentMarker = line .indexOf ('#' );
@@ -2390,7 +2432,7 @@ static public Map<String, String> readSettings(String filename, String[] lines)
23902432 } else {
23912433 String attr = line .substring (0 , equals ).trim ();
23922434 String valu = line .substring (equals + 1 ).trim ();
2393- settings .put (attr , valu );
2435+ settings .set (attr , valu );
23942436 }
23952437 }
23962438 }
@@ -2745,8 +2787,9 @@ static public String contentsToClassPath(File folder) {
27452787 * @param path the input classpath
27462788 * @return array of possible package names
27472789 */
2748- static public String [] packageListFromClassPath (String path ) {
2749- Map <String , Object > map = new HashMap <String , Object >();
2790+ static public StringList packageListFromClassPath (String path ) {
2791+ // Map<String, Object> map = new HashMap<String, Object>();
2792+ StringList list = new StringList ();
27502793 String pieces [] =
27512794 PApplet .split (path , File .pathSeparatorChar );
27522795
@@ -2757,32 +2800,35 @@ static public String[] packageListFromClassPath(String path) {
27572800 if (pieces [i ].toLowerCase ().endsWith (".jar" ) ||
27582801 pieces [i ].toLowerCase ().endsWith (".zip" )) {
27592802 //System.out.println("checking " + pieces[i]);
2760- packageListFromZip (pieces [i ], map );
2803+ packageListFromZip (pieces [i ], list );
27612804
27622805 } else { // it's another type of file or directory
27632806 File dir = new File (pieces [i ]);
27642807 if (dir .exists () && dir .isDirectory ()) {
2765- packageListFromFolder (dir , null , map );
2808+ packageListFromFolder (dir , null , list );
27662809 //importCount = magicImportsRecursive(dir, null,
27672810 // map);
27682811 //imports, importCount);
27692812 }
27702813 }
27712814 }
2772- int mapCount = map .size ();
2773- String output [] = new String [mapCount ];
2774- int index = 0 ;
2775- Set <String > set = map .keySet ();
2776- for (String s : set ) {
2777- output [index ++] = s .replace ('/' , '.' );
2815+ // int mapCount = map.size();
2816+ // String output[] = new String[mapCount];
2817+ // int index = 0;
2818+ // Set<String> set = map.keySet();
2819+ // for (String s : set) {
2820+ // output[index++] = s.replace('/', '.');
2821+ // }
2822+ // return output;
2823+ StringList outgoing = new StringList (list .size ());
2824+ for (String item : list ) {
2825+ outgoing .append (item .replace ('/' , '.' ));
27782826 }
2779- //System.arraycopy(imports, 0, output, 0, importCount);
2780- //PApplet.printarr(output);
2781- return output ;
2827+ return outgoing ;
27822828 }
27832829
27842830
2785- static private void packageListFromZip (String filename , Map < String , Object > map ) {
2831+ static private void packageListFromZip (String filename , StringList list ) {
27862832 try {
27872833 ZipFile file = new ZipFile (filename );
27882834 Enumeration entries = file .entries ();
@@ -2797,9 +2843,10 @@ static private void packageListFromZip(String filename, Map<String, Object> map)
27972843 if (slash == -1 ) continue ;
27982844
27992845 String pname = name .substring (0 , slash );
2800- if (map .get (pname ) == null ) {
2801- map .put (pname , new Object ());
2802- }
2846+ // if (map.get(pname) == null) {
2847+ // map.put(pname, new Object());
2848+ // }
2849+ list .appendUnique (pname );
28032850 }
28042851 }
28052852 }
@@ -2818,10 +2865,8 @@ static private void packageListFromZip(String filename, Map<String, Object> map)
28182865 * walk down into that folder and continue.
28192866 */
28202867 static private void packageListFromFolder (File dir , String sofar ,
2821- Map <String , Object > map ) {
2822- //String imports[],
2823- //int importCount) {
2824- //System.err.println("checking dir '" + dir + "'");
2868+ StringList list ) {
2869+ // Map<String, Object> map) {
28252870 boolean foundClass = false ;
28262871 String files [] = dir .list ();
28272872
@@ -2832,15 +2877,16 @@ static private void packageListFromFolder(File dir, String sofar,
28322877 if (sub .isDirectory ()) {
28332878 String nowfar =
28342879 (sofar == null ) ? files [i ] : (sofar + "." + files [i ]);
2835- packageListFromFolder (sub , nowfar , map );
2880+ packageListFromFolder (sub , nowfar , list );
28362881 //System.out.println(nowfar);
28372882 //imports[importCount++] = nowfar;
28382883 //importCount = magicImportsRecursive(sub, nowfar,
28392884 // imports, importCount);
28402885 } else if (!foundClass ) { // if no classes found in this folder yet
28412886 if (files [i ].endsWith (".class" )) {
28422887 //System.out.println("unique class: " + files[i] + " for " + sofar);
2843- map .put (sofar , new Object ());
2888+ // map.put(sofar, new Object());
2889+ list .appendUnique (sofar );
28442890 foundClass = true ;
28452891 }
28462892 }
0 commit comments