Add translator engine & spanish translations

This commit is contained in:
Alex Spataru 2021-01-01 17:25:52 -05:00
parent 023eba98ac
commit d27cd4bc2d
12 changed files with 1215 additions and 4 deletions

View File

@ -126,6 +126,7 @@ HEADERS += \
src/ModuleManager.h \ src/ModuleManager.h \
src/QmlBridge.h \ src/QmlBridge.h \
src/SerialManager.h \ src/SerialManager.h \
src/Translator.h \
src/Widgets.h src/Widgets.h
SOURCES += \ SOURCES += \
@ -138,6 +139,7 @@ SOURCES += \
src/ModuleManager.cpp \ src/ModuleManager.cpp \
src/QmlBridge.cpp \ src/QmlBridge.cpp \
src/SerialManager.cpp \ src/SerialManager.cpp \
src/Translator.cpp \
src/Widgets.cpp \ src/Widgets.cpp \
src/main.cpp src/main.cpp
@ -145,3 +147,7 @@ DISTFILES += \
assets/qml/Widgets/*.qml \ assets/qml/Widgets/*.qml \
assets/qml/Windows/*.qml \ assets/qml/Windows/*.qml \
assets/qml/*.qml assets/qml/*.qml
TRANSLATIONS += \
assets/translations/en.ts \
assets/translations/es.ts

View File

@ -61,5 +61,8 @@
<file>qml/Windows/Widgets.qml</file> <file>qml/Windows/Widgets.qml</file>
<file>qml/main.qml</file> <file>qml/main.qml</file>
<file>qml/Widgets/ArtificialHorizonDelegate.qml</file> <file>qml/Widgets/ArtificialHorizonDelegate.qml</file>
<file>translations/en.qm</file>
<file>translations/es.qm</file>
<file>messages/Welcome_ES.txt</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,28 @@
________ _____ ______ ____________ _____________
__ ___/______________(_)_____ ___ / __ ___/_ /____ _______ /__(_)_____
_____ \_ _ \_ ___/_ /_ __ `/_ / _____ \_ __/ / / / __ /__ /_ __ \
____/ // __/ / _ / / /_/ /_ / ____/ // /_ / /_/ // /_/ / _ / / /_/ /
/____/ \___//_/ /_/ \__,_/ /_/ /____/ \__/ \__,_/ \__,_/ /_/ \____/
¡Bienvenido a Serial Studio! Para comenzar, seleccione un puerto COM y velocidad
en baudios en el panel de dispositivos a la derecha. Si la conexión en serie es
exitosa y los datos entrantes se interpretan correctamente, este panel se
cerrará automáticamente y el el tablero de instrumentos se mostrará
automáticamente. De lo contrario, puede usar la consola para encontrar el origen
de su problema.
Utilice los botones de la barra de herramientas para mostrar las funciones que
desea utilizar. Si encuentra un problema con Serial Studio, infórmelo en:
https://github.com/Serial-Studio/Serial-Studio/issues
También puede utilizar los enlaces de la ventana "Acerca de". Para obtener
documentación sobre uso de Serial Studio e integración con sus proyectos
actuales, por favor lea la wiki:
https://github.com/Serial-Studio/Serial-Studio/wiki
¡Que te diviertas!
Alex Spataru (https://github.com/alex-spataru)

View File

@ -25,7 +25,16 @@ import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
ApplicationWindow { ApplicationWindow {
id: window id: root
//
// Custom properties
//
readonly property int year: new Date().getFullYear()
//
// Window options
//
flags: Qt.Dialog flags: Qt.Dialog
minimumWidth: 320 minimumWidth: 320
maximumWidth: 320 maximumWidth: 320
@ -87,7 +96,7 @@ ApplicationWindow {
opacity: 0.8 opacity: 0.8
Layout.fillWidth: true Layout.fillWidth: true
wrapMode: Label.WrapAtWordBoundaryOrAnywhere wrapMode: Label.WrapAtWordBoundaryOrAnywhere
text: qsTr("Copyright © 2020 %1, released under the MIT License.").arg(CppAppOrganization) text: qsTr("Copyright © 2020-%1 %2, released under the MIT License.").arg(root.year).arg(CppAppOrganization)
} }
Label { Label {
@ -137,7 +146,7 @@ ApplicationWindow {
Button { Button {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Close") text: qsTr("Close")
onClicked: window.close() onClicked: root.close()
} }
Item { Item {

View File

@ -121,7 +121,7 @@ Control {
onClicked: root.dataClicked() onClicked: root.dataClicked()
enabled: CppQmlBridge.groupCount > 0 enabled: CppQmlBridge.groupCount > 0
icon.source: "qrc:/icons/equalizer.svg" icon.source: "qrc:/icons/equalizer.svg"
text: qsTr("Data Display") + _btSpacer text: qsTr("Dashboard") + _btSpacer
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
Behavior on opacity {NumberAnimation{}} Behavior on opacity {NumberAnimation{}}

BIN
assets/translations/en.qm Normal file

Binary file not shown.

478
assets/translations/en.ts Normal file
View File

@ -0,0 +1,478 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en" sourcelanguage="en">
<context>
<name>About</name>
<message>
<source>About</source>
<translation></translation>
</message>
<message>
<source>Version %1</source>
<translation></translation>
</message>
<message>
<source>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</source>
<translation></translation>
</message>
<message>
<source>Contact author</source>
<translation></translation>
</message>
<message>
<source>Report bug</source>
<translation></translation>
</message>
<message>
<source>Check for updates</source>
<translation></translation>
</message>
<message>
<source>Documentation</source>
<translation></translation>
</message>
<message>
<source>Close</source>
<translation></translation>
</message>
<message>
<source>Copyright © 2020-%1 %2, released under the MIT License.</source>
<translation></translation>
</message>
</context>
<context>
<name>AccelerometerDelegate</name>
<message>
<source>G Units</source>
<translation></translation>
</message>
<message>
<source>%1 G MAX</source>
<translation></translation>
</message>
<message>
<source>%1 G MIN</source>
<translation></translation>
</message>
<message>
<source>%1 G ACT</source>
<translation></translation>
</message>
<message>
<source>Reset</source>
<translation></translation>
</message>
</context>
<context>
<name>Console</name>
<message>
<source>No data received so far...</source>
<translation></translation>
</message>
<message>
<source>Autoscroll</source>
<translation></translation>
</message>
<message>
<source>Send data to device</source>
<translation></translation>
</message>
</context>
<context>
<name>DataGrid</name>
<message>
<source>View</source>
<translation></translation>
</message>
<message>
<source>Horizontal Range</source>
<translation></translation>
</message>
<message>
<source>Data Groups</source>
<translation></translation>
</message>
<message>
<source>Data Plots</source>
<translation></translation>
</message>
<message>
<source>Data</source>
<translation></translation>
</message>
</context>
<context>
<name>DeviceManager</name>
<message>
<source>Communication Mode</source>
<translation></translation>
</message>
<message>
<source>Auto (JSON from serial device)</source>
<translation></translation>
</message>
<message>
<source>Manual (use JSON map file)</source>
<translation></translation>
</message>
<message>
<source>Change map file (%1)</source>
<translation></translation>
</message>
<message>
<source>Select map file</source>
<translation></translation>
</message>
<message>
<source>COM Port</source>
<translation></translation>
</message>
<message>
<source>Baud Rate</source>
<translation></translation>
</message>
<message>
<source>Data Bits</source>
<translation></translation>
</message>
<message>
<source>Parity</source>
<translation></translation>
</message>
<message>
<source>Stop Bits</source>
<translation></translation>
</message>
<message>
<source>Flow Control</source>
<translation></translation>
</message>
</context>
<context>
<name>Downloader</name>
<message>
<source>Updater</source>
<translation></translation>
</message>
<message>
<source>Downloading updates</source>
<translation></translation>
</message>
<message>
<source>Time remaining: 0 minutes</source>
<translation></translation>
</message>
<message>
<source>Open</source>
<translation></translation>
</message>
<message>
<source>Stop</source>
<translation></translation>
</message>
<message>
<source>Time remaining</source>
<translation></translation>
</message>
<message>
<source>unknown</source>
<translation></translation>
</message>
<message>
<source>Error</source>
<translation></translation>
</message>
<message>
<source>Cannot find downloaded update!</source>
<translation></translation>
</message>
<message>
<source>Close</source>
<translation></translation>
</message>
<message>
<source>Download complete!</source>
<translation></translation>
</message>
<message>
<source>The installer will open separately</source>
<translation></translation>
</message>
<message>
<source>Click &quot;OK&quot; to begin installing the update</source>
<translation></translation>
</message>
<message>
<source>In order to install the update, you may need to quit the application.</source>
<translation></translation>
</message>
<message>
<source>In order to install the update, you may need to quit the application. This is a mandatory update, exiting now will close the application</source>
<translation></translation>
</message>
<message>
<source>Click the &quot;Open&quot; button to apply the update</source>
<translation></translation>
</message>
<message>
<source>Are you sure you want to cancel the download?</source>
<translation></translation>
</message>
<message>
<source>Are you sure you want to cancel the download? This is a mandatory update, exiting now will close the application</source>
<translation></translation>
</message>
<message>
<source>%1 bytes</source>
<translation></translation>
</message>
<message>
<source>%1 KB</source>
<translation></translation>
</message>
<message>
<source>%1 MB</source>
<translation></translation>
</message>
<message>
<source>of</source>
<translation></translation>
</message>
<message>
<source>Downloading Updates</source>
<translation></translation>
</message>
<message>
<source>Time Remaining</source>
<translation></translation>
</message>
<message>
<source>Unknown</source>
<translation></translation>
</message>
<message>
<source>about %1 hours</source>
<translation></translation>
</message>
<message>
<source>about one hour</source>
<translation></translation>
</message>
<message>
<source>%1 minutes</source>
<translation></translation>
</message>
<message>
<source>1 minute</source>
<translation></translation>
</message>
<message>
<source>%1 seconds</source>
<translation></translation>
</message>
<message>
<source>1 second</source>
<translation></translation>
</message>
</context>
<context>
<name>Export</name>
<message>
<source>CSV file not open</source>
<translation></translation>
</message>
<message>
<source>Cannot find CSV export file!</source>
<translation></translation>
</message>
<message>
<source>CSV File Error</source>
<translation></translation>
</message>
<message>
<source>Cannot open CSV file for writing!</source>
<translation></translation>
</message>
</context>
<context>
<name>Group</name>
<message>
<source>Invalid</source>
<translation></translation>
</message>
</context>
<context>
<name>GyroDelegate</name>
<message>
<source>%1° YAW</source>
<translation></translation>
</message>
<message>
<source>%1° ROLL</source>
<translation></translation>
</message>
<message>
<source>%1° PITCH</source>
<translation></translation>
</message>
</context>
<context>
<name>JsonParser</name>
<message>
<source>Select JSON map file</source>
<translation></translation>
</message>
<message>
<source>JSON files (*.json)</source>
<translation></translation>
</message>
<message>
<source>JSON parse error</source>
<translation></translation>
</message>
<message>
<source>JSON map file loaded successfully!</source>
<translation></translation>
</message>
<message>
<source>File &quot;%1&quot; loaded into memory</source>
<translation></translation>
</message>
<message>
<source>Cannot read JSON file</source>
<translation></translation>
</message>
<message>
<source>Please check file permissions &amp; location</source>
<translation></translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<source>Failed to load welcome text :(</source>
<translation></translation>
</message>
<message>
<source>:/messages/Welcome_EN.txt</source>
<translation></translation>
</message>
</context>
<context>
<name>SerialManager</name>
<message>
<source>No Parity</source>
<translation></translation>
</message>
<message>
<source>One</source>
<translation></translation>
</message>
<message>
<source>No Flow Control</source>
<translation></translation>
</message>
<message>
<source>No Device</source>
<translation></translation>
</message>
<message>
<source>Received: %1 %2</source>
<translation></translation>
</message>
<message>
<source>Even Parity</source>
<translation></translation>
</message>
<message>
<source>Odd Parity</source>
<translation></translation>
</message>
<message>
<source>Space Parity</source>
<translation></translation>
</message>
<message>
<source>Mark Parity</source>
<translation></translation>
</message>
<message>
<source>One and Half</source>
<translation></translation>
</message>
<message>
<source>Two</source>
<translation></translation>
</message>
<message>
<source>Hardware Control</source>
<translation></translation>
</message>
<message>
<source>Software Control</source>
<translation></translation>
</message>
<message>
<source>Select Port</source>
<translation></translation>
</message>
</context>
<context>
<name>Toolbar</name>
<message>
<source>Devices</source>
<translation></translation>
</message>
<message>
<source>Console</source>
<translation></translation>
</message>
<message>
<source>Widgets</source>
<translation></translation>
</message>
<message>
<source>About</source>
<translation></translation>
</message>
<message>
<source>CSV Export</source>
<translation></translation>
</message>
<message>
<source>Open past CSV</source>
<translation></translation>
</message>
<message>
<source>Open current CSV</source>
<translation></translation>
</message>
<message>
<source>Dashboard</source>
<translation></translation>
</message>
</context>
<context>
<name>Updater</name>
<message>
<source>Would you like to download the update now?</source>
<translation></translation>
</message>
<message>
<source>Would you like to download the update now? This is a mandatory update, exiting now will close the application</source>
<translation></translation>
</message>
<message>
<source>Version %1 of %2 has been released!</source>
<translation></translation>
</message>
<message>
<source>No updates are available for the moment</source>
<translation></translation>
</message>
<message>
<source>Congratulations! You are running the latest version of %1</source>
<translation></translation>
</message>
</context>
</TS>

BIN
assets/translations/es.qm Normal file

Binary file not shown.

486
assets/translations/es.ts Normal file
View File

@ -0,0 +1,486 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="es" sourcelanguage="en">
<context>
<name>About</name>
<message>
<source>About</source>
<translation>Acerca de</translation>
</message>
<message>
<source>Version %1</source>
<translation>Versión %1</translation>
</message>
<message>
<source>Copyright © 2020 %1, released under the MIT License.</source>
<translation type="vanished">Copyright © 2020 %1, distribuido bajo la licencia MIT.</translation>
</message>
<message>
<source>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</source>
<translation>El programa se proporciona TAL CUAL, SIN GARANTÍA DE NINGÚN TIPO, INCLUIDA LA GARANTÍA DE DISEÑO, COMERCIABILIDAD Y APTITUD PARA UN PROPÓSITO EN PARTICULAR.</translation>
</message>
<message>
<source>Contact author</source>
<translation>Contactar al autor</translation>
</message>
<message>
<source>Report bug</source>
<translation>Reportar un error</translation>
</message>
<message>
<source>Check for updates</source>
<translation>Buscar actualizaciones</translation>
</message>
<message>
<source>Documentation</source>
<translation>Documentación</translation>
</message>
<message>
<source>Close</source>
<translation>Cerrar</translation>
</message>
<message>
<source>Copyright © 2020-%1 %2, released under the MIT License.</source>
<translation>Copyright © 2020-%1 %2, distribuido bajo la licencia MIT.</translation>
</message>
</context>
<context>
<name>AccelerometerDelegate</name>
<message>
<source>G Units</source>
<translation>Unidades G</translation>
</message>
<message>
<source>%1 G MAX</source>
<translation>%1 G MAX</translation>
</message>
<message>
<source>%1 G MIN</source>
<translation>%1 G MIN</translation>
</message>
<message>
<source>%1 G ACT</source>
<translation>%1 G ACT</translation>
</message>
<message>
<source>Reset</source>
<translation>Reajustar</translation>
</message>
</context>
<context>
<name>Console</name>
<message>
<source>No data received so far...</source>
<translation>No se han recibido datos hasta ahora ...</translation>
</message>
<message>
<source>Autoscroll</source>
<translation>Desplazamiento automático</translation>
</message>
<message>
<source>Send data to device</source>
<translation>Enviar datos al dispositivo</translation>
</message>
</context>
<context>
<name>DataGrid</name>
<message>
<source>View</source>
<translation>Vista</translation>
</message>
<message>
<source>Horizontal Range</source>
<translation>Rango Horizontal</translation>
</message>
<message>
<source>Data Groups</source>
<translation>Grupos de Datos</translation>
</message>
<message>
<source>Data Plots</source>
<translation>Gráficos de Datos</translation>
</message>
<message>
<source>Data</source>
<translation>Datos</translation>
</message>
</context>
<context>
<name>DeviceManager</name>
<message>
<source>Communication Mode</source>
<translation>Modo de comunicación</translation>
</message>
<message>
<source>Auto (JSON from serial device)</source>
<translation>Automático (JSON desde puerto serial)</translation>
</message>
<message>
<source>Manual (use JSON map file)</source>
<translation>Manual (usar archivo de mapa JSON)</translation>
</message>
<message>
<source>Change map file (%1)</source>
<translation>Cambiar archivo (%1)</translation>
</message>
<message>
<source>Select map file</source>
<translation>Seleccionar archivo de mapa</translation>
</message>
<message>
<source>COM Port</source>
<translation>Puerto COM</translation>
</message>
<message>
<source>Baud Rate</source>
<translation>Baudios</translation>
</message>
<message>
<source>Data Bits</source>
<translation>Bits de datos</translation>
</message>
<message>
<source>Parity</source>
<translation>Paridad</translation>
</message>
<message>
<source>Stop Bits</source>
<translation>Bits de parada</translation>
</message>
<message>
<source>Flow Control</source>
<translation>Control de flujo</translation>
</message>
</context>
<context>
<name>Downloader</name>
<message>
<source>Updater</source>
<translation>Actualizador</translation>
</message>
<message>
<source>Downloading updates</source>
<translation>Descargando actualizaciones</translation>
</message>
<message>
<source>Time remaining: 0 minutes</source>
<translation>Tiempo restante: 0 minutos</translation>
</message>
<message>
<source>Open</source>
<translation>Abrir</translation>
</message>
<message>
<source>Stop</source>
<translation>Cancelar</translation>
</message>
<message>
<source>Time remaining</source>
<translation>Tiempo restante</translation>
</message>
<message>
<source>unknown</source>
<translation>desconocido</translation>
</message>
<message>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
<source>Cannot find downloaded update!</source>
<translation>No se puede encontrar el archivo descargado!</translation>
</message>
<message>
<source>Close</source>
<translation>Cerrar</translation>
</message>
<message>
<source>Download complete!</source>
<translation>Descarga completa!</translation>
</message>
<message>
<source>The installer will open separately</source>
<translation>El instalador se abrirá por separado</translation>
</message>
<message>
<source>Click &quot;OK&quot; to begin installing the update</source>
<translation>Haga clic en &quot;Aceptar&quot; para comenzar a instalar la actualización</translation>
</message>
<message>
<source>In order to install the update, you may need to quit the application.</source>
<translation>Para instalar la actualización, es posible que deba salir de la aplicación.</translation>
</message>
<message>
<source>In order to install the update, you may need to quit the application. This is a mandatory update, exiting now will close the application</source>
<translation>Para instalar la actualización, es posible que deba salir de la aplicación. Esta es una actualización obligatoria, salir ahora cerrará la aplicación</translation>
</message>
<message>
<source>Click the &quot;Open&quot; button to apply the update</source>
<translation>Haga clic en el botón &quot;Abrir&quot; para instalar la actualización</translation>
</message>
<message>
<source>Are you sure you want to cancel the download?</source>
<translation>¿Estás seguro/a de que deseas cancelar la descarga?</translation>
</message>
<message>
<source>Are you sure you want to cancel the download? This is a mandatory update, exiting now will close the application</source>
<translation>¿Estás seguro/a de que deseas cancelar la descarga? Esta es una actualización obligatoria, salir ahora cerrará la aplicación</translation>
</message>
<message>
<source>%1 bytes</source>
<translation></translation>
</message>
<message>
<source>%1 KB</source>
<translation></translation>
</message>
<message>
<source>%1 MB</source>
<translation></translation>
</message>
<message>
<source>of</source>
<translation>de</translation>
</message>
<message>
<source>Downloading Updates</source>
<translation>Descargando actualizaciones</translation>
</message>
<message>
<source>Time Remaining</source>
<translation>Tiempo restante</translation>
</message>
<message>
<source>Unknown</source>
<translation>Desconocido</translation>
</message>
<message>
<source>about %1 hours</source>
<translation>alrededor de %1 horas</translation>
</message>
<message>
<source>about one hour</source>
<translation>alrededor de una hora</translation>
</message>
<message>
<source>%1 minutes</source>
<translation>%1 minutos</translation>
</message>
<message>
<source>1 minute</source>
<translation>1 minuto</translation>
</message>
<message>
<source>%1 seconds</source>
<translation>%1 segundos</translation>
</message>
<message>
<source>1 second</source>
<translation>1 segundo</translation>
</message>
</context>
<context>
<name>Export</name>
<message>
<source>CSV file not open</source>
<translation>Archivo CSV no abierto</translation>
</message>
<message>
<source>Cannot find CSV export file!</source>
<translation>¡No se puede encontrar el archivo de exportación CSV!</translation>
</message>
<message>
<source>CSV File Error</source>
<translation>Error de archivo CSV</translation>
</message>
<message>
<source>Cannot open CSV file for writing!</source>
<translation>¡No se puede abrir el archivo CSV en modo de escritura!</translation>
</message>
</context>
<context>
<name>Group</name>
<message>
<source>Invalid</source>
<translation>Inválido</translation>
</message>
</context>
<context>
<name>GyroDelegate</name>
<message>
<source>%1° YAW</source>
<translation></translation>
</message>
<message>
<source>%1° ROLL</source>
<translation></translation>
</message>
<message>
<source>%1° PITCH</source>
<translation></translation>
</message>
</context>
<context>
<name>JsonParser</name>
<message>
<source>Select JSON map file</source>
<translation>Seleccionar mapa JSON</translation>
</message>
<message>
<source>JSON files (*.json)</source>
<translation>Archivos JSON (*.json)</translation>
</message>
<message>
<source>JSON parse error</source>
<translation>Error de lectura de JSON</translation>
</message>
<message>
<source>JSON map file loaded successfully!</source>
<translation>¡El archivo de mapa JSON se cargó correctamente!</translation>
</message>
<message>
<source>File &quot;%1&quot; loaded into memory</source>
<translation>Archivo &quot;%1&quot; cargado en memoria</translation>
</message>
<message>
<source>Cannot read JSON file</source>
<translation>Error de lectura del archivo JSON</translation>
</message>
<message>
<source>Please check file permissions &amp; location</source>
<translation>Verifique los permisos y la ubicación del archivo</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<source>Failed to load welcome text :(</source>
<translation>Error al cargar el texto de bienvenida :(</translation>
</message>
<message>
<source>:/messages/Welcome_EN.txt</source>
<translation>:/messages/Welcome_ES.txt</translation>
</message>
</context>
<context>
<name>SerialManager</name>
<message>
<source>No Parity</source>
<translation>Sin Paridad</translation>
</message>
<message>
<source>One</source>
<translation>Uno</translation>
</message>
<message>
<source>No Flow Control</source>
<translation>Sin control de flujo</translation>
</message>
<message>
<source>No Device</source>
<translation>Sin Dispositivo</translation>
</message>
<message>
<source>Received: %1 %2</source>
<translation>Recibido: %1 %2</translation>
</message>
<message>
<source>Even Parity</source>
<translation>Par</translation>
</message>
<message>
<source>Odd Parity</source>
<translation>Inpar</translation>
</message>
<message>
<source>Space Parity</source>
<translation>Espacio</translation>
</message>
<message>
<source>Mark Parity</source>
<translation>Marca</translation>
</message>
<message>
<source>One and Half</source>
<translation>Uno y Medio</translation>
</message>
<message>
<source>Two</source>
<translation>Dos</translation>
</message>
<message>
<source>Hardware Control</source>
<translation>Controlado por hardware</translation>
</message>
<message>
<source>Software Control</source>
<translation>Controlado por software</translation>
</message>
<message>
<source>Select Port</source>
<translation>Seleccionar Puerto</translation>
</message>
</context>
<context>
<name>Toolbar</name>
<message>
<source>Devices</source>
<translation>Dispositivos</translation>
</message>
<message>
<source>Console</source>
<translation>Consola</translation>
</message>
<message>
<source>Data Display</source>
<translation type="vanished">Visualización de Datos</translation>
</message>
<message>
<source>Widgets</source>
<translation>Widgets</translation>
</message>
<message>
<source>About</source>
<translation>Acerca de</translation>
</message>
<message>
<source>CSV Export</source>
<translation>Exportación CSV</translation>
</message>
<message>
<source>Open past CSV</source>
<translation>Abrir CSV pasado</translation>
</message>
<message>
<source>Open current CSV</source>
<translation>Abrir CSV actual</translation>
</message>
<message>
<source>Dashboard</source>
<translation>Tablero</translation>
</message>
</context>
<context>
<name>Updater</name>
<message>
<source>Would you like to download the update now?</source>
<translation>¿Le gustaría descargar la actualización ahora?</translation>
</message>
<message>
<source>Would you like to download the update now? This is a mandatory update, exiting now will close the application</source>
<translation>¿Le gustaría descargar la actualización ahora? Esta es una actualización obligatoria, salir ahora cerrará la aplicación</translation>
</message>
<message>
<source>Version %1 of %2 has been released!</source>
<translation>¡Se ha lanzado la versión %1 de %2!</translation>
</message>
<message>
<source>No updates are available for the moment</source>
<translation>No hay actualizaciones disponibles por el momento</translation>
</message>
<message>
<source>Congratulations! You are running the latest version of %1</source>
<translation>¡Felicidades! Estás ejecutando la última versión de %1</translation>
</message>
</context>
</TS>

131
src/Translator.cpp Normal file
View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2020 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.
*/
#include "Translator.h"
/**
* Constructor function
*/
Translator::Translator()
{
m_language = 0;
}
/**
* Returns the current language ID, which corresponds to the indexes of the languages returned
* by the \c availableLanguages() function.
*/
int Translator::language() const
{
return m_language;
}
/**
* Returns the appropiate language ID based on the current locale settings of the host's operating
* system.
*/
int Translator::systemLanguage() const
{
int lang;
switch (QLocale::system().language())
{
case QLocale::English:
lang = 0;
break;
case QLocale::Spanish:
lang = 1;
break;
default:
lang = 0;
break;
}
return lang;
}
/**
* Returns an empty string, this function should be used with QML to automatically update
* all the strings without the need of restarting the application. For example, the following
* QML code:
*
* text: qsTr("Text") + CppTranslator.dummyString
*
* Will force the QML interface to update the value of @a text when the language is changed.
*/
QString Translator::dummyString() const
{
return "";
}
/**
* Returns a list with the available translation languages.
*/
QStringList Translator::availableLanguages() const
{
return QStringList { "English", "Español" };
}
/**
* Changes the language of the application and emits the signals appropiate to reload every
* string that uses the Qt translator system.
*
* @param language language ID based on the indexes of the \a availableLanguages() function
*/
void Translator::setLanguage(const int language)
{
QString langName;
QLocale locale;
switch (language)
{
case 0:
langName = "en";
locale = QLocale(QLocale::English);
break;
case 1:
langName = "es";
locale = QLocale(QLocale::Spanish);
break;
default:
langName = "en";
locale = QLocale(QLocale::English);
break;
}
m_language = language;
setLanguage(locale, langName);
}
/**
* Changes the language of the application and emits the signals neccesary to reload every
* string that uses the Qt translator system.
*
* @param locale user-set locale
* @param language name of the *.qm file to load from the "translations" directory inside the
* application's resources
*/
void Translator::setLanguage(const QLocale &locale, const QString &language)
{
qApp->removeTranslator(&m_translator);
m_translator.load(locale, ":/translations/" + language + ".qm");
qApp->installTranslator(&m_translator);
emit languageChanged();
}

