#ifdef EDITOR import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; import java.util.zip.*; // play, stop, open, save, courseware, print, beautify // height of button panel is 35 public class PdeEditor extends Panel implements PdeEnvironment { static final String DEFAULT_PROGRAM = "// type program here\n"; // otherwise, if the window is resized with the message label // set to blank, it's preferredSize() will be fukered static final String EMPTY = " "; PdeApplet app; PdeEditorButtons buttons; //PdeGraphics graphics; PdeRunner runner; Frame frame; Window fullScreenWindow; Label status; TextArea textarea; String lastDirectory; String lastFile; boolean playing; public PdeEditor(PdeApplet app, String program) { this.app = app; setLayout(new BorderLayout()); Color bgColor = PdeApplet.getColor("bg_color", new Color(51, 102, 153)); Color bgStippleColor = PdeApplet.getColor("bg_stipple_color", null); Color tickColor = PdeApplet.getColor("tick_color", new Color(204, 204, 204)); Color gutterBgColor = PdeApplet.getColor("gutter_bg_color", new Color(0, 51, 102)); Color buttonBgColor = PdeApplet.getColor("button_bg_color", new Color(153, 153, 153)); Color statusBgColor = PdeApplet.getColor("status_bg_color", new Color(204, 204, 204)); //int gwidth = PdeApplet.getInteger("graphics_width", 101); //int gheight = PdeApplet.getInteger("graphics_height", 101); //add("North", new PdeEditorLicensePlate()); //Panel left = new Panel(); //left.setLayout(new BorderLayout()); Panel top = new Panel(); top.setBackground(buttonBgColor); top.setLayout(new BorderLayout()); //boolean privileges = PdeApplet.hasFullPrivileges(); //boolean courseware = PdeApplet.get("save_as") != null; buttons = new PdeEditorButtons(this); //, privileges, courseware, //(privileges & !courseware), false); buttons.setBackground(buttonBgColor); //add("North", buttons); //top.add("North", buttons); top.add("West", buttons); Label buttonStatus = new Label(PdeEditorButtons.EMPTY_STATUS, Label.RIGHT); buttonStatus.setBackground(buttonBgColor); top.add("East", buttonStatus); buttons.status = buttonStatus; /* graphics = new PdeGraphics(gwidth, gheight, bgColor); #ifndef OPENGL graphics = new PdeEditorGraphics(gwidth, gheight, tickColor, bgColor, bgStippleColor, this); #else if (PdeApplet.getBoolean("graphics_3D", false)) { graphics = new PdeEditorGraphics3D(gwidth, gheight, tickColor, bgColor, bgStippleColor, this); } else { graphics = new PdeEditorGraphics(gwidth, gheight, tickColor, bgColor, bgStippleColor, this); } #endif */ //left.add("Center", graphics); //left.setBackground(gutterBgColor); //Panel right = new Panel(); //right.setLayout(new BorderLayout()); Panel statusPanel = new Panel(); statusPanel.setBackground(statusBgColor); statusPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); statusPanel.add(status = new Label(EMPTY)); //right.add("North", statusPanel); top.add("South", statusPanel); add("North", top); if (program == null) program = DEFAULT_PROGRAM; textarea = new TextArea(program, 20, 48, TextArea.SCROLLBARS_VERTICAL_ONLY ); textarea.setFont(PdeApplet.getFont("editor")); //right.add("Center", textarea); add("Center", textarea); /* TextArea console = new TextArea("welcome to pr0[3551ng", 5, 48, TextArea.SCROLLBARS_VERTICAL_ONLY); console.setBackground(Color.gray); console.setFont(PdeApplet.getFont("editor")); add("South", console); */ if (!PdeApplet.isMacintosh()) { // this still relevant? PdeEditorListener listener = new PdeEditorListener(); textarea.addKeyListener(listener); textarea.addFocusListener(listener); textarea.addKeyListener(new PdeKeyListener(this)); } runner = new PdeRunner(this); } public void doPlay() { //doStop(); doClose(); playing = true; buttons.play(); runner.setProgram(textarea.getText()); runner.start(); // required so that key events go to the panel and works //graphics.requestFocus(); // removed for pde } #ifdef RECORDER public void doRecord() { //doStop(); doClose(); PdeRecorder.start(this, graphics.width, graphics.height); doPlay(); } #endif public void doStop() { #ifdef RECORDER if (!playing) return; #endif terminate(); buttons.clear(); playing = false; } public void doClose() { if (playing) { //System.out.println("was playing, will call doStop()"); doStop(); } // some code to close the window here try { // runner.engine is null (runner is not) ((KjcEngine)(runner.engine)).close(); // runner shouldn't be set to null because it gets reused //System.err.println("runner = " + runner); //runner = null; } catch (Exception e) { } buttons.clear(); } public void doOpen() { FileDialog fd = new FileDialog(new Frame(), "Open a PDE program...", FileDialog.LOAD); fd.setDirectory(lastDirectory); //fd.setFile(lastFile); fd.show(); String directory = fd.getDirectory(); String filename = fd.getFile(); if (filename == null) { buttons.clear(); return; // user cancelled } File file = new File(directory, filename); try { FileInputStream input = new FileInputStream(file); int length = (int) file.length(); byte data[] = new byte[length]; int count = 0; while (count != length) { data[count++] = (byte) input.read(); } // set the last dir and file, so that they're // the defaults when you try to save again lastDirectory = directory; lastFile = filename; // once read all the bytes, convert it to the proper // local encoding for this system. //textarea.setText(app.languageEncode(data)); // what the hell was i thinking when i wrote this code if (app.encoding == null) textarea.setText(new String(data)); else textarea.setText(new String(data, app.encoding)); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } buttons.clear(); } public void doSave() { // true if lastfile not set, otherwise false, meaning no prompt handleSave(lastFile == null); } public void doSaveAs() { handleSave(true); } public void handleSave(boolean promptUser) { message("Saving file..."); String s = textarea.getText(); String directory = lastDirectory; String filename = lastFile; if (promptUser) { FileDialog fd = new FileDialog(new Frame(), "Save PDE program as...", FileDialog.SAVE); fd.setDirectory(lastDirectory); fd.setFile(lastFile); fd.show(); directory = fd.getDirectory(); filename = fd.getFile(); if (filename == null) { message(EMPTY); buttons.clear(); return; // user cancelled } } File file = new File(directory, filename); try { FileWriter writer = new FileWriter(file); writer.write(s); writer.flush(); writer.close(); lastDirectory = directory; lastFile = filename; message("Done saving " + filename + "."); } catch (IOException e) { e.printStackTrace(); //message("Did not write file."); message("Could not write " + filename + "."); } buttons.clear(); } public void doExport() { message("Exporting to applet..."); String s = textarea.getText(); FileDialog fd = new FileDialog(new Frame(), "Create applet project named...", FileDialog.SAVE); fd.setDirectory(lastDirectory); fd.setFile(lastFile); fd.show(); String directory = fd.getDirectory(); String projectName = fd.getFile(); if (projectName == null) { // user cancelled message(EMPTY); buttons.clear(); return; } else if (projectName.indexOf(' ') != -1) { // space in filename message("Project name cannot have spaces."); buttons.clear(); return; } //File file = new File(directory, filename); // write java code for applet /* File javaOutputFile = new File(outputDirectory, projectName + ".java"); FileOutputStream fos = new FileOutputStream(javaOutputFile); PrintStream ps = new PrintStream(fos); ps.println("public class " + ps.print(converted); ps.flush(); ps.close(); */ try { String program = textarea.getText(); // create the project directory KjcEngine engine = new KjcEngine(program, this); File projectDir = new File(directory, projectName); projectDir.mkdirs(); engine.writeJava(projectName, false); if (!engine.compileJava()) return; // message() should already hava a message in this case // copy .java to project dir String javaName = projectName + ".java"; copyFile(new File(javaName), new File(projectDir, javaName)); // remove temporary .java and .class files //engine.cleanup(); int wide = 320; int high = 240; int index = program.indexOf("size("); if (index != -1) { try { String str = program.substring(index + 5); int comma = str.indexOf(','); int paren = str.indexOf(')'); wide = Integer.parseInt(str.substring(0, comma).trim()); high = Integer.parseInt(str.substring(comma+1, paren).trim()); } catch (Exception e) { e.printStackTrace(); } } File htmlOutputFile = new File(projectDir, "index.html"); FileOutputStream fos = new FileOutputStream(htmlOutputFile); PrintStream ps = new PrintStream(fos); ps.println(" "); ps.println(); ps.println("


