From 162cbf69d040a96154a84bd5b66702fc143409be Mon Sep 17 00:00:00 2001 From: benfry Date: Sat, 28 Jul 2012 18:45:52 +0000 Subject: [PATCH] use new file choosers, and swap what is used on Linux (issue #1014) --- app/src/processing/app/Base.java | 176 ++++++++++++------ app/src/processing/app/Preferences.java | 22 ++- app/src/processing/app/Sketch.java | 41 ++-- app/src/processing/app/tools/Archiver.java | 20 +- .../processing/mode/android/AndroidSDK.java | 22 +-- build/shared/lib/preferences.txt | 5 + build/shared/revisions.txt | 21 +++ todo.txt | 4 +- 8 files changed, 203 insertions(+), 108 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 38aeb75ed..d9aff3945 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -902,21 +902,18 @@ public class Base { * Prompt for a sketch to open, and open it in a new window. */ public void handleOpenPrompt() { - // get the frontmost window frame for placing file dialog - FileDialog fd = new FileDialog(activeEditor, - "Open a Processing sketch...", - FileDialog.LOAD); - // This was annoying people, so disabled it in 0125. - //fd.setDirectory(Preferences.get("sketchbook.path")); - //fd.setDirectory(getSketchbookPath()); - final ArrayList extensions = new ArrayList(); for (Mode mode : getModeList()) { extensions.add(mode.getDefaultExtension()); } - // Only show .pde files as eligible bachelors - fd.setFilenameFilter(new FilenameFilter() { + final String prompt = "Open a Processing sketch..."; + if (Preferences.getBoolean("chooser.files.native")) { // don't use native dialogs on Linux + // get the front-most window frame for placing file dialog + FileDialog fd = new FileDialog(activeEditor, prompt, FileDialog.LOAD); + + // Only show .pde files as eligible bachelors + fd.setFilenameFilter(new FilenameFilter() { public boolean accept(File dir, String name) { // confirmed to be working properly [fry 110128] for (String ext : extensions) { @@ -928,16 +925,37 @@ public class Base { } }); - fd.setVisible(true); + fd.setVisible(true); - String directory = fd.getDirectory(); - String filename = fd.getFile(); + String directory = fd.getDirectory(); + String filename = fd.getFile(); + if (filename != null) { + File inputFile = new File(directory, filename); + handleOpen(inputFile.getAbsolutePath()); + } - // User canceled selection - if (filename == null) return; + } else { + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle(prompt); - File inputFile = new File(directory, filename); - handleOpen(inputFile.getAbsolutePath()); + fc.setFileFilter(new javax.swing.filechooser.FileFilter() { + public boolean accept(File file) { + for (String ext : extensions) { + if (file.getName().toLowerCase().endsWith("." + ext)) { + return true; + } + } + return false; + } + + public String getDescription() { + return "Processing Sketch"; + } + }); + if (fc.showOpenDialog(activeEditor) == JFileChooser.APPROVE_OPTION) { + handleOpen(fc.getSelectedFile().getAbsolutePath()); + } + } } @@ -1935,8 +1953,17 @@ public class Base { static protected File promptSketchbookLocation() { // Most often this will happen on Linux, so default to their home dir. File folder = new File(System.getProperty("user.home"), "sketchbook"); - String prompt = "Select (or create new) folder for sketches..."; - folder = Base.selectFolder(prompt, folder, null); + String prompt = "Select a folder to place sketches..."; + +// FolderSelector fs = new FolderSelector(prompt, folder, new Frame()); +// folder = fs.getFolder(); + folder = Base.selectFolder(prompt, folder, new Frame()); + +// folder = Base.selectFolder(prompt, folder, null); +// PApplet.selectFolder(prompt, +// "promptSketchbookCallback", dflt, +// Preferences.this, dialog); + if (folder == null) { System.exit(0); } @@ -1997,45 +2024,84 @@ public class Base { // ................................................................. +// /** +// * Prompt for a folder and return it as a File object (or null). +// * Implementation for choosing directories that handles both the +// * Mac OS X hack to allow the native AWT file dialog, or uses +// * the JFileChooser on other platforms. Mac AWT trick obtained from +// * this post +// * on the OS X Java dev archive which explains the cryptic note in +// * Apple's Java 1.4 release docs about the special System property. +// */ +// static public File selectFolder(String prompt, File folder, Frame frame) { +// if (Base.isMacOS()) { +// if (frame == null) frame = new Frame(); //.pack(); +// FileDialog fd = new FileDialog(frame, prompt, FileDialog.LOAD); +// if (folder != null) { +// fd.setDirectory(folder.getParent()); +// //fd.setFile(folder.getName()); +// } +// System.setProperty("apple.awt.fileDialogForDirectories", "true"); +// fd.setVisible(true); +// System.setProperty("apple.awt.fileDialogForDirectories", "false"); +// if (fd.getFile() == null) { +// return null; +// } +// return new File(fd.getDirectory(), fd.getFile()); +// +// } else { +// JFileChooser fc = new JFileChooser(); +// fc.setDialogTitle(prompt); +// if (folder != null) { +// fc.setSelectedFile(folder); +// } +// fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); +// +// int returned = fc.showOpenDialog(new JDialog()); +// if (returned == JFileChooser.APPROVE_OPTION) { +// return fc.getSelectedFile(); +// } +// } +// return null; +// } + + + static class FolderSelector { + File folder; + boolean ready; + + FolderSelector(String prompt, File defaultFile, Frame parentFrame) { + PApplet.selectFolder(prompt, "callback", defaultFile, this, parentFrame); + } + + public void callback(File folder) { + this.folder = folder; + ready = true; + } + + boolean isReady() { + return ready; + } + + /** block until the folder is available */ + File getFolder() { + while (!ready) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { } + } + return folder; + } + } + + /** - * Prompt for a fodler and return it as a File object (or null). - * Implementation for choosing directories that handles both the - * Mac OS X hack to allow the native AWT file dialog, or uses - * the JFileChooser on other platforms. Mac AWT trick obtained from - * this post - * on the OS X Java dev archive which explains the cryptic note in - * Apple's Java 1.4 release docs about the special System property. + * Blocking version of folder selection. Runs and sleeps until an answer + * comes back. Avoid using: try to make things work with the async + * selectFolder inside PApplet instead. */ static public File selectFolder(String prompt, File folder, Frame frame) { - if (Base.isMacOS()) { - if (frame == null) frame = new Frame(); //.pack(); - FileDialog fd = new FileDialog(frame, prompt, FileDialog.LOAD); - if (folder != null) { - fd.setDirectory(folder.getParent()); - //fd.setFile(folder.getName()); - } - System.setProperty("apple.awt.fileDialogForDirectories", "true"); - fd.setVisible(true); - System.setProperty("apple.awt.fileDialogForDirectories", "false"); - if (fd.getFile() == null) { - return null; - } - return new File(fd.getDirectory(), fd.getFile()); - - } else { - JFileChooser fc = new JFileChooser(); - fc.setDialogTitle(prompt); - if (folder != null) { - fc.setSelectedFile(folder); - } - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - - int returned = fc.showOpenDialog(new JDialog()); - if (returned == JFileChooser.APPROVE_OPTION) { - return fc.getSelectedFile(); - } - } - return null; + return new FolderSelector(prompt, folder, frame).getFolder(); } diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 7dbf0be2d..dc2bfd327 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -200,6 +200,8 @@ public class Preferences { } } } + + PApplet.useNativeSelect = Preferences.getBoolean("chooser.files.native"); } @@ -240,11 +242,14 @@ public class Preferences { button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { File dflt = new File(sketchbookLocationField.getText()); - File file = - Base.selectFolder("Select new sketchbook location", dflt, dialog); - if (file != null) { - sketchbookLocationField.setText(file.getAbsolutePath()); - } + PApplet.selectFolder("Select new sketchbook location", + "sketchbookCallback", dflt, + Preferences.this, dialog); +// File file = +// Base.selectFolder("Select new sketchbook location", dflt, dialog); +// if (file != null) { +// sketchbookLocationField.setText(file.getAbsolutePath()); +// } } }); pain.add(button); @@ -521,6 +526,13 @@ public class Preferences { } + public void sketchbookCallback(File file) { + if (file != null) { + sketchbookLocationField.setText(file.getAbsolutePath()); + } + } + + public Dimension getPreferredSize() { return new Dimension(wide, high); } diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 94e0898af..d8316b3a6 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -703,12 +703,26 @@ public class Sketch { protected boolean saveAs() throws IOException { String newParentDir = null; String newName = null; - - if (false) { - // The Swing file chooser has some upside (i.e. fixes an OS X focus - // traversal bug) but is super ugly and not OS native. + // TODO rewrite this to use shared version from PApplet + final String PROMPT = "Save sketch folder as..."; + if (Preferences.getBoolean("chooser.files.native")) { + // get new name for folder + FileDialog fd = new FileDialog(editor, PROMPT, FileDialog.SAVE); + if (isReadOnly() || isUntitled()) { + // default to the sketchbook folder + fd.setDirectory(Preferences.get("sketchbook.path")); + } else { + // default to the parent folder of where this was + fd.setDirectory(folder.getParent()); + } + String oldName = folder.getName(); + fd.setFile(oldName); + fd.setVisible(true); + newParentDir = fd.getDirectory(); + newName = fd.getFile(); + } else { JFileChooser fc = new JFileChooser(); - fc.setDialogTitle("Save sketch folder as..."); + fc.setDialogTitle(PROMPT); if (isReadOnly() || isUntitled()) { // default to the sketchbook folder fc.setCurrentDirectory(new File(Preferences.get("sketchbook.path"))); @@ -724,23 +738,6 @@ public class Sketch { newParentDir = selection.getParent(); newName = selection.getName(); } - } else { - // get new name for folder - FileDialog fd = new FileDialog(editor, - "Save sketch folder as...", - FileDialog.SAVE); - if (isReadOnly() || isUntitled()) { - // default to the sketchbook folder - fd.setDirectory(Preferences.get("sketchbook.path")); - } else { - // default to the parent folder of where this was - fd.setDirectory(folder.getParent()); - } - String oldName = folder.getName(); - fd.setFile(oldName); - fd.setVisible(true); - newParentDir = fd.getDirectory(); - newName = fd.getFile(); } // user canceled selection diff --git a/app/src/processing/app/tools/Archiver.java b/app/src/processing/app/tools/Archiver.java index a760dd79f..78e2564aa 100755 --- a/app/src/processing/app/tools/Archiver.java +++ b/app/src/processing/app/tools/Archiver.java @@ -24,8 +24,8 @@ package processing.app.tools; import processing.app.*; +import processing.core.PApplet; -import java.awt.FileDialog; import java.io.*; import java.text.*; import java.util.*; @@ -95,26 +95,20 @@ public class Archiver implements Tool { } while (newbie.exists()); // open up a prompt for where to save this fella - FileDialog fd = - new FileDialog(editor, "Archive sketch as:", FileDialog.SAVE); - fd.setDirectory(parent.getAbsolutePath()); - fd.setFile(newbie.getName()); - fd.setVisible(true); + PApplet.selectOutput("Archive sketch as...", "fileSelected", newbie, this, editor); + } - String directory = fd.getDirectory(); - String filename = fd.getFile(); - - // only write the file if not canceled - if (filename != null) { - newbie = new File(directory, filename); + public void fileSelected(File newbie) { + if (newbie != null) { try { //System.out.println(newbie); FileOutputStream zipOutputFile = new FileOutputStream(newbie); ZipOutputStream zos = new ZipOutputStream(zipOutputFile); // recursively fill the zip file - buildZip(location, name, zos); + File sketchFolder = editor.getSketch().getFolder(); + buildZip(sketchFolder, sketchFolder.getName(), zos); // close up the jar file zos.flush(); diff --git a/app/src/processing/mode/android/AndroidSDK.java b/app/src/processing/mode/android/AndroidSDK.java index 541f498dc..7d3c3cd53 100644 --- a/app/src/processing/mode/android/AndroidSDK.java +++ b/app/src/processing/mode/android/AndroidSDK.java @@ -77,23 +77,23 @@ class AndroidSDK { path = new File(javaHome, "bin").getCanonicalPath() + File.pathSeparator + path; p.setenv("PATH", path); - + checkDebugCertificate(); } - - + + /** * If a debug certificate exists, check its expiration date. If it's expired, * remove it so that it doesn't cause problems during the build. */ - protected void checkDebugCertificate() { + protected void checkDebugCertificate() { File dotAndroidFolder = new File(System.getProperty("user.home"), ".android"); File keystoreFile = new File(dotAndroidFolder, "debug.keystore"); if (keystoreFile.exists()) { // keytool -list -v -storepass android -keystore debug.keystore - ProcessHelper ph = new ProcessHelper(new String[] { - "keytool", "-list", "-v", - "-storepass", "android", + ProcessHelper ph = new ProcessHelper(new String[] { + "keytool", "-list", "-v", + "-storepass", "android", "-keystore", keystoreFile.getAbsolutePath() }); try { @@ -106,7 +106,7 @@ class AndroidSDK { if (m != null) { String timestamp = m[1].trim(); // "Sun Jan 22 11:09:08 EST 2012" - // Hilariously, this is the format of Date.toString(), however + // Hilariously, this is the format of Date.toString(), however // it isn't the default for SimpleDateFormat or others. Yay! DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); try { @@ -230,9 +230,9 @@ class AndroidSDK { } return null; } - - - static public AndroidSDK locate(final Frame window) + + + static public AndroidSDK locate(final Frame window) throws BadSDKException, IOException { final int result = Base.showYesNoQuestion(window, "Android SDK", ANDROID_SDK_PRIMARY, ANDROID_SDK_SECONDARY); diff --git a/build/shared/lib/preferences.txt b/build/shared/lib/preferences.txt index 7a3adcd42..c8c94631b 100755 --- a/build/shared/lib/preferences.txt +++ b/build/shared/lib/preferences.txt @@ -68,6 +68,11 @@ contribution.backup.on_install = true recent.count = 10 +# Default to the native (AWT) file selector where possible +chooser.files.native = true +# native Linux file chooser is atrocious, use Swing instead +chooser.files.native.linux = false + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 0c53a96f7..88dd882f2 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,24 @@ +PROCESSING 2.0a7 (REV 0206) - 28 July 2012 + +[ changes ] + ++ Major changes to selectInput(), selectOutput(), and selectFolder(). + See the Wiki: http://wiki.processing.org/w/Changes#Change_and_Removed + The changes are there to prevent a threading bug: + http://code.google.com/p/processing/issues/detail?id=173 + http://code.google.com/p/processing/issues/detail?id=931 + And also include an option to set the default file path: + http://code.google.com/p/processing/issues/detail?id=233 + ++ Use Swing file choosers by default on Linux. The default open/save + dialogs provided by Java are pretty gruesome, so we're switching to + the Swing JFileChooser instead. To swap the behavior, set + 'chooser.files.native' in your preferences.txt file. + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 2.0a6 (REV 0205) - 1 June 2012 Lots of changes since the last update as we move closer to beta. diff --git a/todo.txt b/todo.txt index ab30bc247..c5b655b68 100644 --- a/todo.txt +++ b/todo.txt @@ -32,9 +32,9 @@ o examples button on toolbar? open / recent / sketchbook? X switch to using a warning dialog when bits aren't available X http://code.google.com/p/processing/issues/detail?id=884 X suppress XInitThreads message on Linux with JOGL +X Linux file chooser is gross (presumably Windows too) +X http://code.google.com/p/processing/issues/detail?id=1014 -_ Linux file chooser is gross (presumably Windows too) -_ http://code.google.com/p/processing/issues/detail?id=1014 _ Linux sketchbook selector wasn't working properly at all o don't use tmp folder for sketches?