public void populateMenu(JMenu menu, int flags) { if (flags == (Plugin.MENU_TOOLS | Plugin.MENU_MID)) { Sketch sketch = editor.getSketch(); JMenuItem item = new JMenu("Program Bootloader"); item.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { run(); } }); menu.add(item); PropertyFile props = sketch.mergeAllProperties(); String blProgs = props.get("bootloader.upload"); if (blProgs == null) { JMenuItem sub = new JMenuItem("No bootloader programmer defined!"); item.add(sub); return; } String[] progs = blProgs.split("::"); for (String prog : progs) { JMenuItem sub = new JMenuItem(sketch.parseString(props.get("upload." + prog + ".name"))); sub.setActionCommand(prog); sub.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { doProgram(e.getActionCommand()); } }); item.add(sub); } } }
public void setObjectValues() { ((JTextField) (fields.get("board"))).setText(sketch.getBoard().getName()); ((JTextField) (fields.get("core"))).setText(sketch.getCore().getName()); ((JTextField) (fields.get("compiler"))).setText(sketch.getCompiler().getName()); ((JTextField) (fields.get("port"))).setText(sketch.getDevice().toString()); ((JTextField) (fields.get("programmer"))).setText(sketch.getProgrammer()); }
/** * 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. */ private void ensureExistence() { if (sketch.getFolder().exists()) return; Base.showWarning( tr("Sketch Disappeared"), tr( "The sketch folder has disappeared.\n " + "Will attempt to re-save in the same location,\n" + "but anything besides the code will be lost."), null); try { sketch.getFolder().mkdirs(); for (SketchFile file : sketch.getFiles()) { file.save(); // this will force a save } calcModified(); } catch (Exception e) { Base.showWarning( tr("Could not re-save sketch"), tr( "Could not properly re-save the sketch. " + "You may be in trouble at this point,\n" + "and it might be time to copy and paste " + "your code to another text editor."), e); } }
/** * Preprocess and compile all the code for this sketch. * * <p>In an advanced program, the returned class name could be different, which is why the * className is set based on the return value. A compilation error will burp up a RunnerException. * * @return null if compilation failed, main class name if not */ public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException, IOException { // run the preprocessor editor.status.progressUpdate(20); ensureExistence(); CompilerProgressListener progressListener = editor.status::progressUpdate; boolean deleteTemp = false; File pathToSketch = sketch.getPrimaryFile().getFile(); if (sketch.isModified()) { // If any files are modified, make a copy of the sketch with the changes // saved, so arduino-builder will see the modifications. pathToSketch = saveSketchInTempFolder(); deleteTemp = true; } try { return new Compiler(pathToSketch, sketch).build(progressListener, save); } finally { // Make sure we clean up any temporary sketch copy if (deleteTemp) FileUtils.recursiveDelete(pathToSketch.getParentFile()); } }
/** Save all code in the current sketch. */ public boolean save() throws IOException { // make sure the user didn't hide the sketch folder ensureExistence(); if (isReadOnly( BaseNoGui.librariesIndexer.getInstalledLibraries(), BaseNoGui.getExamplesPath())) { Base.showMessage( tr("Sketch is read-only"), tr( "Some files are marked \"read-only\", so you'll\n" + "need to re-save this sketch to another location.")); return saveAs(); } // rename .pde files to .ino List<SketchFile> oldFiles = new ArrayList<>(); for (SketchFile file : sketch.getFiles()) { if (file.isExtension(Sketch.OLD_SKETCH_EXTENSIONS)) oldFiles.add(file); } if (oldFiles.size() > 0) { if (PreferencesData.get("editor.update_extension") == null) { Object[] options = {tr("OK"), tr("Cancel")}; int result = JOptionPane.showOptionDialog( editor, tr( "In Arduino 1.0, the default file extension has changed\n" + "from .pde to .ino. New sketches (including those created\n" + "by \"Save-As\") will use the new extension. The extension\n" + "of existing sketches will be updated on save, but you can\n" + "disable this in the Preferences dialog.\n" + "\n" + "Save sketch and update its extension?"), tr(".pde -> .ino"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (result != JOptionPane.OK_OPTION) return false; // save cancelled PreferencesData.setBoolean("editor.update_extension", true); } if (PreferencesData.getBoolean("editor.update_extension")) { // Do rename of all .pde files to new .ino extension for (SketchFile file : oldFiles) { File newName = FileUtils.replaceExtension(file.getFile(), Sketch.DEFAULT_SKETCH_EXTENSION); file.renameTo(newName.getName()); } } } sketch.save(); return true; }
/** Remove a piece of code from the sketch and from the disk. */ public void handleDeleteCode() throws IOException { SketchFile current = editor.getCurrentTab().getSketchFile(); editor.status.clearState(); // make sure the user didn't hide the sketch folder ensureExistence(); // if read-only, give an error if (isReadOnly( BaseNoGui.librariesIndexer.getInstalledLibraries(), BaseNoGui.getExamplesPath())) { // if the files are read-only, need to first do a "save as". Base.showMessage( tr("Sketch is Read-Only"), tr( "Some files are marked \"read-only\", so you'll\n" + "need to re-save the sketch in another location,\n" + "and try again.")); return; } // confirm deletion with user, yes/no Object[] options = {tr("OK"), tr("Cancel")}; String prompt = current.isPrimary() ? tr("Are you sure you want to delete this sketch?") : I18n.format(tr("Are you sure you want to delete \"{0}\"?"), current.getPrettyName()); int result = JOptionPane.showOptionDialog( editor, prompt, tr("Delete"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (result == JOptionPane.YES_OPTION) { if (current.isPrimary()) { sketch.delete(); editor.base.handleClose(editor); } else { // delete the file if (!current.delete(sketch.getBuildPath().toPath())) { Base.showMessage( tr("Couldn't do it"), I18n.format(tr("Could not delete \"{0}\"."), current.getFileName())); return; } // just set current tab to the main tab editor.selectTab(0); // update the tabs editor.header.repaint(); } } }
public void run() { Sketch sketch = editor.getSketch(); Board board = sketch.getBoard(); Core core = sketch.getCore(); String programmer = sketch.getProgrammer(); PropertyFile props = sketch.mergeAllProperties(); String blProgs = props.get("bootloader.upload"); System.err.println(blProgs); }
private File saveSketchInTempFolder() throws IOException { File tempFolder = FileUtils.createTempFolder("arduino_modified_sketch_"); FileUtils.copy(sketch.getFolder(), tempFolder); for (SketchFile file : Stream.of(sketch.getFiles()).filter(SketchFile::isModified).collect(Collectors.toList())) { Files.write( Paths.get(tempFolder.getAbsolutePath(), file.getFileName()), file.getProgram().getBytes()); } return Paths.get(tempFolder.getAbsolutePath(), sketch.getPrimaryFile().getFileName()).toFile(); }
public void save() { for (String key : fields.keySet()) { JComponent comp = fields.get(key); if (comp instanceof JTextField) { JTextField c = (JTextField) comp; if (c.getText().trim().equals("")) { sketch.configFile.unset(key); } else { sketch.configFile.set(key, c.getText()); } } else if (comp instanceof JTextArea) { JTextArea c = (JTextArea) comp; if (c.getText().trim().equals("")) { sketch.configFile.unset(key); } else { sketch.configFile.set(key, c.getText()); } } } sketch.saveConfig(); }
public void doProgram(String prog) { editor.clearConsole(); Sketch sketch = editor.getSketch(); PropertyFile props = sketch.mergeAllProperties(); editor.message("Programming bootloader using " + prog); String bl = sketch.parseString(props.get("bootloader.file")); editor.message("Bootloader: " + bl); if (bl == null) { String url = sketch.parseString(props.get("bootloader.url")); if (url != null) { editor.error("The bootloader can be downloaded from " + url); return; } } sketch.programFile(prog, bl); }
private boolean sketchFilesAreReadOnly() { for (SketchFile file : sketch.getFiles()) { if (file.isModified() && file.fileReadOnly() && file.fileExists()) { return true; } } return false; }
/** * Called whenever the modification status of one of the tabs changes. TODO: Move this code into * Editor and improve decoupling from EditorTab */ public void calcModified() { editor.header.repaint(); if (OSUtils.isMacOS()) { // http://developer.apple.com/qa/qa2001/qa1146.html Object modifiedParam = sketch.isModified() ? Boolean.TRUE : Boolean.FALSE; editor.getRootPane().putClientProperty("windowModified", modifiedParam); editor.getRootPane().putClientProperty("Window.documentModified", modifiedParam); } }
/** * 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(LibraryList libraries, String examplesPath) { String apath = sketch.getFolder().getAbsolutePath(); Optional<UserLibrary> libraryThatIncludesSketch = libraries .stream() .filter(lib -> apath.startsWith(lib.getInstalledFolder().getAbsolutePath())) .findFirst(); if (libraryThatIncludesSketch.isPresent() && !libraryThatIncludesSketch.get().onGoingDevelopment()) { return true; } return sketchIsSystemExample(apath, examplesPath) || sketchFilesAreReadOnly(); }
/** * Add a file to the sketch. * * <p>Supported code files will be copied to the sketch folder. All other files will be copied to * the "data" folder (which is created if it does not exist yet). * * @return true if successful. */ public boolean addFile(File sourceFile) { String filename = sourceFile.getName(); File destFile = null; boolean isData = false; boolean replacement = false; if (FileUtils.hasExtension(sourceFile, Sketch.EXTENSIONS)) { destFile = new File(sketch.getFolder(), filename); } else { sketch.prepareDataFolder(); destFile = new File(sketch.getDataFolder(), filename); isData = true; } // check whether this file already exists if (destFile.exists()) { Object[] options = {tr("OK"), tr("Cancel")}; String prompt = I18n.format(tr("Replace the existing version of {0}?"), filename); int result = JOptionPane.showOptionDialog( editor, prompt, tr("Replace"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (result == JOptionPane.YES_OPTION) { replacement = true; } else { return false; } } // If it's a replacement, delete the old file first, // otherwise case changes will not be preserved. // http://dev.processing.org/bugs/show_bug.cgi?id=969 if (replacement) { boolean muchSuccess = destFile.delete(); if (!muchSuccess) { Base.showWarning( tr("Error adding file"), I18n.format(tr("Could not delete the existing ''{0}'' file."), filename), null); return false; } } // make sure they aren't the same file if (isData && sourceFile.equals(destFile)) { Base.showWarning( tr("You can't fool me"), tr( "This file has already been copied to the\n" + "location from which where you're trying to add it.\n" + "I ain't not doin nuthin'."), null); return false; } // in case the user is "adding" the code in an attempt // to update the sketch's tabs if (!sourceFile.equals(destFile)) { try { Base.copyFile(sourceFile, destFile); } catch (IOException e) { Base.showWarning( tr("Error adding file"), I18n.format(tr("Could not add ''{0}'' to the sketch."), filename), e); return false; } } if (!isData) { int tabIndex; if (replacement) { tabIndex = editor.findTabIndex(destFile); editor.getTabs().get(tabIndex).reload(); } else { SketchFile sketchFile; try { sketchFile = sketch.addFile(destFile.getName()); editor.addTab(sketchFile, null); } catch (IOException e) { // This does not pass on e, to prevent showing a backtrace for // "normal" errors. Base.showWarning(tr("Error"), e.getMessage(), null); return false; } tabIndex = editor.findTabIndex(sketchFile); } editor.selectTab(tabIndex); } 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. */ protected boolean saveAs() throws IOException { // get new name for folder FileDialog fd = new FileDialog(editor, tr("Save sketch folder as..."), FileDialog.SAVE); if (isReadOnly(BaseNoGui.librariesIndexer.getInstalledLibraries(), BaseNoGui.getExamplesPath()) || isUntitled()) { // default to the sketchbook folder fd.setDirectory(BaseNoGui.getSketchbookFolder().getAbsolutePath()); } else { // default to the parent folder of where this was // on macs a .getParentFile() method is required fd.setDirectory(sketch.getFolder().getParentFile().getAbsolutePath()); } String oldName = sketch.getName(); fd.setFile(oldName); fd.setVisible(true); String newParentDir = fd.getDirectory(); String newName = fd.getFile(); // user canceled selection if (newName == null) return false; newName = SketchController.checkName(newName); File newFolder = new File(newParentDir, newName); // check if the paths are identical if (newFolder.equals(sketch.getFolder())) { // just use "save" here instead, because the user will have received a // message (from the operating system) about "do you want to replace?" return save(); } // check to see if the user is trying to save this sketch inside itself try { String newPath = newFolder.getCanonicalPath() + File.separator; String oldPath = sketch.getFolder().getCanonicalPath() + File.separator; if (newPath.indexOf(oldPath) == 0) { Base.showWarning( tr("How very Borges of you"), tr( "You cannot save the sketch into a folder\n" + "inside itself. This would go on forever."), null); return false; } } catch (IOException e) { // ignore } // if the new folder already exists, then need to remove // its contents before copying everything over // (user will have already been warned) if (newFolder.exists()) { FileUtils.recursiveDelete(newFolder); } // in fact, you can't do this on windows because the file dialog // will instead put you inside the folder, but it happens on osx a lot. try { sketch.saveAs(newFolder); } catch (IOException e) { // This does not pass on e, to prevent showing a backtrace for "normal" // errors. Base.showWarning(tr("Error"), e.getMessage(), null); } // Name changed, rebuild the sketch menus // editor.sketchbook.rebuildMenusAsync(); editor.base.rebuildSketchbookMenus(); editor.header.rebuild(); // Make sure that it's not an untitled sketch setUntitled(false); // let Editor know that the save was successful return true; }
/** * 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. */ protected void nameCode(String newName) { // make sure the user didn't hide the sketch folder ensureExistence(); newName = newName.trim(); if (newName.equals("")) return; if (newName.charAt(0) == '.') { Base.showWarning(tr("Problem with rename"), tr("The name cannot start with a period."), null); return; } FileUtils.SplitFile split = FileUtils.splitFilename(newName); if (split.extension.equals("")) split.extension = Sketch.DEFAULT_SKETCH_EXTENSION; if (!Sketch.EXTENSIONS.contains(split.extension)) { String msg = I18n.format(tr("\".{0}\" is not a valid extension."), split.extension); Base.showWarning(tr("Problem with rename"), msg, null); return; } // Sanitize name split.basename = BaseNoGui.sanitizeName(split.basename); newName = split.join(); if (renamingCode) { SketchFile current = editor.getCurrentTab().getSketchFile(); if (current.isPrimary()) { if (!split.extension.equals(Sketch.DEFAULT_SKETCH_EXTENSION)) { Base.showWarning( tr("Problem with rename"), tr("The main file cannot use an extension"), null); return; } // Primary file, rename the entire sketch final File parent = sketch.getFolder().getParentFile(); File newFolder = new File(parent, split.basename); try { sketch.renameTo(newFolder); } catch (IOException e) { // This does not pass on e, to prevent showing a backtrace for // "normal" errors. Base.showWarning(tr("Error"), e.getMessage(), null); return; } editor.base.rebuildSketchbookMenus(); } else { // Non-primary file, rename just that file try { current.renameTo(newName); } catch (IOException e) { // This does not pass on e, to prevent showing a backtrace for // "normal" errors. Base.showWarning(tr("Error"), e.getMessage(), null); return; } } } else { // creating a new file SketchFile file; try { file = sketch.addFile(newName); editor.addTab(file, ""); } catch (IOException e) { // This does not pass on e, to prevent showing a backtrace for // "normal" errors. Base.showWarning(tr("Error"), e.getMessage(), null); return; } editor.selectTab(editor.findTabIndex(file)); } // update the tabs editor.header.rebuild(); }