1
- import { inject , injectable } from 'inversify' ;
1
+ import { inject , injectable , postConstruct } from 'inversify' ;
2
2
import { Emitter } from '@theia/core/lib/common/event' ;
3
- import { CoreService } from '../../common/protocol' ;
3
+ import { BoardUserField , CoreService } from '../../common/protocol' ;
4
4
import { ArduinoMenus } from '../menu/arduino-menus' ;
5
5
import { ArduinoToolbar } from '../toolbar/arduino-toolbar' ;
6
6
import { BoardsDataStore } from '../boards/boards-data-store' ;
@@ -14,6 +14,7 @@ import {
14
14
KeybindingRegistry ,
15
15
TabBarToolbarRegistry ,
16
16
} from './contribution' ;
17
+ import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog' ;
17
18
18
19
@injectable ( )
19
20
export class UploadSketch extends SketchContribution {
@@ -29,16 +30,81 @@ export class UploadSketch extends SketchContribution {
29
30
@inject ( BoardsServiceProvider )
30
31
protected readonly boardsServiceClientImpl : BoardsServiceProvider ;
31
32
33
+ @inject ( UserFieldsDialog )
34
+ protected readonly userFieldsDialog : UserFieldsDialog ;
35
+
36
+ protected cachedUserFields : Map < string , BoardUserField [ ] > = new Map ( ) ;
37
+
32
38
protected readonly onDidChangeEmitter = new Emitter < Readonly < void > > ( ) ;
33
39
readonly onDidChange = this . onDidChangeEmitter . event ;
34
40
35
41
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
+ }
36
64
37
65
registerCommands ( registry : CommandRegistry ) : void {
38
66
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
+ } ,
40
83
isEnabled : ( ) => ! this . uploadInProgress ,
41
84
} ) ;
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
+ ) ;
42
108
registry . registerCommand (
43
109
UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER ,
44
110
{
@@ -62,10 +128,15 @@ export class UploadSketch extends SketchContribution {
62
128
label : 'Upload' ,
63
129
order : '1' ,
64
130
} ) ;
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
+ } ) ;
65
136
registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
66
137
commandId : UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER . id ,
67
138
label : 'Upload Using Programmer' ,
68
- order : '2 ' ,
139
+ order : '3 ' ,
69
140
} ) ;
70
141
}
71
142
@@ -131,6 +202,11 @@ export class UploadSketch extends SketchContribution {
131
202
const optimizeForDebug = this . editorMode . compileForDebug ;
132
203
const { selectedPort } = boardsConfig ;
133
204
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
+ }
134
210
135
211
if ( usingProgrammer ) {
136
212
const programmer = selectedProgrammer ;
@@ -143,6 +219,7 @@ export class UploadSketch extends SketchContribution {
143
219
verbose,
144
220
verify,
145
221
sourceOverride,
222
+ userFields,
146
223
} ;
147
224
} else {
148
225
options = {
@@ -153,6 +230,7 @@ export class UploadSketch extends SketchContribution {
153
230
verbose,
154
231
verify,
155
232
sourceOverride,
233
+ userFields,
156
234
} ;
157
235
}
158
236
this . outputChannelManager . getChannel ( 'Arduino' ) . clear ( ) ;
@@ -196,6 +274,11 @@ export namespace UploadSketch {
196
274
export const UPLOAD_SKETCH : Command = {
197
275
id : 'arduino-upload-sketch' ,
198
276
} ;
277
+ export const UPLOAD_WITH_CONFIGURATION : Command = {
278
+ id : 'arduino-upload-with-configuration-sketch' ,
279
+ label : 'Configure And Upload' ,
280
+ category : 'Arduino' ,
281
+ }
199
282
export const UPLOAD_SKETCH_USING_PROGRAMMER : Command = {
200
283
id : 'arduino-upload-sketch-using-programmer' ,
201
284
} ;
0 commit comments