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 presentHandler;
Runnable runAndSaveHandler;
Runnable presentAndSaveHandler;
Runnable stopHandler;
Runnable exportHandler;
Runnable exportAppHandler;
@ -563,22 +565,6 @@ public class Editor extends JFrame implements RunnerListener {
});
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();
item = newJMenuItemShift(_("Page Setup"), 'P');
@ -638,13 +624,30 @@ public class Editor extends JFrame implements RunnerListener {
});
sketchMenu.add(item);
// item = newJMenuItemShift("Verify / Compile (verbose)", 'R');
// item.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// handleRun(true);
// }
// });
// sketchMenu.add(item);
item = newJMenuItem(_("Upload"), 'U');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleExport(false);
}
});
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.addActionListener(new ActionListener() {
@ -1508,11 +1511,17 @@ public class Editor extends JFrame implements RunnerListener {
// 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 exportHandler, Runnable exportAppHandler) {
Runnable exportHandler,
Runnable exportAppHandler) {
this.runHandler = runHandler;
this.presentHandler = presentHandler;
this.runAndSaveHandler = runAndSaveHandler;
this.presentAndSaveHandler = presentAndSaveHandler;
this.stopHandler = stopHandler;
this.exportHandler = exportHandler;
this.exportAppHandler = exportAppHandler;
@ -1522,6 +1531,8 @@ public class Editor extends JFrame implements RunnerListener {
public void resetHandlers() {
runHandler = new BuildHandler();
presentHandler = new BuildHandler(true);
runAndSaveHandler = new BuildAndSaveHandler();
presentAndSaveHandler = new BuildAndSaveHandler(true);
stopHandler = new DefaultStopHandler();
exportHandler = new DefaultExportHandler();
exportAppHandler = new DefaultExportAppHandler();
@ -2013,6 +2024,29 @@ public class Editor extends JFrame implements RunnerListener {
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 {
private final boolean verbose;
@ -2029,7 +2063,39 @@ public class Editor extends JFrame implements RunnerListener {
public void run() {
try {
sketch.prepare();
sketch.build(verbose);
sketch.build(verbose, false);
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 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(

View File

@ -1133,8 +1133,8 @@ public class Sketch {
* @return null if compilation failed, main class name if not
* @throws RunnerException
*/
public String build(boolean verbose) throws RunnerException, PreferencesMapException {
return build(tempBuildFolder.getAbsolutePath(), verbose);
public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
return build(tempBuildFolder.getAbsolutePath(), verbose, save);
}
/**
@ -1146,7 +1146,7 @@ public class Sketch {
*
* @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
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 {
@ -1177,7 +1177,7 @@ public class Sketch {
// build the 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
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.upload() (see later...)
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);
showMessage(_("Done compiling"), _("Done compiling"));
@ -541,7 +541,7 @@ public class BaseNoGui {
// if (!data.getFolder().exists()) showError(...);
// 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);
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);
showMessage(_("Done compiling"), _("Done compiling"));
} catch (Exception e) {

View File

@ -67,6 +67,7 @@ public class Compiler implements MessageConsumer {
private SketchData sketch;
private PreferencesMap prefs;
private boolean verbose;
private boolean saveHex;
private List<File> objectFiles;
@ -83,7 +84,7 @@ public class Compiler implements MessageConsumer {
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)
BaseNoGui.showError(_("Bad file selected"),
_("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
// that will bubble up to whomever called build().
try {
if (compiler.compile(verbose)) {
if (compiler.compile(verbose, save)) {
compiler.size(compiler.getBuildPreferences());
return primaryClassName;
}
@ -350,10 +351,11 @@ public class Compiler implements MessageConsumer {
* @return true if successful.
* @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"));
verbose = _verbose || PreferencesData.getBoolean("build.verbose");
saveHex = _save;
sketchIsCompiled = false;
// Hook runs at Start of Compilation
@ -399,26 +401,26 @@ public class Compiler implements MessageConsumer {
}
// 1. compile the sketch (already in the buildPath)
progressListener.progress(30);
progressListener.progress(20);
compileSketch(includeFolders);
sketchIsCompiled = true;
// 2. compile the libraries, outputting .o files to: <buildPath>/<library>/
// Doesn't really use configPreferences
progressListener.progress(40);
progressListener.progress(30);
compileLibraries(includeFolders);
// 3. compile the core, outputting .o files to <buildPath> and then
// collecting them into the core.a library file.
progressListener.progress(50);
progressListener.progress(40);
compileCore();
// 4. link it all together into the .elf file
progressListener.progress(60);
progressListener.progress(50);
compileLink();
// 5. run objcopy to generate output files
progressListener.progress(75);
progressListener.progress(60);
List<String> objcopyPatterns = new ArrayList<String>();
for (String key : prefs.keySet()) {
if (key.startsWith("recipe.objcopy.") && key.endsWith(".pattern"))
@ -429,6 +431,12 @@ public class Compiler implements MessageConsumer {
runRecipe(recipe);
}
// 7. save the hex file
if (saveHex) {
progressListener.progress(80);
saveHex();
}
progressListener.progress(90);
// Hook runs at End of Compilation
@ -1145,6 +1153,37 @@ public class Compiler implements MessageConsumer {
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) {
String res = "";
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.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
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
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)
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
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=\.text\s+([0-9]+).*