diff --git a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx index d9d8f632..9d337ac1 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx +++ b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx @@ -155,7 +155,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut this.statusBar.setElement('arduino-selected-port', { alignment: StatusBarAlignment.RIGHT, text: selectedPort ? `on ${Port.toString(selectedPort)}` : '[not connected]', - className: 'arduino-selected-port' + className: 'arduino-selected-port' }); } } @@ -256,9 +256,6 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut commandId: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, label: 'Advanced Mode' }); - registry.registerMenuAction([...CommonMenus.FILE_SETTINGS_SUBMENU, '3_settings_cli'], { - commandId: ArduinoCommands.OPEN_CLI_CONFIG.id - }); } registerKeybindings(keybindings: KeybindingRegistry): void { diff --git a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts index 22e10781..d206389f 100644 --- a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts @@ -102,6 +102,7 @@ import { PreferencesContribution as TheiaPreferencesContribution } from '@theia/ import { PreferencesContribution } from './theia/preferences/preference-contribution'; import { QuitApp } from './contributions/quit-app'; import { SketchControl } from './contributions/sketch-control-contributions'; +import { Settings } from './contributions/settings'; const ElementQueries = require('css-element-queries/src/ElementQueries'); @@ -331,4 +332,5 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { Contribution.configure(bind, EditContributions); Contribution.configure(bind, QuitApp); Contribution.configure(bind, SketchControl); + Contribution.configure(bind, Settings); }); diff --git a/arduino-ide-extension/src/browser/contributions/settings.ts b/arduino-ide-extension/src/browser/contributions/settings.ts new file mode 100644 index 00000000..9c3a5845 --- /dev/null +++ b/arduino-ide-extension/src/browser/contributions/settings.ts @@ -0,0 +1,42 @@ +import { inject, injectable } from 'inversify'; +import { open, OpenerService } from '@theia/core/lib/browser/opener-service'; +import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution'; +import { URI, Command, MenuModelRegistry, CommandRegistry, SketchContribution } from './contribution'; +import { ArduinoMenus } from '../menu/arduino-menus'; + +@injectable() +export class Settings extends SketchContribution { + + @inject(OpenerService) + protected readonly openerService: OpenerService; + + registerCommands(registry: CommandRegistry): void { + registry.registerCommand(Settings.Commands.OPEN_CLI_CONFIG, { + execute: () => this.configService.getCliConfigFileUri().then(uri => open(this.openerService, new URI(uri))) + }); + } + + registerMenus(registry: MenuModelRegistry): void { + registry.registerMenuAction(ArduinoMenus.FILE__SETTINGS_GROUP, { + commandId: CommonCommands.OPEN_PREFERENCES.id, + label: 'Preferences...', + order: '0' + }); + registry.registerMenuAction(ArduinoMenus.FILE__SETTINGS_GROUP, { + commandId: Settings.Commands.OPEN_CLI_CONFIG.id, + label: 'Open CLI Configuration', + order: '1', + }); + } + +} + +export namespace Settings { + export namespace Commands { + export const OPEN_CLI_CONFIG: Command = { + id: 'arduino-open-cli-config', + label: 'Open CLI Configuration', + category: 'Arduino' + } + } +} diff --git a/arduino-ide-extension/src/browser/menu/arduino-menus.ts b/arduino-ide-extension/src/browser/menu/arduino-menus.ts index a0606ea8..f0a8467d 100644 --- a/arduino-ide-extension/src/browser/menu/arduino-menus.ts +++ b/arduino-ide-extension/src/browser/menu/arduino-menus.ts @@ -1,41 +1,49 @@ import { MAIN_MENU_BAR } from '@theia/core/lib/common/menu'; import { CommonMenus } from '@theia/core/lib/browser/common-frontend-contribution'; +import { isOSX } from '@theia/core'; export namespace ArduinoMenus { // Main menu - // File + // -- File export const FILE__SKETCH_GROUP = [...CommonMenus.FILE, '0_sketch']; export const FILE__PRINT_GROUP = [...CommonMenus.FILE, '1_print']; - export const FILE__SETTINGS_GROUP = [...CommonMenus.FILE, '2_settings']; + // XXX: on macOS, the settings group is not under `File` + export const FILE__SETTINGS_GROUP = [...(isOSX ? MAIN_MENU_BAR : CommonMenus.FILE), '2_settings']; export const FILE__QUIT_GROUP = [...CommonMenus.FILE, '3_quit']; - // Edit - export const EDIT__TEXT_CONTROL_GROUP = [...CommonMenus.EDIT, '2_text_control']; // `Copy`, `Copy to Forum`, `Paste`, etc. Note: `1_undo` is the first group from Theia - export const EDIT__CODE_CONTROL_GROUP = [...CommonMenus.EDIT, '3_code_control']; // `Comment/Uncomment`, etc. + // -- Edit + // `Copy`, `Copy to Forum`, `Paste`, etc. + // Note: `1_undo` is the first group from Theia, we start with `2` + export const EDIT__TEXT_CONTROL_GROUP = [...CommonMenus.EDIT, '2_text_control']; + // `Comment/Uncomment`, etc. + export const EDIT__CODE_CONTROL_GROUP = [...CommonMenus.EDIT, '3_code_control']; export const EDIT__FONT_CONTROL_GROUP = [...CommonMenus.EDIT, '4_font_control']; export const EDIT__FIND_GROUP = [...CommonMenus.EDIT, '5_find']; - // Sketch + // -- 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 + // -- Tools export const TOOLS = [...MAIN_MENU_BAR, '4_tools']; export const TOOLS__MAIN_GROUP = [...TOOLS, '0_main']; // Context menu - // Open + // -- 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']; export const OPEN_SKETCH__CONTEXT__EXAMPLES_GROUP = [...OPEN_SKETCH__CONTEXT, '2_examples']; - // Sketch control (such as `New Tab`, `Rename`, `Delete`, etc.) + // -- Sketch control export const SKETCH_CONTROL__CONTEXT = ['arduino-sketch-control--context']; + // `New Tab`, `Rename`, `Delete` export const SKETCH_CONTROL__CONTEXT__MAIN_GROUP = [...SKETCH_CONTROL__CONTEXT, '0_main']; + // `Previous Tab`, `Next Tab` export const SKETCH_CONTROL__CONTEXT__NAVIGATION_GROUP = [...SKETCH_CONTROL__CONTEXT, '1_navigation']; + // Sketch files opened in editors export const SKETCH_CONTROL__CONTEXT__RESOURCES_GROUP = [...SKETCH_CONTROL__CONTEXT, '2_resources']; } diff --git a/arduino-ide-extension/src/browser/theia/core/common-frontend-contribution.ts b/arduino-ide-extension/src/browser/theia/core/common-frontend-contribution.ts index 3517f6df..ac1f309b 100644 --- a/arduino-ide-extension/src/browser/theia/core/common-frontend-contribution.ts +++ b/arduino-ide-extension/src/browser/theia/core/common-frontend-contribution.ts @@ -19,7 +19,8 @@ export class CommonFrontendContribution extends TheiaCommonFrontendContribution CommonCommands.AUTO_SAVE, CommonCommands.OPEN_PREFERENCES, CommonCommands.SELECT_ICON_THEME, - CommonCommands.SELECT_COLOR_THEME + CommonCommands.SELECT_COLOR_THEME, + CommonCommands.OPEN_PREFERENCES ]) { registry.unregisterMenuAction(command); } diff --git a/arduino-ide-extension/src/browser/theia/core/tab-bar-decorator.ts b/arduino-ide-extension/src/browser/theia/core/tab-bar-decorator.ts index b774dc8d..e82a5f81 100644 --- a/arduino-ide-extension/src/browser/theia/core/tab-bar-decorator.ts +++ b/arduino-ide-extension/src/browser/theia/core/tab-bar-decorator.ts @@ -16,7 +16,6 @@ export class TabBarDecoratorService extends TheiaTabBarDecoratorService { @inject(ILogger) protected readonly logger: ILogger; - protected dataDirUri: URI | undefined; @postConstruct() diff --git a/arduino-ide-extension/src/browser/theia/preferences/preference-contribution.ts b/arduino-ide-extension/src/browser/theia/preferences/preference-contribution.ts index f8d67870..9f1e0c6b 100644 --- a/arduino-ide-extension/src/browser/theia/preferences/preference-contribution.ts +++ b/arduino-ide-extension/src/browser/theia/preferences/preference-contribution.ts @@ -1,11 +1,21 @@ import { injectable } from 'inversify'; +import { isOSX } from '@theia/core/lib/common/os'; +import { MenuModelRegistry } from '@theia/core/lib/common/menu'; import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding'; +import { CommonCommands, CommonMenus } from '@theia/core/lib/browser'; import { PreferencesContribution as TheiaPreferencesContribution } from '@theia/preferences/lib/browser/preference-contribution'; -import { CommonCommands } from '@theia/core/lib/browser'; @injectable() export class PreferencesContribution extends TheiaPreferencesContribution { + registerMenus(registry: MenuModelRegistry): void { + super.registerMenus(registry); + if (isOSX) { + // The settings group: preferences, CLI config is not part of the `File` menu on macOS. + registry.unregisterMenuAction(CommonCommands.OPEN_PREFERENCES.id, CommonMenus.FILE_SETTINGS_SUBMENU_OPEN); + } + } + registerKeybindings(registry: KeybindingRegistry): void { // https://github.com/eclipse-theia/theia/issues/8202 registry.registerKeybinding({ diff --git a/arduino-ide-extension/src/electron-browser/theia/core/electron-main-menu-factory.ts b/arduino-ide-extension/src/electron-browser/theia/core/electron-main-menu-factory.ts index e952c991..8d0ad110 100644 --- a/arduino-ide-extension/src/electron-browser/theia/core/electron-main-menu-factory.ts +++ b/arduino-ide-extension/src/electron-browser/theia/core/electron-main-menu-factory.ts @@ -1,6 +1,8 @@ import { injectable } from 'inversify' +import { remote } from 'electron'; import { Keybinding } from '@theia/core/lib/common/keybinding'; import { ElectronMainMenuFactory as TheiaElectronMainMenuFactory } from '@theia/core/lib/electron-browser/menu/electron-main-menu-factory'; +import { ArduinoMenus } from '../../../browser/menu/arduino-menus'; @injectable() export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory { @@ -14,4 +16,25 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory { .replace('→', 'Right'); } + protected createOSXMenu(): Electron.MenuItemConstructorOptions { + const { submenu } = super.createOSXMenu(); + const label = 'Arduino Pro IDE'; + if (!!submenu && !(submenu instanceof remote.Menu)) { + const [about, , ...rest] = submenu; + const menuModel = this.menuProvider.getMenu(ArduinoMenus.FILE__SETTINGS_GROUP); + const settings = this.fillMenuTemplate([], menuModel); + return { + label, + submenu: [ + about, // TODO: we have two about dialogs! one from electron the other from Theia. + { type: 'separator' }, + ...settings, + { type: 'separator' }, + ...rest + ] + }; + } + return { label, submenu }; + } + }