mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-18 07:52:14 +01:00
Resynced with Processing/Wiring IDE code: improved auto-format, better performance for EditorConsole, etc...
This commit is contained in:
parent
2de016c367
commit
3ea01968d7
200
app/Base.java
200
app/Base.java
@ -52,12 +52,10 @@ import com.ice.jni.registry.*;
|
||||
* files and images, etc) that comes from that.
|
||||
*/
|
||||
public class Base {
|
||||
static final int VERSION = 1;
|
||||
static final int VERSION = 3;
|
||||
static final String VERSION_NAME = "0004 Alpha";
|
||||
|
||||
static public int platform;
|
||||
|
||||
// platform IDs for platform
|
||||
// platform IDs for PApplet.platform
|
||||
|
||||
static final int WINDOWS = 1;
|
||||
static final int MACOS9 = 2;
|
||||
@ -65,17 +63,52 @@ public class Base {
|
||||
static final int LINUX = 4;
|
||||
static final int OTHER = 0;
|
||||
|
||||
// used by split, all the standard whitespace chars
|
||||
// (uncludes unicode nbsp, that little bostage)
|
||||
|
||||
// moved from PApplet
|
||||
// in preperation of detaching the IDE from the
|
||||
// Arduino core classes
|
||||
static final String WHITESPACE = " \t\n\r\f\u00A0";
|
||||
|
||||
/**
|
||||
* Path of filename opened on the command line,
|
||||
* or via the MRJ open document handler.
|
||||
*/
|
||||
static String openedAtStartup;
|
||||
|
||||
Editor editor;
|
||||
|
||||
/**
|
||||
* "1.3" or "1.1" or whatever (just the first three chars)
|
||||
*/
|
||||
public static final String javaVersionName =
|
||||
System.getProperty("java.version").substring(0,3);
|
||||
|
||||
/**
|
||||
* Version of Java that's in use, whether 1.1 or 1.3 or whatever,
|
||||
* stored as a float.
|
||||
* <P>
|
||||
* Note that because this is stored as a float, the values may
|
||||
* not be <EM>exactly</EM> 1.3 or 1.4. Instead, make sure you're
|
||||
* comparing against 1.3f or 1.4f, which will have the same amount
|
||||
* of error (i.e. 1.40000001). This could just be a double, but
|
||||
* since Processing only uses floats, it's safer to do this,
|
||||
* because there's no good way to specify a double with the preproc.
|
||||
*/
|
||||
public static final float javaVersion =
|
||||
new Float(javaVersionName).floatValue();
|
||||
|
||||
/**
|
||||
* Current platform in use, one of the
|
||||
* PConstants WINDOWS, MACOSX, MACOS9, LINUX or OTHER.
|
||||
*/
|
||||
static public int platform;
|
||||
|
||||
/**
|
||||
* Current platform in use.
|
||||
* <P>
|
||||
* Equivalent to System.getProperty("os.name"), just used internally.
|
||||
*/
|
||||
static public String platformName = System.getProperty("os.name");
|
||||
static public String platformName =
|
||||
System.getProperty("os.name");
|
||||
|
||||
static {
|
||||
// figure out which operating system
|
||||
@ -105,23 +138,6 @@ public class Base {
|
||||
}
|
||||
}
|
||||
|
||||
// used by split, all the standard whitespace chars
|
||||
// (uncludes unicode nbsp, that little bostage)
|
||||
|
||||
static final String WHITESPACE = " \t\n\r\f\u00A0";
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Path of filename opened on the command line,
|
||||
* or via the MRJ open document handler.
|
||||
*/
|
||||
static String openedAtStartup;
|
||||
|
||||
Editor editor;
|
||||
|
||||
|
||||
static public void main(String args[]) {
|
||||
|
||||
// make sure that this is running on java 1.4
|
||||
@ -179,6 +195,9 @@ public class Base {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// use native popups so they don't look so crappy on osx
|
||||
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
|
||||
|
||||
// build the editor object
|
||||
editor = new Editor();
|
||||
|
||||
@ -214,7 +233,6 @@ public class Base {
|
||||
* returns true if running on windows.
|
||||
*/
|
||||
static public boolean isWindows() {
|
||||
|
||||
return platform == WINDOWS;
|
||||
}
|
||||
|
||||
@ -223,7 +241,6 @@ public class Base {
|
||||
* true if running on linux.
|
||||
*/
|
||||
static public boolean isLinux() {
|
||||
|
||||
return platform == LINUX;
|
||||
}
|
||||
|
||||
@ -363,26 +380,40 @@ public class Base {
|
||||
}
|
||||
|
||||
|
||||
static public File getBuildFolder() {
|
||||
String buildPath = Preferences.get("build.path");
|
||||
if (buildPath != null) return new File(buildPath);
|
||||
static File buildFolder;
|
||||
|
||||
File folder = new File(getTempFolder(), "build");
|
||||
if (!folder.exists()) folder.mkdirs();
|
||||
return folder;
|
||||
static public File getBuildFolder() {
|
||||
if (buildFolder == null) {
|
||||
String buildPath = Preferences.get("build.path");
|
||||
if (buildPath != null) {
|
||||
buildFolder = new File(buildPath);
|
||||
|
||||
} else {
|
||||
//File folder = new File(getTempFolder(), "build");
|
||||
//if (!folder.exists()) folder.mkdirs();
|
||||
buildFolder = createTempFolder("build");
|
||||
buildFolder.deleteOnExit();
|
||||
}
|
||||
}
|
||||
return buildFolder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the path to the platform's temporary folder, by creating
|
||||
* a temporary temporary file and getting its parent folder.
|
||||
* <br/>
|
||||
* Modified for revision 0094 to actually make the folder randomized
|
||||
* to avoid conflicts in multi-user environments. (Bug 177)
|
||||
*/
|
||||
static public File getTempFolder() {
|
||||
static public File createTempFolder(String name) {
|
||||
try {
|
||||
File ignored = File.createTempFile("ignored", null);
|
||||
String tempPath = ignored.getParent();
|
||||
ignored.delete();
|
||||
return new File(tempPath);
|
||||
File folder = File.createTempFile(name, null);
|
||||
//String tempPath = ignored.getParent();
|
||||
//return new File(tempPath);
|
||||
folder.delete();
|
||||
folder.mkdirs();
|
||||
return folder;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -548,6 +579,55 @@ public class Base {
|
||||
// .................................................................
|
||||
|
||||
|
||||
// someone needs to be slapped
|
||||
//static KeyStroke closeWindowKeyStroke;
|
||||
|
||||
/**
|
||||
* Return true if the key event was a Ctrl-W or an ESC,
|
||||
* both indicators to close the window.
|
||||
* Use as part of a keyPressed() event handler for frames.
|
||||
*/
|
||||
/*
|
||||
static public boolean isCloseWindowEvent(KeyEvent e) {
|
||||
if (closeWindowKeyStroke == null) {
|
||||
int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
||||
closeWindowKeyStroke = KeyStroke.getKeyStroke('W', modifiers);
|
||||
}
|
||||
return ((e.getKeyCode() == KeyEvent.VK_ESCAPE) ||
|
||||
KeyStroke.getKeyStrokeForEvent(e).equals(closeWindowKeyStroke));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Registers key events for a Ctrl-W and ESC with an ActionListener
|
||||
* that will take care of disposing the window.
|
||||
*/
|
||||
static public void registerWindowCloseKeys(JRootPane root, //Window window,
|
||||
ActionListener disposer) {
|
||||
/*
|
||||
JRootPane root = null;
|
||||
if (window instanceof JFrame) {
|
||||
root = ((JFrame)window).getRootPane();
|
||||
} else if (window instanceof JDialog) {
|
||||
root = ((JDialog)window).getRootPane();
|
||||
}
|
||||
*/
|
||||
|
||||
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
|
||||
root.registerKeyboardAction(disposer, stroke,
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
||||
stroke = KeyStroke.getKeyStroke('W', modifiers);
|
||||
root.registerKeyboardAction(disposer, stroke,
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
// .................................................................
|
||||
|
||||
|
||||
/**
|
||||
* Given the reference filename from the keywords list,
|
||||
* builds a URL and passes it to openURL.
|
||||
@ -858,7 +938,9 @@ public class Base {
|
||||
static public void removeDir(File dir) {
|
||||
if (dir.exists()) {
|
||||
removeDescendants(dir);
|
||||
dir.delete();
|
||||
if (!dir.delete()) {
|
||||
System.err.println("Could not delete " + dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -917,6 +999,46 @@ public class Base {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a list of all files within the specified folder,
|
||||
* and returns a list of their relative paths.
|
||||
* Ignores any files/folders prefixed with a dot.
|
||||
*/
|
||||
static public String[] listFiles(String path, boolean relative) {
|
||||
return listFiles(new File(path), relative);
|
||||
}
|
||||
|
||||
static public String[] listFiles(File folder, boolean relative) {
|
||||
String path = folder.getAbsolutePath();
|
||||
Vector vector = new Vector();
|
||||
listFiles(relative ? (path + File.separator) : "", path, vector);
|
||||
String outgoing[] = new String[vector.size()];
|
||||
vector.copyInto(outgoing);
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
static protected void listFiles(String basePath,
|
||||
String path, Vector vector) {
|
||||
File folder = new File(path);
|
||||
String list[] = folder.list();
|
||||
if (list == null) return;
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (list[i].charAt(0) == '.') continue;
|
||||
|
||||
File file = new File(path, list[i]);
|
||||
String newPath = file.getAbsolutePath();
|
||||
if (newPath.startsWith(basePath)) {
|
||||
newPath = newPath.substring(basePath.length());
|
||||
}
|
||||
vector.add(newPath);
|
||||
if (file.isDirectory()) {
|
||||
listFiles(basePath, newPath, vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Equivalent to the one in PApplet, but static (die() is removed)
|
||||
*/
|
||||
|
@ -76,7 +76,9 @@ public class Compiler implements MessageConsumer {
|
||||
|
||||
String userdir = System.getProperty("user.dir") + File.separator;
|
||||
|
||||
String baseCommandCompiler[] = new String[] {
|
||||
LibraryManager libraryManager = new LibraryManager();
|
||||
|
||||
String preCommandCompiler[] = new String[] {
|
||||
((!Base.isMacOS()) ? "tools/avr/bin/avr-gcc" :
|
||||
userdir + "tools/avr/bin/avr-gcc"),
|
||||
"-c", // compile, don't link
|
||||
@ -86,11 +88,19 @@ public class Compiler implements MessageConsumer {
|
||||
"-w", // surpress all warnings
|
||||
"-mmcu=" + Preferences.get("build.mcu"),
|
||||
"-DF_CPU=" + Preferences.get("build.f_cpu"),
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
String baseCommandCompilerCPP[] = new String[] {
|
||||
// use lib directories as include paths
|
||||
String[] libDirs = libraryManager.getFolderPaths();
|
||||
|
||||
// Last two arguments will specify the file being compiled and the output file.
|
||||
String[] baseCommandCompiler = new String[preCommandCompiler.length + libDirs.length + 2];
|
||||
System.arraycopy(preCommandCompiler, 0, baseCommandCompiler, 0, preCommandCompiler.length);
|
||||
for (int i = 0; i < libDirs.length; ++i) {
|
||||
baseCommandCompiler[preCommandCompiler.length + i] = "-I" + libDirs[i];
|
||||
}
|
||||
|
||||
String preCommandCompilerCPP[] = new String[] {
|
||||
((!Base.isMacOS()) ? "tools/avr/bin/avr-g++" :
|
||||
userdir + "tools/avr/bin/avr-g++"),
|
||||
"-c", // compile, don't link
|
||||
@ -101,46 +111,33 @@ public class Compiler implements MessageConsumer {
|
||||
"-fno-exceptions",
|
||||
"-mmcu=" + Preferences.get("build.mcu"),
|
||||
"-DF_CPU=" + Preferences.get("build.f_cpu"),
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
String baseCommandLinker[] = new String[] {
|
||||
// use lib directories as include paths
|
||||
// Last two arguments will specify the file being compiled and the output file.
|
||||
String[] baseCommandCompilerCPP = new String[preCommandCompilerCPP.length + libDirs.length + 2];
|
||||
System.arraycopy(preCommandCompilerCPP, 0, baseCommandCompilerCPP, 0, preCommandCompilerCPP.length);
|
||||
for (int i = 0; i < libDirs.length; ++i) {
|
||||
baseCommandCompilerCPP[preCommandCompilerCPP.length + i] = "-I" + libDirs[i];
|
||||
}
|
||||
|
||||
String preCommandLinker[] = new String[] {
|
||||
((!Base.isMacOS()) ? "tools/avr/bin/avr-gcc" :
|
||||
userdir + "tools/avr/bin/avr-gcc"),
|
||||
" ",
|
||||
"-mmcu=" + Preferences.get("build.mcu"),
|
||||
"-o",
|
||||
" ",
|
||||
// ((!Base.isMacOS()) ? "" : userdir) + "lib/uart.o",
|
||||
// ((!Base.isMacOS()) ? "" : userdir) + "lib/buffer.o",
|
||||
// ((!Base.isMacOS()) ? "" : userdir) + "lib/timer.o",
|
||||
// ((!Base.isMacOS()) ? "" : userdir) + "lib/wiring.o",
|
||||
// ((!Base.isMacOS()) ? "" : userdir) + "lib/pins_arduino.o",
|
||||
//((!Base.isMacOS()) ? "lib/WApplet.o" :
|
||||
//userdir + "lib/WApplet.o"),
|
||||
//((!Base.isMacOS()) ? "lib/WSerial.o" :
|
||||
//userdir + "lib/WSerial.o"),
|
||||
//((!Base.isMacOS()) ? "lib/WTimer.o" :
|
||||
//userdir + "lib/WTimer.o"),
|
||||
//((!Base.isMacOS()) ? "lib/Servo.o" :
|
||||
//userdir + "lib/Servo.o"),
|
||||
////((!Base.isMacOS()) ? "lib/Wire.o" :
|
||||
//// userdir + "lib/Wire.o"),
|
||||
////((!Base.isMacOS()) ? "lib/WServo.o" :
|
||||
//// userdir + "lib/WServo.o"),
|
||||
//((!Base.isMacOS()) ? "lib/WDisplay.o" :
|
||||
//userdir + "lib/WDisplay.o"),
|
||||
//((!Base.isMacOS()) ? "lib/WEncoder.o" :
|
||||
//userdir + "lib/WEncoder.o"),
|
||||
//((!Base.isMacOS()) ? "lib/WInterrupts.o" :
|
||||
//userdir + "lib/WInterrupts.o"),
|
||||
//((!Base.isMacOS()) ? "lib/WCounter.o" :
|
||||
//userdir + "lib/WCounter.o"),
|
||||
//((!Base.isMacOS()) ? "tools/avr/avr/lib/libm.a" :
|
||||
//userdir + "tools/avr/avr/lib/libm.a")
|
||||
};
|
||||
|
||||
// use lib object files during include
|
||||
String[] libObjectFiles = libraryManager.getObjectFiles();
|
||||
String[] baseCommandLinker = new String[preCommandLinker.length + libObjectFiles.length];
|
||||
System.arraycopy(preCommandLinker, 0, baseCommandLinker, 0, preCommandLinker.length);
|
||||
for (int i = 0; i < libObjectFiles.length; ++i) {
|
||||
baseCommandLinker[preCommandLinker.length + i] = libObjectFiles[i];
|
||||
}
|
||||
|
||||
String baseCommandObjcopy[] = new String[] {
|
||||
((!Base.isMacOS()) ? "tools/avr/bin/avr-objcopy" :
|
||||
userdir + "tools/avr/bin/avr-objcopy"),
|
||||
@ -295,8 +292,8 @@ public class Compiler implements MessageConsumer {
|
||||
Process process;
|
||||
boolean compiling = true;
|
||||
for(int i = 0; i < fileCount; i++) {
|
||||
baseCommandCompiler[8] = sourceNames[i];
|
||||
baseCommandCompiler[9] = "-o"+ objectNames[i];
|
||||
baseCommandCompiler[baseCommandCompiler.length - 2] = sourceNames[i];
|
||||
baseCommandCompiler[baseCommandCompiler.length - 1] = "-o"+ objectNames[i];
|
||||
//System.arraycopy(baseCommandCompiler.length
|
||||
//for(int j = 0; j < baseCommandCompiler.length; j++) {
|
||||
// System.out.println(baseCommandCompiler[j]);
|
||||
@ -325,8 +322,8 @@ public class Compiler implements MessageConsumer {
|
||||
}
|
||||
|
||||
for(int i = 0; i < fileCountCPP; i++) {
|
||||
baseCommandCompilerCPP[9] = sourceNamesCPP[i];
|
||||
baseCommandCompilerCPP[10] = "-o"+ objectNamesCPP[i];
|
||||
baseCommandCompilerCPP[baseCommandCompilerCPP.length - 2] = sourceNamesCPP[i];
|
||||
baseCommandCompilerCPP[baseCommandCompilerCPP.length - 1] = "-o"+ objectNamesCPP[i];
|
||||
//for(int j = 0; j < baseCommandCompilerCPP.length; j++) {
|
||||
// System.out.println(baseCommandCompilerCPP[j]);
|
||||
//}
|
||||
|
645
app/Editor.java
645
app/Editor.java
@ -30,6 +30,8 @@ import processing.app.syntax.*;
|
||||
import processing.app.tools.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
@ -46,10 +48,8 @@ import javax.swing.undo.*;
|
||||
import com.oroinc.text.regex.*;
|
||||
|
||||
import com.apple.mrj.*;
|
||||
|
||||
import gnu.io.*;
|
||||
|
||||
|
||||
public class Editor extends JFrame
|
||||
implements MRJAboutHandler, MRJQuitHandler, MRJPrefsHandler,
|
||||
MRJOpenDocumentHandler //, MRJOpenApplicationHandler
|
||||
@ -101,27 +101,27 @@ public class Editor extends JFrame
|
||||
//Point presentLocation;
|
||||
//Window presentationWindow;
|
||||
RunButtonWatcher watcher;
|
||||
Runner runtime;
|
||||
//Runner runtime;
|
||||
|
||||
//JMenuItem exportAppItem;
|
||||
JMenuItem exportAppItem;
|
||||
JMenuItem saveMenuItem;
|
||||
JMenuItem saveAsMenuItem;
|
||||
|
||||
//ButtonGroup serialGroup;
|
||||
JMenu serialSubMenu;
|
||||
JMenu serialRateSubMenu;
|
||||
JMenu serialMenu;
|
||||
JMenu serialRateMenu;
|
||||
SerialMenuListener serialMenuListener;
|
||||
|
||||
//
|
||||
boolean debugging;
|
||||
boolean running;
|
||||
boolean presenting;
|
||||
boolean debugging;
|
||||
|
||||
// undo fellers
|
||||
JMenuItem undoItem, redoItem;
|
||||
protected UndoAction undoAction;
|
||||
protected RedoAction redoAction;
|
||||
UndoManager undo;
|
||||
// used internally, and only briefly
|
||||
CompoundEdit compoundEdit;
|
||||
|
||||
//static public UndoManager undo = new UndoManager(); // editor needs this guy
|
||||
|
||||
//
|
||||
@ -129,7 +129,7 @@ public class Editor extends JFrame
|
||||
//SketchHistory history; // TODO re-enable history
|
||||
Sketchbook sketchbook;
|
||||
//Preferences preferences;
|
||||
FindReplace find;
|
||||
//FindReplace find;
|
||||
|
||||
//static Properties keywords; // keyword -> reference html lookup
|
||||
|
||||
@ -175,7 +175,7 @@ public class Editor extends JFrame
|
||||
setJMenuBar(menubar);
|
||||
|
||||
// doesn't matter when this is created, just make it happen at some point
|
||||
find = new FindReplace(Editor.this);
|
||||
//find = new FindReplace(Editor.this);
|
||||
|
||||
Container pain = getContentPane();
|
||||
pain.setLayout(new BorderLayout());
|
||||
@ -240,28 +240,87 @@ public class Editor extends JFrame
|
||||
listener = new EditorListener(this, textarea);
|
||||
pain.add(box);
|
||||
|
||||
/*
|
||||
// set the undo stuff for this feller
|
||||
Document document = textarea.getDocument();
|
||||
//document.addUndoableEditListener(new PdeUndoableEditListener());
|
||||
document.addUndoableEditListener(new UndoableEditListener() {
|
||||
public void undoableEditHappened(UndoableEditEvent e) {
|
||||
if (undo != null) {
|
||||
//System.out.println(e.getEdit());
|
||||
undo.addEdit(e.getEdit());
|
||||
undoAction.updateUndoState();
|
||||
redoAction.updateRedoState();
|
||||
DropTarget dt = new DropTarget(this, new DropTargetListener() {
|
||||
|
||||
public void dragEnter(DropTargetDragEvent event) {
|
||||
// debug messages for diagnostics
|
||||
//System.out.println("dragEnter " + event);
|
||||
event.acceptDrag(DnDConstants.ACTION_COPY);
|
||||
}
|
||||
|
||||
public void dragExit(DropTargetEvent event) {
|
||||
//System.out.println("dragExit " + event);
|
||||
}
|
||||
|
||||
public void dragOver(DropTargetDragEvent event) {
|
||||
//System.out.println("dragOver " + event);
|
||||
event.acceptDrag(DnDConstants.ACTION_COPY);
|
||||
}
|
||||
|
||||
public void dropActionChanged(DropTargetDragEvent event) {
|
||||
//System.out.println("dropActionChanged " + event);
|
||||
}
|
||||
|
||||
public void drop(DropTargetDropEvent event) {
|
||||
//System.out.println("drop " + event);
|
||||
event.acceptDrop(DnDConstants.ACTION_COPY);
|
||||
|
||||
Transferable transferable = event.getTransferable();
|
||||
DataFlavor flavors[] = transferable.getTransferDataFlavors();
|
||||
int successful = 0;
|
||||
|
||||
for (int i = 0; i < flavors.length; i++) {
|
||||
try {
|
||||
//System.out.println(flavors[i]);
|
||||
//System.out.println(transferable.getTransferData(flavors[i]));
|
||||
java.util.List list =
|
||||
(java.util.List) transferable.getTransferData(flavors[i]);
|
||||
for (int j = 0; j < list.size(); j++) {
|
||||
Object item = list.get(j);
|
||||
if (item instanceof File) {
|
||||
File file = (File) item;
|
||||
|
||||
// see if this is a .pde file to be opened
|
||||
String filename = file.getName();
|
||||
if (filename.endsWith(".pde")) {
|
||||
String name = filename.substring(0, filename.length() - 4);
|
||||
File parent = file.getParentFile();
|
||||
if (name.equals(parent.getName())) {
|
||||
handleOpenFile(file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sketch.addFile(file)) {
|
||||
successful++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (successful == 0) {
|
||||
error("No files were added to the sketch.");
|
||||
|
||||
} else if (successful == 1) {
|
||||
message("One file added to the sketch.");
|
||||
|
||||
} else {
|
||||
message(successful + " files added to the sketch.");
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hack for #@#)$(* Mac OS X.
|
||||
* This appears to only be required on OS X 10.2, and this code
|
||||
* isn't even being hit on OS X 10.3 or Windows.
|
||||
* Hack for #@#)$(* Mac OS X 10.2.
|
||||
* <p/>
|
||||
* This appears to only be required on OS X 10.2, and is not
|
||||
* even being called on later versions of OS X or Windows.
|
||||
*/
|
||||
public Dimension getMinimumSize() {
|
||||
//System.out.println("getting minimum size");
|
||||
@ -435,16 +494,6 @@ public class Editor extends JFrame
|
||||
JMenuItem item;
|
||||
JMenu menu = new JMenu("File");
|
||||
|
||||
/*
|
||||
menu.add(item = new JMenuItem("do the editor thing"));
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textarea.getPainter().setFont(new Font("Courier", Font.PLAIN, 36));
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
if (!Preferences.getBoolean("export.library")) {
|
||||
item = newJMenuItem("New", 'N');
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -452,30 +501,12 @@ public class Editor extends JFrame
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
} else {
|
||||
item = newJMenuItem("New Sketch", 'N');
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleNew(false);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = new JMenuItem("New Library");
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleNewLibrary();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
}
|
||||
menu.add(sketchbook.getOpenMenu());
|
||||
|
||||
saveMenuItem = newJMenuItem("Save", 'S');
|
||||
saveMenuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleSave();
|
||||
handleSave(false);
|
||||
}
|
||||
});
|
||||
menu.add(saveMenuItem);
|
||||
@ -496,14 +527,18 @@ public class Editor extends JFrame
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
// exportAppItem = newJMenuItem("Export Application", 'E', true);
|
||||
// exportAppItem.addActionListener(new ActionListener() {
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// handleExportApp();
|
||||
// }
|
||||
// });
|
||||
// menu.add(exportAppItem);
|
||||
|
||||
/*exportAppItem = newJMenuItem("Export Application", 'E', true);
|
||||
exportAppItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//buttons.activate(EditorButtons.EXPORT);
|
||||
//SwingUtilities.invokeLater(new Runnable() {
|
||||
//public void run() {
|
||||
handleExportApplication();
|
||||
//}});
|
||||
}
|
||||
});
|
||||
menu.add(exportAppItem);
|
||||
*/
|
||||
menu.addSeparator();
|
||||
|
||||
item = newJMenuItem("Page Setup", 'P', true);
|
||||
@ -552,14 +587,14 @@ public class Editor extends JFrame
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
//item = newJMenuItem("Present", 'R', true);
|
||||
//item.addActionListener(new ActionListener() {
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// handleRun(true);
|
||||
// }
|
||||
// });
|
||||
//menu.add(item);
|
||||
|
||||
/*item = newJMenuItem("Present", 'R', true);
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleRun(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
*/
|
||||
item = new JMenuItem("Stop");
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -583,7 +618,7 @@ public class Editor extends JFrame
|
||||
if (Base.isWindows() || Base.isMacOS()) {
|
||||
// no way to do an 'open in file browser' on other platforms
|
||||
// since there isn't any sort of standard
|
||||
item = new JMenuItem("Show Sketch Folder");
|
||||
item = newJMenuItem("Show Sketch Folder", 'K', false);
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//Base.openFolder(sketchDir);
|
||||
@ -599,59 +634,6 @@ public class Editor extends JFrame
|
||||
}
|
||||
|
||||
|
||||
// taken from an ancient version of processing
|
||||
class SerialMenuListener implements ActionListener {
|
||||
|
||||
SerialMenuListener() {}
|
||||
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
int count = serialSubMenu.getItemCount();
|
||||
Object to;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
to = serialSubMenu.getItem(i);
|
||||
if ( to instanceof JCheckBoxMenuItem) ((JCheckBoxMenuItem)serialSubMenu.getItem(i)).setState(false);
|
||||
}
|
||||
|
||||
JCheckBoxMenuItem item = (JCheckBoxMenuItem)actionevent.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getLabel();
|
||||
|
||||
Preferences.set("serial.port", name);
|
||||
//System.out.println("port set to " + name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// manages the serial port speed menu
|
||||
class SerialRateMenuListener implements ActionListener {
|
||||
|
||||
SerialRateMenuListener() {}
|
||||
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
int count = serialRateSubMenu.getItemCount();
|
||||
Object to;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
to = serialRateSubMenu.getItem(i);
|
||||
if ( to instanceof JCheckBoxMenuItem) ((JCheckBoxMenuItem)serialRateSubMenu.getItem(i)).setState(false);
|
||||
}
|
||||
|
||||
JCheckBoxMenuItem item = (JCheckBoxMenuItem)actionevent.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getLabel();
|
||||
|
||||
Preferences.set("serial.debug_rate", name);
|
||||
//System.out.println("serial port speed set to " + name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected JMenu buildToolsMenu() {
|
||||
JMenuItem item;
|
||||
JMenuItem rbMenuItem;
|
||||
@ -668,40 +650,49 @@ public class Editor extends JFrame
|
||||
|
||||
item = newJMenuItem("Auto Format", 'T', false);
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
synchronized public void actionPerformed(ActionEvent e) {
|
||||
new AutoFormat(Editor.this).show();
|
||||
//handleBeautify();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
/*item = new JMenuItem("Create Font...");
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//new CreateFont().show(sketch.dataFolder);
|
||||
new CreateFont(Editor.this).show();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
*/
|
||||
|
||||
item = new JMenuItem("Archive Sketch");
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new Archiver(Editor.this).show();
|
||||
//Archiver archiver = new Archiver();
|
||||
//archiver.setup(Editor.this);
|
||||
//archiver.show();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = new JMenuItem("Export Folder...");
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new ExportFolder(Editor.this).show();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
menu.addSeparator();
|
||||
|
||||
// The serial options
|
||||
|
||||
serialSubMenu = new JMenu("Serial Port");
|
||||
|
||||
// item = newJMenuItem("Update List", 'E', false);
|
||||
// item.addActionListener(new ActionListener() {
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// // if (debug) displayResult("Serial Port List Updated");
|
||||
// //updateSerial();
|
||||
// }
|
||||
// });
|
||||
|
||||
//serialGroup = new ButtonGroup();
|
||||
serialMenu = new JMenu("Serial Port");
|
||||
populateSerialMenu();
|
||||
menu.add(serialSubMenu);
|
||||
menu.add(serialMenu);
|
||||
|
||||
// End of The serial options
|
||||
serialRateMenu = new JMenu("Serial Monitor Baud Rate");
|
||||
|
||||
// menu.addSeparator();
|
||||
|
||||
// add the serial speed submenu
|
||||
|
||||
serialRateSubMenu = new JMenu("Serial Monitor Baud Rate");
|
||||
|
||||
//serialSubMenu.add(item);
|
||||
//serialSubMenu.addSeparator();
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
|
||||
String curr_rate = Preferences.get("serial.debug_rate");
|
||||
@ -710,10 +701,10 @@ public class Editor extends JFrame
|
||||
rbMenuItem = new JCheckBoxMenuItem(portRates[i], portRates[i].equals(curr_rate));
|
||||
rbMenuItem.addActionListener(srml);
|
||||
group.add(rbMenuItem);
|
||||
serialRateSubMenu.add(rbMenuItem);
|
||||
serialRateMenu.add(rbMenuItem);
|
||||
}
|
||||
|
||||
menu.add(serialRateSubMenu);
|
||||
menu.add(serialRateMenu);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
@ -739,6 +730,7 @@ public class Editor extends JFrame
|
||||
public void menuCanceled(MenuEvent e) {}
|
||||
public void menuDeselected(MenuEvent e) {}
|
||||
public void menuSelected(MenuEvent e) {
|
||||
//System.out.println("Tools menu selected.");
|
||||
populateSerialMenu();
|
||||
}
|
||||
});
|
||||
@ -746,25 +738,89 @@ public class Editor extends JFrame
|
||||
return menu;
|
||||
}
|
||||
|
||||
// taken from an ancient version of processing
|
||||
class SerialMenuListener implements ActionListener {
|
||||
//public SerialMenuListener() { }
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(serialMenu == null) {
|
||||
System.out.println("serialMenu is null");
|
||||
return;
|
||||
}
|
||||
int count = serialMenu.getItemCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
((JCheckBoxMenuItem)serialMenu.getItem(i)).setState(false);
|
||||
}
|
||||
|
||||
JCheckBoxMenuItem item = (JCheckBoxMenuItem)e.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getLabel();
|
||||
|
||||
//System.out.println(item.getLabel());
|
||||
Preferences.set("serial.port", name);
|
||||
//System.out.println("set to " + get("serial.port"));
|
||||
}
|
||||
|
||||
/*
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println(e.getSource());
|
||||
String name = e.getActionCommand();
|
||||
PdeBase.properties.put("serial.port", name);
|
||||
System.out.println("set to " + get("serial.port"));
|
||||
//editor.skOpen(path + File.separator + name, name);
|
||||
// need to push "serial.port" into PdeBase.properties
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// manages the serial port speed menu
|
||||
class SerialRateMenuListener implements ActionListener {
|
||||
|
||||
SerialRateMenuListener() {}
|
||||
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
int count = serialRateMenu.getItemCount();
|
||||
Object to;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
to = serialRateMenu.getItem(i);
|
||||
if ( to instanceof JCheckBoxMenuItem) ((JCheckBoxMenuItem)serialRateMenu.getItem(i)).setState(false);
|
||||
}
|
||||
|
||||
JCheckBoxMenuItem item = (JCheckBoxMenuItem)actionevent.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getLabel();
|
||||
|
||||
Preferences.set("serial.debug_rate", name);
|
||||
//System.out.println("serial port speed set to " + name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void populateSerialMenu() {
|
||||
// getting list of ports
|
||||
|
||||
JMenuItem rbMenuItem;
|
||||
|
||||
serialSubMenu.removeAll();
|
||||
//System.out.println("Clearing serial port menu.");
|
||||
|
||||
serialMenu.removeAll();
|
||||
|
||||
try
|
||||
{
|
||||
for (Enumeration enumeration = CommPortIdentifier.getPortIdentifiers(); enumeration.hasMoreElements();)
|
||||
{
|
||||
CommPortIdentifier commportidentifier = (CommPortIdentifier)enumeration.nextElement();
|
||||
//System.out.println("Found communication port: " + commportidentifier);
|
||||
if (commportidentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
|
||||
{
|
||||
//System.out.println("Adding port to serial port menu: " + commportidentifier);
|
||||
String curr_port = commportidentifier.getName();
|
||||
rbMenuItem = new JCheckBoxMenuItem(curr_port, curr_port.equals(Preferences.get("serial.port")));
|
||||
rbMenuItem.addActionListener(serialMenuListener);
|
||||
//serialGroup.add(rbMenuItem);
|
||||
serialSubMenu.add(rbMenuItem);
|
||||
serialMenu.add(rbMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,12 +832,12 @@ public class Editor extends JFrame
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
if (serialSubMenu.getItemCount() == 0) {
|
||||
serialSubMenu.setEnabled(false);
|
||||
if (serialMenu.getItemCount() == 0) {
|
||||
serialMenu.setEnabled(false);
|
||||
}
|
||||
|
||||
//serialSubMenu.addSeparator();
|
||||
//serialSubMenu.add(item);
|
||||
//serialMenu.addSeparator();
|
||||
//serialMenu.add(item);
|
||||
}
|
||||
|
||||
|
||||
@ -882,7 +938,7 @@ public class Editor extends JFrame
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textarea.cut();
|
||||
sketch.setModified();
|
||||
sketch.setModified(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
@ -899,7 +955,7 @@ public class Editor extends JFrame
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textarea.paste();
|
||||
sketch.setModified();
|
||||
sketch.setModified(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
@ -917,7 +973,9 @@ public class Editor extends JFrame
|
||||
item = newJMenuItem("Find...", 'F');
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
find.show();
|
||||
new FindReplace(Editor.this).show();
|
||||
//find.show();
|
||||
//find.setVisible(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
@ -927,6 +985,8 @@ public class Editor extends JFrame
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// TODO find next should only be enabled after a
|
||||
// search has actually taken place
|
||||
//find.find(true);
|
||||
FindReplace find = new FindReplace(Editor.this); //.show();
|
||||
find.find(true);
|
||||
}
|
||||
});
|
||||
@ -986,11 +1046,17 @@ public class Editor extends JFrame
|
||||
undoItem.setEnabled(true);
|
||||
undoItem.setText(undo.getUndoPresentationName());
|
||||
putValue(Action.NAME, undo.getUndoPresentationName());
|
||||
if (sketch != null) {
|
||||
sketch.setModified(true); // 0107
|
||||
}
|
||||
} else {
|
||||
this.setEnabled(false);
|
||||
undoItem.setEnabled(false);
|
||||
undoItem.setText("Undo");
|
||||
putValue(Action.NAME, "Undo");
|
||||
if (sketch != null) {
|
||||
sketch.setModified(false); // 0107
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1015,7 +1081,7 @@ public class Editor extends JFrame
|
||||
|
||||
protected void updateRedoState() {
|
||||
if (undo.canRedo()) {
|
||||
this.setEnabled(true);
|
||||
//this.setEnabled(true);
|
||||
redoItem.setEnabled(true);
|
||||
redoItem.setText(undo.getRedoPresentationName());
|
||||
putValue(Action.NAME, undo.getRedoPresentationName());
|
||||
@ -1095,64 +1161,24 @@ public class Editor extends JFrame
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called to update the text but not switch to a different
|
||||
* set of code (which would affect the undo manager).
|
||||
*/
|
||||
//public void setText(String what) { //, boolean discardUndo) {
|
||||
//setText(what, 0, 0);
|
||||
//}
|
||||
|
||||
|
||||
/**
|
||||
* Called to update the text but not switch to a different
|
||||
* set of code (which would affect the undo manager).
|
||||
*/
|
||||
public void setText(String what, int selectionStart, int selectionEnd) {
|
||||
beginCompoundEdit();
|
||||
textarea.setText(what);
|
||||
endCompoundEdit();
|
||||
|
||||
// make sure that a tool isn't asking for a bad location
|
||||
selectionStart =
|
||||
Math.max(0, Math.min(selectionStart, textarea.getDocumentLength()));
|
||||
selectionEnd =
|
||||
Math.max(0, Math.min(selectionStart, textarea.getDocumentLength()));
|
||||
textarea.select(selectionStart, selectionEnd);
|
||||
textarea.requestFocus(); // get the caret blinking
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by Sketch when the tab is changed or a new set of files are opened.
|
||||
*/
|
||||
/*
|
||||
public void setText(String currentProgram,
|
||||
int selectionStart, int selectionEnd,
|
||||
UndoManager currentUndo) {
|
||||
//System.out.println("setting text, changing undo");
|
||||
this.undo = null;
|
||||
|
||||
//if (discardUndo) undo.discardAllEdits();
|
||||
|
||||
// don't set the undo object yet otherwise gets hokey
|
||||
textarea.setText(currentProgram);
|
||||
textarea.select(selectionStart, selectionEnd);
|
||||
textarea.requestFocus(); // get the caret blinking
|
||||
|
||||
this.undo = currentUndo;
|
||||
undoAction.updateUndoState();
|
||||
redoAction.updateRedoState();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public void setDocument(SyntaxDocument document,
|
||||
int selectionStart, int selectionStop,
|
||||
int scrollPosition, UndoManager undo) {
|
||||
|
||||
textarea.setDocument(document, selectionStart, selectionStop,
|
||||
scrollPosition);
|
||||
|
||||
textarea.requestFocus(); // get the caret blinking
|
||||
|
||||
this.undo = undo;
|
||||
undoAction.updateUndoState();
|
||||
redoAction.updateRedoState();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
@ -1179,7 +1205,10 @@ public class Editor extends JFrame
|
||||
// connect the undo listener to the editor
|
||||
code.document.addUndoableEditListener(new UndoableEditListener() {
|
||||
public void undoableEditHappened(UndoableEditEvent e) {
|
||||
if (undo != null) {
|
||||
if (compoundEdit != null) {
|
||||
compoundEdit.addEdit(e.getEdit());
|
||||
|
||||
} else if (undo != null) {
|
||||
undo.addEdit(e.getEdit());
|
||||
undoAction.updateUndoState();
|
||||
redoAction.updateRedoState();
|
||||
@ -1200,12 +1229,24 @@ public class Editor extends JFrame
|
||||
redoAction.updateRedoState();
|
||||
}
|
||||
|
||||
public void beginCompoundEdit() {
|
||||
compoundEdit = new CompoundEdit();
|
||||
}
|
||||
|
||||
public void endCompoundEdit() {
|
||||
compoundEdit.end();
|
||||
undo.addEdit(compoundEdit);
|
||||
undoAction.updateUndoState();
|
||||
redoAction.updateRedoState();
|
||||
compoundEdit = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void handleRun(boolean present) {
|
||||
doClose();
|
||||
running = true;
|
||||
buttons.run();
|
||||
buttons.activate(EditorButtons.RUN);
|
||||
message("Compiling...");
|
||||
// do this for the terminal window / dos prompt / etc
|
||||
for (int i = 0; i < 10; i++) System.out.println();
|
||||
@ -1291,17 +1332,15 @@ public class Editor extends JFrame
|
||||
}
|
||||
|
||||
public void run() {
|
||||
/*
|
||||
while (Thread.currentThread() == thread) {
|
||||
if (runtime == null) {
|
||||
/*if (runtime == null) {
|
||||
stop();
|
||||
|
||||
} else {
|
||||
// FIXME remove dependance from core libs
|
||||
//if (runtime.applet != null) {
|
||||
// if (runtime.applet.finished) {
|
||||
// stop();
|
||||
//}
|
||||
if (runtime.applet != null) {
|
||||
if (runtime.applet.finished) {
|
||||
stop();
|
||||
}
|
||||
//buttons.running(!runtime.applet.finished);
|
||||
|
||||
} else if (runtime.process != null) {
|
||||
@ -1310,13 +1349,12 @@ public class Editor extends JFrame
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException e) { }
|
||||
//System.out.println("still inside runner thread");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@ -1329,6 +1367,7 @@ public class Editor extends JFrame
|
||||
public void handleSerial() {
|
||||
if (!debugging) {
|
||||
console.clear();
|
||||
buttons.activate(EditorButtons.SERIAL);
|
||||
serialPort = new Serial(true);
|
||||
debugging = true;
|
||||
} else {
|
||||
@ -1343,6 +1382,7 @@ public class Editor extends JFrame
|
||||
} else {
|
||||
doStop();
|
||||
}
|
||||
buttons.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -1350,11 +1390,11 @@ public class Editor extends JFrame
|
||||
* Stop the applet but don't kill its window.
|
||||
*/
|
||||
public void doStop() {
|
||||
//if (runtime != null) runtime.stop();
|
||||
if (debugging) {
|
||||
serialPort.dispose();
|
||||
debugging = false;
|
||||
}
|
||||
if (runtime != null) runtime.stop();
|
||||
if (watcher != null) watcher.stop();
|
||||
message(EMPTY);
|
||||
|
||||
@ -1371,32 +1411,31 @@ public class Editor extends JFrame
|
||||
* mode, this will always be called instead of doStop().
|
||||
*/
|
||||
public void doClose() {
|
||||
/*
|
||||
//if (presenting) {
|
||||
//presentationWindow.hide();
|
||||
//} else {
|
||||
try {
|
||||
//try {
|
||||
// the window will also be null the process was running
|
||||
// externally. so don't even try setting if window is null
|
||||
// since Runner will set the appletLocation when an
|
||||
// external process is in use.
|
||||
//if (runtime.window != null) {
|
||||
appletLocation = runtime.window.getLocation();
|
||||
}
|
||||
} catch (NullPointerException e) { }
|
||||
// if (runtime.window != null) {
|
||||
// appletLocation = runtime.window.getLocation();
|
||||
// }
|
||||
//} catch (NullPointerException e) { }
|
||||
//}
|
||||
|
||||
//if (running) doStop();
|
||||
doStop(); // need to stop if runtime error
|
||||
|
||||
try {
|
||||
if (runtime != null) {
|
||||
//try {
|
||||
/*if (runtime != null) {
|
||||
runtime.close(); // kills the window
|
||||
runtime = null; // will this help?
|
||||
}
|
||||
} catch (Exception e) { }
|
||||
}*/
|
||||
//} catch (Exception e) { }
|
||||
//buttons.clear(); // done by doStop
|
||||
*/
|
||||
|
||||
sketch.cleanup();
|
||||
|
||||
// [toxi 030903]
|
||||
@ -1450,7 +1489,7 @@ public class Editor extends JFrame
|
||||
options[0]);
|
||||
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
handleSave();
|
||||
handleSave(true);
|
||||
checkModified2();
|
||||
|
||||
} else if (result == JOptionPane.NO_OPTION) {
|
||||
@ -1480,15 +1519,20 @@ public class Editor extends JFrame
|
||||
/**
|
||||
* New was called (by buttons or by menu), first check modified
|
||||
* and if things work out ok, handleNew2() will be called.
|
||||
*
|
||||
* <p/>
|
||||
* If shift is pressed when clicking the toolbar button, then
|
||||
* force the opposite behavior from sketchbook.prompt's setting
|
||||
*/
|
||||
public void handleNew(boolean shift) {
|
||||
public void handleNew(final boolean shift) {
|
||||
buttons.activate(EditorButtons.NEW);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
doStop();
|
||||
handleNewShift = shift;
|
||||
handleNewLibrary = false;
|
||||
checkModified(HANDLE_NEW);
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
@ -1539,6 +1583,7 @@ public class Editor extends JFrame
|
||||
"An error occurred while creating\n" +
|
||||
"a new sketch. Arduino must now quit.", e);
|
||||
}
|
||||
buttons.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -1556,15 +1601,22 @@ public class Editor extends JFrame
|
||||
* Open a sketch given the full path to the .pde file.
|
||||
* Pass in 'null' to prompt the user for the name of the sketch.
|
||||
*/
|
||||
public void handleOpen(String path) {
|
||||
public void handleOpen(final String ipath) {
|
||||
// haven't run across a case where i can verify that this works
|
||||
// because open is usually very fast.
|
||||
buttons.activate(EditorButtons.OPEN);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
String path = ipath;
|
||||
if (path == null) { // "open..." selected from the menu
|
||||
path = sketchbook.handleOpen();
|
||||
if (path == null) return;
|
||||
}
|
||||
doClose();
|
||||
//doStop();
|
||||
handleOpenPath = path;
|
||||
checkModified(HANDLE_OPEN);
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
@ -1692,7 +1744,32 @@ public class Editor extends JFrame
|
||||
|
||||
|
||||
// there is no handleSave1 since there's never a need to prompt
|
||||
public void handleSave() {
|
||||
/**
|
||||
* Actually handle the save command. If 'force' is set to false,
|
||||
* this will happen in another thread so that the message area
|
||||
* will update and the save button will stay highlighted while the
|
||||
* save is happening. If 'force' is true, then it will happen
|
||||
* immediately. This is used during a quit, because invokeLater()
|
||||
* won't run properly while a quit is happening. This fixes
|
||||
* <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=276">Bug 276</A>.
|
||||
*/
|
||||
public void handleSave(boolean force) {
|
||||
doStop();
|
||||
buttons.activate(EditorButtons.SAVE);
|
||||
|
||||
if (force) {
|
||||
handleSave2();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
handleSave2();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void handleSave2() {
|
||||
message("Saving...");
|
||||
try {
|
||||
if (sketch.save()) {
|
||||
@ -1718,7 +1795,10 @@ public class Editor extends JFrame
|
||||
|
||||
public void handleSaveAs() {
|
||||
doStop();
|
||||
buttons.activate(EditorButtons.SAVE);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
message("Saving...");
|
||||
try {
|
||||
if (sketch.saveAs()) {
|
||||
@ -1727,12 +1807,12 @@ public class Editor extends JFrame
|
||||
} else {
|
||||
message("Save Cancelled.");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// show the error as a message in the window
|
||||
error(e);
|
||||
}
|
||||
buttons.clear();
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
@ -1746,10 +1826,13 @@ public class Editor extends JFrame
|
||||
synchronized public void handleExport() {
|
||||
if(debugging)
|
||||
doStop();
|
||||
buttons.activate(EditorButtons.EXPORT);
|
||||
console.clear();
|
||||
//String what = sketch.isLibrary() ? "Applet" : "Library";
|
||||
//message("Exporting " + what + "...");
|
||||
message("Uploading to I/O Board...");
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
//boolean success = sketch.isLibrary() ?
|
||||
//sketch.exportLibrary() : sketch.exportApplet();
|
||||
@ -1769,11 +1852,57 @@ public class Editor extends JFrame
|
||||
e.printStackTrace();
|
||||
}
|
||||
buttons.clear();
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
synchronized public void handleExportApp() {
|
||||
message("Arduino - Export - app");
|
||||
message("Exporting application...");
|
||||
try {
|
||||
if (sketch.exportApplication()) {
|
||||
message("Done exporting.");
|
||||
} else {
|
||||
// error message will already be visible
|
||||
}
|
||||
} catch (Exception e) {
|
||||
message("Error during export.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
buttons.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if the sketch has been modified, and if so,
|
||||
* asks the user to save the sketch or cancel the export.
|
||||
* This prevents issues where an incomplete version of the sketch
|
||||
* would be exported, and is a fix for
|
||||
* <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=157">Bug 157</A>
|
||||
*/
|
||||
public boolean handleExportCheckModified() {
|
||||
if (!sketch.modified) return true;
|
||||
|
||||
Object[] options = { "OK", "Cancel" };
|
||||
int result = JOptionPane.showOptionDialog(this,
|
||||
"Save changes before export?",
|
||||
"Save",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
options,
|
||||
options[0]);
|
||||
if (result == JOptionPane.OK_OPTION) {
|
||||
handleSave(true);
|
||||
|
||||
} else {
|
||||
// why it's not CANCEL_OPTION is beyond me (at least on the mac)
|
||||
// but f-- it.. let's get this shite done..
|
||||
//} else if (result == JOptionPane.CANCEL_OPTION) {
|
||||
message("Export canceled, changes must first be saved.");
|
||||
buttons.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1799,6 +1928,7 @@ public class Editor extends JFrame
|
||||
Preferences.save();
|
||||
|
||||
sketchbook.clean();
|
||||
console.handleQuit();
|
||||
|
||||
//System.out.println("exiting here");
|
||||
System.exit(0);
|
||||
@ -1887,6 +2017,14 @@ public class Editor extends JFrame
|
||||
// ...................................................................
|
||||
|
||||
|
||||
/**
|
||||
* Show an error int the status bar.
|
||||
*/
|
||||
public void error(String what) {
|
||||
status.error(what);
|
||||
}
|
||||
|
||||
|
||||
public void error(Exception e) {
|
||||
if (e == null) {
|
||||
System.err.println("Editor.error() was passed a null exception.");
|
||||
@ -1905,7 +2043,7 @@ public class Editor extends JFrame
|
||||
if (mess.indexOf(javaLang) == 0) {
|
||||
mess = mess.substring(javaLang.length());
|
||||
}
|
||||
status.error(mess);
|
||||
error(mess);
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -1923,37 +2061,23 @@ public class Editor extends JFrame
|
||||
String rxString = "RuntimeException: ";
|
||||
if (mess.indexOf(rxString) == 0) {
|
||||
mess = mess.substring(rxString.length());
|
||||
//System.out.println("MESS3: " + mess);
|
||||
}
|
||||
String javaLang = "java.lang.";
|
||||
if (mess.indexOf(javaLang) == 0) {
|
||||
mess = mess.substring(javaLang.length());
|
||||
}
|
||||
status.error(mess);
|
||||
|
||||
buttons.clearRun();
|
||||
error(mess);
|
||||
buttons.clear();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void finished() {
|
||||
running = false;
|
||||
buttons.clearRun();
|
||||
message("Done.");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public void message(String msg) {
|
||||
status.notice(msg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void messageClear(String msg) {
|
||||
status.unnotice(msg);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// ...................................................................
|
||||
|
||||
@ -1962,7 +2086,6 @@ public class Editor extends JFrame
|
||||
* Returns the edit popup menu.
|
||||
*/
|
||||
class TextAreaPopup extends JPopupMenu {
|
||||
//protected ReferenceKeys referenceItems = new ReferenceKeys();
|
||||
String currentDir = System.getProperty("user.dir");
|
||||
String referenceFile = null;
|
||||
|
||||
@ -1977,6 +2100,7 @@ public class Editor extends JFrame
|
||||
cutItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textarea.cut();
|
||||
sketch.setModified(true);
|
||||
}
|
||||
});
|
||||
this.add(cutItem);
|
||||
@ -1993,6 +2117,7 @@ public class Editor extends JFrame
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textarea.paste();
|
||||
sketch.setModified(true);
|
||||
}
|
||||
});
|
||||
this.add(item);
|
||||
|
@ -41,9 +41,11 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
};
|
||||
|
||||
static final int BUTTON_COUNT = title.length;
|
||||
static final int BUTTON_WIDTH = 27; //Preferences.GRID_SIZE;
|
||||
static final int BUTTON_HEIGHT = 32; //Preferences.GRID_SIZE;
|
||||
static final int BUTTON_GAP = 15; //BUTTON_WIDTH / 2;
|
||||
/// height, width of the toolbar buttons
|
||||
static final int BUTTON_WIDTH = 27;
|
||||
static final int BUTTON_HEIGHT = 32;
|
||||
/// amount of space between groups of buttons on the toolbar
|
||||
static final int BUTTON_GAP = 15;
|
||||
|
||||
static final int RUN = 0;
|
||||
static final int STOP = 1;
|
||||
@ -59,7 +61,7 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
static final int ACTIVE = 2;
|
||||
|
||||
Editor editor;
|
||||
boolean disableRun;
|
||||
//boolean disableRun;
|
||||
//Label status;
|
||||
|
||||
Image offscreen;
|
||||
@ -72,7 +74,7 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
Image rollover[];
|
||||
Image active[];
|
||||
int currentRollover;
|
||||
int currentSelection;
|
||||
//int currentSelection;
|
||||
|
||||
JPopupMenu popup;
|
||||
|
||||
@ -234,10 +236,10 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
if (sel == -1) return;
|
||||
|
||||
if (state[sel] != ACTIVE) {
|
||||
if (!(disableRun && ((sel == RUN) || (sel == STOP)))) {
|
||||
//if (!(disableRun && ((sel == RUN) || (sel == STOP)))) {
|
||||
setState(sel, ROLLOVER, true);
|
||||
currentRollover = sel;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,6 +286,10 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
|
||||
|
||||
public void mouseExited(MouseEvent e) {
|
||||
// if the popup menu for is visible, don't register this,
|
||||
// because the popup being set visible will fire a mouseExited() event
|
||||
if ((popup != null) && popup.isVisible()) return;
|
||||
|
||||
if (state[OPEN] != INACTIVE) {
|
||||
setState(OPEN, INACTIVE, true);
|
||||
}
|
||||
@ -295,26 +301,77 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
int x = e.getX();
|
||||
int y = e.getY();
|
||||
final int x = e.getX();
|
||||
final int y = e.getY();
|
||||
|
||||
int sel = findSelection(x, y);
|
||||
///if (sel == -1) return false;
|
||||
if (sel == -1) return;
|
||||
currentRollover = -1;
|
||||
currentSelection = sel;
|
||||
if (!(disableRun && ((sel == RUN) || (sel == STOP)))) {
|
||||
setState(sel, ACTIVE, true);
|
||||
}
|
||||
//int currentSelection = sel;
|
||||
//if (!(disableRun && ((sel == RUN) || (sel == STOP)))) {
|
||||
// moving the handling of this over into the editor
|
||||
//setState(sel, ACTIVE, true);
|
||||
//}
|
||||
|
||||
if (currentSelection == OPEN) {
|
||||
//if (currentSelection == OPEN) {
|
||||
//switch (currentSelection) {
|
||||
switch (sel) {
|
||||
case RUN:
|
||||
//if (!disableRun) {
|
||||
editor.handleRun(e.isShiftDown());
|
||||
//}
|
||||
break;
|
||||
|
||||
case STOP:
|
||||
//if (!disableRun) {
|
||||
//setState(RUN, INACTIVE, true);
|
||||
//setInactive();
|
||||
editor.handleStop();
|
||||
//}
|
||||
break;
|
||||
|
||||
case OPEN:
|
||||
if (popup == null) {
|
||||
//popup = new JPopupMenu();
|
||||
popup = editor.sketchbook.getPopupMenu();
|
||||
// no events properly being fired, so nevermind
|
||||
/*
|
||||
popup.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println("action " + e);
|
||||
}
|
||||
});
|
||||
popup.addComponentListener(new ComponentAdapter() {
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
System.out.println("hidden " + e);
|
||||
}
|
||||
});
|
||||
*/
|
||||
add(popup);
|
||||
}
|
||||
//editor.sketchbook.rebuildPopup(popup);
|
||||
popup.show(this, x, y);
|
||||
//activate(OPEN);
|
||||
//SwingUtilities.invokeLater(new Runnable() {
|
||||
//public void run() {
|
||||
popup.show(EditorButtons.this, x, y);
|
||||
//}});
|
||||
break;
|
||||
|
||||
case NEW:
|
||||
editor.handleNew(e.isShiftDown());
|
||||
break;
|
||||
|
||||
case SAVE:
|
||||
editor.handleSave(false);
|
||||
break;
|
||||
|
||||
case EXPORT:
|
||||
editor.handleExport();
|
||||
break;
|
||||
|
||||
case SERIAL:
|
||||
editor.handleSerial();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,6 +380,7 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
/*
|
||||
switch (currentSelection) {
|
||||
case RUN:
|
||||
if (!disableRun) {
|
||||
@ -344,14 +402,47 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
case SERIAL: editor.handleSerial(); break;
|
||||
}
|
||||
currentSelection = -1;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public void disableRun(boolean what) {
|
||||
disableRun = what;
|
||||
//public void disableRun(boolean what) {
|
||||
//disableRun = what;
|
||||
//}
|
||||
|
||||
|
||||
/*
|
||||
public void run() {
|
||||
if (inactive == null) return;
|
||||
clear();
|
||||
setState(RUN, ACTIVE, true);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public void running(boolean yesno) {
|
||||
setState(RUN, yesno ? ACTIVE : INACTIVE, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a particular button to be active.
|
||||
*/
|
||||
public void activate(int what) {
|
||||
if (inactive == null) return;
|
||||
setState(what, ACTIVE, true);
|
||||
}
|
||||
|
||||
|
||||
//public void clearRun() {
|
||||
//if (inactive == null) return;
|
||||
//setState(RUN, INACTIVE, true);
|
||||
//}
|
||||
|
||||
|
||||
/**
|
||||
* Clear all the state of all buttons.
|
||||
*/
|
||||
public void clear() { // (int button) {
|
||||
if (inactive == null) return;
|
||||
|
||||
@ -363,24 +454,6 @@ public class EditorButtons extends JComponent implements MouseInputListener {
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
if (inactive == null) return;
|
||||
clear();
|
||||
setState(RUN, ACTIVE, true);
|
||||
}
|
||||
|
||||
|
||||
public void running(boolean yesno) {
|
||||
setState(RUN, yesno ? ACTIVE : INACTIVE, true);
|
||||
}
|
||||
|
||||
|
||||
public void clearRun() {
|
||||
if (inactive == null) return;
|
||||
setState(RUN, INACTIVE, true);
|
||||
}
|
||||
|
||||
|
||||
public void message(String msg) {
|
||||
//status.setText(msg + " "); // don't mind the hack
|
||||
status = msg;
|
||||
|
@ -28,7 +28,7 @@ import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Message console that sits below the editing area.
|
||||
@ -41,7 +41,7 @@ public class EditorConsole extends JScrollPane {
|
||||
Editor editor;
|
||||
|
||||
JTextPane consoleTextPane;
|
||||
StyledDocument consoleDoc;
|
||||
BufferedStyledDocument consoleDoc;
|
||||
|
||||
MutableAttributeSet stdStyle;
|
||||
MutableAttributeSet errStyle;
|
||||
@ -51,6 +51,10 @@ public class EditorConsole extends JScrollPane {
|
||||
//int maxCharCount;
|
||||
int maxLineCount;
|
||||
|
||||
static File errFile;
|
||||
static File outFile;
|
||||
static File tempFolder;
|
||||
|
||||
static PrintStream systemOut;
|
||||
static PrintStream systemErr;
|
||||
|
||||
@ -66,9 +70,9 @@ public class EditorConsole extends JScrollPane {
|
||||
|
||||
maxLineCount = Preferences.getInteger("console.length");
|
||||
|
||||
consoleTextPane = new JTextPane();
|
||||
consoleDoc = new BufferedStyledDocument(10000, maxLineCount);
|
||||
consoleTextPane = new JTextPane(consoleDoc);
|
||||
consoleTextPane.setEditable(false);
|
||||
consoleDoc = consoleTextPane.getStyledDocument();
|
||||
|
||||
// necessary?
|
||||
MutableAttributeSet standard = new SimpleAttributeSet();
|
||||
@ -115,15 +119,20 @@ public class EditorConsole extends JScrollPane {
|
||||
systemOut = System.out;
|
||||
systemErr = System.err;
|
||||
|
||||
tempFolder = Base.createTempFolder("console");
|
||||
try {
|
||||
String outFileName = Preferences.get("console.output.file");
|
||||
if (outFileName != null) {
|
||||
stdoutFile = new FileOutputStream(outFileName);
|
||||
outFile = new File(tempFolder, outFileName);
|
||||
stdoutFile = new FileOutputStream(outFile);
|
||||
//outFile.deleteOnExit();
|
||||
}
|
||||
|
||||
String errFileName = Preferences.get("console.error.file");
|
||||
if (errFileName != null) {
|
||||
stderrFile = new FileOutputStream(outFileName);
|
||||
errFile = new File(tempFolder, errFileName);
|
||||
stderrFile = new FileOutputStream(errFile);
|
||||
//errFile.deleteOnExit();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Base.showWarning("Console Error",
|
||||
@ -151,6 +160,52 @@ public class EditorConsole extends JScrollPane {
|
||||
if (Base.isMacOS()) {
|
||||
setBorder(null);
|
||||
}
|
||||
|
||||
// periodically post buffered messages to the console
|
||||
// should the interval come from the preferences file?
|
||||
new javax.swing.Timer(250, new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
// only if new text has been added
|
||||
if (consoleDoc.hasAppendage) {
|
||||
// insert the text that's been added in the meantime
|
||||
consoleDoc.insertAll();
|
||||
// always move to the end of the text as it's added
|
||||
consoleTextPane.setCaretPosition(consoleDoc.getLength());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the streams so that the temporary files can be deleted.
|
||||
* <p/>
|
||||
* File.deleteOnExit() cannot be used because the stdout and stderr
|
||||
* files are inside a folder, and have to be deleted before the
|
||||
* folder itself is deleted, which can't be guaranteed when using
|
||||
* the deleteOnExit() method.
|
||||
*/
|
||||
public void handleQuit() {
|
||||
// replace original streams to remove references to console's streams
|
||||
System.setOut(systemOut);
|
||||
System.setErr(systemErr);
|
||||
|
||||
// close the PrintStream
|
||||
consoleOut.close();
|
||||
consoleErr.close();
|
||||
|
||||
// also have to close the original FileOutputStream
|
||||
// otherwise it won't be shut down completely
|
||||
try {
|
||||
stdoutFile.close();
|
||||
stderrFile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace(systemOut);
|
||||
}
|
||||
|
||||
outFile.delete();
|
||||
errFile.delete();
|
||||
tempFolder.delete();
|
||||
}
|
||||
|
||||
|
||||
@ -174,10 +229,8 @@ public class EditorConsole extends JScrollPane {
|
||||
synchronized public void message(String what, boolean err, boolean advance) {
|
||||
if (err) {
|
||||
systemErr.print(what);
|
||||
//systemErr.print("CE" + what);
|
||||
} else {
|
||||
systemOut.print(what);
|
||||
//systemOut.print("CO" + what);
|
||||
}
|
||||
|
||||
if (advance) {
|
||||
@ -204,66 +257,13 @@ public class EditorConsole extends JScrollPane {
|
||||
* and eventually leads to EditorConsole.appendText(), which directly
|
||||
* updates the Swing text components, causing deadlock.
|
||||
* <P>
|
||||
* A quick hack from Francis Li (who found this to be a problem)
|
||||
* wraps the contents of appendText() into a Runnable and uses
|
||||
* SwingUtilities.invokeLater() to ensure that the updates only
|
||||
* occur on the main event dispatching thread, and that appears
|
||||
* to have solved the problem.
|
||||
* <P>
|
||||
* unfortunately this is probably extremely slow and helping cause
|
||||
* some of the general print() and println() mess.. need to fix
|
||||
* up so that it's using a proper queue instead.
|
||||
* Updates are buffered to the console and displayed at regular
|
||||
* intervals on Swing's event-dispatching thread. (patch by David Mellis)
|
||||
*/
|
||||
synchronized private void appendText(String txt, boolean e) {
|
||||
final String text = txt;
|
||||
final boolean err = e;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
// check how many lines have been used so far
|
||||
// if too many, shave off a few lines from the beginning
|
||||
Element element = consoleDoc.getDefaultRootElement();
|
||||
int lineCount = element.getElementCount();
|
||||
int overage = lineCount - maxLineCount;
|
||||
if (overage > 0) {
|
||||
// if 1200 lines, and 1000 lines is max,
|
||||
// find the position of the end of the 200th line
|
||||
//systemOut.println("overage is " + overage);
|
||||
Element lineElement = element.getElement(overage);
|
||||
if (lineElement == null) return; // do nuthin
|
||||
|
||||
int endOffset = lineElement.getEndOffset();
|
||||
// remove to the end of the 200th line
|
||||
consoleDoc.remove(0, endOffset);
|
||||
consoleDoc.appendString(txt, e ? errStyle : stdStyle);
|
||||
}
|
||||
|
||||
// make sure this line doesn't go over 32k chars
|
||||
lineCount = element.getElementCount(); // may have changed
|
||||
Element currentElement = element.getElement(lineCount-1);
|
||||
int currentStart = currentElement.getStartOffset();
|
||||
int currentEnd = currentElement.getEndOffset();
|
||||
//systemOut.println(currentEnd - currentStart);
|
||||
if (currentEnd - currentStart > 10000) { // force a newline
|
||||
consoleDoc.insertString(consoleDoc.getLength(), "\n",
|
||||
err ? errStyle : stdStyle);
|
||||
}
|
||||
|
||||
// add the text to the end of the console,
|
||||
consoleDoc.insertString(consoleDoc.getLength(), text,
|
||||
err ? errStyle : stdStyle);
|
||||
|
||||
// always move to the end of the text as it's added
|
||||
consoleTextPane.setCaretPosition(consoleDoc.getLength());
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// ignore the error otherwise this will cause an infinite loop
|
||||
// maybe not a good idea in the long run?
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void clear() {
|
||||
try {
|
||||
consoleDoc.remove(0, consoleDoc.getLength());
|
||||
@ -332,3 +332,87 @@ class EditorConsoleStream extends OutputStream {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Buffer updates to the console and output them in batches. For info, see:
|
||||
* http://java.sun.com/products/jfc/tsc/articles/text/element_buffer and
|
||||
* http://javatechniques.com/public/java/docs/gui/jtextpane-speed-part2.html
|
||||
* appendString() is called from multiple threads, and insertAll from the
|
||||
* swing event thread, so they need to be synchronized
|
||||
*/
|
||||
class BufferedStyledDocument extends DefaultStyledDocument {
|
||||
ArrayList elements = new ArrayList();
|
||||
int maxLineLength, maxLineCount;
|
||||
int currentLineLength = 0;
|
||||
boolean needLineBreak = false;
|
||||
boolean hasAppendage = false;
|
||||
|
||||
public BufferedStyledDocument(int maxLineLength, int maxLineCount) {
|
||||
this.maxLineLength = maxLineLength;
|
||||
this.maxLineCount = maxLineCount;
|
||||
}
|
||||
|
||||
/** buffer a string for insertion at the end of the DefaultStyledDocument */
|
||||
public synchronized void appendString(String str, AttributeSet a) {
|
||||
// do this so that it's only updated when needed (otherwise console
|
||||
// updates every 250 ms when an app isn't even running.. see bug 180)
|
||||
hasAppendage = true;
|
||||
|
||||
// process each line of the string
|
||||
while (str.length() > 0) {
|
||||
// newlines within an element have (almost) no effect, so we need to
|
||||
// replace them with proper paragraph breaks (start and end tags)
|
||||
if (needLineBreak || currentLineLength > maxLineLength) {
|
||||
elements.add(new ElementSpec(a, ElementSpec.EndTagType));
|
||||
elements.add(new ElementSpec(a, ElementSpec.StartTagType));
|
||||
currentLineLength = 0;
|
||||
}
|
||||
|
||||
if (str.indexOf('\n') == -1) {
|
||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
||||
str.toCharArray(), 0, str.length()));
|
||||
currentLineLength += str.length();
|
||||
needLineBreak = false;
|
||||
str = str.substring(str.length()); // eat the string
|
||||
} else {
|
||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
||||
str.toCharArray(), 0, str.indexOf('\n') + 1));
|
||||
needLineBreak = true;
|
||||
str = str.substring(str.indexOf('\n') + 1); // eat the line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** insert the buffered strings */
|
||||
public synchronized void insertAll() {
|
||||
ElementSpec[] elementArray = new ElementSpec[elements.size()];
|
||||
elements.toArray(elementArray);
|
||||
|
||||
try {
|
||||
// check how many lines have been used so far
|
||||
// if too many, shave off a few lines from the beginning
|
||||
Element element = super.getDefaultRootElement();
|
||||
int lineCount = element.getElementCount();
|
||||
int overage = lineCount - maxLineCount;
|
||||
if (overage > 0) {
|
||||
// if 1200 lines, and 1000 lines is max,
|
||||
// find the position of the end of the 200th line
|
||||
//systemOut.println("overage is " + overage);
|
||||
Element lineElement = element.getElement(overage);
|
||||
if (lineElement == null) return; // do nuthin
|
||||
|
||||
int endOffset = lineElement.getEndOffset();
|
||||
// remove to the end of the 200th line
|
||||
super.remove(0, endOffset);
|
||||
}
|
||||
super.insert(super.getLength(), elementArray);
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// ignore the error otherwise this will cause an infinite loop
|
||||
// maybe not a good idea in the long run?
|
||||
}
|
||||
elements.clear();
|
||||
hasAppendage = false;
|
||||
}
|
||||
}
|
||||
|
@ -339,8 +339,10 @@ public class EditorHeader extends JComponent {
|
||||
Sketch sketch = editor.sketch;
|
||||
if (sketch != null) {
|
||||
for (int i = 0; i < sketch.hiddenCount; i++) {
|
||||
item = new JMenuItem(sketch.hidden[i].name);
|
||||
item.setActionCommand(sketch.hidden[i].name);
|
||||
item = new JMenuItem(sketch.hidden[i].name +
|
||||
Sketch.flavorExtensionsShown[sketch.hidden[i].flavor]);
|
||||
item.setActionCommand(sketch.hidden[i].name +
|
||||
Sketch.flavorExtensionsShown[sketch.hidden[i].flavor]);
|
||||
item.addActionListener(unhideListener);
|
||||
unhide.add(item);
|
||||
}
|
||||
@ -360,7 +362,8 @@ public class EditorHeader extends JComponent {
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < sketch.codeCount; i++) {
|
||||
item = new JMenuItem(sketch.code[i].name);
|
||||
item = new JMenuItem(sketch.code[i].name +
|
||||
Sketch.flavorExtensionsShown[sketch.code[i].flavor]);
|
||||
item.addActionListener(jumpListener);
|
||||
menu.add(item);
|
||||
}
|
||||
|
@ -35,13 +35,25 @@ import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
* Filters key events for tab expansion/indent/etc.
|
||||
* <p/>
|
||||
* For version 0099, some changes have been made to make the indents
|
||||
* smarter. There are still issues though:
|
||||
* + indent happens when it picks up a curly brace on the previous line,
|
||||
* but not if there's a blank line between them.
|
||||
* + It also doesn't handle single indent situations where a brace
|
||||
* isn't used (i.e. an if statement or for loop that's a single line).
|
||||
* It shouldn't actually be using braces.
|
||||
* Solving these issues, however, would probably best be done by a
|
||||
* smarter parser/formatter, rather than continuing to hack this class.
|
||||
*/
|
||||
public class EditorListener {
|
||||
Editor editor;
|
||||
JEditTextArea textarea;
|
||||
|
||||
boolean externalEditor;
|
||||
boolean expandTabs;
|
||||
boolean tabsExpand;
|
||||
boolean tabsIndent;
|
||||
int tabSize;
|
||||
String tabString;
|
||||
boolean autoIndent;
|
||||
|
||||
@ -61,8 +73,9 @@ public class EditorListener {
|
||||
|
||||
|
||||
public void applyPreferences() {
|
||||
expandTabs = Preferences.getBoolean("editor.tabs.expand");
|
||||
int tabSize = Preferences.getInteger("editor.tabs.size");
|
||||
tabsExpand = Preferences.getBoolean("editor.tabs.expand");
|
||||
//tabsIndent = Preferences.getBoolean("editor.tabs.indent");
|
||||
tabSize = Preferences.getInteger("editor.tabs.size");
|
||||
tabString = Editor.EMPTY.substring(0, tabSize);
|
||||
autoIndent = Preferences.getBoolean("editor.indent");
|
||||
externalEditor = Preferences.getBoolean("editor.external");
|
||||
@ -74,7 +87,13 @@ public class EditorListener {
|
||||
//}
|
||||
|
||||
|
||||
// called by JEditTextArea inside processKeyEvent
|
||||
/**
|
||||
* Intercepts key pressed events for JEditTextArea.
|
||||
* <p/>
|
||||
* Called by JEditTextArea inside processKeyEvent(). Note that this
|
||||
* won't intercept actual characters, because those are fired on
|
||||
* keyTyped().
|
||||
*/
|
||||
public boolean keyPressed(KeyEvent event) {
|
||||
// don't do things if the textarea isn't editable
|
||||
if (externalEditor) return false;
|
||||
@ -92,21 +111,148 @@ public class EditorListener {
|
||||
}
|
||||
|
||||
// TODO i don't like these accessors. clean em up later.
|
||||
if (!editor.sketch.current.modified) {
|
||||
if (!editor.sketch.modified) {
|
||||
if ((code == KeyEvent.VK_BACK_SPACE) || (code == KeyEvent.VK_TAB) ||
|
||||
(code == KeyEvent.VK_ENTER) || ((c >= 32) && (c < 128))) {
|
||||
editor.sketch.setModified();
|
||||
editor.sketch.setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
if ((code == KeyEvent.VK_UP) &&
|
||||
((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
||||
// back up to the last empty line
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
//int origIndex = textarea.getCaretPosition() - 1;
|
||||
int caretIndex = textarea.getCaretPosition();
|
||||
|
||||
int index = calcLineStart(caretIndex - 1, contents);
|
||||
//System.out.println("line start " + (int) contents[index]);
|
||||
index -= 2; // step over the newline
|
||||
//System.out.println((int) contents[index]);
|
||||
boolean onlySpaces = true;
|
||||
while (index > 0) {
|
||||
if (contents[index] == 10) {
|
||||
if (onlySpaces) {
|
||||
index++;
|
||||
break;
|
||||
} else {
|
||||
onlySpaces = true; // reset
|
||||
}
|
||||
} else if (contents[index] != ' ') {
|
||||
onlySpaces = false;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
// if the first char, index will be -2
|
||||
if (index < 0) index = 0;
|
||||
|
||||
if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
|
||||
textarea.setSelectionStart(caretIndex);
|
||||
textarea.setSelectionEnd(index);
|
||||
} else {
|
||||
textarea.setCaretPosition(index);
|
||||
}
|
||||
event.consume();
|
||||
return true;
|
||||
|
||||
} else if ((code == KeyEvent.VK_DOWN) &&
|
||||
((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
int caretIndex = textarea.getCaretPosition();
|
||||
|
||||
int index = caretIndex;
|
||||
int lineStart = 0;
|
||||
boolean onlySpaces = false; // don't count this line
|
||||
while (index < contents.length) {
|
||||
if (contents[index] == 10) {
|
||||
if (onlySpaces) {
|
||||
index = lineStart; // this is it
|
||||
break;
|
||||
} else {
|
||||
lineStart = index + 1;
|
||||
onlySpaces = true; // reset
|
||||
}
|
||||
} else if (contents[index] != ' ') {
|
||||
onlySpaces = false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
// if the first char, index will be -2
|
||||
//if (index < 0) index = 0;
|
||||
|
||||
//textarea.setSelectionStart(index);
|
||||
//textarea.setSelectionEnd(index);
|
||||
if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
|
||||
textarea.setSelectionStart(caretIndex);
|
||||
textarea.setSelectionEnd(index);
|
||||
} else {
|
||||
textarea.setCaretPosition(index);
|
||||
}
|
||||
event.consume();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
switch ((int) c) {
|
||||
|
||||
case 9: // expand tabs
|
||||
if (expandTabs) {
|
||||
//tc.replaceSelection(tabString);
|
||||
if (tabsExpand) {
|
||||
textarea.setSelectedText(tabString);
|
||||
event.consume();
|
||||
return true;
|
||||
|
||||
} else if (tabsIndent) {
|
||||
// this code is incomplete
|
||||
|
||||
// if this brace is the only thing on the line, outdent
|
||||
//char contents[] = getCleanedContents();
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
// index to the character to the left of the caret
|
||||
int prevCharIndex = textarea.getCaretPosition() - 1;
|
||||
|
||||
// now find the start of this line
|
||||
int lineStart = calcLineStart(prevCharIndex, contents);
|
||||
|
||||
int lineEnd = lineStart;
|
||||
while ((lineEnd < contents.length - 1) &&
|
||||
(contents[lineEnd] != 10)) {
|
||||
lineEnd++;
|
||||
}
|
||||
|
||||
// get the number of braces, to determine whether this is an indent
|
||||
int braceBalance = 0;
|
||||
int index = lineStart;
|
||||
while ((index < contents.length) &&
|
||||
(contents[index] != 10)) {
|
||||
if (contents[index] == '{') {
|
||||
braceBalance++;
|
||||
} else if (contents[index] == '}') {
|
||||
braceBalance--;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
// if it's a starting indent, need to ignore it, so lineStart
|
||||
// will be the counting point. but if there's a closing indent,
|
||||
// then the lineEnd should be used.
|
||||
int where = (braceBalance > 0) ? lineStart : lineEnd;
|
||||
int indent = calcBraceIndent(where, contents);
|
||||
if (indent == -1) {
|
||||
// no braces to speak of, do nothing
|
||||
indent = 0;
|
||||
} else {
|
||||
indent += tabSize;
|
||||
}
|
||||
|
||||
// and the number of spaces it has
|
||||
int spaceCount = calcSpaceCount(prevCharIndex, contents);
|
||||
|
||||
textarea.setSelectionStart(lineStart);
|
||||
textarea.setSelectionEnd(lineStart + spaceCount);
|
||||
textarea.setSelectedText(Editor.EMPTY.substring(0, indent));
|
||||
|
||||
event.consume();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -115,13 +261,18 @@ public class EditorListener {
|
||||
if (autoIndent) {
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
|
||||
// this is the position of the caret, if the textarea
|
||||
// only used a single kind of line ending
|
||||
// this is the previous character
|
||||
// (i.e. when you hit return, it'll be the last character
|
||||
// just before where the newline will be inserted)
|
||||
int origIndex = textarea.getCaretPosition() - 1;
|
||||
|
||||
// NOTE all this cursing about CRLF stuff is probably moot
|
||||
// NOTE since the switch to JEditTextArea, which seems to use
|
||||
// NOTE only LFs internally (thank god). disabling for 0099.
|
||||
// walk through the array to the current caret position,
|
||||
// and count how many weirdo windows line endings there are,
|
||||
// which would be throwing off the caret position number
|
||||
/*
|
||||
int offset = 0;
|
||||
int realIndex = origIndex;
|
||||
for (int i = 0; i < realIndex-1; i++) {
|
||||
@ -130,38 +281,140 @@ public class EditorListener {
|
||||
realIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// back up until \r \r\n or \n.. @#($* cross platform
|
||||
|
||||
//System.out.println(origIndex + " offset = " + offset);
|
||||
origIndex += offset; // ARGH!#(* WINDOWS#@($*
|
||||
*/
|
||||
|
||||
int index = origIndex;
|
||||
int spaceCount = 0;
|
||||
int spaceCount = calcSpaceCount(origIndex, contents);
|
||||
//int origCount = spaceCount;
|
||||
|
||||
// now before inserting this many spaces, walk forward from
|
||||
// the caret position, so that the number of spaces aren't
|
||||
// just being duplicated again
|
||||
int index = origIndex + 1;
|
||||
int extraCount = 0;
|
||||
while ((index < contents.length) &&
|
||||
(contents[index] == ' ')) {
|
||||
//spaceCount--;
|
||||
extraCount++;
|
||||
index++;
|
||||
}
|
||||
|
||||
// hitting return on a line with spaces *after* the caret
|
||||
// can cause trouble. for simplicity's sake, just ignore this case.
|
||||
//if (spaceCount < 0) spaceCount = origCount;
|
||||
if (spaceCount - extraCount > 0) {
|
||||
spaceCount -= extraCount;
|
||||
}
|
||||
|
||||
// if the last character was a left curly brace, then indent
|
||||
if (origIndex != -1) {
|
||||
if (contents[origIndex] == '{') {
|
||||
spaceCount += tabSize;
|
||||
}
|
||||
}
|
||||
|
||||
String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount);
|
||||
textarea.setSelectedText(insertion);
|
||||
|
||||
// mark this event as already handled
|
||||
event.consume();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if (autoIndent) {
|
||||
// first remove anything that was there (in case this multiple
|
||||
// characters are selected, so that it's not in the way of the
|
||||
// spaces for the auto-indent
|
||||
if (textarea.getSelectionStart() != textarea.getSelectionEnd()) {
|
||||
textarea.setSelectedText("");
|
||||
}
|
||||
|
||||
// if this brace is the only thing on the line, outdent
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
// index to the character to the left of the caret
|
||||
int prevCharIndex = textarea.getCaretPosition() - 1;
|
||||
|
||||
// backup from the current caret position to the last newline,
|
||||
// checking for anything besides whitespace along the way.
|
||||
// if there's something besides whitespace, exit without
|
||||
// messing any sort of indenting.
|
||||
int index = prevCharIndex;
|
||||
boolean finished = false;
|
||||
while ((index != -1) && (!finished)) {
|
||||
if ((contents[index] == 10) ||
|
||||
(contents[index] == 13)) {
|
||||
if (contents[index] == 10) {
|
||||
finished = true;
|
||||
index++; // maybe ?
|
||||
index++;
|
||||
} else if (contents[index] != ' ') {
|
||||
// don't do anything, this line has other stuff on it
|
||||
return false;
|
||||
} else {
|
||||
index--; // new
|
||||
index--;
|
||||
}
|
||||
}
|
||||
if (!finished) return false; // brace with no start
|
||||
int lineStartIndex = index;
|
||||
|
||||
/*
|
||||
// now that we know things are ok to be indented, walk
|
||||
// backwards to the last { to see how far its line is indented.
|
||||
// this isn't perfect cuz it'll pick up commented areas,
|
||||
// but that's not really a big deal and can be fixed when
|
||||
// this is all given a more complete (proper) solution.
|
||||
index = prevCharIndex;
|
||||
int braceDepth = 1;
|
||||
finished = false;
|
||||
while ((index != -1) && (!finished)) {
|
||||
if (contents[index] == '}') {
|
||||
// aww crap, this means we're one deeper
|
||||
// and will have to find one more extra {
|
||||
braceDepth++;
|
||||
index--;
|
||||
} else if (contents[index] == '{') {
|
||||
braceDepth--;
|
||||
if (braceDepth == 0) {
|
||||
finished = true;
|
||||
} // otherwise just teasing, keep going..
|
||||
} else {
|
||||
index--;
|
||||
}
|
||||
}
|
||||
// never found a proper brace, be safe and don't do anything
|
||||
if (!finished) return false;
|
||||
|
||||
// check how many spaces on the line with the matching open brace
|
||||
int pairedSpaceCount = calcSpaceCount(index, contents);
|
||||
//System.out.println(pairedSpaceCount);
|
||||
*/
|
||||
int pairedSpaceCount = calcBraceIndent(prevCharIndex, contents); //, 1);
|
||||
if (pairedSpaceCount == -1) return false;
|
||||
|
||||
/*
|
||||
// now walk forward and figure out how many spaces there are
|
||||
while ((index < contents.length) && (index >= 0) &&
|
||||
(contents[index++] == ' ')) {
|
||||
spaceCount++;
|
||||
}
|
||||
*/
|
||||
|
||||
// seems that \r is being inserted anyway
|
||||
// so no need to insert the platform's line separator
|
||||
String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount);
|
||||
//tc.replaceSelection(insertion);
|
||||
textarea.setSelectedText(insertion);
|
||||
// microsoft vm version:
|
||||
//tc.setCaretPosition(oldCarrot + insertion.length() - 1);
|
||||
// sun vm version:
|
||||
// tc.setCaretPosition(oldCarrot + insertion.length());
|
||||
// number of spaces found on this line
|
||||
//int newSpaceCount = Math.max(0, spaceCount - tabSize);
|
||||
// number of spaces on this current line
|
||||
//int spaceCount = calcSpaces(caretIndex, contents);
|
||||
//System.out.println("spaces is " + spaceCount);
|
||||
//String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount);
|
||||
//int differential = newSpaceCount - spaceCount;
|
||||
//System.out.println("diff is " + differential);
|
||||
//int newStart = textarea.getSelectionStart() + differential;
|
||||
//textarea.setSelectionStart(newStart);
|
||||
//textarea.setSelectedText("}");
|
||||
textarea.setSelectionStart(lineStartIndex);
|
||||
textarea.setSelectedText(Editor.EMPTY.substring(0, pairedSpaceCount));
|
||||
|
||||
// mark this event as already handled
|
||||
event.consume();
|
||||
return true;
|
||||
}
|
||||
@ -169,4 +422,143 @@ public class EditorListener {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the index for the first character on this line.
|
||||
*/
|
||||
protected int calcLineStart(int index, char contents[]) {
|
||||
// backup from the current caret position to the last newline,
|
||||
// so that we can figure out how far this line was indented
|
||||
int spaceCount = 0;
|
||||
boolean finished = false;
|
||||
while ((index != -1) && (!finished)) {
|
||||
if ((contents[index] == 10) ||
|
||||
(contents[index] == 13)) {
|
||||
finished = true;
|
||||
//index++; // maybe ?
|
||||
} else {
|
||||
index--; // new
|
||||
}
|
||||
}
|
||||
// add one because index is either -1 (the start of the document)
|
||||
// or it's the newline character for the previous line
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the number of spaces on this line.
|
||||
*/
|
||||
protected int calcSpaceCount(int index, char contents[]) {
|
||||
index = calcLineStart(index, contents);
|
||||
|
||||
int spaceCount = 0;
|
||||
// now walk forward and figure out how many spaces there are
|
||||
while ((index < contents.length) && (index >= 0) &&
|
||||
(contents[index++] == ' ')) {
|
||||
spaceCount++;
|
||||
}
|
||||
return spaceCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Walk back from 'index' until the brace that seems to be
|
||||
* the beginning of the current block, and return the number of
|
||||
* spaces found on that line.
|
||||
*/
|
||||
protected int calcBraceIndent(int index, char contents[]) {
|
||||
// now that we know things are ok to be indented, walk
|
||||
// backwards to the last { to see how far its line is indented.
|
||||
// this isn't perfect cuz it'll pick up commented areas,
|
||||
// but that's not really a big deal and can be fixed when
|
||||
// this is all given a more complete (proper) solution.
|
||||
int braceDepth = 1;
|
||||
boolean finished = false;
|
||||
while ((index != -1) && (!finished)) {
|
||||
if (contents[index] == '}') {
|
||||
// aww crap, this means we're one deeper
|
||||
// and will have to find one more extra {
|
||||
braceDepth++;
|
||||
//if (braceDepth == 0) {
|
||||
//finished = true;
|
||||
//}
|
||||
index--;
|
||||
} else if (contents[index] == '{') {
|
||||
braceDepth--;
|
||||
if (braceDepth == 0) {
|
||||
finished = true;
|
||||
}
|
||||
index--;
|
||||
} else {
|
||||
index--;
|
||||
}
|
||||
}
|
||||
// never found a proper brace, be safe and don't do anything
|
||||
if (!finished) return -1;
|
||||
|
||||
// check how many spaces on the line with the matching open brace
|
||||
//int pairedSpaceCount = calcSpaceCount(index, contents);
|
||||
//System.out.println(pairedSpaceCount);
|
||||
return calcSpaceCount(index, contents);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the character array and blank out the commented areas.
|
||||
* This hasn't yet been tested, the plan was to make auto-indent
|
||||
* less gullible (it gets fooled by braces that are commented out).
|
||||
*/
|
||||
protected char[] getCleanedContents() {
|
||||
char c[] = textarea.getText().toCharArray();
|
||||
|
||||
int index = 0;
|
||||
while (index < c.length - 1) {
|
||||
if ((c[index] == '/') && (c[index+1] == '*')) {
|
||||
c[index++] = 0;
|
||||
c[index++] = 0;
|
||||
while ((index < c.length - 1) &&
|
||||
!((c[index] == '*') && (c[index+1] == '/'))) {
|
||||
c[index++] = 0;
|
||||
}
|
||||
|
||||
} else if ((c[index] == '/') && (c[index+1] == '/')) {
|
||||
// clear out until the end of the line
|
||||
while ((index < c.length) && (c[index] != 10)) {
|
||||
c[index++] = 0;
|
||||
}
|
||||
if (index != c.length) {
|
||||
index++; // skip over the newline
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
protected char[] getCleanedContents() {
|
||||
char c[] = textarea.getText().toCharArray();
|
||||
boolean insideMulti; // multi-line comment
|
||||
boolean insideSingle; // single line double slash
|
||||
|
||||
//for (int i = 0; i < c.length - 1; i++) {
|
||||
int index = 0;
|
||||
while (index < c.length - 1) {
|
||||
if (insideMulti && (c[index] == '*') && (c[index+1] == '/')) {
|
||||
insideMulti = false;
|
||||
index += 2;
|
||||
} else if ((c[index] == '/') && (c[index+1] == '*')) {
|
||||
insideMulti = true;
|
||||
index += 2;
|
||||
} else if ((c[index] == '/') && (c[index+1] == '/')) {
|
||||
// clear out until the end of the line
|
||||
while (c[index] != 10) {
|
||||
c[index++] = 0;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ public class EditorStatus extends JPanel implements ActionListener {
|
||||
} else if (e.getSource() == yesButton) {
|
||||
// answer was in response to "save changes?"
|
||||
unprompt();
|
||||
editor.handleSave();
|
||||
editor.handleSave(true);
|
||||
editor.checkModified2();
|
||||
|
||||
} else if (e.getSource() == cancelButton) {
|
||||
|
@ -29,10 +29,21 @@ import javax.swing.*;
|
||||
|
||||
|
||||
/**
|
||||
* Find & Replace window for the processing editor.
|
||||
* Find & Replace window for the Processing editor.
|
||||
* <p/>
|
||||
* One major annoyance in this is that the window is re-created each time
|
||||
* that "Find" is called. This is because Mac OS X has a strange focus
|
||||
* issue with windows that are re-shown with setVisible() or show().
|
||||
* requestFocusInWindow() properly sets the focus to the find field,
|
||||
* however, just a short moment later, the focus is set to null. Even
|
||||
* trying to catch this scenario and request it again doesn't seem to work.
|
||||
* Most likely this is some annoyance buried deep in one of Apple's docs,
|
||||
* or in the doc for the focus stuff (I tend to think the former because
|
||||
* Windows doesn't seem to be quite so beligerent). Filed as
|
||||
* <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=244"> Bug 244</A>
|
||||
* should anyone have clues about how to fix.
|
||||
*/
|
||||
public class FindReplace extends JFrame
|
||||
implements ActionListener, KeyListener {
|
||||
public class FindReplace extends JFrame implements ActionListener {
|
||||
|
||||
static final int BIG = 13;
|
||||
static final int SMALL = 6;
|
||||
@ -41,16 +52,17 @@ public class FindReplace extends JFrame
|
||||
|
||||
JTextField findField;
|
||||
JTextField replaceField;
|
||||
static String findString;
|
||||
static String replaceString;
|
||||
|
||||
JButton replaceButton;
|
||||
JButton replaceAllButton;
|
||||
JButton findButton;
|
||||
|
||||
JCheckBox ignoreCaseBox;
|
||||
boolean ignoreCase;
|
||||
|
||||
KeyStroke windowClose;
|
||||
static boolean ignoreCase = true;
|
||||
|
||||
/// true when there's something selected in the editor
|
||||
boolean found;
|
||||
|
||||
|
||||
@ -74,6 +86,27 @@ public class FindReplace extends JFrame
|
||||
pain.add(replaceField = new JTextField(20));
|
||||
Dimension d2 = findField.getPreferredSize();
|
||||
|
||||
if (findString != null) findField.setText(findString);
|
||||
if (replaceString != null) replaceField.setText(replaceString);
|
||||
//System.out.println("setting find str to " + findString);
|
||||
//findField.requestFocusInWindow();
|
||||
|
||||
//pain.setDefault
|
||||
/*
|
||||
findField.addFocusListener(new FocusListener() {
|
||||
public void focusGained(FocusEvent e) {
|
||||
System.out.println("Focus gained " + e.getOppositeComponent());
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
System.out.println("Focus lost "); // + e.getOppositeComponent());
|
||||
if (e.getOppositeComponent() == null) {
|
||||
requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
// +1 since it's better to tend downwards
|
||||
int yoff = (1 + d2.height - d1.height) / 2;
|
||||
|
||||
@ -82,7 +115,7 @@ public class FindReplace extends JFrame
|
||||
replaceLabel.setBounds(BIG, BIG + d2.height + SMALL + yoff,
|
||||
d1.width, d1.height);
|
||||
|
||||
ignoreCase = true;
|
||||
//ignoreCase = true;
|
||||
ignoreCaseBox = new JCheckBox("Ignore Case");
|
||||
ignoreCaseBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -110,12 +143,8 @@ public class FindReplace extends JFrame
|
||||
}
|
||||
pain.add(buttons);
|
||||
|
||||
// 0069 TEMPORARILY DISABLED!
|
||||
//replaceAllButton.setEnabled(false);
|
||||
|
||||
// to fix ugliness.. normally macosx java 1.3 puts an
|
||||
// ugly white border around this object, so turn it off.
|
||||
//if (Base.platform == Base.MACOSX) {
|
||||
if (Base.isMacOS()) {
|
||||
buttons.setBorder(null);
|
||||
}
|
||||
@ -146,7 +175,7 @@ public class FindReplace extends JFrame
|
||||
replaceButton.setEnabled(false);
|
||||
|
||||
// so that typing will go straight to this field
|
||||
findField.requestFocus();
|
||||
//findField.requestFocus();
|
||||
|
||||
// make the find button the blinky default
|
||||
getRootPane().setDefaultButton(findButton);
|
||||
@ -161,48 +190,62 @@ public class FindReplace extends JFrame
|
||||
(screen.height - high) / 2, wide, high);
|
||||
|
||||
// add key listener to trap esc and ctrl/cmd-w
|
||||
findField.addKeyListener(this);
|
||||
replaceField.addKeyListener(this);
|
||||
addKeyListener(this);
|
||||
/*
|
||||
KeyListener listener = new KeyAdapter() {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (Base.isCloseWindowEvent(e)) hide();
|
||||
}
|
||||
};
|
||||
findField.addKeyListener(listener);
|
||||
replaceField.addKeyListener(listener);
|
||||
addKeyListener(listener);
|
||||
*/
|
||||
ActionListener disposer = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
//hide();
|
||||
handleClose();
|
||||
}
|
||||
};
|
||||
|
||||
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
handleClose();
|
||||
}
|
||||
});
|
||||
Base.registerWindowCloseKeys(getRootPane(), disposer);
|
||||
|
||||
/*
|
||||
// hack to to get first field to focus properly on osx
|
||||
// though this still doesn't seem to work
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowActivated(WindowEvent e) {
|
||||
//System.out.println("activating");
|
||||
findField.requestFocus();
|
||||
findField.selectAll();
|
||||
//boolean ok = findField.requestFocusInWindow();
|
||||
//System.out.println("got " + ok);
|
||||
//findField.selectAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle window closing commands for ctrl/cmd-W or hitting ESC.
|
||||
*/
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (windowClose == null) {
|
||||
int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
||||
windowClose = KeyStroke.getKeyStroke('W', modifiers);
|
||||
}
|
||||
if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) ||
|
||||
(KeyStroke.getKeyStrokeForEvent(e).equals(windowClose))) {
|
||||
|
||||
|
||||
public void handleClose() {
|
||||
//System.out.println("handling close now");
|
||||
findString = findField.getText();
|
||||
replaceString = replaceField.getText();
|
||||
|
||||
// this object should eventually become dereferenced
|
||||
hide();
|
||||
//} else {
|
||||
//System.out.println("event " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e) { }
|
||||
|
||||
public void keyTyped(KeyEvent e) { }
|
||||
|
||||
|
||||
/*
|
||||
public void show() {
|
||||
findField.requestFocusInWindow();
|
||||
super.show();
|
||||
findField.selectAll();
|
||||
findField.requestFocus();
|
||||
//findField.selectAll();
|
||||
//findField.requestFocus();
|
||||
}
|
||||
*/
|
||||
|
||||
@ -266,9 +309,10 @@ public class FindReplace extends JFrame
|
||||
}
|
||||
|
||||
|
||||
// replace the current selection with whatever's in the
|
||||
// replacement text field
|
||||
|
||||
/**
|
||||
* Replace the current selection with whatever's in the
|
||||
* replacement text field.
|
||||
*/
|
||||
public void replace() {
|
||||
if (!found) return; // don't replace if nothing found
|
||||
|
||||
@ -284,15 +328,17 @@ public class FindReplace extends JFrame
|
||||
editor.textarea.setSelectedText(replaceField.getText());
|
||||
//editor.setSketchModified(true);
|
||||
//editor.sketch.setCurrentModified(true);
|
||||
editor.sketch.setModified();
|
||||
editor.sketch.setModified(true);
|
||||
|
||||
// don't allow a double replace
|
||||
replaceButton.setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
// keep doing find and replace alternately until nothing more found
|
||||
|
||||
/**
|
||||
* Replace everything that matches by doing find and replace
|
||||
* alternately until nothing more found.
|
||||
*/
|
||||
public void replaceAll() {
|
||||
// move to the beginning
|
||||
editor.textarea.select(0, 0);
|
||||
|
444
app/Library.java
Executable file
444
app/Library.java
Executable file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
Library.java - Library System for Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/*
|
||||
* Provides information about and builds a library
|
||||
*/
|
||||
public class Library implements MessageConsumer{
|
||||
|
||||
private File libFolder;
|
||||
private LibraryManager libManager;
|
||||
RunnerException exception;
|
||||
|
||||
static final String BUGS_URL = "https://developer.berlios.de/bugs/?group_id=3590";
|
||||
static final String SUPER_BADNESS = "Compiler error, please submit this code to " + BUGS_URL;
|
||||
|
||||
/*
|
||||
* Create a Library
|
||||
*/
|
||||
public Library(LibraryManager manager, File folder)
|
||||
{
|
||||
libFolder = folder;
|
||||
libManager = manager;
|
||||
|
||||
/* for debug output
|
||||
System.out.println("library: " + getName());
|
||||
System.out.println("folder: " + getFolder());
|
||||
System.out.println("built: " + isBuilt());
|
||||
System.out.println("buildable: " + isBuildable());
|
||||
System.out.println("o files: " + getObjectFiles().length);
|
||||
System.out.println("c files: " + getCSourceFiles().length);
|
||||
System.out.println("cpp files: " + getCPPSourceFiles().length);
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory of library
|
||||
* @return File object of library's folder
|
||||
*/
|
||||
public File getFolder()
|
||||
{
|
||||
return libFolder;
|
||||
}
|
||||
|
||||
/*
|
||||
* The name of library
|
||||
* @return String with library name, derived from folder
|
||||
* note: this will be eventually taken from xml description file
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return libFolder.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests if library is built
|
||||
* @return True if library has .o files, false otherwise
|
||||
*/
|
||||
public boolean isBuilt()
|
||||
{
|
||||
FileFilter onlyObjectFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return file.getName().endsWith(".o");
|
||||
}
|
||||
};
|
||||
if(0 < (libFolder.listFiles(onlyObjectFiles)).length){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests if library is buildable
|
||||
* @return True if library has .cpp files, false otherwise
|
||||
*/
|
||||
public boolean isBuildable()
|
||||
{
|
||||
FileFilter onlySourceFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".cpp");
|
||||
}
|
||||
};
|
||||
if(0 < (libFolder.listFiles(onlySourceFiles)).length){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests if library is unbuilt but buildable
|
||||
* @return True if library has .cpp files but no .o files, false otherwise
|
||||
*/
|
||||
public boolean isUnbuiltBuildable()
|
||||
{
|
||||
if(isBuildable()){
|
||||
if(!isBuilt()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds examples folder
|
||||
* @return "examples" folder as file object or null
|
||||
*/
|
||||
private File getExamplesFolder()
|
||||
{
|
||||
FileFilter filter = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
if(file.isDirectory()){
|
||||
if((file.getName()).equalsIgnoreCase("examples")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
File[] files = libFolder.listFiles(filter);
|
||||
if(files.length > 0){
|
||||
return files[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates example menu or submenu with files
|
||||
*/
|
||||
private void populateWithExamples(File folder, JMenu menu, ActionListener listener) {
|
||||
FileFilter onlyfolders = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory();
|
||||
}
|
||||
};
|
||||
File[] folders = folder.listFiles(onlyfolders);
|
||||
File file;
|
||||
JMenu submenu;
|
||||
JMenuItem item;
|
||||
for(int i = 0; i < folders.length; ++i){
|
||||
file = new File(folders[i], folders[i].getName() + ".pde");
|
||||
if(file.exists()){
|
||||
item = new JMenuItem(folders[i].getName());
|
||||
item.setActionCommand(file.getAbsolutePath());
|
||||
item.addActionListener(listener);
|
||||
menu.add(item);
|
||||
}else{
|
||||
submenu = new JMenu(folders[i].getName());
|
||||
populateWithExamples(folders[i], submenu, listener);
|
||||
menu.add(submenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds and returns an examples menu
|
||||
* @return JMenu object with example files, or null if none
|
||||
*/
|
||||
public JMenu getExamplesMenu(ActionListener listener) {
|
||||
JMenu submenu;
|
||||
File examplesFolder = getExamplesFolder();
|
||||
if(null != examplesFolder){
|
||||
submenu = new JMenu("Library-" + getName());
|
||||
populateWithExamples(examplesFolder, submenu, listener);
|
||||
return submenu;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of object files for linking
|
||||
* @return Array of library's object files as File objects
|
||||
*/
|
||||
public File[] getObjectFiles()
|
||||
{
|
||||
FileFilter onlyObjectFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".o");
|
||||
}
|
||||
};
|
||||
return libFolder.listFiles(onlyObjectFiles);
|
||||
}
|
||||
|
||||
/*
|
||||
* List of header source files for inclusion
|
||||
* @return Array of library's header source files as File objects
|
||||
*/
|
||||
public File[] getHeaderFiles()
|
||||
{
|
||||
FileFilter onlyHFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".h");
|
||||
}
|
||||
};
|
||||
return libFolder.listFiles(onlyHFiles);
|
||||
}
|
||||
|
||||
/*
|
||||
* List of C source files for compiling
|
||||
* @return Array of library's C source files as File objects
|
||||
*/
|
||||
private File[] getCSourceFiles()
|
||||
{
|
||||
FileFilter onlyCFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".c");
|
||||
}
|
||||
};
|
||||
return libFolder.listFiles(onlyCFiles);
|
||||
}
|
||||
|
||||
/*
|
||||
* List of C++ source files for compiling
|
||||
* @return Array of library's C++ source files as File objects
|
||||
*/
|
||||
private File[] getCPPSourceFiles()
|
||||
{
|
||||
FileFilter onlyCPPFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".cpp");
|
||||
}
|
||||
};
|
||||
return libFolder.listFiles(onlyCPPFiles);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to build library
|
||||
* @return true on successful build, false otherwise
|
||||
*/
|
||||
public boolean build() throws RunnerException
|
||||
{
|
||||
if(isBuildable()){
|
||||
String userDir = System.getProperty("user.dir") + File.separator;
|
||||
|
||||
String[] baseCompileCommandC = new String[] {
|
||||
((!Base.isMacOS()) ? "tools/avr/bin/avr-gcc" : userDir + "tools/avr/bin/avr-gcc"),
|
||||
"-c",
|
||||
"-g",
|
||||
"-Os",
|
||||
"-Wall",
|
||||
"-mmcu=" + Preferences.get("build.mcu"),
|
||||
"-DF_CPU=" + Preferences.get("build.f_cpu"),
|
||||
"-Ilib",
|
||||
"-I" + getFolder(),
|
||||
};
|
||||
|
||||
String[] baseCompileCommandCPP = new String[] {
|
||||
((!Base.isMacOS()) ? "tools/avr/bin/avr-g++" : userDir + "tools/avr/bin/avr-g++"),
|
||||
"-c",
|
||||
"-g",
|
||||
"-Os",
|
||||
"-Wall",
|
||||
"-fno-exceptions",
|
||||
"-mmcu=" + Preferences.get("build.mcu"),
|
||||
"-DF_CPU=" + Preferences.get("build.f_cpu"),
|
||||
"-Ilib",
|
||||
"-I" + getFolder(),
|
||||
};
|
||||
|
||||
// use built lib directories in include paths when searching for headers
|
||||
// this allows libs to use other libs easily
|
||||
String[] libDirs = libManager.getFolderPaths();
|
||||
String[] compileCommandC = new String[baseCompileCommandC.length + libDirs.length + 2];
|
||||
String[] compileCommandCPP = new String[baseCompileCommandCPP.length + libDirs.length + 2];
|
||||
System.arraycopy(baseCompileCommandC, 0, compileCommandC, 0, baseCompileCommandC.length);
|
||||
System.arraycopy(baseCompileCommandCPP, 0, compileCommandCPP, 0, baseCompileCommandCPP.length);
|
||||
for (int i = 0; i < libDirs.length; ++i) {
|
||||
compileCommandC[baseCompileCommandC.length + i] = "-I" + libDirs[i];
|
||||
compileCommandCPP[baseCompileCommandCPP.length + i] = "-I" + libDirs[i];
|
||||
}
|
||||
|
||||
File[] sourcesC = getCSourceFiles();
|
||||
File[] sourcesCPP = getCPPSourceFiles();
|
||||
|
||||
// execute the compiler, and create threads to deal
|
||||
// with the input and error streams
|
||||
//
|
||||
int result = 0;
|
||||
try {
|
||||
String nameSansExtension;
|
||||
Process process;
|
||||
boolean compiling = true;
|
||||
|
||||
// compile c sources
|
||||
for(int i = 0; i < sourcesC.length; ++i) {
|
||||
nameSansExtension = sourcesC[i].getName();
|
||||
nameSansExtension = nameSansExtension.substring(0, nameSansExtension.length() - 2); // -2 because ".c"
|
||||
|
||||
compileCommandC[compileCommandC.length - 2] = sourcesC[i].getPath();
|
||||
compileCommandC[compileCommandC.length - 1] = "-o" + getFolder() + File.separator + nameSansExtension + ".o";
|
||||
|
||||
process = Runtime.getRuntime().exec(compileCommandC);
|
||||
new MessageSiphon(process.getInputStream(), this);
|
||||
new MessageSiphon(process.getErrorStream(), this);
|
||||
|
||||
// wait for the process to finish. if interrupted
|
||||
// before waitFor returns, continue waiting
|
||||
//
|
||||
compiling = true;
|
||||
while (compiling) {
|
||||
try {
|
||||
result = process.waitFor();
|
||||
//System.out.println("result is " + result);
|
||||
compiling = false;
|
||||
} catch (InterruptedException ignored) { }
|
||||
}
|
||||
if (exception != null) {
|
||||
exception.hideStackTrace = true;
|
||||
throw exception;
|
||||
}
|
||||
if(result != 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// compile c++ sources
|
||||
for(int i = 0; i < sourcesCPP.length; ++i) {
|
||||
nameSansExtension = sourcesCPP[i].getName();
|
||||
nameSansExtension = nameSansExtension.substring(0, nameSansExtension.length() - 4); // -4 because ".cpp"
|
||||
|
||||
compileCommandCPP[compileCommandCPP.length - 2] = sourcesCPP[i].getPath();
|
||||
compileCommandCPP[compileCommandCPP.length - 1] = "-o" + getFolder() + File.separator + nameSansExtension + ".o";
|
||||
|
||||
process = Runtime.getRuntime().exec(compileCommandCPP);
|
||||
new MessageSiphon(process.getInputStream(), this);
|
||||
new MessageSiphon(process.getErrorStream(), this);
|
||||
|
||||
// wait for the process to finish. if interrupted
|
||||
// before waitFor returns, continue waiting
|
||||
//
|
||||
compiling = true;
|
||||
while (compiling) {
|
||||
try {
|
||||
result = process.waitFor();
|
||||
//System.out.println("result is " + result);
|
||||
compiling = false;
|
||||
} catch (InterruptedException ignored) { }
|
||||
}
|
||||
if (exception != null) {
|
||||
exception.hideStackTrace = true;
|
||||
throw exception;
|
||||
}
|
||||
if(result != 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
if ((msg != null) && (msg.indexOf("avr-gcc: not found") != -1)) {
|
||||
Base.showWarning("Compiler error",
|
||||
"Could not find the compiler.\n" +
|
||||
"avr-gcc is missing from your PATH,\n" +
|
||||
"see readme.txt for help.", null);
|
||||
return false;
|
||||
|
||||
} else if ((msg != null) && (msg.indexOf("avr-g++: not found") != -1)) {
|
||||
Base.showWarning("Compiler error",
|
||||
"Could not find the compiler.\n" +
|
||||
"avr-g++ is missing from your PATH,\n" +
|
||||
"see readme.txt for help.", null);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// an error was queued up by message()
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (result != 0 && result != 1 ) {
|
||||
Base.openURL(BUGS_URL);
|
||||
throw new RunnerException(SUPER_BADNESS);
|
||||
}
|
||||
|
||||
// success would mean that 'result' is set to zero
|
||||
return (result == 0); // ? true : false;
|
||||
}
|
||||
return false; // library is not buildable (contains no sources)
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the MessageConsumer interface, this is called
|
||||
* whenever a piece (usually a line) of error message is spewed
|
||||
* out from the compiler. The errors are parsed for their contents
|
||||
* and line number, which is then reported back to Editor.
|
||||
*/
|
||||
public void message(String inString) {
|
||||
// This receives messages as full lines, so a newline needs
|
||||
// to be added as they're printed to the console.
|
||||
|
||||
// always print all compilation output for library writers!
|
||||
String outString = "";
|
||||
|
||||
// shorten file paths so that they are friendlier
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
String substring = libFolder.getPath() + File.separator;
|
||||
StringBuffer result = new StringBuffer();
|
||||
while ((end = inString.indexOf(substring, start)) >= 0) {
|
||||
result.append(inString.substring(start, end));
|
||||
start = end + substring.length();
|
||||
}
|
||||
result.append(inString.substring(start));
|
||||
outString = result.toString();
|
||||
|
||||
System.err.print(outString);
|
||||
|
||||
// prepare error for throwing
|
||||
if (inString.indexOf("error") != -1){
|
||||
exception = new RunnerException("Error building library \"" + getName() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
217
app/LibraryManager.java
Executable file
217
app/LibraryManager.java
Executable file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
LibraryManager.java - Library System for Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/*
|
||||
* Provides information about and builds libraries
|
||||
*/
|
||||
public class LibraryManager {
|
||||
|
||||
private File libDir;
|
||||
private List libraries = new ArrayList();
|
||||
|
||||
/*
|
||||
* Create a LibraryManager.
|
||||
*/
|
||||
public LibraryManager()
|
||||
{
|
||||
String userDir = System.getProperty("user.dir") + File.separator;
|
||||
libDir = new File(
|
||||
((!Base.isMacOS()) ? "" : userDir) + "lib" + File.separator +
|
||||
"targets" + File.separator + "libraries");
|
||||
refreshLibraries();
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans for libraries and refreshes internal list
|
||||
*/
|
||||
private void refreshLibraries()
|
||||
{
|
||||
FileFilter onlyDirs = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory();
|
||||
}
|
||||
};
|
||||
libraries.clear();
|
||||
File[] libs = libDir.listFiles(onlyDirs);
|
||||
for(int i = 0; i < libs.length; ++i){
|
||||
libraries.add(new Library(this, libs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a collection of all library objects
|
||||
* @return A read-only collection of Library objects
|
||||
*/
|
||||
public Collection getAll() {
|
||||
refreshLibraries();
|
||||
return Collections.unmodifiableList(libraries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a collection of all built library objects
|
||||
* @return A read-only collection of built Library objects
|
||||
*/
|
||||
public Collection getBuiltLibraries() {
|
||||
refreshLibraries();
|
||||
List builtLibraries = new ArrayList();
|
||||
Library library;
|
||||
ListIterator libIterator = libraries.listIterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
if(library.isBuilt()){
|
||||
builtLibraries.add(library);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(builtLibraries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a collection of all buildable library objects
|
||||
* @return A read-only collection of built Library objects
|
||||
*/
|
||||
public Collection getLibrariesToBuild() {
|
||||
refreshLibraries();
|
||||
List buildableLibraries = new ArrayList();
|
||||
Library library;
|
||||
ListIterator libIterator = libraries.listIterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
if(library.isUnbuiltBuildable()){
|
||||
buildableLibraries.add(library);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(buildableLibraries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gathers paths to object files
|
||||
* @return Array of strings of paths to object files
|
||||
*/
|
||||
public String[] getObjectFiles() {
|
||||
ArrayList filesArrayList = new ArrayList();
|
||||
Collection builtLibraries = getBuiltLibraries();
|
||||
Library library;
|
||||
File[] files;
|
||||
Iterator libIterator = builtLibraries.iterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
files = library.getObjectFiles();
|
||||
for(int i = 0; i < files.length; ++i){
|
||||
filesArrayList.add(files[i].getPath());
|
||||
}
|
||||
}
|
||||
String[] filesArray = new String[filesArrayList.size()];
|
||||
filesArrayList.toArray(filesArray);
|
||||
return filesArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gathers filenames of header files
|
||||
* @return Array of strings of filenames of header files
|
||||
*/
|
||||
public String[] getHeaderFiles() {
|
||||
ArrayList filesArrayList = new ArrayList();
|
||||
Collection builtLibraries = getBuiltLibraries();
|
||||
Library library;
|
||||
File[] files;
|
||||
Iterator libIterator = builtLibraries.iterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
files = library.getHeaderFiles();
|
||||
for(int i = 0; i < files.length; ++i){
|
||||
filesArrayList.add(files[i].getName());
|
||||
}
|
||||
}
|
||||
String[] filesArray = new String[filesArrayList.size()];
|
||||
filesArrayList.toArray(filesArray);
|
||||
return filesArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gathers paths to library folders
|
||||
* @return Array of strings of paths to library folders
|
||||
*/
|
||||
public String[] getFolderPaths() {
|
||||
ArrayList foldersArrayList = new ArrayList();
|
||||
Collection builtLibraries = getBuiltLibraries();
|
||||
Library library;
|
||||
Iterator libIterator = builtLibraries.iterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
foldersArrayList.add(library.getFolder().getPath());
|
||||
}
|
||||
String[] foldersArray = new String[foldersArrayList.size()];
|
||||
foldersArrayList.toArray(foldersArray);
|
||||
return foldersArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds unbuilt libraries
|
||||
* @return Number of libraries built as int, -1 & exception on error
|
||||
*/
|
||||
public int buildAllUnbuilt() throws RunnerException {
|
||||
Collection buildableLibraries = getLibrariesToBuild();
|
||||
Library library;
|
||||
Iterator libIterator = buildableLibraries.iterator();
|
||||
int countBuilt = 0;
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
//System.out.println("Building library \"" + library.getName() + "\"");
|
||||
try {
|
||||
if(library.build()){
|
||||
++countBuilt;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}catch (RunnerException re) {
|
||||
throw new RunnerException(re.getMessage());
|
||||
} catch (Exception ex) {
|
||||
throw new RunnerException(ex.toString());
|
||||
}
|
||||
}
|
||||
return countBuilt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates examples menu with library folders
|
||||
*/
|
||||
public void populateExamplesMenu(JMenu examplesMenu, ActionListener listener) {
|
||||
Library library;
|
||||
Collection libraries = getBuiltLibraries();
|
||||
Iterator iterator = libraries.iterator();
|
||||
JMenu libraryExamples;
|
||||
while(iterator.hasNext()){
|
||||
library = (Library)iterator.next();
|
||||
libraryExamples = library.getExamplesMenu(listener);
|
||||
if(null != libraryExamples){
|
||||
examplesMenu.add(libraryExamples);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ import javax.swing.filechooser.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.undo.*;
|
||||
|
||||
//import processing.core.PApplet;
|
||||
|
||||
|
||||
/**
|
||||
@ -50,7 +51,7 @@ import javax.swing.undo.*;
|
||||
* properties files are iso8859-1, which is highly likely to
|
||||
* be a problem when trying to save sketch folders and locations.
|
||||
*/
|
||||
public class Preferences extends JComponent {
|
||||
public class Preferences {
|
||||
|
||||
// what to call the feller
|
||||
|
||||
@ -72,16 +73,32 @@ public class Preferences extends JComponent {
|
||||
static final String PROMPT_OK = "OK";
|
||||
static final String PROMPT_BROWSE = "Browse";
|
||||
|
||||
// mac needs it to be 70, windows needs 66, linux needs 76
|
||||
/**
|
||||
* Standardized width for buttons. Mac OS X 10.3 wants 70 as its default,
|
||||
* Windows XP needs 66, and Linux needs 76, so 76 seems proper.
|
||||
*/
|
||||
static public int BUTTON_WIDTH = 76;
|
||||
|
||||
static int BUTTON_WIDTH = 76;
|
||||
static int BUTTON_HEIGHT = 24;
|
||||
/**
|
||||
* Standardized button height. Mac OS X 10.3 (Java 1.4) wants 29,
|
||||
* presumably because it now includes the blue border, where it didn't
|
||||
* in Java 1.3. Windows XP only wants 23 (not sure what default Linux
|
||||
* would be). Because of the disparity, on Mac OS X, it will be set
|
||||
* inside a static block.
|
||||
*/
|
||||
static public int BUTTON_HEIGHT = 24;
|
||||
static {
|
||||
if (Base.isMacOS()) BUTTON_HEIGHT = 29;
|
||||
}
|
||||
|
||||
// value for the size bars, buttons, etc
|
||||
|
||||
static final int GRID_SIZE = 33;
|
||||
|
||||
// gui variables
|
||||
|
||||
// indents and spacing standards. these probably need to be modified
|
||||
// per platform as well, since macosx is so huge, windows is smaller,
|
||||
// and linux is all over the map
|
||||
|
||||
static final int GUI_BIG = 13;
|
||||
static final int GUI_BETWEEN = 10;
|
||||
@ -89,14 +106,12 @@ public class Preferences extends JComponent {
|
||||
|
||||
// gui elements
|
||||
|
||||
//JFrame frame;
|
||||
JDialog frame;
|
||||
JDialog dialog;
|
||||
int wide, high;
|
||||
|
||||
JTextField sketchbookLocationField;
|
||||
JCheckBox sketchPromptBox;
|
||||
JCheckBox sketchCleanBox;
|
||||
//JCheckBox exportLibraryBox;
|
||||
JCheckBox externalEditorBox;
|
||||
JCheckBox checkUpdatesBox;
|
||||
|
||||
@ -111,7 +126,6 @@ public class Preferences extends JComponent {
|
||||
|
||||
static Hashtable table = new Hashtable();;
|
||||
static File preferencesFile;
|
||||
//boolean firstTime; // first time this feller has been run
|
||||
|
||||
|
||||
static public void init() {
|
||||
@ -152,9 +166,6 @@ public class Preferences extends JComponent {
|
||||
|
||||
// next load user preferences file
|
||||
|
||||
//File home = new File(System.getProperty("user.home"));
|
||||
//File arduinoHome = new File(home, "Arduino");
|
||||
//preferencesFile = new File(home, PREFS_FILE);
|
||||
preferencesFile = Base.getSettingsFile(PREFS_FILE);
|
||||
|
||||
if (!preferencesFile.exists()) {
|
||||
@ -181,14 +192,12 @@ public class Preferences extends JComponent {
|
||||
|
||||
public Preferences() {
|
||||
|
||||
// setup frame for the prefs
|
||||
// setup dialog for the prefs
|
||||
|
||||
//frame = new JFrame("Preferences");
|
||||
frame = new JDialog(editor, "Preferences", true);
|
||||
//frame.setResizable(false);
|
||||
dialog = new JDialog(editor, "Preferences", true);
|
||||
dialog.setResizable(false);
|
||||
|
||||
//Container pain = this;
|
||||
Container pain = frame.getContentPane();
|
||||
Container pain = dialog.getContentPane();
|
||||
pain.setLayout(null);
|
||||
|
||||
int top = GUI_BIG;
|
||||
@ -284,20 +293,6 @@ public class Preferences extends JComponent {
|
||||
top += d.height + GUI_BETWEEN;
|
||||
|
||||
|
||||
// [ ] Enable export to "Library"
|
||||
|
||||
/*
|
||||
exportLibraryBox = new JCheckBox("Enable advanced \"Library\" features" +
|
||||
" (requires restart)");
|
||||
exportLibraryBox.setEnabled(false);
|
||||
pain.add(exportLibraryBox);
|
||||
d = exportLibraryBox.getPreferredSize();
|
||||
exportLibraryBox.setBounds(left, top, d.width, d.height);
|
||||
right = Math.max(right, left + d.width);
|
||||
top += d.height + GUI_BETWEEN;
|
||||
*/
|
||||
|
||||
|
||||
// [ ] Use external editor
|
||||
|
||||
externalEditorBox = new JCheckBox("Use external editor");
|
||||
@ -320,21 +315,6 @@ public class Preferences extends JComponent {
|
||||
|
||||
// More preferences are in the ...
|
||||
|
||||
/*
|
||||
String blather =
|
||||
"More preferences can be edited directly\n" +
|
||||
"in the file " + preferencesFile.getAbsolutePath();
|
||||
//"More preferences are in the 'lib' folder inside text files\n" +
|
||||
//"named preferences.txt and pde_" +
|
||||
//Base.platforms[Base.platform] + ".properties";
|
||||
|
||||
JTextArea textarea = new JTextArea(blather);
|
||||
textarea.setEditable(false);
|
||||
textarea.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
textarea.setBackground(null);
|
||||
textarea.setFont(new Font("Dialog", Font.PLAIN, 12));
|
||||
pain.add(textarea);
|
||||
*/
|
||||
label = new JLabel("More preferences can be edited directly in the file");
|
||||
|
||||
pain.add(label);
|
||||
@ -362,9 +342,6 @@ public class Preferences extends JComponent {
|
||||
|
||||
// [ OK ] [ Cancel ] maybe these should be next to the message?
|
||||
|
||||
//right = Math.max(right, left + d.width + GUI_BETWEEN +
|
||||
// BUTTON_WIDTH + GUI_SMALL + BUTTON_WIDTH);
|
||||
|
||||
button = new JButton(PROMPT_OK);
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -376,9 +353,6 @@ public class Preferences extends JComponent {
|
||||
d2 = button.getPreferredSize();
|
||||
BUTTON_HEIGHT = d2.height;
|
||||
|
||||
// smoosh up to the line before
|
||||
//top -= BUTTON_HEIGHT;
|
||||
|
||||
h = right - (BUTTON_WIDTH + GUI_SMALL + BUTTON_WIDTH);
|
||||
button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||
h += BUTTON_WIDTH + GUI_SMALL;
|
||||
@ -398,32 +372,39 @@ public class Preferences extends JComponent {
|
||||
// finish up
|
||||
|
||||
wide = right + GUI_BIG;
|
||||
high = top + GUI_SMALL; //GUI_BIG;
|
||||
setSize(wide, high);
|
||||
high = top + GUI_SMALL;
|
||||
//setSize(wide, high);
|
||||
|
||||
|
||||
// closing the window is same as hitting cancel button
|
||||
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
dialog.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
disposeFrame();
|
||||
}
|
||||
});
|
||||
|
||||
Container content = frame.getContentPane();
|
||||
content.setLayout(new BorderLayout());
|
||||
content.add(this, BorderLayout.CENTER);
|
||||
|
||||
frame.pack();
|
||||
ActionListener disposer = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
disposeFrame();
|
||||
}
|
||||
};
|
||||
Base.registerWindowCloseKeys(dialog.getRootPane(), disposer);
|
||||
|
||||
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
frame.setLocation((screen.width - wide) / 2,
|
||||
dialog.setLocation((screen.width - wide) / 2,
|
||||
(screen.height - high) / 2);
|
||||
|
||||
|
||||
dialog.pack(); // get insets
|
||||
Insets insets = dialog.getInsets();
|
||||
dialog.setSize(wide + insets.left + insets.right,
|
||||
high + insets.top + insets.bottom);
|
||||
|
||||
|
||||
// handle window closing commands for ctrl/cmd-W or hitting ESC.
|
||||
|
||||
addKeyListener(new KeyAdapter() {
|
||||
pain.addKeyListener(new KeyAdapter() {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
KeyStroke wc = Editor.WINDOW_CLOSE_KEYSTROKE;
|
||||
if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) ||
|
||||
@ -435,6 +416,26 @@ public class Preferences extends JComponent {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
protected JRootPane createRootPane() {
|
||||
System.out.println("creating root pane esc received");
|
||||
|
||||
ActionListener actionListener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
//setVisible(false);
|
||||
System.out.println("esc received");
|
||||
}
|
||||
};
|
||||
|
||||
JRootPane rootPane = new JRootPane();
|
||||
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
|
||||
rootPane.registerKeyboardAction(actionListener, stroke,
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
return rootPane;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(wide, high);
|
||||
}
|
||||
@ -447,7 +448,7 @@ public class Preferences extends JComponent {
|
||||
* Close the window after an OK or Cancel.
|
||||
*/
|
||||
public void disposeFrame() {
|
||||
frame.dispose();
|
||||
dialog.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -487,7 +488,7 @@ public class Preferences extends JComponent {
|
||||
externalEditorBox.setSelected(getBoolean("editor.external"));
|
||||
checkUpdatesBox.setSelected(getBoolean("update.check"));
|
||||
|
||||
frame.show();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
|
142
app/Sketch.java
142
app/Sketch.java
@ -1,7 +1,7 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Arduino project - http://arduino.berlios.de/
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-05 Ben Fry and Casey Reas
|
||||
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
||||
@ -19,8 +19,6 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
@ -67,7 +65,12 @@ public class Sketch {
|
||||
public File codeFolder;
|
||||
|
||||
static final int PDE = 0;
|
||||
static final int JAVA = 1;
|
||||
static final int CPP = 1;
|
||||
static final int C = 2;
|
||||
static final int HEADER = 3;
|
||||
|
||||
static final String flavorExtensionsReal[] = new String[] { ".pde", ".cpp", ".c", ".h" };
|
||||
static final String flavorExtensionsShown[] = new String[] { "", ".cpp", ".c", ".h" };
|
||||
|
||||
public SketchCode current;
|
||||
int codeCount;
|
||||
@ -104,6 +107,8 @@ public class Sketch {
|
||||
name = mainFilename.substring(0, mainFilename.length() - 4);
|
||||
} else if (mainFilename.endsWith(".c")) {
|
||||
name = mainFilename.substring(0, mainFilename.length() - 2);
|
||||
} else if (mainFilename.endsWith(".h")) {
|
||||
name = mainFilename.substring(0, mainFilename.length() - 2);
|
||||
} else if (mainFilename.endsWith(".cpp")) {
|
||||
name = mainFilename.substring(0, mainFilename.length() - 4);
|
||||
}
|
||||
@ -157,9 +162,11 @@ public class Sketch {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (list[i].endsWith(".pde")) codeCount++;
|
||||
else if (list[i].endsWith(".c")) codeCount++;
|
||||
else if (list[i].endsWith(".h")) codeCount++;
|
||||
else if (list[i].endsWith(".cpp")) codeCount++;
|
||||
else if (list[i].endsWith(".pde.x")) hiddenCount++;
|
||||
else if (list[i].endsWith(".c.x")) hiddenCount++;
|
||||
else if (list[i].endsWith(".h.x")) hiddenCount++;
|
||||
else if (list[i].endsWith(".cpp.x")) hiddenCount++;
|
||||
}
|
||||
|
||||
@ -180,13 +187,19 @@ public class Sketch {
|
||||
code[codeCounter++] =
|
||||
new SketchCode(list[i].substring(0, list[i].length() - 2),
|
||||
new File(folder, list[i]),
|
||||
JAVA);
|
||||
C);
|
||||
|
||||
} else if (list[i].endsWith(".h")) {
|
||||
code[codeCounter++] =
|
||||
new SketchCode(list[i].substring(0, list[i].length() - 2),
|
||||
new File(folder, list[i]),
|
||||
HEADER);
|
||||
|
||||
} else if (list[i].endsWith(".cpp")) {
|
||||
code[codeCounter++] =
|
||||
new SketchCode(list[i].substring(0, list[i].length() - 4),
|
||||
new File(folder, list[i]),
|
||||
JAVA);
|
||||
CPP);
|
||||
|
||||
} else if (list[i].endsWith(".pde.x")) {
|
||||
hidden[hiddenCounter++] =
|
||||
@ -198,12 +211,17 @@ public class Sketch {
|
||||
hidden[hiddenCounter++] =
|
||||
new SketchCode(list[i].substring(0, list[i].length() - 4),
|
||||
new File(folder, list[i]),
|
||||
JAVA);
|
||||
C);
|
||||
} else if (list[i].endsWith(".h.x")) {
|
||||
hidden[hiddenCounter++] =
|
||||
new SketchCode(list[i].substring(0, list[i].length() - 4),
|
||||
new File(folder, list[i]),
|
||||
HEADER);
|
||||
} else if (list[i].endsWith(".cpp.x")) {
|
||||
hidden[hiddenCounter++] =
|
||||
new SketchCode(list[i].substring(0, list[i].length() - 6),
|
||||
new File(folder, list[i]),
|
||||
JAVA);
|
||||
CPP);
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,8 +332,7 @@ public class Sketch {
|
||||
renamingCode = true;
|
||||
String prompt = (current == code[0]) ?
|
||||
"New name for sketch:" : "New name for file:";
|
||||
String oldName =
|
||||
(current.flavor == PDE) ? current.name : current.name + ".cpp";
|
||||
String oldName = current.name + flavorExtensionsShown[current.flavor];
|
||||
editor.status.edit(prompt, oldName);
|
||||
}
|
||||
|
||||
@ -348,6 +365,7 @@ public class Sketch {
|
||||
}
|
||||
|
||||
if (newName.trim().equals(".c") ||
|
||||
newName.trim().equals(".h") ||
|
||||
newName.trim().equals(".pde") ||
|
||||
newName.trim().equals(".cpp")) {
|
||||
return;
|
||||
@ -363,23 +381,28 @@ public class Sketch {
|
||||
newName = newName.substring(0, newName.length() - 4);
|
||||
newFlavor = PDE;
|
||||
|
||||
} else if (newName.endsWith(".c") || newName.endsWith(".cpp")) {
|
||||
} else if (newName.endsWith(".c") || newName.endsWith(".cpp") ||
|
||||
newName.endsWith(".h")) {
|
||||
// don't show this error if creating a new tab
|
||||
if (renamingCode && (code[0] == current)) {
|
||||
Base.showWarning("Problem with rename",
|
||||
"The main .pde file cannot be .c or .cpp file.\n" +
|
||||
"The main .pde file cannot be .c, .cpp, or .h file.\n" +
|
||||
"(It may be time for your to graduate to a\n" +
|
||||
"\"real\" programming environment)", null);
|
||||
return;
|
||||
}
|
||||
|
||||
newFilename = newName;
|
||||
if(newName.endsWith(".c"))
|
||||
if(newName.endsWith(".c")) {
|
||||
newName = newName.substring(0, newName.length() - 2);
|
||||
else if(newName.endsWith(".cpp"))
|
||||
newFlavor = C;
|
||||
} if(newName.endsWith(".h")) {
|
||||
newName = newName.substring(0, newName.length() - 2);
|
||||
newFlavor = HEADER;
|
||||
} else if(newName.endsWith(".cpp")) {
|
||||
newName = newName.substring(0, newName.length() - 4);
|
||||
newFlavor = JAVA;
|
||||
|
||||
newFlavor = CPP;
|
||||
}
|
||||
} else {
|
||||
newFilename = newName + ".pde";
|
||||
newFlavor = PDE;
|
||||
@ -538,7 +561,7 @@ public class Sketch {
|
||||
sortCode();
|
||||
|
||||
// set the new guy as current
|
||||
setCurrent(newName);
|
||||
setCurrent(newName + flavorExtensionsShown[newFlavor]);
|
||||
|
||||
// update the tabs
|
||||
//editor.header.repaint();
|
||||
@ -572,7 +595,8 @@ public class Sketch {
|
||||
Object[] options = { "OK", "Cancel" };
|
||||
String prompt = (current == code[0]) ?
|
||||
"Are you sure you want to delete this sketch?" :
|
||||
"Are you sure you want to delete \"" + current.name + "\"?";
|
||||
"Are you sure you want to delete \"" + current.name +
|
||||
flavorExtensionsShown[current.flavor] + "\"?";
|
||||
int result = JOptionPane.showOptionDialog(editor,
|
||||
prompt,
|
||||
"Delete",
|
||||
@ -684,9 +708,14 @@ public class Sketch {
|
||||
|
||||
public void unhideCode(String what) {
|
||||
SketchCode unhideCode = null;
|
||||
String name = what.substring(0,
|
||||
(what.indexOf(".") == -1 ? what.length() : what.indexOf(".")));
|
||||
String extension = what.indexOf(".") == -1 ? "" :
|
||||
what.substring(what.indexOf("."));
|
||||
|
||||
for (int i = 0; i < hiddenCount; i++) {
|
||||
if (hidden[i].name.equals(what)) {
|
||||
if (hidden[i].name.equals(name) &&
|
||||
Sketch.flavorExtensionsShown[hidden[i].flavor].equals(extension)) {
|
||||
//unhideIndex = i;
|
||||
unhideCode = hidden[i];
|
||||
|
||||
@ -730,8 +759,8 @@ public class Sketch {
|
||||
/**
|
||||
* Sets the modified value for the code in the frontmost tab.
|
||||
*/
|
||||
public void setModified() {
|
||||
current.modified = true;
|
||||
public void setModified(boolean state) {
|
||||
current.modified = state;
|
||||
calcModified();
|
||||
}
|
||||
|
||||
@ -996,6 +1025,26 @@ public class Sketch {
|
||||
// it move instead of copy, they can do it by hand
|
||||
File sourceFile = new File(directory, filename);
|
||||
|
||||
// now do the work of adding the file
|
||||
addFile(sourceFile);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a file to the sketch.
|
||||
* <p/>
|
||||
* .pde or .java files will be added to the sketch folder. <br/>
|
||||
* .jar, .class, .dll, .jnilib, and .so files will all
|
||||
* be added to the "code" folder. <br/>
|
||||
* All other files will be added to the "data" folder.
|
||||
* <p/>
|
||||
* If they don't exist already, the "code" or "data" folder
|
||||
* will be created.
|
||||
* <p/>
|
||||
* @return true if successful.
|
||||
*/
|
||||
public boolean addFile(File sourceFile) {
|
||||
String filename = sourceFile.getName();
|
||||
File destFile = null;
|
||||
boolean addingCode = false;
|
||||
|
||||
@ -1012,6 +1061,7 @@ public class Sketch {
|
||||
|
||||
} else if (filename.toLowerCase().endsWith(".pde") ||
|
||||
filename.toLowerCase().endsWith(".c") ||
|
||||
filename.toLowerCase().endsWith(".h") ||
|
||||
filename.toLowerCase().endsWith(".cpp")) {
|
||||
destFile = new File(this.folder, filename);
|
||||
addingCode = true;
|
||||
@ -1028,7 +1078,7 @@ public class Sketch {
|
||||
"This file has already been copied to the\n" +
|
||||
"location where you're trying to add it.\n" +
|
||||
"I ain't not doin nuthin'.", null);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// in case the user is "adding" the code in an attempt
|
||||
@ -1036,10 +1086,12 @@ public class Sketch {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,9 +1102,15 @@ public class Sketch {
|
||||
if (newName.toLowerCase().endsWith(".pde")) {
|
||||
newName = newName.substring(0, newName.length() - 4);
|
||||
newFlavor = PDE;
|
||||
} else {
|
||||
} else if (newName.toLowerCase().endsWith(".c")) {
|
||||
newName = newName.substring(0, newName.length() - 2);
|
||||
newFlavor = JAVA;
|
||||
newFlavor = C;
|
||||
} else if (newName.toLowerCase().endsWith(".h")) {
|
||||
newName = newName.substring(0, newName.length() - 2);
|
||||
newFlavor = HEADER;
|
||||
} else { // ".cpp"
|
||||
newName = newName.substring(0, newName.length() - 4);
|
||||
newFlavor = CPP;
|
||||
}
|
||||
|
||||
// see also "nameCode" for identical situation
|
||||
@ -1062,6 +1120,7 @@ public class Sketch {
|
||||
setCurrent(newName);
|
||||
editor.header.repaint();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1145,8 +1204,15 @@ public class Sketch {
|
||||
* based on a name (used by codeNew and codeRename).
|
||||
*/
|
||||
protected void setCurrent(String findName) {
|
||||
SketchCode unhideCode = null;
|
||||
String name = findName.substring(0,
|
||||
(findName.indexOf(".") == -1 ? findName.length() : findName.indexOf(".")));
|
||||
String extension = findName.indexOf(".") == -1 ? "" :
|
||||
findName.substring(findName.indexOf("."));
|
||||
|
||||
for (int i = 0; i < codeCount; i++) {
|
||||
if (findName.equals(code[i].name)) {
|
||||
if (name.equals(code[i].name) &&
|
||||
Sketch.flavorExtensionsShown[code[i].flavor].equals(extension)) {
|
||||
setCurrent(i);
|
||||
return;
|
||||
}
|
||||
@ -1264,6 +1330,20 @@ public class Sketch {
|
||||
*/
|
||||
protected String build(Target target, String buildPath, String suggestedClassName)
|
||||
throws RunnerException {
|
||||
|
||||
// build unbuilt buildable libraries
|
||||
// completely independent from sketch, so run all the time
|
||||
LibraryManager libraryManager = new LibraryManager();
|
||||
try {
|
||||
libraryManager.buildAllUnbuilt();
|
||||
} catch (RunnerException re) {
|
||||
throw new RunnerException(re.getMessage());
|
||||
} catch (Exception ex) {
|
||||
throw new RunnerException(ex.toString());
|
||||
}
|
||||
// update sketchbook menu, this adds examples of any built libs
|
||||
editor.sketchbook.rebuildMenus();
|
||||
|
||||
// make sure the user didn't hide the sketch folder
|
||||
ensureExistence();
|
||||
|
||||
@ -1316,7 +1396,7 @@ public class Sketch {
|
||||
// check to see if multiple files that include a .java file
|
||||
externalRuntime = false;
|
||||
for (int i = 0; i < codeCount; i++) {
|
||||
if (code[i].flavor == JAVA) {
|
||||
if (code[i].flavor == C || code[i].flavor == CPP) {
|
||||
externalRuntime = true;
|
||||
break;
|
||||
}
|
||||
@ -1382,7 +1462,6 @@ public class Sketch {
|
||||
//System.out.println();
|
||||
|
||||
} else {
|
||||
//code[0].preprocName = className + "." + Preferences.get("build.extension");
|
||||
code[0].preprocName = className + ".cpp";
|
||||
}
|
||||
|
||||
@ -1408,6 +1487,7 @@ public class Sketch {
|
||||
}
|
||||
errorLine -= code[errorFile].preprocOffset;
|
||||
errorLine -= preprocessor.prototypeCount;
|
||||
errorLine -= preprocessor.headerCount;
|
||||
|
||||
throw new RunnerException(re.getMessage(), errorFile,
|
||||
errorLine, re.getColumn());
|
||||
@ -1449,6 +1529,7 @@ public class Sketch {
|
||||
}
|
||||
errorLine -= code[errorFile].preprocOffset;
|
||||
errorLine -= preprocessor.prototypeCount;
|
||||
errorLine -= preprocessor.headerCount;
|
||||
|
||||
throw new RunnerException(tsre.getMessage(),
|
||||
errorFile, errorLine, errorColumn);
|
||||
@ -1507,13 +1588,12 @@ public class Sketch {
|
||||
// 3. then loop over the code[] and save each .java file
|
||||
|
||||
for (int i = 0; i < codeCount; i++) {
|
||||
if (code[i].flavor == JAVA) {
|
||||
if (code[i].flavor == CPP || code[i].flavor == C || code[i].flavor == HEADER) {
|
||||
// no pre-processing services necessary for java files
|
||||
// just write the the contents of 'program' to a .java file
|
||||
// into the build directory. uses byte stream and reader/writer
|
||||
// shtuff so that unicode bunk is properly handled
|
||||
//String filename = code[i].name + "." + Preferences.get("build.extension");
|
||||
String filename = code[i].name + ".cpp";
|
||||
String filename = code[i].name + flavorExtensionsReal[code[i].flavor];
|
||||
try {
|
||||
Base.saveFile(code[i].program, new File(buildPath, filename));
|
||||
} catch (IOException e) {
|
||||
@ -1538,7 +1618,7 @@ public class Sketch {
|
||||
} catch (RunnerException re) {
|
||||
throw new RunnerException(re.getMessage(),
|
||||
re.file,
|
||||
re.line - preprocessor.prototypeCount,
|
||||
re.line - preprocessor.prototypeCount - preprocessor.headerCount,
|
||||
re.column);
|
||||
} catch (Exception ex) {
|
||||
// TODO better method for handling this?
|
||||
|
@ -383,9 +383,17 @@ public class Sketchbook {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
LibraryManager libManager = new LibraryManager();
|
||||
ActionListener listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
editor.handleOpen(e.getActionCommand());
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
JMenu examplesMenu = new JMenu("Examples");
|
||||
addSketches(examplesMenu, examplesFolder);
|
||||
libManager.populateExamplesMenu(examplesMenu, listener);
|
||||
menu.add(examplesMenu);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -542,8 +550,10 @@ public class Sketchbook {
|
||||
list[i].equals("CVS")) continue;
|
||||
|
||||
File subfolder = new File(folder, list[i]);
|
||||
if (!subfolder.isDirectory()) continue;
|
||||
|
||||
File exported = new File(subfolder, "library");
|
||||
File entry = new File(exported, list[i] + ".jar");
|
||||
File entry = new File(exported, list[i] + ".o");
|
||||
// if a .jar file of the same prefix as the folder exists
|
||||
// inside the 'library' subfolder of the sketch
|
||||
if (entry.exists()) {
|
||||
@ -556,7 +566,7 @@ public class Sketchbook {
|
||||
Base.showMessage("Ignoring bad sketch name", mess);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
// get the path for all .jar files in this code folder
|
||||
String libraryClassPath =
|
||||
Compiler.contentsToClassPath(exported);
|
||||
@ -565,12 +575,12 @@ public class Sketchbook {
|
||||
librariesClassPath +=
|
||||
File.pathSeparatorChar + libraryClassPath;
|
||||
// need to associate each import with a library folder
|
||||
String packages[] = new String[0];
|
||||
//Compiler.packageListFromClassPath(libraryClassPath);
|
||||
String packages[] =
|
||||
Compiler.packageListFromClassPath(libraryClassPath);
|
||||
for (int k = 0; k < packages.length; k++) {
|
||||
importToLibraryTable.put(packages[k], exported);
|
||||
}
|
||||
|
||||
*/
|
||||
JMenuItem item = new JMenuItem(list[i]);
|
||||
item.addActionListener(listener);
|
||||
item.setActionCommand(entry.getAbsolutePath());
|
||||
@ -589,7 +599,7 @@ public class Sketchbook {
|
||||
}
|
||||
}
|
||||
return ifound;
|
||||
}
|
||||
/*return false;*/ }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -74,6 +74,9 @@ public class PdePreprocessor {
|
||||
// stores number of built user-defined function prototypes
|
||||
public int prototypeCount = 0;
|
||||
|
||||
// stores number of included library headers written
|
||||
public int headerCount = 0;
|
||||
|
||||
/**
|
||||
* These may change in-between (if the prefs panel adds this option)
|
||||
* so grab them here on construction.
|
||||
@ -236,7 +239,6 @@ public class PdePreprocessor {
|
||||
String returntype, functioname, parameterlist, prototype;
|
||||
java.util.LinkedList prototypes = new java.util.LinkedList();
|
||||
//System.out.println("prototypes:");
|
||||
//if (Preferences.get("build.extension").equals("cpp")) {
|
||||
while(matcher.contains(input, pattern)){
|
||||
result = matcher.getMatch();
|
||||
//System.out.println(result);
|
||||
@ -253,7 +255,6 @@ public class PdePreprocessor {
|
||||
prototypes.add(prototype);
|
||||
//System.out.println(prototype);
|
||||
}
|
||||
//}
|
||||
// store # of prototypes so that line number reporting can be adjusted
|
||||
prototypeCount = prototypes.size();
|
||||
|
||||
@ -263,6 +264,7 @@ public class PdePreprocessor {
|
||||
// through so that the line numbers when the compiler reports errors
|
||||
// match those that will be highlighted in the PDE IDE
|
||||
//
|
||||
//System.out.println(program);
|
||||
WLexer lexer = new WLexer(programReader);
|
||||
//lexer.setTokenObjectClass("antlr.CommonHiddenStreamToken");
|
||||
lexer.setTokenObjectClass("processing.app.preproc.CToken");
|
||||
@ -329,7 +331,6 @@ public class PdePreprocessor {
|
||||
// output the code
|
||||
//
|
||||
WEmitter emitter = new WEmitter(lexer.getPreprocessorInfoChannel());
|
||||
//File streamFile = new File(buildPath, name + "." + Preferences.get("build.extension"));
|
||||
File streamFile = new File(buildPath, name + ".cpp");
|
||||
PrintStream stream = new PrintStream(new FileOutputStream(streamFile));
|
||||
|
||||
@ -382,6 +383,16 @@ public class PdePreprocessor {
|
||||
void writeHeader(PrintStream out, String className, java.util.LinkedList prototypes) {
|
||||
out.print("#include \"WProgram.h\"\n");
|
||||
|
||||
// print library headers
|
||||
LibraryManager libraryManager = new LibraryManager();
|
||||
String[] headerFiles = libraryManager.getHeaderFiles();
|
||||
for(int i = 0; i < headerFiles.length; ++i){
|
||||
out.print("#include \"" + headerFiles[i] + "\"\n");
|
||||
}
|
||||
|
||||
// record number of header lines written for error line adjustment
|
||||
headerCount = headerFiles.length;
|
||||
|
||||
// print user defined prototypes
|
||||
while(0 < prototypes.size()){
|
||||
out.print(prototypes.removeFirst() + "\n");
|
||||
|
@ -1647,7 +1647,7 @@ public class JEditTextArea extends JComponent
|
||||
inputHandler.keyTyped(evt);
|
||||
break;
|
||||
case KeyEvent.KEY_PRESSED:
|
||||
if (!editorListener.keyPressed(evt)) {
|
||||
if ((editorListener != null) && !editorListener.keyPressed(evt)) {
|
||||
inputHandler.keyPressed(evt);
|
||||
}
|
||||
break;
|
||||
|
@ -475,6 +475,42 @@ public class TextAreaPainter extends JComponent implements TabExpander
|
||||
Token currentLineTokens;
|
||||
Segment currentLine;
|
||||
|
||||
/**
|
||||
* Accessor used by tools that want to hook in and grab the formatting.
|
||||
*/
|
||||
public int getCurrentLineIndex() {
|
||||
return currentLineIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor used by tools that want to hook in and grab the formatting.
|
||||
*/
|
||||
public void setCurrentLineIndex(int what) {
|
||||
currentLineIndex = what;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor used by tools that want to hook in and grab the formatting.
|
||||
*/
|
||||
public Token getCurrentLineTokens() {
|
||||
return currentLineTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor used by tools that want to hook in and grab the formatting.
|
||||
*/
|
||||
public void setCurrentLineTokens(Token tokens) {
|
||||
currentLineTokens = tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor used by tools that want to hook in and grab the formatting.
|
||||
*/
|
||||
public Segment getCurrentLine() {
|
||||
return currentLine;
|
||||
}
|
||||
|
||||
|
||||
// protected members
|
||||
protected JEditTextArea textArea;
|
||||
|
||||
|
156
app/tools/Archiver.java
Executable file
156
app/tools/Archiver.java
Executable file
@ -0,0 +1,156 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Archiver - plugin tool for archiving sketches
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-05 Ben Fry and Casey Reas
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.app.tools;
|
||||
|
||||
import processing.app.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
|
||||
public class Archiver {
|
||||
Editor editor;
|
||||
|
||||
// someday these will be settable
|
||||
boolean useDate = true; //false;
|
||||
int digits = 3;
|
||||
|
||||
NumberFormat numberFormat;
|
||||
SimpleDateFormat dateFormat;
|
||||
|
||||
|
||||
public Archiver(Editor editor) {
|
||||
this.editor = editor;
|
||||
|
||||
numberFormat = NumberFormat.getInstance();
|
||||
numberFormat.setGroupingUsed(false); // no commas
|
||||
numberFormat.setMinimumIntegerDigits(digits);
|
||||
|
||||
dateFormat = new SimpleDateFormat("yyMMdd");
|
||||
}
|
||||
|
||||
|
||||
public void show() {
|
||||
// first save the sketch so that things don't archive strangely
|
||||
boolean success = false;
|
||||
try {
|
||||
success = editor.sketch.save();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!success) {
|
||||
Base.showWarning("Couldn't archive sketch",
|
||||
"Archiving the sketch has been canceled because\n" +
|
||||
"the sketch couldn't save properly.", null);
|
||||
return;
|
||||
}
|
||||
|
||||
File location = editor.sketch.folder;
|
||||
String name = location.getName();
|
||||
File parent = new File(location.getParent());
|
||||
|
||||
//System.out.println("loc " + location);
|
||||
//System.out.println("par " + parent);
|
||||
|
||||
File newbie = null;
|
||||
String namely = null;
|
||||
int index = 0;
|
||||
do {
|
||||
if (useDate) {
|
||||
String purty = dateFormat.format(new Date());
|
||||
String stamp = purty + ((char) ('a' + index));
|
||||
namely = name + "-" + stamp;
|
||||
newbie = new File(parent, namely + ".zip");
|
||||
|
||||
} else {
|
||||
String diggie = numberFormat.format(index + 1);
|
||||
namely = name + "-" + diggie;
|
||||
newbie = new File(parent, namely + ".zip");
|
||||
}
|
||||
index++;
|
||||
} while (newbie.exists());
|
||||
|
||||
try {
|
||||
//System.out.println(newbie);
|
||||
FileOutputStream zipOutputFile = new FileOutputStream(newbie);
|
||||
ZipOutputStream zos = new ZipOutputStream(zipOutputFile);
|
||||
|
||||
// recursively fill the zip file
|
||||
buildZip(location, name, zos);
|
||||
|
||||
// close up the jar file
|
||||
zos.flush();
|
||||
zos.close();
|
||||
|
||||
editor.message("Created archive " + newbie.getName() + ".");
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void buildZip(File dir, String sofar,
|
||||
ZipOutputStream zos) throws IOException {
|
||||
String files[] = dir.list();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (files[i].equals(".") ||
|
||||
files[i].equals("..")) continue;
|
||||
|
||||
File sub = new File(dir, files[i]);
|
||||
String nowfar = (sofar == null) ?
|
||||
files[i] : (sofar + "/" + files[i]);
|
||||
|
||||
if (sub.isDirectory()) {
|
||||
// directories are empty entries and have / at the end
|
||||
ZipEntry entry = new ZipEntry(nowfar + "/");
|
||||
//System.out.println(entry);
|
||||
zos.putNextEntry(entry);
|
||||
zos.closeEntry();
|
||||
buildZip(sub, nowfar, zos);
|
||||
|
||||
} else {
|
||||
ZipEntry entry = new ZipEntry(nowfar);
|
||||
entry.setTime(sub.lastModified());
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(Base.grabFile(sub));
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int index = 0;
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
|
||||
String purty = formatter.format(new Date());
|
||||
do {
|
||||
newbieName = "sketch_" + purty + ((char) ('a' + index));
|
||||
newbieDir = new File(newbieParentDir, newbieName);
|
||||
index++;
|
||||
} while (newbieDir.exists());
|
||||
*/
|
@ -3,7 +3,7 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2005 Ben Fry and Casey Reas
|
||||
Copyright (c) 2005-06 Ben Fry and Casey Reas
|
||||
Copyright (c) 2003 Martin Gomez, Ateneo de Manila University
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -31,122 +31,20 @@ import java.util.StringTokenizer;
|
||||
|
||||
|
||||
/**
|
||||
* Alternate handler for dealing with auto format,
|
||||
* contributed by Martin Gomez.
|
||||
* Alternate handler for dealing with auto format.
|
||||
* Contributed by Martin Gomez, additional bug fixes by Ben Fry.
|
||||
*/
|
||||
public class AutoFormat {
|
||||
Editor editor;
|
||||
|
||||
|
||||
public AutoFormat(Editor editor) {
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void show() {
|
||||
String prog = editor.textarea.getText();
|
||||
|
||||
// TODO re-enable history
|
||||
//history.record(prog, SketchHistory.BEAUTIFY);
|
||||
|
||||
//int tabSize = Preferences.getInteger("editor.tabs.size");
|
||||
|
||||
char program[] = prog.toCharArray();
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
boolean gotBlankLine = false;
|
||||
int index = 0;
|
||||
int level = 0;
|
||||
|
||||
while (index != program.length) {
|
||||
int begin = index;
|
||||
while ((program[index] != '\n') &&
|
||||
(program[index] != '\r')) {
|
||||
index++;
|
||||
if (program.length == index)
|
||||
break;
|
||||
}
|
||||
int end = index;
|
||||
if (index != program.length) {
|
||||
if ((index+1 != program.length) &&
|
||||
// treat \r\n from windows as one line
|
||||
(program[index] == '\r') &&
|
||||
(program[index+1] == '\n')) {
|
||||
index += 2;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
} // otherwise don't increment
|
||||
|
||||
String line = new String(program, begin, end-begin);
|
||||
line = line.trim();
|
||||
|
||||
if (line.length() == 0) {
|
||||
if (!gotBlankLine) {
|
||||
// let first blank line through
|
||||
buffer.append('\n');
|
||||
gotBlankLine = true;
|
||||
}
|
||||
} else {
|
||||
//System.out.println(level);
|
||||
int idx = -1;
|
||||
String myline = line.substring(0);
|
||||
while (myline.lastIndexOf('}') != idx) {
|
||||
idx = myline.indexOf('}');
|
||||
myline = myline.substring(idx+1);
|
||||
level--;
|
||||
}
|
||||
//for (int i = 0; i < level*2; i++) {
|
||||
// TODO i've since forgotten how i made this work (maybe it's even
|
||||
// a bug) but for now, level is incrementing/decrementing in
|
||||
// steps of two. in the interest of getting a release out,
|
||||
// i'm just gonna roll with that since this function will prolly
|
||||
// be replaced entirely and there are other things to worry about.
|
||||
for (int i = 0; i < tabSize * level / 2; i++) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append(line);
|
||||
buffer.append('\n');
|
||||
//if (line.charAt(0) == '{') {
|
||||
//level++;
|
||||
//}
|
||||
idx = -1;
|
||||
myline = line.substring(0);
|
||||
while (myline.lastIndexOf('{') != idx) {
|
||||
idx = myline.indexOf('{');
|
||||
myline = myline.substring(idx+1);
|
||||
level++;
|
||||
}
|
||||
gotBlankLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
// save current (rough) selection point
|
||||
int selectionEnd = editor.textarea.getSelectionEnd();
|
||||
|
||||
// replace with new bootiful text
|
||||
editor.setText(buffer.toString(), false);
|
||||
|
||||
// make sure the caret would be past the end of the text
|
||||
if (buffer.length() < selectionEnd - 1) {
|
||||
selectionEnd = buffer.length() - 1;
|
||||
}
|
||||
|
||||
// at least in the neighborhood
|
||||
editor.textarea.select(selectionEnd, selectionEnd);
|
||||
|
||||
editor.sketch.setModified();
|
||||
//buttons.clear();
|
||||
}
|
||||
*/
|
||||
|
||||
static final int BLOCK_MAXLEN = 1024;
|
||||
|
||||
StringBuffer strOut;
|
||||
String formattedText;
|
||||
//String formattedText;
|
||||
int indentValue;
|
||||
String indentChar;
|
||||
String uhOh = null;
|
||||
String theStuff;
|
||||
//String uhOh = null;
|
||||
//String theStuff;
|
||||
int EOF;
|
||||
BufferedInputStream bin = null;
|
||||
int nBytesRead, indexBlock, lineLength, lineNumber;
|
||||
@ -167,7 +65,6 @@ public class AutoFormat {
|
||||
int s_tabs[][];
|
||||
String w_if_, w_else, w_for, w_ds, w_case, w_cpp_comment, w_jdoc;
|
||||
int jdoc, j;
|
||||
int BLOCK_MAXLEN;
|
||||
char string[];
|
||||
byte bstring[];
|
||||
byte bblank;
|
||||
@ -183,10 +80,15 @@ public class AutoFormat {
|
||||
|
||||
String line_feed;
|
||||
|
||||
static int outfil; // temporary
|
||||
//static int outfil; // temporary
|
||||
|
||||
|
||||
public void comment() {
|
||||
public AutoFormat(Editor editor) {
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
|
||||
public void comment() throws IOException {
|
||||
int save_s_flg;
|
||||
save_s_flg = s_flg;
|
||||
|
||||
@ -194,7 +96,7 @@ public class AutoFormat {
|
||||
c = string[j++] = getchr(); // extra char
|
||||
while (done == 0) {
|
||||
c = string[j++] = getchr();
|
||||
while(c != '/') {
|
||||
while ((c != '/') && (j < string.length)) {
|
||||
if(c == '\n' || c == '\r') {
|
||||
lineNumber++;
|
||||
putcoms();
|
||||
@ -216,7 +118,7 @@ public class AutoFormat {
|
||||
}
|
||||
|
||||
|
||||
public char get_string() {
|
||||
public char get_string() throws IOException {
|
||||
char ch;
|
||||
ch = '*';
|
||||
while (true) {
|
||||
@ -275,8 +177,9 @@ public class AutoFormat {
|
||||
}
|
||||
|
||||
|
||||
public void fprintf(int outfil, String out_string) {
|
||||
int out_len = out_string.length();
|
||||
//public void fprintf(int outfil, String out_string) {
|
||||
public void fprintf(String out_string) {
|
||||
//int out_len = out_string.length();
|
||||
String j_string = new String(string);
|
||||
strOut.append(out_string);
|
||||
}
|
||||
@ -287,491 +190,6 @@ public class AutoFormat {
|
||||
}
|
||||
|
||||
|
||||
public void setUhOh(String s) {
|
||||
uhOh = s;
|
||||
}
|
||||
|
||||
|
||||
public String grabUhOh() {
|
||||
return uhOh;
|
||||
}
|
||||
|
||||
|
||||
public void show() {
|
||||
StringBuffer onechar;
|
||||
|
||||
theStuff = editor.textarea.getText();
|
||||
strOut = new StringBuffer();
|
||||
indentValue = Preferences.getInteger("editor.tabs.size");
|
||||
indentChar = new String(" ");
|
||||
|
||||
lineNumber = 0;
|
||||
BLOCK_MAXLEN = 256;
|
||||
c_level = if_lev = level = e_flg = paren = 0;
|
||||
a_flg = q_flg = j = b_flg = tabs = 0;
|
||||
if_flg = peek = -1;
|
||||
peekc = '`';
|
||||
s_flg = 1;
|
||||
bblank = ' ';
|
||||
jdoc = 0;
|
||||
|
||||
s_level = new int[10];
|
||||
sp_flg = new int[20][10];
|
||||
s_ind = new int[20][10];
|
||||
s_if_lev = new int[10];
|
||||
s_if_flg = new int[10];
|
||||
ind = new int[10];
|
||||
p_flg = new int[10];
|
||||
s_tabs = new int[20][10];
|
||||
|
||||
w_else = new String ("else");
|
||||
w_if_ = new String ("if");
|
||||
w_for = new String ("for");
|
||||
w_ds = new String ("default");
|
||||
w_case = new String ("case");
|
||||
w_cpp_comment = new String ("//");
|
||||
w_jdoc = new String ("/**");
|
||||
line_feed = new String ("\n");
|
||||
|
||||
try { // opening input string
|
||||
// open for input
|
||||
ByteArrayInputStream in =
|
||||
new ByteArrayInputStream(theStuff.getBytes());
|
||||
|
||||
// add buffering to that InputStream
|
||||
bin = new BufferedInputStream(in);
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
|
||||
// read as long as there is something to read
|
||||
EOF = 0; // = 1 set in getchr when EOF
|
||||
|
||||
bArray = new byte[BLOCK_MAXLEN];
|
||||
string = new char[BLOCK_MAXLEN];
|
||||
try { // the whole process
|
||||
for (int ib = 0; ib < BLOCK_MAXLEN; ib++) bArray[ib] = '\0';
|
||||
|
||||
lineLength = nBytesRead = 0;
|
||||
// read up a block - remember how many bytes read
|
||||
nBytesRead = bin.read(bArray);
|
||||
strBlock = new String(bArray);
|
||||
|
||||
lineLength = nBytesRead;
|
||||
lineNumber = 1;
|
||||
indexBlock = -1;
|
||||
j = 0;
|
||||
while(EOF == 0)
|
||||
{
|
||||
c = getchr();
|
||||
switch(c)
|
||||
{
|
||||
default:
|
||||
string[j++] = c;
|
||||
if(c != ',')
|
||||
{
|
||||
l_char = c;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
if(lookup(w_else) == 1)
|
||||
{
|
||||
gotelse();
|
||||
if(s_flg == 0 || j > 0)string[j++] = c;
|
||||
indent_puts();
|
||||
s_flg = 0;
|
||||
break;
|
||||
}
|
||||
if(s_flg == 0 || j > 0)string[j++] = c;
|
||||
break;
|
||||
case '\r': /* <CR> for MS Windows 95 */
|
||||
case '\n':
|
||||
lineNumber++;
|
||||
if (EOF==1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
String j_string = new String(string);
|
||||
|
||||
e_flg = lookup(w_else);
|
||||
if(e_flg == 1) gotelse();
|
||||
if (lookup_com(w_cpp_comment) == 1)
|
||||
{
|
||||
if (string[j] == '\n')
|
||||
{
|
||||
string[j] = '\0';
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
indent_puts();
|
||||
fprintf(outfil, line_feed);
|
||||
s_flg = 1;
|
||||
if(e_flg == 1)
|
||||
{
|
||||
p_flg[level]++;
|
||||
tabs++;
|
||||
}
|
||||
else
|
||||
if(p_char == l_char)
|
||||
{
|
||||
a_flg = 1;
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
if(lookup(w_else) == 1)gotelse();
|
||||
s_if_lev[c_level] = if_lev;
|
||||
s_if_flg[c_level] = if_flg;
|
||||
if_lev = if_flg = 0;
|
||||
c_level++;
|
||||
if(s_flg == 1 && p_flg[level] != 0)
|
||||
{
|
||||
p_flg[level]--;
|
||||
tabs--;
|
||||
}
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
getnl() ;
|
||||
indent_puts();
|
||||
fprintf(outfil,"\n");
|
||||
tabs++;
|
||||
s_flg = 1;
|
||||
if(p_flg[level] > 0)
|
||||
{
|
||||
ind[level] = 1;
|
||||
level++;
|
||||
s_level[level] = c_level;
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
c_level--;
|
||||
if (c_level < 0)
|
||||
{
|
||||
EOF = 1;
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
break;
|
||||
}
|
||||
if((if_lev = s_if_lev[c_level]-1) < 0)if_lev = 0;
|
||||
if_flg = s_if_flg[c_level];
|
||||
indent_puts();
|
||||
tabs--;
|
||||
p_tabs();
|
||||
peekc = getchr();
|
||||
if( peekc == ';')
|
||||
{
|
||||
onechar = new StringBuffer();
|
||||
onechar.append(c); /* } */
|
||||
onechar.append(';');
|
||||
fprintf(outfil, onechar.toString());
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
}
|
||||
else
|
||||
{
|
||||
onechar = new StringBuffer();
|
||||
onechar.append(c);
|
||||
fprintf(outfil, onechar.toString());
|
||||
peek = 1;
|
||||
}
|
||||
getnl();
|
||||
indent_puts();
|
||||
fprintf(outfil,"\n");
|
||||
s_flg = 1;
|
||||
if(c_level < s_level[level])
|
||||
if(level > 0) level--;
|
||||
if(ind[level] != 0)
|
||||
{
|
||||
tabs -= p_flg[level];
|
||||
p_flg[level] = 0;
|
||||
ind[level] = 0;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
string[j++] = c;
|
||||
cc = getchr();
|
||||
while(cc != c)
|
||||
{
|
||||
// max. length of line should be 256
|
||||
string[j++] = cc;
|
||||
|
||||
if(cc == '\\')
|
||||
{
|
||||
cc = string[j++] = getchr();
|
||||
}
|
||||
if(cc == '\n')
|
||||
{
|
||||
lineNumber++;
|
||||
indent_puts();
|
||||
s_flg = 1;
|
||||
}
|
||||
cc = getchr();
|
||||
|
||||
}
|
||||
string[j++] = cc;
|
||||
if(getnl() == 1)
|
||||
{
|
||||
l_char = cc;
|
||||
peek = 1;
|
||||
peekc = '\n';
|
||||
}
|
||||
break;
|
||||
case ';':
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
if(p_flg[level] > 0 && ind[level] == 0)
|
||||
{
|
||||
tabs -= p_flg[level];
|
||||
p_flg[level] = 0;
|
||||
}
|
||||
getnl();
|
||||
indent_puts();
|
||||
fprintf(outfil,"\n");
|
||||
s_flg = 1;
|
||||
if(if_lev > 0)
|
||||
if(if_flg == 1)
|
||||
{
|
||||
if_lev--;
|
||||
if_flg = 0;
|
||||
}
|
||||
else if_lev = 0;
|
||||
break;
|
||||
case '\\':
|
||||
string[j++] = c;
|
||||
string[j++] = getchr();
|
||||
break;
|
||||
case '?':
|
||||
q_flg = 1;
|
||||
string[j++] = c;
|
||||
break;
|
||||
case ':':
|
||||
string[j++] = c;
|
||||
peekc = getchr();
|
||||
if(peekc == ':')
|
||||
{
|
||||
indent_puts();
|
||||
fprintf (outfil,":");
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int double_colon = 0;
|
||||
peek = 1;
|
||||
}
|
||||
|
||||
if(q_flg == 1)
|
||||
{
|
||||
q_flg = 0;
|
||||
break;
|
||||
}
|
||||
if(lookup(w_ds) == 0 && lookup(w_case) == 0)
|
||||
{
|
||||
s_flg = 0;
|
||||
indent_puts();
|
||||
}
|
||||
else
|
||||
{
|
||||
tabs--;
|
||||
indent_puts();
|
||||
tabs++;
|
||||
}
|
||||
peekc = getchr();
|
||||
if(peekc == ';')
|
||||
{
|
||||
fprintf(outfil,";");
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
}
|
||||
else
|
||||
{
|
||||
peek = 1;
|
||||
}
|
||||
getnl();
|
||||
indent_puts();
|
||||
fprintf(outfil,"\n");
|
||||
s_flg = 1;
|
||||
break;
|
||||
|
||||
case '/':
|
||||
c0 = string[j];
|
||||
string[j++] = c;
|
||||
peekc = getchr();
|
||||
|
||||
if(peekc == '/')
|
||||
{
|
||||
string[j++] = peekc;
|
||||
peekc = '`';
|
||||
peek = -1;
|
||||
cpp_comment();
|
||||
fprintf(outfil,"\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
peek = 1;
|
||||
}
|
||||
|
||||
if(peekc != '*') {
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (j > 0) string[j--] = '\0';
|
||||
if (j > 0) indent_puts();
|
||||
string[j++] = '/';
|
||||
string[j++] = '*';
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
comment();
|
||||
break;
|
||||
}
|
||||
case '#':
|
||||
string[j++] = c;
|
||||
cc = getchr();
|
||||
while(cc != '\n')
|
||||
{
|
||||
string[j++] = cc;
|
||||
cc = getchr();
|
||||
}
|
||||
string[j++] = cc;
|
||||
s_flg = 0;
|
||||
indent_puts();
|
||||
s_flg = 1;
|
||||
break;
|
||||
case ')':
|
||||
paren--;
|
||||
if (paren < 0)
|
||||
{
|
||||
EOF = 1;
|
||||
}
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
if(getnl() == 1)
|
||||
{
|
||||
peekc = '\n';
|
||||
peek = 1;
|
||||
if(paren != 0)
|
||||
{
|
||||
a_flg = 1;
|
||||
}
|
||||
else if(tabs > 0)
|
||||
{
|
||||
p_flg[level]++;
|
||||
tabs++;
|
||||
ind[level] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
string[j++] = c;
|
||||
paren++;
|
||||
if ((lookup(w_for) == 1))
|
||||
{
|
||||
c = get_string();
|
||||
while(c != ';') c = get_string();
|
||||
ct=0;
|
||||
int for_done = 0;
|
||||
while (for_done==0)
|
||||
{
|
||||
c = get_string();
|
||||
while(c != ')')
|
||||
{
|
||||
if(c == '(') ct++;
|
||||
c = get_string();
|
||||
}
|
||||
if(ct != 0)
|
||||
{
|
||||
ct--;
|
||||
}
|
||||
else for_done = 1;
|
||||
} /* endwhile for_done */
|
||||
paren--;
|
||||
if (paren < 0)
|
||||
{
|
||||
EOF = 1;
|
||||
}
|
||||
indent_puts();
|
||||
if(getnl() == 1)
|
||||
{
|
||||
peekc = '\n';
|
||||
peek = 1;
|
||||
p_flg[level]++;
|
||||
tabs++;
|
||||
ind[level] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(lookup(w_if_) == 1)
|
||||
{
|
||||
indent_puts();
|
||||
s_tabs[c_level][if_lev] = tabs;
|
||||
sp_flg[c_level][if_lev] = p_flg[level];
|
||||
s_ind[c_level][if_lev] = ind[level];
|
||||
if_lev++;
|
||||
if_flg = 1;
|
||||
}
|
||||
} /* end switch */
|
||||
|
||||
String j_string = new String(string);
|
||||
|
||||
} // end while not EOF
|
||||
|
||||
//formattedText = strOut.toString();
|
||||
|
||||
// save current (rough) selection point
|
||||
int selectionEnd = editor.textarea.getSelectionEnd();
|
||||
|
||||
// make sure the caret would be past the end of the text
|
||||
if (strOut.length() < selectionEnd - 1) {
|
||||
selectionEnd = strOut.length() - 1;
|
||||
}
|
||||
|
||||
// replace with new bootiful text
|
||||
// selectionEnd hopefully at least in the neighborhood
|
||||
editor.setText(strOut.toString(), selectionEnd, selectionEnd);
|
||||
|
||||
editor.sketch.setModified();
|
||||
|
||||
bin.close(); // close buff
|
||||
|
||||
} catch (IOException ioe) {
|
||||
editor.error(ioe);
|
||||
//ioe.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
// () {} check
|
||||
|
||||
String ck_paren = new String("left");
|
||||
if (paren < 0) ck_paren = "right";
|
||||
|
||||
if (paren != 0) {
|
||||
setUhOh("Uh oh... too many " + ck_paren + " parentheses.");
|
||||
|
||||
} else { // check braces only if parens are ok
|
||||
ck_paren = "left";
|
||||
if (c_level < 0) {
|
||||
ck_paren = "right";
|
||||
} else if (c_level != 0) {
|
||||
setUhOh("Uh oh... too many " + ck_paren + " curled braces.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* throw back the stuff to the editor */
|
||||
public String getFormattedText()
|
||||
{
|
||||
return formattedText;
|
||||
}
|
||||
|
||||
|
||||
/* special edition of put string for comment processing */
|
||||
public void putcoms()
|
||||
{
|
||||
@ -793,26 +211,30 @@ public class AutoFormat {
|
||||
{
|
||||
if ((last_char != ';') && (sav_s_flg==1) )
|
||||
{
|
||||
fprintf(outfil, strBuffer.substring(i,j));
|
||||
//fprintf(outfil, strBuffer.substring(i,j));
|
||||
fprintf(strBuffer.substring(i,j));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(outfil, strBuffer);
|
||||
//fprintf(outfil, strBuffer);
|
||||
fprintf(strBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string[i]=='*' || jdoc == 0)
|
||||
fprintf (outfil, " "+strBuffer.substring(i,j));
|
||||
//fprintf (outfil, " "+strBuffer.substring(i,j));
|
||||
fprintf (" "+strBuffer.substring(i,j));
|
||||
else
|
||||
fprintf (outfil, " * "+strBuffer.substring(i,j));
|
||||
//fprintf (outfil, " * "+strBuffer.substring(i,j));
|
||||
fprintf (" * "+strBuffer.substring(i,j));
|
||||
}
|
||||
j = 0;
|
||||
string[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
public void cpp_comment()
|
||||
public void cpp_comment() throws IOException
|
||||
{
|
||||
c = getchr();
|
||||
while(c != '\n' && c != '\r' && j<133)
|
||||
@ -842,7 +264,7 @@ public class AutoFormat {
|
||||
}
|
||||
|
||||
|
||||
public char getchr()
|
||||
public char getchr() throws IOException
|
||||
{
|
||||
if((peek < 0) && (last_char != ' ') && (last_char != '\t'))
|
||||
{
|
||||
@ -862,8 +284,8 @@ public class AutoFormat {
|
||||
for (int ib=0; ib<nBytesRead; ib++) bArray[ib] = '\0';
|
||||
|
||||
lineLength = nBytesRead = 0;
|
||||
try /* to get the next block */
|
||||
{
|
||||
//try /* to get the next block */
|
||||
//{
|
||||
if (bin.available() > 0)
|
||||
{
|
||||
nBytesRead = bin.read(bArray);
|
||||
@ -876,14 +298,15 @@ public class AutoFormat {
|
||||
}
|
||||
else
|
||||
{
|
||||
//System.out.println("eof a");
|
||||
EOF = 1;
|
||||
peekc = '\0';
|
||||
}
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
System.out.println(ioe.toString());
|
||||
}
|
||||
//}
|
||||
//catch(IOException ioe)
|
||||
//{
|
||||
//System.out.println(ioe.toString());
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -909,13 +332,14 @@ public class AutoFormat {
|
||||
}
|
||||
|
||||
/* read to new_line */
|
||||
public int getnl()
|
||||
public int getnl() throws IOException
|
||||
{
|
||||
int save_s_flg;
|
||||
save_s_flg = tabs;
|
||||
peekc = getchr();
|
||||
while(peekc == '\t' || peekc == ' ')
|
||||
{
|
||||
//while ((peekc == '\t' || peekc == ' ') &&
|
||||
// (j < string.length)) {
|
||||
while (peekc == '\t' || peekc == ' ') {
|
||||
string[j++] = peekc;
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
@ -1008,4 +432,512 @@ public class AutoFormat {
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
public void show() {
|
||||
StringBuffer onechar;
|
||||
|
||||
String originalText = editor.textarea.getText();
|
||||
strOut = new StringBuffer();
|
||||
indentValue = Preferences.getInteger("editor.tabs.size");
|
||||
indentChar = new String(" ");
|
||||
|
||||
lineNumber = 0;
|
||||
//BLOCK_MAXLEN = 256;
|
||||
c_level = if_lev = level = e_flg = paren = 0;
|
||||
a_flg = q_flg = j = b_flg = tabs = 0;
|
||||
if_flg = peek = -1;
|
||||
peekc = '`';
|
||||
s_flg = 1;
|
||||
bblank = ' ';
|
||||
jdoc = 0;
|
||||
|
||||
s_level = new int[10];
|
||||
sp_flg = new int[20][10];
|
||||
s_ind = new int[20][10];
|
||||
s_if_lev = new int[10];
|
||||
s_if_flg = new int[10];
|
||||
ind = new int[10];
|
||||
p_flg = new int[10];
|
||||
s_tabs = new int[20][10];
|
||||
|
||||
w_else = new String ("else");
|
||||
w_if_ = new String ("if");
|
||||
w_for = new String ("for");
|
||||
w_ds = new String ("default");
|
||||
w_case = new String ("case");
|
||||
w_cpp_comment = new String ("//");
|
||||
w_jdoc = new String ("/**");
|
||||
line_feed = new String ("\n");
|
||||
|
||||
// read as long as there is something to read
|
||||
EOF = 0; // = 1 set in getchr when EOF
|
||||
|
||||
bArray = new byte[BLOCK_MAXLEN];
|
||||
string = new char[BLOCK_MAXLEN];
|
||||
try { // the whole process
|
||||
// open for input
|
||||
ByteArrayInputStream in =
|
||||
new ByteArrayInputStream(originalText.getBytes());
|
||||
|
||||
// add buffering to that InputStream
|
||||
bin = new BufferedInputStream(in);
|
||||
|
||||
for (int ib = 0; ib < BLOCK_MAXLEN; ib++) bArray[ib] = '\0';
|
||||
|
||||
lineLength = nBytesRead = 0;
|
||||
// read up a block - remember how many bytes read
|
||||
nBytesRead = bin.read(bArray);
|
||||
strBlock = new String(bArray);
|
||||
|
||||
lineLength = nBytesRead;
|
||||
lineNumber = 1;
|
||||
indexBlock = -1;
|
||||
j = 0;
|
||||
while (EOF == 0)
|
||||
{
|
||||
c = getchr();
|
||||
switch(c)
|
||||
{
|
||||
default:
|
||||
string[j++] = c;
|
||||
if(c != ',')
|
||||
{
|
||||
l_char = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
if(lookup(w_else) == 1)
|
||||
{
|
||||
gotelse();
|
||||
if(s_flg == 0 || j > 0)string[j++] = c;
|
||||
indent_puts();
|
||||
s_flg = 0;
|
||||
break;
|
||||
}
|
||||
if(s_flg == 0 || j > 0)string[j++] = c;
|
||||
break;
|
||||
|
||||
case '\r': // <CR> for MS Windows 95
|
||||
case '\n':
|
||||
lineNumber++;
|
||||
if (EOF==1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
String j_string = new String(string);
|
||||
|
||||
e_flg = lookup(w_else);
|
||||
if(e_flg == 1) gotelse();
|
||||
if (lookup_com(w_cpp_comment) == 1)
|
||||
{
|
||||
if (string[j] == '\n')
|
||||
{
|
||||
string[j] = '\0';
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
indent_puts();
|
||||
//fprintf(outfil, line_feed);
|
||||
fprintf(line_feed);
|
||||
s_flg = 1;
|
||||
if(e_flg == 1)
|
||||
{
|
||||
p_flg[level]++;
|
||||
tabs++;
|
||||
}
|
||||
else
|
||||
if(p_char == l_char)
|
||||
{
|
||||
a_flg = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '{':
|
||||
if(lookup(w_else) == 1)gotelse();
|
||||
s_if_lev[c_level] = if_lev;
|
||||
s_if_flg[c_level] = if_flg;
|
||||
if_lev = if_flg = 0;
|
||||
c_level++;
|
||||
if(s_flg == 1 && p_flg[level] != 0)
|
||||
{
|
||||
p_flg[level]--;
|
||||
tabs--;
|
||||
}
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
getnl() ;
|
||||
indent_puts();
|
||||
//fprintf(outfil,"\n");
|
||||
fprintf("\n");
|
||||
tabs++;
|
||||
s_flg = 1;
|
||||
if(p_flg[level] > 0)
|
||||
{
|
||||
ind[level] = 1;
|
||||
level++;
|
||||
s_level[level] = c_level;
|
||||
}
|
||||
break;
|
||||
|
||||
case '}':
|
||||
c_level--;
|
||||
if (c_level < 0)
|
||||
{
|
||||
EOF = 1;
|
||||
//System.out.println("eof b");
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
break;
|
||||
}
|
||||
if ((if_lev = s_if_lev[c_level]-1) < 0)
|
||||
if_lev = 0;
|
||||
if_flg = s_if_flg[c_level];
|
||||
indent_puts();
|
||||
tabs--;
|
||||
p_tabs();
|
||||
peekc = getchr();
|
||||
if( peekc == ';')
|
||||
{
|
||||
onechar = new StringBuffer();
|
||||
onechar.append(c); // the }
|
||||
onechar.append(';');
|
||||
//fprintf(outfil, onechar.toString());
|
||||
fprintf(onechar.toString());
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
}
|
||||
else
|
||||
{
|
||||
onechar = new StringBuffer();
|
||||
onechar.append(c);
|
||||
//fprintf(outfil, onechar.toString());
|
||||
fprintf(onechar.toString());
|
||||
peek = 1;
|
||||
}
|
||||
getnl();
|
||||
indent_puts();
|
||||
//fprintf(outfil,"\n");
|
||||
fprintf("\n");
|
||||
s_flg = 1;
|
||||
if(c_level < s_level[level])
|
||||
if(level > 0) level--;
|
||||
if(ind[level] != 0)
|
||||
{
|
||||
tabs -= p_flg[level];
|
||||
p_flg[level] = 0;
|
||||
ind[level] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
string[j++] = c;
|
||||
cc = getchr();
|
||||
while(cc != c)
|
||||
{
|
||||
// max. length of line should be 256
|
||||
string[j++] = cc;
|
||||
|
||||
if(cc == '\\')
|
||||
{
|
||||
cc = string[j++] = getchr();
|
||||
}
|
||||
if(cc == '\n')
|
||||
{
|
||||
lineNumber++;
|
||||
indent_puts();
|
||||
s_flg = 1;
|
||||
}
|
||||
cc = getchr();
|
||||
|
||||
}
|
||||
string[j++] = cc;
|
||||
if(getnl() == 1)
|
||||
{
|
||||
l_char = cc;
|
||||
peek = 1;
|
||||
peekc = '\n';
|
||||
}
|
||||
break;
|
||||
|
||||
case ';':
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
if(p_flg[level] > 0 && ind[level] == 0)
|
||||
{
|
||||
tabs -= p_flg[level];
|
||||
p_flg[level] = 0;
|
||||
}
|
||||
getnl();
|
||||
indent_puts();
|
||||
//fprintf(outfil,"\n");
|
||||
fprintf("\n");
|
||||
s_flg = 1;
|
||||
if(if_lev > 0)
|
||||
if(if_flg == 1)
|
||||
{
|
||||
if_lev--;
|
||||
if_flg = 0;
|
||||
}
|
||||
else if_lev = 0;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
string[j++] = c;
|
||||
string[j++] = getchr();
|
||||
break;
|
||||
|
||||
case '?':
|
||||
q_flg = 1;
|
||||
string[j++] = c;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
string[j++] = c;
|
||||
peekc = getchr();
|
||||
if(peekc == ':')
|
||||
{
|
||||
indent_puts();
|
||||
//fprintf (outfil,":");
|
||||
fprintf(":");
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int double_colon = 0;
|
||||
peek = 1;
|
||||
}
|
||||
|
||||
if(q_flg == 1)
|
||||
{
|
||||
q_flg = 0;
|
||||
break;
|
||||
}
|
||||
if(lookup(w_ds) == 0 && lookup(w_case) == 0)
|
||||
{
|
||||
s_flg = 0;
|
||||
indent_puts();
|
||||
}
|
||||
else
|
||||
{
|
||||
tabs--;
|
||||
indent_puts();
|
||||
tabs++;
|
||||
}
|
||||
peekc = getchr();
|
||||
if(peekc == ';')
|
||||
{
|
||||
//fprintf(outfil,";");
|
||||
fprintf(";");
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
}
|
||||
else
|
||||
{
|
||||
peek = 1;
|
||||
}
|
||||
getnl();
|
||||
indent_puts();
|
||||
//fprintf(outfil,"\n");
|
||||
fprintf("\n");
|
||||
s_flg = 1;
|
||||
break;
|
||||
|
||||
case '/':
|
||||
c0 = string[j];
|
||||
string[j++] = c;
|
||||
peekc = getchr();
|
||||
|
||||
if(peekc == '/')
|
||||
{
|
||||
string[j++] = peekc;
|
||||
peekc = '`';
|
||||
peek = -1;
|
||||
cpp_comment();
|
||||
//fprintf(outfil,"\n");
|
||||
fprintf("\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
peek = 1;
|
||||
}
|
||||
|
||||
if(peekc != '*') {
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (j > 0) string[j--] = '\0';
|
||||
if (j > 0) indent_puts();
|
||||
string[j++] = '/';
|
||||
string[j++] = '*';
|
||||
peek = -1;
|
||||
peekc = '`';
|
||||
comment();
|
||||
break;
|
||||
}
|
||||
|
||||
case '#':
|
||||
string[j++] = c;
|
||||
cc = getchr();
|
||||
while(cc != '\n')
|
||||
{
|
||||
string[j++] = cc;
|
||||
cc = getchr();
|
||||
}
|
||||
string[j++] = cc;
|
||||
s_flg = 0;
|
||||
indent_puts();
|
||||
s_flg = 1;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
paren--;
|
||||
if (paren < 0)
|
||||
{
|
||||
EOF = 1;
|
||||
//System.out.println("eof c");
|
||||
}
|
||||
string[j++] = c;
|
||||
indent_puts();
|
||||
if(getnl() == 1)
|
||||
{
|
||||
peekc = '\n';
|
||||
peek = 1;
|
||||
if(paren != 0)
|
||||
{
|
||||
a_flg = 1;
|
||||
}
|
||||
else if(tabs > 0)
|
||||
{
|
||||
p_flg[level]++;
|
||||
tabs++;
|
||||
ind[level] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
string[j++] = c;
|
||||
paren++;
|
||||
if ((lookup(w_for) == 1))
|
||||
{
|
||||
c = get_string();
|
||||
while(c != ';') c = get_string();
|
||||
ct=0;
|
||||
int for_done = 0;
|
||||
while (for_done==0)
|
||||
{
|
||||
c = get_string();
|
||||
while(c != ')')
|
||||
{
|
||||
if(c == '(') ct++;
|
||||
c = get_string();
|
||||
}
|
||||
if(ct != 0)
|
||||
{
|
||||
ct--;
|
||||
}
|
||||
else for_done = 1;
|
||||
} // endwhile for_done
|
||||
paren--;
|
||||
if (paren < 0)
|
||||
{
|
||||
EOF = 1;
|
||||
//System.out.println("eof d");
|
||||
}
|
||||
indent_puts();
|
||||
if(getnl() == 1)
|
||||
{
|
||||
peekc = '\n';
|
||||
peek = 1;
|
||||
p_flg[level]++;
|
||||
tabs++;
|
||||
ind[level] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(lookup(w_if_) == 1)
|
||||
{
|
||||
indent_puts();
|
||||
s_tabs[c_level][if_lev] = tabs;
|
||||
sp_flg[c_level][if_lev] = p_flg[level];
|
||||
s_ind[c_level][if_lev] = ind[level];
|
||||
if_lev++;
|
||||
if_flg = 1;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
//System.out.println("string len is " + string.length);
|
||||
//if (EOF == 1) System.out.println(string);
|
||||
String j_string = new String(string);
|
||||
|
||||
} // end while not EOF
|
||||
|
||||
/*
|
||||
int bad;
|
||||
while ((bad = bin.read()) != -1) {
|
||||
System.out.print((char) bad);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
char bad;
|
||||
//while ((bad = getchr()) != 0) {
|
||||
while (true) {
|
||||
getchr();
|
||||
if (peek != -1) {
|
||||
System.out.print(last_char);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// save current (rough) selection point
|
||||
int selectionEnd = editor.textarea.getSelectionEnd();
|
||||
|
||||
// make sure the caret would be past the end of the text
|
||||
if (strOut.length() < selectionEnd - 1) {
|
||||
selectionEnd = strOut.length() - 1;
|
||||
}
|
||||
|
||||
bin.close(); // close buff
|
||||
|
||||
String formattedText = strOut.toString();
|
||||
if (formattedText.equals(originalText)) {
|
||||
editor.message("No changes necessary for Auto Format.");
|
||||
|
||||
} else {
|
||||
// replace with new bootiful text
|
||||
// selectionEnd hopefully at least in the neighborhood
|
||||
editor.setText(formattedText, selectionEnd, selectionEnd);
|
||||
editor.sketch.setModified(true);
|
||||
|
||||
// warn user if there are too many parens in either direction
|
||||
if (paren != 0) {
|
||||
editor.error("Warning: Too many " +
|
||||
((paren < 0) ? "right" : "left") +
|
||||
" parentheses.");
|
||||
|
||||
} else if (c_level != 0) { // check braces only if parens are ok
|
||||
editor.error("Warning: Too many " +
|
||||
((c_level < 0) ? "right" : "left") +
|
||||
" curly braces.");
|
||||
} else {
|
||||
editor.message("Auto Format finished.");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
editor.error(e);
|
||||
}
|
||||
}
|
||||
}
|
120
app/tools/ExportFolder.java
Executable file
120
app/tools/ExportFolder.java
Executable file
@ -0,0 +1,120 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
ExportFolder - tool to export all sketches within a certain folder
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2005-06 Ben Fry and Casey Reas
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.app.tools;
|
||||
|
||||
import processing.app.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
public class ExportFolder {
|
||||
Editor editor;
|
||||
static JFileChooser fc;
|
||||
|
||||
|
||||
public ExportFolder(Editor editor) {
|
||||
this.editor = editor;
|
||||
|
||||
if (fc == null) {
|
||||
fc = new JFileChooser();
|
||||
fc.setSelectedFile(new File(Sketchbook.getSketchbookPath()));
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void show() {
|
||||
if (fc.showOpenDialog(new JDialog()) != JFileChooser.APPROVE_OPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
File folder = fc.getSelectedFile();
|
||||
// export everything under this folder
|
||||
|
||||
Vector sketches = new Vector();
|
||||
try {
|
||||
addSketches(sketches, folder);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
boolean success = true;
|
||||
int counter = 0;
|
||||
|
||||
try {
|
||||
// iterate through the list
|
||||
Enumeration en = sketches.elements();
|
||||
while (en.hasMoreElements()) {
|
||||
editor.message("Exporting sketch " + (++counter) +
|
||||
" of " + sketches.size());
|
||||
String path = (String) en.nextElement();
|
||||
editor.handleOpen(path);
|
||||
// success may not be that useful, usually an ex is thrown
|
||||
success = editor.sketch.exportApplet(new Target(
|
||||
System.getProperty("user.dir") + File.separator + "lib" +
|
||||
File.separator + "targets", Preferences.get("build.target")));
|
||||
if (!success) break;
|
||||
//System.out.println("success was " + success);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
editor.error(e);
|
||||
success = false;
|
||||
//e.printStackTrace();
|
||||
}
|
||||
|
||||
if (success) {
|
||||
editor.message("Done exporting.");
|
||||
} // else the error message will be visible
|
||||
}
|
||||
|
||||
|
||||
protected void addSketches(Vector sketches, File folder) throws IOException {
|
||||
|
||||
// skip .DS_Store files, etc
|
||||
if (!folder.isDirectory()) return; // false;
|
||||
|
||||
String list[] = folder.list();
|
||||
// if a bad folder or something like that, this might come back null
|
||||
if (list == null) return; // false;
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (list[i].charAt(0) == '.') continue;
|
||||
|
||||
File subfolder = new File(folder, list[i]);
|
||||
File entry = new File(subfolder, list[i] + ".pde");
|
||||
// if a .pde file of the same prefix as the folder exists..
|
||||
if (entry.exists()) {
|
||||
sketches.add(entry.getAbsolutePath());
|
||||
|
||||
} else if (subfolder.isDirectory()) { // only follow if a dir
|
||||
addSketches(sketches, subfolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -219,6 +219,10 @@
|
||||
33AF61B30965C54B00B514A9 /* WTreeParser.java in Sources */ = {isa = PBXBuildFile; fileRef = 33FFFE520965BD110016AC38 /* WTreeParser.java */; };
|
||||
33AF61B40965C54B00B514A9 /* JEditTextArea.java in Sources */ = {isa = PBXBuildFile; fileRef = 33FFFE630965BD110016AC38 /* JEditTextArea.java */; };
|
||||
33AF61B50965C54B00B514A9 /* Base.java in Sources */ = {isa = PBXBuildFile; fileRef = 33FFFE240965BD100016AC38 /* Base.java */; };
|
||||
33BEDDB109D6DC1300430D5B /* Library.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDAF09D6DC1300430D5B /* Library.java */; };
|
||||
33BEDDB209D6DC1300430D5B /* LibraryManager.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDB009D6DC1300430D5B /* LibraryManager.java */; };
|
||||
33BEDDD509D6E8D800430D5B /* Archiver.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDD309D6E8D800430D5B /* Archiver.java */; };
|
||||
33BEDDD609D6E8D800430D5B /* ExportFolder.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDD409D6E8D800430D5B /* ExportFolder.java */; };
|
||||
33CF03B209662CB700F2C9A9 /* arduino.icns in Resources */ = {isa = PBXBuildFile; fileRef = 33CF03B009662CA800F2C9A9 /* arduino.icns */; };
|
||||
33CF03CC09662DC000F2C9A9 /* mrj.jar in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33AF620C0965D67900B514A9 /* mrj.jar */; settings = {JAVA_ARCHIVE_SUBDIR = ../shared/lib; }; };
|
||||
33CF03CD09662DC000F2C9A9 /* RXTXcomm.jar in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33AF620F0965D67A00B514A9 /* RXTXcomm.jar */; settings = {JAVA_ARCHIVE_SUBDIR = ../shared/lib; }; };
|
||||
@ -371,6 +375,10 @@
|
||||
33AF620D0965D67900B514A9 /* oro.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = oro.jar; sourceTree = "<group>"; };
|
||||
33AF620E0965D67A00B514A9 /* registry.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = registry.jar; sourceTree = "<group>"; };
|
||||
33AF620F0965D67A00B514A9 /* RXTXcomm.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = RXTXcomm.jar; sourceTree = "<group>"; };
|
||||
33BEDDAF09D6DC1300430D5B /* Library.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = Library.java; sourceTree = "<group>"; };
|
||||
33BEDDB009D6DC1300430D5B /* LibraryManager.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = LibraryManager.java; sourceTree = "<group>"; };
|
||||
33BEDDD309D6E8D800430D5B /* Archiver.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = Archiver.java; sourceTree = "<group>"; };
|
||||
33BEDDD409D6E8D800430D5B /* ExportFolder.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = ExportFolder.java; sourceTree = "<group>"; };
|
||||
33CF03B009662CA800F2C9A9 /* arduino.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = arduino.icns; path = dist/arduino.icns; sourceTree = "<group>"; };
|
||||
33DD8FB6096AC8DA0013AF8F /* Arduino.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Arduino.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33FF01DC0965BD160016AC38 /* examples.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = examples.zip; sourceTree = "<group>"; };
|
||||
@ -738,6 +746,8 @@
|
||||
33FFFE220965BD100016AC38 /* app */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
33BEDDAF09D6DC1300430D5B /* Library.java */,
|
||||
33BEDDB009D6DC1300430D5B /* LibraryManager.java */,
|
||||
33FFFE240965BD100016AC38 /* Base.java */,
|
||||
33FFFE260965BD100016AC38 /* Compiler.java */,
|
||||
33FFFE270965BD100016AC38 /* Editor.java */,
|
||||
@ -847,6 +857,8 @@
|
||||
33FFFE710965BD110016AC38 /* tools */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
33BEDDD309D6E8D800430D5B /* Archiver.java */,
|
||||
33BEDDD409D6E8D800430D5B /* ExportFolder.java */,
|
||||
33FFFE720965BD110016AC38 /* AutoFormat.java */,
|
||||
);
|
||||
path = tools;
|
||||
@ -1126,6 +1138,10 @@
|
||||
33AF61B40965C54B00B514A9 /* JEditTextArea.java in Sources */,
|
||||
33AF61B50965C54B00B514A9 /* Base.java in Sources */,
|
||||
332D4DB609CF147F00BF81F6 /* Sizer.java in Sources */,
|
||||
33BEDDB109D6DC1300430D5B /* Library.java in Sources */,
|
||||
33BEDDB209D6DC1300430D5B /* LibraryManager.java in Sources */,
|
||||
33BEDDD509D6E8D800430D5B /* Archiver.java in Sources */,
|
||||
33BEDDD609D6E8D800430D5B /* ExportFolder.java in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -53,8 +53,13 @@ PWM now working on pin 11 (in addition to pins 9 and 10).
|
||||
Slowed PWM frequency (on all three PWM pins) to 1KHz.
|
||||
Now give an error if compiled sketch is too big.
|
||||
Fixed abs(), min(), max(), and constrain() macros.
|
||||
Added menu items to the IDE to burn bootloader.
|
||||
Now display binary sketch size on upload, and give error if too big.
|
||||
Added C++ serial library.
|
||||
Resynced with Processing/Wiring IDE code (improved auto-format, faster logging
|
||||
to serial monitor console, other bug fixes)
|
||||
|
||||
0003
|
||||
0003 - 2006.01.16
|
||||
|
||||
API Changes
|
||||
Reversed the analog input pins to correspond to newer boards. This means
|
||||
|
Loading…
x
Reference in New Issue
Block a user