From 3f1fbadc4a406ebcd67addaaa848d8fae7627de0 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Mon, 19 Mar 2018 21:37:43 +0100 Subject: [PATCH 1/4] First version of the auto board selector. Working! --- app/src/processing/app/Base.java | 6 +- app/src/processing/app/Editor.java | 17 ++++ app/src/processing/app/EditorTab.java | 49 +++++++-- arduino-core/src/processing/app/Sketch.java | 105 ++++++++++++++++++++ 4 files changed, 169 insertions(+), 8 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 1752e1dc824..468594c4f30 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -477,7 +477,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); @@ -1496,6 +1499,7 @@ public void actionPerformed(ActionEvent actionevent) { } } + private JRadioButtonMenuItem createBoardMenusAndCustomMenus( final List boardsCustomMenus, List menuItemsToClickAfterStartup, Map buttonGroupsMap, diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 99e53e488dc..102d652c737 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -65,6 +65,7 @@ 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; @@ -339,6 +340,7 @@ public void windowDeactivated(WindowEvent e) { // Open the document that was passed in boolean loaded = handleOpenInternal(file); if (!loaded) sketchController = null; + } @@ -764,6 +766,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(); @@ -2512,6 +2518,17 @@ public void handlePlotter() { } + public void handleAddBuildSettings(){ + final LinkedHashMap 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); + sketch.setBuildSettings(findTab(sketch.getPrimaryFile()), settingsMap); + handleSave(true); + System.out.println("Build settings header should be added"); + } + private void handleBurnBootloader() { console.clear(); statusNotice(tr("Burning bootloader to I/O Board (this may take a minute)...")); diff --git a/app/src/processing/app/EditorTab.java b/app/src/processing/app/EditorTab.java index 33dabdbbbc2..b190d9b6e34 100644 --- a/app/src/processing/app/EditorTab.java +++ b/app/src/processing/app/EditorTab.java @@ -34,13 +34,12 @@ import java.awt.event.MouseWheelEvent; 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; @@ -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; @@ -109,7 +110,7 @@ public EditorTab(Editor editor, SketchFile file, String contents) file.setStorage(this); applyPreferences(); add(scrollPane, BorderLayout.CENTER); - textarea.addMouseWheelListener(this); + textarea.addMouseWheelListener(this); } private RSyntaxDocument createDocument(String contents) { @@ -433,6 +434,40 @@ public void setText(String what) { } } + /** + * This method loads the build settings from the main .INO file and sets the Arduino IDE accordingly + */ + public void loadBuildSettings(Base base){ + + LinkedHashMap buildSettings = getSketch().getSketch().getBuildSettingsFromProgram(getText()); + + Optional 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 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? */ diff --git a/arduino-core/src/processing/app/Sketch.java b/arduino-core/src/processing/app/Sketch.java index 6c417403ec9..c7ee9c9cbea 100644 --- a/arduino-core/src/processing/app/Sketch.java +++ b/arduino-core/src/processing/app/Sketch.java @@ -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 void removeBuildSettingsHeader(EditorTab tab){ + if(tab.getText().contains(buildToolsHeader)) { + int headerStartIndex = tab.getText().indexOf(buildToolsHeader); + int headerStopIndex = tab.getText().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 < tab.getText().length(); i++) { + if (headerStartIndex < ordinalIndexOf(tab.getText(), buildToolsHeaderEnd, i)) { + headerStopIndex = ordinalIndexOf(tab.getText(), buildToolsHeaderEnd, i); + break; + } + } + } + String header = tab.getText().substring(headerStartIndex, headerStopIndex + buildToolsHeaderEnd.length()); + tab.setText(tab.getText().replace(header, "")); + // Run this method again so we are sure that there aren't any headers left + removeBuildSettingsHeader(tab); + } + } + + /** + * 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 first header that was found in the program code + */ + public LinkedHashMap getBuildSettingsFromProgram(String program){ + LinkedHashMap 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 first, LinkedHashMap second){ + return first.keySet().containsAll(second.keySet()) && first.values().containsAll(second.values()); + } + + public void setBuildSettings(EditorTab tab, LinkedHashMap buildSettings){ + if(tab.getSketch().getSketch() != 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(tab.getText()),buildSettings)){ + removeBuildSettingsHeader(tab); + tab.setText(customBoardSettingsHeader + ((tab.getText().charAt(0) == '\n') ? "" : "\n") + tab.getText()); + } + } + public int getCodeCount() { return files.size(); } From 0b2982c73802cca30f96a3434f9dc557471f86d6 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 20 Mar 2018 15:06:01 +0100 Subject: [PATCH 2/4] Little formatting fix and added the Arduino/Genuino Uno as the default header for the sketch --- .gitignore | 1 + app/src/processing/app/Base.java | 2 -- app/src/processing/app/EditorTab.java | 1 + build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino | 6 +++++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0ff213c4047..5f5d747e730 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 468594c4f30..5cfb8dc0f4c 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -680,10 +680,8 @@ protected int[] nextEditorLocation() { } } - // ................................................................. - boolean breakTime = false; String[] months = { "jan", "feb", "mar", "apr", "may", "jun", diff --git a/app/src/processing/app/EditorTab.java b/app/src/processing/app/EditorTab.java index b190d9b6e34..54d17f3a9e3 100644 --- a/app/src/processing/app/EditorTab.java +++ b/app/src/processing/app/EditorTab.java @@ -463,6 +463,7 @@ public void loadBuildSettings(Base base){ optionalBoardMenuItem.get().getAction().actionPerformed(new ActionEvent(this, -1, "")); }else{ // TODO Ask the user which value should replace the current value + } }); } diff --git a/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino b/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino index 95c2b6eb0a8..6586e6e69ab 100644 --- a/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino +++ b/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino @@ -1,3 +1,7 @@ +/** Arduino IDE Board Tool details + * Board: Arduino/Genuino Uno +*/ + void setup() { // put your setup code here, to run once: @@ -6,4 +10,4 @@ void setup() { void loop() { // put your main code here, to run repeatedly: -} +} \ No newline at end of file From 18b401660d804f1f9cde7ff1aa2302b1264d466b Mon Sep 17 00:00:00 2001 From: timkoers Date: Tue, 20 Mar 2018 16:40:54 +0100 Subject: [PATCH 3/4] Update Sketch.java This should fix the build error --- arduino-core/src/processing/app/Sketch.java | 1 + 1 file changed, 1 insertion(+) diff --git a/arduino-core/src/processing/app/Sketch.java b/arduino-core/src/processing/app/Sketch.java index c7ee9c9cbea..8c02ba50758 100644 --- a/arduino-core/src/processing/app/Sketch.java +++ b/arduino-core/src/processing/app/Sketch.java @@ -9,6 +9,7 @@ import cc.arduino.files.DeleteFilesOnShutdown; import processing.app.helpers.FileUtils; +import processing.app.EditorTab; import static processing.app.I18n.tr; From 9f1dcee2c58c6aea5732b365486125e2a215c3a0 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 20 Mar 2018 19:08:59 +0100 Subject: [PATCH 4/4] The Java compilation error has been fixed --- app/src/processing/app/Editor.java | 10 ++++-- app/src/processing/app/EditorTab.java | 1 + arduino-core/src/processing/app/Sketch.java | 35 ++++++++++----------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 102d652c737..cd9c49e9382 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2524,9 +2524,13 @@ public void handleAddBuildSettings(){ 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); - sketch.setBuildSettings(findTab(sketch.getPrimaryFile()), settingsMap); - handleSave(true); - System.out.println("Build settings header should be added"); + handleSave(true); + Optional 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() { diff --git a/app/src/processing/app/EditorTab.java b/app/src/processing/app/EditorTab.java index 54d17f3a9e3..07ac0020aa0 100644 --- a/app/src/processing/app/EditorTab.java +++ b/app/src/processing/app/EditorTab.java @@ -434,6 +434,7 @@ public void setText(String what) { } } + /** * This method loads the build settings from the main .INO file and sets the Arduino IDE accordingly */ diff --git a/arduino-core/src/processing/app/Sketch.java b/arduino-core/src/processing/app/Sketch.java index 8c02ba50758..c9c42bc7f59 100644 --- a/arduino-core/src/processing/app/Sketch.java +++ b/arduino-core/src/processing/app/Sketch.java @@ -9,7 +9,6 @@ import cc.arduino.files.DeleteFilesOnShutdown; import processing.app.helpers.FileUtils; -import processing.app.EditorTab; import static processing.app.I18n.tr; @@ -166,24 +165,23 @@ private static int ordinalIndexOf(String str, String substr, int n) { return pos; } - private void removeBuildSettingsHeader(EditorTab tab){ - if(tab.getText().contains(buildToolsHeader)) { - int headerStartIndex = tab.getText().indexOf(buildToolsHeader); - int headerStopIndex = tab.getText().indexOf(buildToolsHeaderEnd); + 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 < tab.getText().length(); i++) { - if (headerStartIndex < ordinalIndexOf(tab.getText(), buildToolsHeaderEnd, i)) { - headerStopIndex = ordinalIndexOf(tab.getText(), buildToolsHeaderEnd, i); + 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 = tab.getText().substring(headerStartIndex, headerStopIndex + buildToolsHeaderEnd.length()); - tab.setText(tab.getText().replace(header, "")); - // Run this method again so we are sure that there aren't any headers left - removeBuildSettingsHeader(tab); + String header = sketch.getPrimaryFile().getProgram().substring(headerStartIndex, headerStopIndex + buildToolsHeaderEnd.length()); + return sketch.getPrimaryFile().getProgram().replace(header, ""); } + return sketch.getPrimaryFile().getProgram(); } /** @@ -233,16 +231,17 @@ private boolean isBuildSettingsEqual(LinkedHashMap first, LinkedH return first.keySet().containsAll(second.keySet()) && first.values().containsAll(second.values()); } - public void setBuildSettings(EditorTab tab, LinkedHashMap buildSettings){ - if(tab.getSketch().getSketch() != this){ - return; + public String setBuildSettings(Sketch sketch, LinkedHashMap 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(tab.getText()),buildSettings)){ - removeBuildSettingsHeader(tab); - tab.setText(customBoardSettingsHeader + ((tab.getText().charAt(0) == '\n') ? "" : "\n") + tab.getText()); + if(!isBuildSettingsEqual(getBuildSettingsFromProgram(sketch.getPrimaryFile().getProgram()),buildSettings)){ + String headerLessProgram = removeBuildSettingsHeader(sketch); + return customBoardSettingsHeader + ((headerLessProgram.charAt(0) == '\n') ? "" : "\n") + headerLessProgram; } + return ""; } public int getCodeCount() { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy