Finish spanish translation

This commit is contained in:
Alex Spataru 2024-09-23 01:17:27 -05:00
parent 284384fc67
commit 414f06c0c2
33 changed files with 12573 additions and 17415 deletions

View File

@ -55,6 +55,7 @@ find_package(
Bluetooth Bluetooth
Positioning Positioning
PrintSupport PrintSupport
LinguistTools
QuickControls2 QuickControls2
) )
@ -62,7 +63,7 @@ qt_standard_project_setup()
qt_policy(SET QTP0001 NEW) qt_policy(SET QTP0001 NEW)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Import source code & resources # Import source code
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
include_directories(src) include_directories(src)
@ -224,11 +225,17 @@ elseif(UNIX)
endif() endif()
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Generate resources # Add resources
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
qt_add_resources(RES_RCC ${CMAKE_CURRENT_SOURCE_DIR}/rcc/rcc.qrc) qt_add_resources(RES_RCC ${CMAKE_CURRENT_SOURCE_DIR}/rcc/rcc.qrc)
#-------------------------------------------------------------------------------
# Add translations
#-------------------------------------------------------------------------------
qt_add_resources(QM_RCC ${CMAKE_CURRENT_SOURCE_DIR}/translations/translations.qrc)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Create executable # Create executable
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@ -239,6 +246,9 @@ qt_add_executable(
${HEADERS} ${HEADERS}
${QML_RCC} ${QML_RCC}
${RES_RCC} ${RES_RCC}
${QM_RCC}
${QT_RCC_TRANSLATIONS}
${APP_RCC_TRANSLATIONS}
MANUAL_FINALIZATION MANUAL_FINALIZATION
) )

View File

@ -295,7 +295,6 @@ ToolBar {
"qrc:/rcc/icons/toolbar/disconnect.svg" "qrc:/rcc/icons/toolbar/disconnect.svg"
// //
// Connect/disconnect device when button is clicked // Connect/disconnect device when button is clicked
// //

View File

@ -95,8 +95,8 @@
"#ff2d55", "#ff2d55",
"#7a7c80", "#7a7c80",
"#8e8e93", "#8e8e93",
"#61afef", "#b16286",
"#b16286" "#56b6c2"
] ]
} }
} }

View File

@ -244,7 +244,7 @@ void CSV::Player::openFile(const QString &filePath)
"to disconnect from the serial port"), "to disconnect from the serial port"),
qAppName(), QMessageBox::No | QMessageBox::Yes); qAppName(), QMessageBox::No | QMessageBox::Yes);
if (response == QMessageBox::Yes) if (response == QMessageBox::Yes)
IO::Manager::instance().disconnectDriver(); IO::Manager::instance().disconnectDevice();
else else
return; return;
} }

View File

@ -536,6 +536,6 @@ void IO::Drivers::Network::onErrorOccurred(
else else
error = QString::number(socketError); error = QString::number(socketError);
Manager::instance().disconnectDriver(); Manager::instance().disconnectDevice();
Misc::Utilities::showMessageBox(tr("Network socket error"), error); Misc::Utilities::showMessageBox(tr("Network socket error"), error);
} }

View File

