1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-29 10:24:12 +01:00

update Sketch menu, add Save hex option

* Moving Upload options from "File" menu to "Sketch" menu as those
     are sketch actions more than file actions.

Signed-off-by: Arnav Gupta <championswimmer@gmail.com>
This commit is contained in:
Arnav Gupta 2015-01-23 08:30:46 +05:30 committed by Federico Fissore
parent 11327bb3a6
commit 78936541b7
6 changed files with 154 additions and 41 deletions

View File

@ -152,6 +152,8 @@ public class Editor extends JFrame implements RunnerListener {
Runnable runHandler; Runnable runHandler;
Runnable presentHandler; Runnable presentHandler;
Runnable runAndSaveHandler;
Runnable presentAndSaveHandler;
Runnable stopHandler; Runnable stopHandler;
Runnable exportHandler; Runnable exportHandler;
Runnable exportAppHandler; Runnable exportAppHandler;
@ -563,22 +565,6 @@ public class Editor extends JFrame implements RunnerListener {
}); });
fileMenu.add(saveAsMenuItem); fileMenu.add(saveAsMenuItem);
item = newJMenuItem(_("Upload"), 'U');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleExport(false);
}
});
fileMenu.add(item);
item = newJMenuItemShift(_("Upload Using Programmer"), 'U');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleExport(true);
}
});
fileMenu.add(item);
fileMenu.addSeparator(); fileMenu.addSeparator();
item = newJMenuItemShift(_("Page Setup"), 'P'); item = newJMenuItemShift(_("Page Setup"), 'P');
@ -638,13 +624,30 @@ public class Editor extends JFrame implements RunnerListener {
}); });
sketchMenu.add(item); sketchMenu.add(item);
// item = newJMenuItemShift("Verify / Compile (verbose)", 'R'); item = newJMenuItem(_("Upload"), 'U');
// item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
// handleRun(true); handleExport(false);
// } }
// }); });
// sketchMenu.add(item); sketchMenu.add(item);
item = newJMenuItemShift(_("Upload Using Programmer"), 'U');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleExport(true);
}
});
sketchMenu.add(item);
item = newJMenuItemAlt("Export compiled Binary", 'S');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleRunAndSave(true);
}
});
sketchMenu.add(item);
// item = new JMenuItem("Stop"); // item = new JMenuItem("Stop");
// item.addActionListener(new ActionListener() { // item.addActionListener(new ActionListener() {
@ -1508,11 +1511,17 @@ public class Editor extends JFrame implements RunnerListener {
// abstract from the editor in this fashion. // abstract from the editor in this fashion.
public void setHandlers(Runnable runHandler, Runnable presentHandler, public void setHandlers(Runnable runHandler,
Runnable presentHandler,
Runnable runAndSaveHandler,
Runnable presentAndSaveHandler,
Runnable stopHandler, Runnable stopHandler,
Runnable exportHandler, Runnable exportAppHandler) { Runnable exportHandler,
Runnable exportAppHandler) {
this.runHandler = runHandler; this.runHandler = runHandler;
this.presentHandler = presentHandler; this.presentHandler = presentHandler;
this.runAndSaveHandler = runAndSaveHandler;
this.presentAndSaveHandler = presentAndSaveHandler;
this.stopHandler = stopHandler; this.stopHandler = stopHandler;
this.exportHandler = exportHandler; this.exportHandler = exportHandler;
this.exportAppHandler = exportAppHandler; this.exportAppHandler = exportAppHandler;
@ -1522,6 +1531,8 @@ public class Editor extends JFrame implements RunnerListener {
public void resetHandlers() { public void resetHandlers() {
runHandler = new BuildHandler(); runHandler = new BuildHandler();
presentHandler = new BuildHandler(true); presentHandler = new BuildHandler(true);
runAndSaveHandler = new BuildAndSaveHandler();
presentAndSaveHandler = new BuildAndSaveHandler(true);
stopHandler = new DefaultStopHandler(); stopHandler = new DefaultStopHandler();
exportHandler = new DefaultExportHandler(); exportHandler = new DefaultExportHandler();
exportAppHandler = new DefaultExportAppHandler(); exportAppHandler = new DefaultExportAppHandler();
@ -2013,6 +2024,29 @@ public class Editor extends JFrame implements RunnerListener {
new Thread(verbose ? presentHandler : runHandler).start(); new Thread(verbose ? presentHandler : runHandler).start();
} }
/**
* Implements Sketch &rarr; Run and Save.
* @param verbose Set true to run with verbose output.
*/
public void handleRunAndSave(final boolean verbose) {
internalCloseRunner();
running = true;
toolbar.activate(EditorToolbar.RUN);
status.progress(_("Compiling sketch..."));
// do this to advance/clear the terminal window / dos prompt / etc
for (int i = 0; i < 10; i++) System.out.println();
// clear the console on each run, unless the user doesn't want to
if (Preferences.getBoolean("console.auto_clear")) {
console.clear();
}
// Cannot use invokeLater() here, otherwise it gets
// placed on the event thread and causes a hang--bad idea all around.
new Thread(verbose ? presentAndSaveHandler : runAndSaveHandler).start();
}
class BuildHandler implements Runnable { class BuildHandler implements Runnable {
private final boolean verbose; private final boolean verbose;
@ -2029,7 +2063,7 @@ public class Editor extends JFrame implements RunnerListener {
public void run() { public void run() {
try { try {
sketch.prepare(); sketch.prepare();
sketch.build(verbose); sketch.build(verbose, false);
statusNotice(_("Done compiling.")); statusNotice(_("Done compiling."));
} catch (PreferencesMapException e) { } catch (PreferencesMapException e) {
statusError(I18n.format( statusError(I18n.format(
@ -2045,6 +2079,38 @@ public class Editor extends JFrame implements RunnerListener {
} }
} }
class BuildAndSaveHandler implements Runnable {
private final boolean verbose;
public BuildAndSaveHandler() {
this(false);
}
public BuildAndSaveHandler(boolean verbose) {
this.verbose = verbose;
}
@Override
public void run() {
try {
sketch.prepare();
sketch.build(verbose, true);
statusNotice(_("Done compiling."));
} catch (PreferencesMapException e) {
statusError(I18n.format(
_("Error while compiling: missing '{0}' configuration parameter"),
e.getMessage()));
} catch (Exception e) {
status.unprogress();
statusError(e);
}
status.unprogress();
toolbar.deactivate(EditorToolbar.RUN);
}
}
class DefaultStopHandler implements Runnable { class DefaultStopHandler implements Runnable {
public void run() { public void run() {
// TODO // TODO

View File

@ -1133,8 +1133,8 @@ public class Sketch {
* @return null if compilation failed, main class name if not * @return null if compilation failed, main class name if not
* @throws RunnerException * @throws RunnerException
*/ */
public String build(boolean verbose) throws RunnerException, PreferencesMapException { public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
return build(tempBuildFolder.getAbsolutePath(), verbose); return build(tempBuildFolder.getAbsolutePath(), verbose, save);
} }
/** /**
@ -1146,7 +1146,7 @@ public class Sketch {
* *
* @return null if compilation failed, main class name if not * @return null if compilation failed, main class name if not
*/ */
public String build(String buildPath, boolean verbose) throws RunnerException, PreferencesMapException { public String build(String buildPath, boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
// run the preprocessor // run the preprocessor
editor.status.progressUpdate(20); editor.status.progressUpdate(20);
@ -1159,7 +1159,7 @@ public class Sketch {
} }
}; };
return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose); return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose, save);
} }
protected boolean exportApplet(boolean usingProgrammer) throws Exception { protected boolean exportApplet(boolean usingProgrammer) throws Exception {
@ -1177,7 +1177,7 @@ public class Sketch {
// build the sketch // build the sketch
editor.status.progressNotice(_("Compiling sketch...")); editor.status.progressNotice(_("Compiling sketch..."));
String foundName = build(appletPath, false); String foundName = build(appletPath, false, false);
// (already reported) error during export, exit this function // (already reported) error during export, exit this function
if (foundName == null) return false; if (foundName == null) return false;

View File

@ -496,7 +496,7 @@ public class BaseNoGui {
// - calls Sketch.build(verbose=false) that calls Sketch.ensureExistence(), set progressListener and calls Compiler.build() // - calls Sketch.build(verbose=false) that calls Sketch.ensureExistence(), set progressListener and calls Compiler.build()
// - calls Sketch.upload() (see later...) // - calls Sketch.upload() (see later...)
if (!data.getFolder().exists()) showError(_("No sketch"), _("Can't find the sketch in the specified path"), null); if (!data.getFolder().exists()) showError(_("No sketch"), _("Can't find the sketch in the specified path"), null);
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild()); String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild(), false);
if (suggestedClassName == null) showError(_("Error while verifying"), _("An error occurred while verifying the sketch"), null); if (suggestedClassName == null) showError(_("Error while verifying"), _("An error occurred while verifying the sketch"), null);
showMessage(_("Done compiling"), _("Done compiling")); showMessage(_("Done compiling"), _("Done compiling"));
@ -541,7 +541,7 @@ public class BaseNoGui {
// if (!data.getFolder().exists()) showError(...); // if (!data.getFolder().exists()) showError(...);
// String ... = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, verbose); // String ... = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, verbose);
if (!data.getFolder().exists()) showError(_("No sketch"), _("Can't find the sketch in the specified path"), null); if (!data.getFolder().exists()) showError(_("No sketch"), _("Can't find the sketch in the specified path"), null);
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild()); String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild(), false);
if (suggestedClassName == null) showError(_("Error while verifying"), _("An error occurred while verifying the sketch"), null); if (suggestedClassName == null) showError(_("Error while verifying"), _("An error occurred while verifying the sketch"), null);
showMessage(_("Done compiling"), _("Done compiling")); showMessage(_("Done compiling"), _("Done compiling"));
} catch (Exception e) { } catch (Exception e) {

View File

@ -67,6 +67,7 @@ public class Compiler implements MessageConsumer {
private SketchData sketch; private SketchData sketch;
private PreferencesMap prefs; private PreferencesMap prefs;
private boolean verbose; private boolean verbose;
private boolean saveHex;
private List<File> objectFiles; private List<File> objectFiles;
@ -83,7 +84,7 @@ public class Compiler implements MessageConsumer {
private ProgressListener progressListener; private ProgressListener progressListener;
static public String build(SketchData data, String buildPath, File tempBuildFolder, ProgressListener progListener, boolean verbose) throws RunnerException, PreferencesMapException { static public String build(SketchData data, String buildPath, File tempBuildFolder, ProgressListener progListener, boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
if (SketchData.checkSketchFile(data.getPrimaryFile()) == null) if (SketchData.checkSketchFile(data.getPrimaryFile()) == null)
BaseNoGui.showError(_("Bad file selected"), BaseNoGui.showError(_("Bad file selected"),
_("Bad sketch primary file or bad sketch directory structure"), null); _("Bad sketch primary file or bad sketch directory structure"), null);
@ -113,7 +114,7 @@ public class Compiler implements MessageConsumer {
// compile the program. errors will happen as a RunnerException // compile the program. errors will happen as a RunnerException
// that will bubble up to whomever called build(). // that will bubble up to whomever called build().
try { try {
if (compiler.compile(verbose)) { if (compiler.compile(verbose, save)) {
compiler.size(compiler.getBuildPreferences()); compiler.size(compiler.getBuildPreferences());
return primaryClassName; return primaryClassName;
} }
@ -350,10 +351,11 @@ public class Compiler implements MessageConsumer {
* @return true if successful. * @return true if successful.
* @throws RunnerException Only if there's a problem. Only then. * @throws RunnerException Only if there's a problem. Only then.
*/ */
public boolean compile(boolean _verbose) throws RunnerException, PreferencesMapException { public boolean compile(boolean _verbose, boolean _save) throws RunnerException, PreferencesMapException {
preprocess(prefs.get("build.path")); preprocess(prefs.get("build.path"));
verbose = _verbose || PreferencesData.getBoolean("build.verbose"); verbose = _verbose || PreferencesData.getBoolean("build.verbose");
saveHex = _save;
sketchIsCompiled = false; sketchIsCompiled = false;
// Hook runs at Start of Compilation // Hook runs at Start of Compilation
@ -399,26 +401,26 @@ public class Compiler implements MessageConsumer {
} }
// 1. compile the sketch (already in the buildPath) // 1. compile the sketch (already in the buildPath)
progressListener.progress(30); progressListener.progress(20);
compileSketch(includeFolders); compileSketch(includeFolders);
sketchIsCompiled = true; sketchIsCompiled = true;
// 2. compile the libraries, outputting .o files to: <buildPath>/<library>/ // 2. compile the libraries, outputting .o files to: <buildPath>/<library>/
// Doesn't really use configPreferences // Doesn't really use configPreferences
progressListener.progress(40); progressListener.progress(30);
compileLibraries(includeFolders); compileLibraries(includeFolders);
// 3. compile the core, outputting .o files to <buildPath> and then // 3. compile the core, outputting .o files to <buildPath> and then
// collecting them into the core.a library file. // collecting them into the core.a library file.
progressListener.progress(50); progressListener.progress(40);
compileCore(); compileCore();
// 4. link it all together into the .elf file // 4. link it all together into the .elf file
progressListener.progress(60); progressListener.progress(50);
compileLink(); compileLink();
// 5. run objcopy to generate output files // 5. run objcopy to generate output files
progressListener.progress(75); progressListener.progress(60);
List<String> objcopyPatterns = new ArrayList<String>(); List<String> objcopyPatterns = new ArrayList<String>();
for (String key : prefs.keySet()) { for (String key : prefs.keySet()) {
if (key.startsWith("recipe.objcopy.") && key.endsWith(".pattern")) if (key.startsWith("recipe.objcopy.") && key.endsWith(".pattern"))
@ -429,6 +431,12 @@ public class Compiler implements MessageConsumer {
runRecipe(recipe); runRecipe(recipe);
} }
// 7. save the hex file
if (saveHex) {
progressListener.progress(80);
saveHex();
}
progressListener.progress(90); progressListener.progress(90);
// Hook runs at End of Compilation // Hook runs at End of Compilation
@ -1145,6 +1153,37 @@ public class Compiler implements MessageConsumer {
execAsynchronously(cmdArray); execAsynchronously(cmdArray);
} }
//7. Save the .hex file
void saveHex() throws RunnerException {
PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + BaseNoGui.REVISION);
String[] cmdArray;
try {
String tmp_file = prefs.getOrExcept("recipe.hex.tmp_file");
tmp_file = StringReplacer.replaceFromMapping(tmp_file, dict);
String save_file = prefs.getOrExcept("recipe.hex.save_file");
save_file = StringReplacer.replaceFromMapping(save_file, dict);
File hexFile = new File(prefs.get("build.path") + "/" + tmp_file);
File saveFile = new File(sketch.getFolder().getAbsolutePath() + "/" + save_file);
FileReader in = new FileReader(hexFile);
FileWriter out = new FileWriter(saveFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
} catch (Exception e) {
throw new RunnerException(e);
}
}
private static String prepareIncludes(List<File> includeFolders) { private static String prepareIncludes(List<File> includeFolders) {
String res = ""; String res = "";
for (File p : includeFolders) for (File p : includeFolders)

View File

@ -71,6 +71,10 @@ recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.f
recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep" recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
## Save hex
recipe.hex.tmp_file={build.project_name}.hex
recipe.hex.save_file={build.project_name}.{build.variant}.hex
## Compute size ## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*

View File

@ -75,6 +75,10 @@ recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.f
## Create output (.bin file) ## Create output (.bin file)
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
## Save hex
recipe.hex.tmp_file={build.project_name}.bin
recipe.hex.save_file={build.project_name}.{build.variant}.bin
## Compute size ## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=\.text\s+([0-9]+).* recipe.size.regex=\.text\s+([0-9]+).*