| [ Web Proxy ] |
| Viewing: https://raw.githubusercontent.com/dimr/processing/master/app/src/processing/app/Sketch.java | [Back] [Original] |
* Generally this is only done once, rather than * each time a change is made, because otherwise it gets to be * a nightmare to keep track of what files went where, because * not all the data will be saved to disk. *
* This also gets called when the main sketch file is renamed, * because the sketch has to be reloaded from a different folder. *
* Another exception is when an external editor is in use, * in which case the load happens each time "run" is hit. */ protected void load() { codeFolder = new File(folder, "code"); dataFolder = new File(folder, "data"); List filenames = new ArrayList(); List extensions = new ArrayList(); getSketchCodeFiles(filenames, extensions); codeCount = filenames.size(); code = new SketchCode[codeCount]; for (int i = 0; i < codeCount; i++) { String filename = filenames.get(i); String extension = extensions.get(i); code[i] = new SketchCode(new File(folder, filename), extension); } // move the main class to the first tab // start at 1, if it's at zero, don't bother for (int i = 1; i < codeCount; i++) { //if (code[i].file.getName().equals(mainFilename)) { if (code[i].getFile().equals(primaryFile)) { SketchCode temp = code[0]; code[0] = code[i]; code[i] = temp; break; } } // sort the entries at the top sortCode(); // set the main file to be the current tab if (editor != null) { setCurrentCode(0); } } public void getSketchCodeFiles(List outFilenames, List outExtensions) { // get list of files in the sketch folder String list[] = folder.list(); for (String filename : list) { // Ignoring the dot prefix files is especially important to avoid files // with the ._ prefix on Mac OS X. (You'll see this with Mac files on // non-HFS drives, i.e. a thumb drive formatted FAT32.) if (filename.startsWith(".")) continue; // Don't let some wacko name a directory blah.pde or bling.java. if (new File(folder, filename).isDirectory()) continue; // figure out the name without any extension String base = filename; // now strip off the .pde and .java extensions for (String extension : mode.getExtensions()) { if (base.toLowerCase().endsWith("." + extension)) { base = base.substring(0, base.length() - (extension.length() + 1)); // Don't allow people to use files with invalid names, since on load, // it would be otherwise possible to sneak in nasty filenames. [0116] if (isSanitaryName(base)) { if (outFilenames != null) outFilenames.add(filename); if (outExtensions != null) outExtensions.add(extension); } } } } } /** * Reload the current sketch. Used to update the text area when * an external editor is in use. */ public void reload() { // set current to null so that the tab gets updated // http://dev.processing.org/bugs/show_bug.cgi?id=515 current = null; // nuke previous files and settings load(); } protected void replaceCode(SketchCode newCode) { for (int i = 0; i < codeCount; i++) { if (code[i].getFileName().equals(newCode.getFileName())) { code[i] = newCode; break; } } } protected void insertCode(SketchCode newCode) { // make sure the user didn't hide the sketch folder ensureExistence(); // add file to the code/codeCount list, resort the list //if (codeCount == code.length) { code = (SketchCode[]) PApplet.append(code, newCode); codeCount++; //} //code[codeCount++] = newCode; } protected void sortCode() { // cheap-ass sort of the rest of the files // it's a dumb, slow sort, but there shouldn't be more than ~5 files for (int i = 1; i < codeCount; i++) { int who = i; for (int j = i + 1; j < codeCount; j++) { if (code[j].getFileName().compareTo(code[who].getFileName()) < 0) { who = j; // this guy is earlier in the alphabet } } if (who != i) { // swap with someone if changes made SketchCode temp = code[who]; code[who] = code[i]; code[i] = temp; // We also need to update the current tab if (currentIndex == i) { currentIndex = who; } else if (currentIndex == who) { currentIndex = i; } } } } boolean renamingCode; /** * Handler for the New Code menu option. */ public void handleNewCode() { // 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". Messages.showMessage(Language.text("new.messages.is_read_only"), Language.text("new.messages.is_read_only.description")); return; } renamingCode = false; // editor.status.edit("Name for new file:", ""); promptForTabName(Language.text("editor.tab.rename.description")+":", ""); } /** * Handler for the Rename Code menu option. */ public void handleRenameCode() { // make sure the user didn't hide the sketch folder ensureExistence(); if (currentIndex == 0 && isUntitled()) { Messages.showMessage(Language.text("rename.messages.is_untitled"), Language.text("rename.messages.is_untitled.description")); return; } if (isModified()) { Messages.showMessage(Language.text("menu.file.save"), Language.text("rename.messages.is_modified")); return; } // if read-only, give an error if (isReadOnly()) { // if the files are read-only, need to first do a "save as". Messages.showMessage(Language.text("rename.messages.is_read_only"), Language.text("rename.messages.is_read_only.description")); return; } // ask for new name of file (internal to window) // TODO maybe just popup a text area? renamingCode = true; String prompt = (currentIndex == 0) ? Language.text("editor.sketch.rename.description") : Language.text("editor.tab.rename.description"); String oldName = (current.isExtension(mode.getDefaultExtension())) ? current.getPrettyName() : current.getFileName(); promptForTabName(prompt + ":", oldName); } /** * Displays a dialog for renaming or creating a new tab */ protected void promptForTabName(String prompt, String oldName) { final JTextField field = new JTextField(oldName); field.addKeyListener(new KeyAdapter() { // Forget ESC, the JDialog should handle it. // Use keyTyped to catch when the feller is actually added to the text // field. With keyTyped, as opposed to keyPressed, the keyCode will be // zero, even if it's enter or backspace or whatever, so the keychar // should be used instead. Grr. public void keyTyped(KeyEvent event) { //System.out.println("got event " + event); char ch = event.getKeyChar(); if ((ch == '_') || (ch == '.') || // allow.pde and .java (('A' = codeCount || which < 0) { return; } // get the text currently being edited if (current != null) { current.setState(editor.getText(), editor.getSelectionStart(), editor.getSelectionStop(), editor.getScrollPosition()); } current = code[which]; currentIndex = which; current.visited = System.currentTimeMillis(); editor.setCode(current); editor.repaintHeader(); } /** * Internal helper function to set the current tab based on a name. * @param findName the file name (not pretty name) to be shown */ public void setCurrentCode(String findName) { for (int i = 0; i < codeCount; i++) { if (findName.equals(code[i].getFileName()) || findName.equals(code[i].getPrettyName())) { setCurrentCode(i); return; } } } /** * Create a temporary folder that includes the sketch's name in its title. */ public File makeTempFolder() { try { return Util.createTempFolder(name, "temp", null); } catch (IOException e) { Messages.showWarning(Language.text("temp_dir.messages.bad_build_folder"), Language.text("temp_dir.messages.bad_build_folder.description"), e); } return null; } /** * When running from the editor, take care of preparations before running * a build or an export. Also erases and/or creates 'targetFolder' if it's * not null, and if preferences say to do so when exporting. * @param targetFolder is something like applet, application, android... */ /* public void prepareBuild(File targetFolder) throws SketchException { // make sure the user didn't hide the sketch folder ensureExistence(); // don't do from the command line if (editor != null) { // make sure any edits have been stored current.setProgram(editor.getText()); // if an external editor is being used, need to grab the // latest version of the code from the file. if (Preferences.getBoolean("editor.external")) { // set current to null so that the tab gets updated // http://dev.processing.org/bugs/show_bug.cgi?id=515 current = null; // nuke previous files and settings load(); } } if (targetFolder != null) { // Nuke the old applet/application folder because it can cause trouble if (Preferences.getBoolean("export.delete_target_folder")) { System.out.println("temporarily skipping deletion of " + targetFolder); // Base.removeDir(targetFolder); // targetFolder.renameTo(dest); } // Create a fresh output folder (needed before preproc is run next) targetFolder.mkdirs(); } } */ /** * Make sure the sketch hasn't been moved or deleted by some * nefarious user. If they did, try to re-create it and save. * Only checks to see if the main folder is still around, * but not its contents. */ public void ensureExistence() { if (!folder.exists()) { // Disaster recovery, try to salvage what's there already. Messages.showWarning(Language.text("ensure_exist.messages.missing_sketch"), Language.text("ensure_exist.messages.missing_sketch.description")); try { folder.mkdirs(); modified = true; for (int i = 0; i < codeCount; i++) { code[i].save(); // this will force a save } calcModified(); } catch (Exception e) { Messages.showWarning(Language.text("ensure_exist.messages.unrecoverable"), Language.text("ensure_exist.messages.unrecoverable.description"), e); } } } /** * Returns true if this is a read-only sketch. Used for the * examples directory, or when sketches are loaded from read-only * volumes or folders without appropriate permissions. */ public boolean isReadOnly() { String apath = folder.getAbsolutePath(); List modes = editor.getBase().getModeList(); // Make sure it's not read-only for another Mode besides this one // https://github.com/processing/processing/issues/773 for (Mode mode : modes) { if (apath.startsWith(mode.getExamplesFolder().getAbsolutePath()) || apath.startsWith(mode.getLibrariesFolder().getAbsolutePath())) { return true; } } // check to see if each modified code file can be written to // canWrite() doesn't work on directories for (int i = 0; i < codeCount; i++) { if (code[i].isModified() && code[i].fileReadOnly() && code[i].fileExists()) { //System.err.println("found a read-only file " + code[i].file); return true; } } return false; } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // Additional accessors added in 0136 because of package work. // These will also be helpful for tool developers. /** * Returns the name of this sketch. (The pretty name of the main tab.) */ public String getName() { return name; } /** * Returns a File object for the main .pde file for this sketch. */ public File getMainFile() { return primaryFile; } /** * Returns path to the main .pde file for this sketch. */ public String getMainFilePath() { return primaryFile.getAbsolutePath(); } /** * Returns the sketch folder. */ public File getFolder() { return folder; } /** * Returns the location of the sketch's data folder. (It may not exist yet.) */ public File getDataFolder() { return dataFolder; } public boolean hasDataFolder() { return dataFolder.exists(); } /** * Create the data folder if it does not exist already. As a convenience, * it also returns the data folder, since it's likely about to be used. */ public File prepareDataFolder() { if (!dataFolder.exists()) { dataFolder.mkdirs(); } return dataFolder; } /** * Returns the location of the sketch's code folder. (It may not exist yet.) */ public File getCodeFolder() { return codeFolder; } public boolean hasCodeFolder() { return (codeFolder != null) && codeFolder.exists(); } /** * Create the code folder if it does not exist already. As a convenience, * it also returns the code folder, since it's likely about to be used. */ public File prepareCodeFolder() { if (!codeFolder.exists()) { codeFolder.mkdirs(); } return codeFolder; } // public String getClassPath() { // return classPath; // } // public String getLibraryPath() { // return javaLibraryPath; // } public SketchCode[] getCode() { return code; } public int getCodeCount() { return codeCount; } public SketchCode getCode(int index) { return code[index]; } public int getCodeIndex(SketchCode who) { for (int i = 0; i < codeCount; i++) { if (who == code[i]) { return i; } } return -1; } public SketchCode getCurrentCode() { return current; } public int getCurrentCodeIndex() { return currentIndex; } public String getMainProgram() { return getCode(0).getProgram(); } public void setUntitled(boolean untitled) { // editor.untitled = u; this.untitled = untitled; editor.updateTitle(); } public boolean isUntitled() { // return editor.untitled; return untitled; } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . /** * Convert to sanitized name and alert the user * if changes were made. */ static public String checkName(String origName) { String newName = sanitizeName(origName); if (!newName.equals(origName)) { String msg = Language.text("check_name.messages.is_name_modified"); System.out.println(msg); } return newName; } /** * Return true if the name is valid for a Processing sketch. Extensions of the form .foo are * ignored. */ public static boolean isSanitaryName(String name) { final int dot = name.lastIndexOf('.'); if (dot >= 0) { name = name.substring(0, dot); } return sanitizeName(name).equals(name); } static final boolean asciiLetter(char c) { return (c >= 'a' && c = 'A' && c
| Web Proxy Viewer | New URL | Original Page |