Skip to content

Add dialog to insert user fields for board that require them to upload #550

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

Merged
merged 11 commits into from
Nov 25, 2021
Prev Previous commit
Next Next commit
Add configure and upload step when uploading to board requiring user …
…fields
  • Loading branch information
silvanocerza authored and Alberto Iannaccone committed Nov 24, 2021
commit 53b4f17b7ace3dcd002e14c276d6850c423c2043
91 changes: 87 additions & 4 deletions arduino-ide-extension/src/browser/contributions/upload-sketch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { inject, injectable } from 'inversify';
import { inject, injectable, postConstruct } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { CoreService } from '../../common/protocol';
import { BoardUserField, CoreService } from '../../common/protocol';
import { ArduinoMenus } from '../menu/arduino-menus';
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
import { BoardsDataStore } from '../boards/boards-data-store';
Expand All @@ -14,6 +14,7 @@ import {
KeybindingRegistry,
TabBarToolbarRegistry,
} from './contribution';
import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog';
import { nls } from '@theia/core/lib/browser/nls';

@injectable()
Expand All @@ -30,16 +31,81 @@ export class UploadSketch extends SketchContribution {
@inject(BoardsServiceProvider)
protected readonly boardsServiceClientImpl: BoardsServiceProvider;

@inject(UserFieldsDialog)
protected readonly userFieldsDialog: UserFieldsDialog;

protected cachedUserFields: Map<string, BoardUserField[]> = new Map();

protected readonly onDidChangeEmitter = new Emitter<Readonly<void>>();
readonly onDidChange = this.onDidChangeEmitter.event;

protected uploadInProgress = false;
protected boardRequiresUserFields = false;

@postConstruct()
protected init(): void {
this.boardsServiceClientImpl.onBoardsConfigChanged(async () => {
const userFields = await this.boardsServiceClientImpl.selectedBoardUserFields();
this.boardRequiresUserFields = userFields.length > 0;
})
}

private selectedFqbnAddress(): string {
const { boardsConfig } = this.boardsServiceClientImpl;
const fqbn = boardsConfig.selectedBoard?.fqbn;
if (!fqbn) {
return "";
}
const address = boardsConfig.selectedBoard?.port?.address
if (!address) {
return "";
}
return fqbn + "|" + address;
}

registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
execute: () => this.uploadSketch(),
execute: async () => {
const key = this.selectedFqbnAddress();
if (!key) {
return;
}
if (this.boardRequiresUserFields && !this.cachedUserFields.has(key)) {
// Deep clone the array of board fields to avoid editing the cached ones
this.userFieldsDialog.value = (await this.boardsServiceClientImpl.selectedBoardUserFields()).map(f => ({ ...f }));
const result = await this.userFieldsDialog.open();
if (!result) {
return;
}
this.cachedUserFields.set(key, result);
}
this.uploadSketch();
},
isEnabled: () => !this.uploadInProgress,
});
registry.registerCommand(
UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION,
{
execute: async () => {
const key = this.selectedFqbnAddress();
if (!key) {
return;
}

const cached = this.cachedUserFields.get(key);
// Deep clone the array of board fields to avoid editing the cached ones
this.userFieldsDialog.value = (cached ?? await this.boardsServiceClientImpl.selectedBoardUserFields()).map(f => ({ ...f }));

const result = await this.userFieldsDialog.open()
if (!result) {
return;
}
this.cachedUserFields.set(key, result);
this.uploadSketch();
},
isEnabled: () => !this.uploadInProgress && this.boardRequiresUserFields,
}
);
registry.registerCommand(
UploadSketch.Commands.UPLOAD_SKETCH_USING_PROGRAMMER,
{
Expand All @@ -63,13 +129,18 @@ export class UploadSketch extends SketchContribution {
label: nls.localize('arduino/sketch/upload', 'Upload'),
order: '1',
});
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
commandId: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.id,
label: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label,
order: '2',
});
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
commandId: UploadSketch.Commands.UPLOAD_SKETCH_USING_PROGRAMMER.id,
label: nls.localize(
'arduino/sketch/uploadUsingProgrammer',
'Upload Using Programmer'
),
order: '2',
order: '3',
});
}

Expand Down Expand Up @@ -127,6 +198,11 @@ export class UploadSketch extends SketchContribution {
const optimizeForDebug = this.editorMode.compileForDebug;
const { selectedPort } = boardsConfig;
const port = selectedPort;
const userFields = this.cachedUserFields.get(this.selectedFqbnAddress());
if (!userFields) {
this.messageService.error(nls.localize('arduino/sketch/userFieldsNotFoundError', "Can't find user fields for connected board"));
return;
}

if (usingProgrammer) {
const programmer = selectedProgrammer;
Expand All @@ -139,6 +215,7 @@ export class UploadSketch extends SketchContribution {
verbose,
verify,
sourceOverride,
userFields,
};
} else {
options = {
Expand All @@ -149,6 +226,7 @@ export class UploadSketch extends SketchContribution {
verbose,
verify,
sourceOverride,
userFields,
};
}
this.outputChannelManager.getChannel('Arduino').clear();
Expand Down Expand Up @@ -197,6 +275,11 @@ export namespace UploadSketch {
export const UPLOAD_SKETCH: Command = {
id: 'arduino-upload-sketch',
};
export const UPLOAD_WITH_CONFIGURATION: Command = {
id: 'arduino-upload-with-configuration-sketch',
label: nls.localize('arduino/sketch/configureAndUpload', 'Configure And Upload'),
category: 'Arduino',
}
export const UPLOAD_SKETCH_USING_PROGRAMMER: Command = {
id: 'arduino-upload-sketch-using-programmer',
};
Expand Down
2 changes: 2 additions & 0 deletions arduino-ide-extension/src/common/protocol/core-service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BoardUserField } from '.';
import { Port } from '../../common/protocol/boards-service';
import { Programmer } from './boards-service';

Expand Down Expand Up @@ -44,6 +45,7 @@ export namespace CoreService {
readonly port?: Port | undefined;
readonly programmer?: Programmer | undefined;
readonly verify: boolean;
readonly userFields: BoardUserField[];
}
}

Expand Down
5 changes: 5 additions & 0 deletions arduino-ide-extension/src/node/core-service-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
}
req.setVerbose(options.verbose);
req.setVerify(options.verify);

options.userFields.forEach(e => {
req.getUserFieldsMap().set(e.name, e.value);
});

const result = responseHandler(client, req);

try {
Expand Down