"); ps.println(); ps.print(""); ps.println(""); ps.println(); ps.println("source code"); ps.println(); ps.println("
"); ps.println(" "); ps.flush(); ps.close(); final String classes[] = { "Bagel.class", "BagelConstants.class", "BagelFont.class", "BagelImage.class", "BagelLight.class", "BagelPolygon.class", "ProcessingApplet.class" }; // create new .jar file FileOutputStream zipOutputFile = new FileOutputStream(new File(projectDir, projectName + ".jar")); ZipOutputStream zos = new ZipOutputStream(zipOutputFile); ZipEntry entry; // add standard .class files to the jar for (int i = 0; i < classes.length; i++) { //System.out.println("adding class " + (i+1) + " of " + classes.length); entry = new ZipEntry(classes[i]); zos.putNextEntry(entry); zos.write(grabFile(new File("lib" + File.separator + "export" + File.separator + classes[i]))); zos.closeEntry(); } // add the project's .class to the jar //System.out.println("adding " + projectName + ".class"); entry = new ZipEntry(projectName + ".class"); zos.putNextEntry(entry); zos.write(grabFile(new File("lib", projectName + ".class"))); zos.closeEntry(); // close up the jar file zos.flush(); zos.close(); //zipOutputFile.close(); engine.cleanup(); message("Done exporting."); } catch (Exception e) { message("Error during export."); e.printStackTrace(); } buttons.clear(); } static protected byte[] grabFile(File file) throws IOException { int size = (int) file.length(); FileInputStream input = new FileInputStream(file); byte buffer[] = new byte[size]; int offset = 0; int bytesRead; while ((bytesRead = input.read(buffer, offset, size-offset)) != -1) { offset += bytesRead; //System.out.println(offset + " " + bytesRead); if (bytesRead == 0) break; } //System.out.println("done grabbing file"); return buffer; } static protected void copyFile(File afile, File bfile) { try { FileInputStream from = new FileInputStream(afile); FileOutputStream to = new FileOutputStream(bfile); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = from.read(buffer)) != -1) { to.write(buffer, 0, bytesRead); } } catch (IOException e) { e.printStackTrace(); } } public void doSnapshot() { /* //dbcp.msg("Sending your file to the server..."); message("Sending your file to the server..."); try { String programStr = textarea.getText(); //byte imageData[] = dbrp.runners[dbrp.current].dbg.getPixels(); //byte imageData[] = graphics.getPixels(); String imageStr = new String(graphics.makeTiffData()); URL appletUrl = app.getDocumentBase(); String document = appletUrl.getFile(); document = document.substring(0, document.lastIndexOf("?")); URL url = new URL("http", appletUrl.getHost(), document); URLConnection conn = url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); DataOutputStream printout = new DataOutputStream(conn.getOutputStream()); String content = "save_as=" + URLEncoder.encode(PdeApplet.get("save_as")) + "&save_image=" + URLEncoder.encode(imageStr) + "&save_program=" + URLEncoder.encode(programStr); printout.writeBytes(content); printout.flush(); printout.close(); // what did they say back? DataInputStream input = new DataInputStream(conn.getInputStream()); String str = null; while ((str = input.readLine()) != null) { //System.out.println(str); } input.close(); message("Done saving file."); } catch (Exception e) { e.printStackTrace(); message("Problem: Your work could not be saved."); } buttons.clear(); */ } static byte tiffHeader[] = { 77, 77, 0, 42, 0, 0, 0, 8, 0, 9, 0, -2, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 3, 0, 0, 0, 122, 1, 6, 0, 3, 0, 0, 0, 1, 0, 2, 0, 0, 1, 17, 0, 4, 0, 0, 0, 1, 0, 0, 3, 0, 1, 21, 0, 3, 0, 0, 0, 1, 0, 3, 0, 0, 1, 22, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1, 23, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 8, 0, 8 }; static byte[] makeTiffData(int pixels[], int width, int height) { byte tiff[] = new byte[768 + width*height*3]; System.arraycopy(tiffHeader, 0, tiff, 0, tiffHeader.length); tiff[30] = (byte) ((width >> 8) & 0xff); tiff[31] = (byte) ((width) & 0xff); tiff[42] = tiff[102] = (byte) ((height >> 8) & 0xff); tiff[43] = tiff[103] = (byte) ((height) & 0xff); int count = width*height*3; tiff[114] = (byte) ((count >> 24) & 0xff); tiff[115] = (byte) ((count >> 16) & 0xff); tiff[116] = (byte) ((count >> 8) & 0xff); tiff[117] = (byte) ((count) & 0xff); int index = 768; for (int i = 0; i < pixels.length; i++) { tiff[index++] = (byte) ((pixels[i] >> 16) & 0xff); tiff[index++] = (byte) ((pixels[i] >> 8) & 0xff); tiff[index++] = (byte) ((pixels[i] >> 0) & 0xff); } return tiff; } //public byte[] makeTiffData() { //return makeTiffData(pixels, width, height); //} public void doSaveTiff() { /* message("Saving TIFF image..."); String s = textarea.getText(); FileDialog fd = new FileDialog(new Frame(), "Save image as...", FileDialog.SAVE); fd.setDirectory(lastDirectory); fd.setFile("untitled.tif"); fd.show(); String directory = fd.getDirectory(); String filename = fd.getFile(); if (filename == null) return; File file = new File(directory, filename); try { FileOutputStream fos = new FileOutputStream(file); byte data[] = graphics.makeTiffData(); fos.write(data); fos.flush(); fos.close(); lastDirectory = directory; message("Done saving image."); } catch (IOException e) { e.printStackTrace(); message("An error occurred, no image could be written."); } */ } /* static void writeTiffHeader(OutputStream os, int width, int height) throws IOException { byte header[] = new byte[768]; System.arraycopy(tiffHeader, 0, header, 0, tiffHeader.length); header[30] = (byte) ((width >> 8) & 0xff); header[31] = (byte) ((width) & 0xff); header[42] = header[102] = (byte) ((height >> 8) & 0xff); header[43] = header[103] = (byte) ((height) & 0xff); int count = width*height*3; header[114] = (byte) ((count >> 24) & 0xff); header[115] = (byte) ((count >> 16) & 0xff); header[116] = (byte) ((count >> 8) & 0xff); header[117] = (byte) ((count) & 0xff); os.write(header); } static void writeTiff(OutputStream os, int width, int height, int pixels[]) { writeTiffHeader(os, width, height); for (int i = 0; i < pixels.length; i++) { write((pixels[i] >> 16) & 0xff); write((pixels[i] >> 8) & 0xff); write(pixels[i] & 0xff); } os.flush(); } */ /* static public byte[] makePgmData(byte inData[], int width, int height) { String headerStr = "P5 " + width + " " + height + " 255\n"; byte header[] = headerStr.getBytes(); int count = width * height; byte outData[] = new byte[header.length + count]; System.arraycopy(header, 0, outData, 0, header.length); System.arraycopy(inData, 0, outData, header.length, count); return outData; } */ public void doPrint() { /* Frame frame = new Frame(); // bullocks int screenWidth = getToolkit().getScreenSize().width; frame.reshape(screenWidth + 20, 100, screenWidth + 100, 200); frame.show(); Properties props = new Properties(); PrintJob pj = getToolkit().getPrintJob(frame, "PDE", props); if (pj != null) { Graphics g = pj.getGraphics(); // awful way to do printing, but sometimes brute force is // just the way. java printing across multiple platforms is // outrageously inconsistent. int offsetX = 100; int offsetY = 100; int index = 0; for (int y = 0; y < graphics.height; y++) { for (int x = 0; x < graphics.width; x++) { g.setColor(new Color(graphics.pixels[index++])); g.drawLine(offsetX + x, offsetY + y, offsetX + x, offsetY + y); } } g.dispose(); g = null; pj.end(); } frame.dispose(); buttons.clear(); */ } public void doBeautify() { /* String prog = textarea.getText(); if ((prog.charAt(0) == '#') || (prog.charAt(0) == ';')) { message("Only DBN code can be made beautiful."); buttons.clear(); return; } 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 { if (line.charAt(0) == '}') { level--; } for (int i = 0; i < level*3; i++) { buffer.append(' '); } buffer.append(line); buffer.append('\n'); if (line.charAt(0) == '{') { level++; } gotBlankLine = false; } } textarea.setText(buffer.toString()); */ buttons.clear(); } public void enableFullScreen() { if (fullScreenWindow == null) { Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); if (PdeApplet.isMacintosh()) { fullScreenWindow = new Frame(); // mrj is still (with version 2.2.x) a piece of shit, // and doesn't return valid insets for frames //fullScreenWindow.pack(); // make a peer so insets are valid //Insets insets = fullScreenWindow.getInsets(); // the extra +20 is because the resize boxes intrude Insets insets = new Insets(21, 5, 5 + 20, 5); //System.out.println(insets); fullScreenWindow.setBounds(-insets.left, -insets.top, screen.width + insets.left + insets.right, screen.height + insets.top + insets.bottom); } else { fullScreenWindow = new Window(new Frame()); fullScreenWindow.setBounds(0, 0, screen.width, screen.height); } fullScreenWindow.setBackground(new Color(102, 102, 102)); /* fullScreenWindow.addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { System.out.println("activated"); } } ); */ fullScreenWindow.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { //System.out.println("activated"); /*PdeApplication.*/ if (frame != null) frame.toFront(); } } ); } fullScreenWindow.show(); fullScreenWindow.toFront(); // not sure what to do with applet.. // (since i can't bring the browser window to the front) // unless there's a method in AppletContext //if (frame != null) frame.toFront(); /* try { //System.out.println("my parent is " + getParent()); ((PdeApplication)getParent()).frame.toFront(); } catch (Exception e) { } */ try { ((KjcEngine)(runner.engine)).window.toFront(); } catch (Exception e) { // rather than writing code to check all the posible // errors with the above statement, just fail quietly //System.out.println("couldn't bring kjc engine window forward"); } //if (runner.engine != null) { //if (runner.engine instanceof KjcEngine) { //} //} buttons.clear(); } public void disableFullScreen() { fullScreenWindow.hide(); buttons.clear(); } public void terminate() { // part of PdeEnvironment runner.stop(); message(EMPTY); } // TODO iron out bugs with this code under // different platforms, especially macintosh public void highlightLine(int lnum) { if (lnum < 0) { textarea.select(0, 0); return; } //System.out.println(lnum); String s = textarea.getText(); int len = s.length(); //int lnum = .line; int st = -1, end = -1; int lc = 0; if (lnum == 0) st = 0; for (int i = 0; i < len; i++) { //if ((s.charAt(i) == '\n') || (s.charAt(i) == '\r')) { boolean newline = false; if (s.charAt(i) == '\r') { if ((i != len-1) && (s.charAt(i+1) == '\n')) i++; lc++; newline = true; } else if (s.charAt(i) == '\n') { lc++; newline = true; } if (newline) { if (lc == lnum) st = i+1; else if (lc == lnum+1) { end = i; break; } } } if (end == -1) end = len; //System.out.println("st/end: "+st+"/"+end); textarea.select(st, end+1); //if (iexplorerp) { //textarea.invalidate(); //textarea.repaint(); //} } public void error(PdeException e) { // part of PdeEnvironment if (e.line >= 0) highlightLine(e.line); //dbcp.repaint(); // button should go back to 'play' //System.err.println(e.getMessage()); //message("Problem: " + e.getMessage()); message(e.getMessage()); buttons.clearPlay(); //showStatus(e.getMessage()); } public void finished() { // part of PdeEnvironment #ifdef RECORDER PdeRecorder.stop(); #endif playing = false; buttons.clearPlay(); message("Done."); } public void message(String msg) { // part of PdeEnvironment status.setText(msg); } public void messageClear(String msg) { if (status.getText().equals(msg)) status.setText(EMPTY); } } #endif