From 5dd60c1343e91e4a6a5ba6f66a8f956e9628f2cc Mon Sep 17 00:00:00 2001 From: benfry Date: Mon, 23 Jul 2012 19:14:35 +0000 Subject: [PATCH] finish recent sketches menu, remove confusing new/open behavior --- app/src/processing/app/Base.java | 301 +++++++++--------- app/src/processing/app/Recent.java | 27 +- .../mode/android/AndroidToolbar.java | 29 +- app/src/processing/mode/java/JavaToolbar.java | 30 +- .../mode/javascript/JavaScriptToolbar.java | 38 +-- todo.txt | 22 +- 6 files changed, 229 insertions(+), 218 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 9e6e7e967..0476a12a1 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -155,14 +155,14 @@ public class Base { initPlatform(); - // Use native popups so they don't look so crappy on osx + // Use native popups so they don't look so crappy on OS X JPopupMenu.setDefaultLightWeightPopupEnabled(false); // Don't put anything above this line that might make GUI, // because the platform has to be inited properly first. // Make sure a full JDK is installed -// initRequirements(); + initRequirements(); // run static initialization that grabs all the prefs Preferences.init(null); @@ -234,14 +234,21 @@ public class Base { Class.forName("com.sun.jdi.VirtualMachine"); } catch (ClassNotFoundException cnfe) { //String cp = System.getProperty("java.class.path").replace(File.pathSeparatorChar, '\n'); - String cp = System.getProperty("sun.boot.class.path").replace(File.pathSeparatorChar, '\n'); +// String cp = System.getProperty("sun.boot.class.path").replace(File.pathSeparatorChar, '\n'); Base.openURL("http://wiki.processing.org/w/Supported_Platforms"); - Base.showError("Please install JDK 1.6 or later", - "Processing requires a full JDK (not just a JRE)\n" + - "to run. Please install JDK 1.6 or later.\n" + - "More information can be found in the reference." + - "\n\n" + cp, cnfe); +// Base.showError("Please install JDK 1.6 or later", +// "Processing requires a full JDK (not just a JRE)\n" + +// "to run. Please install JDK 1.6 or later.\n" + +// "More information can be found on the Wiki." + +// "\n\nJAVA_HOME is currently\n" + +// System.getProperty("java.home") + "\n" + +// "And the CLASSPATH contains\n" + cp, cnfe); + Base.showError("Missing required files", + "Processing requires a JRE with tools.jar (or a\n" + + "full JDK) installed in (or linked to) a folder\n" + + "named “java” next to the Processing application.\n" + + "More information can be found on the Wiki.", cnfe); } } @@ -279,12 +286,12 @@ public class Base { } public Base(String[] args) { - recent = new Recent(this); -// recentMenu = recent.createMenu(); - // Get the sketchbook path, and make sure it's set properly determineSketchbookFolder(); + // Needs to happen after the sketchbook folder has been located + recent = new Recent(this); + // Delete all modes and tools that have been flagged for deletion before // they are initialized by an editor. ArrayList contribs = new ArrayList(); @@ -660,10 +667,7 @@ public class Base { handleClose(activeEditor, true); // re-open the sketch - Editor editor = handleOpen(mainPath, state); - if (editor != null) { - editor.untitled = untitled; - } + /*Editor editor =*/ handleOpen(mainPath, untitled, state); } } } @@ -757,148 +761,132 @@ public class Base { "jul", "aug", "sep", "oct", "nov", "dec" }; - /** - * Handle creating a sketch folder, return its base .pde file - * or null if the operation was canceled. - * @param shift whether shift is pressed, which will invert prompt setting - * @param noPrompt disable prompt, no matter the setting - */ - protected String createNewUntitled() throws IOException { - File newbieDir = null; - String newbieName = null; - - // In 0126, untitled sketches will begin in the temp folder, - // and then moved to a new location because Save will default to Save As. -// File sketchbookDir = getSketchbookFolder(); - File newbieParentDir = untitledFolder; - - String prefix = Preferences.get("editor.untitled.prefix"); - - // Use a generic name like sketch_031008a, the date plus a char - int index = 0; - String format = Preferences.get("editor.untitled.suffix"); - String suffix = null; - if (format == null) { - Calendar cal = Calendar.getInstance(); - int day = cal.get(Calendar.DAY_OF_MONTH); // 1..31 - int month = cal.get(Calendar.MONTH); // 0..11 - suffix = months[month] + PApplet.nf(day, 2); - } else { - //SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd"); - //SimpleDateFormat formatter = new SimpleDateFormat("MMMdd"); - //String purty = formatter.format(new Date()).toLowerCase(); - SimpleDateFormat formatter = new SimpleDateFormat(format); - suffix = formatter.format(new Date()); - } - do { - if (index == 26) { - // In 0159, avoid running past z by sending people outdoors. - if (!breakTime) { - Base.showWarning("Time for a Break", - "You've reached the limit for auto naming of new sketches\n" + - "for the day. How about going for a walk instead?", null); - breakTime = true; - } else { - Base.showWarning("Sunshine", - "No really, time for some fresh air for you.", null); - } - return null; - } - newbieName = prefix + suffix + ((char) ('a' + index)); - // Also sanitize the name since it might do strange things on - // non-English systems that don't use this sort of date format. - // http://code.google.com/p/processing/issues/detail?id=283 - newbieName = Sketch.sanitizeName(newbieName); - newbieDir = new File(newbieParentDir, newbieName); - index++; - // Make sure it's not in the temp folder *and* it's not in the sketchbook - } while (newbieDir.exists() || new File(sketchbookFolder, newbieName).exists()); - - // Make the directory for the new sketch - newbieDir.mkdirs(); - - // Make an empty pde file - //File newbieFile = new File(newbieDir, newbieName + getExtension()); - File newbieFile = new File(newbieDir, newbieName + "." + nextMode.getDefaultExtension()); - new FileOutputStream(newbieFile); // create the file - return newbieFile.getAbsolutePath(); - } - /** * Create a new untitled document in a new sketch window. */ public void handleNew() { try { - String path = createNewUntitled(); - if (path != null) { - Editor editor = handleOpen(path); - editor.untitled = true; + File newbieDir = null; + String newbieName = null; + + // In 0126, untitled sketches will begin in the temp folder, + // and then moved to a new location because Save will default to Save As. +// File sketchbookDir = getSketchbookFolder(); + File newbieParentDir = untitledFolder; + + String prefix = Preferences.get("editor.untitled.prefix"); + + // Use a generic name like sketch_031008a, the date plus a char + int index = 0; + String format = Preferences.get("editor.untitled.suffix"); + String suffix = null; + if (format == null) { + Calendar cal = Calendar.getInstance(); + int day = cal.get(Calendar.DAY_OF_MONTH); // 1..31 + int month = cal.get(Calendar.MONTH); // 0..11 + suffix = months[month] + PApplet.nf(day, 2); } else { - // happens when user gets to the end of 26 new sketches for the day - //System.err.println("untitled went null..."); + //SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd"); + //SimpleDateFormat formatter = new SimpleDateFormat("MMMdd"); + //String purty = formatter.format(new Date()).toLowerCase(); + SimpleDateFormat formatter = new SimpleDateFormat(format); + suffix = formatter.format(new Date()); } + do { + if (index == 26) { + // In 0159, avoid running past z by sending people outdoors. + if (!breakTime) { + Base.showWarning("Time for a Break", + "You've reached the limit for auto naming of new sketches\n" + + "for the day. How about going for a walk instead?", null); + breakTime = true; + } else { + Base.showWarning("Sunshine", + "No really, time for some fresh air for you.", null); + } + return; + } + newbieName = prefix + suffix + ((char) ('a' + index)); + // Also sanitize the name since it might do strange things on + // non-English systems that don't use this sort of date format. + // http://code.google.com/p/processing/issues/detail?id=283 + newbieName = Sketch.sanitizeName(newbieName); + newbieDir = new File(newbieParentDir, newbieName); + index++; + // Make sure it's not in the temp folder *and* it's not in the sketchbook + } while (newbieDir.exists() || new File(sketchbookFolder, newbieName).exists()); + + // Make the directory for the new sketch + newbieDir.mkdirs(); + + // Make an empty pde file + File newbieFile = + new File(newbieDir, newbieName + "." + nextMode.getDefaultExtension()); + if (!newbieFile.createNewFile()) { + throw new IOException(newbieFile + " already exists."); + } + String path = newbieFile.getAbsolutePath(); + /*Editor editor =*/ handleOpen(path, true); } catch (IOException e) { - if (activeEditor != null) { - activeEditor.statusError(e); - } else { - e.printStackTrace(); - } + Base.showWarning("That's new to me", + "A strange and unexplainable error occurred\n" + + "while trying to create a new sketch.", e); } } - /** - * Replace the sketch in the current window with a new untitled document. - */ - public void handleNewReplace() { - if (!activeEditor.checkModified()) { - return; // sketch was modified, and user canceled - } - // Close the running window, avoid window boogers with multiple sketches - activeEditor.internalCloseRunner(); - - // Actually replace things - handleNewReplaceImpl(); - } +// /** +// * Replace the sketch in the current window with a new untitled document. +// */ +// public void handleNewReplace() { +// if (!activeEditor.checkModified()) { +// return; // sketch was modified, and user canceled +// } +// // Close the running window, avoid window boogers with multiple sketches +// activeEditor.internalCloseRunner(); +// +// // Actually replace things +// handleNewReplaceImpl(); +// } - protected void handleNewReplaceImpl() { - try { - String path = createNewUntitled(); - if (path != null) { - activeEditor.handleOpenInternal(path); - activeEditor.untitled = true; - } -// return true; - - } catch (IOException e) { - activeEditor.statusError(e); -// return false; - } - } +// protected void handleNewReplaceImpl() { +// try { +// String path = createNewUntitled(); +// if (path != null) { +// activeEditor.handleOpenInternal(path); +// activeEditor.untitled = true; +// } +//// return true; +// +// } catch (IOException e) { +// activeEditor.statusError(e); +//// return false; +// } +// } - /** - * Open a sketch, replacing the sketch in the current window. - * @param path Location of the primary pde file for the sketch. - */ - public void handleOpenReplace(String path) { - if (!activeEditor.checkModified()) { - return; // sketch was modified, and user canceled - } - // Close the running window, avoid window boogers with multiple sketches - activeEditor.internalCloseRunner(); - - boolean loaded = activeEditor.handleOpenInternal(path); - if (!loaded) { - // replace the document without checking if that's ok - handleNewReplaceImpl(); - } else { - recent.handle(activeEditor); - } - } +// /** +// * Open a sketch, replacing the sketch in the current window. +// * @param path Location of the primary pde file for the sketch. +// */ +// public void handleOpenReplace(String path) { +// if (!activeEditor.checkModified()) { +// return; // sketch was modified, and user canceled +// } +// // Close the running window, avoid window boogers with multiple sketches +// activeEditor.internalCloseRunner(); +// +// boolean loaded = activeEditor.handleOpenInternal(path); +// if (!loaded) { +// // replace the document without checking if that's ok +// handleNewReplaceImpl(); +// } else { +// handleRecent(activeEditor); +// } +// } /** @@ -944,21 +932,28 @@ public class Base { } + /** + * Open a sketch from the path specified. Do not use for untitled sketches. + */ + public Editor handleOpen(String path) { + return handleOpen(path, false); + } + + /** * Open a sketch in a new window. * @param path Path to the pde file for the sketch in question * @return the Editor object, so that properties (like 'untitled') * can be set by the caller */ - public Editor handleOpen(String path) { - //return handleOpen(path, nextEditorLocation()); - return handleOpen(path, new EditorState(editors)); + public Editor handleOpen(String path, boolean untitled) { + return handleOpen(path, untitled, new EditorState(editors)); } // protected Editor handleOpen(String path, int[] location) { // protected Editor handleOpen(String path, Rectangle bounds, int divider) { - protected Editor handleOpen(String path, EditorState state) { + protected Editor handleOpen(String path, boolean untitled, EditorState state) { // System.err.println("entering handleOpen " + path); File file = new File(path); @@ -978,7 +973,7 @@ public class Base { if (editor.getSketch().getMainFilePath().equals(path)) { editor.toFront(); // move back to the top of the recent list - recent.handle(editor); + handleRecent(editor); return editor; } } @@ -1047,8 +1042,9 @@ public class Base { return null; // Just walk away quietly } + editor.untitled = untitled; editors.add(editor); - recent.handle(editor); + handleRecent(editor); // now that we're ready, show the window // (don't do earlier, cuz we might move it based on a window being closed) @@ -1303,11 +1299,6 @@ public class Base { } -// public void renameRecent(String oldPath, String newPath) { -// recent.handleRename(oldPath, newPath); -// } - - public void handleRecent(Editor editor) { recent.handle(editor); } @@ -1356,11 +1347,11 @@ public class Base { if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) { replace = !replace; } - if (replace) { - handleOpenReplace(path); - } else { - handleOpen(path); - } +// if (replace) { +// handleOpenReplace(path); +// } else { + handleOpen(path); +// } } else { showWarning("Sketch Disappeared", "The selected sketch no longer exists.\n" + diff --git a/app/src/processing/app/Recent.java b/app/src/processing/app/Recent.java index e37377817..2495eae33 100644 --- a/app/src/processing/app/Recent.java +++ b/app/src/processing/app/Recent.java @@ -32,7 +32,7 @@ import processing.core.PApplet; // dealing with renaming // before sketch save/rename, remove it from the recent list // after sketch save/rename add it to the list -// need to do this whether or not +// (this is the more straightforward model, otherwise has lots of weird edge cases) public class Recent { static final String FILENAME = "recent.txt"; @@ -40,14 +40,15 @@ public class Recent { Base base; File file; - int count; + /** How many recent sketches to remember. */ + int remember; ArrayList records; JMenu menu; public Recent(Base base) { this.base = base; - count = Preferences.getInteger("recent.count"); + remember = Preferences.getInteger("recent.count"); file = Base.getSettingsFile(FILENAME); menu = new JMenu("Recent Sketches"); @@ -106,7 +107,14 @@ public class Recent { private void updateMenu() { menu.removeAll(); for (final Record rec : records) { - JMenuItem item = new JMenuItem(rec.getName()); + String purtyPath = new File(rec.getPath()).getParent(); + String sketchbookPath = base.getSketchbookFolder().getAbsolutePath(); + if (purtyPath.startsWith(sketchbookPath)) { + purtyPath = "sketchbook \u2192 " + + purtyPath.substring(sketchbookPath.length() + 1); + } + + JMenuItem item = new JMenuItem(rec.getName() + " | " + purtyPath); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Base will call handle() (below) which will cause this entry to @@ -181,18 +189,21 @@ public class Recent { */ synchronized void handle(Editor editor) { if (!editor.getSketch().isUntitled()) { - // If this is already in the menu, remove it + // If this sketch is already in the menu, remove it remove(editor); - if (records.size() == count) { + if (records.size() == remember) { records.remove(0); // remove the first entry } +// new Exception("adding to recent: " + editor.getSketch().getMainFilePath()).printStackTrace(System.out); // Record newRec = new Record(editor, editor.getSketch()); // records.add(newRec); records.add(new Record(editor)); // updateMenu(); save(); +// } else { +// new Exception("NOT adding to recent: " + editor.getSketch().getMainFilePath()).printStackTrace(System.out); } } @@ -266,6 +277,10 @@ public class Recent { return name.substring(0, name.indexOf('.')); } + String getPath() { + return path; + } + // String getPath() { // if (sketch != null) { // return sketch.getMainFilePath(); diff --git a/app/src/processing/mode/android/AndroidToolbar.java b/app/src/processing/mode/android/AndroidToolbar.java index d4cda80aa..9e1dd6a22 100644 --- a/app/src/processing/mode/android/AndroidToolbar.java +++ b/app/src/processing/mode/android/AndroidToolbar.java @@ -1,7 +1,8 @@ /* + Part of the Processing project - http://processing.org - Copyright (c) 2011 Ben Fry and Casey Reas + Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -38,26 +39,26 @@ public class AndroidToolbar extends EditorToolbar { static protected final int SAVE = 4; static protected final int EXPORT = 5; - + public AndroidToolbar(Editor editor, Base base) { super(editor, base); } - - + + public void init() { Image[][] images = loadImages(); for (int i = 0; i < 6; i++) { addButton(getTitle(i, false), getTitle(i, true), images[i], i == NEW); } } - - + + static public String getTitle(int index, boolean shift) { switch (index) { case RUN: return !shift ? "Run in Emulator" : "Run on Device"; case STOP: return "Stop"; - case NEW: return !shift ? "New" : "New Editor Window"; - case OPEN: return !shift ? "Open" : "Open in Another Window"; + case NEW: return "New"; + case OPEN: return "Open"; case SAVE: return "Save"; case EXPORT: return !shift ? "Export Signed Package" : "Export Android Project"; } @@ -68,7 +69,7 @@ public class AndroidToolbar extends EditorToolbar { public void handlePressed(MouseEvent e, int sel) { boolean shift = e.isShiftDown(); AndroidEditor aeditor = (AndroidEditor) editor; - + switch (sel) { case RUN: if (shift) { @@ -89,11 +90,11 @@ public class AndroidToolbar extends EditorToolbar { break; case NEW: - if (shift) { - base.handleNew(); - } else { - base.handleNewReplace(); - } +// if (shift) { + base.handleNew(); +// } else { +// base.handleNewReplace(); +// } break; case SAVE: diff --git a/app/src/processing/mode/java/JavaToolbar.java b/app/src/processing/mode/java/JavaToolbar.java index cf8e168e0..182e95c2b 100644 --- a/app/src/processing/mode/java/JavaToolbar.java +++ b/app/src/processing/mode/java/JavaToolbar.java @@ -34,8 +34,8 @@ public class JavaToolbar extends EditorToolbar { // static final String title[] = { // "Run", "Stop", "New", "Open", "Save", "Export" // }; - - /** Titles for each button when the shift key is pressed. */ + + /** Titles for each button when the shift key is pressed. */ // static final String titleShift[] = { // "Present", "Stop", "New Editor Window", "Open in Another Window", "Save", "Export to Application" // }; @@ -51,26 +51,26 @@ public class JavaToolbar extends EditorToolbar { // JPopupMenu popup; // JMenu menu; - + public JavaToolbar(Editor editor, Base base) { super(editor, base); } - - + + public void init() { Image[][] images = loadImages(); for (int i = 0; i < 6; i++) { addButton(getTitle(i, false), getTitle(i, true), images[i], i == NEW); } } - - + + static public String getTitle(int index, boolean shift) { switch (index) { case RUN: return !shift ? "Run" : "Present"; case STOP: return "Stop"; - case NEW: return !shift ? "New" : "New Editor Window"; - case OPEN: return !shift ? "Open" : "Open in Another Window"; + case NEW: return "New"; + case OPEN: return "Open"; case SAVE: return "Save"; // case EXPORT: return !shift ? "Export Application" : "Export Applet"; case EXPORT: return "Export Application"; @@ -82,7 +82,7 @@ public class JavaToolbar extends EditorToolbar { public void handlePressed(MouseEvent e, int sel) { boolean shift = e.isShiftDown(); JavaEditor jeditor = (JavaEditor) editor; - + switch (sel) { case RUN: if (shift) { @@ -104,11 +104,11 @@ public class JavaToolbar extends EditorToolbar { break; case NEW: - if (shift) { - base.handleNew(); - } else { - base.handleNewReplace(); - } +// if (shift) { + base.handleNew(); +// } else { +// base.handleNewReplace(); +// } break; case SAVE: diff --git a/app/src/processing/mode/javascript/JavaScriptToolbar.java b/app/src/processing/mode/javascript/JavaScriptToolbar.java index 4b50e54ae..7f27a7c54 100644 --- a/app/src/processing/mode/javascript/JavaScriptToolbar.java +++ b/app/src/processing/mode/javascript/JavaScriptToolbar.java @@ -10,7 +10,7 @@ import processing.app.Editor; import processing.app.EditorToolbar; public class JavaScriptToolbar extends EditorToolbar { - + static protected final int RUN = 0; static protected final int STOP = 1; @@ -20,47 +20,47 @@ public class JavaScriptToolbar extends EditorToolbar { static protected final int EXPORT = 5; - static public String getTitle ( int index, boolean shift ) + static public String getTitle ( int index, boolean shift ) { - switch (index) + switch (index) { case RUN: return "Start server"; case STOP: return "Stop server"; - case NEW: return !shift ? "New" : "New Editor Window"; - case OPEN: return !shift ? "Open" : "Open in Another Window"; + case NEW: return "New"; + case OPEN: return "Open"; case SAVE: return "Save"; case EXPORT: return "Export for Web"; } return null; - } + } - public JavaScriptToolbar ( Editor editor, Base base ) + public JavaScriptToolbar ( Editor editor, Base base ) { super(editor, base); } - public void init () + public void init () { Image[][] images = loadImages(); - for (int i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { addButton( getTitle(i, false), getTitle(i, true), images[i], i == NEW ); } } - public void handlePressed ( MouseEvent e, int index ) + public void handlePressed ( MouseEvent e, int index ) { - boolean shift = e.isShiftDown(); +// boolean shift = e.isShiftDown(); JavaScriptEditor jsEditor = (JavaScriptEditor) editor; switch (index) { - + case RUN: jsEditor.handleStartServer(); break; - + case STOP: jsEditor.handleStopServer(); break; @@ -71,13 +71,13 @@ public class JavaScriptToolbar extends EditorToolbar { break; case NEW: - if (shift) { - base.handleNew(); - } else { - base.handleNewReplace(); - } +// if (shift) { + base.handleNew(); +// } else { +// base.handleNewReplace(); +// } break; - + case SAVE: jsEditor.handleSave(false); break; diff --git a/todo.txt b/todo.txt index 74c203fb6..a3cdb9fe4 100644 --- a/todo.txt +++ b/todo.txt @@ -15,16 +15,20 @@ X launch4j problem o no crash when double-clicking a sketch and loading it (?) X http://code.google.com/p/processing/issues/detail?id=176 X also move back to using non-custom for 2.0 when we can drop QT support - -_ move initRequirements check for JVM to Runner - -_ grab tools.jar from reg keys? -_ don't mess with reg keys until the app is loaded -_ NPE causes trouble sometimes +X lots of fighting with Windows registry and launch4j to figure out launcher +o grab tools.jar from reg keys? +_ don't mess with reg keys until the app is loaded +_ NPE causes trouble sometimes +o move initRequirements check for JVM to Runner +X remove the shift designation for new and open to open in same editor or not +X code is just getting too messy _ revisions.txt should have Windows line endings _ change in SVN to be platform specific _ add 64-bit Linux version to the next download +_ don't use tmp folder for sketches? +_ or restrict more things like "show sketch folder" +_ don't allow adding files w/o saving earlier X remove jvm from cvs @@ -35,10 +39,10 @@ X not necessary -- ant takes care of it recent/open X add EditorState class, device-aware placement -X get rid of restore sketch feature +X get rid of restore sketch feature o remove pref for restoring sketches -_ make sure this is still around, we want it -_ implement recent sketches menu +_ oops, make sure this is still around, we want it +X implement recent sketches menu _ Opening sketch via editor window open-menu ignores mode _ http://code.google.com/p/processing/issues/detail?id=1034 _ don't pollute the recent menu with un-saved sketches