64
src/Translator.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2020 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.
*/
#ifndef TRANSLATOR_H
#define TRANSLATOR_H
#include <QLocale>
#include <QObject>
#include <QTranslator>
#ifdef QT_QML_LIB
# include <QtQml>
#endif
class Translator : public QObject
{
Q_OBJECT
#ifdef QT_QML_LIB
Q_PROPERTY(int language READ language WRITE setLanguage NOTIFY languageChanged)
Q_PROPERTY(QString dummy READ dummyString NOTIFY languageChanged)
Q_PROPERTY(QStringList availableLanguages READ availableLanguages CONSTANT)
#endif
signals:
void languageChanged();
public:
explicit Translator();
int language() const;
int systemLanguage() const;
QString dummyString() const;
QStringList availableLanguages() const;
public slots:
void setLanguage(const int language);
void setLanguage(const QLocale &locale, const QString &language);
private:
int m_language;
QTranslator m_translator;
};
#endif

View File

@ -40,6 +40,7 @@
#include "GraphProvider.h" #include "GraphProvider.h"
#include "SerialManager.h" #include "SerialManager.h"
#include "Translator.h"
#include "ModuleManager.h" #include "ModuleManager.h"
/** /**
@ -93,6 +94,11 @@ int main(int argc, char **argv)
qmlRegisterType<Group>("Group", 1, 0, "Group"); qmlRegisterType<Group>("Group", 1, 0, "Group");
qmlRegisterType<Dataset>("Dataset", 1, 0, "Dataset"); qmlRegisterType<Dataset>("Dataset", 1, 0, "Dataset");
// Start translator & set lenguage
Translator translator;
// QLocale locale(QLocale::Spanish, QLocale::Mexico);
// translator.setLanguage(locale, "es");
// Get console welcome text string // Get console welcome text string
QString welcomeText = QObject::tr("Failed to load welcome text :("); QString welcomeText = QObject::tr("Failed to load welcome text :(");
QFile file(QObject::tr(":/messages/Welcome_EN.txt")); QFile file(QObject::tr(":/messages/Welcome_EN.txt"));