diff --git a/processing/app/PdeEditor.java b/processing/app/PdeEditor.java index 33a8a7343..88ad08072 100644 --- a/processing/app/PdeEditor.java +++ b/processing/app/PdeEditor.java @@ -26,7 +26,7 @@ import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; -import java.text.*; +//import java.text.*; import java.util.*; import java.util.zip.*; @@ -65,6 +65,7 @@ public class PdeEditor extends JFrame static final int HANDLE_QUIT = 3; int checking; String handleOpenPath; + //String handleSaveAsPath; //String openingName; PdeEditorButtons buttons; @@ -81,14 +82,13 @@ public class PdeEditor extends JFrame // currently opened program PdeSketch sketch; - // used by PdeRuntime for placing the window + // runtime information and window placement Point appletLocation; Point presentLocation; - Window presentationWindow; + RunButtonWatcher watcher; + PdeRuntime runtime; - //RunButtonWatcher watcher; - //PdeRuntime runtime; //boolean externalRuntime; //String externalPaths; //File externalCode; @@ -472,7 +472,8 @@ public class PdeEditor extends JFrame item = newJMenuItem("New", 'N'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - skNew(); + //skNew(); + handleNew(); } }); menu.add(item); @@ -482,7 +483,7 @@ public class PdeEditor extends JFrame saveMenuItem = newJMenuItem("Save", 'S'); saveMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - doSave(); + handleSave2(); } }); menu.add(saveMenuItem); @@ -490,21 +491,11 @@ public class PdeEditor extends JFrame saveAsMenuItem = newJMenuItem("Save as...", 'S', true); saveAsMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - skSaveAs(false); + handleSaveAs(); } }); menu.add(saveAsMenuItem); - /* - item = new JMenuItem("Rename..."); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - skSaveAs(true); - } - }); - menu.add(item); - */ - item = newJMenuItem("Export", 'E'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -953,7 +944,11 @@ public class PdeEditor extends JFrame } try { - sketch.run(); + if (!sketch.handleRun()) return; + + runtime = new PdeRuntime(sketch, this); + runtime.start(presenting ? presentLocation : appletLocation); + watcher = new RunButtonWatcher(); } catch (PdeException e) { error(e); @@ -961,7 +956,48 @@ public class PdeEditor extends JFrame } catch (Exception e) { e.printStackTrace(); } - sketch.cleanup(); + //sketch.cleanup(); // where does this go? + } + + + class RunButtonWatcher implements Runnable { + Thread thread; + + public RunButtonWatcher() { + thread = new Thread(this); + thread.start(); + } + + public void run() { + while (Thread.currentThread() == thread) { + if (runtime == null) { + stop(); + + } else { + if (runtime.applet != null) { + if (runtime.applet.finished) { + stop(); + } + //buttons.running(!runtime.applet.finished); + + } else if (runtime.process != null) { + //buttons.running(true); // ?? + + } else { + stop(); + } + } + try { + Thread.sleep(250); + } catch (InterruptedException e) { } + //System.out.println("still inside runner thread"); + } + } + + public void stop() { + buttons.running(false); + thread = null; + } } @@ -1208,6 +1244,7 @@ public class PdeEditor extends JFrame } + /* protected void handleOpen2(String isketchName, File isketchFile, File isketchDir) { if (!isketchFile.exists()) { @@ -1239,12 +1276,10 @@ public class PdeEditor extends JFrame sketch.directory = isketchDir; setSketchModified(false); - /* - // TODO re-enable history - history.setPath(sketchFile.getParent(), readOnlySketch()); - history.rebuildMenu(); - history.lastRecorded = program; - */ + // TODO re-enable history + //history.setPath(sketchFile.getParent(), readOnlySketch()); + //history.rebuildMenu(); + //history.lastRecorded = program; header.reset(); @@ -1259,8 +1294,10 @@ public class PdeEditor extends JFrame } buttons.clear(); } + */ + /* public void doSave() { // true if lastfile not set, otherwise false, meaning no prompt //handleSave(lastFile == null); @@ -1271,7 +1308,27 @@ public class PdeEditor extends JFrame public void doSaveAs() { handleSave(true); } + */ + // there is no handleSave1 since there's never a need to prompt + public void handleSave2() { + message("Saving..."); + try { + sketch.save(); + } catch (Exception e) { + error(e); + //message("Error during export."); + //e.printStackTrace(); + } + buttons.clear(); + } + + + //public void + //sketch.saveAs(); + + + /* protected void handleSave(boolean promptUser) { message("Saving file..."); String s = textarea.getText(); @@ -1328,11 +1385,23 @@ public class PdeEditor extends JFrame } buttons.clear(); } + */ - public void skSaveAs(/*boolean rename*/) { + public void handleSaveAs() { doStop(); + if (!PdePreferences.getBoolean("sketchbook.prompt")) { + status.edit("Save sketch as...", sketch.name); + } else { + handleSaveAs2(null); + } + } + + + /* + public void skSaveAs() { + //this.renaming = rename; //if (rename) { //status.edit("Rename sketch to...", sketchName); @@ -1340,7 +1409,93 @@ public class PdeEditor extends JFrame status.edit("Save sketch as...", sketchName); //} } + */ + + public void handleSaveAs2(String newSketchName) { + if (newSketchName.equals(sketch.name)) { + return; // do nothing + + } else if (newSketchName.equalsIgnoreCase(sketch.name)) { + // NEED TO GET THE ACTUAL SKETCH NAME FROM CODE[0] HERE + + boolean problem = (sketchDir.renameTo(newSketchDir) || + sketchFile.renameTo(newSketchFile)); + if (problem) { + status.error("Error while trying to re-save the sketch."); + } + + } else { + // setup new sketch object with new name + } + + /* + File newSketchDir = new File(sketchDir.getParent() + + File.separator + newSketchName); + File newSketchFile = new File(newSketchDir, newSketchName + ".pde"); + + //doSave(); // save changes before renaming.. risky but oh well + String textareaContents = textarea.getText(); + int textareaPosition = textarea.getCaretPosition(); + + // if same name, but different case, just use renameTo + if (newSketchName.toLowerCase(). + equals(sketchName.toLowerCase())) { + //System.out.println("using renameTo"); + + boolean problem = (sketchDir.renameTo(newSketchDir) || + sketchFile.renameTo(newSketchFile)); + if (problem) { + status.error("Error while trying to re-save the sketch."); + } + + } else { + // make new dir + newSketchDir.mkdirs(); + // copy the sketch file itself with new name + PdeBase.copyFile(sketchFile, newSketchFile); + + // copy everything from the old dir to the new one + PdeBase.copyDir(sketchDir, newSketchDir); + + // remove the old sketch file from the new dir + new File(newSketchDir, sketchName + ".pde").delete(); + + // remove the old dir (!) + //if (renaming) { + // in case java is holding on to any files we want to delete + //System.gc(); + //PdeBase.removeDir(sketchDir); + //} + + // (important!) has to be done before opening, + // otherwise the new dir is set to sketchDir.. + // remove .jar, .class, and .java files from the applet dir + File appletDir = new File(newSketchDir, "applet"); + File oldjar = new File(appletDir, sketchName + ".jar"); + if (oldjar.exists()) oldjar.delete(); + File oldjava = new File(appletDir, sketchName + ".java"); + if (oldjava.exists()) oldjava.delete(); + File oldclass = new File(appletDir, sketchName + ".class"); + if (oldclass.exists()) oldclass.delete(); + } + + // get the changes into the sketchbook menu + //base.rebuildSketchbookMenu(); + sketchbook.rebuildMenu(); + + // open the new guy + handleOpen2(newSketchName, newSketchFile, newSketchDir); + + // update with the new junk and save that as the new code + changeText(textareaContents, true); + textarea.setCaretPosition(textareaPosition); + doSave(); + */ + } + + + /* public void skSaveAs2(String newSketchName) { if (newSketchName.equals(sketchName)) { // nothing changes @@ -1409,6 +1564,7 @@ public class PdeEditor extends JFrame textarea.setCaretPosition(textareaPosition); doSave(); } + */ /** @@ -1416,7 +1572,7 @@ public class PdeEditor extends JFrame * queues all the gui status stuff that comes along with it. */ public void handleExport() { - editor.message("Exporting code..."); + message("Exporting code..."); try { if (sketch.export()) { message("Done exporting."); @@ -1424,7 +1580,7 @@ public class PdeEditor extends JFrame // error message will already be visible } } catch (Exception e) { - editor.message("Error during export."); + message("Error during export."); e.printStackTrace(); } buttons.clear(); @@ -1618,6 +1774,12 @@ public class PdeEditor extends JFrame // ................................................................... + public void error(Exception e) { + status.error(e.getMessage()); + e.printStackTrace(); + } + + public void error(PdeException e) { if (e.line >= 0) highlightLine(e.line); diff --git a/processing/app/PdeEditorStatus.java b/processing/app/PdeEditorStatus.java index 4fc3be3e1..663571eb3 100644 --- a/processing/app/PdeEditorStatus.java +++ b/processing/app/PdeEditorStatus.java @@ -111,15 +111,12 @@ public class PdeEditorStatus extends JPanel implements ActionListener { public void error(String message) { mode = ERROR; this.message = message; - //update(); repaint(); } public void prompt(String message) { - //System.out.println("prompting..."); - mode = PROMPT; this.message = message; @@ -129,206 +126,22 @@ public class PdeEditorStatus extends JPanel implements ActionListener { cancelButton.setVisible(true); yesButton.requestFocus(); - //update(); repaint(); - - /* - Point upperLeft = new Point(getLocation()); - //Point lowerRight = new Point(upperLeft.x + getBounds().width, - // upperLeft.y + getBounds().height); - SwingUtilities.convertPointToScreen(upperLeft, this); - - //Dialog dialog = new JDialog(editor.base, "none", true); - Dialog dialog = new Dialog(editor.base, "none", true); - //System.out.println(dialog.isDisplayable()); - //System.out.println(dialog.isDisplayable()); - dialog.setBounds(upperLeft.x, upperLeft.y, - getBounds().width, getBounds().height); - - //System.out.println(dialog.isDisplayable()); - //dialog.setModal(true); - //dialog.undecorated = true; - dialog.setUndecorated(true); - - System.out.println("showing"); - - dialog.show(); - System.out.println(dialog.isDisplayable()); - */ - - /* - //System.out.println(pt); - System.out.println(Thread.currentThread()); - - promptThread = new Thread(this); - promptThread.start(); - */ } - /* - public void run() { - //while (Thread.currentThread() == promptThread) { - synchronized (promptThread) { - while (promptThread != null) { - if (response != 0) { - System.out.println("stopping prompt thread"); - //promptThread.stop(); - promptThread = null; - System.out.println("exiting prompt loop"); - unprompt(); - break; - - } else { - try { - System.out.println("inside prompt thread " + - System.currentTimeMillis()); - Thread.sleep(10); - } catch (InterruptedException e) { } - } - } - System.out.println("exiting prompt thread"); - } - } - */ - - - /** - * Makes the Dialog visible. If the dialog and/or its owner - * are not yet displayable, both are made displayable. The - * dialog will be validated prior to being made visible. - * If the dialog is already visible, this will bring the dialog - * to the front. - *