@ -746,7 +746,7 @@ void IO::Drivers::Serial::refreshSerialDevices()
void IO::Drivers::Serial::handleError(QSerialPort::SerialPortError error) void IO::Drivers::Serial::handleError(QSerialPort::SerialPortError error)
{ {
if (error != QSerialPort::NoError) if (error != QSerialPort::NoError)
Manager::instance().disconnectDriver(); Manager::instance().disconnectDevice();
} }
/** /**

View File

@ -241,7 +241,7 @@ qint64 IO::Manager::writeData(const QByteArray &data)
void IO::Manager::toggleConnection() void IO::Manager::toggleConnection()
{ {
if (connected()) if (connected())
disconnectDriver(); disconnectDevice();
else else
connectDevice(); connectDevice();
} }
@ -269,7 +269,7 @@ void IO::Manager::connectDevice()
// Error opening the device // Error opening the device
else else
disconnectDriver(); disconnectDevice();
// Update UI // Update UI
Q_EMIT connectedChanged(); Q_EMIT connectedChanged();
@ -279,21 +279,18 @@ void IO::Manager::connectDevice()
/** /**
* Disconnects from the current device and clears temp. data * Disconnects from the current device and clears temp. data
*/ */
void IO::Manager::disconnectDriver() void IO::Manager::disconnectDevice()
{ {
if (deviceAvailable()) if (deviceAvailable())
{ {
// Disconnect device signals/slots // Disconnect device signals/slots
disconnect(driver(), &IO::HAL_Driver::dataReceived, this, disconnect(driver(), &IO::HAL_Driver::dataReceived, this,
&IO::Manager::onDataReceived); &IO::Manager::onDataReceived);
disconnect(driver(), &IO::HAL_Driver::configurationChanged, this,
&IO::Manager::configurationChanged);
// Close driver device // Close driver device
driver()->close(); driver()->close();
// Update device pointer // Reset data buffer
m_driver = Q_NULLPTR;
m_receivedBytes = 0; m_receivedBytes = 0;
m_dataBuffer.clear(); m_dataBuffer.clear();
m_dataBuffer.reserve(maxBufferSize()); m_dataBuffer.reserve(maxBufferSize());
@ -395,14 +392,11 @@ void IO::Manager::setSeparatorSequence(const QString &sequence)
void IO::Manager::setSelectedDriver(const IO::Manager::SelectedDriver &driver) void IO::Manager::setSelectedDriver(const IO::Manager::SelectedDriver &driver)
{ {
// Disconnect current driver // Disconnect current driver
disconnectDriver(); disconnectDevice();
// Change data source // Change data source
m_selectedDriver = driver; m_selectedDriver = driver;
// Disconnect previous device (if any)
disconnectDriver();
// Try to open a serial port connection // Try to open a serial port connection
if (selectedDriver() == SelectedDriver::Serial) if (selectedDriver() == SelectedDriver::Serial)
setDriver(&(Drivers::Serial::instance())); setDriver(&(Drivers::Serial::instance()));
@ -537,7 +531,7 @@ void IO::Manager::onDataReceived(const QByteArray &data)
{ {
// Verify that device is still valid // Verify that device is still valid
if (!driver()) if (!driver())
disconnectDriver(); disconnectDevice();
// Read data & append it to buffer // Read data & append it to buffer
auto bytes = data.length(); auto bytes = data.length();

View File

@ -157,7 +157,7 @@ public:
public slots: public slots:
void connectDevice(); void connectDevice();
void toggleConnection(); void toggleConnection();
void disconnectDriver(); void disconnectDevice();
void setWriteEnabled(const bool enabled); void setWriteEnabled(const bool enabled);
void processPayload(const QByteArray &payload); void processPayload(const QByteArray &payload);
void setMaxBufferSize(const int maxBufferSize); void setMaxBufferSize(const int maxBufferSize);

View File

@ -168,7 +168,7 @@ void Misc::ModuleManager::onQuit()
{ {
CSV::Export::instance().closeFile(); CSV::Export::instance().closeFile();
CSV::Player::instance().closeFile(); CSV::Player::instance().closeFile();
IO::Manager::instance().disconnectDriver(); IO::Manager::instance().disconnectDevice();
Misc::TimerEvents::instance().stopTimers(); Misc::TimerEvents::instance().stopTimers();
Plugins::Server::instance().removeConnection(); Plugins::Server::instance().removeConnection();
} }

View File

@ -167,27 +167,27 @@ void Misc::Translator::setLanguage(const int language)
switch (language) switch (language)
{ {
case 0: case 0:
langName = QStringLiteral("en"); langName = QStringLiteral("en_US");
locale = QLocale(QLocale::English); locale = QLocale(QLocale::English);
break; break;
case 1: case 1:
langName = QStringLiteral("es"); langName = QStringLiteral("es_MX");
locale = QLocale(QLocale::Spanish); locale = QLocale(QLocale::Spanish);
break; break;
case 2: case 2:
langName = QStringLiteral("zh"); langName = QStringLiteral("zh_CN");
locale = QLocale(QLocale::Chinese); locale = QLocale(QLocale::Chinese);
break; break;
case 3: case 3:
langName = QStringLiteral("de"); langName = QStringLiteral("de_DE");
locale = QLocale(QLocale::German); locale = QLocale(QLocale::German);
break; break;
case 4: case 4:
langName = QStringLiteral("ru"); langName = QStringLiteral("ru_RU");
locale = QLocale(QLocale::Russian); locale = QLocale(QLocale::Russian);
break; break;
default: default:
langName = QStringLiteral("en"); langName = QStringLiteral("en_US");
locale = QLocale(QLocale::English); locale = QLocale(QLocale::English);
break; break;
} }
@ -210,7 +210,7 @@ void Misc::Translator::setLanguage(const QLocale &locale,
const QString &language) const QString &language)
{ {
qApp->removeTranslator(&m_translator); qApp->removeTranslator(&m_translator);
const auto qmPath = QStringLiteral(":/rcc/translations/%1.qm").arg(language); const auto qmPath = QStringLiteral(":/qm/%1.qm").arg(language);
if (m_translator.load(locale, qmPath)) if (m_translator.load(locale, qmPath))
{ {
qApp->installTranslator(&m_translator); qApp->installTranslator(&m_translator);

133
app/translations/README.md Normal file
View File

@ -0,0 +1,133 @@
# Translation Manager
`translation_manager.py` is a Python script designed to manage Qt translation files (`.ts` and `.qm`). It can be used to:
1. Create new translation source (`.ts`) files for a given language.
2. Update existing `.ts` files by running `lupdate` and removing obsolete strings.
3. Compile `.ts` files into binary `.qm` files using `lrelease`.
## Prerequisites
Before using this script, ensure the following tools are installed on your system:
- **Qt Linguist**: The `lupdate` and `lrelease` commands are part of the Qt toolchain. Make sure they are available in your system's path.
You can verify the installation by running:
```bash
lupdate --version
lrelease --version
```
Additionally, ensure that you have Python 3.x installed.
## Usage
The script provides three main functionalities:
- **Create a new `.ts` file for a language**
- **Update existing `.ts` files using `lupdate`**
- **Compile `.ts` files into `.qm` files using `lrelease`**
### 1. Creating a New Translation File
To create a new `.ts` file for a language, use the `--new-ts` option followed by the language code (e.g., `es_MX` for Mexican Spanish):
```bash
python3 translation_manager.py --new-ts es_MX
```
This will generate a new `es_MX.ts` file in the `app/translations/ts` folder with the source language set to `en_US`.
### 2. Updating Existing `.ts` Files
To update existing `.ts` files and remove obsolete entries, use the `--lupdate` option:
```bash
python3 translation_manager.py --lupdate
```
This will scan the source files (both `.cpp`, `.h`, and `.qml`) in the `app` and `lib` directories and update the translations in the `.ts` files located in the `app/translations/ts` folder.
### 3. Compiling `.ts` Files into `.qm` Files
To compile the `.ts` files into binary `.qm` files for use in the application, use the `--lrelease` option:
```bash
python3 translation_manager.py --lrelease
```
The `.qm` files will be generated and placed in the `app/translations/qm` folder.
### 4. Running Both `lupdate` and `lrelease`
You can also combine both updating and compiling into a single command:
```bash
python3 translation_manager.py --lupdate --lrelease
```
### 5. Help and Usage Instructions
If no arguments are provided, the script will display the help message:
```bash
python3 translation_manager.py
```
This will output the following information:
```
usage: translation_manager.py [-h] [--new-ts LANGUAGE] [--lupdate] [--lrelease]
Manage translations with lupdate and lrelease.
optional arguments:
-h, --help show this help message and exit
--new-ts LANGUAGE Create a new .ts file for the given language code (e.g., "es" for Spanish).
--lupdate Run lupdate to update all existing .ts files.
--lrelease Run lrelease to compile .ts files into .qm files.
```
## Folder Structure
Heres an example of the folder structure where the script operates:
```
app/
├── translations/
│ ├── ts/ # Folder containing the .ts files (source translations)
│ │ ├── en_US.ts
│ │ ├── es_MX.ts
│ │ └── ru_RU.ts
│ ├── qm/ # Folder where the .qm files (compiled translations) are stored
│ └── translation_manager.py # This script
```
## Example Commands
1. Create a new French translation file (`fr_FR.ts`):
```bash
python3 translation_manager.py --new-ts fr_FR
```
2. Update all existing `.ts` files:
```bash
python3 translation_manager.py --lupdate
```
3. Compile `.ts` files into `.qm`:
```bash
python3 translation_manager.py --lrelease
```
4. Perform both update and compile:
```bash
python3 translation_manager.py --lupdate --lrelease
```
## Notes
- The script assumes that your source language is `en_US`, and this is automatically set when creating new `.ts` files.
- Make sure that the `lib` folder (which contains additional source files) exists at the same level as the `app` folder.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
#
# Copyright (c) 2024 Alex Spataru <https://github.com/alex-spataru>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import os
import subprocess
import argparse
def run_lupdate(ts_dir, app_sources, lib_sources):
"""
Run lupdate to update the .ts files.
"""
ts_files = [os.path.join(ts_dir, file) for file in os.listdir(ts_dir) if file.endswith('.ts')]
if not ts_files:
print(f"No .ts files found in {ts_dir}.")
return
all_sources = app_sources + lib_sources
command = ['lupdate'] + all_sources + ['-ts'] + ts_files
print("Running lupdate command:", ' '.join(command))
try:
subprocess.run(command, check=True)
print("lupdate completed successfully, obsolete entries removed.")
except subprocess.CalledProcessError as e:
print(f"lupdate failed with error code: {e.returncode}")
print(e.output)
def run_lrelease(ts_dir, qm_dir):
"""
Run lrelease to compile the .ts files into .qm files.
"""
ts_files = [os.path.join(ts_dir, file) for file in os.listdir(ts_dir) if file.endswith('.ts')]
if not ts_files:
print(f"No .ts files found in {ts_dir}.")
return
if not os.path.exists(qm_dir):
os.makedirs(qm_dir)
for ts_file in ts_files:
qm_file = os.path.join(qm_dir, os.path.splitext(os.path.basename(ts_file))[0] + '.qm')
command = ['lrelease', ts_file, '-qm', qm_file]
print("Running lrelease command:", ' '.join(command))
try:
subprocess.run(command, check=True)
print(f"lrelease completed successfully, created {qm_file}")
except subprocess.CalledProcessError as e:
print(f"lrelease failed with error code: {e.returncode}")
print(e.output)
def create_ts(language, ts_dir, app_sources, lib_sources):
"""
Create a new .ts file for the given language code.
"""
new_ts_file = os.path.join(ts_dir, f"{language}.ts")
if os.path.exists(new_ts_file):
print(f"The .ts file for language '{language}' already exists.")
return
print(f"Creating new .ts file: {new_ts_file}")
all_sources = app_sources + lib_sources
command = ['lupdate', '-source-language', 'en_US', '-target-language', language] + all_sources + ['-ts', new_ts_file]
try:
subprocess.run(command, check=True)
print(f"New .ts file {new_ts_file} created successfully.")
except subprocess.CalledProcessError as e:
print(f"lupdate failed with error code: {e.returncode}")
print(e.output)
def collect_sources(app_dir, lib_dir):
"""
Collect all relevant .cpp, .h, and .qml files from app and lib directories.
"""
app_sources = []
for root, _, files in os.walk(app_dir):
for file in files:
if file.endswith(('.cpp', '.h', '.qml')):
app_sources.append(os.path.join(root, file))
lib_sources = []
if os.path.exists(lib_dir):
for root, _, files in os.walk(lib_dir):
for file in files:
if file.endswith(('.cpp', '.h')):
lib_sources.append(os.path.join(root, file))
return app_sources, lib_sources
if __name__ == "__main__":
# Set up argument parser
parser = argparse.ArgumentParser(description="Manage translations with lupdate and lrelease.")
parser.add_argument('--new-ts', metavar='LANGUAGE', help='Create a new .ts file for the given language code (e.g., "es" for Spanish).')
parser.add_argument('--lupdate', action='store_true', help='Run lupdate to update all existing .ts files.')
parser.add_argument('--lrelease', action='store_true', help='Run lrelease to compile .ts files into .qm files.')
args = parser.parse_args()
if not any(vars(args).values()):
# If no arguments are passed, print the help message
parser.print_help()
exit(0)
# Define paths
translations_dir = os.path.dirname(os.path.abspath(__file__))
app_dir = os.path.dirname(os.path.dirname(translations_dir))
lib_dir = os.path.join(os.path.dirname(app_dir), 'lib')
ts_dir = os.path.join(translations_dir, 'ts')
qm_dir = os.path.join(translations_dir, 'qm')
# Ensure the translations/ts directory exists
if not os.path.exists(ts_dir):
print(f"Error: {ts_dir} directory does not exist.")
exit(1)
# Collect source files from app and lib directories
app_sources, lib_sources = collect_sources(app_dir, lib_dir)
# Handle --new-ts option
if args.new_ts:
create_ts(args.new_ts, ts_dir, app_sources, lib_sources)
# Handle --lupdate option
if args.lupdate:
run_lupdate(ts_dir, app_sources, lib_sources)
# Handle --lrelease option
if args.lrelease:
run_lrelease(ts_dir, qm_dir)

View File

@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/">
<file>qm/de_DE.qm</file>
<file>qm/en_US.qm</file>
<file>qm/es_MX.qm</file>
<file>qm/ru_RU.qm</file>
<file>qm/zh_CN.qm</file>
</qresource>
</RCC>

2448
app/translations/ts/de_DE.ts Normal file

File diff suppressed because it is too large Load Diff

2448
app/translations/ts/en_US.ts Normal file

File diff suppressed because it is too large Load Diff

2449
app/translations/ts/es_MX.ts Normal file

File diff suppressed because it is too large Load Diff

2448
app/translations/ts/ru_RU.ts Normal file

File diff suppressed because it is too large Load Diff

2448
app/translations/ts/zh_CN.ts Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff