diff --git a/app/PdeCode.java b/app/PdeCode.java index 16bedae58..0a214ce3b 100644 --- a/app/PdeCode.java +++ b/app/PdeCode.java @@ -5,7 +5,7 @@ Part of the Processing project - http://processing.org Except where noted, code is written by Ben Fry - Copyright (c) 2001-03 Massachusetts Institute of Technology + Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -66,6 +66,14 @@ public class PdeCode { // TODO re-enable history //history.record(s, PdeHistory.SAVE); - PdeBase.saveFile(program, file); + try { + PdeBase.saveFile(program, file); + + } catch (Exception e) { + PdeBase.showWarning("Error saving file", + "Could not save " + file + "\n" + + "because of an error.", e); + } + modified = false; } } diff --git a/app/PdeEditor.java b/app/PdeEditor.java index 86ad60ce4..d0ccc175a 100644 --- a/app/PdeEditor.java +++ b/app/PdeEditor.java @@ -126,7 +126,6 @@ public class PdeEditor extends JFrame // this is needed by just about everything else preferences = new PdePreferences(); - #ifdef MACOS // #@$*(@#$ apple.. always gotta think different MRJApplicationUtils.registerAboutHandler(this); @@ -469,15 +468,32 @@ public class PdeEditor extends JFrame JMenuItem item; JMenu menu = new JMenu("File"); - item = newJMenuItem("New", 'N'); + item = newJMenuItem("New sketch", 'N'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - //skNew(); handleNew(); } }); menu.add(item); + /* + item = newJMenuItem("New code", 'N', true); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleNewCode(); + } + }); + menu.add(item); + */ + + item = newJMenuItem("Open", 'O'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleOpen(); + } + }); + menu.add(item); + menu.add(sketchbook.rebuildMenu()); saveMenuItem = newJMenuItem("Save", 'S'); @@ -591,7 +607,7 @@ public class PdeEditor extends JFrame item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //PdeBase.openFolder(sketchDir); - PdeBase.openFolder(sketch.sketchFolder); + PdeBase.openFolder(sketch.folder); } }); menu.add(item); @@ -1072,14 +1088,20 @@ public class PdeEditor extends JFrame } - public void setModified(boolean what) { - //header.sketchModified = what; - sketch.setCurrentModified(what); - header.repaint(); - //sketchModified = what; + /* + public boolean isModified() { + return sketch.isModified(); } + public void setModified(boolean what) { + //sketch.setCurrentModified(what); + sketch.setModified(what); + header.repaint(); + } + */ + + /** * Check to see if there have been changes. If so, prompt user * whether or not to save first. If the user cancels, just ignore. @@ -1094,9 +1116,8 @@ public class PdeEditor extends JFrame //openingPath = path; //openingName = name; - if (!sketch.isModified()) { - checkModified2(); - } + //if (!sketch.isModified()) { + if (sketch.modified) checkModified2(); String prompt = "Save changes to " + sketch.name + "? "; @@ -1148,7 +1169,7 @@ public class PdeEditor extends JFrame public void checkModified2() { switch (checking) { case HANDLE_NEW: handleNew2(false); break; - case HANDLE_OPEN: handleOpen2(); break; + case HANDLE_OPEN: handleOpen2(handleOpenPath); break; case HANDLE_QUIT: handleQuit2(); break; } checking = 0; @@ -1187,8 +1208,8 @@ public class PdeEditor extends JFrame /** - * Need to determine what to open, happens when the 'open' button - * is hit or open is selected from the menu. + * Handler for the user selecting "Open" to open a sketch + * from anywhere else. */ public void handleOpen() { String path = sketchbook.handleOpen(); @@ -1197,7 +1218,7 @@ public class PdeEditor extends JFrame /** - * Get ready to open something good. + * Handler used by handleOpen() and also by the sketchbook menu */ public void handleOpen(String path) { doStop(); @@ -1208,13 +1229,14 @@ public class PdeEditor extends JFrame protected void handleOpen2(String path) { try { - sketch = new PdeSketch(path); + sketch = new PdeSketch(this, path); } catch (Exception e) { error(e); } } + /* protected void handleOpen2() { try { sketch = new PdeSketch(handleOpenPath); @@ -1223,6 +1245,7 @@ public class PdeEditor extends JFrame error(e); } } + */ /* @@ -1740,7 +1763,8 @@ public class PdeEditor extends JFrame textarea.select(selectionEnd, selectionEnd); //setSketchModified(true); - sketch.setCurrentModified(true); + //sketch.setCurrentModified(true); + sketch.setModified(); buttons.clear(); } diff --git a/app/PdeEditorFind.java b/app/PdeEditorFind.java index b4cc49067..8418e4887 100644 --- a/app/PdeEditorFind.java +++ b/app/PdeEditorFind.java @@ -227,7 +227,8 @@ public class PdeEditorFind extends JFrame implements ActionListener { editor.textarea.setSelectedText(replaceField.getText()); //editor.setSketchModified(true); - editor.sketch.setCurrentModified(true); + //editor.sketch.setCurrentModified(true); + editor.sketch.setModified(); // don't allow a double replace replaceButton.setEnabled(false); diff --git a/app/PdeSketch.java b/app/PdeSketch.java index 2119f432a..f0a508881 100644 --- a/app/PdeSketch.java +++ b/app/PdeSketch.java @@ -22,23 +22,32 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.FileDialog; import java.io.*; import java.util.*; import java.util.zip.*; +import com.oroinc.text.regex.*; + public class PdeSketch { static String TEMP_BUILD_PATH = "lib" + File.separator + "build"; - static String tempBuildFolder; + static File tempBuildFolder; + + PdeEditor editor; // name of sketch, which is the name of main file // (without .pde or .java extension) String name; - String mainFilename; // name of 'main' file, used by load() + // name of 'main' file, used by load(), such as sketch_04040.pde + String mainFilename; //String path; // path to 'main' file for this sketch - File sketchFolder; + // true if any of the files have been modified + boolean modified; + + File folder; //sketchFolder; File dataFolder; File codeFolder; @@ -63,7 +72,9 @@ public class PdeSketch { * path is location of the main .pde file, because this is also * simplest to use when opening the file from the finder/explorer. */ - public PdeSketch(String path) throws IOException { + public PdeSketch(PdeEditor editor, String path) throws IOException { + this.editor = editor; + File mainFile = new File(path); System.out.println("main file is " + mainFile); @@ -93,7 +104,7 @@ public class PdeSketch { "the application to complete the repair.", null); } - folder = new File(path.getParent()); + folder = new File(new File(path).getParent()); System.out.println("sketch dir is " + folder); codeFolder = new File(folder, "code"); @@ -119,8 +130,8 @@ public class PdeSketch { String list[] = folder.list(); for (int i = 0; i < list.length; i++) { - if (list[i].endsWith(".pde")) fileCount++; - else if (list[i].endsWith(".java")) fileCount++; + if (list[i].endsWith(".pde")) codeCount++; + else if (list[i].endsWith(".java")) codeCount++; else if (list[i].endsWith(".pde.x")) hiddenCount++; else if (list[i].endsWith(".java.x")) hiddenCount++; } @@ -128,18 +139,18 @@ public class PdeSketch { code = new PdeCode[codeCount]; hidden = new PdeCode[hiddenCount]; - int fileCounter = 0; + int codeCounter = 0; int hiddenCounter = 0; for (int i = 0; i < list.length; i++) { if (list[i].endsWith(".pde")) { - code[fileCounter++] = + code[codeCounter++] = new PdeCode(list[i].substring(0, list[i].length() - 4), new File(folder, list[i]), PDE); } else if (list[i].endsWith(".java")) { - code[fileCounter++] = + code[codeCounter++] = new PdeCode(list[i].substring(0, list[i].length() - 5), new File(folder, list[i]), JAVA); @@ -190,7 +201,7 @@ public class PdeSketch { for (int i = 1; i < codeCount; i++) { int who = i; for (int j = i + 1; j < codeCount; j++) { - if (code[j].name.compare(code[who].name) < 0) { + if (code[j].name.compareTo(code[who].name) < 0) { who = j; // this guy is earlier in the alphabet } } @@ -203,18 +214,72 @@ public class PdeSketch { } + /** + * Sets the modified value for the code in the frontmost tab. + */ + //public void setCurrentModified(boolean what) { + //public void setModified(boolean what) { + public void setModified() { + //modified = true; + current.modified = true; + //editor.header.repaint(); + calcModified(); + } + + + public void calcModified() { + modified = false; + for (int i = 0; i < codeCount; i++) { + if (code[i].modified) { + modified = true; + break; + } + } + editor.header.repaint(); + } + + /** + * Return true if any of the items are modified. + */ + /* + public boolean isModified() { + for (int i = 0; i < codeCount; i++) { + if (code[i].modified) return true; + } + return false; + } + */ + + /** * Save all code in the current sketch. */ public void save() { + // check if the files are read-only. + // if so, need to first do a "save as". + if (modified && isReadOnly()) { + PdeBase.showMessage("Sketch is read-only", + "You can't save changes to this sketch\n" + + "in the place it's currently located.\n" + + "You'll have to save it to another location."); + saveAs(); + } + for (int i = 0; i < codeCount; i++) { code[i].save(); } + calcModified(); } public void saveCurrent() { current.save(); + calcModified(); + } + + + public void saveAs() { + System.err.println("need to save ass here. code not yet finished."); } @@ -228,7 +293,8 @@ public class PdeSketch { // get a dialog, select a file to add to the sketch String prompt = "Select an image or other data file to copy to your sketch"; - FileDialog fd = new FileDialog(new Frame(), prompt, FileDialog.LOAD); + //FileDialog fd = new FileDialog(new Frame(), prompt, FileDialog.LOAD); + FileDialog fd = new FileDialog(editor, prompt, FileDialog.LOAD); fd.show(); String directory = fd.getDirectory(); @@ -265,25 +331,6 @@ public class PdeSketch { } - /** - * Sets the modified value for the code in the frontmost tab. - */ - public void setCurrentModified(boolean what) { - current.modified = what; - } - - - /** - * Return true if any of the items are modified. - */ - public boolean isModified() { - for (int i = 0; i < codeCount; i++) { - if (code[i].modified) return true; - } - return false; - } - - /** * Change what file is currently being edited. * 1. store the String for the text of the current file. @@ -390,7 +437,7 @@ public class PdeSketch { // just drop the files in the build folder (pre-68) //PdeBase.copyDir(dataDir, buildDir); // drop the files into a 'data' subfolder of the build dir - PdeBase.copyDir(dataDir, new File(buildDir, "data")); + PdeBase.copyDir(dataFolder, new File(tempBuildFolder, "data")); } // make up a temporary class name to suggest. @@ -486,13 +533,14 @@ public class PdeSketch { // figure out the contents of the code folder to see if there // are files that need to be added to the imports - File codeFolder = new File(sketchDir, "code"); + //File codeFolder = new File(folder, "code"); if (codeFolder.exists()) { externalRuntime = true; classPath += File.separator + PdeCompiler.contentsToClassPath(codeFolder); importPackageList = PdeCompiler.magicImports(classPath); - libraryPath = codeFolder.getCanonicalPath(); + //libraryPath = codeFolder.getCanonicalPath(); + libraryPath = codeFolder.getAbsolutePath(); } else { externalRuntime = (codeCount > 1); // may still be set true later importPackageList = null; @@ -820,8 +868,12 @@ public class PdeSketch { // copy the source files to the target, since we like // to encourage people to share their code for (int i = 0; i < codeCount; i++) { - PdeBase.copyFile(code[i].file, - new File(appletDir, code[i].file.getName())); + try { + PdeBase.copyFile(code[i].file, + new File(appletDir, code[i].file.getName())); + } catch (IOException e) { + + } } // create new .jar file @@ -832,7 +884,7 @@ public class PdeSketch { // add the contents of the code folder to the jar // unpacks all jar files - File codeFolder = new File(sketchDir, "code"); + //File codeFolder = new File(folder, "code"); if (codeFolder.exists()) { String includes = PdeCompiler.contentsToClassPath(codeFolder); packClassPathIntoZipFile(includes, zos); @@ -1035,6 +1087,13 @@ public class PdeSketch { * volumes or folders without appropraite permissions. */ public boolean isReadOnly() { + if (folder.getAbsolutePath().startsWith(PdeSketchbook.examplesPath)) { + return true; + + } else if (!folder.canWrite()) { // is this ok for directories? + System.err.println("read only directory..."); + return true; + } return false; } diff --git a/app/PdeSketchbook.java b/app/PdeSketchbook.java index e47c568b3..db6f5a259 100644 --- a/app/PdeSketchbook.java +++ b/app/PdeSketchbook.java @@ -48,10 +48,13 @@ public class PdeSketchbook { //String sketchbookPath; // canonical path // last file/directory used for file opening - String handleOpenDirectory; + //String handleOpenDirectory; + // opted against this.. in imovie, apple always goes + // to the "Movies" folder, even if that wasn't the last used - File examplesFolder; - String examplesPath; // canonical path (for comparison) + // these are static because they're used by PdeSketch + static File examplesFolder; + static String examplesPath; // canonical path (for comparison) public PdeSketchbook(PdeEditor editor) { @@ -86,11 +89,8 @@ public class PdeSketchbook { sketchbookFolder.getAbsolutePath()); if (!sketchbookFolder.exists()) sketchbookFolder.mkdirs(); - //sketchbookPath = sketchbookFolder.getAbsolutePath(); - //} else { - //sketchbookFolder = new File(sketchbookPath); } - menu = new JMenu("Open"); + menu = new JMenu("Sketchbook"); } @@ -110,11 +110,13 @@ public class PdeSketchbook { // unless, ermm, they user tested it and people preferred that as // a way to get started. shite. now i hate myself. // - if (PdePreferences.getBoolean("sketchbook.prompt") && !startup) { + //if (PdePreferences.getBoolean("sketchbook.prompt") && !startup) { + if (!startup) { // prompt for the filename and location for the new sketch FileDialog fd = new FileDialog(new Frame(), - "Create new sketch named", + //"Create new sketch named", + "Create sketch folder named:", FileDialog.SAVE); fd.setDirectory(PdePreferences.get("sketchbook.path")); fd.show(); @@ -158,9 +160,9 @@ public class PdeSketchbook { MRJFileUtils.setFileTypeAndCreator(newbieFile, MRJOSType.kTypeTEXT, new MRJOSType("Pde1")); + // thank you apple, for changing this @#$)(* + //com.apple.eio.setFileTypeAndCreator(String filename, int, int) } - // thank you apple, for changing this @#$)(* - //com.apple.eio.setFileTypeAndCreator(String filename, int, int) #endif // make a note of a newly added sketch in the sketchbook menu @@ -174,13 +176,16 @@ public class PdeSketchbook { public String handleOpen() { + // swing's file choosers are ass ugly, so we use the + // native (awt peered) dialogs instead FileDialog fd = new FileDialog(new Frame(), "Open a Processing sketch...", FileDialog.LOAD); - if (handleOpenDirectory == null) { - handleOpenDirectory = PdePreferences.get("sketchbook.path"); - } - fd.setDirectory(handleOpenDirectory); + //if (handleOpenDirectory == null) { + // handleOpenDirectory = PdePreferences.get("sketchbook.path"); + //} + //fd.setDirectory(handleOpenDirectory); + fd.setDirectory(PdePreferences.get("sketchbook.path")); // only show .pde files as eligible bachelors fd.setFilenameFilter(new FilenameFilter() { @@ -200,7 +205,7 @@ public class PdeSketchbook { if (filename == null) return null; // this may come in handy sometime - handleOpenDirectory = directory; + //handleOpenDirectory = directory; File selection = new File(directory, filename); return selection.getAbsolutePath();