From fdd621787bad7198b0538e7df113f3c32e04858f Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Thu, 15 Sep 2022 15:50:21 +0200 Subject: [PATCH] Fixed missing translations Aligned the languge pack versions. Closes #1431 Signed-off-by: Akos Kitta --- .../browser/arduino-ide-frontend-module.ts | 20 -- .../src/browser/boards/boards-config.tsx | 11 +- .../browser/contributions/board-selection.ts | 7 +- .../dialogs/settings/settings-component.tsx | 23 ++- .../plotter/plotter-frontend-contribution.ts | 8 +- .../src/browser/style/list-widget.css | 6 +- .../search-in-workspace-result-tree-widget.ts | 44 ----- .../search-in-workspace-widget.tsx | 80 -------- .../component-list/list-item-renderer.tsx | 9 +- .../src/common/protocol/boards-service.ts | 23 +++ .../src/common/protocol/core-service.ts | 12 ++ .../i18n/arduino-localization-contribution.ts | 173 ++++-------------- .../i18n/localization-backend-contribution.ts | 4 +- electron-app/patch/frontend/index.js | 56 +++++- electron/build/template-package.json | 19 -- electron/packager/index.js | 37 ++-- i18n/en.json | 27 ++- package.json | 25 ++- 18 files changed, 235 insertions(+), 349 deletions(-) delete mode 100644 arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-result-tree-widget.ts delete mode 100644 arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-widget.tsx 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 d6e9571f7..0a6df55ff 100644 --- a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts @@ -53,8 +53,6 @@ import { DockPanelRenderer as TheiaDockPanelRenderer, TabBarRendererFactory, ContextMenuRenderer, - createTreeContainer, - TreeWidget, } from '@theia/core/lib/browser'; import { MenuContribution } from '@theia/core/lib/common/menu'; import { @@ -207,12 +205,8 @@ import { WorkspaceVariableContribution as TheiaWorkspaceVariableContribution } f import { WorkspaceVariableContribution } from './theia/workspace/workspace-variable-contribution'; import { DebugConfigurationManager } from './theia/debug/debug-configuration-manager'; import { DebugConfigurationManager as TheiaDebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager'; -import { SearchInWorkspaceWidget as TheiaSearchInWorkspaceWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-widget'; -import { SearchInWorkspaceWidget } from './theia/search-in-workspace/search-in-workspace-widget'; import { SearchInWorkspaceFactory as TheiaSearchInWorkspaceFactory } from '@theia/search-in-workspace/lib/browser/search-in-workspace-factory'; import { SearchInWorkspaceFactory } from './theia/search-in-workspace/search-in-workspace-factory'; -import { SearchInWorkspaceResultTreeWidget as TheiaSearchInWorkspaceResultTreeWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-result-tree-widget'; -import { SearchInWorkspaceResultTreeWidget } from './theia/search-in-workspace/search-in-workspace-result-tree-widget'; import { MonacoEditorProvider } from './theia/monaco/monaco-editor-provider'; import { MonacoEditorFactory, @@ -605,9 +599,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(MonacoEditorProvider).toSelf().inSingletonScope(); rebind(TheiaMonacoEditorProvider).toService(MonacoEditorProvider); - bind(SearchInWorkspaceWidget).toSelf(); - rebind(TheiaSearchInWorkspaceWidget).toService(SearchInWorkspaceWidget); - // Disabled reference counter in the editor manager to avoid opening the same editor (with different opener options) multiple times. bind(EditorManager).toSelf().inSingletonScope(); rebind(TheiaEditorManager).toService(EditorManager); @@ -617,17 +608,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { .to(SearchInWorkspaceFactory) .inSingletonScope(); - rebind(TheiaSearchInWorkspaceResultTreeWidget).toDynamicValue( - ({ container }) => { - const childContainer = createTreeContainer(container); - childContainer.bind(SearchInWorkspaceResultTreeWidget).toSelf(); - childContainer - .rebind(TreeWidget) - .toService(SearchInWorkspaceResultTreeWidget); - return childContainer.get(SearchInWorkspaceResultTreeWidget); - } - ); - // Show a disconnected status bar, when the daemon is not available bind(ApplicationConnectionStatusContribution).toSelf().inSingletonScope(); rebind(TheiaApplicationConnectionStatusContribution).toService( diff --git a/arduino-ide-extension/src/browser/boards/boards-config.tsx b/arduino-ide-extension/src/browser/boards/boards-config.tsx index c145ec924..df5ed5a33 100644 --- a/arduino-ide-extension/src/browser/boards/boards-config.tsx +++ b/arduino-ide-extension/src/browser/boards/boards-config.tsx @@ -259,9 +259,12 @@ export class BoardsConfig extends React.Component< override render(): React.ReactNode { return ( <> - {this.renderContainer('boards', this.renderBoards.bind(this))} {this.renderContainer( - 'ports', + nls.localize('arduino/board/boards', 'boards'), + this.renderBoards.bind(this) + )} + {this.renderContainer( + nls.localize('arduino/board/ports', 'ports'), this.renderPorts.bind(this), this.renderPortsFooter.bind(this) )} @@ -384,7 +387,9 @@ export class BoardsConfig extends React.Component< defaultChecked={this.state.showAllPorts} onChange={this.toggleFilterPorts} /> - Show all ports + + {nls.localize('arduino/board/showAllPorts', 'Show all ports')} + ); diff --git a/arduino-ide-extension/src/browser/contributions/board-selection.ts b/arduino-ide-extension/src/browser/contributions/board-selection.ts index 21acc221b..037587d99 100644 --- a/arduino-ide-extension/src/browser/contributions/board-selection.ts +++ b/arduino-ide-extension/src/browser/contributions/board-selection.ts @@ -5,7 +5,6 @@ import { DisposableCollection, Disposable, } from '@theia/core/lib/common/disposable'; -import { firstToUpperCase } from '../../common/utils'; import { BoardsConfig } from '../boards/boards-config'; import { MainMenuManager } from '../../common/main-menu-manager'; import { BoardsListWidget } from '../boards/boards-list-widget'; @@ -267,7 +266,11 @@ PID: ${PID}`; ]; const placeholder = new PlaceholderMenuNode( menuPath, - `${firstToUpperCase(protocol)} ports`, + nls.localize( + 'arduino/board/typeOfPorts', + '{0} ports', + Port.Protocols.protocolLabel(protocol) + ), { order: protocolOrder.toString() } ); this.menuModelRegistry.registerMenuNode(menuPath, placeholder); diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx index f6d380c4d..dac80d61c 100644 --- a/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx +++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx @@ -10,6 +10,7 @@ import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog/fil import { DisposableCollection } from '@theia/core/lib/common/disposable'; import { AdditionalUrls, + CompilerWarnings, CompilerWarningLiterals, Network, ProxySettings, @@ -260,7 +261,7 @@ export class SettingsComponent extends React.Component< > {CompilerWarningLiterals.map((value) => ( ))} @@ -398,10 +399,22 @@ export class SettingsComponent extends React.Component<
-
Host name:
-
Port number:
-
Username:
-
Password:
+
{`${nls.localize( + 'arduino/preferences/proxySettings/hostname', + 'Host name' + )}:`}
+
{`${nls.localize( + 'arduino/preferences/proxySettings/port', + 'Port number' + )}:`}
+
{`${nls.localize( + 'arduino/preferences/proxySettings/username', + 'Username' + )}:`}
+
{`${nls.localize( + 'arduino/preferences/proxySettings/password', + 'Password' + )}:`}
diff --git a/arduino-ide-extension/src/browser/serial/plotter/plotter-frontend-contribution.ts b/arduino-ide-extension/src/browser/serial/plotter/plotter-frontend-contribution.ts index 3914c061a..c403c4201 100644 --- a/arduino-ide-extension/src/browser/serial/plotter/plotter-frontend-contribution.ts +++ b/arduino-ide-extension/src/browser/serial/plotter/plotter-frontend-contribution.ts @@ -18,6 +18,7 @@ import { CLOSE_PLOTTER_WINDOW, SHOW_PLOTTER_WINDOW, } from '../../../common/ipc-communication'; +import { nls } from '@theia/core/lib/common/nls'; const queryString = require('query-string'); @@ -107,7 +108,12 @@ export class PlotterFrontendContribution extends Contribution { if (wsPort) { this.open(wsPort); } else { - this.messageService.error(`Couldn't open serial plotter`); + this.messageService.error( + nls.localize( + 'arduino/contributions/plotter/couldNotOpen', + "Couldn't open serial plotter" + ) + ); } } diff --git a/arduino-ide-extension/src/browser/style/list-widget.css b/arduino-ide-extension/src/browser/style/list-widget.css index f60159e34..843be61f9 100644 --- a/arduino-ide-extension/src/browser/style/list-widget.css +++ b/arduino-ide-extension/src/browser/style/list-widget.css @@ -111,13 +111,15 @@ font-weight: bold; max-height: calc(1em + 4px); color: var(--theia-button-foreground); - content: 'INSTALLED'; + content: attr(install); + text-transform: uppercase; } .component-list-item .header .installed:hover:before { background-color: var(--theia-button-foreground); color: var(--theia-button-background); - content: 'UNINSTALL'; + content: attr(uninstall); + text-transform: uppercase; } .component-list-item[min-width~="170px"] .footer { diff --git a/arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-result-tree-widget.ts b/arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-result-tree-widget.ts deleted file mode 100644 index e831cd402..000000000 --- a/arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-result-tree-widget.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { injectable } from '@theia/core/shared/inversify'; -import URI from '@theia/core/lib/common/uri'; -import { - SearchInWorkspaceFileNode, - SearchInWorkspaceResultTreeWidget as TheiaSearchInWorkspaceResultTreeWidget, -} from '@theia/search-in-workspace/lib/browser/search-in-workspace-result-tree-widget'; -import { MEMORY_TEXT } from '@theia/core/lib/common/resource'; - -/** - * Workaround for https://github.com/eclipse-theia/theia/pull/9192/. - */ -@injectable() -export class SearchInWorkspaceResultTreeWidget extends TheiaSearchInWorkspaceResultTreeWidget { - protected override async createReplacePreview( - node: SearchInWorkspaceFileNode - ): Promise { - const fileUri = new URI(node.fileUri).withScheme('file'); - const openedEditor = this.editorManager.all.find( - ({ editor }) => editor.uri.toString() === fileUri.toString() - ); - let content: string; - if (openedEditor) { - content = openedEditor.editor.document.getText(); - } else { - const resource = await this.fileResourceResolver.resolve(fileUri); - content = await resource.readContents(); - } - - const lines = content.split('\n'); - node.children.map((l) => { - const leftPositionedNodes = node.children.filter( - (rl) => rl.line === l.line && rl.character < l.character - ); - const diff = - (this._replaceTerm.length - this.searchTerm.length) * - leftPositionedNodes.length; - const start = lines[l.line - 1].substr(0, l.character - 1 + diff); - const end = lines[l.line - 1].substr(l.character - 1 + diff + l.length); - lines[l.line - 1] = start + this._replaceTerm + end; - }); - - return fileUri.withScheme(MEMORY_TEXT).withQuery(lines.join('\n')); - } -} diff --git a/arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-widget.tsx b/arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-widget.tsx deleted file mode 100644 index cae633024..000000000 --- a/arduino-ide-extension/src/browser/theia/search-in-workspace/search-in-workspace-widget.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { injectable, postConstruct } from '@theia/core/shared/inversify'; -import * as React from '@theia/core/shared/react'; -import { Key, KeyCode } from '@theia/core/lib/browser'; -import { SearchInWorkspaceWidget as TheiaSearchInWorkspaceWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-widget'; - -/** - * Workaround for https://github.com/eclipse-theia/theia/pull/9183. - */ -@injectable() -export class SearchInWorkspaceWidget extends TheiaSearchInWorkspaceWidget { - @postConstruct() - protected override init(): void { - super.init(); - this.title.iconClass = 'fa fa-arduino-search'; - } - - protected override renderGlobField(kind: 'include' | 'exclude'): React.ReactNode { - const currentValue = this.searchInWorkspaceOptions[kind]; - const value = (currentValue && currentValue.join(', ')) || ''; - return ( -
-
{'files to ' + kind}
- { - if (e.target) { - const targetValue = (e.target as HTMLInputElement).value || ''; - let shouldSearch = - Key.ENTER.keyCode === - KeyCode.createKeyCode(e.nativeEvent).key?.keyCode; - const currentOptions = (this.searchInWorkspaceOptions[kind] || []) - .slice() - .map((s) => s.trim()) - .sort(); - const candidateOptions = this.splitOnComma(targetValue) - .map((s) => s.trim()) - .sort(); - const sameAs = (left: string[], right: string[]) => { - if (left.length !== right.length) { - return false; - } - for (let i = 0; i < left.length; i++) { - if (left[i] !== right[i]) { - return false; - } - } - return true; - }; - if (!sameAs(currentOptions, candidateOptions)) { - this.searchInWorkspaceOptions[kind] = - this.splitOnComma(targetValue); - shouldSearch = true; - } - if (shouldSearch) { - this.resultTreeWidget.search( - this.searchTerm, - this.searchInWorkspaceOptions - ); - } - } - }} - onFocus={ - kind === 'include' - ? this.handleFocusIncludesInputBox - : this.handleFocusExcludesInputBox - } - onBlur={ - kind === 'include' - ? this.handleBlurIncludesInputBox - : this.handleBlurExcludesInputBox - } - > -
- ); - } -} diff --git a/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx b/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx index 537f4d415..ea9e257ec 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx @@ -55,7 +55,14 @@ export class ListItemRenderer { item.installedVersion )} - +
); diff --git a/arduino-ide-extension/src/common/protocol/boards-service.ts b/arduino-ide-extension/src/common/protocol/boards-service.ts index 7be49725e..763fc9bd6 100644 --- a/arduino-ide-extension/src/common/protocol/boards-service.ts +++ b/arduino-ide-extension/src/common/protocol/boards-service.ts @@ -285,6 +285,29 @@ export namespace Port { return false; }; } + + export namespace Protocols { + export const KnownProtocolLiterals = ['serial', 'network'] as const; + export type KnownProtocol = typeof KnownProtocolLiterals[number]; + export namespace KnownProtocol { + export function is(protocol: unknown): protocol is KnownProtocol { + return ( + typeof protocol === 'string' && + KnownProtocolLiterals.indexOf(protocol as KnownProtocol) >= 0 + ); + } + } + export const ProtocolLabels: Record = { + serial: nls.localize('arduino/portProtocol/serial', 'Serial'), + network: nls.localize('arduino/portProtocol/network', 'Network'), + }; + export function protocolLabel(protocol: string): string { + if (KnownProtocol.is(protocol)) { + return ProtocolLabels[protocol]; + } + return protocol; + } + } } export interface BoardsPackage extends ArduinoComponent { diff --git a/arduino-ide-extension/src/common/protocol/core-service.ts b/arduino-ide-extension/src/common/protocol/core-service.ts index a7124d865..a4b63a604 100644 --- a/arduino-ide-extension/src/common/protocol/core-service.ts +++ b/arduino-ide-extension/src/common/protocol/core-service.ts @@ -1,3 +1,4 @@ +import { nls } from '@theia/core/lib/common/nls'; import { ApplicationError } from '@theia/core/lib/common/application-error'; import type { Location, @@ -18,6 +19,17 @@ export const CompilerWarningLiterals = [ 'All', ] as const; export type CompilerWarnings = typeof CompilerWarningLiterals[number]; +export namespace CompilerWarnings { + export function labelOf(warning: CompilerWarnings): string { + return CompilerWarningLabels[warning]; + } + const CompilerWarningLabels: Record = { + None: nls.localize('arduino/core/compilerWarnings/none', 'None'), + Default: nls.localize('arduino/core/compilerWarnings/default', 'Default'), + More: nls.localize('arduino/core/compilerWarnings/more', 'More'), + All: nls.localize('arduino/core/compilerWarnings/all', 'All'), + }; +} export namespace CoreError { export interface ErrorLocationRef { readonly message: string; diff --git a/arduino-ide-extension/src/node/i18n/arduino-localization-contribution.ts b/arduino-ide-extension/src/node/i18n/arduino-localization-contribution.ts index 3465ab83d..686d28bd7 100644 --- a/arduino-ide-extension/src/node/i18n/arduino-localization-contribution.ts +++ b/arduino-ide-extension/src/node/i18n/arduino-localization-contribution.ts @@ -3,150 +3,45 @@ import { LocalizationRegistry, } from '@theia/core/lib/node/i18n/localization-contribution'; import { injectable } from '@theia/core/shared/inversify'; +import { join } from 'path'; @injectable() export class ArduinoLocalizationContribution implements LocalizationContribution { - async registerLocalizations(registry: LocalizationRegistry): Promise { - registry.registerLocalizationFromRequire( - 'af', - require('../../../build/i18n/af.json') - ); - - registry.registerLocalizationFromRequire( - 'en', - require('../../../build/i18n/en.json') - ); - - registry.registerLocalizationFromRequire( - 'fr', - require('../../../build/i18n/fr.json') - ); - - registry.registerLocalizationFromRequire( - 'ko', - require('../../../build/i18n/ko.json') - ); - - registry.registerLocalizationFromRequire( - 'pt-br', - require('../../../build/i18n/pt.json') - ); - - registry.registerLocalizationFromRequire( - 'uk_UA', - require('../../../build/i18n/uk_UA.json') - ); - - registry.registerLocalizationFromRequire( - 'ar', - require('../../../build/i18n/ar.json') - ); - - registry.registerLocalizationFromRequire( - 'es', - require('../../../build/i18n/es.json') - ); - - registry.registerLocalizationFromRequire( - 'he', - require('../../../build/i18n/he.json') - ); - - registry.registerLocalizationFromRequire( - 'my_MM', - require('../../../build/i18n/my_MM.json') - ); - - registry.registerLocalizationFromRequire( - 'ro', - require('../../../build/i18n/ro.json') - ); - - registry.registerLocalizationFromRequire( - 'zh-cn', - require('../../../build/i18n/zh.json') - ); - - registry.registerLocalizationFromRequire( - 'bg', - require('../../../build/i18n/bg.json') - ); - - registry.registerLocalizationFromRequire( - 'eu', - require('../../../build/i18n/eu.json') - ); + // 0. index: locale + // 1. index: optional JSON file to `require` (if differs from the locale) + // If you touch the locales, please keep the alphabetical order. Also in the `package.json` for the VS Code language packs. Thank you! ❤️ + // Note that IDE2 has more translations than available VS Code language packs. (https://github.com/arduino/arduino-ide/issues/1447) + private readonly locales: ReadonlyArray<[string, string?]> = [ + ['bg'], + ['cs'], + ['de'], + ['es'], + ['fr'], + ['hu'], + // ['id'], Does not have Transifex translations, but has a VS Code language pack available on Open VSX. + ['it'], + ['ja'], + ['ko'], + ['nl'], + ['pl'], + ['pt-br', 'pt'], + ['ru'], + ['tr'], + ['uk', 'uk_UA'], + ['zh-cn', 'zh'], + ]; - registry.registerLocalizationFromRequire( - 'hu', - require('../../../build/i18n/hu.json') - ); - - registry.registerLocalizationFromRequire( - 'ne', - require('../../../build/i18n/ne.json') - ); - - registry.registerLocalizationFromRequire( - 'ru', - require('../../../build/i18n/ru.json') - ); - - registry.registerLocalizationFromRequire( - 'zh_TW', - require('../../../build/i18n/zh_TW.json') - ); - - registry.registerLocalizationFromRequire( - 'de', - require('../../../build/i18n/de.json') - ); - - registry.registerLocalizationFromRequire( - 'fa', - require('../../../build/i18n/fa.json') - ); - - registry.registerLocalizationFromRequire( - 'it', - require('../../../build/i18n/it.json') - ); - - registry.registerLocalizationFromRequire( - 'nl', - require('../../../build/i18n/nl.json') - ); - - registry.registerLocalizationFromRequire( - 'sv_SE', - require('../../../build/i18n/sv_SE.json') - ); - - registry.registerLocalizationFromRequire( - 'el', - require('../../../build/i18n/el.json') - ); - - registry.registerLocalizationFromRequire( - 'fil', - require('../../../build/i18n/fil.json') - ); - - registry.registerLocalizationFromRequire( - 'ja', - require('../../../build/i18n/ja.json') - ); - - registry.registerLocalizationFromRequire( - 'pl', - require('../../../build/i18n/pl.json') - ); - - registry.registerLocalizationFromRequire( - 'tr', - require('../../../build/i18n/tr.json') - ); + async registerLocalizations(registry: LocalizationRegistry): Promise { + for (const [locale, jsonFilename] of this.locales) { + registry.registerLocalizationFromRequire( + locale, + require(join( + __dirname, + `../../../build/i18n/${jsonFilename ?? locale}.json` + )) + ); + } } } diff --git a/arduino-ide-extension/src/node/i18n/localization-backend-contribution.ts b/arduino-ide-extension/src/node/i18n/localization-backend-contribution.ts index e5bc11f03..75ea0deba 100644 --- a/arduino-ide-extension/src/node/i18n/localization-backend-contribution.ts +++ b/arduino-ide-extension/src/node/i18n/localization-backend-contribution.ts @@ -23,8 +23,8 @@ export class LocalizationBackendContribution extends TheiaLocalizationBackendCon app.get('/i18n/:locale', async (req, res) => { let locale = req.params.locale; /* - Waiting for the deploy of the language plugins is neecessary to avoid checking the available - languages before they're finished to be loaded: https://github.com/eclipse-theia/theia/issues/11471 + Waiting for the deploy of the language plugins is necessary to avoid checking the available + languages before they're finished to be loaded: https://github.com/eclipse-theia/theia/issues/11471 */ const start = performance.now(); await this.initialized.promise; diff --git a/electron-app/patch/frontend/index.js b/electron-app/patch/frontend/index.js index 26afbfedd..c227aef44 100644 --- a/electron-app/patch/frontend/index.js +++ b/electron-app/patch/frontend/index.js @@ -17,6 +17,53 @@ const { FrontendApplicationConfigProvider, } = require('@theia/core/lib/browser/frontend-application-config-provider'); +function fetchFrom(path) { + const { Endpoint } = require('@theia/core/lib/browser/endpoint'); + const endpoint = new Endpoint({ path }).getRestUrl().toString(); + return fetch(endpoint); +} + +async function loadTranslations() { + const { nls } = require('@theia/core/lib/common/nls'); + const defaultLocale = typeof window === 'object' && window && window.localStorage.getItem(nls.localeId) || ''; + if (defaultLocale && !nls.locale) { + Object.assign(nls, { + locale: defaultLocale + }); + } + if (nls.locale) { + const response = await fetchFrom(`/i18n/${nls.locale}`); + nls.localization = await response.json(); + } +} + +async function loadBackendOS() { + const response = await fetchFrom('/os'); + const osType = await response.text(); + const isWindows = osType === 'Windows'; + const isOSX = osType === 'OSX'; + OS.backend.isOSX = isOSX; + OS.backend.isWindows = isWindows; + OS.backend.type = () => osType; +} + +function customizeMonacoNls() { + const MonacoNls = require('@theia/monaco-editor-core/esm/vs/nls'); + const { nls: TheiaNls } = require('@theia/core/lib/common/nls'); + const { Localization } = require('@theia/core/lib/common/i18n/localization'); + Object.assign(MonacoNls, { + localize(_, label, ...args) { + if (TheiaNls.locale) { + const defaultKey = TheiaNls.getDefaultKey(label); + if (defaultKey) { + return TheiaNls.localize(defaultKey, label, ...args); + } + } + return Localization.format(label, args); + } + }); +} + // It is a mighty hack to support theme updates in the bundled IDE2. // If the custom theme registration happens before the restoration of the existing monaco themes, then any custom theme changes will be ignored. // This patch introduces a static deferred promise in the monaco-theming service that will be resolved when the restoration is ready. @@ -25,8 +72,14 @@ const { // This patch customizes the monaco theme service behavior before loading the DI containers via the preload. // The preload is called only once before the app loads. The Theia extensions are not loaded at that point, but the app config provider is ready. const preloader = require('@theia/core/lib/browser/preloader'); -const originalPreload = preloader.preload; preloader.preload = async function () { + // Must require the monaco frontend module to activate the NLS customization for monaco. + // Otherwise, the NLS customization would trigger after the monaco UI components with all their translations are already loaded. + await Promise.allSettled([ + loadTranslations(), + loadBackendOS(), + ]); + customizeMonacoNls(); const { MonacoThemingService } = require('@theia/monaco/lib/browser/monaco-theming-service'); const { MonacoThemeServiceIsReady } = require('arduino-ide-extension/lib/browser/utils/window'); const { Deferred } = require('@theia/core/lib/common/promise-util'); @@ -42,7 +95,6 @@ preloader.preload = async function () { await this.restore(); ready.resolve(); }.bind(MonacoThemingService); - return originalPreload(); }.bind(preloader); const lightTheme = 'arduino-theme'; diff --git a/electron/build/template-package.json b/electron/build/template-package.json index 5c15d0560..f934a176f 100644 --- a/electron/build/template-package.json +++ b/electron/build/template-package.json @@ -137,24 +137,5 @@ "path": "arduino-ide/nightly" } ] - }, - "theiaPluginsDir": "plugins", - "theiaPlugins": { - "vscode-builtin-cpp": "https://open-vsx.org/api/vscode/cpp/1.52.1/file/vscode.cpp-1.52.1.vsix", - "vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.5.vsix", - "vscode-builtin-json": "https://open-vsx.org/api/vscode/json/1.46.1/file/vscode.json-1.46.1.vsix", - "vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix", - "cortex-debug": "https://open-vsx.org/api/marus25/cortex-debug/0.3.10/file/marus25.cortex-debug-0.3.10.vsix", - "vscode-language-pack-nl": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-nl/1.48.3/file/MS-CEINTL.vscode-language-pack-nl-1.48.3.vsix", - "vscode-language-pack-fr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-fr/1.69.0/file/MS-CEINTL.vscode-language-pack-fr-1.69.0.vsix", - "vscode-language-pack-zh-hans": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-zh-hans/1.69.0/file/MS-CEINTL.vscode-language-pack-zh-hans-1.69.0.vsix", - "vscode-language-pack-de": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-de/1.69.0/file/MS-CEINTL.vscode-language-pack-de-1.69.0.vsix", - "vscode-language-pack-ja": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ja/1.69.0/file/MS-CEINTL.vscode-language-pack-ja-1.69.0.vsix", - "vscode-language-pack-tr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-tr/1.69.0/file/MS-CEINTL.vscode-language-pack-tr-1.69.0.vsix", - "vscode-language-pack-it": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-it/1.69.0/file/MS-CEINTL.vscode-language-pack-it-1.69.0.vsix", - "vscode-language-pack-ru":"https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ru/1.69.0/file/MS-CEINTL.vscode-language-pack-ru-1.69.0.vsix", - "vscode-language-pack-es": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-es/1.69.0/file/MS-CEINTL.vscode-language-pack-es-1.69.0.vsix", - "vscode-language-pack-pt-BR": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-pt-BR/1.69.0/file/MS-CEINTL.vscode-language-pack-pt-BR-1.69.0.vsix", - "vscode-language-pack-cs": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-cs/1.69.0/file/MS-CEINTL.vscode-language-pack-cs-1.69.0.vsix" } } diff --git a/electron/packager/index.js b/electron/packager/index.js index 12b36097a..d769fecc0 100644 --- a/electron/packager/index.js +++ b/electron/packager/index.js @@ -123,8 +123,8 @@ // Save some time: no need to build the projects that are not needed in final app. Currently unused. | //---------------------------------------------------------------------------------------------------+ //@ts-ignore - let pkg = require('../working-copy/package.json'); - const workspaces = pkg.workspaces; + const rootPackageJson = require('../working-copy/package.json'); + const workspaces = rootPackageJson.workspaces; // We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies. const dependenciesToRemove = []; for (const dependencyToRemove of dependenciesToRemove) { @@ -133,10 +133,10 @@ workspaces.splice(index, 1); } } - pkg.workspaces = workspaces; + rootPackageJson.workspaces = workspaces; fs.writeFileSync( path('..', workingCopy, 'package.json'), - JSON.stringify(pkg, null, 2) + JSON.stringify(rootPackageJson, null, 2) ); //-------------------------------------------------------------------------------------------------+ @@ -169,13 +169,13 @@ if (extension !== 'arduino-ide-extension') { // Do not unlink self. // @ts-ignore - pkg = require(`../working-copy/${extension}/package.json`); + rootPackageJson = require(`../working-copy/${extension}/package.json`); // @ts-ignore - pkg.dependencies['arduino-ide-extension'] = + rootPackageJson.dependencies['arduino-ide-extension'] = 'file:../arduino-ide-extension'; fs.writeFileSync( path('..', workingCopy, extension, 'package.json'), - JSON.stringify(pkg, null, 2) + JSON.stringify(rootPackageJson, null, 2) ); } } @@ -184,7 +184,7 @@ // Merge the `working-copy/package.json` with `electron/build/template-package.json`. | //------------------------------------------------------------------------------------+ // @ts-ignore - pkg = require('../working-copy/electron-app/package.json'); + const appPackageJson = require('../working-copy/electron-app/package.json'); template.build.files = [ ...template.build.files, ...unusedDependencies.map((name) => `!node_modules/${name}`), @@ -195,25 +195,26 @@ dependencies[extension] = `file:../working-copy/${extension}`; } // @ts-ignore - pkg.dependencies = { ...pkg.dependencies, ...dependencies }; - pkg.devDependencies = { ...pkg.devDependencies, ...template.devDependencies }; - // Deep-merging the Theia application configuration. We enable the electron window reload in dev mode but not for the final product. (arduino/arduino-pro-ide#187) + appPackageJson.dependencies = { ...appPackageJson.dependencies, ...dependencies }; + appPackageJson.devDependencies = { ...appPackageJson.devDependencies, ...template.devDependencies }; + // Deep-merging the Theia application configuration. // @ts-ignore - const theia = merge(pkg.theia || {}, template.theia || {}); + const theia = merge(appPackageJson.theia || {}, template.theia || {}); const content = { - ...pkg, + ...appPackageJson, ...template, theia, // @ts-ignore - dependencies: pkg.dependencies, - devDependencies: pkg.devDependencies, + dependencies: appPackageJson.dependencies, + devDependencies: appPackageJson.devDependencies, + // VS Code extensions and the plugins folder is defined in the top level `package.json`. The template picks them up. + theiaPluginsDir: rootPackageJson.theiaPluginsDir, + theiaPlugins: rootPackageJson.theiaPlugins, }; - const overwriteMerge = (destinationArray, sourceArray, options) => - sourceArray; fs.writeFileSync( path('..', 'build', 'package.json'), JSON.stringify( - merge(content, template, { arrayMerge: overwriteMerge }), + merge(content, template, { arrayMerge: (_, sourceArray) => sourceArray }), null, 2 ) diff --git a/i18n/en.json b/i18n/en.json index dff1729e5..4db465ba8 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -8,6 +8,7 @@ "board": "Board{0}", "boardConfigDialogTitle": "Select Other Board and Port", "boardInfo": "Board Info", + "boards": "boards", "configDialog1": "Select both a Board and a Port if you want to upload a sketch.", "configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.", "couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?", @@ -25,6 +26,7 @@ "pleasePickBoard": "Please pick a board connected to the port you have selected.", "port": "Port{0}", "portLabel": "Port: {0}", + "ports": "ports", "programmer": "Programmer", "reselectLater": "Reselect later", "searchBoard": "Search board", @@ -32,8 +34,10 @@ "selectBoardForInfo": "Please select a board to obtain board info.", "selectPortForInfo": "Please select a port to obtain board info.", "showAllAvailablePorts": "Shows all available ports when enabled", + "showAllPorts": "Show all ports", "succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}", - "succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}" + "succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}", + "typeOfPorts": "{0} ports" }, "boardsManager": "Boards Manager", "boardsType": { @@ -149,8 +153,19 @@ "contributions": { "addFile": "Add File", "fileAdded": "One file added to the sketch.", + "plotter": { + "couldNotOpen": "Couldn't open serial plotter" + }, "replaceTitle": "Replace" }, + "core": { + "compilerWarnings": { + "all": "All", + "default": "Default", + "more": "More", + "none": "None" + } + }, "coreContribution": { "copyError": "Copy error messages", "noBoardSelected": "No board selected. Please select your Arduino board from the Tools > Board menu." @@ -282,6 +297,10 @@ "unableToCloseWebSocket": "Unable to close websocket", "unableToConnectToWebSocket": "Unable to connect to websocket" }, + "portProtocol": { + "network": "Network", + "serial": "Serial" + }, "preferences": { "additionalManagerURLs": "Additional Boards Manager URLs", "auth.audience": "The OAuth2 audience.", @@ -321,6 +340,12 @@ "network": "Network", "newSketchbookLocation": "Select new sketchbook location", "noProxy": "No proxy", + "proxySettings": { + "hostname": "Host name", + "password": "Password", + "port": "Port number", + "username": "Username" + }, "showVerbose": "Show verbose output during", "sketchbook.location": "Sketchbook location", "sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", diff --git a/package.json b/package.json index 9800d23e7..92b49adfe 100644 --- a/package.json +++ b/package.json @@ -78,16 +78,21 @@ "vscode-builtin-json": "https://open-vsx.org/api/vscode/json/1.46.1/file/vscode.json-1.46.1.vsix", "vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix", "cortex-debug": "https://open-vsx.org/api/marus25/cortex-debug/0.3.10/file/marus25.cortex-debug-0.3.10.vsix", + "vscode-language-pack-bg": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-bg/1.48.3/file/MS-CEINTL.vscode-language-pack-bg-1.48.3.vsix", + "vscode-language-pack-cs": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-cs/1.53.2/file/MS-CEINTL.vscode-language-pack-cs-1.53.2.vsix", + "vscode-language-pack-de": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-de/1.53.2/file/MS-CEINTL.vscode-language-pack-de-1.53.2.vsix", + "vscode-language-pack-es": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-es/1.53.2/file/MS-CEINTL.vscode-language-pack-es-1.53.2.vsix", + "vscode-language-pack-fr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-fr/1.53.2/file/MS-CEINTL.vscode-language-pack-fr-1.53.2.vsix", + "vscode-language-pack-hu": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-hu/1.48.3/file/MS-CEINTL.vscode-language-pack-hu-1.48.3.vsix", + "vscode-language-pack-it": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-it/1.53.2/file/MS-CEINTL.vscode-language-pack-it-1.53.2.vsix", + "vscode-language-pack-ja": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ja/1.53.2/file/MS-CEINTL.vscode-language-pack-ja-1.53.2.vsix", + "vscode-language-pack-ko": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ko/1.53.2/file/MS-CEINTL.vscode-language-pack-ko-1.53.2.vsix", "vscode-language-pack-nl": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-nl/1.48.3/file/MS-CEINTL.vscode-language-pack-nl-1.48.3.vsix", - "vscode-language-pack-fr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-fr/1.69.0/file/MS-CEINTL.vscode-language-pack-fr-1.69.0.vsix", - "vscode-language-pack-zh-hans": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-zh-hans/1.69.0/file/MS-CEINTL.vscode-language-pack-zh-hans-1.69.0.vsix", - "vscode-language-pack-de": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-de/1.69.0/file/MS-CEINTL.vscode-language-pack-de-1.69.0.vsix", - "vscode-language-pack-ja": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ja/1.69.0/file/MS-CEINTL.vscode-language-pack-ja-1.69.0.vsix", - "vscode-language-pack-tr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-tr/1.69.0/file/MS-CEINTL.vscode-language-pack-tr-1.69.0.vsix", - "vscode-language-pack-it": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-it/1.69.0/file/MS-CEINTL.vscode-language-pack-it-1.69.0.vsix", - "vscode-language-pack-ru": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ru/1.69.0/file/MS-CEINTL.vscode-language-pack-ru-1.69.0.vsix", - "vscode-language-pack-es": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-es/1.69.0/file/MS-CEINTL.vscode-language-pack-es-1.69.0.vsix", - "vscode-language-pack-pt-BR": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-pt-BR/1.69.0/file/MS-CEINTL.vscode-language-pack-pt-BR-1.69.0.vsix", - "vscode-language-pack-cs": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-cs/1.69.0/file/MS-CEINTL.vscode-language-pack-cs-1.69.0.vsix" + "vscode-language-pack-pl": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-pl/1.53.2/file/MS-CEINTL.vscode-language-pack-pl-1.53.2.vsix", + "vscode-language-pack-pt-BR": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-pt-BR/1.53.2/file/MS-CEINTL.vscode-language-pack-pt-BR-1.53.2.vsix", + "vscode-language-pack-ru": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ru/1.53.2/file/MS-CEINTL.vscode-language-pack-ru-1.53.2.vsix", + "vscode-language-pack-tr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-tr/1.53.2/file/MS-CEINTL.vscode-language-pack-tr-1.53.2.vsix", + "vscode-language-pack-uk": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-uk/1.48.3/file/MS-CEINTL.vscode-language-pack-uk-1.48.3.vsix", + "vscode-language-pack-zh-hans": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-zh-hans/1.53.2/file/MS-CEINTL.vscode-language-pack-zh-hans-1.53.2.vsix" } }