diff --git a/README.md b/README.md index 22f7e1966..0746ca999 100644 --- a/README.md +++ b/README.md @@ -17,18 +17,18 @@ changes made by [processing-bugs](https://github.com/processing-bugs), it may be Over time this will clean itself up as bugs are fixed and new issues are added from within Github. Help speed this process along by helping us! -The [processing-web](https://github.com/processing/processing-web/) repository -contains reference, examples, and the site. +The [processing-docs](https://github.com/processing/processing-docs/) repository contains reference, examples, and the site. (Please use that link to file issues regarding the web site, the examples, or the reference.) The instructions for building the source [are here](https://github.com/processing/processing/wiki/Build-Instructions). Someday we'll also write code style guidelines, fix all these bugs, -throw together hundreds of unit tests, and solve the Israeli-Palestinian conflict. +throw together hundreds of unit tests, +and get rich off all this stuff that we're giving away for free. But in the meantime, I ask for your patience, [participation](https://github.com/processing/processing/wiki/Project-List), and [patches](https://github.com/processing/processing/pulls). Ben Fry, 3 February 2013 -Last updated 8 June 2014 +Last updated 30 July 2014 diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index a24ee9a93..db6ed2383 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -602,32 +602,37 @@ public class Base { } + /** + * The call has already checked to make sure this sketch is not modified, + * now change the mode. + */ protected void changeMode(Mode mode) { if (activeEditor.getMode() != mode) { Sketch sketch = activeEditor.getSketch(); nextMode = mode; - - // If the current editor contains file extensions that the new mode can handle, then - // write a sketch.properties file with the new mode specified, and reopen. - boolean newModeCanHandleCurrentSource = true; - for (final SketchCode code: sketch.getCode()) { - if (!mode.validExtension(code.getExtension())) { - newModeCanHandleCurrentSource = false; - break; - } - } - if (newModeCanHandleCurrentSource) { - final File props = new File(sketch.getCodeFolder(), "sketch.properties"); - saveModeSettings(props, nextMode); + + if (sketch.isUntitled()) { + // If no changes have been made, just close and start fresh. + // (Otherwise the editor would lose its 'untitled' status.) handleClose(activeEditor, true); - handleOpen(sketch.getMainFilePath()); - } else { - // If you're changing modes, and there's nothing in the current sketch, you probably - // don't intend to keep the old, wrong-mode editor around. - if (sketch.isUntitled()) { - handleClose(activeEditor, true); - } handleNew(); + + } else { + // If the current editor contains file extensions that the new mode can handle, then + // write a sketch.properties file with the new mode specified, and reopen. + boolean newModeCanHandleCurrentSource = true; + for (final SketchCode code: sketch.getCode()) { + if (!mode.validExtension(code.getExtension())) { + newModeCanHandleCurrentSource = false; + break; + } + } + if (newModeCanHandleCurrentSource) { + final File props = new File(sketch.getCodeFolder(), "sketch.properties"); + saveModeSettings(props, nextMode); + handleClose(activeEditor, true); + handleOpen(sketch.getMainFilePath()); + } } } } @@ -921,14 +926,18 @@ public class Base { return null; } - // System.err.println(" editors: " + editors); // Cycle through open windows to make sure that it's not already open. for (Editor editor : editors) { - if (editor.getSketch().getMainFile().equals(file)) { - editor.toFront(); - // move back to the top of the recent list - handleRecent(editor); - return editor; + // User may have double-clicked any PDE in the sketch folder, + // so we have to check each open tab (not just the main one). + // https://github.com/processing/processing/issues/2506 + for (SketchCode tab : editor.getSketch().getCode()) { + if (tab.getFile().equals(file)) { + editor.toFront(); + // move back to the top of the recent list + handleRecent(editor); + return editor; + } } } @@ -951,8 +960,6 @@ public class Base { // Editor.State state = new Editor.State(editors); Editor editor = nextMode.createEditor(this, path, state); if (editor == null) { - // if it's the last editor window -// if (editors.size() == 0 && defaultFileMenu == null) { // if it's not mode[0] already, then don't go into an infinite loop // trying to recreate a window with the default mode. if (nextMode == coreModes[0]) { @@ -965,15 +972,14 @@ public class Base { editor = coreModes[0].createEditor(this, path, state); } } - + // Make sure that the sketch actually loaded - if (editor.getSketch() == null) { -// System.err.println("sketch was null, getting out of handleOpen"); + Sketch sketch = editor.getSketch(); + if (sketch == null) { return null; // Just walk away quietly } -// editor.untitled = untitled; - editor.getSketch().setUntitled(untitled); + sketch.setUntitled(untitled); editors.add(editor); handleRecent(editor); @@ -1858,41 +1864,15 @@ public class Base { } -// static public String getExamplesPath() { -// return examplesFolder.getAbsolutePath(); -// } - -// public File getExamplesFolder() { -// return examplesFolder; -// } - - -// static public String getLibrariesPath() { -// return librariesFolder.getAbsolutePath(); -// } - - -// public File getLibrariesFolder() { -// return librariesFolder; -// } - - -// static public File getToolsFolder() { static public File getToolsFolder() { -// return toolsFolder; return getContentFile("tools"); } -// static public String getToolsPath() { -// return toolsFolder.getAbsolutePath(); -// } - - static public void locateSketchbookFolder() { // If a value is at least set, first check to see if the folder exists. // If it doesn't, warn the user that the sketchbook folder is being reset. - String sketchbookPath = Preferences.get("sketchbook.path"); //$NON-NLS-1$ + String sketchbookPath = Preferences.getSketchbookPath(); if (sketchbookPath != null) { sketchbookFolder = new File(sketchbookPath); if (!sketchbookFolder.exists()) { @@ -1909,7 +1889,7 @@ public class Base { // If no path is set, get the default sketchbook folder for this platform if (sketchbookFolder == null) { sketchbookFolder = getDefaultSketchbookFolder(); - Preferences.set("sketchbook.path", sketchbookFolder.getAbsolutePath()); + Preferences.setSketchbookPath(sketchbookFolder.getAbsolutePath()); if (!sketchbookFolder.exists()) { sketchbookFolder.mkdirs(); } @@ -1924,19 +1904,17 @@ public class Base { public void setSketchbookFolder(File folder) { sketchbookFolder = folder; - Preferences.set("sketchbook.path", folder.getAbsolutePath()); + Preferences.setSketchbookPath(folder.getAbsolutePath()); rebuildSketchbookMenus(); } static public File getSketchbookFolder() { -// return new File(Preferences.get("sketchbook.path")); return sketchbookFolder; } static public File getSketchbookLibrariesFolder() { -// return new File(getSketchbookFolder(), "libraries"); return new File(sketchbookFolder, "libraries"); } diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index fe18ab4a2..480f79919 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -606,6 +606,16 @@ public abstract class Editor extends JFrame implements RunnerListener { fileMenu.add(item); fileMenu.add(base.getSketchbookMenu()); + + JMenuItem sbMenu = Toolkit.newJMenuItemShift("Sketchbook Tree", 'K'); + sbMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mode.showSketchbookFrame(); + } + }); + + fileMenu.add(sbMenu); // fileMenu.add(mode.getExamplesMenu()); item = Toolkit.newJMenuItemShift("Examples...", 'O'); @@ -2444,7 +2454,10 @@ public abstract class Editor extends JFrame implements RunnerListener { statusNotice("Saving..."); try { if (sketch.saveAs()) { - statusNotice("Done Saving."); + // statusNotice("Done Saving."); + // status is now printed from Sketch so that "Done Saving." + // is only printed after Save As when progress bar is shown. + // Disabling this for 0125, instead rebuild the menu inside // the Save As method of the Sketch object, since that's the // only one who knows whether something was renamed. diff --git a/app/src/processing/app/EditorConsole.java b/app/src/processing/app/EditorConsole.java index 6ad9eb709..935539841 100644 --- a/app/src/processing/app/EditorConsole.java +++ b/app/src/processing/app/EditorConsole.java @@ -212,7 +212,13 @@ public class EditorConsole extends JScrollPane { StyleConstants.setBold(errStyle, font.isBold()); StyleConstants.setItalic(errStyle, font.isItalic()); - consoleTextPane.setBackground(bgColor); + if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { + getViewport().setBackground(bgColor); + consoleTextPane.setOpaque(false); + consoleTextPane.setBackground(new Color(0, 0, 0, 0)); + } else { + consoleTextPane.setBackground(bgColor); + } // calculate height of a line of text in pixels // and size window accordingly diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index 741474606..5f0779e3d 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -879,6 +879,104 @@ public abstract class Mode { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + public DefaultMutableTreeNode buildSketchbookTree(){ + DefaultMutableTreeNode sbNode = new DefaultMutableTreeNode("Sketchbook"); + try { + base.addSketches(sbNode, Base.getSketchbookFolder()); + } catch (IOException e) { + e.printStackTrace(); + } + return sbNode; + } + + protected JFrame sketchbookFrame; + + public void showSketchbookFrame() { + if (sketchbookFrame == null) { + sketchbookFrame = new JFrame("Processing Sketchbook"); + Toolkit.setIcon(sketchbookFrame); + Toolkit.registerWindowCloseKeys(sketchbookFrame.getRootPane(), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + sketchbookFrame.setVisible(false); + } + }); + + final JTree tree = new JTree(buildSketchbookTree()); + tree.getSelectionModel() + .setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.setShowsRootHandles(true); + tree.expandRow(0); + tree.setRootVisible(false); + + tree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree + .getLastSelectedPathComponent(); + + int selRow = tree.getRowForLocation(e.getX(), e.getY()); + //TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); + //if (node != null && node.isLeaf() && node.getPath().equals(selPath)) { + if (node != null && node.isLeaf() && selRow != -1) { + SketchReference sketch = (SketchReference) node.getUserObject(); + base.handleOpen(sketch.getPath()); + } + } + } + }); + + tree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { // doesn't fire keyTyped() + sketchbookFrame.setVisible(false); + } + } + + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == KeyEvent.VK_ENTER) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree + .getLastSelectedPathComponent(); + if (node != null && node.isLeaf()) { + SketchReference sketch = (SketchReference) node.getUserObject(); + base.handleOpen(sketch.getPath()); + } + } + } + }); + + tree.setBorder(new EmptyBorder(5, 5, 5, 5)); + if (Base.isMacOS()) { + tree.setToggleClickCount(2); + } else { + tree.setToggleClickCount(1); + } + JScrollPane treePane = new JScrollPane(tree); + treePane.setPreferredSize(new Dimension(250, 450)); + treePane.setBorder(new EmptyBorder(0, 0, 0, 0)); + sketchbookFrame.getContentPane().add(treePane); + sketchbookFrame.pack(); + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + // Space for the editor plus a li'l gap + int roughWidth = sketchbookFrame.getWidth() + 20; + Point p = null; + // If no window open, or the editor is at the edge of the screen + if (base.activeEditor == null + || (p = base.activeEditor.getLocation()).x < roughWidth) { + // Center the window on the screen + sketchbookFrame.setLocationRelativeTo(null); + } else { + // Open the window relative to the editor + sketchbookFrame.setLocation(p.x - roughWidth, p.y); + } + sketchbookFrame.setVisible(true); + } + }); + } /** * Get an image object from the theme folder. diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 77343774e..b03a9b991 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-12 Ben Fry and Casey Reas + Copyright (c) 2004-14 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -100,7 +100,7 @@ public class Preferences { // and linux is all over the map static final int GUI_BIG = 13; - static final int GUI_BETWEEN = 10; + static final int GUI_BETWEEN = 8; static final int GUI_SMALL = 6; // gui elements @@ -117,7 +117,6 @@ public class Preferences { JCheckBox memoryOverrideBox; JTextField memoryField; JCheckBox checkUpdatesBox; - //JTextField fontSizeField; JComboBox fontSizeField; JComboBox consoleSizeField; JCheckBox inputMethodBox; @@ -131,13 +130,9 @@ public class Preferences { JCheckBox importSuggestionsBox; JCheckBox codeCompletionTriggerBox; - //JRadioButton bitsThirtyTwoButton; - //JRadioButton bitsSixtyFourButton; - JComboBox displaySelectionBox; int displayCount; - //Font[] monoFontList; String[] monoFontFamilies; JComboBox fontSelectionBox; @@ -168,16 +163,6 @@ public class Preferences { // check for platform-specific properties in the defaults String platformExt = "." + PConstants.platformNames[PApplet.platform]; //$NON-NLS-1$ int platformExtLength = platformExt.length(); -// Enumeration e = table.keys(); -// while (e.hasMoreElements()) { -// String key = (String) e.nextElement(); -// if (key.endsWith(platformExt)) { -// // this is a key specific to a particular platform -// String actualKey = key.substring(0, key.length() - platformExtLength); -// String value = get(key); -// table.put(actualKey, value); -// } -// } // Get a list of keys that are specific to this platform ArrayList platformKeys = new ArrayList(); @@ -200,28 +185,10 @@ public class Preferences { // other things that have to be set explicitly for the defaults setColor("run.window.bgcolor", SystemColor.control); //$NON-NLS-1$ - - // Load a prefs file if specified on the command line -// if (commandLinePrefs != null) { -// try { -// load(new FileInputStream(commandLinePrefs)); -// -// } catch (Exception poe) { -// Base.showError("Error", -// "Could not read preferences from " + -// commandLinePrefs, poe); -// } -// } else if (!Base.isCommandLine()) { + // next load user preferences file preferencesFile = Base.getSettingsFile(PREFS_FILE); - if (!preferencesFile.exists()) { - // create a new preferences file if none exists - // saves the defaults out to the file - save(); - - } else { - // load the previous preferences file - + if (preferencesFile.exists()) { try { load(new FileInputStream(preferencesFile)); @@ -232,7 +199,12 @@ public class Preferences { preferencesFile.getAbsolutePath() + " and restart Processing.", ex); } -// } + } + + if (checkSketchbookPref() || !preferencesFile.exists()) { + // create a new preferences file if none exists + // saves the defaults out to the file + save(); } PApplet.useNativeSelect = @@ -257,11 +229,6 @@ public class Preferences { dialog = new JFrame("Preferences"); dialog.setResizable(false); -// GroupLayout layout = new GroupLayout(getContentPane()); -// dialog.getContentPane().setLayout(layout); -// layout.setAutoCreateGaps(true); -// layout.setAutoCreateContainerGaps(true); - Container pain = dialog.getContentPane(); pain.setLayout(null); @@ -296,11 +263,6 @@ public class Preferences { PApplet.selectFolder("Select new sketchbook location", "sketchbookCallback", dflt, Preferences.this, dialog); -// File file = -// Base.selectFolder("Select new sketchbook location", dflt, dialog); -// if (file != null) { -// sketchbookLocationField.setText(file.getAbsolutePath()); -// } } }); pain.add(button); @@ -357,12 +319,9 @@ public class Preferences { label = new JLabel("Editor font size: "); box.add(label); - //fontSizeField = new JTextField(4); fontSizeField = new JComboBox(FONT_SIZES); fontSizeField.setEditable(true); box.add(fontSizeField); -// label = new JLabel(" (requires restart of Processing)"); -// box.add(label); box.add(Box.createHorizontalStrut(GUI_BETWEEN)); label = new JLabel("Console font size: "); @@ -374,9 +333,6 @@ public class Preferences { pain.add(box); d = box.getPreferredSize(); box.setBounds(left, top, d.width, d.height); -// Font editorFont = Preferences.getFont("editor.font"); - //fontSizeField.setText(String.valueOf(editorFont.getSize())); -// fontSizeField.setSelectedItem(editorFont.getSize()); fontSizeField.setSelectedItem(Preferences.getFont("editor.font.size")); top += d.height + GUI_BETWEEN; @@ -509,8 +465,6 @@ public class Preferences { // [ ] Use smooth text in editor window editorAntialiasBox = new JCheckBox("Use smooth text in editor window"); -// new JCheckBox("Use smooth text in editor window " + -// "(requires restart of Processing)"); pain.add(editorAntialiasBox); d = editorAntialiasBox.getPreferredSize(); // adding +10 because ubuntu + jre 1.5 truncating items @@ -530,24 +484,25 @@ public class Preferences { right = Math.max(right, left + d.width); top += d.height + GUI_BETWEEN; - // [ ] Enable Error Checking - PDE X + // [ ] Continuously check for errors - PDE X errorCheckerBox = - new JCheckBox("Enable error checking"); + new JCheckBox("Continuously check for errors"); pain.add(errorCheckerBox); d = errorCheckerBox.getPreferredSize(); errorCheckerBox.setBounds(left, top, d.width + 10, d.height); - right = Math.max(right, left + d.width); - top += d.height + GUI_BETWEEN; + //right = Math.max(right, left + d.width); + //top += d.height + GUI_BETWEEN; + int warningLeft = left + d.width; - // [ ] Enable Warnings - PDE X + // [ ] Show Warnings - PDE X warningsCheckerBox = - new JCheckBox("Enable warnings"); + new JCheckBox("Show warnings"); pain.add(warningsCheckerBox); d = warningsCheckerBox.getPreferredSize(); - warningsCheckerBox.setBounds(left, top, d.width + 10, d.height); - right = Math.max(right, left + d.width); + warningsCheckerBox.setBounds(warningLeft, top, d.width + 10, d.height); + right = Math.max(right, warningLeft + d.width); top += d.height + GUI_BETWEEN; // [ ] Enable Code Completion - PDE X @@ -557,17 +512,17 @@ public class Preferences { pain.add(codeCompletionBox); d = codeCompletionBox.getPreferredSize(); codeCompletionBox.setBounds(left, top, d.width + 10, d.height); - right = Math.max(right, left + d.width); - top += d.height + GUI_BETWEEN; + int toggleLeft = left + d.width; // [ ] Toggle Code Completion Trigger - PDE X + final String modifier = Base.isMacOS() ? "\u2318" : "Ctrl"; codeCompletionTriggerBox = - new JCheckBox("Trigger code completion on Ctrl(Cmd) + Space"); + new JCheckBox("Trigger with " + modifier + "-space"); pain.add(codeCompletionTriggerBox); d = codeCompletionTriggerBox.getPreferredSize(); - codeCompletionTriggerBox.setBounds(left, top, d.width + 10, d.height); - right = Math.max(right, left + d.width); + codeCompletionTriggerBox.setBounds(toggleLeft, top, d.width + 10, d.height); + right = Math.max(right, toggleLeft + d.width); top += d.height + GUI_BETWEEN; @@ -585,19 +540,6 @@ public class Preferences { top += d.height + GUI_BETWEEN; -// // [ ] Use multiple .jar files when exporting applets -// -// exportSeparateBox = -// new JCheckBox("Use multiple .jar files when exporting applets " + -// "(ignored when using libraries)"); -// pain.add(exportSeparateBox); -// d = exportSeparateBox.getPreferredSize(); -// // adding +10 because ubuntu + jre 1.5 truncating items -// exportSeparateBox.setBounds(left, top, d.width + 10, d.height); -// right = Math.max(right, left + d.width); -// top += d.height + GUI_BETWEEN; - - // [ ] Delete previous application folder on export deletePreviousBox = @@ -609,17 +551,7 @@ public class Preferences { top += d.height + GUI_BETWEEN; -// // [ ] Use external editor -// -// externalEditorBox = new JCheckBox("Use external editor"); -// pain.add(externalEditorBox); -// d = externalEditorBox.getPreferredSize(); -// externalEditorBox.setBounds(left, top, d.width + 10, d.height); -// right = Math.max(right, left + d.width); -// top += d.height + GUI_BETWEEN; - - - // [ ] Use external editor + // [ ] Hide tab/toolbar background image whinyBox = new JCheckBox("Hide tab/toolbar background image (requires restart)"); pain.add(whinyBox); @@ -672,30 +604,6 @@ public class Preferences { } - // Launch programs as [ ] 32-bit [ ] 64-bit (Mac OS X only) - - /* - if (Base.isMacOS()) { - box = Box.createHorizontalBox(); - label = new JLabel("Launch programs in "); - box.add(label); - bitsThirtyTwoButton = new JRadioButton("32-bit mode "); - box.add(bitsThirtyTwoButton); - bitsSixtyFourButton = new JRadioButton("64-bit mode"); - box.add(bitsSixtyFourButton); - - ButtonGroup bg = new ButtonGroup(); - bg.add(bitsThirtyTwoButton); - bg.add(bitsSixtyFourButton); - - pain.add(box); - d = box.getPreferredSize(); - box.setBounds(left, top, d.width, d.height); - top += d.height + GUI_BETWEEN; - } - */ - - // More preferences are in the ... label = new JLabel("More preferences can be edited directly in the file"); @@ -854,7 +762,7 @@ public class Preferences { // each platform, and nobody wants to debug/support that. // if the sketchbook path has changed, rebuild the menus - String oldPath = get("sketchbook.path"); //$NON-NLS-1$ + String oldPath = getSketchbookPath(); String newPath = sketchbookLocationField.getText(); if (!newPath.equals(oldPath)) { base.setSketchbookFolder(new File(newPath)); @@ -889,52 +797,12 @@ public class Preferences { System.err.println("Ignoring bad memory setting"); } - /* - // was gonna use this to check memory settings, - // but it quickly gets much too messy - if (getBoolean("run.options.memory")) { - Process process = Runtime.getRuntime().exec(new String[] { - "java", "-Xms" + memoryMin + "m", "-Xmx" + memoryMax + "m" - }); - processInput = new SystemOutSiphon(process.getInputStream()); - processError = new MessageSiphon(process.getErrorStream(), this); - } - */ - - /* - // If a change has been made between 32- and 64-bit, the libraries need - // to be reloaded so that their native paths are set correctly. - if (Base.isMacOS()) { - String oldBits = get("run.options.bits"); //$NON-NLS-1$ - String newBits = bitsThirtyTwoButton.isSelected() ? "32" : "64"; //$NON-NLS-1$ //$NON-NLS-2$ - if (!oldBits.equals(newBits)) { - set("run.options.bits", newBits); //$NON-NLS-1$ - for (Mode m : base.getModeList()) { - m.rebuildLibraryList(); - } - } - } - */ - // Don't change anything if the user closes the window before fonts load if (fontSelectionBox.isEnabled()) { String fontFamily = (String) fontSelectionBox.getSelectedItem(); set("editor.font.family", fontFamily); } - /* - String newSizeText = fontSizeField.getText(); - try { - int newSize = Integer.parseInt(newSizeText.trim()); - //String pieces[] = PApplet.split(get("editor.font"), ','); //$NON-NLS-1$ - //pieces[2] = String.valueOf(newSize); - //set("editor.font", PApplet.join(pieces, ',')); //$NON-NLS-1$ - set("editor.font.size", String.valueOf(newSize)); - - } catch (Exception e) { - Base.log("Ignoring invalid font size " + newSizeText); //$NON-NLS-1$ - } - */ try { Object selection = fontSizeField.getSelectedItem(); if (selection instanceof String) { @@ -988,34 +856,18 @@ public class Preferences { warningsCheckerBox.setSelected(getBoolean("pdex.warningsEnabled")); codeCompletionBox.setSelected(getBoolean("pdex.ccEnabled")); codeCompletionTriggerBox.setSelected(getBoolean("pdex.ccTriggerEnabled")); - // set all settings entry boxes to their actual status -// exportSeparateBox. -// setSelected(getBoolean("export.applet.separate_jar_files")); deletePreviousBox. setSelected(getBoolean("export.delete_target_folder")); //$NON-NLS-1$ - //closingLastQuitsBox. - // setSelected(getBoolean("sketchbook.closing_last_window_quits")); - //sketchPromptBox. - // setSelected(getBoolean("sketchbook.prompt")); - //sketchCleanBox. - // setSelected(getBoolean("sketchbook.auto_clean")); - - sketchbookLocationField. - setText(get("sketchbook.path")); //$NON-NLS-1$ -// externalEditorBox. -// setSelected(getBoolean("editor.external")); - checkUpdatesBox. - setSelected(getBoolean("update.check")); //$NON-NLS-1$ + sketchbookLocationField.setText(getSketchbookPath()); + checkUpdatesBox.setSelected(getBoolean("update.check")); //$NON-NLS-1$ whinyBox.setSelected(getBoolean("header.hide.image") || //$NON-NLS-1$ getBoolean("buttons.hide.image")); //$NON-NLS-1$ updateDisplayList(); int displayNum = getInteger("run.display"); //$NON-NLS-1$ -// System.out.println("display is " + displayNum + ", d count is " + displayCount); if (displayNum >= 0 && displayNum < displayCount) { -// System.out.println("setting num to " + displayNum); displaySelectionBox.setSelectedIndex(displayNum); } @@ -1037,22 +889,6 @@ public class Preferences { memoryField. setText(get("run.options.memory.maximum")); //$NON-NLS-1$ - /* - if (Base.isMacOS()) { - String bits = Preferences.get("run.options.bits"); //$NON-NLS-1$ - if (bits.equals("32")) { //$NON-NLS-1$ - bitsThirtyTwoButton.setSelected(true); - } else if (bits.equals("64")) { //$NON-NLS-1$ - bitsSixtyFourButton.setSelected(true); - } - // in case we go back and support OS X 10.5... - if (System.getProperty("os.version").startsWith("10.5")) { //$NON-NLS-1$ //$NON-NLS-2$ - bitsSixtyFourButton.setSelected(true); - bitsThirtyTwoButton.setEnabled(false); - } - } - */ - if (autoAssociateBox != null) { autoAssociateBox. setSelected(getBoolean("platform.auto_file_type_associations")); //$NON-NLS-1$ @@ -1080,37 +916,11 @@ public class Preferences { void initFontList() { - /* - if (monoFontList == null) { - monoFontList = Toolkit.getMonoFontList().toArray(new Font[0]); - fontSelectionBox.setModel(new DefaultComboBoxModel(monoFontList)); - fontSelectionBox.setRenderer(new FontNamer()); - - // Preferred size just makes it extend to the container - //fontSelectionBox.setSize(fontSelectionBox.getPreferredSize()); - // Minimum size is better, but cuts things off (on OS X), so we add 20 - //Dimension minSize = fontSelectionBox.getMinimumSize(); - //Dimension minSize = fontSelectionBox.getPreferredSize(); - //fontSelectionBox.setSize(minSize.width + 20, minSize.height); - fontSelectionBox.setEnabled(true); - } - */ if (monoFontFamilies == null) { monoFontFamilies = Toolkit.getMonoFontFamilies(); fontSelectionBox.setModel(new DefaultComboBoxModel(monoFontFamilies)); String family = get("editor.font.family"); -// System.out.println("family is " + family); -// System.out.println("font sel items = " + fontSelectionBox.getItemCount()); -// for (int i = 0; i < fontSelectionBox.getItemCount(); i++) { -// String item = (String) fontSelectionBox.getItemAt(i); -// if (fontSelectionBox.getItemAt(i) == family) { -// System.out.println("found at index " + i); -// } else if (item.equals(family)) { -// System.out.println("equals at index " + i); -// } else { -// System.out.println("nothing doing: " + item); -// } -// } + // Set a reasonable default, in case selecting the family fails fontSelectionBox.setSelectedItem("Monospaced"); fontSelectionBox.setSelectedItem(family); @@ -1134,22 +944,6 @@ public class Preferences { } - // Workaround for Apple bullsh*t caused by their not releasing a 32-bit - // version of Java for Mac OS X 10.5. -// static public String checkBits() { -// String bits = Preferences.get("run.options.bits"); -// if (bits == null) { -// if (System.getProperty("os.version").startsWith("10.5")) { -// bits = "64"; -// } else { -// bits = "32"; -// } -// Preferences.set("run.options.bits", bits); -// } -// return bits; -// } - - // ................................................................. @@ -1208,20 +1002,8 @@ public class Preferences { // all the information from preferences.txt - //static public String get(String attribute) { - //return get(attribute, null); - //} - static public String get(String attribute /*, String defaultValue */) { return table.get(attribute); - /* - //String value = (properties != null) ? - //properties.getProperty(attribute) : applet.getParameter(attribute); - String value = properties.getProperty(attribute); - - return (value == null) ? - defaultValue : value; - */ } @@ -1359,28 +1141,37 @@ public class Preferences { } return new Font("Dialog", Font.PLAIN, 12); } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + - - /* - static public SyntaxStyle getStyle(String what) { - String str = get("editor." + what + ".style"); //, dflt); //$NON-NLS-1$ //$NON-NLS-2$ - - StringTokenizer st = new StringTokenizer(str, ","); //$NON-NLS-1$ - - String s = st.nextToken(); - if (s.indexOf("#") == 0) s = s.substring(1); //$NON-NLS-1$ - Color color = Color.DARK_GRAY; - try { - color = new Color(Integer.parseInt(s, 16)); - } catch (Exception e) { } - - s = st.nextToken(); - boolean bold = (s.indexOf("bold") != -1); //$NON-NLS-1$ -// boolean italic = (s.indexOf("italic") != -1); //$NON-NLS-1$ - //System.out.println(what + " = " + str + " " + bold + " " + italic); - -// return new SyntaxStyle(color, italic, bold); - return new SyntaxStyle(color, bold); + /** + * Check for a 3.0 sketchbook location, and if none exists, + * try to grab it from the 2.0 sketchbook location. + * @return true if a location was found and the pref didn't exist + */ + static protected boolean checkSketchbookPref() { + // If a 3.0 sketchbook location has never been inited + if (getSketchbookPath() == null) { + String twoPath = get("sketchbook.path"); + // If they've run the 2.0 version, start with that location + if (twoPath != null) { + setSketchbookPath(twoPath); + return true; // save the sketchbook right away + } + // Otherwise it'll be null, and reset properly by Base + } + return false; + } + + + static protected String getSketchbookPath() { + return get("sketchbook.path.three"); //$NON-NLS-1$ + } + + + static protected void setSketchbookPath(String path) { + set("sketchbook.path.three", path); //$NON-NLS-1$ } - */ } diff --git a/app/src/processing/app/ProgressFrame.java b/app/src/processing/app/ProgressFrame.java new file mode 100644 index 000000000..3e91ee54c --- /dev/null +++ b/app/src/processing/app/ProgressFrame.java @@ -0,0 +1,379 @@ +package processing.app; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.SwingWorker; + +//Class used to handle progress bar, and run Save As or Add File in +//background so that +//progress bar can update without freezing +public class ProgressFrame extends JFrame implements PropertyChangeListener { + + private static final long serialVersionUID = 1L; + + private JProgressBar progressBar; + + private JLabel saveAsLabel; + + private TaskSaveAs t; + + private TaskAddFile t2; + + private File[] copyItems; + + private File newFolder; + + private File addFile, sourceFile; + + private Editor editor; + + // create a new background thread to save as + public class TaskSaveAs extends SwingWorker { + + @Override + protected Void doInBackground() throws Exception { + // a large part of the file copying happens in this background + // thread + + long totalSize = 0; + for (File copyable : copyItems) { + totalSize += getFileLength(copyable); + } + + long progress = 0; + setProgress(0); + for (File copyable : ProgressFrame.this.copyItems) { + // loop to copy over the items that make sense, and to set the + // current progress + + if (copyable.isDirectory()) { + copyDir(copyable, + new File(ProgressFrame.this.newFolder, copyable.getName()), + this, progress, totalSize); + progress += getFileLength(copyable); + } else { + copyFile(copyable, + new File(ProgressFrame.this.newFolder, copyable.getName()), + this, progress, totalSize); + if (getFileLength(copyable) < 524288) { + // If the file length > 0.5MB, the copyFile() function has + // been redesigned to change progress every 0.5MB so that + // the progress bar doesn't stagnate during that time + progress += getFileLength(copyable); + setProgress((int) Math.min(Math.ceil(progress * 100.0 / totalSize), + 100)); + } + } + } + + return null; + } + + public void setProgressBarStatus(int status) { + + setProgress(status); + } + + @Override + public void done() { + // to close the progress bar automatically when done, and to + // print that Saving is done in Message Area + + editor.statusNotice("Done Saving."); + ProgressFrame.this.closeProgressBar(); + } + + } + + // create a new background thread to add a file + public class TaskAddFile extends SwingWorker { + + @Override + protected Void doInBackground() throws Exception { + // a large part of the file copying happens in this background + // thread + + setProgress(0); + + copyFile(sourceFile, addFile, this); + + if (addFile.length() < 1024) { + // If the file length > 1kB, the copyFile() function has + // been redesigned to change progress every 1kB so that + // the progress bar doesn't stagnate during that time + + // If file <1 kB, just fill up Progress Bar to 100% + // directly, since time to copy is now negligable (when + // perceived by a human, anyway) + setProgress(100); + } + + return null; + } + + public void setProgressBarStatus(int status) { + setProgress(status); + } + + @Override + public void done() { + // to close the progress bar automatically when done, and to + // print that adding file is done in Message Area + + editor.statusNotice("One file added to the sketch."); + ProgressFrame.this.closeProgressBar(); + } + + } + + //Use for Save As + public ProgressFrame(File[] c, File nf, String oldName, String newName, + Editor editor) { + // initialize a copyItems and newFolder, which are used for file + // copying in the background thread + copyItems = c; + newFolder = nf; + this.editor = editor; + + // the UI of the progress bar follows + setDefaultCloseOperation(HIDE_ON_CLOSE); + setBounds(200, 200, 400, 140); + setResizable(false); + setTitle("Saving As..."); + JPanel panel = new JPanel(null); + add(panel); + setContentPane(panel); + saveAsLabel = new JLabel("Saving " + oldName + " as " + newName + "..."); + saveAsLabel.setBounds(40, 20, 300, 20); + + progressBar = new JProgressBar(0, 100); + progressBar.setValue(0); + progressBar.setBounds(40, 50, 300, 30); + progressBar.setStringPainted(true); + + panel.add(progressBar); + panel.add(saveAsLabel); + Toolkit.setIcon(this); + this.setVisible(true); + + // create an instance of TaskSaveAs and run execute() on this + // instance to + // start background thread + t = new TaskSaveAs(); + t.addPropertyChangeListener(this); + t.execute(); + } + + //Use for Add File + public ProgressFrame(File sf, File add, Editor editor) { + + addFile = add; + sourceFile = sf; + this.editor = editor; + + // the UI of the progress bar follows + setDefaultCloseOperation(HIDE_ON_CLOSE); + setBounds(200, 200, 400, 140); + setResizable(false); + setTitle("Adding File..."); + JPanel panel = new JPanel(null); + add(panel); + setContentPane(panel); + saveAsLabel = new JLabel("Adding " + addFile.getName()); + saveAsLabel.setBounds(40, 20, 300, 20); + + progressBar = new JProgressBar(0, 100); + progressBar.setValue(0); + progressBar.setBounds(40, 50, 300, 30); + progressBar.setStringPainted(true); + + panel.add(progressBar); + panel.add(saveAsLabel); + Toolkit.setIcon(this); + this.setVisible(true); + + // create an instance of TaskAddFile and run execute() on this + // instance to + // start background thread + t2 = new TaskAddFile(); + t2.addPropertyChangeListener(this); + t2.execute(); + } + + public long getFileLength(File f)// function to return the length of + // the file, or + // ENTIRE directory, including the + // component files + // and sub-folders if passed + { + long fol_len = 0; + if (f.isDirectory()) { + String files[] = f.list(); + for (int i = 0; i < files.length; i++) { + File temp = new File(f, files[i]); + if (temp.isDirectory()) { + fol_len += getFileLength(temp); + } else { + fol_len += (temp.length()); + } + } + } else { + return (f.length()); + } + return fol_len; + } + + public void propertyChange(PropertyChangeEvent evt) + // detects a change in the property of the background task, i.e., is + // called when the size of files already copied changes + { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } + } + + private void closeProgressBar() + // closes progress bar + { + this.dispose(); + } + + static public void copyFile(File sourceFile, File targetFile, + ProgressFrame.TaskSaveAs progBar, + double progress, double totalSize) + throws IOException { + // Overloaded copyFile that is called whenever a Save As is being done, so that the + // ProgressBar is updated for very large files as well + BufferedInputStream from = new BufferedInputStream( + new FileInputStream( + sourceFile)); + BufferedOutputStream to = new BufferedOutputStream( + new FileOutputStream( + targetFile)); + byte[] buffer = new byte[16 * 1024]; + int bytesRead; + int totalRead = 0; + while ((bytesRead = from.read(buffer)) != -1) { + to.write(buffer, 0, bytesRead); + totalRead += bytesRead; + if (totalRead >= 524288) //to update progress bar every 0.5MB + { + progress += totalRead; + progBar.setProgressBarStatus((int) Math.min(Math.ceil(progress * 100.0 + / totalSize), 100)); + totalRead = 0; + } + } + if (sourceFile.length() > 524288) { + // Update the progress bar one final time if file size is more than 0.5MB, + // otherwise, the update is handled either by the copyDir function, + // or directly by ProgressFrame.TaskSaveAs.doInBackground() + progress += totalRead; + progBar.setProgressBarStatus((int) Math.min(Math.ceil(progress * 100.0 + / totalSize), 100)); + } + from.close(); + from = null; + to.flush(); + to.close(); + to = null; + + targetFile.setLastModified(sourceFile.lastModified()); + targetFile.setExecutable(sourceFile.canExecute()); + } + + static public void copyFile(File sourceFile, File targetFile, + ProgressFrame.TaskAddFile progBar) + throws IOException { + // Overloaded copyFile that is called whenever a addFile is being done, + // so that the + // ProgressBar is updated + double totalSize = sourceFile.length(); + int progress = 0; + BufferedInputStream from = new BufferedInputStream( + new FileInputStream( + sourceFile)); + BufferedOutputStream to = new BufferedOutputStream( + new FileOutputStream( + targetFile)); + byte[] buffer = new byte[16 * 1024]; + int bytesRead; + int totalRead = 0; + while ((bytesRead = from.read(buffer)) != -1) { + to.write(buffer, 0, bytesRead); + totalRead += bytesRead; + if (totalRead >= 1024) // to update progress bar every 1kB + { + progress += totalRead; + progBar.setProgressBarStatus((int) Math.min(Math.ceil(progress * 100.0 + / totalSize), 100)); + totalRead = 0; + } + } + if (sourceFile.length() > 1024) { + // Update the progress bar one final time if file size is more than + // 1kB, + // otherwise, the update is handled directly by + // ProgressFrame.TaskAddFile.doInBackground() + progress += totalRead; + progBar.setProgressBarStatus((int) Math.min(Math.ceil(progress * 100.0 + / totalSize), 100)); + } + from.close(); + from = null; + to.flush(); + to.close(); + to = null; + targetFile.setLastModified(sourceFile.lastModified()); + targetFile.setExecutable(sourceFile.canExecute()); + } + + static public double copyDir(File sourceDir, File targetDir, + ProgressFrame.TaskSaveAs progBar, + double progress, double totalSize) + throws IOException { + // Overloaded copyDir so that the Save As progress bar gets updated when the + // files are in folders as well (like in the data folder) + if (sourceDir.equals(targetDir)) { + final String urDum = "source and target directories are identical"; + throw new IllegalArgumentException(urDum); + } + targetDir.mkdirs(); + String files[] = sourceDir.list(); + for (int i = 0; i < files.length; i++) { + // Ignore dot files (.DS_Store), dot folders (.svn) while copying + if (files[i].charAt(0) == '.') + continue; + //if (files[i].equals(".") || files[i].equals("..")) continue; + File source = new File(sourceDir, files[i]); + File target = new File(targetDir, files[i]); + if (source.isDirectory()) { + //target.mkdirs(); + progress = copyDir(source, target, progBar, progress, totalSize); + progBar.setProgressBarStatus((int) Math.min(Math.ceil(progress * 100.0 + / totalSize), 100)); + target.setLastModified(source.lastModified()); + } else { + copyFile(source, target, progBar, progress, totalSize); + // Update SaveAs progress bar + progress += source.length(); + progBar.setProgressBarStatus((int) Math.min(Math.ceil(progress * 100.0 + / totalSize), 100)); + } + } + return progress; + } + +} diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 78d0b1752..7c00152a3 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -340,27 +340,26 @@ public class Sketch { * @param oldName */ protected void promptForTabName(String prompt, String oldName) { - final JTextField txtTabName = new JTextField(); - txtTabName.addKeyListener(new KeyAdapter() { + final JTextField field = new JTextField(oldName); + + field.addKeyListener(new KeyAdapter() { // Forget ESC, the JDialog should handle it. - - // Use keyTyped to catch when the feller is actually - // added to the text field. With keyTyped, as opposed to - // keyPressed, the keyCode will be zero, even if it's - // enter or backspace or whatever, so the keychar should - // be used instead. Grr. + // Use keyTyped to catch when the feller is actually added to the text + // field. With keyTyped, as opposed to keyPressed, the keyCode will be + // zero, even if it's enter or backspace or whatever, so the keychar + // should be used instead. Grr. public void keyTyped(KeyEvent event) { //System.out.println("got event " + event); char ch = event.getKeyChar(); if ((ch == '_') || (ch == '.') || // allow.pde and .java - (('A' <= ch) && (ch <= 'Z')) || (('a' <= ch) && (ch <= 'z'))) { + (('A' <= ch) && (ch <= 'Z')) || (('a' <= ch) && (ch <= 'z'))) { // These events are allowed straight through. } else if (ch == ' ') { - String t = txtTabName.getText(); - int start = txtTabName.getSelectionStart(); - int end = txtTabName.getSelectionEnd(); - txtTabName.setText(t.substring(0, start) + "_" + t.substring(end)); - txtTabName.setCaretPosition(start + 1); + String t = field.getText(); + int start = field.getSelectionStart(); + int end = field.getSelectionEnd(); + field.setText(t.substring(0, start) + "_" + t.substring(end)); + field.setCaretPosition(start + 1); event.consume(); } else if ((ch >= '0') && (ch <= '9')) { // getCaretPosition == 0 means that it's the first char @@ -368,31 +367,29 @@ public class Sketch { // getSelectionStart means that it *will be* the first // char, because the selection is about to be replaced // with whatever is typed. - if ((txtTabName.getCaretPosition() == 0) - || (txtTabName.getSelectionStart() == 0)) { + if (field.getCaretPosition() == 0 || + field.getSelectionStart() == 0) { // number not allowed as first digit - //System.out.println("bad number bad"); event.consume(); } } else if (ch == KeyEvent.VK_ENTER) { - // Slightly ugly hack that ensures OK button of the dialog - // consumes the Enter key event. Since the text field is the - // default component in the dialog(see below), OK button doesn't - // consume Enter key event, by default. - Container parent = txtTabName.getParent(); + // Slightly ugly hack that ensures OK button of the dialog consumes + // the Enter key event. Since the text field is the default component + // in the dialog, OK doesn't consume Enter key event, by default. + Container parent = field.getParent(); while (!(parent instanceof JOptionPane)) { parent = parent.getParent(); } JOptionPane pane = (JOptionPane) parent; - final JPanel pnlBottom = (JPanel) pane.getComponent(pane - .getComponentCount() - 1); + final JPanel pnlBottom = (JPanel) + pane.getComponent(pane.getComponentCount() - 1); for (int i = 0; i < pnlBottom.getComponents().length; i++) { Component component = pnlBottom.getComponents()[i]; if (component instanceof JButton) { - final JButton okButton = ((JButton) component); + final JButton okButton = (JButton) component; if (okButton.getText().equalsIgnoreCase("OK")) { - ActionListener[] actionListeners = okButton - .getActionListeners(); + ActionListener[] actionListeners = + okButton.getActionListeners(); if (actionListeners.length > 0) { actionListeners[0].actionPerformed(null); event.consume(); @@ -400,26 +397,24 @@ public class Sketch { } } } - } - else { + } else { event.consume(); } } }); int userReply = JOptionPane.showOptionDialog(editor, new Object[] { - prompt, txtTabName }, - "Tab Name", + prompt, field }, + "New Name", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[] { - Preferences.PROMPT_OK, - Preferences.PROMPT_CANCEL }, - txtTabName); + Preferences.PROMPT_OK, + Preferences.PROMPT_CANCEL }, + field); if (userReply == JOptionPane.OK_OPTION) { - String answer = txtTabName.getText(); - nameCode(answer); + nameCode(field.getText()); } } @@ -749,7 +744,8 @@ public class Sketch { if (Base.isMacOS()) { // http://developer.apple.com/qa/qa2001/qa1146.html Object modifiedParam = modified ? Boolean.TRUE : Boolean.FALSE; - editor.getRootPane().putClientProperty("windowModified", modifiedParam); + // https://developer.apple.com/library/mac/technotes/tn2007/tn2196.html#WINDOW_DOCUMENTMODIFIED + editor.getRootPane().putClientProperty("Window.documentModified", modifiedParam); } } @@ -807,6 +803,8 @@ public class Sketch { protected boolean saveAs() throws IOException { String newParentDir = null; String newName = null; + + final String oldName2 = folder.getName(); // TODO rewrite this to use shared version from PApplet final String PROMPT = "Save sketch folder as..."; if (Preferences.getBoolean("chooser.files.native")) { @@ -814,7 +812,7 @@ public class Sketch { FileDialog fd = new FileDialog(editor, PROMPT, FileDialog.SAVE); if (isReadOnly() || isUntitled()) { // default to the sketchbook folder - fd.setDirectory(Preferences.get("sketchbook.path")); + fd.setDirectory(Preferences.getSketchbookPath()); } else { // default to the parent folder of where this was fd.setDirectory(folder.getParent()); @@ -829,7 +827,7 @@ public class Sketch { fc.setDialogTitle(PROMPT); if (isReadOnly() || isUntitled()) { // default to the sketchbook folder - fc.setCurrentDirectory(new File(Preferences.get("sketchbook.path"))); + fc.setCurrentDirectory(new File(Preferences.getSketchbookPath())); } else { // default to the parent folder of where this was fc.setCurrentDirectory(folder.getParentFile()); @@ -941,15 +939,21 @@ public class Sketch { return true; } }); - // now copy over the items that make sense - for (File copyable : copyItems) { - if (copyable.isDirectory()) { - Base.copyDir(copyable, new File(newFolder, copyable.getName())); - } else { - Base.copyFile(copyable, new File(newFolder, copyable.getName())); - } - } + + final File newFolder2 = newFolder; + final File[] copyItems2 = copyItems; + final String newName2 = newName; + + // Create a new event dispatch thread- to display ProgressBar + // while Saving As + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + new ProgressFrame(copyItems2, newFolder2, oldName2, newName2, editor); + } + }); + + // save the other tabs to their new location for (int i = 1; i < codeCount; i++) { File newFile = new File(newFolder, code[i].getFileName()); @@ -980,6 +984,7 @@ public class Sketch { } + /** * Update internal state for new sketch name or folder location. */ @@ -1046,7 +1051,8 @@ public class Sketch { boolean result = addFile(sourceFile); if (result) { - editor.statusNotice("One file added to the sketch."); +// editor.statusNotice("One file added to the sketch."); + //Done from within TaskAddFile inner class when copying is completed } } @@ -1139,16 +1145,17 @@ public class Sketch { // in case the user is "adding" the code in an attempt // to update the sketch's tabs - if (!sourceFile.equals(destFile)) { - try { - Base.copyFile(sourceFile, destFile); - - } catch (IOException e) { - Base.showWarning("Error adding file", - "Could not add '" + filename + "' to the sketch.", e); - return false; + if (!sourceFile.equals(destFile)) { + final File sourceFile2 = sourceFile; + final File destFile2 = destFile; + // Create a new event dispatch thread- to display ProgressBar + // while Saving As + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + new ProgressFrame(sourceFile2, destFile2, editor); } - } + }); + } if (codeExtension != null) { SketchCode newCode = new SketchCode(destFile, codeExtension); diff --git a/app/src/processing/app/Toolkit.java b/app/src/processing/app/Toolkit.java index 34aa23834..83ead7661 100644 --- a/app/src/processing/app/Toolkit.java +++ b/app/src/processing/app/Toolkit.java @@ -40,8 +40,8 @@ import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.io.BufferedInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; @@ -453,9 +453,16 @@ public class Toolkit { } + /** + * Get a font from the JRE lib/fonts folder. Our default fonts are also + * installed there so that the monospace (and others) can be used by other + * font listing calls (i.e. it appears in the list of monospace fonts in + * the Preferences window). + */ static private Font createFont(String filename, int size) throws IOException, FontFormatException { - InputStream is = Base.getLibStream("fonts/" + filename); - BufferedInputStream input = new BufferedInputStream(is); + //InputStream is = Base.getLibStream("fonts/" + filename); + File fontFile = new File(System.getProperty("java.home"), "lib/fonts/" + filename); + BufferedInputStream input = new BufferedInputStream(new FileInputStream(fontFile)); Font font = Font.createFont(Font.TRUETYPE_FONT, input); input.close(); return font.deriveFont((float) size); diff --git a/app/src/processing/app/contrib/ContributionManagerDialog.java b/app/src/processing/app/contrib/ContributionManagerDialog.java index c0a23d79f..9d46e21cb 100644 --- a/app/src/processing/app/contrib/ContributionManagerDialog.java +++ b/app/src/processing/app/contrib/ContributionManagerDialog.java @@ -125,6 +125,7 @@ public class ContributionManagerDialog { * Close the window after an OK or Cancel. */ protected void disposeFrame() { + status.clear(); dialog.dispose(); editor = null; } diff --git a/app/src/processing/app/contrib/ContributionPanel.java b/app/src/processing/app/contrib/ContributionPanel.java index 37b4fb6b3..c4a2763b5 100644 --- a/app/src/processing/app/contrib/ContributionPanel.java +++ b/app/src/processing/app/contrib/ContributionPanel.java @@ -101,6 +101,7 @@ class ContributionPanel extends JPanel { installActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { + listPanel.contribManager.status.clear(); if (contrib instanceof AvailableContribution) { installContribution((AvailableContribution) contrib); contribListing.replaceContribution(contrib, contrib); @@ -110,6 +111,7 @@ class ContributionPanel extends JPanel { undoActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { + listPanel.contribManager.status.clear(); if (contrib instanceof LocalContribution) { LocalContribution installed = (LocalContribution) contrib; installed.setDeletionFlag(false); @@ -120,6 +122,7 @@ class ContributionPanel extends JPanel { removeActionListener = new ActionListener() { public void actionPerformed(ActionEvent arg) { + listPanel.contribManager.status.clear(); if (contrib.isInstalled() && contrib instanceof LocalContribution) { updateButton.setEnabled(false); installRemoveButton.setEnabled(false); @@ -182,6 +185,9 @@ class ContributionPanel extends JPanel { descriptionBlock.setContentType("text/html"); setTextStyle(descriptionBlock); descriptionBlock.setOpaque(false); + if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { + descriptionBlock.setBackground(new Color(0, 0, 0, 0)); + } // stripTextSelectionListeners(descriptionBlock); descriptionBlock.setBorder(new EmptyBorder(4, 7, 7, 7)); @@ -211,6 +217,7 @@ class ContributionPanel extends JPanel { updateButton.setVisible(false); updateButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + listPanel.contribManager.status.clear(); updateButton.setEnabled(false); AvailableContribution ad = contribListing.getAvailableContribution(contrib); String url = ad.link; diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index a4f98e14c..ea1e874ac 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -45,6 +45,11 @@ class StatusPanel extends JLabel { setText(message); repaint(); } + + void clear() { + setText(""); + repaint(); + } } diff --git a/app/src/processing/app/platform/ThinkDifferent.java b/app/src/processing/app/platform/ThinkDifferent.java index aba1ed4ba..e13db6f0b 100644 --- a/app/src/processing/app/platform/ThinkDifferent.java +++ b/app/src/processing/app/platform/ThinkDifferent.java @@ -22,7 +22,6 @@ package processing.app.platform; -import java.awt.Dimension; import java.awt.event.*; import javax.swing.*; @@ -30,7 +29,6 @@ import javax.swing.*; import processing.app.About; import processing.app.Base; import processing.app.Toolkit; -import processing.core.PApplet; import com.apple.eawt.*; @@ -84,27 +82,27 @@ public class ThinkDifferent implements ApplicationListener { // This is kind of a gross way to do this, but the alternatives? Hrm. Base.defaultFileMenu = fileMenu; - if (PApplet.javaVersion <= 1.6f) { // doesn't work on Oracle's Java - try { - application.setDefaultMenuBar(defaultMenuBar); - - } catch (Exception e) { - e.printStackTrace(); // oh well nevermind - } - } else { - // The douchebags at Oracle didn't feel that a working f*king menubar - // on OS X was important enough to make it into the 7u40 release. - //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8007267 - // It languished in the JDK 8 source and has been backported for 7u60: - //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8022667 - - JFrame offscreen = new JFrame(); - offscreen.setUndecorated(true); - offscreen.setJMenuBar(defaultMenuBar); - Dimension screen = Toolkit.getScreenSize(); - offscreen.setLocation(screen.width, screen.height); - offscreen.setVisible(true); +// if (PApplet.javaVersion <= 1.6f) { // doesn't work on Oracle's Java + try { + application.setDefaultMenuBar(defaultMenuBar); + + } catch (Exception e) { + e.printStackTrace(); // oh well, never mind } +// } else { +// // The douchebags at Oracle didn't feel that a working f*king menubar +// // on OS X was important enough to make it into the 7u40 release. +// //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8007267 +// // It languished in the JDK 8 source and has been backported for 7u60: +// //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8022667 +// +// JFrame offscreen = new JFrame(); +// offscreen.setUndecorated(true); +// offscreen.setJMenuBar(defaultMenuBar); +// Dimension screen = Toolkit.getScreenSize(); +// offscreen.setLocation(screen.width, screen.height); +// offscreen.setVisible(true); +// } } diff --git a/app/src/processing/mode/java/JavaBuild.java b/app/src/processing/mode/java/JavaBuild.java index 021f7ea5e..42f8de00f 100644 --- a/app/src/processing/mode/java/JavaBuild.java +++ b/app/src/processing/mode/java/JavaBuild.java @@ -422,7 +422,7 @@ public class JavaBuild { String entry = (dot == -1) ? item : item.substring(0, dot); // System.out.print(entry + " => "); - if (item.startsWith("static ")) { + if (item.startsWith("static ")) { // import static - https://github.com/processing/processing/issues/8 // Remove more stuff. int dot2 = item.lastIndexOf('.'); @@ -472,8 +472,8 @@ public class JavaBuild { javaClassPath = javaClassPath.substring(1, javaClassPath.length() - 1); } classPath += File.pathSeparator + javaClassPath; - - // But make sure that there isn't anything in there that's missing, + + // But make sure that there isn't anything in there that's missing, // otherwise ECJ will complain and die. For instance, Java 1.7 (or maybe // it's appbundler?) adds Java/Classes to the path, which kills us. //String[] classPieces = PApplet.split(classPath, File.pathSeparator); @@ -549,7 +549,7 @@ public class JavaBuild { if (pkg.startsWith("processing.data.")) return true; if (pkg.startsWith("processing.event.")) return true; if (pkg.startsWith("processing.opengl.")) return true; - + // if (pkg.startsWith("com.jogamp.")) return true; // // ignore core, data, and opengl packages @@ -1113,11 +1113,11 @@ public class JavaBuild { File folder = null; for (String platformName : PConstants.platformNames) { int platform = Base.getPlatformIndex(platformName); - + // Can only embed Java on the native platform - boolean embedJava = (platform == PApplet.platform) && + boolean embedJava = (platform == PApplet.platform) && Preferences.getBoolean("export.application.embed_java"); - + if (Preferences.getBoolean("export.application.platform." + platformName)) { if (Library.hasMultipleArch(platform, importedLibraries)) { // export the 32-bit version @@ -1216,41 +1216,41 @@ public class JavaBuild { File jdkFolder = new File(Base.getJavaHome(), "../../.."); String jdkFolderName = jdkFolder.getCanonicalFile().getName(); jvmRuntime = "JVMRuntime\n " + jdkFolderName + ""; - jdkPath = new File(dotAppFolder, "Contents/PlugIns/" + jdkFolderName + ".jdk").getAbsolutePath(); + jdkPath = new File(dotAppFolder, "Contents/PlugIns/" + jdkFolderName).getAbsolutePath(); } File contentsFolder = new File(dotAppFolder, "Contents"); contentsFolder.mkdirs(); // Info.plist will be written later - + // set the jar folder to a different location than windows/linux //jarFolder = new File(dotAppFolder, "Contents/Resources/Java"); jarFolder = new File(contentsFolder, "Java"); File macosFolder = new File(contentsFolder, "MacOS"); macosFolder.mkdirs(); - Base.copyFile(new File(contentsOrig, "MacOS/Processing"), + Base.copyFile(new File(contentsOrig, "MacOS/Processing"), new File(contentsFolder, "MacOS/" + sketch.getName())); - + File pkgInfo = new File(contentsFolder, "PkgInfo"); PrintWriter writer = PApplet.createWriter(pkgInfo); writer.println("APPL????"); writer.flush(); writer.close(); - + // Use faster(?) native copy here (also to do sym links) if (embedJava) { Base.copyDirNative(new File(contentsOrig, "PlugIns"), new File(contentsFolder, "PlugIns")); } - + File resourcesFolder = new File(contentsFolder, "Resources"); - Base.copyDir(new File(contentsOrig, "Resources/en.lproj"), + Base.copyDir(new File(contentsOrig, "Resources/en.lproj"), new File(resourcesFolder, "en.lproj")); Base.copyFile(mode.getContentFile("application/sketch.icns"), new File(resourcesFolder, "sketch.icns")); - + /* String stubName = "Contents/MacOS/JavaApplicationStub"; // need to set the stub to executable @@ -1279,7 +1279,7 @@ public class JavaBuild { if (embedJava) { Base.copyDirNative(Base.getJavaHome(), new File(destFolder, "java")); } - + } else if (exportPlatform == PConstants.WINDOWS) { if (embedJava) { Base.copyDir(Base.getJavaHome(), new File(destFolder, "java")); @@ -1312,7 +1312,7 @@ public class JavaBuild { } */ - + /// start copying all jar files Vector jarListVector = new Vector(); @@ -1448,7 +1448,7 @@ public class JavaBuild { runOptions.add("-Djna.nosys=true"); // https://github.com/processing/processing/issues/2559 if (exportPlatform == PConstants.WINDOWS) { - runOptions.add("-Djava.library.path=\"%EXEDIR%\\lib;%PATH%\""); + runOptions.add("-Djava.library.path=\"%EXEDIR%\\lib\""); } @@ -1461,7 +1461,7 @@ public class JavaBuild { runOptionsXML.append(opt); runOptionsXML.append(""); runOptionsXML.append('\n'); - } + } String PLIST_TEMPLATE = "Info.plist.tmpl"; File plistTemplate = new File(sketch.getFolder(), PLIST_TEMPLATE); @@ -1504,10 +1504,10 @@ public class JavaBuild { // attempt to code sign if the Xcode tools appear to be installed if (Base.isMacOS() && new File("/usr/bin/codesign_allocate").exists()) { if (embedJava) { - ProcessHelper.ffs("codesign", "--force", "--sign", "-", jdkPath); + ProcessHelper.ffs("codesign", "--force", "--sign", "-", jdkPath); } String appPath = dotAppFolder.getAbsolutePath(); - ProcessHelper.ffs("codesign", "--force", "--sign", "-", appPath); + ProcessHelper.ffs("codesign", "--force", "--sign", "-", appPath); } } else if (exportPlatform == PConstants.WINDOWS) { @@ -1517,27 +1517,27 @@ public class JavaBuild { XML project = new XML("project"); XML target = project.addChild("target"); target.setString("name", "windows"); - + XML taskdef = target.addChild("taskdef"); taskdef.setString("name", "launch4j"); taskdef.setString("classname", "net.sf.launch4j.ant.Launch4jTask"); String launchPath = mode.getContentFile("application/launch4j").getAbsolutePath(); taskdef.setString("classpath", launchPath + "/launch4j.jar:" + launchPath + "/lib/xstream.jar"); - + XML launch4j = target.addChild("launch4j"); // not all launch4j options are available when embedded inside the ant // build file (i.e. the icon param doesn't work), so use a config file // launch4j.setString("configFile", configFile.getAbsolutePath()); - + XML config = new XML("launch4jConfig"); config.addChild("headerType").setContent("gui"); config.addChild("dontWrapJar").setContent("true"); config.addChild("downloadUrl").setContent("http://java.com/download"); - + File exeFile = new File(destFolder, sketch.getName() + ".exe"); config.addChild("outfile").setContent(exeFile.getAbsolutePath()); - + File iconFile = mode.getContentFile("application/sketch.ico"); config.addChild("icon").setContent(iconFile.getAbsolutePath()); @@ -1554,7 +1554,7 @@ public class JavaBuild { for (String opt : runOptions) { jre.addChild("opt").setContent(opt); } - + /* XML config = launch4j.addChild("config"); config.setString("headerType", "gui"); @@ -1562,10 +1562,10 @@ public class JavaBuild { config.setString("outfile", exeFile.getAbsolutePath()); config.setString("dontWrapJar", "true"); config.setString("jarPath", "lib\\" + jarList[0]); - + File iconFile = mode.getContentFile("application/sketch.ico"); config.addChild("icon").setContent(iconFile.getAbsolutePath()); - + XML clazzPath = config.addChild("classPath"); clazzPath.setString("mainClass", sketch.getName()); for (int i = 1; i < jarList.length; i++) { @@ -1579,11 +1579,11 @@ public class JavaBuild { jre.addChild("opt").setContent(opt); } */ - + config.save(configFile); project.save(buildFile); if (!buildWindowsLauncher(buildFile, "windows")) { - // don't delete the build file, might be useful for debugging + // don't delete the build file, might be useful for debugging return false; } configFile.delete(); @@ -1601,10 +1601,10 @@ public class JavaBuild { // another fix for bug #234, LD_LIBRARY_PATH ignored on some platforms //ps.print("LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$APPDIR\n"); if (embedJava) { - // https://github.com/processing/processing/issues/2349 + // https://github.com/processing/processing/issues/2349 pw.print("$APPDIR/java/bin/"); } - String runOptionsStr = + String runOptionsStr = PApplet.join(runOptions.toArray(new String[0]), " "); pw.print("java " + runOptionsStr + " -Djava.library.path=\"$APPDIR:$APPDIR/lib\"" + @@ -1650,7 +1650,7 @@ public class JavaBuild { } - /** + /** * Run the launch4j build.xml file through ant to create the exe. * Most of this code was lifted from Android mode. */ diff --git a/app/src/processing/mode/java/JavaEditor.java b/app/src/processing/mode/java/JavaEditor.java index 70e083ea4..270209ef2 100644 --- a/app/src/processing/mode/java/JavaEditor.java +++ b/app/src/processing/mode/java/JavaEditor.java @@ -283,6 +283,11 @@ public class JavaEditor extends Editor { } }); + // Only possible to export OS X applications on OS X + if (!Base.isMacOS()) { + // Make sure they don't have a previous 'true' setting for this + Preferences.setBoolean("export.application.platform.macosx", false); + } final JCheckBox macosxButton = new JCheckBox("Mac OS X"); macosxButton.setSelected(Preferences.getBoolean("export.application.platform.macosx")); macosxButton.addItemListener(new ItemListener() { @@ -290,6 +295,10 @@ public class JavaEditor extends Editor { Preferences.setBoolean("export.application.platform.macosx", macosxButton.isSelected()); } }); + if (!Base.isMacOS()) { + macosxButton.setEnabled(false); + macosxButton.setToolTipText("Mac OS X export is only available on Mac OS X"); + } final JCheckBox linuxButton = new JCheckBox("Linux"); //linuxButton.setMnemonic(KeyEvent.VK_L); diff --git a/app/src/processing/mode/java/runner/Runner.java b/app/src/processing/mode/java/runner/Runner.java index 8812627c9..4fbf5f8f1 100644 --- a/app/src/processing/mode/java/runner/Runner.java +++ b/app/src/processing/mode/java/runner/Runner.java @@ -63,19 +63,6 @@ public class Runner implements MessageConsumer { // Thread transferring remote output stream to our output stream protected Thread outThread = null; - // Mode for tracing the Trace program (default= 0 off) -// protected int debugTraceMode = 0; - - // Do we want to watch assignments to fields -// protected boolean watchFields = false; - -// // Class patterns for which we don't want events -// protected String[] excludes = { -// "java.*", "javax.*", "sun.*", "com.sun.*", -// "apple.*", -// "processing.*" -// }; - protected SketchException exception; protected Editor editor; protected JavaBuild build; @@ -138,60 +125,6 @@ public class Runner implements MessageConsumer { // Everyone works the same under Java 7 (also on OS X) String[] commandArgs = new String[] { Base.getJavaPath(), jdwpArg }; - /* - String[] commandArgs = null; - if (!Base.isMacOS()) { - commandArgs = new String[] { - Base.getJavaPath(), - jdwpArg - }; - } else { - // Decided to just set this to 1.6 only, because otherwise it's gonna - // be a shitshow if folks are getting Apple's 1.6 with 32-bit and - // Oracle's 1.7 when run in 64-bit mode. ("Why does my sketch suck in - // 64-bit? Why is retina broken?) - // The --request flag will prompt to install Apple's 1.6 JVM if none is - // available. We're specifying 1.6 so that we can get support for both - // 32- and 64-bit, because Oracle won't be releasing Java 1.7 in 32-bit. - // Helpfully, the --request flag is not present on Mac OS X 10.6 - // (luckily it is also not needed, because 1.6 is installed by default) - // but it requires an additional workaround to not use that flag, - // otherwise will see an error about an unsupported option. The flag is - // available with 10.7 and 10.8, the only other supported versions of - // OS X at this point, because we require 10.6.8 and higher. That also - // means we don't need to check for any other OS versions, the user is - // a douchebag and modifies Info.plist to get around the restriction. - if (false) { - if (System.getProperty("os.version").startsWith("10.6")) { - commandArgs = new String[] { - "/usr/libexec/java_home", - "--version", "1.6", - "--exec", "java", - "-d" + Base.getNativeBits(), - jdwpArg - }; - } else { // for 10.7, 10.8, etc - commandArgs = new String[] { - "/usr/libexec/java_home", - "--request", // install on-demand - "--version", "1.6", - "--exec", "java", - "-d" + Base.getNativeBits(), -// debugArg, - jdwpArg - }; - } - } else { - // testing jdk-7u40 - commandArgs = new String[] { - //"/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/bin/java", - Base.getJavaPath(), - jdwpArg - }; - } - } - */ - commandArgs = PApplet.concat(commandArgs, vmParams); commandArgs = PApplet.concat(commandArgs, sketchParams); // PApplet.println(commandArgs); @@ -482,153 +415,6 @@ public class Runner implements MessageConsumer { } - /* - protected VirtualMachine launchVirtualMachine(String[] vmParams, - String[] classParams) { - //vm = launchTarget(sb.toString()); - LaunchingConnector connector = (LaunchingConnector) - findConnector("com.sun.jdi.RawCommandLineLaunch"); - //PApplet.println(connector); // gets the defaults - - //Map arguments = connectorArguments(connector, mainArgs); - Map arguments = connector.defaultArguments(); - - Connector.Argument commandArg = - (Connector.Argument)arguments.get("command"); - // Using localhost instead of 127.0.0.1 sometimes causes a - // "Transport Error 202" error message when trying to run. - // http://dev.processing.org/bugs/show_bug.cgi?id=895 - // String addr = "127.0.0.1:" + (8000 + (int) (Math.random() * 1000)); - //String addr = "localhost:" + (8000 + (int) (Math.random() * 1000)); - // Better yet, host is not needed, so using just the port for the address - String addr = "" + (8000 + (int) (Math.random() * 1000)); - - String commandArgs = - "java -Xrunjdwp:transport=dt_socket,address=" + addr + ",suspend=y "; - if (Base.isMacOS()) { - // Decided to just set this to 1.6 only, because otherwise it's gonna - // be a shitshow if folks are getting Apple's 1.6 with 32-bit and - // Oracle's 1.7 when run in 64-bit mode. ("Why does my sketch suck in - // 64-bit? Why is retina broken?) - // The --request flag will prompt to install Apple's 1.6 JVM if none is - // available. We're specifying 1.6 so that we can get support for both - // 32- and 64-bit, because Oracle won't be releasing Java 1.7 in 32-bit. - // Helpfully, the --request flag is not present on Mac OS X 10.6 - // (luckily it is also not needed, because 1.6 is installed by default) - // but it requires an additional workaround to not use that flag, - // otherwise will see an error about an unsupported option. The flag is - // available with 10.7 and 10.8, the only other supported versions of - // OS X at this point, because we require 10.6.8 and higher. That also - // means we don't need to check for any other OS versions, unless - // is a douchebag and modifies Info.plist to get around the restriction. - addr = "" + (8000 + (int) (Math.random() * 1000)); - commandArgs = - "/usr/libexec/java_home " + - (System.getProperty("os.version").startsWith("10.6") ? "" : "--request ") + - "--version 1.6 " + - "--exec java " + - "-d" + Base.getNativeBits() + " " + - "-Xrunjdwp:transport=dt_socket,address=" + addr + ",suspend=y "; - } - - for (int i = 0; i < vmParams.length; i++) { - commandArgs = addArgument(commandArgs, vmParams[i], ' '); - } - if (classParams != null) { - for (int i = 0; i < classParams.length; i++) { - commandArgs = addArgument(commandArgs, classParams[i], ' '); - } - } - System.out.println("commandArgs is " + commandArgs); - commandArg.setValue(commandArgs); - - Connector.Argument addressArg = - (Connector.Argument)arguments.get("address"); - addressArg.setValue(addr); - - //PApplet.println(connector); // prints the current - //com.sun.tools.jdi.AbstractLauncher al; - //com.sun.tools.jdi.RawCommandLineLauncher rcll; - - //System.out.println(PApplet.javaVersion); - // http://java.sun.com/j2se/1.5.0/docs/guide/jpda/conninv.html#sunlaunch - try { - return connector.launch(arguments); - } catch (IOException exc) { - throw new Error("Unable to launch target VM: " + exc); - } catch (IllegalConnectorArgumentsException exc) { - throw new Error("Internal error: " + exc); - } catch (VMStartException exc) { - Process p = exc.process(); - //System.out.println(p); - String[] errorStrings = PApplet.loadStrings(p.getErrorStream()); - //String[] inputStrings = - PApplet.loadStrings(p.getInputStream()); - - if (errorStrings != null && errorStrings.length > 1) { - if (errorStrings[0].indexOf("Invalid maximum heap size") != -1) { - Base.showWarning("Way Too High", - "Please lower the value for \u201Cmaximum available memory\u201D in the\n" + - "Preferences window. For more information, read Help \u2192 Troubleshooting.", - exc); - } else { - PApplet.println(errorStrings); - System.err.println("Using startup command:"); - PApplet.println(arguments); - } - } else { - exc.printStackTrace(); - System.err.println("Could not run the sketch (Target VM failed to initialize)."); - if (Preferences.getBoolean("run.options.memory")) { - // Only mention this if they've even altered the memory setup - System.err.println("Make sure that you haven't set the maximum available memory too high."); - } - System.err.println("For more information, read revisions.txt and Help \u2192 Troubleshooting."); - } - // changing this to separate editor and listener [091124] - //if (editor != null) { - listener.statusError("Could not run the sketch."); - //} - return null; - } - } - - - private static boolean hasWhitespace(String string) { - int length = string.length(); - for (int i = 0; i < length; i++) { - if (Character.isWhitespace(string.charAt(i))) { - return true; - } - } - return false; - } - - - private static String addArgument(String string, String argument, char sep) { - if (hasWhitespace(argument) || argument.indexOf(',') != -1) { - // Quotes were stripped out for this argument, add 'em back. - StringBuffer buffer = new StringBuffer(string); - buffer.append('"'); - for (int i = 0; i < argument.length(); i++) { - char c = argument.charAt(i); - if (c == '"') { - buffer.append('\\'); -// buffer.append("\\\\"); - } - buffer.append(c); - } - buffer.append('"'); - buffer.append(sep); - return buffer.toString(); - - } else { - return string + argument + String.valueOf(sep); - } - } - */ - - /** * Generate the trace. * Enable events, start thread to display events, diff --git a/build/build.xml b/build/build.xml index 9433bf858..808195bde 100755 --- a/build/build.xml +++ b/build/build.xml @@ -31,6 +31,9 @@ + + @@ -205,6 +208,10 @@ + + + + @@ -229,6 +236,9 @@ + + + @@ -261,23 +271,16 @@ - + - - - - - - + + + + - + @@ -500,7 +503,7 @@ - + @@ -599,7 +602,7 @@ - + @@ -621,7 +624,7 @@ - + @@ -768,7 +771,7 @@ - + @@ -788,7 +791,7 @@ tofile="${launch4j.dir}/bin/ld.exe" /> - + @@ -949,7 +952,9 @@ remove the spaces for depth since it should be double dash, but screws up commen + diff --git a/build/macosx/jAppleMenuBar.url b/build/macosx/jAppleMenuBar.url deleted file mode 100644 index 62dc0f635..000000000 --- a/build/macosx/jAppleMenuBar.url +++ /dev/null @@ -1,2 +0,0 @@ -[InternetShortcut] -URL=https://github.com/kritzikratzi/jAppleMenuBar diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 30acaafcc..d76ae25ee 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -3,12 +3,20 @@ PROCESSING 3.0a2 (REV 0229) - ?? August 2014 [ fixes ] -+ The Examples and Reference weren't included in 3.0a1. Oops. ++ The Examples weren't included in 3.0a1. Oops. https://github.com/processing/processing/issues/2652 [ changes ] ++ Added a new sketchbook location, so that you can have separate sketchbooks + with 2.0 and 3.0 releases. The downside is that they won't stay in sync, + but the upside is that sketches that haven't been updated, or conflicting + Libraries, Modes, or Tools won't cause trouble with the other version. + The new preference is called sketchbook.location.three (the old preference + was sketchbook.location). If you already have a 2.0 sketchbook, that will + be used by default with 3.0 until you change it in the Preferences window. + + Neglected to mention with the previous release that the video library has been removed from the default download. This decreases the size of the Processing download by about 20%. In addition, it was only the video diff --git a/core/build.xml b/core/build.xml index 8bb8b3a2c..3d24eae76 100755 --- a/core/build.xml +++ b/core/build.xml @@ -38,8 +38,10 @@ + diff --git a/core/src/japplemenubar/JAppleMenuBar.java b/core/src/japplemenubar/JAppleMenuBar.java deleted file mode 100755 index 148eed94d..000000000 --- a/core/src/japplemenubar/JAppleMenuBar.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011-12 hansi raber, released under LGPL under agreement - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, version 2.1. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ -package japplemenubar; - -import java.io.*; - -import processing.core.PApplet; - - -/** - * Starting point for the application. General initialization should be done - * inside the ApplicationController's init() method. If certain kinds of - * non-Swing initialization takes too long, it should happen in a new Thread - * and off the Swing event dispatch thread (EDT). - * - * @author hansi - */ -public class JAppleMenuBar { - static JAppleMenuBar instance; - static final String FILENAME = "libjAppleMenuBar.jnilib"; - - static { - try { - File temp = File.createTempFile("processing", "menubar"); - temp.delete(); // remove the file itself - temp.mkdirs(); // create a directory out of it - temp.deleteOnExit(); - - File jnilibFile = new File(temp, FILENAME); - InputStream input = JAppleMenuBar.class.getResourceAsStream(FILENAME); - if (input != null) { - if (PApplet.saveStream(jnilibFile, input)) { - System.load(jnilibFile.getAbsolutePath()); - instance = new JAppleMenuBar(); - - } else { - sadness("Problem saving " + FILENAME + " for full screen use."); - } - } else { - sadness("Could not load " + FILENAME + " from core.jar"); - } - } catch (IOException e) { - sadness("Unknown error, here's the stack trace."); - e.printStackTrace(); - } - } - - - static void sadness(String msg) { - System.err.println("Full screen mode disabled. " + msg); - } - - -// static public void show() { -// instance.setVisible(true); -// } - - - static public void hide() { - instance.setVisible(false, false); - } - - - public native void setVisible(boolean visibility, boolean kioskMode); - - -// public void setVisible(boolean visibility) { -// // Keep original API in-tact. Default kiosk-mode to off. -// setVisible(visibility, false); -// } -} diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index edc1a1960..0cb8b3a66 100755 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -10410,25 +10410,6 @@ public class PApplet extends Applet } -// /** -// * GIF image of the Processing logo. -// */ -// static public final byte[] ICON_IMAGE = { -// 71, 73, 70, 56, 57, 97, 16, 0, 16, 0, -77, 0, 0, 0, 0, 0, -1, -1, -1, 12, -// 12, 13, -15, -15, -14, 45, 57, 74, 54, 80, 111, 47, 71, 97, 62, 88, 117, -// 1, 14, 27, 7, 41, 73, 15, 52, 85, 2, 31, 55, 4, 54, 94, 18, 69, 109, 37, -// 87, 126, -1, -1, -1, 33, -7, 4, 1, 0, 0, 15, 0, 44, 0, 0, 0, 0, 16, 0, 16, -// 0, 0, 4, 122, -16, -107, 114, -86, -67, 83, 30, -42, 26, -17, -100, -45, -// 56, -57, -108, 48, 40, 122, -90, 104, 67, -91, -51, 32, -53, 77, -78, -100, -// 47, -86, 12, 76, -110, -20, -74, -101, 97, -93, 27, 40, 20, -65, 65, 48, -// -111, 99, -20, -112, -117, -123, -47, -105, 24, 114, -112, 74, 69, 84, 25, -// 93, 88, -75, 9, 46, 2, 49, 88, -116, -67, 7, -19, -83, 60, 38, 3, -34, 2, -// 66, -95, 27, -98, 13, 4, -17, 55, 33, 109, 11, 11, -2, -128, 121, 123, 62, -// 91, 120, -128, 127, 122, 115, 102, 2, 119, 0, -116, -113, -119, 6, 102, -// 121, -108, -126, 5, 18, 6, 4, -102, -101, -100, 114, 15, 17, 0, 59 -// }; - - static ArrayList iconImages; protected void setIconImage(Frame frame) { @@ -10457,18 +10438,46 @@ public class PApplet extends Applet } - // Not gonna do this dynamically, only on startup. Too much headache. -// public void fullscreen() { -// if (frame != null) { -// if (PApplet.platform == MACOSX) { -// japplemenubar.JAppleMenuBar.hide(); -// } -// GraphicsConfiguration gc = frame.getGraphicsConfiguration(); -// Rectangle rect = gc.getBounds(); -//// GraphicsDevice device = gc.getDevice(); -// frame.setBounds(rect.x, rect.y, rect.width, rect.height); -// } -// } + /** + * Use reflection to call + * com.apple.eawt.FullScreenUtilities.setWindowCanFullScreen(window, true); + */ + static private void macosxFullScreenEnable(Window window) { + try { + Class util = Class.forName("com.apple.eawt.FullScreenUtilities"); + Class params[] = new Class[] { Window.class, Boolean.TYPE }; + Method method = util.getMethod("setWindowCanFullScreen", params); + method.invoke(util, window, true); + + } catch (ClassNotFoundException cnfe) { + // ignored + } catch (Exception e) { + e.printStackTrace(); + } + } + + + /** + * Use reflection to call + * com.apple.eawt.Application.getApplication().requestToggleFullScreen(window); + */ + static private void macosxFullScreenToggle(Window window) { + try { + Class appClass = Class.forName("com.apple.eawt.Application"); + + Method getAppMethod = appClass.getMethod("getApplication"); + Object app = getAppMethod.invoke(null, new Object[0]); + + Method requestMethod = + appClass.getMethod("requestToggleFullScreen", Window.class); + requestMethod.invoke(app, window); + + } catch (ClassNotFoundException cnfe) { + // ignored + } catch (Exception e) { + e.printStackTrace(); + } + } /** @@ -10868,11 +10877,21 @@ public class PApplet extends Applet // // or cmd/ctrl-shift-R in the PDE. if (present) { - if (platform == MACOSX) { - // Call some native code to remove the menu bar on OS X. Not necessary - // on Linux and Windows, who are happy to make full screen windows. - japplemenubar.JAppleMenuBar.hide(); - } +// if (platform == MACOSX) { +// println("before"); +// println(screenRect); +// println(frame.getBounds()); +// +// // Call some native code to remove the menu bar on OS X. Not necessary +// // on Linux and Windows, who are happy to make full screen windows. +//// japplemenubar.JAppleMenuBar.hide(); +// toggleFullScreen(frame); +// println("after"); +// println(screenRect); +// println(frame.getBounds()); +// +// println(applet.width + " " + applet.height); +// } // After the pack(), the screen bounds are gonna be 0s frame.setBounds(screenRect); @@ -10880,6 +10899,17 @@ public class PApplet extends Applet (screenRect.height - applet.height) / 2, applet.width, applet.height); + if (platform == MACOSX) { + macosxFullScreenEnable(frame); + macosxFullScreenToggle(frame); + +// toggleFullScreen(frame); +// println("after"); +// println(screenRect); +// println(frame.getBounds()); +// println(applet.width + " " + applet.height); + } + if (!hideStop) { Label label = new Label("stop"); label.setForeground(stopColor); diff --git a/core/src/processing/core/PGraphicsJava2D.java b/core/src/processing/core/PGraphicsJava2D.java index a2828d08a..af906a6dd 100644 --- a/core/src/processing/core/PGraphicsJava2D.java +++ b/core/src/processing/core/PGraphicsJava2D.java @@ -1301,6 +1301,12 @@ public class PGraphicsJava2D extends PGraphics { } if (who.modified) { + if (who.pixels == null) { + // This might be a PGraphics that hasn't been drawn to yet. + // Can't just bail because the cache has been created above. + // https://github.com/processing/processing/issues/2208 + who.pixels = new int[who.width * who.height]; + } cash.update(who, tint, tintColor); who.modified = false; } diff --git a/core/src/processing/core/PImage.java b/core/src/processing/core/PImage.java index 430d67228..94be0a2e2 100644 --- a/core/src/processing/core/PImage.java +++ b/core/src/processing/core/PImage.java @@ -283,10 +283,14 @@ public class PImage implements PConstants, Cloneable { width = bi.getWidth(); height = bi.getHeight(); pixels = new int[width * height]; - WritableRaster raster = bi.getRaster(); - raster.getDataElements(0, 0, width, height, pixels); - if (bi.getType() == BufferedImage.TYPE_INT_ARGB) { + pixels = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData(); + int type = bi.getType(); + if (type == BufferedImage.TYPE_INT_ARGB) { format = ARGB; + } else if (type == BufferedImage.TYPE_INT_RGB) { + for (int i = 0; i < pixels.length; i++) { + pixels[i] = 0xFF000000 | pixels[i]; + } } } else { // go the old school java 1.0 route diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index 8420f72f6..d0db5006b 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -2065,7 +2065,12 @@ public class PShape implements PConstants { vertices[index][X] = vec.x; vertices[index][Y] = vec.y; - vertices[index][Z] = vec.z; + + if (vertices[index].length > 2) { + vertices[index][Z] = vec.z; + } else if (vec.z != 0 && vec.z == vec.z) { + throw new IllegalArgumentException("Cannot set a z-coordinate on a 2D shape"); + } } diff --git a/core/src/processing/data/FloatDict.java b/core/src/processing/data/FloatDict.java index 71ea99ffd..d300afc1d 100644 --- a/core/src/processing/data/FloatDict.java +++ b/core/src/processing/data/FloatDict.java @@ -668,7 +668,22 @@ public class FloatDict { Sort s = new Sort() { @Override public int size() { - return count; + if (useKeys) { + return count; // don't worry about NaN values + + } else { // first move NaN values to the end of the list + int right = count - 1; + while (values[right] != values[right]) { + right--; + } + for (int i = right; i >= 0; --i) { + if (Float.isNaN(values[i])) { + swap(i, right); + --right; + } + } + return right + 1; + } } @Override @@ -729,12 +744,11 @@ public class FloatDict { } -// /** -// * Write tab-delimited entries out to the console. -// */ -// public void print() { -// write(new PrintWriter(System.out)); -// } + public void print() { + for (int i = 0; i < size(); i++) { + System.out.println(keys[i] + " = " + values[i]); + } + } /** diff --git a/core/src/processing/data/FloatList.java b/core/src/processing/data/FloatList.java index 9921cb326..1e4a85f19 100644 --- a/core/src/processing/data/FloatList.java +++ b/core/src/processing/data/FloatList.java @@ -110,6 +110,9 @@ public class FloatList implements Iterable { * @brief Get an entry at a particular index */ public float get(int index) { + if (index >= count) { + throw new ArrayIndexOutOfBoundsException(index); + } return data[index]; } @@ -563,7 +566,20 @@ public class FloatList implements Iterable { new Sort() { @Override public int size() { - return count; + // move NaN values to the end of the list and don't sort them + int right = count - 1; + while (data[right] != data[right]) { + right--; + } + for (int i = right; i >= 0; --i) { + float v = data[i]; + if (v != v) { + data[i] = data[right]; + data[right] = v; + --right; + } + } + return right + 1; } @Override @@ -601,7 +617,7 @@ public class FloatList implements Iterable { /** * @webref floatlist:method - * @brief Reverse sort, orders values by first digit + * @brief Reverse the order of the list elements */ public void reverse() { int ii = count - 1; @@ -763,6 +779,13 @@ public class FloatList implements Iterable { } + public void print() { + for (int i = 0; i < size(); i++) { + System.out.format("[%d] %f%n", i, data[i]); + } + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index b581eaecf..022d9195f 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -663,6 +663,13 @@ public class IntDict { } + public void print() { + for (int i = 0; i < size(); i++) { + System.out.println(keys[i] + " = " + values[i]); + } + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/core/src/processing/data/IntList.java b/core/src/processing/data/IntList.java index 78775be3f..00483f927 100644 --- a/core/src/processing/data/IntList.java +++ b/core/src/processing/data/IntList.java @@ -130,6 +130,9 @@ public class IntList implements Iterable { * @brief Get an entry at a particular index */ public int get(int index) { + if (index >= this.count) { + throw new ArrayIndexOutOfBoundsException(index); + } return data[index]; } @@ -569,7 +572,7 @@ public class IntList implements Iterable { /** * @webref intlist:method - * @brief Reverse sort, orders values by first digit + * @brief Reverse the order of the list elements */ public void reverse() { int ii = count - 1; diff --git a/core/src/processing/data/Sort.java b/core/src/processing/data/Sort.java index d205edb12..b42e0f141 100644 --- a/core/src/processing/data/Sort.java +++ b/core/src/processing/data/Sort.java @@ -31,8 +31,8 @@ public abstract class Sort implements Runnable { protected int partition(int left, int right) { int pivot = right; do { - while (compare(++left, pivot) < 0) ; - while ((right != 0) && (compare(--right, pivot) > 0)) ; + while (compare(++left, pivot) < 0) { } + while ((right != 0) && (compare(--right, pivot) > 0)) { } swap(left, right); } while (left < right); swap(left, right); diff --git a/core/src/processing/data/StringDict.java b/core/src/processing/data/StringDict.java index 38b2175eb..becc5ee51 100644 --- a/core/src/processing/data/StringDict.java +++ b/core/src/processing/data/StringDict.java @@ -428,6 +428,13 @@ public class StringDict { } + public void print() { + for (int i = 0; i < size(); i++) { + System.out.println(keys[i] + " = " + values[i]); + } + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/core/src/processing/data/StringList.java b/core/src/processing/data/StringList.java index a407265a9..67e58a9ee 100644 --- a/core/src/processing/data/StringList.java +++ b/core/src/processing/data/StringList.java @@ -113,6 +113,9 @@ public class StringList implements Iterable { * @brief Get an entry at a particular index */ public String get(int index) { + if (index >= count) { + throw new ArrayIndexOutOfBoundsException(index); + } return data[index]; } @@ -309,7 +312,7 @@ public class StringList implements Iterable { if (index < 0) { throw new IllegalArgumentException("insert() index cannot be negative: it was " + index); } - if (index >= values.length) { + if (index >= data.length) { throw new IllegalArgumentException("insert() index " + index + " is past the end of this list"); } @@ -495,7 +498,7 @@ public class StringList implements Iterable { /** * @webref stringlist:method - * @brief To come... + * @brief Reverse the order of the list elements */ public void reverse() { int ii = count - 1; @@ -702,10 +705,11 @@ public class StringList implements Iterable { } -// static public StringList split(String value, char delim) { -// String[] array = PApplet.split(value, delim); -// return new StringList(array); -// } + public void print() { + for (int i = 0; i < size(); i++) { + System.out.format("[%d] %s%n", i, data[i]); + } + } @Override diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index a76ec9bfe..93ba62fc4 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -2984,11 +2984,19 @@ public class Table { return missingString; } return columnCategories[column].key(cat); - } else { - return String.valueOf(Array.get(columns[column], row)); + } else if (columnTypes[column] == FLOAT) { + if (Float.isNaN(getFloat(row, column))) { + return null; + } + } else if (columnTypes[column] == DOUBLE) { + if (Double.isNaN(getFloat(row, column))) { + return null; + } } + return String.valueOf(Array.get(columns[column], row)); } + /** * @param columnName title of the column to reference */ @@ -3443,9 +3451,9 @@ public class Table { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - public void replaceAll(String orig, String replacement) { + public void replaceAll(String regex, String replacement) { for (int col = 0; col < columns.length; col++) { - replaceAll(orig, replacement, col); + replaceAll(regex, replacement, col); } } @@ -4284,4 +4292,10 @@ public class Table { } } */ + + + /** Make a copy of the current table */ + public Table copy() { + return new Table(rows()); + } } diff --git a/core/todo.txt b/core/todo.txt index ecf2cc743..ee3902ee8 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,5 +1,30 @@ 0229 core (3.0a2) +X PImage resize() causes images to not draw +X https://github.com/processing/processing/issues/2228 +X https://github.com/processing/processing/pull/2324 +X move to native OS X full screen (gets rid of native code) +X https://github.com/processing/processing/issues/2641 +X do bounds check on setVertex(PVector) +X https://github.com/processing/processing/issues/2556 +X using createGraphics() w/o begin/endDraw(), don't attempt drawing w/ image() +X https://github.com/processing/processing/issues/2208 +data +X add copy() method to Table +X return null from getString() on NaN float and double values +X affects how saveTable() works (writes blank entries instead of NaN) +X get(5) with an empty Int/Float/StringList was returning 0 +X https://github.com/processing/processing/pull/2343 +o fix for maxValue() and minValue() when all entries are bad +o on FloatDict it was NaN, check across the lists and other dict types +X nothing else to do here +X FloatDict and FloatList should always put NaN values at the end on sort +X same for the other list and dict classes +X (this is part of the point of having these easier versions) +o 'collector' class.. Dict that points to a list +o String as a key, int/float/string list as values +X seems too much like a better place for HashMap +X add print() method to other data types (not just IntList) pulls X implement A and a (elliptical arcs) @@ -7,23 +32,52 @@ X https://github.com/processing/processing/issues/169 X http://code.google.com/p/processing/issues/detail?id=130 X https://github.com/processing/processing/pull/2659 X done with an approximation, if re-saving this will destroy data (docs) +X fix typo in StringList.insert() +X https://github.com/processing/processing/pull/2672 +X StingList.insert() error (should be an easy fix) +X https://github.com/processing/processing/issues/2548 + +earlier +X default font fixes (merged for 2.2.1 or earlier) +X https://github.com/processing/processing/issues/2331 +X https://github.com/processing/processing/pull/2338 +X image resize() takes oddly long time +X https://github.com/processing/processing/issues/5 +X the problem was confirmed to have fixed itself -applet removal +applet/component _ remove Applet as base class _ performance issues on OS X (might be threading due to Applet) _ https://github.com/processing/processing/issues/2423 +_ play with improvements to full screen here +_ new full screen sometimes causes sketch to temporarily be in the wrong spot +_ add option to have full screen span across screens +_ display=all in cmd line +_ sketchDisplay() -> 0 for all, or 1, 2, 3... +_ clean up requestFocus() stuff +_ make sure it works with retina/canvas/strategy as well -_ fix for maxValue() and minValue() when all entries are bad -_ on FloatDict it was NaN, check across the lists and other dict types -_ StringDict should always put NaN values at the end on sort -_ same for the other list and dict classes -_ (this is part of the point of having these easier versions) -_ better full screen mode for OS X -_ https://github.com/processing/processing/issues/2641 -_ http://stackoverflow.com/questions/6873568/fullscreen-feature-for-java-apps-on-osx-lion +processing.data +_ need a better method for "missing" data in Table +_ if missing int is zero, can't just remove those values from saving a table +_ but for NaN values, it's a necessity +_ get() methods in List/Dict shouldn't allow you to get bad values +_ but set() methods can automatically resize the arrays +_ though that means insert() should allow you to insert past the end +_ addRow() is not efficient, probably need to do the doubling +o or have a setIncrement() function? +_ it would default to 1 on tables loaded from a file +_ and default to doubling when created with "new Table" +_ row count and array size are combined.. need to break apart +_ match and iterators +_ add match version that returns table that's only a pointer to original +_ save the constructor for the version that actually copies data +_ the table pointer version will be speedy and allow chaining + +later _ bring back chaining in JSON (and add to XML) _ maybe once we make the PVector change @@ -31,10 +85,6 @@ _ maybe once we make the PVector change high _ Closing opengl sketch from the PDE doesn't stop java process on windows _ https://github.com/processing/processing/issues/2335 -_ StingList.insert() error (should be an easy fix) -_ https://github.com/processing/processing/issues/2548 -_ pull for image resize and alpha issues -_ https://github.com/processing/processing/pull/2324 _ dataPath() not working when app is not run from app dir on Linux _ https://github.com/processing/processing/issues/2195 _ "Buffers have not been created" error for sketches w/o draw() @@ -45,32 +95,21 @@ _ some sort of threading issue happening here _ https://github.com/processing/processing/issues/1672 _ https://github.com/processing/processing/issues/2039 (dupe) _ https://github.com/processing/processing/issues/2294 (dupe) +_ also check this out with the new full screen code on OS X _ point() rendering differently in 2.0.3 and 2.1 _ https://github.com/processing/processing/issues/2278 _ internally, we probably have to call set() if it's a 1 pixel point _ but that's going to be a mess.. need to first check the CTM _ tint() not working in PDF (regression between 2.0.3 and 2.1) _ https://github.com/processing/processing/issues/2428 -_ default font fixes -_ https://github.com/processing/processing/issues/2331 -_ https://github.com/processing/processing/pull/2338 -_ add print() method to other data types (not just IntList) _ Sort out blending differences with P2D/P3D _ might be that compatible images not setting alpha mode correctly _ image = gc.createCompatibleVolatileImage(source.width, source.height, Transparency.TRANSLUCENT); _ https://github.com/processing/processing/issues/1844 -_ 'collector' class.. Dict that points to a list -_ String as a key, int/float/string list as values -_ add option to have full screen span across screens -_ display=all in cmd line -_ sketchDisplay() -> 0 for all, or 1, 2, 3... -_ clean up requestFocus() stuff -_ make sure it works with retina/canvas/strategy as well _ finish PFont.getShape() implementation _ needs to have a way to set width/height properly _ draw(s) doesn't work on the returned PShape -_ TGA files writing strangely -_ https://github.com/processing/processing/issues/2096 + hidpi _ saveFrame() with retina render is making black images @@ -88,21 +127,13 @@ _ https://github.com/processing/processing/issues/2411 _ retina sketches slow to start _ https://github.com/processing/processing/issues/2357 + cantfix _ crash on startup when "Mirror Displays" selected _ suspect that this is a specific chipset since Oracle didn't reproduce _ https://github.com/processing/processing/issues/2186 +_ test with JG's 13" retina laptop -table -_ addRow() is not efficient, probably need to do the doubling -_ or have a setIncrement() function? -_ it would default to 1 on tables loaded from a file -_ and default to doubling when created with "new Table" -_ row count and array size are combined.. need to break apart -_ match and iterators -_ add match version that returns table that's only a pointer to original -_ save the constructor for the version that actually copies data -_ the table pointer version will be speedy and allow chaining decisions/misc _ make join() work with Iterable? @@ -200,6 +231,8 @@ _ is this still true? _ decide how disconnectEvent should actually be handled (and name?) _ was disconnect always there? _ will need documentation +_ negative indices so that we can work relative to the end in data classes? +_ add Double and Long versions of the classes? @@ -340,6 +373,9 @@ _ https://github.com/processing/processing/issues/1727 CORE / PImage +_ TGA files writing strangely +_ https://github.com/processing/processing/issues/2096 + _ don't grab pixels of java2d images unless asked _ this is the difference between a lot of loadPixels() and not _ so important to have it in before beta if that's the change diff --git a/done.txt b/done.txt index 6273246fd..bffe7352c 100644 --- a/done.txt +++ b/done.txt @@ -22,6 +22,7 @@ X tweak mode integrated X https://github.com/processing/processing/pull/2624 X wrong mode selected if sketch is modified (checkbox changes) X https://github.com/processing/processing/issues/2615 +X https://github.com/processing/processing/issues/2586 X Add date and time stamps to the Contribution Manager X https://github.com/processing/processing/pull/2651 diff --git a/java/libraries/net/src/processing/net/Server.java b/java/libraries/net/src/processing/net/Server.java index 4cfeb784d..05addd256 100644 --- a/java/libraries/net/src/processing/net/Server.java +++ b/java/libraries/net/src/processing/net/Server.java @@ -107,8 +107,9 @@ public class Server implements Runnable { } } catch (IOException e) { - e.printStackTrace(); + //e.printStackTrace(); thread = null; + throw new RuntimeException(e); //errorMessage("", e); } } diff --git a/java/libraries/sound/src/processing/sound/Engine.java b/java/libraries/sound/src/processing/sound/Engine.java index 51a04a40f..9d03657b9 100644 --- a/java/libraries/sound/src/processing/sound/Engine.java +++ b/java/libraries/sound/src/processing/sound/Engine.java @@ -32,7 +32,7 @@ public class Engine { private static int m_bufferSize=512; private Engine() { - welcome(); + //welcome(); methCla = new MethClaInterface(); methCla.engineNew(m_sampleRate, m_bufferSize); methCla.engineStart(); diff --git a/pdex/.externalToolBuilders/Ant_Builder.launch b/pdex/.externalToolBuilders/Ant_Builder.launch index 9b95f0090..2f93ff37a 100644 --- a/pdex/.externalToolBuilders/Ant_Builder.launch +++ b/pdex/.externalToolBuilders/Ant_Builder.launch @@ -12,7 +12,7 @@ - + diff --git a/pdex/build.xml b/pdex/build.xml index 3d4828f8a..a839c9160 100644 --- a/pdex/build.xml +++ b/pdex/build.xml @@ -37,7 +37,7 @@ - + diff --git a/todo.txt b/todo.txt index e8dd91c28..c7e49d2d7 100644 --- a/todo.txt +++ b/todo.txt @@ -1,77 +1,134 @@ 0229 pde (3.0a2) X new tab/rename dialog box X https://github.com/processing/processing/issues/2431 +X fix issue where the browser wasn't opening the reference properly +X https://github.com/processing/processing/pull/2657 +X fix "No such file or directory" error when exporting an application on OSX +X this also resulted in the application not being signed at all +X https://github.com/processing/processing/issues/2614 +X this is a fairly major issue... +X possible to open a sketch multiple times +X by double-clicking one of its files instead of the main pde file +X user opens non-main pde of already open sketch, it'll open again +X https://github.com/processing/processing/issues/2506 +X remove the prefs for 32/64-bit from Preferences +X also remove the extra OS X cruft inside Runner.java +X OS X export button not disabled on other platforms +X https://github.com/processing/processing/issues/2642 +o try new syntax package +X exclude 'fonts' folder from build (since it's going into the JRE) +X was storing our fonts in both ./lib/fonts and jre/lib/fonts +X now gets the jre folder and loads from there +X make ant fail when trying to delete JRE files that don't exist +X some aren't being removed properly +X fix the build scripts to include the examples +X https://github.com/processing/processing/issues/2652 +X all examples are out of "processing/java" and are now in "processing-docs/content/". The Book examples have been removed entirely from our repositories. +o "Platform is ${platform}" message during 'ant clean' +o on OS X, but not Windows (haven't checked Linux) +X this was in pdex/build.xml +X remove welcome message from the sound library +X URL opening problem fixed by use of getCanonicalPath() on Windows +X https://github.com/processing/processing/issues/2656 +X add a new pref for the 3.0 sketchbook location +X if Server constructor fails, throw an exception +X https://github.com/processing/processing/issues/2604 +o check on why 2x core.jar inside the Java folder +o maybe OS X Java can't look in subfolders? (just auto-adds things) +o https://github.com/processing/processing/issues/2344 +X one is used by the PDE, the other is used as a library +X get 'modified' indicator working on document windows again +X https://github.com/processing/processing/issues/2194 +X remove default menu bar hack when 7u60 arrives +X http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8022667 +X when renaming a tab, include the previous name to be edited +X changing the mode on an untitled, unmodified sketch removes untitled status + +gsoc +X clear status messages in the Contribution Manager +X https://github.com/processing/processing/pull/2667 +X https://github.com/processing/processing/issues/2599 +X may need a progress bar for "save as" +X or just the file copy function in general +X since it may take a long time (i.e. 1000s of screen grabs) +X http://code.google.com/p/processing/issues/detail?id=31 +X https://github.com/processing/processing/issues/70 +X https://github.com/processing/processing/pull/2370 pulls X insert tabs properly when prefs set for tabs mode X https://github.com/processing/processing/pull/2607 - - -_ fix the build scripts to include the examples -_ https://github.com/processing/processing/issues/2652 -_ reference wasn't included either -_ https://github.com/processing/processing/issues/2656 - - -_ "Platform is ${platform}" message during 'ant clean' - -_ add a new pref for the 3.0 sketchbook location -_ remove minim -_ add the new sound library to the build process - -_ double-clicking a .pde file doesn't open properly on OS X -_ https://github.com/processing/processing/issues/2639 -_ OS X export button not disabled on other platforms -_ https://github.com/processing/processing/issues/2642 - -_ look at the sound library https://github.com/wirsing/ProcessingSound - -_ moving p5 examples to the web repo -all examples are out of "processing/java" and are now in "processing-docs/content/". The Book examples have been removed entirely from our repositories. -_ remove reference.zip from main repo -_ processing-web/java_generate/ReferenceGenerator - -_ try new syntax package -_ possibility of libraries folder inside a particular sketch? -_ incorporate new preproc -_ https://github.com/fjenett/processing-preprocessor-antlr4 -_ glw? lwjgl? -_ move sketchbook into its own window -_ move recent into the sketchbook menu -_ needs to recognize the p5 app folder -_ also should recognize the user's home dir -_ move examples into web repo -_ make reference and examples build process part of dist -_ separate ant targets, but only require them for dist -_ as separate targets, folks can build explicitly if they'd like - -_ shouldn't write sketch.properties unless it's a non-default mode -_ https://github.com/processing/processing/issues/2531 -_ huge i18n patch -_ https://github.com/processing/processing/pull/2084 -_ make ant fail when trying to delete JRE files that don't exist -_ some aren't being removed properly +X improve look of Nimbus LAF +X https://github.com/processing/processing/pull/2671 earlier +X maxHeapSize typo in the build scripts +X https://github.com/processing/processing/issues/2603 +X remove minim +X add the new sound library to the build process X for() loop with nothing inside parens crashes Auto Format X https://github.com/processing/processing/issues/2141 +o double-clicking a .pde file doesn't open properly on OS X +o https://github.com/processing/processing/issues/2639 +X moving p5 examples to the web repo +X move examples into web repo +o OS X not opening a sketch at all on pde double-click? (though opening the app) +X Chinese text is overlapped in Processing 2.1 editor +X https://github.com/processing/processing/issues/2173 +o type cut off in dialog boxes on OS X retina machines +o https://github.com/processing/processing/issues/2116 +o add spaces to the end of the text? +X seems to have fixed itself in newer Java releases +X implement Windows menu in the PDE +X https://github.com/processing/processing/issues/584 -gsoc + +pending +_ huge i18n patch +_ https://github.com/processing/processing/pull/2084 +_ look at the sound library https://github.com/wirsing/ProcessingSound +_ sound is not yet supported on Windows +_ glw? lwjgl? retina jogl? +_ make reference build process part of dist +_ https://github.com/processing/processing-docs/issues/85 +_ separate ant target, but only require them for dist +_ as separate targets, folks can build explicitly if they'd like +_ processing-docs/java_generate/ReferenceGenerator/processingrefBuild.sh +_ remove reference.zip from main repo + + +gsoc/help me _ `return` keyword not treated as such when followed by a bracket _ https://github.com/processing/processing/issues/2099 _ IllegalArgumentException when clicking between editor windows _ https://github.com/processing/processing/issues/2530 _ "String index out of range" error _ https://github.com/processing/processing/issues/1940 - -medium -_ possible to open a sketch multiple times -_ by double-clicking one of its files instead of the main pde file -_ https://github.com/processing/processing/issues/2506 +_ shouldn't write sketch.properties unless it's a non-default mode +_ https://github.com/processing/processing/issues/2531 _ closing the color selector makes things freeze (only Linux and Windows?) _ https://github.com/processing/processing/issues/2381 -_ check on why 2x core.jar inside the Java folder -_ maybe OS X Java can't look in subfolders? (just auto-adds things) +_ move sketchbook into its own window +_ move recent into the sketchbook menu +_ needs to recognize the p5 app folder +_ also should recognize the user's home dir +_ incorporate new preproc +_ https://github.com/fjenett/processing-preprocessor-antlr4 +_ SOCKS proxy not working: +_ https://github.com/processing/processing/issues/2643 +_ the current code that gets/sets the pref is in Preferences +_ instead of current implementation, can we auto-detect proxy settings? +_ old issue: https://github.com/processing/processing/issues/1476 +_ http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html +_ http://docs.oracle.com/javase/1.5.0/docs/guide/net/proxies.html +_ http://stackoverflow.com/questions/4933677/detecting-windows-ie-proxy-setting-using-java +_ http://www.java2s.com/Code/Java/Network-Protocol/DetectProxySettingsforInternetConnection.htm +_ problems with non-US keyboards and some shortcuts +_ https://github.com/processing/processing/issues/2199 + + +medium +_ possibility of libraries folder inside a particular sketch? _ display "1" is not correct in 2.1.2 _ https://github.com/processing/processing/issues/2502 _ re/move things from Google Code downloads @@ -118,21 +175,6 @@ _ PDE and sketches are 2x smaller on high-res Windows 8 machines _ https://github.com/processing/processing/issues/2411 -pulls -_ may need a progress bar for "save as" -_ or just the file copy function in general -_ since it may take a long time (i.e. 1000s of screen grabs) -_ http://code.google.com/p/processing/issues/detail?id=31 -_ https://github.com/processing/processing/issues/70 -_ https://github.com/processing/processing/pull/2370 - - -post 2.1 cleaning -_ remove the prefs for 32/64-bit from Preferences -_ remove the extra OS X cruft inside Runner.java -_ exclude 'fonts' folder from build (since it's going into the JRE) - - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -310,9 +352,6 @@ PDE - Processing Development Environment PDE / Dialogs -_ type cut off in dialog boxes on OS X retina machines -_ https://github.com/processing/processing/issues/2116 -_ add spaces to the end of the text? _ dialog box icon is fuzzy on OS X retina machines _ https://github.com/processing/processing/issues/2117 _ solution might be our own dialog boxes @@ -850,14 +889,13 @@ _ http://code.google.com/p/processing/issues/detail?id=632 DIST / Mac OS X +_ more OS X-specific hackery for improved appearance +_ https://developer.apple.com/library/mac/technotes/tn2007/tn2196.html _ possible better option for doing retina? _ g.getFontRenderContext().getTransform().equals(AffineTransform.getScaleInstance(2.0, 2.0)) _ appbundler improvements _ don't re-copy JRE into work folder if already exists _ implement a splash screen -_ remove default menu bar hack when 7u60 arrives -_ http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8022667 -_ OS X not opening a sketch at all on pde double-click? (though opening the app) _ LWJGL forum discussion _ http://lwjgl.org/forum/index.php/topic,4711.225.html _ change cmd line for OS X to use symlink?