diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 8b2d9cd91..fe94c6f41 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5949,7 +5949,7 @@ public class PApplet implements PConstants { } /** - * @param options "compact" and "indent=N", replace N with the number of spaces + * @param options "compact" and "indent=N", replace N with the number of spaces */ public boolean saveJSONObject(JSONObject json, String filename, String options) { return json.save(saveFile(filename), options); @@ -6000,7 +6000,7 @@ public class PApplet implements PConstants { } /** - * @param options "compact" and "indent=N", replace N with the number of spaces + * @param options "compact" and "indent=N", replace N with the number of spaces */ public boolean saveJSONArray(JSONArray json, String filename, String options) { return json.save(saveFile(filename), options); @@ -6529,6 +6529,133 @@ public class PApplet implements PConstants { + ////////////////////////////////////////////////////////////// + + // LISTING DIRECTORIES + + + public String[] listPaths(String path, String... options) { + File[] list = listFiles(path, options); + + int offset = 0; + for (String opt : options) { + if (opt.equals("relative")) { + if (!path.endsWith(File.pathSeparator)) { + path += File.pathSeparator; + } + offset = path.length(); + break; + } + } + String[] outgoing = new String[list.length]; + for (int i = 0; i < list.length; i++) { + // as of Java 1.8, substring(0) returns the original object + outgoing[i] = list[i].getAbsolutePath().substring(offset); + } + return outgoing; + } + + + public File[] listFiles(String path, String... options) { + File file = new File(path); + // if not an absolute path, make it relative to the sketch folder + if (!file.isAbsolute()) { + file = sketchFile(path); + } + return listFiles(file, options); + } + + + // "relative" -> no effect with the Files version, but important for listPaths + // "recursive" + // "extension=js" or "extensions=js|csv|txt" (no dot) + // "directories" -> only directories + // "files" -> only files + // "hidden" -> include hidden files (prefixed with .) disabled by default + static public File[] listFiles(File base, String... options) { + boolean recursive = false; + String[] extensions = null; + boolean directories = true; + boolean files = true; + boolean hidden = false; + + for (String opt : options) { + if (opt.equals("recursive")) { + recursive = true; + } else if (opt.startsWith("extension=")) { + extensions = new String[] { opt.substring(10) }; + } else if (opt.startsWith("extensions=")) { + extensions = split(opt.substring(10), ','); + } else if (opt.equals("files")) { + directories = false; + } else if (opt.equals("directories")) { + files = false; + } else if (opt.equals("hidden")) { + hidden = true; + } else if (opt.equals("relative")) { + // ignored + } else { + throw new RuntimeException(opt + " is not a listFiles() option"); + } + } + + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + extensions[i] = "." + extensions[i]; + } + } + + if (!files && !directories) { + // just make "only files" and "only directories" mean... both + files = true; + directories = true; + } + + if (!base.canRead()) { + return null; + } + + List outgoing = new ArrayList<>(); + listFilesImpl(base, recursive, extensions, hidden, directories, files, outgoing); + return outgoing.toArray(new File[0]); + } + + + static void listFilesImpl(File folder, boolean recursive, + String[] extensions, boolean hidden, + boolean directories, boolean files, + List list) { + File[] items = folder.listFiles(); + if (items != null) { + for (File item : items) { + String name = item.getName(); + if (!hidden && name.charAt(0) == '.') { + continue; + } + if (item.isDirectory()) { + if (recursive) { + listFilesImpl(item, recursive, extensions, hidden, directories, files, list); + } + if (directories) { + list.add(item); + } + } else if (files) { + if (extensions == null) { + list.add(item); + } else { + for (String ext : extensions) { + if (item.getName().toLowerCase().endsWith(ext)) { + list.add(item); + } + } + } + } + } + } + } + + + ////////////////////////////////////////////////////////////// // EXTENSIONS diff --git a/core/todo.txt b/core/todo.txt index 66f63e15e..913d1798f 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,11 +1,15 @@ 0256 (3.2.4 or 3.3) X write exec() documentation X https://github.com/processing/processing/issues/4740 +X add listPaths(), listFiles() +X https://github.com/processing/processing/issues/4622 +_ needs documentation contribs X Adding missing docs and keywords for TableRow X https://github.com/processing/processing/pull/4333 +_ add increment() that takes IntDict to merge things _ add StringDict.Entry class for iterating _ TRIANGLE_STRIP not working correctly with createShape() and default renderer @@ -14,10 +18,6 @@ _ https://github.com/processing/processing/issues/4678 _ should we drop the 'default' prefix from the ex handler so it's not static? _ http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html -_ listPaths(), listFiles()? -_ https://github.com/processing/processing/issues/4622 -_ add increment() that takes IntDict to merge things - _ option to disable OpenGL ES on Linux? _ https://github.com/processing/processing/issues/4584