- * If the dialog is modal and is not already visible, this call will - * not return until the dialog is hidden by calling hide or - * dispose. It is permissible to show modal dialogs from - * the event dispatching thread because the toolkit will ensure that - * another event pump runs while the one which invoked this method - * is blocked. - * @see Component#hide - * @see Component#isDisplayable - * @see Component#validate - * @see java.awt.Dialog#isModal - */ - - - /* - // Stores the app context on which event dispatch thread the dialog - // is being shown. Initialized in show(), used in hideAndDisposeHandler() - private AppContext showAppContext; - - private boolean keepBlocking = false; - - - public void show() { - //if (!isModal()) { - //conditionalShow(); - //} else { - - // Set this variable before calling conditionalShow(). That - // way, if the Dialog is hidden right after being shown, we - // won't mistakenly block this thread. - keepBlocking = true; - - // Store the app context on which this dialog is being shown. - // Event dispatch thread of this app context will be sleeping until - // we wake it by any event from hideAndDisposeHandler(). - showAppContext = AppContext.getAppContext(); - - //if (conditionalShow()) { - // We have two mechanisms for blocking: 1. If we're on the - // EventDispatchThread, start a new event pump. 2. If we're - // on any other thread, call wait() on the treelock. - - // keep the KeyEvents from being dispatched - // until the focus has been transfered - long time = Toolkit.getEventQueue().getMostRecentEventTime(); - Component predictedFocusOwner = getMostRecentFocusOwner(); - KeyboardFocusManager.getCurrentKeyboardFocusManager(). - enqueueKeyEvents(time, predictedFocusOwner); - - if (Toolkit.getEventQueue().isDispatchThread()) { - EventDispatchThread dispatchThread = - (EventDispatchThread)Thread.currentThread(); - dispatchThread.pumpEventsForHierarchy(new Conditional() { - public boolean evaluate() { - return keepBlocking && windowClosingException == null; - } - }, this); - } else { - synchronized (getTreeLock()) { - while (keepBlocking && windowClosingException == null) { - try { - getTreeLock().wait(); - } catch (InterruptedException e) { - break; - } - } - } - } - KeyboardFocusManager.getCurrentKeyboardFocusManager(). - dequeueKeyEvents(time, predictedFocusOwner); - if (windowClosingException != null) { - windowClosingException.fillInStackTrace(); - throw windowClosingException; - } - //} - } - //} - - void interruptBlocking() { - hideAndDisposeHandler(); // this is what impl did - - //if (modal) { - //disposeImpl(); - //} else if (windowClosingException != null) { - // windowClosingException.fillInStackTrace(); - // windowClosingException.printStackTrace(); - // windowClosingException = null; - // } - } - - final static class WakingRunnable implements Runnable { - public void run() { - } - } - - private void hideAndDisposeHandler() { - if (keepBlocking) { - synchronized (getTreeLock()) { - keepBlocking = false; - - if (showAppContext != null) { - // Wake up event dispatch thread on which the dialog was - // initially shown - SunToolkit.postEvent(showAppContext, - new PeerEvent(this, - new WakingRunnable(), - PeerEvent.PRIORITY_EVENT)); - } - EventQueue.invokeLater(new WakingRunnable()); - getTreeLock().notifyAll(); - } - } - } - */ - - // prompt has been handled, re-hide the buttons public void unprompt() { yesButton.setVisible(false); noButton.setVisible(false); cancelButton.setVisible(false); - //promptThread = null; empty(); } - public void edit(String message, String dflt /*, boolean rename*/) { + public void edit(String message, String dflt) { mode = EDIT; this.message = message; - //this.editRename = rename; response = 0; okButton.setVisible(true); @@ -339,7 +152,6 @@ public class PdeEditorStatus extends JPanel implements ActionListener { editField.requestFocus(); repaint(); - //update(); } public void unedit() { @@ -588,33 +400,28 @@ public class PdeEditorStatus extends JPanel implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getSource() == noButton) { - //System.out.println("clicked no"); - //response = 2; // shut everything down, clear status, and return unprompt(); + // don't need to save changes editor.checkModified2(); } else if (e.getSource() == yesButton) { - //System.out.println("clicked yes"); - //response = 1; - // shutdown/clear status, and call checkModified2 + // answer was in response to "save changes?" unprompt(); - editor.doSave(); // assuming that something is set? hmm - //System.out.println("calling checkmodified2"); + editor.handleSave2(); editor.checkModified2(); } else if (e.getSource() == cancelButton) { + // don't do anything, don't continue with checkModified2 if (mode == PROMPT) unprompt(); - if (mode == EDIT) unedit(); + else if (mode == EDIT) unedit(); editor.buttons.clear(); } else if (e.getSource() == okButton) { + // answering to "save as..." question String answer = editField.getText(); - editor.skSaveAs2(answer); + editor.handleSaveAs2(answer); unedit(); - - } else if (e.getSource() == editField) { - //System.out.println("editfield: " + e); } } } diff --git a/processing/app/PdeSketch.java b/processing/app/PdeSketch.java index 1dca07ca4..d35cacaa6 100644 --- a/processing/app/PdeSketch.java +++ b/processing/app/PdeSketch.java @@ -356,7 +356,8 @@ public class PdeSketch { * * X. afterwards, some of these steps need a cleanup function */ - public void run() throws PdeException { + //public void run() throws PdeException { + public boolean handleRun() throws PdeException { current.program = editor.getText(); // TODO record history here @@ -374,6 +375,12 @@ public class PdeSketch { load(); } + // in case there were any boogers left behind + // do this here instead of after exiting, since the exit + // can happen so many different ways.. and this will be + // better connected to the dataFolder stuff below. + cleanup(); + // copy contents of data dir into lib/build // TODO write a file sync procedure here.. if the files // already exist in the target, or haven't been modified @@ -397,7 +404,7 @@ public class PdeSketch { // externalPaths is magically set by build() // if the compilation worked, run the applet - if (mainClassName != null) { +// if (mainClassName != null) { /* if (externalPaths == null) { @@ -422,7 +429,7 @@ public class PdeSketch { */ // create a runtime object - runtime = new PdeRuntime(this, editor); +// runtime = new PdeRuntime(this, editor); // if programType is ADVANCED // or the code/ folder is not empty -> or just exists (simpler) @@ -436,58 +443,18 @@ public class PdeSketch { //PdeMessageStream messageStream = new PdeMessageStream(runtime); // start the applet - runtime.start(presenting ? presentLocation : appletLocation); //, +// runtime.start(presenting ? presentLocation : appletLocation); //, //new PrintStream(messageStream)); // spawn a thread to update PDE GUI state - watcher = new RunButtonWatcher(); +// watcher = new RunButtonWatcher(); - } else { +// } else { // [dmose] throw an exception here? // [fry] iirc the exception will have already been thrown - cleanup(); - } - } - - - class RunButtonWatcher implements Runnable { - Thread thread; - - public RunButtonWatcher() { - thread = new Thread(this); - thread.start(); - } - - public void run() { - while (Thread.currentThread() == thread) { - if (runtime == null) { - stop(); - - } else { - if (runtime.applet != null) { - if (runtime.applet.finished) { - stop(); - } - //buttons.running(!runtime.applet.finished); - - } else if (runtime.process != null) { - //buttons.running(true); // ?? - - } else { - stop(); - } - } - try { - Thread.sleep(250); - } catch (InterruptedException e) { } - //System.out.println("still inside runner thread"); - } - } - - public void stop() { - buttons.running(false); - thread = null; - } +// cleanup(); +// } + return (mainClassName != null); } @@ -1083,6 +1050,14 @@ public class PdeSketch { } + /** + * Returns the path to the sketch folder. + * Used by PdeEditor.handleSaveAs() + */ + //public String getPath() { + //return sketchFolder.getPath(); + //} + /** * Returns path to the main .pde file for this sketch. */