diff --git a/processing/app/PdeBase.java b/processing/app/PdeBase.java index ab31f2481..e08d847fa 100644 --- a/processing/app/PdeBase.java +++ b/processing/app/PdeBase.java @@ -59,44 +59,27 @@ public class PdeBase extends JFrame implements ActionListener static Properties keywords; // keyword -> reference html lookup //static Frame frame; // now 'this' - static String encoding; + //static String encoding; static Image icon; // indicator that this is the first time this feller has used p5 - static boolean firstTime; + //static boolean firstTime; - boolean errorState; + //boolean errorState; PdeEditor editor; //WindowAdapter windowListener; - Menu sketchbookMenu; - File sketchbookFolder; - String sketchbookPath; - - boolean recordingHistory; - Menu historyMenu; - ActionListener historyMenuListener = - new ActionListener() { - public void actionPerformed(ActionEvent e) { - editor.retrieveHistory(e.getActionCommand()); - } - }; - //Menu serialMenu; - MenuItem undoItem, redoItem; - MenuItem saveMenuItem; - MenuItem saveAsMenuItem; - MenuItem beautifyMenuItem; + JMenuItem saveMenuItem; + JMenuItem saveAsMenuItem; + JMenuItem beautifyMenuItem; //CheckboxMenuItem externalEditorItem; //Menu renderMenu; //CheckboxMenuItem normalItem, openglItem; //MenuItem illustratorItem; - - static final String WINDOW_TITLE = "Processing"; - // the platforms static final int WINDOWS = 1; static final int MACOS9 = 2; @@ -188,7 +171,7 @@ public class PdeBase extends JFrame implements ActionListener // load in preferences (last sketch used, window placement, etc) - prefs = new PdePreferences(); + preferences = new PdePreferences(); // read in the keywords for the reference @@ -223,152 +206,17 @@ public class PdeBase extends JFrame implements ActionListener // build the editor object - editor = new PdeEditor(this); - getContentPane().setLayout(new BorderLayout()); - getContentPane().add("Center", editor); + //editor = new PdeEditor(this); + //getContentPane().setLayout(new BorderLayout()); + //getContentPane().add("Center", editor); - // setup menu bar - - MenuBar menubar = new MenuBar(); - Menu menu; - MenuItem item; - - - // file menu - - menu = new Menu("File"); - menu.add(new MenuItem("New", new MenuShortcut('N'))); - sketchbookMenu = new Menu("Open"); - menu.add(sketchbookMenu); - saveMenuItem = new MenuItem("Save", new MenuShortcut('S')); - saveAsMenuItem = new MenuItem("Save as...", new MenuShortcut('S', true)); - menu.add(saveMenuItem); - menu.add(saveAsMenuItem); - menu.add(new MenuItem("Rename...")); - menu.addSeparator(); - - menu.add(new MenuItem("Export to Web", new MenuShortcut('E'))); - item = new MenuItem("Export Application", new MenuShortcut('E', true)); - item.setEnabled(false); - menu.add(item); - - if (platform != MACOSX) { - menu.add(new MenuItem("Preferences")); - menu.addSeparator(); - menu.add(new MenuItem("Quit", new MenuShortcut('Q'))); - - } else { #ifdef MACOS // #@$*(@#$ apple.. always gotta think different MRJApplicationUtils.registerAboutHandler(this); MRJApplicationUtils.registerPrefsHandler(this); MRJApplicationUtils.registerQuitHandler(this); #endif - } - menu.addActionListener(this); - menubar.add(menu); - - - // edit menu - menubar.add(editor.buildEditMenu()); - - - // sketch menu - - menu = new Menu("Sketch"); - menu.add(new MenuItem("Run", new MenuShortcut('R'))); - menu.add(new MenuItem("Present", new MenuShortcut('R', true))); - menu.add(new MenuItem("Stop", new MenuShortcut('T'))); - menu.addSeparator(); - - menu.add(new MenuItem("Add file...")); - menu.add(new MenuItem("Create font...")); - - if ((platform == WINDOWS) || (platform == MACOSX)) { - // no way to do an 'open in file browser' on other platforms - // since there isn't any sort of standard - menu.add(new MenuItem("Show sketch folder")); - } - - recordingHistory = PdePreferences.getBoolean("history.recording", true); - if (recordingHistory) { - historyMenu = new Menu("History"); - menu.add(historyMenu); - } - - //menu.addSeparator(); - - //menu.addSeparator(); - //serialMenu = new Menu("Serial Port"); - //menu.add(serialMenu); - - /* - Menu rendererMenu = new Menu("Renderer"); -#ifdef OPENGL - // opengl support has started, but remains as yet unfinished - menu.add(rendererMenu); -#endif - - normalItem = new CheckboxMenuItem("Normal"); - rendererMenu.add(normalItem); - normalItem.setState(true); - normalItem.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - openglItem.setState(false); - normalItem.setState(true); - } - }); - - openglItem = new CheckboxMenuItem("OpenGL"); - rendererMenu.add(openglItem); - openglItem.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - openglItem.setState(true); - normalItem.setState(false); - } - }); - */ - - /* - externalEditorItem = new CheckboxMenuItem("Use External Editor"); - externalEditorItem.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - //System.out.println(e); - if (e.getStateChange() == ItemEvent.SELECTED) { - editor.setExternalEditor(true); - } else { - editor.setExternalEditor(false); - } - } - }); - menu.add(externalEditorItem); - */ - - menu.addActionListener(this); - menubar.add(menu); // add the sketch menu - - - // help menu - - menu = new Menu("Help"); - menu.add(new MenuItem("Help")); - menu.add(new MenuItem("Reference")); - menu.add(new MenuItem("Proce55ing.net", new MenuShortcut('5'))); - - // macosx already has its own about menu - if (platform != MACOSX) { - menu.addSeparator(); - menu.add(new MenuItem("About Processing")); - } - menu.addActionListener(this); - menubar.setHelpMenu(menu); - - - // set all menus - - this.setMenuBar(menubar); - // load preferences and finish up @@ -384,19 +232,6 @@ public class PdeBase extends JFrame implements ActionListener } - // antidote for overthought swing api mess for setting accelerators - - static public JMenuItem newMenuItem(String title, char what) { - return newMenuItem(title, what, false); - } - - static public JMenuItem newMenuItem(String title, char what, boolean shift) { - JMenuItem menuItem = new JMenuItem(title); - menuItem.setAccelerator(KeyStroke.getKeyStroke(what, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | (shift ? ActionEvent.SHIFT_MASK : 0))); - return menuItem; - } - - public void restorePreferences() { // figure out window placement @@ -593,101 +428,6 @@ public class PdeBase extends JFrame implements ActionListener } - /* - class HistoryMenuListener implements ActionListener { - public void actionPerformed(ActionEvent e) { - editor.selectHistory(e.getActionCommand); - } - } - */ - - public void rebuildHistoryMenu(String path) { - rebuildHistoryMenu(historyMenu, path); - } - - public void rebuildHistoryMenu(Menu menu, String path) { - if (!recordingHistory) return; - - menu.removeAll(); - - File hfile = new File(path); - if (!hfile.exists()) return; // no history yet - - MenuItem item = new MenuItem("Clear History"); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (!editor.historyFile.delete()) { - System.err.println("couldn't erase history"); - } - rebuildHistoryMenu(historyMenu, editor.historyFile.getPath()); - } - }); - menu.add(item); - menu.addSeparator(); - - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(path)))); - String line = null; - - int historyCount = 0; - String historyList[] = new String[100]; - - try { - while ((line = reader.readLine()) != null) { - //while (line = reader.readLine()) { - //while (true) { line = reader.readLine(); - //if (line == null) continue; - //System.out.println("line: " + line); - if (line.equals(PdeEditor.HISTORY_SEPARATOR)) { - // next line is the good stuff - line = reader.readLine(); - int version = - Integer.parseInt(line.substring(0, line.indexOf(' '))); - if (version == 1) { - String whysub = line.substring(2); // after "1 " - String why = whysub.substring(0, whysub.indexOf(" -")); - //System.out.println("'" + why + "'"); - - String readable = line.substring(line.lastIndexOf("-") + 2); - if (historyList.length == historyCount) { - String temp[] = new String[historyCount*2]; - System.arraycopy(historyList, 0, temp, 0, historyCount); - historyList = temp; - } - historyList[historyCount++] = why + " - " + readable; - - } // otherwise don't know what to do - } - } - //System.out.println(line); - } catch (IOException e) { - e.printStackTrace(); - } - - // add the items to the menu in reverse order - /* - ActionListener historyMenuListener = - new ActionListener() { - public void actionPerformed(ActionEvent e) { - editor.retrieveHistory(e.getActionCommand()); - } - }; - */ - - for (int i = historyCount-1; i >= 0; --i) { - MenuItem mi = new MenuItem(historyList[i]); - mi.addActionListener(historyMenuListener); - menu.add(mi); - } - - reader.close(); - - } catch (IOException e) { - e.printStackTrace(); - } - } - - // interfaces for MRJ Handlers, but naming is fine // so used internally for everything else diff --git a/processing/app/PdeEditor.java b/processing/app/PdeEditor.java index dc5569f97..52dd0cdbf 100644 --- a/processing/app/PdeEditor.java +++ b/processing/app/PdeEditor.java @@ -34,6 +34,7 @@ import java.util.zip.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; +import javax.swing.undo.*; import com.oroinc.text.regex.*; @@ -42,14 +43,14 @@ import com.apple.mrj.*; #endif -public class PdeEditor extends JPanel { +public class PdeEditor extends JFrame { + // yeah + static final String WINDOW_TITLE = "Processing"; + // otherwise, if the window is resized with the message label // set to blank, it's preferredSize() will be fukered static final String EMPTY = " "; - static final String HISTORY_SEPARATOR = - "#################################################"; - static final int SK_NEW = 1; static final int SK_OPEN = 2; static final int DO_OPEN = 3; @@ -58,11 +59,6 @@ public class PdeEditor extends JPanel { String openingPath; String openingName; - static final int RUN = 5; // for history - static final int SAVE = 6; - static final int AUTOSAVE = 7; - static final int BEAUTIFY = 8; - PdeEditorButtons buttons; PdeEditorHeader header; PdeEditorStatus status; @@ -73,24 +69,12 @@ public class PdeEditor extends JPanel { JEditTextArea textarea; - //boolean externalEditor; - // currently opened program - //String userName; // user currently logged in String sketchName; // name of the file (w/o pde if a sketch) File sketchFile; // the .pde file itself File sketchDir; // if a sketchbook project, the parent dir boolean sketchModified; - File historyFile; - //OutputStream historyStream; - //PrintWriter historyWriter; - String historyLast; - - //String lastDirectory; - //String lastFile; - - //PdeRunner runner; Point appletLocation; //= new Point(0, 0); Point presentLocation; // = new Point(0, 0); @@ -103,7 +87,11 @@ public class PdeEditor extends JPanel { String externalPaths; File externalCode; - //static final int INSET_SIZE = 5; + JMenuItem saveMenuItem; + JMenuItem saveAsMenuItem; + JMenuItem beautifyMenuItem; + + // boolean running; boolean presenting; @@ -120,6 +108,8 @@ public class PdeEditor extends JPanel { static final String TEMP_CLASS = "Temporary"; // undo fellers + JMenuItem undoItem, redoItem; + protected UndoAction undoAction; protected RedoAction redoAction; static public UndoManager undo = new UndoManager(); // editor needs this guy @@ -128,7 +118,15 @@ public class PdeEditor extends JPanel { public PdeEditor(PdeBase base) { this.base = base; - setLayout(new BorderLayout()); + history = new PdeHistory(this); + sketchbook = new PdeSketchbook(this); + + JMenuBar menubar = new JMenuBar(); + menubar.add(buildFileMenu()); + menubar.add(buildEditMenu()); + + Container pain = getContentPane(); + pain.setLayout(new BorderLayout()); Panel leftPanel = new Panel(); leftPanel.setLayout(new BorderLayout()); @@ -142,7 +140,7 @@ public class PdeEditor extends JPanel { dummy.setBackground(buttonBgColor); leftPanel.add("Center", dummy); - add("West", leftPanel); + pain.add("West", leftPanel); JPanel rightPanel = new JPanel(); rightPanel.setLayout(new BorderLayout()); @@ -186,7 +184,7 @@ public class PdeEditor extends JPanel { rightPanel.add(splitPane, BorderLayout.CENTER); - add("Center", rightPanel); + pain.add("Center", rightPanel); // hopefully these are no longer needed w/ swing // (that was wishful thinking, they still are, until we switch to jedit) @@ -284,6 +282,9 @@ public class PdeEditor extends JPanel { } + // ................................................................... + + /** * Post-constructor setup for the editor area. Loads the last * sketch that was used (if any), and restores other Editor settings. @@ -324,9 +325,9 @@ public class PdeEditor extends JPanel { boolean external = getBoolean("editor.external"); textarea.setEditable(!external); - base.saveMenuItem.setEnabled(!external); - base.saveAsMenuItem.setEnabled(!external); - base.beautifyMenuItem.setEnabled(!external); + saveMenuItem.setEnabled(!external); + saveAsMenuItem.setEnabled(!external); + beautifyMenuItem.setEnabled(!external); TextAreaPainter painter = textarea.getPainter(); if (external) { @@ -362,15 +363,97 @@ public class PdeEditor extends JPanel { // ................................................................... + protected JMenu buildFileMenu() { + JMenuItem item; + JMenu menu = new Menu("File"); + + item = newMenuItem("New", 'N'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + skNew(); + } + }); + menu.add(item); + + sketchbookMenu = new Menu("Open"); + menu.add(sketchbookMenu); + saveMenuItem = new MenuItem("Save", new MenuShortcut('S')); + saveAsMenuItem = new MenuItem("Save as...", new MenuShortcut('S', true)); + menu.add(saveMenuItem); + menu.add(saveAsMenuItem); + menu.add(new MenuItem("Rename...")); + menu.addSeparator(); + + menu.add(new MenuItem("Export to Web", new MenuShortcut('E'))); + item = new MenuItem("Export Application", new MenuShortcut('E', true)); + item.setEnabled(false); + menu.add(item); + + if (PdeBase.platform != PdeBase.MACOSX) { + menu.add(new MenuItem("Preferences")); + menu.addSeparator(); + menu.add(new MenuItem("Quit", new MenuShortcut('Q'))); + } + menu.addActionListener(this); + //menubar.add(menu); + return menu; + } + + + protected JMenu buildSketchMenu() { + JMenuItem item; + JMenu menu = new Menu("Sketch"); + + menu.add(newMenuItem("Run", 'R')); + menu.add(newMenuItem("Present", 'R', true)); + menu.add(newMenuItem("Stop", 'T')); + menu.addSeparator(); + + menu.add(newMenuItem("Add file...")); + menu.add(newMenuItem("Create font...")); + + if ((platform == WINDOWS) || (platform == MACOSX)) { + // no way to do an 'open in file browser' on other platforms + // since there isn't any sort of standard + menu.add(newMenuItem("Show sketch folder")); + } + + history.attachMenu(menu); + + menu.addActionListener(this); + menubar.add(menu); // add the sketch menu + + + // help menu + + menu = new Menu("Help"); + menu.add(new MenuItem("Help")); + menu.add(new MenuItem("Reference")); + menu.add(new MenuItem("Proce55ing.net", new MenuShortcut('5'))); + + // macosx already has its own about menu + if (platform != MACOSX) { + menu.addSeparator(); + menu.add(new MenuItem("About Processing")); + } + menu.addActionListener(this); + menubar.setHelpMenu(menu); + + + // set all menus + + this.setMenuBar(menubar); + + public JMenu buildEditMenu() { JMenu menu = new JMenu("Edit"); JMenuItem item; - undoItem = PdeBase.newMenuItem("Undo", 'Z'); + undoItem = newMenuItem("Undo", 'Z'); undoItem.addActionListener(undoAction = new UndoAction()); menu.add(undoItem); - redoItem = PdeBase.newMenuItem("Redo", 'Y'); + redoItem = newMenuItem("Redo", 'Y'); redoItem.addActionListener(redoAction = new RedoAction()); menu.add(redoItem); @@ -378,7 +461,7 @@ public class PdeEditor extends JPanel { // "cut" and "copy" should really only be enabled // if some text is currently selected - item = PdeBase.newMenuItem("Cut", 'X'); + item = newMenuItem("Cut", 'X'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textarea.cut(); @@ -386,7 +469,7 @@ public class PdeEditor extends JPanel { }); menu.add(item); - item = PdeBase.newMenuItem("Copy", 'C'); + item = newMenuItem("Copy", 'C'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textarea.copy(); @@ -394,7 +477,7 @@ public class PdeEditor extends JPanel { }); menu.add(item); - item = PdeBase.newMenuItem("Paste", 'V'); + item = newMenuItem("Paste", 'V'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textarea.paste(); @@ -402,7 +485,7 @@ public class PdeEditor extends JPanel { }); menu.add(item); - item = PdeBase.newMenuItem("Select All", 'A'); + item = newMenuItem("Select All", 'A'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textarea.selectAll(); @@ -410,13 +493,13 @@ public class PdeEditor extends JPanel { }); menu.add(item); - beautifyMenuItem = PdeBase.newMenuItem("Beautify", 'B'); + beautifyMenuItem = newMenuItem("Beautify", 'B'); beautifyMenuItem.addActionListener(this); menu.add(beautifyMenuItem); menu.addSeparator(); - item = PdeBase.newMenuItem("Find...", 'F'); + item = newMenuItem("Find...", 'F'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { find(); @@ -424,7 +507,7 @@ public class PdeEditor extends JPanel { }); menu.add(item); - item = PdeBase.newMenuItem("Find Next", 'G'); + item = newMenuItem("Find Next", 'G'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { findNext(); @@ -432,7 +515,7 @@ public class PdeEditor extends JPanel { }); menu.add(item); - item = PdeBase.newMenuItem("Find in Reference", 'F', true); + item = newMenuItem("Find in Reference", 'F', true); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (textarea.isSelectionActive()) { @@ -455,6 +538,19 @@ public class PdeEditor extends JPanel { } + // antidote for overthought swing api mess for setting accelerators + + static public JMenuItem newMenuItem(String title, char what) { + return newMenuItem(title, what, false); + } + + static public JMenuItem newMenuItem(String title, char what, boolean shift) { + JMenuItem menuItem = new JMenuItem(title); + menuItem.setAccelerator(KeyStroke.getKeyStroke(what, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | (shift ? ActionEvent.SHIFT_MASK : 0))); + return menuItem; + } + + // This one listens for edits that can be undone. protected class PdeUndoableEditListener implements UndoableEditListener { public void undoableEditHappened(UndoableEditEvent e) { @@ -544,160 +640,6 @@ public class PdeEditor extends JPanel { } - // mode is RUN, SAVE or AUTO - public void makeHistory(String program, int mode) { - if (!base.recordingHistory) return; - //if (historyLast.equals(program) && !externalEditor) return; - if ((historyLast != null) && - (historyLast.equals(program))) return; - - String modeStr = null; - switch (mode) { - case RUN: modeStr = "run"; break; - case SAVE: modeStr = "save"; break; - case AUTOSAVE: modeStr = "autosave"; break; - case BEAUTIFY: modeStr = "beautify"; break; - } - - try { - boolean noPreviousHistory = false; - - ByteArrayOutputStream old = null; - if (historyFile.exists()) { - InputStream oldStream = new GZIPInputStream(new BufferedInputStream(new FileInputStream(historyFile))); - old = new ByteArrayOutputStream(); - - int c = oldStream.read(); - while (c != -1) { - old.write(c); - c = oldStream.read(); - } - //return out.toByteArray(); - oldStream.close(); - - } else { - noPreviousHistory = true; // rebuild menu - } - - OutputStream historyStream = - new GZIPOutputStream(new FileOutputStream(historyFile)); - - if (old != null) { - historyStream.write(old.toByteArray()); - } - PrintWriter historyWriter = - new PrintWriter(new OutputStreamWriter(historyStream)); - - historyWriter.println(); - historyWriter.println(HISTORY_SEPARATOR); - - Calendar now = Calendar.getInstance(); - // 2002 06 18 11 43 29 - // when listing, study for descrepancies.. if all are - // 2002, then don't list the year and soforth. - // for the other end, if all minutes are unique, - // then don't show seconds - int year = now.get(Calendar.YEAR); - int month = now.get(Calendar.MONTH) + 1; - int day = now.get(Calendar.DAY_OF_MONTH); - int hour = now.get(Calendar.HOUR_OF_DAY); - int minute = now.get(Calendar.MINUTE); - int second = now.get(Calendar.SECOND); - String parseDate = year + " " + month + " " + day + " " + - hour + " " + minute + " " + second; - - String readableDate = now.getTime().toString(); - - // increment this so sketchbook won't be mangled - // each time this format has to change - String historyVersion = "1"; - //Date date = new Date(); - //String datestamp = date.toString(); - - historyWriter.println(historyVersion + " " + modeStr + " - " + - parseDate + " - " + readableDate); - historyWriter.println(); - historyWriter.println(program); - historyWriter.flush(); // ?? - historyLast = program; - - //JMenuItem menuItem = new JMenuItem(modeStr + " - " + readableDate); - MenuItem menuItem = new MenuItem(modeStr + " - " + readableDate); - menuItem.addActionListener(base.historyMenuListener); - base.historyMenu.insert(menuItem, 2); - - historyWriter.flush(); - historyWriter.close(); - - if (noPreviousHistory) { - // to get add the actual menu, to get the 'clear' item in there - base.rebuildHistoryMenu(historyFile.getPath()); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - - - public void retrieveHistory(String selection) { - //System.out.println("sel '" + selection + "'"); - String readableDate = - selection.substring(selection.indexOf("-") + 2); - - // make history for the current guy - makeHistory(textarea.getText(), AUTOSAVE); - // mark editor text as having been edited - - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(historyFile)))); - String line = null; - - int historyCount = 0; - String historyList[] = new String[100]; - - try { - boolean found = false; - while ((line = reader.readLine()) != null) { - //System.out.println("->" + line); - if (line.equals(PdeEditor.HISTORY_SEPARATOR)) { - line = reader.readLine(); - if (line.indexOf(readableDate) != -1) { // this is the one - found = true; - break; - } - } - } - if (found) { - // read lines until the next separator - line = reader.readLine(); // ignored - //String sep = System.getProperty("line.separator"); - StringBuffer buffer = new StringBuffer(); - while ((line = reader.readLine()) != null) { - if (line.equals(PdeEditor.HISTORY_SEPARATOR)) break; - //textarea.append(line + sep); - //buffer.append(line + sep); // JTextPane wants only \n going in - buffer.append(line + "\n"); - //System.out.println("'" + line + "'"); - } - //textarea.editorSetText(buffer.toString()); - changeText(buffer.toString(), true); - historyLast = textarea.getText(); - setSketchModified(false); - - } else { - System.err.println("couldn't find history entry for " + - "'" + readableDate + "'"); - } - } catch (IOException e) { - e.printStackTrace(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - // in an advanced program, the returned classname could be different, // which is why the className is set based on the return value. // @param exporting if set, then code is cleaner, diff --git a/processing/app/PdeHistory.java b/processing/app/PdeHistory.java new file mode 100644 index 000000000..3f2771371 --- /dev/null +++ b/processing/app/PdeHistory.java @@ -0,0 +1,323 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + PdeHistory - handler for storing history information about a project + Part of the Processing project - http://Proce55ing.net + + Copyright (c) 2001-03 + Ben Fry, Massachusetts Institute of Technology and + Casey Reas, Interaction Design Institute Ivrea + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +import java.io.*; +import java.util.*; +import java.util.zip.*; + + +public class PdeHistory { + PdeEditor editor; + + // why things have been saved for history + static final int RUN = 5; + static final int SAVE = 6; + static final int AUTOSAVE = 7; + static final int BEAUTIFY = 8; + + static final String HISTORY_SEPARATOR = + "#################################################"; + + File historyFile; + //OutputStream historyStream; + //PrintWriter historyWriter; + String historyLast; + + + + ActionListener historyMenuListener = + new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.retrieveHistory(e.getActionCommand()); + } + }; + + + public PdeHistory(PdeEditor editor) { + this.editor = editor; + } + + + public void attachMenu(JMenu menu) { + if (PdePreferences.getBoolean("history.recording")) { + historyMenu = new Menu("History"); + menu.add(historyMenu); + } + } + + + //boolean recordingHistory; + JMenu historyMenu; + + + // mode is RUN, SAVE or AUTO + public void makeHistory(String program, int mode) { + if (!base.recordingHistory) return; + //if (historyLast.equals(program) && !externalEditor) return; + if ((historyLast != null) && + (historyLast.equals(program))) return; + + String modeStr = null; + switch (mode) { + case RUN: modeStr = "run"; break; + case SAVE: modeStr = "save"; break; + case AUTOSAVE: modeStr = "autosave"; break; + case BEAUTIFY: modeStr = "beautify"; break; + } + + try { + boolean noPreviousHistory = false; + + ByteArrayOutputStream old = null; + if (historyFile.exists()) { + InputStream oldStream = new GZIPInputStream(new BufferedInputStream(new FileInputStream(historyFile))); + old = new ByteArrayOutputStream(); + + int c = oldStream.read(); + while (c != -1) { + old.write(c); + c = oldStream.read(); + } + //return out.toByteArray(); + oldStream.close(); + + } else { + noPreviousHistory = true; // rebuild menu + } + + OutputStream historyStream = + new GZIPOutputStream(new FileOutputStream(historyFile)); + + if (old != null) { + historyStream.write(old.toByteArray()); + } + PrintWriter historyWriter = + new PrintWriter(new OutputStreamWriter(historyStream)); + + historyWriter.println(); + historyWriter.println(HISTORY_SEPARATOR); + + Calendar now = Calendar.getInstance(); + // 2002 06 18 11 43 29 + // when listing, study for descrepancies.. if all are + // 2002, then don't list the year and soforth. + // for the other end, if all minutes are unique, + // then don't show seconds + int year = now.get(Calendar.YEAR); + int month = now.get(Calendar.MONTH) + 1; + int day = now.get(Calendar.DAY_OF_MONTH); + int hour = now.get(Calendar.HOUR_OF_DAY); + int minute = now.get(Calendar.MINUTE); + int second = now.get(Calendar.SECOND); + String parseDate = year + " " + month + " " + day + " " + + hour + " " + minute + " " + second; + + String readableDate = now.getTime().toString(); + + // increment this so sketchbook won't be mangled + // each time this format has to change + String historyVersion = "1"; + //Date date = new Date(); + //String datestamp = date.toString(); + + historyWriter.println(historyVersion + " " + modeStr + " - " + + parseDate + " - " + readableDate); + historyWriter.println(); + historyWriter.println(program); + historyWriter.flush(); // ?? + historyLast = program; + + //JMenuItem menuItem = new JMenuItem(modeStr + " - " + readableDate); + MenuItem menuItem = new MenuItem(modeStr + " - " + readableDate); + menuItem.addActionListener(base.historyMenuListener); + base.historyMenu.insert(menuItem, 2); + + historyWriter.flush(); + historyWriter.close(); + + if (noPreviousHistory) { + // to get add the actual menu, to get the 'clear' item in there + base.rebuildHistoryMenu(historyFile.getPath()); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public void retrieveHistory(String selection) { + //System.out.println("sel '" + selection + "'"); + String readableDate = + selection.substring(selection.indexOf("-") + 2); + + // make history for the current guy + makeHistory(textarea.getText(), AUTOSAVE); + // mark editor text as having been edited + + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(historyFile)))); + String line = null; + + int historyCount = 0; + String historyList[] = new String[100]; + + try { + boolean found = false; + while ((line = reader.readLine()) != null) { + //System.out.println("->" + line); + if (line.equals(PdeEditor.HISTORY_SEPARATOR)) { + line = reader.readLine(); + if (line.indexOf(readableDate) != -1) { // this is the one + found = true; + break; + } + } + } + if (found) { + // read lines until the next separator + line = reader.readLine(); // ignored + //String sep = System.getProperty("line.separator"); + StringBuffer buffer = new StringBuffer(); + while ((line = reader.readLine()) != null) { + if (line.equals(PdeEditor.HISTORY_SEPARATOR)) break; + //textarea.append(line + sep); + //buffer.append(line + sep); // JTextPane wants only \n going in + buffer.append(line + "\n"); + //System.out.println("'" + line + "'"); + } + //textarea.editorSetText(buffer.toString()); + changeText(buffer.toString(), true); + historyLast = textarea.getText(); + setSketchModified(false); + + } else { + System.err.println("couldn't find history entry for " + + "'" + readableDate + "'"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /* + class HistoryMenuListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + editor.selectHistory(e.getActionCommand); + } + } + */ + + + public void rebuildHistoryMenu(String path) { + rebuildHistoryMenu(historyMenu, path); + } + + public void rebuildHistoryMenu(Menu menu, String path) { + if (!recordingHistory) return; + + menu.removeAll(); + + File hfile = new File(path); + if (!hfile.exists()) return; // no history yet + + MenuItem item = new MenuItem("Clear History"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (!editor.historyFile.delete()) { + System.err.println("couldn't erase history"); + } + rebuildHistoryMenu(historyMenu, editor.historyFile.getPath()); + } + }); + menu.add(item); + menu.addSeparator(); + + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(path)))); + String line = null; + + int historyCount = 0; + String historyList[] = new String[100]; + + try { + while ((line = reader.readLine()) != null) { + //while (line = reader.readLine()) { + //while (true) { line = reader.readLine(); + //if (line == null) continue; + //System.out.println("line: " + line); + if (line.equals(PdeEditor.HISTORY_SEPARATOR)) { + // next line is the good stuff + line = reader.readLine(); + int version = + Integer.parseInt(line.substring(0, line.indexOf(' '))); + if (version == 1) { + String whysub = line.substring(2); // after "1 " + String why = whysub.substring(0, whysub.indexOf(" -")); + //System.out.println("'" + why + "'"); + + String readable = line.substring(line.lastIndexOf("-") + 2); + if (historyList.length == historyCount) { + String temp[] = new String[historyCount*2]; + System.arraycopy(historyList, 0, temp, 0, historyCount); + historyList = temp; + } + historyList[historyCount++] = why + " - " + readable; + + } // otherwise don't know what to do + } + } + //System.out.println(line); + } catch (IOException e) { + e.printStackTrace(); + } + + // add the items to the menu in reverse order + /* + ActionListener historyMenuListener = + new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.retrieveHistory(e.getActionCommand()); + } + }; + */ + + for (int i = historyCount-1; i >= 0; --i) { + MenuItem mi = new MenuItem(historyList[i]); + mi.addActionListener(historyMenuListener); + menu.add(mi); + } + + reader.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/processing/app/PdePreferences.java b/processing/app/PdePreferences.java index 165547eee..ec2724af9 100644 --- a/processing/app/PdePreferences.java +++ b/processing/app/PdePreferences.java @@ -93,7 +93,7 @@ public class PdePreferences extends JComponent { JCheckBox newSketchPromptBox; JTextField sketchbookLocationField; - JCheckbox externalEditorBox; + JCheckBox externalEditorBox; // data model @@ -177,8 +177,8 @@ public class PdePreferences extends JComponent { // setup frame for the prefs - //frame = new JFrame("Preferences"); - frame = new JDialog("Preferences"); + frame = new JFrame("Preferences"); + //frame = new JDialog("Preferences"); frame.setResizable(false); Container pain = this; @@ -315,7 +315,7 @@ public class PdePreferences extends JComponent { button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { apply(); - hideFrame(); + disposeFrame(); } }); pain.add(button); @@ -327,7 +327,7 @@ public class PdePreferences extends JComponent { button = new JButton(PROMPT_CANCEL); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - hideFrame(); + disposeFrame(); } }); pain.add(button); @@ -353,11 +353,13 @@ public class PdePreferences extends JComponent { // + /* frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { frame.hide(); } }); + */ } @@ -369,8 +371,9 @@ public class PdePreferences extends JComponent { } - public void hideFrame() { - frame.hide(); + public void disposeFrame() { + frame.hide() + //frame.dispose(); } @@ -547,6 +550,12 @@ public class PdePreferences extends JComponent { defaultValue : value; } + + static public void set(String attribute, String value) { + preferences.put(attribute, value); + } + + static public boolean getBoolean(String attribute /*, boolean defaultValue*/) { String value = get(attribute, null); return (value == null) ? defaultValue : @@ -566,6 +575,12 @@ public class PdePreferences extends JComponent { */ } + + static public boolean setBoolean(String attribute, boolean value) { + set(attribute, value ? "true" : "false"); + } + + static public int getInteger(String attribute /*, int defaultValue*/) { String value = get(attribute, null); if (value == null) return defaultValue; @@ -583,6 +598,11 @@ public class PdePreferences extends JComponent { } + static public void setInteger(String key, int value) { + set(key, String.valueOf(value)); + } + + static public Color getColor(String name /*, Color otherwise*/) { Color parsed = null; String s = get(name, null); diff --git a/processing/app/PdePreprocessorOro.java b/processing/app/PdePreprocessorOro.java index 2d8a487ca..2b6abfc4e 100644 --- a/processing/app/PdePreprocessorOro.java +++ b/processing/app/PdePreprocessorOro.java @@ -23,6 +23,11 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef HELL_HAS_FROZEN_OVER +// disable this guy for a little while + + import com.oroinc.text.regex.*; import java.io.*; @@ -430,3 +435,6 @@ public class PdePreprocessorOro extends PdePreprocessor { //} } } + + +#endif diff --git a/processing/app/PdeSketchbook.java b/processing/app/PdeSketchbook.java new file mode 100644 index 000000000..ed4ffdb13 --- /dev/null +++ b/processing/app/PdeSketchbook.java @@ -0,0 +1,44 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + PdeSketchbook - handles sketchbook mechanics for the sketch menu + Part of the Processing project - http://Proce55ing.net + + Except where noted, code is written by Ben Fry + Copyright (c) 2001-03 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.*; + + +public class PdeSketchbook { + JMenu sketchbookMenu; + File sketchbookFolder; + String sketchbookPath; + + +} diff --git a/processing/build/macosx/make.sh b/processing/build/macosx/make.sh index f76c9ec7e..6913ac2c0 100755 --- a/processing/build/macosx/make.sh +++ b/processing/build/macosx/make.sh @@ -122,11 +122,11 @@ cd app # but for now, the parser is only built when the work dir # is created, to speed the build process. -if test -f preprocessor/expandedpde.g -then -echo -else -cd preprocessor +#if test -f preprocessor/expandedpde.g +#then +#echo +#else + cd preprocessor # build classes/grammar for preprocessor echo Building antlr grammar code... # first build the default java goop @@ -134,7 +134,7 @@ cd preprocessor # now build the pde stuff that extends the java classes java -cp ../../build/macosx/work/lib/antlr.jar antlr.Tool -glib java.g pde.g cd .. -fi +#fi ### -- BUILD PDE ------------------------------------------------ diff --git a/processing/build/shared/lib/pde.properties b/processing/build/shared/lib/pde.properties index 936b4856e..7287875b3 100644 --- a/processing/build/shared/lib/pde.properties +++ b/processing/build/shared/lib/pde.properties @@ -1,10 +1,14 @@ -# These are the default preferences for Processing +# !!!!!!!! UNLIKE PREVIOUS VERSIONS OF PROCESSING !!!!!!!!!! +# DO NOT MODIFY THIS FILE, OR DELETE SETTINGS FROM THIS FILE -# They will be copied to your home folder into a file called -# .processing, where you can make changes for your machine. +# These are the default preferences. They will be copied +# to your home folder into a file called .processing, +# where you can make changes for your machine. -# a pound sign at the beginning of a line is a comment -# parameters need to be un-commented before they take effect +# You'll have problems running Processing if you incorrectly +# modify lines in this file. + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # default size for the main window @@ -14,6 +18,12 @@ default.window.height = 500 # font size for editor editor.font=Monospaced,plain,12 +# monospaced on java 1.3 was monaco, but on 1.4 it has changed +# to courier, which actually matches other platforms better. +# (and removes the 12 point being too large issue) +# monaco is nicer on macosx, so use that explicitly +editor.font.macosx = Monaco,plain,10 + # anti-aliased text, turned off by default editor.antialias=false @@ -87,15 +97,9 @@ console.bgcolor = #1A1A00 console.fgcolor.output = #ccccbb console.fgcolor.error = #ff3000 console.font = Monospaced,plain,11 +console.font.macosx = Monaco,plain,10 console.lines = 4 -# monospaced on java 1.3 was monaco, but on 1.4 it has changed -# to courier, which actually matches other platforms better. -# (and removes the 12 point being too large issue) -# monaco is nicer on macosx, so use that explicitly -editor.font.macosx = Monaco,plain,10 -console.font.macosx = Monaco,plain,10 - editor.status.notice.fgcolor = #333322 editor.status.notice.bgcolor = #bbbbaa editor.status.error.fgcolor = #ffffee @@ -131,6 +135,8 @@ sketchbook.prompt = false # note that this path should use forward slashes (like unix) # instead of \ on windows or : on windows or whatever else +history.recording = true + # may be useful when attempting to debug the preprocessor #editor.save_build_files=false