mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-24 11:46:32 +00:00
more refactoring.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
5abfc2c1aa
commit
20f44fe072
@ -4,22 +4,6 @@ export namespace ArduinoCommands {
|
||||
|
||||
const category = 'Arduino';
|
||||
|
||||
export const VERIFY: Command = {
|
||||
id: 'arduino-verify',
|
||||
label: 'Verify Sketch'
|
||||
};
|
||||
export const VERIFY_TOOLBAR: Command = {
|
||||
id: 'arduino-verify-toolbar',
|
||||
};
|
||||
|
||||
export const UPLOAD: Command = {
|
||||
id: 'arduino-upload',
|
||||
label: 'Upload Sketch'
|
||||
};
|
||||
export const UPLOAD_TOOLBAR: Command = {
|
||||
id: 'arduino-upload-toolbar',
|
||||
};
|
||||
|
||||
export const TOGGLE_COMPILE_FOR_DEBUG: Command = {
|
||||
id: 'arduino-toggle-compile-for-debug'
|
||||
};
|
||||
|
@ -1,27 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import { injectable, inject, postConstruct } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser/editor-widget';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import { CommandContribution, CommandRegistry, Command, CommandHandler } from '@theia/core/lib/common/command';
|
||||
import { CommandContribution, CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { BoardsService, BoardsServiceClient, CoreService, SketchesService, ToolOutputServiceClient } from '../common/protocol';
|
||||
import { ArduinoCommands } from './arduino-commands';
|
||||
import { BoardsServiceClientImpl } from './boards/boards-service-client-impl';
|
||||
import { WorkspaceCommands } from '@theia/workspace/lib/browser/workspace-commands';
|
||||
import { SelectionService, MenuContribution, MenuModelRegistry, MAIN_MENU_BAR, MenuPath } from '@theia/core';
|
||||
import { SelectionService, MenuContribution, MenuModelRegistry, MAIN_MENU_BAR } from '@theia/core';
|
||||
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
|
||||
import { EditorManager, EditorMainMenu } from '@theia/editor/lib/browser';
|
||||
import {
|
||||
ContextMenuRenderer, StatusBar, StatusBarAlignment, FrontendApplicationContribution,
|
||||
FrontendApplication, KeybindingContribution, KeybindingRegistry, OpenerService, open
|
||||
} from '@theia/core/lib/browser';
|
||||
import { OpenFileDialogProps, FileDialogService } from '@theia/filesystem/lib/browser/file-dialog';
|
||||
import { FileSystem, FileStat } from '@theia/filesystem/lib/common';
|
||||
import { CommonCommands, CommonMenus } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||
import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common';
|
||||
import { CommonMenus } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
|
||||
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { BoardsConfigDialog } from './boards/boards-config-dialog';
|
||||
import { BoardsToolBarItem } from './boards/boards-toolbar-item';
|
||||
import { BoardsConfig } from './boards/boards-config';
|
||||
@ -34,7 +31,6 @@ import { OutlineViewContribution } from '@theia/outline-view/lib/browser/outline
|
||||
import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
|
||||
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
||||
import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
|
||||
import { FileNavigatorCommands } from '@theia/navigator/lib/browser/navigator-contribution';
|
||||
import { EditorMode } from './editor-mode';
|
||||
import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
|
||||
import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
|
||||
@ -43,19 +39,7 @@ import { ConfigService } from '../common/protocol/config-service';
|
||||
import { BoardsConfigStore } from './boards/boards-config-store';
|
||||
import { MainMenuManager } from './menu/main-menu-manager';
|
||||
import { FileSystemExt } from '../common/protocol/filesystem-ext';
|
||||
import { OpenSketch } from './contributions/open-sketch';
|
||||
|
||||
export namespace ArduinoMenus {
|
||||
export const SKETCH = [...MAIN_MENU_BAR, '3_sketch'];
|
||||
export const TOOLS = [...MAIN_MENU_BAR, '4_tools'];
|
||||
}
|
||||
|
||||
export namespace ArduinoToolbarContextMenu {
|
||||
export const OPEN_SKETCH_PATH: MenuPath = ['arduino-open-sketch-context-menu'];
|
||||
export const OPEN_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '1_open'];
|
||||
export const WS_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '2_sketches'];
|
||||
export const EXAMPLE_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '3_examples'];
|
||||
}
|
||||
import { ArduinoMenus } from './menu/arduino-menus';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoFrontendContribution implements FrontendApplicationContribution,
|
||||
@ -155,9 +139,6 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
@inject(FileSystemExt)
|
||||
protected readonly fileSystemExt: FileSystemExt;
|
||||
|
||||
protected application: FrontendApplication;
|
||||
protected wsSketchCount: number = 0; // TODO: this does not belong here, does it?
|
||||
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
if (!window.navigator.onLine) {
|
||||
@ -172,12 +153,9 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
}
|
||||
this.boardsServiceClientImpl.onBoardsConfigChanged(updateStatusBar);
|
||||
updateStatusBar(this.boardsServiceClientImpl.boardsConfig);
|
||||
|
||||
this.registerSketchesInMenu(this.menuRegistry);
|
||||
}
|
||||
|
||||
onStart(app: FrontendApplication): void {
|
||||
this.application = app;
|
||||
// Initialize all `pro-mode` widgets. This is a NOOP if in normal mode.
|
||||
for (const viewContribution of [
|
||||
this.fileNavigatorContributions,
|
||||
@ -186,26 +164,13 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
this.problemContribution,
|
||||
this.scmContribution,
|
||||
this.siwContribution] as Array<FrontendApplicationContribution>) {
|
||||
|
||||
if (viewContribution.initializeLayout) {
|
||||
viewContribution.initializeLayout(this.application);
|
||||
viewContribution.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||
registry.registerItem({
|
||||
id: ArduinoCommands.VERIFY.id,
|
||||
command: ArduinoCommands.VERIFY_TOOLBAR.id,
|
||||
tooltip: 'Verify',
|
||||
priority: 1
|
||||
});
|
||||
registry.registerItem({
|
||||
id: ArduinoCommands.UPLOAD.id,
|
||||
command: ArduinoCommands.UPLOAD_TOOLBAR.id,
|
||||
tooltip: 'Upload',
|
||||
priority: 2
|
||||
});
|
||||
registry.registerItem({
|
||||
id: BoardsToolBarItem.TOOLBAR_ID,
|
||||
render: () => <BoardsToolBarItem
|
||||
@ -213,7 +178,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
commands={this.commandRegistry}
|
||||
boardsServiceClient={this.boardsServiceClientImpl} />,
|
||||
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
|
||||
priority: 6
|
||||
priority: 7
|
||||
});
|
||||
registry.registerItem({
|
||||
id: 'toggle-serial-monitor',
|
||||
@ -223,80 +188,21 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
registry.registerItem({
|
||||
id: ArduinoCommands.TOGGLE_ADVANCED_MODE.id,
|
||||
command: ArduinoCommands.TOGGLE_ADVANCED_MODE_TOOLBAR.id,
|
||||
tooltip: 'Toggle Advanced Mode',
|
||||
text: (this.editorMode.proMode ? '$(toggle-on)' : '$(toggle-off)')
|
||||
tooltip: this.editorMode.proMode ? 'Switch to Classic Mode' : 'Switch to Advanced Mode',
|
||||
text: this.editorMode.proMode ? '$(toggle-on)' : '$(toggle-off)'
|
||||
});
|
||||
}
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
// TODO: use proper API https://github.com/eclipse-theia/theia/pull/6599
|
||||
const allHandlers: { [id: string]: CommandHandler[] } = (registry as any)._handlers;
|
||||
|
||||
// Make sure to reveal the `Explorer` before executing `New File` and `New Folder`.
|
||||
for (const command of [WorkspaceCommands.NEW_FILE, WorkspaceCommands.NEW_FOLDER]) {
|
||||
const { id } = command;
|
||||
const handlers = allHandlers[id].slice();
|
||||
registry.unregisterCommand(id);
|
||||
registry.registerCommand(command);
|
||||
for (const handler of handlers) {
|
||||
const wrapper: CommandHandler = {
|
||||
execute: (...args: any[]) => {
|
||||
this.fileNavigatorContributions.openView({ reveal: true }).then(() => handler.execute(args));
|
||||
},
|
||||
isVisible: (...args: any[]) => {
|
||||
return handler.isVisible!(args);
|
||||
},
|
||||
isEnabled: (args: any[]) => {
|
||||
return handler.isEnabled!(args);
|
||||
},
|
||||
isToggled: (args: any[]) => {
|
||||
return handler.isToggled!(args);
|
||||
}
|
||||
};
|
||||
if (!handler.isEnabled) {
|
||||
delete wrapper.isEnabled;
|
||||
}
|
||||
if (!handler.isToggled) {
|
||||
delete wrapper.isToggled;
|
||||
}
|
||||
if (!handler.isVisible) {
|
||||
delete wrapper.isVisible;
|
||||
}
|
||||
registry.registerHandler(id, wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
registry.registerCommand(ArduinoCommands.VERIFY, {
|
||||
execute: this.verify.bind(this)
|
||||
});
|
||||
registry.registerCommand(ArduinoCommands.VERIFY_TOOLBAR, {
|
||||
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
|
||||
execute: this.verify.bind(this)
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.TOGGLE_COMPILE_FOR_DEBUG, {
|
||||
execute: () => this.editorMode.toggleCompileForDebug(),
|
||||
isToggled: () => this.editorMode.compileForDebug
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.UPLOAD, {
|
||||
execute: this.upload.bind(this)
|
||||
});
|
||||
registry.registerCommand(ArduinoCommands.UPLOAD_TOOLBAR, {
|
||||
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
|
||||
execute: this.upload.bind(this)
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.OPEN_FILE_NAVIGATOR, {
|
||||
execute: () => this.doOpenFile()
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.OPEN_SKETCH_FILES, {
|
||||
execute: async (uri: string) => {
|
||||
this.openSketchFiles(uri);
|
||||
}
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.OPEN_BOARDS_DIALOG, {
|
||||
execute: async () => {
|
||||
const boardsConfig = await this.boardsConfigDialog.open();
|
||||
@ -305,7 +211,6 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.TOGGLE_ADVANCED_MODE, {
|
||||
isToggled: () => this.editorMode.proMode,
|
||||
execute: () => this.editorMode.toggleProMode()
|
||||
@ -315,183 +220,41 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
isToggled: () => this.editorMode.proMode,
|
||||
execute: () => this.editorMode.toggleProMode()
|
||||
});
|
||||
|
||||
registry.registerCommand(ArduinoCommands.OPEN_CLI_CONFIG, {
|
||||
execute: () => this.configService.getCliConfigFileUri().then(uri => open(this.openerService, new URI(uri)))
|
||||
});
|
||||
}
|
||||
|
||||
protected async verify() {
|
||||
const widget = this.getCurrentWidget();
|
||||
if (widget instanceof EditorWidget) {
|
||||
await widget.saveable.save();
|
||||
}
|
||||
|
||||
const uri = this.toUri(widget);
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { boardsConfig } = this.boardsServiceClientImpl;
|
||||
if (!boardsConfig || !boardsConfig.selectedBoard) {
|
||||
throw new Error('No boards selected. Please select a board.');
|
||||
}
|
||||
if (!boardsConfig.selectedBoard.fqbn) {
|
||||
throw new Error(`No core is installed for the '${boardsConfig.selectedBoard.name}' board. Please install the core.`);
|
||||
}
|
||||
const fqbn = await this.boardsConfigStore.appendConfigToFqbn(boardsConfig.selectedBoard.fqbn);
|
||||
this.outputContribution.openView({ reveal: true });
|
||||
await this.coreService.compile({
|
||||
sketchUri: uri.toString(),
|
||||
fqbn,
|
||||
optimizeForDebug: this.editorMode.compileForDebug
|
||||
});
|
||||
} catch (e) {
|
||||
await this.messageService.error(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected async upload() {
|
||||
const widget = this.getCurrentWidget();
|
||||
if (widget instanceof EditorWidget) {
|
||||
await widget.saveable.save();
|
||||
}
|
||||
|
||||
const uri = this.toUri(widget);
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
const monitorConfig = this.monitorConnection.monitorConfig;
|
||||
if (monitorConfig) {
|
||||
await this.monitorConnection.disconnect();
|
||||
}
|
||||
|
||||
try {
|
||||
const { boardsConfig } = this.boardsServiceClientImpl;
|
||||
if (!boardsConfig || !boardsConfig.selectedBoard) {
|
||||
throw new Error('No boards selected. Please select a board.');
|
||||
}
|
||||
const { selectedPort } = boardsConfig;
|
||||
if (!selectedPort) {
|
||||
throw new Error('No ports selected. Please select a port.');
|
||||
}
|
||||
if (!boardsConfig.selectedBoard.fqbn) {
|
||||
throw new Error(`No core is installed for the '${boardsConfig.selectedBoard.name}' board. Please install the core.`);
|
||||
}
|
||||
this.outputContribution.openView({ reveal: true });
|
||||
const fqbn = await this.boardsConfigStore.appendConfigToFqbn(boardsConfig.selectedBoard.fqbn);
|
||||
await this.coreService.upload({
|
||||
sketchUri: uri.toString(),
|
||||
fqbn,
|
||||
port: selectedPort.address,
|
||||
optimizeForDebug: this.editorMode.compileForDebug
|
||||
});
|
||||
} catch (e) {
|
||||
await this.messageService.error(e.toString());
|
||||
} finally {
|
||||
if (monitorConfig) {
|
||||
await this.monitorConnection.connect(monitorConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry) {
|
||||
if (!this.editorMode.proMode) {
|
||||
// If are not in pro-mode, we have to disable the context menu for the tabs.
|
||||
// Such as `Close`, `Close All`, etc.
|
||||
for (const command of [
|
||||
CommonCommands.CLOSE_TAB,
|
||||
CommonCommands.CLOSE_OTHER_TABS,
|
||||
CommonCommands.CLOSE_RIGHT_TABS,
|
||||
CommonCommands.CLOSE_ALL_TABS,
|
||||
CommonCommands.COLLAPSE_PANEL,
|
||||
CommonCommands.TOGGLE_MAXIMIZED,
|
||||
FileNavigatorCommands.REVEAL_IN_NAVIGATOR
|
||||
]) {
|
||||
if (command) { }
|
||||
// registry.unregisterMenuAction(command);
|
||||
const menuId = (menuPath: string[]): string => {
|
||||
const index = menuPath.length - 1;
|
||||
const menuId = menuPath[index];
|
||||
return menuId;
|
||||
}
|
||||
|
||||
// registry.unregisterMenuAction(FileSystemCommands.UPLOAD);
|
||||
// registry.unregisterMenuAction(FileDownloadCommands.DOWNLOAD);
|
||||
|
||||
// registry.unregisterMenuAction(WorkspaceCommands.OPEN_FOLDER);
|
||||
// registry.unregisterMenuAction(WorkspaceCommands.OPEN_WORKSPACE);
|
||||
// registry.unregisterMenuAction(WorkspaceCommands.OPEN_RECENT_WORKSPACE);
|
||||
// registry.unregisterMenuAction(WorkspaceCommands.SAVE_WORKSPACE_AS);
|
||||
// registry.unregisterMenuAction(WorkspaceCommands.CLOSE);
|
||||
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(this.getMenuId(MonacoMenus.SELECTION));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(this.getMenuId(EditorMainMenu.GO));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(this.getMenuId(TerminalMenus.TERMINAL));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(this.getMenuId(CommonMenus.VIEW));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(menuId(MonacoMenus.SELECTION));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(menuId(EditorMainMenu.GO));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(menuId(TerminalMenus.TERMINAL));
|
||||
registry.getMenu(MAIN_MENU_BAR).removeNode(menuId(CommonMenus.VIEW));
|
||||
}
|
||||
registry.registerSubmenu(ArduinoMenus.SKETCH, 'Sketch');
|
||||
registry.registerSubmenu(ArduinoMenus.TOOLS, 'Tools');
|
||||
registry.registerMenuAction(ArduinoMenus.SKETCH, {
|
||||
commandId: ArduinoCommands.TOGGLE_COMPILE_FOR_DEBUG.id,
|
||||
label: 'Optimize for Debugging',
|
||||
order: '1'
|
||||
});
|
||||
registry.registerMenuAction(ArduinoMenus.SKETCH, {
|
||||
commandId: ArduinoCommands.VERIFY.id,
|
||||
label: 'Verify/Compile',
|
||||
order: '2'
|
||||
});
|
||||
registry.registerMenuAction(ArduinoMenus.SKETCH, {
|
||||
commandId: ArduinoCommands.UPLOAD.id,
|
||||
label: 'Upload',
|
||||
order: '3'
|
||||
});
|
||||
|
||||
registry.registerSubmenu(ArduinoMenus.TOOLS, 'Tools');
|
||||
|
||||
registry.registerMenuAction(CommonMenus.HELP, {
|
||||
commandId: ArduinoCommands.TOGGLE_ADVANCED_MODE.id,
|
||||
label: 'Advanced Mode'
|
||||
});
|
||||
|
||||
registry.registerMenuAction([...CommonMenus.FILE_SETTINGS_SUBMENU, '3_settings_cli'], {
|
||||
commandId: ArduinoCommands.OPEN_CLI_CONFIG.id
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected getMenuId(menuPath: string[]): string {
|
||||
const index = menuPath.length - 1;
|
||||
const menuId = menuPath[index];
|
||||
return menuId;
|
||||
}
|
||||
|
||||
registerKeybindings(keybindings: KeybindingRegistry): void {
|
||||
keybindings.unregisterKeybinding('ctrlcmd+n'); // Unregister the keybinding for `New File`, will be used by `New Sketch`. (eclipse-theia/theia#8170)
|
||||
keybindings.registerKeybinding({
|
||||
command: ArduinoCommands.VERIFY.id,
|
||||
keybinding: 'CtrlCmd+Alt+V'
|
||||
});
|
||||
keybindings.registerKeybinding({
|
||||
command: ArduinoCommands.UPLOAD.id,
|
||||
keybinding: 'CtrlCmd+Alt+U'
|
||||
});
|
||||
}
|
||||
|
||||
protected async registerSketchesInMenu(registry: MenuModelRegistry): Promise<void> {
|
||||
const sketches = await this.sketchService.getSketches();
|
||||
this.wsSketchCount = sketches.length;
|
||||
sketches.forEach(sketch => {
|
||||
const command: Command = {
|
||||
id: 'openSketch' + sketch.name
|
||||
}
|
||||
this.commandRegistry.registerCommand(command, {
|
||||
execute: () => this.commandRegistry.executeCommand(OpenSketch.Commands.OPEN_SKETCH.id, sketch)
|
||||
});
|
||||
|
||||
registry.registerMenuAction(ArduinoToolbarContextMenu.WS_SKETCHES_GROUP, {
|
||||
commandId: command.id,
|
||||
label: sketch.name
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected async openSketchFiles(uri: string): Promise<void> {
|
||||
@ -501,82 +264,6 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a file after prompting the `Open File` dialog. Shows a warning message if
|
||||
* - the file to open does not exist,
|
||||
* - it was not a file, but a directory, or
|
||||
* - the file does not pass validation.
|
||||
*
|
||||
* Otherwise, resolves to the URI of the file.
|
||||
*/
|
||||
protected async doOpenFile(): Promise<void> {
|
||||
const props: OpenFileDialogProps = {
|
||||
title: WorkspaceCommands.OPEN_FILE.dialogLabel,
|
||||
canSelectFolders: false,
|
||||
canSelectFiles: true
|
||||
};
|
||||
const [rootStat] = await this.workspaceService.roots;
|
||||
const destinationFileUri = await this.fileDialogService.showOpenDialog(props, rootStat);
|
||||
if (!destinationFileUri) {
|
||||
return;
|
||||
}
|
||||
const destinationFile = await this.fileSystem.getFileStat(destinationFileUri.toString());
|
||||
if (!destinationFile) {
|
||||
this.messageService.warn(`File does not exist: ${this.fileSystem.getFsPath(destinationFileUri.toString())}`)
|
||||
return;
|
||||
}
|
||||
if (destinationFile.isDirectory) {
|
||||
this.messageService.warn('Please select a sketch file, not a directory.')
|
||||
return;
|
||||
}
|
||||
const message = await this.validate(destinationFile);
|
||||
if (message) {
|
||||
this.messageService.warn(message);
|
||||
return;
|
||||
}
|
||||
this.workspaceService.open(destinationFileUri.parent);
|
||||
}
|
||||
|
||||
protected getCurrentWidget(): EditorWidget | undefined {
|
||||
let widget = this.editorManager.currentEditor;
|
||||
if (!widget) {
|
||||
const visibleWidgets = this.editorManager.all.filter(w => w.isVisible);
|
||||
if (visibleWidgets.length > 0) {
|
||||
widget = visibleWidgets[0];
|
||||
}
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `undefined` if the `file` is valid. Otherwise, returns with the validation error message.
|
||||
*/
|
||||
protected validate(file: FileStat): MaybePromise<string | undefined> {
|
||||
const uri = new URI(file.uri);
|
||||
const path = uri.path;
|
||||
const { name, ext, dir } = path;
|
||||
if (ext !== '.ino') {
|
||||
return "Only sketches with '.ino' extension can be opened.";
|
||||
}
|
||||
if (name !== dir.name) {
|
||||
return `The file "${name}${ext}" needs to be inside a sketch folder named "${name}".`;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private toUri(arg: any): URI | undefined {
|
||||
if (arg instanceof URI) {
|
||||
return arg;
|
||||
}
|
||||
if (typeof arg === 'string') {
|
||||
return new URI(arg);
|
||||
}
|
||||
if (arg instanceof EditorWidget) {
|
||||
return arg.editor.uri;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
registerColors(colors: ColorRegistry): void {
|
||||
colors.register(
|
||||
{
|
||||
|
@ -85,6 +85,8 @@ import { OpenSketch } from './contributions/open-sketch';
|
||||
import { CloseSketch } from './contributions/close-sketch';
|
||||
import { SaveAsSketch } from './contributions/save-as-sketch';
|
||||
import { SaveSketch } from './contributions/save-sketch';
|
||||
import { VerifySketch } from './contributions/verify-sketch';
|
||||
import { UploadSketch } from './contributions/upload-sketch';
|
||||
|
||||
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||
|
||||
@ -310,4 +312,6 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un
|
||||
Contribution.configure(bind, CloseSketch);
|
||||
Contribution.configure(bind, SaveSketch);
|
||||
Contribution.configure(bind, SaveAsSketch);
|
||||
Contribution.configure(bind, VerifySketch);
|
||||
Contribution.configure(bind, UploadSketch);
|
||||
});
|
||||
|
@ -7,7 +7,6 @@ import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-c
|
||||
import { InstallationProgressDialog } from '../components/progress-dialog';
|
||||
import { BoardsConfig } from './boards-config';
|
||||
|
||||
|
||||
/**
|
||||
* Listens on `BoardsConfig.Config` changes, if a board is selected which does not
|
||||
* have the corresponding core installed, it proposes the user to install the core.
|
||||
|
@ -5,9 +5,9 @@ import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposa
|
||||
import { BoardsServiceClientImpl } from './boards-service-client-impl';
|
||||
import { Board, ConfigOption } from '../../common/protocol';
|
||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
||||
import { ArduinoMenus } from '../arduino-frontend-contribution';
|
||||
import { BoardsConfigStore } from './boards-config-store';
|
||||
import { MainMenuManager } from '../menu/main-menu-manager';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
|
||||
@injectable()
|
||||
export class BoardsDetailsMenuUpdater implements FrontendApplicationContribution {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { MenuModelRegistry } from '@theia/core';
|
||||
import { BoardsListWidget } from './boards-list-widget';
|
||||
import { ArduinoMenus } from '../arduino-frontend-contribution';
|
||||
import { BoardsPackage } from '../../common/protocol/boards-service';
|
||||
import { ListWidgetFrontendContribution } from '../components/component-list/list-widget-frontend-contribution';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
|
||||
@injectable()
|
||||
export class BoardsListWidgetFrontendContribution extends ListWidgetFrontendContribution<BoardsPackage> {
|
||||
|
@ -10,6 +10,7 @@ import { KeybindingRegistry, KeybindingContribution } from '@theia/core/lib/brow
|
||||
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { Command, CommandRegistry, CommandContribution, CommandService } from '@theia/core/lib/common/command';
|
||||
import { SketchesService, ConfigService, FileSystemExt, Sketch } from '../../common/protocol';
|
||||
import { EditorMode } from '../editor-mode';
|
||||
|
||||
export { Command, CommandRegistry, MenuModelRegistry, KeybindingRegistry, TabBarToolbarRegistry, URI, Sketch };
|
||||
|
||||
@ -28,6 +29,9 @@ export abstract class Contribution implements CommandContribution, MenuContribut
|
||||
@inject(WorkspaceService)
|
||||
protected readonly workspaceService: WorkspaceService;
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ export class NewSketch extends SketchContribution {
|
||||
id: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
|
||||
command: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
|
||||
tooltip: 'New',
|
||||
priority: 4
|
||||
priority: 3
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ export class OpenSketch extends SketchContribution {
|
||||
id: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
|
||||
command: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
|
||||
tooltip: 'Open',
|
||||
priority: 5
|
||||
priority: 4
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ export class SaveSketch extends SketchContribution {
|
||||
id: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
|
||||
command: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
|
||||
tooltip: 'Save',
|
||||
priority: 6
|
||||
priority: 5
|
||||
});
|
||||
}
|
||||
|
||||
|
107
arduino-ide-extension/src/browser/contributions/upload-sketch.ts
Normal file
107
arduino-ide-extension/src/browser/contributions/upload-sketch.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { CoreService } from '../../common/protocol';
|
||||
import { MonitorConnection } from '../monitor/monitor-connection';
|
||||
import { BoardsConfigStore } from '../boards/boards-config-store';
|
||||
import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||
import { SketchContribution, Command, CommandRegistry, MenuModelRegistry, KeybindingRegistry, TabBarToolbarRegistry } from './contribution';
|
||||
|
||||
@injectable()
|
||||
export class UploadSketch extends SketchContribution {
|
||||
|
||||
@inject(CoreService)
|
||||
protected readonly coreService: CoreService;
|
||||
|
||||
@inject(MonitorConnection)
|
||||
protected readonly monitorConnection: MonitorConnection;
|
||||
|
||||
@inject(BoardsConfigStore)
|
||||
protected readonly boardsConfigStore: BoardsConfigStore;
|
||||
|
||||
@inject(BoardsServiceClientImpl)
|
||||
protected readonly boardsServiceClientImpl: BoardsServiceClientImpl;
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
|
||||
execute: () => this.uploadSketch()
|
||||
});
|
||||
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR, {
|
||||
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
|
||||
execute: () => registry.executeCommand(UploadSketch.Commands.UPLOAD_SKETCH.id)
|
||||
});
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
|
||||
commandId: UploadSketch.Commands.UPLOAD_SKETCH.id,
|
||||
label: 'Verify',
|
||||
order: '0'
|
||||
});
|
||||
}
|
||||
|
||||
registerKeybindings(registry: KeybindingRegistry): void {
|
||||
registry.registerKeybinding({
|
||||
command: UploadSketch.Commands.UPLOAD_SKETCH.id,
|
||||
keybinding: 'CtrlCmd+U'
|
||||
});
|
||||
}
|
||||
|
||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||
registry.registerItem({
|
||||
id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
|
||||
command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
|
||||
tooltip: 'Upload',
|
||||
priority: 1
|
||||
});
|
||||
}
|
||||
|
||||
async uploadSketch(): Promise<void> {
|
||||
const sketch = await this.getCurrentSketch();
|
||||
if (!sketch) {
|
||||
return;
|
||||
}
|
||||
const monitorConfig = this.monitorConnection.monitorConfig;
|
||||
if (monitorConfig) {
|
||||
await this.monitorConnection.disconnect();
|
||||
}
|
||||
try {
|
||||
const { boardsConfig } = this.boardsServiceClientImpl;
|
||||
if (!boardsConfig || !boardsConfig.selectedBoard) {
|
||||
throw new Error('No boards selected. Please select a board.');
|
||||
}
|
||||
const { selectedPort } = boardsConfig;
|
||||
if (!selectedPort) {
|
||||
throw new Error('No ports selected. Please select a port.');
|
||||
}
|
||||
if (!boardsConfig.selectedBoard.fqbn) {
|
||||
throw new Error(`No core is installed for the '${boardsConfig.selectedBoard.name}' board. Please install the core.`);
|
||||
}
|
||||
const fqbn = await this.boardsConfigStore.appendConfigToFqbn(boardsConfig.selectedBoard.fqbn);
|
||||
await this.coreService.upload({
|
||||
sketchUri: sketch.uri,
|
||||
fqbn,
|
||||
port: selectedPort.address,
|
||||
optimizeForDebug: this.editorMode.compileForDebug
|
||||
});
|
||||
} catch (e) {
|
||||
await this.messageService.error(e.toString());
|
||||
} finally {
|
||||
if (monitorConfig) {
|
||||
await this.monitorConnection.connect(monitorConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace UploadSketch {
|
||||
export namespace Commands {
|
||||
export const UPLOAD_SKETCH: Command = {
|
||||
id: 'arduino-upload-sketch'
|
||||
};
|
||||
export const UPLOAD_SKETCH_TOOLBAR: Command = {
|
||||
id: 'arduino-upload-sketch--toolbar'
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||
import { BoardsConfigStore } from '../boards/boards-config-store';
|
||||
import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl';
|
||||
import { SketchContribution, Command, CommandRegistry, MenuModelRegistry, KeybindingRegistry, TabBarToolbarRegistry } from './contribution';
|
||||
import { CoreService } from '../../common/protocol';
|
||||
|
||||
@injectable()
|
||||
export class VerifySketch extends SketchContribution {
|
||||
|
||||
@inject(CoreService)
|
||||
protected readonly coreService: CoreService;
|
||||
|
||||
@inject(BoardsConfigStore)
|
||||
protected readonly boardsConfigStore: BoardsConfigStore;
|
||||
|
||||
@inject(BoardsServiceClientImpl)
|
||||
protected readonly boardsServiceClientImpl: BoardsServiceClientImpl;
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
|
||||
execute: () => this.verifySketch()
|
||||
});
|
||||
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR, {
|
||||
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
|
||||
execute: () => registry.executeCommand(VerifySketch.Commands.VERIFY_SKETCH.id)
|
||||
});
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
|
||||
commandId: VerifySketch.Commands.VERIFY_SKETCH.id,
|
||||
label: 'Verify/Compile',
|
||||
order: '0'
|
||||
});
|
||||
}
|
||||
|
||||
registerKeybindings(registry: KeybindingRegistry): void {
|
||||
registry.registerKeybinding({
|
||||
command: VerifySketch.Commands.VERIFY_SKETCH.id,
|
||||
keybinding: 'CtrlCmd+R'
|
||||
});
|
||||
}
|
||||
|
||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||
registry.registerItem({
|
||||
id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
|
||||
command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
|
||||
tooltip: 'Verify',
|
||||
priority: 0
|
||||
});
|
||||
}
|
||||
|
||||
async verifySketch(): Promise<void> {
|
||||
const sketch = await this.getCurrentSketch();
|
||||
if (!sketch) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const { boardsConfig } = this.boardsServiceClientImpl;
|
||||
if (!boardsConfig || !boardsConfig.selectedBoard) {
|
||||
throw new Error('No boards selected. Please select a board.');
|
||||
}
|
||||
if (!boardsConfig.selectedBoard.fqbn) {
|
||||
throw new Error(`No core is installed for the '${boardsConfig.selectedBoard.name}' board. Please install the core.`);
|
||||
}
|
||||
const fqbn = await this.boardsConfigStore.appendConfigToFqbn(boardsConfig.selectedBoard.fqbn);
|
||||
await this.coreService.compile({
|
||||
sketchUri: sketch.uri,
|
||||
fqbn,
|
||||
optimizeForDebug: this.editorMode.compileForDebug
|
||||
});
|
||||
} catch (e) {
|
||||
await this.messageService.error(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace VerifySketch {
|
||||
export namespace Commands {
|
||||
export const VERIFY_SKETCH: Command = {
|
||||
id: 'arduino-verify-sketch'
|
||||
};
|
||||
export const VERIFY_SKETCH_TOOLBAR: Command = {
|
||||
id: 'arduino-verify-sketch--toolbar'
|
||||
};
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ import { FrontendApplicationContribution } from '@theia/core/lib/browser/fronten
|
||||
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||
import { MenuModelRegistry } from '@theia/core';
|
||||
import { LibraryListWidget } from './library-list-widget';
|
||||
import { ArduinoMenus } from '../arduino-frontend-contribution';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
|
||||
@injectable()
|
||||
export class LibraryListWidgetFrontendContribution extends AbstractViewContribution<LibraryListWidget> implements FrontendApplicationContribution {
|
||||
|
@ -1,12 +1,24 @@
|
||||
import { MAIN_MENU_BAR } from '@theia/core/lib/common/menu';
|
||||
import { CommonMenus } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||
|
||||
export namespace ArduinoMenus {
|
||||
|
||||
// Main menu
|
||||
// File
|
||||
export const FILE__SKETCH_GROUP = [...CommonMenus.FILE, '0_sketch'];
|
||||
export const FILE__PRINT_GROUP = [...CommonMenus.FILE, '1_print'];
|
||||
|
||||
// `Open...` context menu
|
||||
// Sketch
|
||||
export const SKETCH = [...MAIN_MENU_BAR, '3_sketch'];
|
||||
export const SKETCH__MAIN_GROUP = [...SKETCH, '0_main'];
|
||||
export const SKETCH__UTILS_GROUP = [...SKETCH, '1_utils'];
|
||||
|
||||
// Tools
|
||||
export const TOOLS = [...MAIN_MENU_BAR, '4_tools'];
|
||||
export const TOOLS__MAIN_GROUP = [...TOOLS, '0_main'];
|
||||
|
||||
// Context menu
|
||||
// Open
|
||||
export const OPEN_SKETCH__CONTEXT = ['arduino-open-sketch--context'];
|
||||
export const OPEN_SKETCH__CONTEXT__OPEN_GROUP = [...OPEN_SKETCH__CONTEXT, '0_open'];
|
||||
export const OPEN_SKETCH__CONTEXT__RECENT_GROUP = [...OPEN_SKETCH__CONTEXT, '1_recent'];
|
||||
|
@ -5,7 +5,6 @@ import { MainMenuManager } from './main-menu-manager';
|
||||
import { ArduinoMenuContribution } from './arduino-menu-contribution';
|
||||
import { ArduinoBrowserMainMenuFactory } from './arduino-browser-main-menu-factory';
|
||||
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(ArduinoBrowserMainMenuFactory).toSelf().inSingletonScope();
|
||||
bind(MainMenuManager).toService(ArduinoBrowserMainMenuFactory);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { injectable, inject } from "inversify";
|
||||
import { AbstractViewContribution } from "@theia/core/lib/browser";
|
||||
import { MonitorWidget } from "./monitor-widget";
|
||||
import { MenuModelRegistry, Command, CommandRegistry } from "@theia/core";
|
||||
import { ArduinoMenus } from "../arduino-frontend-contribution";
|
||||
import { TabBarToolbarContribution, TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar";
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { AbstractViewContribution } from '@theia/core/lib/browser';
|
||||
import { MonitorWidget } from './monitor-widget';
|
||||
import { MenuModelRegistry, Command, CommandRegistry } from '@theia/core';
|
||||
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||
import { MonitorModel } from './monitor-model';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
|
||||
export namespace SerialMonitor {
|
||||
export namespace Commands {
|
||||
|
@ -28,8 +28,8 @@
|
||||
background: var(--theia-button-hoverBackground);
|
||||
}
|
||||
|
||||
.arduino-verify,
|
||||
.arduino-upload {
|
||||
.arduino-verify-sketch--toolbar,
|
||||
.arduino-upload-sketch--toolbar {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
@ -43,17 +43,17 @@
|
||||
mask-size: 800%;
|
||||
}
|
||||
|
||||
.arduino-save-sketch-icon {
|
||||
.arduino-save-sketch--toolbar-icon {
|
||||
-webkit-mask-position: 59px -4px;
|
||||
mask-position: 59px -4px;
|
||||
}
|
||||
|
||||
.arduino-verify-icon {
|
||||
.arduino-verify-sketch--toolbar-icon {
|
||||
-webkit-mask-position: 188px -4px;
|
||||
mask-position: 188px -4px;
|
||||
}
|
||||
|
||||
.arduino-upload-icon {
|
||||
.arduino-upload-sketch--toolbar-icon {
|
||||
-webkit-mask-position: 156px -4px;
|
||||
mask-position: 156px -4px;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user