@@ -12,6 +12,7 @@ import { ILogger } from '@theia/core/lib/common/logger';
12
12
import { deepClone , deepFreeze } from '@theia/core/lib/common/objects' ;
13
13
import type { Mutable } from '@theia/core/lib/common/types' ;
14
14
import { inject , injectable , named } from '@theia/core/shared/inversify' ;
15
+ import { FQBN } from 'fqbn' ;
15
16
import {
16
17
BoardDetails ,
17
18
BoardsService ,
@@ -20,6 +21,7 @@ import {
20
21
Programmer ,
21
22
isBoardIdentifierChangeEvent ,
22
23
isProgrammer ,
24
+ sanitizeFqbn ,
23
25
} from '../../common/protocol' ;
24
26
import { notEmpty } from '../../common/utils' ;
25
27
import type {
@@ -29,6 +31,14 @@ import type {
29
31
import { NotificationCenter } from '../notification-center' ;
30
32
import { BoardsServiceProvider } from './boards-service-provider' ;
31
33
34
+ export interface SelectConfigOptionParams {
35
+ readonly fqbn : string ;
36
+ readonly optionsToUpdate : readonly Readonly < {
37
+ option : string ;
38
+ selectedValue : string ;
39
+ } > [ ] ;
40
+ }
41
+
32
42
@injectable ( )
33
43
export class BoardsDataStore
34
44
implements
@@ -64,7 +74,12 @@ export class BoardsDataStore
64
74
this . toDispose . pushAll ( [
65
75
this . boardsServiceProvider . onBoardsConfigDidChange ( ( event ) => {
66
76
if ( isBoardIdentifierChangeEvent ( event ) ) {
67
- this . updateSelectedBoardData ( event . selectedBoard ?. fqbn ) ;
77
+ this . updateSelectedBoardData (
78
+ event . selectedBoard ?. fqbn ,
79
+ // If the change event comes from toolbar and the FQBN contains custom board options, change the currently selected options
80
+ // https://github.com/arduino/arduino-ide/issues/1588
81
+ event . reason === 'toolbar'
82
+ ) ;
68
83
}
69
84
} ) ,
70
85
this . notificationCenter . onPlatformDidInstall ( async ( { item } ) => {
@@ -116,7 +131,7 @@ export class BoardsDataStore
116
131
if ( ! fqbn ) {
117
132
return undefined ;
118
133
} else {
119
- const data = await this . getData ( fqbn ) ;
134
+ const data = await this . getData ( sanitizeFqbn ( fqbn ) ) ;
120
135
if ( data === BoardsDataStore . Data . EMPTY ) {
121
136
return undefined ;
122
137
}
@@ -125,9 +140,22 @@ export class BoardsDataStore
125
140
}
126
141
127
142
private async updateSelectedBoardData (
128
- fqbn : string | undefined
143
+ fqbn : string | undefined ,
144
+ updateConfigOptions = false
129
145
) : Promise < void > {
130
146
this . _selectedBoardData = await this . getSelectedBoardData ( fqbn ) ;
147
+ if ( fqbn && updateConfigOptions ) {
148
+ const { options } = new FQBN ( fqbn ) ;
149
+ if ( options ) {
150
+ const optionsToUpdate = Object . entries ( options ) . map ( ( [ key , value ] ) => ( {
151
+ option : key ,
152
+ selectedValue : value ,
153
+ } ) ) ;
154
+ const params = { fqbn, optionsToUpdate } ;
155
+ await this . selectConfigOption ( params ) ;
156
+ this . _selectedBoardData = await this . getSelectedBoardData ( fqbn ) ; // reload the updated data
157
+ }
158
+ }
131
159
}
132
160
133
161
onStop ( ) : void {
@@ -168,7 +196,7 @@ export class BoardsDataStore
168
196
return undefined ;
169
197
}
170
198
const { configOptions } = await this . getData ( fqbn ) ;
171
- return ConfigOption . decorate ( fqbn , configOptions ) ;
199
+ return new FQBN ( fqbn ) . withConfigOptions ( ... configOptions ) . toString ( ) ;
172
200
}
173
201
174
202
async getData ( fqbn : string | undefined ) : Promise < BoardsDataStore . Data > {
@@ -201,48 +229,63 @@ export class BoardsDataStore
201
229
fqbn : string ;
202
230
selectedProgrammer : Programmer ;
203
231
} ) : Promise < boolean > {
204
- const storedData = deepClone ( await this . getData ( fqbn ) ) ;
232
+ const sanitizedFQBN = sanitizeFqbn ( fqbn ) ;
233
+ const storedData = deepClone ( await this . getData ( sanitizedFQBN ) ) ;
205
234
const { programmers } = storedData ;
206
235
if ( ! programmers . find ( ( p ) => Programmer . equals ( selectedProgrammer , p ) ) ) {
207
236
return false ;
208
237
}
209
238
210
- const data = { ...storedData , selectedProgrammer } ;
211
- await this . setData ( { fqbn, data } ) ;
212
- this . fireChanged ( { fqbn, data } ) ;
239
+ const change : BoardsDataStoreChange = {
240
+ fqbn : sanitizedFQBN ,
241
+ data : { ...storedData , selectedProgrammer } ,
242
+ } ;
243
+ await this . setData ( change ) ;
244
+ this . fireChanged ( change ) ;
213
245
return true ;
214
246
}
215
247
216
- async selectConfigOption ( {
217
- fqbn,
218
- option,
219
- selectedValue,
220
- } : {
221
- fqbn : string ;
222
- option : string ;
223
- selectedValue : string ;
224
- } ) : Promise < boolean > {
225
- const data = deepClone ( await this . getData ( fqbn ) ) ;
226
- const { configOptions } = data ;
227
- const configOption = configOptions . find ( ( c ) => c . option === option ) ;
228
- if ( ! configOption ) {
248
+ async selectConfigOption ( params : SelectConfigOptionParams ) : Promise < boolean > {
249
+ const { fqbn, optionsToUpdate } = params ;
250
+ if ( ! optionsToUpdate . length ) {
229
251
return false ;
230
252
}
231
- let updated = false ;
232
- for ( const value of configOption . values ) {
233
- const mutable : Mutable < ConfigValue > = value ;
234
- if ( mutable . value === selectedValue ) {
235
- mutable . selected = true ;
236
- updated = true ;
237
- } else {
238
- mutable . selected = false ;
253
+
254
+ const sanitizedFQBN = sanitizeFqbn ( fqbn ) ;
255
+ const mutableData = deepClone ( await this . getData ( sanitizedFQBN ) ) ;
256
+ let didChange = false ;
257
+
258
+ for ( const { option, selectedValue } of optionsToUpdate ) {
259
+ const { configOptions } = mutableData ;
260
+ const configOption = configOptions . find ( ( c ) => c . option === option ) ;
261
+ if ( configOption ) {
262
+ const configOptionValueIndex = configOption . values . findIndex (
263
+ ( configOptionValue ) => configOptionValue . value === selectedValue
264
+ ) ;
265
+ if ( configOptionValueIndex >= 0 ) {
266
+ // unselect all
267
+ configOption . values
268
+ . map ( ( value ) => value as Mutable < ConfigValue > )
269
+ . forEach ( ( value ) => ( value . selected = false ) ) ;
270
+ const mutableConfigValue : Mutable < ConfigValue > =
271
+ configOption . values [ configOptionValueIndex ] ;
272
+ // make the new value `selected`
273
+ mutableConfigValue . selected = true ;
274
+ didChange = true ;
275
+ }
239
276
}
240
277
}
241
- if ( ! updated ) {
278
+
279
+ if ( ! didChange ) {
242
280
return false ;
243
281
}
244
- await this . setData ( { fqbn, data } ) ;
245
- this . fireChanged ( { fqbn, data } ) ;
282
+
283
+ const change : BoardsDataStoreChange = {
284
+ fqbn : sanitizedFQBN ,
285
+ data : mutableData ,
286
+ } ;
287
+ await this . setData ( change ) ;
288
+ this . fireChanged ( change ) ;
246
289
return true ;
247
290
}
248
291
0 commit comments