1- import { inject , injectable } from 'inversify' ;
1+ import { inject , injectable , postConstruct } from 'inversify' ;
22import { Emitter } from '@theia/core/lib/common/event' ;
3- import { CoreService } from '../../common/protocol' ;
3+ import { BoardUserField , CoreService } from '../../common/protocol' ;
44import { ArduinoMenus } from '../menu/arduino-menus' ;
55import { ArduinoToolbar } from '../toolbar/arduino-toolbar' ;
66import { BoardsDataStore } from '../boards/boards-data-store' ;
@@ -14,6 +14,7 @@ import {
1414 KeybindingRegistry ,
1515 TabBarToolbarRegistry ,
1616} from './contribution' ;
17+ import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog' ;
1718
1819@injectable ( )
1920export class UploadSketch extends SketchContribution {
@@ -29,16 +30,81 @@ export class UploadSketch extends SketchContribution {
2930 @inject ( BoardsServiceProvider )
3031 protected readonly boardsServiceClientImpl : BoardsServiceProvider ;
3132
33+ @inject ( UserFieldsDialog )
34+ protected readonly userFieldsDialog : UserFieldsDialog ;
35+
36+ protected cachedUserFields : Map < string , BoardUserField [ ] > = new Map ( ) ;
37+
3238 protected readonly onDidChangeEmitter = new Emitter < Readonly < void > > ( ) ;
3339 readonly onDidChange = this . onDidChangeEmitter . event ;
3440
3541 protected uploadInProgress = false ;
42+ protected boardRequiresUserFields = false ;
43+
44+ @postConstruct ( )
45+ protected init ( ) : void {
46+ this . boardsServiceClientImpl . onBoardsConfigChanged ( async ( ) => {
47+ const userFields = await this . boardsServiceClientImpl . selectedBoardUserFields ( ) ;
48+ this . boardRequiresUserFields = userFields . length > 0 ;
49+ } )
50+ }
51+
52+ private selectedFqbnAddress ( ) : string {
53+ const { boardsConfig } = this . boardsServiceClientImpl ;
54+ const fqbn = boardsConfig . selectedBoard ?. fqbn ;
55+ if ( ! fqbn ) {
56+ return "" ;
57+ }
58+ const address = boardsConfig . selectedBoard ?. port ?. address
59+ if ( ! address ) {
60+ return "" ;
61+ }
62+ return fqbn + "|" + address ;
63+ }
3664
3765 registerCommands ( registry : CommandRegistry ) : void {
3866 registry . registerCommand ( UploadSketch . Commands . UPLOAD_SKETCH , {
39- execute : ( ) => this . uploadSketch ( ) ,
67+ execute : async ( ) => {
68+ const key = this . selectedFqbnAddress ( ) ;
69+ if ( ! key ) {
70+ return ;
71+ }
72+ if ( this . boardRequiresUserFields && ! this . cachedUserFields . has ( key ) ) {
73+ // Deep clone the array of board fields to avoid editing the cached ones
74+ this . userFieldsDialog . value = ( await this . boardsServiceClientImpl . selectedBoardUserFields ( ) ) . map ( f => ( { ...f } ) ) ;
75+ const result = await this . userFieldsDialog . open ( ) ;
76+ if ( ! result ) {
77+ return ;
78+ }
79+ this . cachedUserFields . set ( key , result ) ;
80+ }
81+ this . uploadSketch ( ) ;
82+ } ,
4083 isEnabled : ( ) => ! this . uploadInProgress ,
4184 } ) ;
85+ registry . registerCommand (
86+ UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION ,
87+ {
88+ execute : async ( ) => {
89+ const key = this . selectedFqbnAddress ( ) ;
90+ if ( ! key ) {
91+ return ;
92+ }
93+
94+ const cached = this . cachedUserFields . get ( key ) ;
95+ // Deep clone the array of board fields to avoid editing the cached ones
96+ this . userFieldsDialog . value = ( cached ?? await this . boardsServiceClientImpl . selectedBoardUserFields ( ) ) . map ( f => ( { ...f } ) ) ;
97+
98+ const result = await this . userFieldsDialog . open ( )
99+ if ( ! result ) {
100+ return ;
101+ }
102+ this . cachedUserFields . set ( key , result ) ;
103+ this . uploadSketch ( ) ;
104+ } ,
105+ isEnabled : ( ) => ! this . uploadInProgress && this . boardRequiresUserFields ,
106+ }
107+ ) ;
42108 registry . registerCommand (
43109 UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER ,
44110 {
@@ -62,10 +128,15 @@ export class UploadSketch extends SketchContribution {
62128 label : 'Upload' ,
63129 order : '1' ,
64130 } ) ;
131+ registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
132+ commandId : UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION . id ,
133+ label : UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION . label ,
134+ order : '2' ,
135+ } ) ;
65136 registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
66137 commandId : UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER . id ,
67138 label : 'Upload Using Programmer' ,
68- order : '2 ' ,
139+ order : '3 ' ,
69140 } ) ;
70141 }
71142
@@ -131,6 +202,11 @@ export class UploadSketch extends SketchContribution {
131202 const optimizeForDebug = this . editorMode . compileForDebug ;
132203 const { selectedPort } = boardsConfig ;
133204 const port = selectedPort ;
205+ const userFields = this . cachedUserFields . get ( this . selectedFqbnAddress ( ) ) ;
206+ if ( ! userFields ) {
207+ this . messageService . error ( "Can't find user fields for connected board" ) ;
208+ return ;
209+ }
134210
135211 if ( usingProgrammer ) {
136212 const programmer = selectedProgrammer ;
@@ -143,6 +219,7 @@ export class UploadSketch extends SketchContribution {
143219 verbose,
144220 verify,
145221 sourceOverride,
222+ userFields,
146223 } ;
147224 } else {
148225 options = {
@@ -153,6 +230,7 @@ export class UploadSketch extends SketchContribution {
153230 verbose,
154231 verify,
155232 sourceOverride,
233+ userFields,
156234 } ;
157235 }
158236 this . outputChannelManager . getChannel ( 'Arduino' ) . clear ( ) ;
@@ -196,6 +274,11 @@ export namespace UploadSketch {
196274 export const UPLOAD_SKETCH : Command = {
197275 id : 'arduino-upload-sketch' ,
198276 } ;
277+ export const UPLOAD_WITH_CONFIGURATION : Command = {
278+ id : 'arduino-upload-with-configuration-sketch' ,
279+ label : 'Configure And Upload' ,
280+ category : 'Arduino' ,
281+ }
199282 export const UPLOAD_SKETCH_USING_PROGRAMMER : Command = {
200283 id : 'arduino-upload-sketch-using-programmer' ,
201284 } ;
0 commit comments