Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto board selection #10721

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ app/pde.jar
build/macosx/work/
arduino-core/bin/
arduino-core/arduino-core.jar
lib/*
hardware/arduino/bootloaders/caterina_LUFA/Descriptors.o
hardware/arduino/bootloaders/caterina_LUFA/Descriptors.lst
hardware/arduino/bootloaders/caterina_LUFA/Caterina.sym
Expand Down
7 changes: 4 additions & 3 deletions app/src/processing/app/Base.java
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,10 @@ public Base(String[] args) throws Exception {
contributionsSelfCheck = new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), contributionInstaller, libraryInstaller);
new Timer(false).schedule(contributionsSelfCheck, Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD);
}

// Load the build settings
for(Editor editor: editors){
editor.findTab(editor.sketch.getPrimaryFile()).loadBuildSettings(this);
}
} else if (parser.isNoOpMode()) {
// Do nothing (intended for only changing preferences)
System.exit(0);
Expand Down Expand Up @@ -715,10 +718,8 @@ protected int[] nextEditorLocation() {
}
}


// .................................................................


boolean breakTime = false;
String[] months = {
"jan", "feb", "mar", "apr", "may", "jun",
Expand Down
47 changes: 47 additions & 0 deletions app/src/processing/app/Editor.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,34 @@
import processing.app.tools.MenuScroller;
import processing.app.tools.Tool;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.ArrayList;

import static processing.app.I18n.tr;
import static processing.app.Theme.scale;

/**
* Main editor panel for the Processing Development Environment.
*/
Expand Down Expand Up @@ -748,6 +776,10 @@ private JMenu buildToolsMenu() {
item = new JMenuItem(tr("Get Board Info"));
item.addActionListener(e -> handleBoardInfo());
toolsMenu.add(item);

item = new JMenuItem(tr("Add build settings to .INO file"));
item.addActionListener(e -> handleAddBuildSettings());
toolsMenu.add(item);
toolsMenu.addSeparator();

base.rebuildProgrammerMenu();
Expand Down Expand Up @@ -2369,6 +2401,21 @@ public void handlePlotter() {

}

public void handleAddBuildSettings(){
final LinkedHashMap<String, String> settingsMap = base.getBoardsCustomMenus().stream().filter(JMenu::isVisible).map((e)->{
String setting = e.getText().substring(0, e.getText().indexOf(":"));
String value = e.getText().replace(setting + ":", "").replace("\"", "").trim();
return new String[]{setting, value};
}).collect(LinkedHashMap::new, (map, menu) -> map.put(menu[0], menu[1]), LinkedHashMap::putAll);
handleSave(true);
Optional<EditorTab> optionalEditorTab = tabs.stream().filter(tab -> tab.getSketch().getSketch().equals(sketch)).findFirst();
if(optionalEditorTab.isPresent()){
optionalEditorTab.get().setText(sketch.setBuildSettings(sketch, settingsMap));
handleSave(true);
System.out.println("Build settings header should be added");
}
}

private void handleBurnBootloader() {
console.clear();
EditorConsole.setCurrentEditorConsole(this.console);
Expand Down
49 changes: 43 additions & 6 deletions app/src/processing/app/EditorTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.IOException;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Optional;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ToolTipManager;
import javax.swing.*;
import javax.swing.border.MatteBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
Expand All @@ -57,6 +56,8 @@
import org.fife.ui.rtextarea.RTextScrollPane;

import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
import processing.app.debug.TargetBoard;
import processing.app.debug.TargetPackage;
import processing.app.helpers.DocumentTextChangeListener;
import processing.app.syntax.ArduinoTokenMakerFactory;
import processing.app.syntax.PdeKeywords;
Expand Down Expand Up @@ -447,6 +448,42 @@ public void setText(String what) {
textarea.setLineWrap(textarea.getLineWrap());
}


/**
* This method loads the build settings from the main .INO file and sets the Arduino IDE accordingly
*/
public void loadBuildSettings(Base base){

LinkedHashMap<String, String> buildSettings = getSketch().getSketch().getBuildSettingsFromProgram(getText());

Optional<TargetBoard> optionalTargetBoard = BaseNoGui.getTargetPlatform().getBoards().values().stream().filter(board -> board.getPreferences().get("name","").equals("Node32s")).findFirst();

TargetBoard targetBoard;
if(optionalTargetBoard.isPresent()){
targetBoard = optionalTargetBoard.get();
}else{
return;
}

for(String readableName : buildSettings.values()){
base.getBoardsCustomMenus().forEach(menuItem -> {
Optional<JRadioButtonMenuItem> optionalBoardMenuItem = Arrays.stream(menuItem.getMenuComponents()).filter(subItem->{
return subItem instanceof JRadioButtonMenuItem && ((JRadioButtonMenuItem)subItem).getText().equals(readableName) && (((JRadioButtonMenuItem) subItem).getAction().getValue("board") == null || (((JRadioButtonMenuItem) subItem).getAction().getValue("board").equals(targetBoard)));
}
).map(subItem-> {
return subItem instanceof JRadioButtonMenuItem ? (JRadioButtonMenuItem)subItem : new JRadioButtonMenuItem();
}).findFirst();
if(optionalBoardMenuItem.isPresent()){
optionalBoardMenuItem.get().setSelected(true);
optionalBoardMenuItem.get().getAction().actionPerformed(new ActionEvent(this, -1, ""));
}else{
// TODO Ask the user which value should replace the current value

}
});
}
}

/**
* Is the text modified since the last save / load?
*/
Expand Down
105 changes: 105 additions & 0 deletions arduino-core/src/processing/app/Sketch.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,111 @@ public void save() throws IOException {
}
}

private final String buildToolsHeader = "\n/** Arduino IDE Board Tool details\n";
private final String buildToolsHeaderEnd = "*/";

/**
* Checks the code for a valid build tool header
* @param program The code to scan for the build tools
* @return True if the build tool header was found ONE time. Returns false if found MORE than one time, or not found at all.
*/
private boolean containsBuildSettings(String program){
return program.contains(buildToolsHeader) && (program.indexOf(buildToolsHeader) == program.lastIndexOf(buildToolsHeader));
}

/**
* This function returns the index of the Nth occurrence of the substring in the specified string (http://programming.guide/java/nth-occurrence-in-string.html)
* @param str The string to find the Nth occurrence in
* @param substr The string to find
* @param n The occurrence number you'd like to find
* @return
*/
private static int ordinalIndexOf(String str, String substr, int n) {
int pos = str.indexOf(substr);
while (--n > 0 && pos != -1)
pos = str.indexOf(substr, pos + 1);
return pos;
}

private String removeBuildSettingsHeader(Sketch sketch){
if(sketch.getPrimaryFile().getProgram().contains(buildToolsHeader)) {
int headerStartIndex = sketch.getPrimaryFile().getProgram().indexOf(buildToolsHeader);
int headerStopIndex = sketch.getPrimaryFile().getProgram().indexOf(buildToolsHeaderEnd);
if (headerStartIndex > headerStopIndex) {
System.err.println("The build tool header is not the first comment block in your file! Please fix this.");
for (int i = 0; i < sketch.getPrimaryFile().getProgram().length(); i++) {
if (headerStartIndex < ordinalIndexOf(sketch.getPrimaryFile().getProgram(), buildToolsHeaderEnd, i)) {
headerStopIndex = ordinalIndexOf(sketch.getPrimaryFile().getProgram(), buildToolsHeaderEnd, i);
break;
}
}
}
String header = sketch.getPrimaryFile().getProgram().substring(headerStartIndex, headerStopIndex + buildToolsHeaderEnd.length());
return sketch.getPrimaryFile().getProgram().replace(header, "");
}
return sketch.getPrimaryFile().getProgram();
}

/**
* This checks the program code for a valid build tool settings header and returns the LinkedHashMap with the setting name and the value.
* The build tools header should not be changed or manipulated by the pre-processor as the pre-processors output may depend on the build tools.
* @param program The program code
* @return The {@code LinkedHashMap} with the settings and their values of the <b>first</b> header that was found in the program code
*/
public LinkedHashMap<String, String> getBuildSettingsFromProgram(String program){
LinkedHashMap<String, String> buildSettings = new LinkedHashMap<>();
if(containsBuildSettings(program)){
int headerStartIndex = program.indexOf(buildToolsHeader);
int headerStopIndex = program.indexOf(buildToolsHeaderEnd);
if(headerStartIndex > headerStopIndex){
System.err.println("The build tool header is not the first comment block in your file! Please fix this.");
for(int i = 0; i < program.length(); i++){
if(headerStartIndex < ordinalIndexOf(program, buildToolsHeaderEnd, i)){
headerStopIndex = ordinalIndexOf(program, buildToolsHeaderEnd, i);
break;
}
}
}
String header = program.substring(headerStartIndex + buildToolsHeader.length(), headerStopIndex);

String[] headerLines = header.split("\n");

for(int line = 0; line < headerLines.length; line++){
String[] setting = headerLines[line].replace("*","").trim().split(": ");
if(headerLines[line].indexOf(": ") != (headerLines[line].length() -1)){
// The value of the setting is not empty
buildSettings.put(setting[0].trim(), setting[1].trim());
}else{
buildSettings.put(setting[0], "");
}
}
}else{
if(!program.contains(buildToolsHeader)){
// There are multiple headers, remove them
// TODO Create a dialog asking the user to add a build header to the file
}
}

return buildSettings;
}

private boolean isBuildSettingsEqual(LinkedHashMap<String,String> first, LinkedHashMap<String, String> second){
return first.keySet().containsAll(second.keySet()) && first.values().containsAll(second.values());
}

public String setBuildSettings(Sketch sketch, LinkedHashMap<String, String> buildSettings){
if(sketch != this){
return "";
}

String customBoardSettingsHeader = buildSettings.entrySet().stream().map(entry-> String.format(" * %s: %s\n", entry.getKey(), entry.getValue())).collect(Collectors.joining("", buildToolsHeader, "*/"));
if(!isBuildSettingsEqual(getBuildSettingsFromProgram(sketch.getPrimaryFile().getProgram()),buildSettings)){
String headerLessProgram = removeBuildSettingsHeader(sketch);
return customBoardSettingsHeader + ((headerLessProgram.charAt(0) == '\n') ? "" : "\n") + headerLessProgram;
}
return "";
}

public int getCodeCount() {
return files.size();
}
Expand Down
6 changes: 5 additions & 1 deletion build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/** Arduino IDE Board Tool details
* Board: Arduino/Genuino Uno
*/

void setup() {
// put your setup code here, to run once:

Expand All @@ -6,4 +10,4 @@ void setup() {
void loop() {
// put your main code here, to run repeatedly:

}
}