diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8d8fb2557..e56db0a40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -317,7 +317,7 @@ jobs: if not exist "${{ matrix.config.working-directory }}" mklink /d "${{ matrix.config.working-directory }}" "C:\actions-runner\_work\arduino-ide\arduino-ide" - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Node.js @@ -441,10 +441,10 @@ jobs: echo "CHANNEL_FILES_PATH=${{ runner.temp }}/channel-files" >> "$GITHUB_ENV" - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download staged-for-merge channel file artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: merge-multiple: true path: ${{ env.CHANNEL_FILES_PATH }} @@ -513,7 +513,7 @@ jobs: steps: - name: Download job transfer artifact that contains ${{ matrix.artifact.name }} tester build - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: name: ${{ env.JOB_TRANSFER_ARTIFACT_PREFIX }}${{ matrix.artifact.job-transfer-artifact-suffix }} path: ${{ env.BUILD_ARTIFACTS_FOLDER }} @@ -533,7 +533,7 @@ jobs: BODY: ${{ steps.changelog.outputs.BODY }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 # To fetch all history for all branches and tags. @@ -600,7 +600,7 @@ jobs: steps: - name: Download all job transfer artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: merge-multiple: true path: ${{ env.ARTIFACTS_FOLDER }} @@ -643,7 +643,7 @@ jobs: steps: - name: Download all job transfer artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: merge-multiple: true path: ${{ env.ARTIFACTS_FOLDER }} diff --git a/.github/workflows/check-containers.yml b/.github/workflows/check-containers.yml index 964867cdd..a3211e99d 100644 --- a/.github/workflows/check-containers.yml +++ b/.github/workflows/check-containers.yml @@ -40,7 +40,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Build and push to local registry uses: docker/build-push-action@v6 diff --git a/.github/workflows/check-i18n-task.yml b/.github/workflows/check-i18n-task.yml index 3064dc602..42f65c196 100644 --- a/.github/workflows/check-i18n-task.yml +++ b/.github/workflows/check-i18n-task.yml @@ -56,7 +56,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Node.js 18.17 uses: actions/setup-node@v4 diff --git a/.github/workflows/check-javascript.yml b/.github/workflows/check-javascript.yml index 26720d48b..5a7ec4a51 100644 --- a/.github/workflows/check-javascript.yml +++ b/.github/workflows/check-javascript.yml @@ -65,7 +65,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/check-yarn.yml b/.github/workflows/check-yarn.yml index 019cfec88..5d3e2702a 100644 --- a/.github/workflows/check-yarn.yml +++ b/.github/workflows/check-yarn.yml @@ -64,7 +64,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/compose-full-changelog.yml b/.github/workflows/compose-full-changelog.yml index 0e669cf8f..8cf2ac214 100644 --- a/.github/workflows/compose-full-changelog.yml +++ b/.github/workflows/compose-full-changelog.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/i18n-nightly-push.yml b/.github/workflows/i18n-nightly-push.yml index 7b3ba2efc..41cc41764 100644 --- a/.github/workflows/i18n-nightly-push.yml +++ b/.github/workflows/i18n-nightly-push.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Node.js 18.17 uses: actions/setup-node@v4 diff --git a/.github/workflows/i18n-weekly-pull.yml b/.github/workflows/i18n-weekly-pull.yml index 6d75556d3..fe5692aa4 100644 --- a/.github/workflows/i18n-weekly-pull.yml +++ b/.github/workflows/i18n-weekly-pull.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Node.js 18.17 uses: actions/setup-node@v4 diff --git a/.github/workflows/push-container-images.yml b/.github/workflows/push-container-images.yml index f6a2c9a5b..03f08ae76 100644 --- a/.github/workflows/push-container-images.yml +++ b/.github/workflows/push-container-images.yml @@ -43,7 +43,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Log in to the Container registry uses: docker/login-action@v3 diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 22fa0d0e9..bcfa7542a 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download JSON schema for labels configuration file id: download-schema @@ -106,10 +106,10 @@ jobs: echo "flag=--dry-run" >> $GITHUB_OUTPUT - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download configuration file artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: merge-multiple: true pattern: ${{ env.CONFIGURATIONS_ARTIFACT_PREFIX }}* diff --git a/.github/workflows/test-javascript.yml b/.github/workflows/test-javascript.yml index a1665f4f5..1a84c33a4 100644 --- a/.github/workflows/test-javascript.yml +++ b/.github/workflows/test-javascript.yml @@ -82,7 +82,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/themes-weekly-pull.yml b/.github/workflows/themes-weekly-pull.yml index 4daa767ba..86816d10e 100644 --- a/.github/workflows/themes-weekly-pull.yml +++ b/.github/workflows/themes-weekly-pull.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Node.js uses: actions/setup-node@v4 diff --git a/README.md b/README.md index a7a88f491..b5825e18f 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,9 @@ See [**the contributor guide**](docs/CONTRIBUTING.md#contributor-guide) for more See the [**development guide**](docs/development.md) for a technical overview of the application and instructions for building the code. -## Donations +### Support the project -This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [donating](https://www.arduino.cc/en/donate/) or [sponsoring](https://github.com/sponsors/arduino) to support our work, as well as [buying original Arduino boards](https://store.arduino.cc/) which is the best way to make sure our effort can continue in the long term. +This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [buying original Arduino boards](https://store.arduino.cc/) to support our work on the project. ## License diff --git a/arduino-ide-extension/package.json b/arduino-ide-extension/package.json index 3d478a88e..ff9a09eff 100644 --- a/arduino-ide-extension/package.json +++ b/arduino-ide-extension/package.json @@ -1,6 +1,6 @@ { "name": "arduino-ide-extension", - "version": "2.3.6", + "version": "2.3.7", "description": "An extension for Theia building the Arduino IDE", "license": "AGPL-3.0-or-later", "scripts": { diff --git a/arduino-ide-extension/src/browser/serial/monitor/monitor-utils.ts b/arduino-ide-extension/src/browser/serial/monitor/monitor-utils.ts index 41cb4f450..eca1756f2 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/monitor-utils.ts +++ b/arduino-ide-extension/src/browser/serial/monitor/monitor-utils.ts @@ -67,3 +67,7 @@ export function truncateLines( } return [lines, charCount]; } + +export function joinLines(lines: Line[]): string { + return lines.map((line: Line) => line.message).join(''); +} \ No newline at end of file diff --git a/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx b/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx index 98bf53625..3697363ef 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx @@ -52,6 +52,9 @@ export namespace SerialMonitor { }, 'vscode/output.contribution/clearOutput.label' ); + export const COPY_OUTPUT = { + id: 'serial-monitor-copy-output', + }; } } @@ -149,6 +152,12 @@ export class MonitorViewContribution 'Clear Output' ), }); + registry.registerItem({ + id: SerialMonitor.Commands.COPY_OUTPUT.id, + command: SerialMonitor.Commands.COPY_OUTPUT.id, + icon: codicon('copy'), + tooltip: nls.localize('arduino/serial/copyOutput', 'Copy Output'), + }); } override registerCommands(commands: CommandRegistry): void { @@ -161,6 +170,15 @@ export class MonitorViewContribution } }, }); + commands.registerCommand(SerialMonitor.Commands.COPY_OUTPUT, { + isEnabled: (widget) => widget instanceof MonitorWidget, + isVisible: (widget) => widget instanceof MonitorWidget, + execute: (widget) => { + if (widget instanceof MonitorWidget) { + widget.copyOutput(); + } + }, + }); if (this.toggleCommand) { commands.registerCommand(this.toggleCommand, { execute: () => this.toggle(), diff --git a/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx b/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx index f5c394603..ee39ec228 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx @@ -28,6 +28,7 @@ import { import { MonitorModel } from '../../monitor-model'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { serialMonitorWidgetLabel } from '../../../common/nls'; +import { ClipboardService } from '@theia/core/lib/browser/clipboard-service'; @injectable() export class MonitorWidget extends ReactWidget { @@ -47,6 +48,7 @@ export class MonitorWidget extends ReactWidget { */ protected closing = false; protected readonly clearOutputEmitter = new Emitter(); + protected readonly copyOutputEmitter = new Emitter(); @inject(MonitorModel) private readonly monitorModel: MonitorModel; @@ -56,6 +58,8 @@ export class MonitorWidget extends ReactWidget { private readonly boardsServiceProvider: BoardsServiceProvider; @inject(FrontendApplicationStateService) private readonly appStateService: FrontendApplicationStateService; + @inject(ClipboardService) + private readonly clipboardService: ClipboardService; private readonly toDisposeOnReset: DisposableCollection; @@ -102,6 +106,10 @@ export class MonitorWidget extends ReactWidget { this.clearOutputEmitter.fire(undefined); this.update(); } + + copyOutput(): void { + this.copyOutputEmitter.fire(); + } override dispose(): void { this.toDisposeOnReset.dispose(); @@ -247,6 +255,8 @@ export class MonitorWidget extends ReactWidget { monitorModel={this.monitorModel} monitorManagerProxy={this.monitorManagerProxy} clearConsoleEvent={this.clearOutputEmitter.event} + copyOutputEvent={this.copyOutputEmitter.event} + clipboardService={this.clipboardService} height={Math.floor(this.widgetHeight - 50)} /> diff --git a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-output.tsx b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-output.tsx index ec2327ad5..f93b24e53 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-output.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-output.tsx @@ -3,9 +3,10 @@ import { Event } from '@theia/core/lib/common/event'; import { DisposableCollection } from '@theia/core/lib/common/disposable'; import { areEqual, FixedSizeList as List } from 'react-window'; import dateFormat from 'dateformat'; -import { messagesToLines, truncateLines } from './monitor-utils'; +import { messagesToLines, truncateLines, joinLines } from './monitor-utils'; import { MonitorManagerProxyClient } from '../../../common/protocol'; import { MonitorModel } from '../../monitor-model'; +import { ClipboardService } from '@theia/core/lib/browser/clipboard-service'; export type Line = { message: string; timestamp?: Date; lineLen: number }; @@ -74,6 +75,9 @@ export class SerialMonitorOutput extends React.Component< this.props.clearConsoleEvent(() => this.setState({ lines: [], charCount: 0 }) ), + this.props.copyOutputEvent(() => + this.props.clipboardService.writeText(joinLines(this.state.lines)) + ), this.props.monitorModel.onChange(({ property }) => { if (property === 'timestamp') { const { timestamp } = this.props.monitorModel; @@ -130,6 +134,8 @@ export namespace SerialMonitorOutput { readonly monitorModel: MonitorModel; readonly monitorManagerProxy: MonitorManagerProxyClient; readonly clearConsoleEvent: Event; + readonly copyOutputEvent: Event; + readonly clipboardService: ClipboardService; readonly height: number; } diff --git a/arduino-ide-extension/src/test/browser/monitor-utils.test.ts b/arduino-ide-extension/src/test/browser/monitor-utils.test.ts index cf1025740..b219ec2ea 100644 --- a/arduino-ide-extension/src/test/browser/monitor-utils.test.ts +++ b/arduino-ide-extension/src/test/browser/monitor-utils.test.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { messagesToLines, truncateLines, + joinLines, } from '../../browser/serial/monitor/monitor-utils'; import { Line } from '../../browser/serial/monitor/serial-monitor-send-output'; import { set, reset } from 'mockdate'; @@ -15,6 +16,7 @@ type TestLine = { charCount: number; maxCharacters?: number; }; + expectedJoined?: string; }; const date = new Date(); @@ -22,6 +24,7 @@ const testLines: TestLine[] = [ { messages: ['Hello'], expected: { lines: [{ message: 'Hello', lineLen: 5 }], charCount: 5 }, + expectedJoined: 'Hello', }, { messages: ['Hello', 'Dog!'], @@ -36,6 +39,7 @@ const testLines: TestLine[] = [ ], charCount: 10, }, + expectedJoined: 'Hello\nDog!' }, { messages: ['Dog!'], @@ -67,6 +71,7 @@ const testLines: TestLine[] = [ { message: "You're a good boy!", lineLen: 8 }, ], }, + expectedJoined: "Hello Dog!\n Who's a good boy?\nYou're a good boy!", }, { messages: ['boy?\n', "You're a good boy!"], @@ -116,6 +121,7 @@ const testLines: TestLine[] = [ { message: 'Yo', lineLen: 2 }, ], }, + expectedJoined: "Hello Dog!\nWho's a good boy?\nYo", }, ]; @@ -165,6 +171,10 @@ describe('Monitor Utils', () => { }); expect(totalCharCount).to.equal(charCount); } + if (testLine.expectedJoined) { + const joined_str = joinLines(testLine.expected.lines); + expect(joined_str).to.equal(testLine.expectedJoined); + } }); }); }); diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index a1ca9e0c8..1221ce9f2 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -6,24 +6,22 @@ Thanks for your interest in contributing to this project! There are several ways you can get involved: -| Type of contribution | Contribution method | -| ----------------------------------------- | -------------------------------------------------------------------------------- | -| - Support
- Question
- Discussion | Post on the [**Arduino Forum**][forum] | -| - Bug report
- Feature request | Issue report (see the guide [**here**][issues]) | -| Testing | Beta testing, PR review (see the guide [**here**][beta-testing]) | -| Translation | See the guide [**here**][translate] | -| - Bug fix
- Enhancement | Pull request (see the guide [**here**][prs]) | -| Monetary | - [Donate][donate]
- [Sponsor][sponsor]
- [Buy official products][store] | +| Type of contribution | Contribution method | +| ----------------------------------------- | ---------------------------------------------------------------- | +| - Support
- Question
- Discussion | Post on the [**Arduino Forum**][forum] | +| - Bug report
- Feature request | Issue report (see the guide [**here**][issues]) | +| Testing | Beta testing, PR review (see the guide [**here**][beta-testing]) | +| Translation | See the guide [**here**][translate] | +| - Bug fix
- Enhancement | Pull request (see the guide [**here**][prs]) | +| Monetary | [Buy official products][store] | [forum]: https://forum.arduino.cc -[issues]: contributor-guide/issues.md#issue-report-guide -[beta-testing]: contributor-guide/beta-testing.md#beta-testing-guide -[translate]: contributor-guide/translation.md#translator-guide -[prs]: contributor-guide/pull-requests.md#pull-request-guide -[donate]: https://www.arduino.cc/en/donate/ -[sponsor]: https://github.com/sponsors/arduino +[issues]: /docs/contributor-guide/issues.md#issue-report-guide +[beta-testing]: /docs/contributor-guide/beta-testing.md#beta-testing-guide +[translate]: /docs/contributor-guide/translation.md#translator-guide +[prs]: /docs/contributor-guide/pull-requests.md#pull-request-guide [store]: https://store.arduino.cc ## Resources -- [**Development Guide**](development.md#development-guide) +- [**Development Guide**](/docs/development.md#development-guide) diff --git a/docs/contributor-guide/translation.md b/docs/contributor-guide/translation.md index 4b8b82400..637b03f66 100644 --- a/docs/contributor-guide/translation.md +++ b/docs/contributor-guide/translation.md @@ -1,13 +1,43 @@ # Translator Guide -The text of the Arduino IDE interface is translated into several languages. The language can be selected in the dialog opened via **File > Preferences** in the Arduino IDE menus (**Arduino IDE > Preferences** for macOS users). +The text of the Arduino IDE user interface is translated into several languages. The language can be selected in the dialog opened via **File > Preferences** in the Arduino IDE menus (**Arduino IDE > Preferences** for macOS users). Translating text and improving on existing translations is a valuable contribution to the project, helping make Arduino accessible to everyone. -The translations for the text found in the Arduino IDE come from several sources: +The translations for the text found in Arduino IDE come from several sources: ## Arduino IDE Text +The text of the Arduino IDE application can be translated to the following languages: + +- čeština (Czech) +- Deutsch (German) +- Dutch +- español (Spanish) +- français (French) +- italiano (Italian) +- magyar (Hungarian) +- polski (Polish) +- português (Portuguese) +- Türkçe (Turkish) +- български (Bulgarian) +- русский (Russian) +- українська (Ukrainian) +- 한국어 (Korean) +- 中文(简体) (Chinese Simplified) +- 中文(繁體) (Chinese Traditional) +- 日本語 (Japanese) + +--- + +⚠ Unfortunately the 3rd party localization framework used by the Arduino IDE application imposes a technical restriction to that set of languages. Unless a language is supported by that framework, it cannot be supported in the Arduino IDE. For this reason, we are currently unable to add support to Arduino IDE for additional languages (see [`arduino/arduino-ide#1447`](https://github.com/arduino/arduino-ide/issues/1447) for details). +If a new language becomes available through the said framework, it will be added to the above list. When that happens, we may consider adding support for that language to Arduino IDE. +Meanwhile we will continue to accept contributions for other languages, but be aware that we cannot say if and when those languages will become available in Arduino IDE. + +There is no technical limitation on the set of languages to which **Arduino CLI** can be translated. If you would like to contribute translations for a language not on the above list, you are welcome to [contribute to the **Arduino CLI** project](#arduino-cli-text). + +--- + Translations of Arduino IDE's text is done in the "**Arduino IDE 2.0**" project on the **Transifex** localization platform: https://explore.transifex.com/arduino-1/ide2/ diff --git a/electron-app/package.json b/electron-app/package.json index 6a31d222a..774fe56bc 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "electron-app", - "version": "2.3.6", + "version": "2.3.7", "license": "AGPL-3.0-or-later", "main": "./src-gen/backend/electron-main.js", "dependencies": { @@ -19,7 +19,7 @@ "@theia/preferences": "1.57.0", "@theia/terminal": "1.57.0", "@theia/workspace": "1.57.0", - "arduino-ide-extension": "2.3.6" + "arduino-ide-extension": "2.3.7" }, "devDependencies": { "@theia/cli": "1.57.0", diff --git a/i18n/en.json b/i18n/en.json index e6dbab0c0..5e3d19be2 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -435,6 +435,7 @@ "autoscroll": "Autoscroll", "carriageReturn": "Carriage Return", "connecting": "Connecting to '{0}' on '{1}'...", + "copyOutput": "Copy Output", "message": "Message (Enter to send message to '{0}' on '{1}')", "newLine": "New Line", "newLineCarriageReturn": "Both NL & CR", diff --git a/package.json b/package.json index f71303a0d..8b5356b49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "arduino-ide", - "version": "2.3.6", + "version": "2.3.7", "description": "Arduino IDE", "repository": "https://github.com/arduino/arduino-ide.git", "author": "Arduino SA",