// TODO Why is this necessary? Why isn't Sketch.isModified() used? private static boolean isSketchModified(Sketch sketch) { for (SketchCode sc : sketch.getCode()) { if (sc.isModified()) { return true; } } return false; }
/** Save all code in the current sketch. */ public boolean save() throws IOException { // make sure the user didn't hide the sketch folder ensureExistence(); // first get the contents of the editor text area if (current.modified) { current.program = editor.getText(); } // don't do anything if not actually modified // if (!modified) return false; if (isReadOnly()) { // if the files are read-only, need to first do a "save as". Base.showMessage( "Sketch is read-only", "Some files are marked \"read-only\", so you'll\n" + "need to re-save this sketch to another location."); // if the user cancels, give up on the save() if (!saveAs()) return false; } for (int i = 0; i < codeCount; i++) { if (code[i].modified) code[i].save(); } calcModified(); return true; }
/** * Handles 'Save As' for a sketch. * * <p>This basically just duplicates the current sketch folder to a new location, and then calls * 'Save'. (needs to take the current state of the open files and save them to the new folder.. * but not save over the old versions for the old sketch..) * * <p>Also removes the previously-generated .class and .jar files, because they can cause trouble. */ public boolean saveAs() throws IOException { // get new name for folder FileDialog fd = new FileDialog(editor, "Save file as...", FileDialog.SAVE); if (isReadOnly()) { // default to the sketchbook folder fd.setDirectory(Base.preferences.get("sketchbook.path", null)); } else { // default to the parent folder of where this was fd.setDirectory(folder.getParent()); } fd.setFile(folder.getName()); fd.setVisible(true); String newParentDir = fd.getDirectory(); String newName = fd.getFile(); File newFolder = new File(newParentDir); // user cancelled selection if (newName == null) return false; if (!newName.endsWith(".gcode")) newName = newName + ".gcode"; // grab the contents of the current tab before saving // first get the contents of the editor text area if (current.modified) { current.program = editor.getText(); } // save the other tabs to their new location for (int i = 1; i < codeCount; i++) { File newFile = new File(newFolder, code[i].file.getName()); code[i].saveAs(newFile); } // save the hidden code to its new location for (int i = 0; i < hiddenCount; i++) { File newFile = new File(newFolder, hidden[i].file.getName()); hidden[i].saveAs(newFile); } // save the main tab with its new name File newFile = new File(newFolder, newName); code[0].saveAs(newFile); editor.handleOpenUnchecked( newFile.getPath(), currentIndex, editor.textarea.getSelectionStart(), editor.textarea.getSelectionEnd(), editor.textarea.getScrollPosition()); // Name changed, rebuild the sketch menus // editor.sketchbook.rebuildMenusAsync(); // let MainWindow know that the save was successful return true; }
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(name) && Sketch.flavorExtensionsShown[hidden[i].flavor].equals(extension)) { // unhideIndex = i; unhideCode = hidden[i]; // remove from the 'hidden' list for (int j = i; j < hiddenCount - 1; j++) { hidden[j] = hidden[j + 1]; } hiddenCount--; break; } } // if (unhideIndex == -1) { if (unhideCode == null) { System.err.println("internal error: could find " + what + " to unhide."); return; } if (!unhideCode.file.exists()) { Base.showMessage("Can't unhide", "The file \"" + what + "\" no longer exists."); // System.out.println(unhideCode.file); return; } String unhidePath = unhideCode.file.getAbsolutePath(); File unhideFile = new File(unhidePath.substring(0, unhidePath.length() - 2)); if (!unhideCode.file.renameTo(unhideFile)) { Base.showMessage( "Can't unhide", "The file \"" + what + "\" could not be" + "renamed and unhidden."); return; } unhideCode.file = unhideFile; insertCode(unhideCode); sortCode(); setCurrent(unhideCode.name); editor.header.repaint(); }
/** * Change what file is currently being edited. * * <OL> * <LI>store the String for the text of the current file. * <LI>retrieve the String for the text of the new file. * <LI>change the text that's visible in the text area * </OL> */ public void setCurrent(int which) { // if current is null, then this is the first setCurrent(0) if ((currentIndex == which) && (current != null)) { return; } // get the text currently being edited if (current != null) { current.program = editor.getText(); current.selectionStart = editor.textarea.getSelectionStart(); current.selectionStop = editor.textarea.getSelectionEnd(); current.scrollPosition = editor.textarea.getScrollPosition(); } current = code[which]; currentIndex = which; editor.setCode(current); // editor.setDocument(current.document, // current.selectionStart, current.selectionStop, // current.scrollPosition, current.undo); // set to the text for this file // 'true' means to wipe out the undo buffer // (so they don't undo back to the other file.. whups!) /* * editor.setText(current.program, current.selectionStart, * current.selectionStop, current.undo); */ // set stored caret and scroll positions // editor.textarea.setScrollPosition(current.scrollPosition); // editor.textarea.select(current.selectionStart, // current.selectionStop); // editor.textarea.setSelectionStart(current.selectionStart); // editor.textarea.setSelectionEnd(current.selectionStop); editor.header.rebuild(); }
/** Run the GCode. */ public boolean handleRun() { // make sure the user didn't hide the sketch folder ensureExistence(); current.program = editor.getText(); // TODO record history here // current.history.record(program, SketchHistory.RUN); // in case there were any boogers left behind // do this here instead of after exiting, since the exit // can happen so many different ways.. and this will be // better connected to the dataFolder stuff below. cleanup(); return (mainClassName != null); }
public void hideCode() { // make sure the user didn't hide the sketch folder ensureExistence(); // if read-only, give an error if (isReadOnly()) { // if the files are read-only, need to first do a "save as". Base.showMessage( "Sketch is Read-Only", "Some files are marked \"read-only\", so you'll\n" + "need to re-save the sketch in another location,\n" + "and try again."); return; } // don't allow hide of the main code // TODO maybe gray out the menu on setCurrent(0) if (currentIndex == 0) { Base.showMessage( "Can't do that", "You cannot hide the main " + ".gcode file from a sketch\n"); return; } // rename the file File newFile = new File(current.file.getAbsolutePath() + ".x"); if (!current.file.renameTo(newFile)) { Base.showWarning("Error", "Could not hide " + "\"" + current.file.getName() + "\".", null); return; } current.file = newFile; // move it to the hidden list if (hiddenCount == hidden.length) { SketchCode temp[] = new SketchCode[hiddenCount + 1]; System.arraycopy(hidden, 0, temp, 0, hiddenCount); hidden = temp; } hidden[hiddenCount++] = current; // remove it from the main list removeCode(current); // update the tabs setCurrent(0); editor.header.repaint(); }
/** Sets the modified value for the code in the frontmost tab. */ public void setModified(boolean state) { current.modified = state; calcModified(); }
/** * This is called upon return from entering a new file name. (that is, from either newCode or * renameCode after the prompt) This code is almost identical for both the newCode and renameCode * cases, so they're kept merged except for right in the middle where they diverge. */ public void nameCode(String newName) { // make sure the user didn't hide the sketch folder ensureExistence(); // if renaming to the same thing as before, just ignore. // also ignoring case here, because i don't want to write // a bunch of special stuff for each platform // (osx is case insensitive but preserving, windows insensitive, // *nix is sensitive and preserving.. argh) if (renamingCode && newName.equalsIgnoreCase(current.name)) { // exit quietly for the 'rename' case. // if it's a 'new' then an error will occur down below return; } // don't allow blank names if (newName.trim().equals("")) { return; } if (newName.trim().equals(".gcode")) { return; } String newFilename = null; int newFlavor = 0; // separate into newName (no extension) and newFilename (with ext) // add .gcode to file if it has no extension if (newName.endsWith(".gcode")) { newFilename = newName; newName = newName.substring(0, newName.length() - 6); newFlavor = GCODE; } else { newFilename = newName + ".gcode"; newFlavor = GCODE; } // dots are allowed for the .gcode and .java, but not in the name // make sure the user didn't name things poo.time.gcode // or something like that (nothing against poo time) if (newName.indexOf('.') != -1) { newFilename = newName + ".gcode"; } // create the new file, new SketchCode object and load it File newFile = new File(folder, newFilename); if (newFile.exists()) { // yay! users will try anything Base.showMessage( "Nope", "A file named \"" + newFile + "\" already exists\n" + "in \"" + folder.getAbsolutePath() + "\""); return; } File newFileHidden = new File(folder, newFilename + ".x"); if (newFileHidden.exists()) { // don't let them get away with it if they try to create something // with the same name as something hidden Base.showMessage( "No Way", "A hidden tab with the same name already exists.\n" + "Use \"Unhide\" to bring it back."); return; } if (renamingCode) { if (currentIndex == 0) { // get the new folder name/location File newFolder = new File(folder.getParentFile(), newName); if (newFolder.exists()) { Base.showWarning( "Cannot Rename", "Sorry, a sketch (or folder) named " + "\"" + newName + "\" already exists.", null); return; } // unfortunately this can't be a "save as" because that // only copies the sketch files and the data folder // however this *will* first save the sketch, then rename // first get the contents of the editor text area if (current.modified) { current.program = editor.getText(); try { // save this new SketchCode current.save(); } catch (Exception e) { Base.showWarning("Error", "Could not rename the sketch. (0)", e); return; } } if (!current.file.renameTo(newFile)) { Base.showWarning( "Error", "Could not rename \"" + current.file.getName() + "\" to \"" + newFile.getName() + "\"", null); return; } // save each of the other tabs because this is gonna be // re-opened try { for (int i = 1; i < codeCount; i++) { // if (code[i].modified) code[i].save(); code[i].save(); } } catch (Exception e) { Base.showWarning("Error", "Could not rename the sketch. (1)", e); return; } // now rename the sketch folder and re-open boolean success = folder.renameTo(newFolder); if (!success) { Base.showWarning("Error", "Could not rename the sketch. (2)", null); return; } // if successful, set base properties for the sketch File mainFile = new File(newFolder, newName + ".gcode"); mainFilename = mainFile.getAbsolutePath(); // having saved everything and renamed the folder and the main // .gcode, // use the editor to re-open the sketch to re-init state // (unfortunately this will kill positions for carets etc) editor.handleOpenUnchecked( mainFilename, currentIndex, editor.textarea.getSelectionStart(), editor.textarea.getSelectionEnd(), editor.textarea.getScrollPosition()); // get the changes into the sketchbook menu // (re-enabled in 0115 to fix bug #332) // editor.sketchbook.rebuildMenus(); } else { // else if something besides code[0] if (!current.file.renameTo(newFile)) { Base.showWarning( "Error", "Could not rename \"" + current.file.getName() + "\" to \"" + newFile.getName() + "\"", null); return; } // just reopen the class itself current.name = newName; current.file = newFile; current.flavor = newFlavor; } } else { // creating a new file try { newFile.createNewFile(); // TODO returns a boolean } catch (IOException e) { Base.showWarning( "Error", "Could not create the file \"" + newFile + "\"\n" + "in \"" + folder.getAbsolutePath() + "\"", e); return; } SketchCode newCode = new SketchCode(newName, newFile, newFlavor); insertCode(newCode); } // sort the entries sortCode(); // set the new guy as current setCurrent(newName + flavorExtensionsShown[newFlavor]); // update the tabs // editor.header.repaint(); editor.header.rebuild(); // force the update on the mac? Toolkit.getDefaultToolkit().sync(); // editor.header.getToolkit().sync(); }