diff --git a/Serial-Studio.pro b/Serial-Studio.pro index 5473bdfe..43c3ab20 100644 --- a/Serial-Studio.pro +++ b/Serial-Studio.pro @@ -126,6 +126,7 @@ HEADERS += \ src/ModuleManager.h \ src/QmlBridge.h \ src/SerialManager.h \ + src/Translator.h \ src/Widgets.h SOURCES += \ @@ -138,6 +139,7 @@ SOURCES += \ src/ModuleManager.cpp \ src/QmlBridge.cpp \ src/SerialManager.cpp \ + src/Translator.cpp \ src/Widgets.cpp \ src/main.cpp @@ -145,3 +147,7 @@ DISTFILES += \ assets/qml/Widgets/*.qml \ assets/qml/Windows/*.qml \ assets/qml/*.qml + +TRANSLATIONS += \ + assets/translations/en.ts \ + assets/translations/es.ts diff --git a/assets/assets.qrc b/assets/assets.qrc index fa6a63f3..ddd28df2 100644 --- a/assets/assets.qrc +++ b/assets/assets.qrc @@ -61,5 +61,8 @@ qml/Windows/Widgets.qml qml/main.qml qml/Widgets/ArtificialHorizonDelegate.qml + translations/en.qm + translations/es.qm + messages/Welcome_ES.txt diff --git a/assets/messages/Welcome_ES.txt b/assets/messages/Welcome_ES.txt new file mode 100644 index 00000000..e401872a --- /dev/null +++ b/assets/messages/Welcome_ES.txt @@ -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) + diff --git a/assets/qml/Windows/About.qml b/assets/qml/Windows/About.qml index 15a8ed3f..08f0eef7 100644 --- a/assets/qml/Windows/About.qml +++ b/assets/qml/Windows/About.qml @@ -25,7 +25,16 @@ import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 ApplicationWindow { - id: window + id: root + + // + // Custom properties + // + readonly property int year: new Date().getFullYear() + + // + // Window options + // flags: Qt.Dialog minimumWidth: 320 maximumWidth: 320 @@ -87,7 +96,7 @@ ApplicationWindow { opacity: 0.8 Layout.fillWidth: true 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 { @@ -137,7 +146,7 @@ ApplicationWindow { Button { Layout.fillWidth: true text: qsTr("Close") - onClicked: window.close() + onClicked: root.close() } Item { diff --git a/assets/qml/Windows/Toolbar.qml b/assets/qml/Windows/Toolbar.qml index 6c00d702..e8dcb0da 100644 --- a/assets/qml/Windows/Toolbar.qml +++ b/assets/qml/Windows/Toolbar.qml @@ -121,7 +121,7 @@ Control { onClicked: root.dataClicked() enabled: CppQmlBridge.groupCount > 0 icon.source: "qrc:/icons/equalizer.svg" - text: qsTr("Data Display") + _btSpacer + text: qsTr("Dashboard") + _btSpacer opacity: enabled ? 1 : 0.5 Behavior on opacity {NumberAnimation{}} diff --git a/assets/translations/en.qm b/assets/translations/en.qm new file mode 100644 index 00000000..fe5c9824 Binary files /dev/null and b/assets/translations/en.qm differ diff --git a/assets/translations/en.ts b/assets/translations/en.ts new file mode 100644 index 00000000..c04f0bd0 --- /dev/null +++ b/assets/translations/en.ts @@ -0,0 +1,478 @@ + + + + + About + + About + + + + Version %1 + + + + The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + + + Contact author + + + + Report bug + + + + Check for updates + + + + Documentation + + + + Close + + + + Copyright © 2020-%1 %2, released under the MIT License. + + + + + AccelerometerDelegate + + G Units + + + + %1 G MAX + + + + %1 G MIN + + + + %1 G ACT + + + + Reset + + + + + Console + + No data received so far... + + + + Autoscroll + + + + Send data to device + + + + + DataGrid + + View + + + + Horizontal Range + + + + Data Groups + + + + Data Plots + + + + Data + + + + + DeviceManager + + Communication Mode + + + + Auto (JSON from serial device) + + + + Manual (use JSON map file) + + + + Change map file (%1) + + + + Select map file + + + + COM Port + + + + Baud Rate + + + + Data Bits + + + + Parity + + + + Stop Bits + + + + Flow Control + + + + + Downloader + + Updater + + + + Downloading updates + + + + Time remaining: 0 minutes + + + + Open + + + + Stop + + + + Time remaining + + + + unknown + + + + Error + + + + Cannot find downloaded update! + + + + Close + + + + Download complete! + + + + The installer will open separately + + + + Click "OK" to begin installing the update + + + + In order to install the update, you may need to quit the application. + + + + In order to install the update, you may need to quit the application. This is a mandatory update, exiting now will close the application + + + + Click the "Open" button to apply the update + + + + Are you sure you want to cancel the download? + + + + Are you sure you want to cancel the download? This is a mandatory update, exiting now will close the application + + + + %1 bytes + + + + %1 KB + + + + %1 MB + + + + of + + + + Downloading Updates + + + + Time Remaining + + + + Unknown + + + + about %1 hours + + + + about one hour + + + + %1 minutes + + + + 1 minute + + + + %1 seconds + + + + 1 second + + + + + Export + + CSV file not open + + + + Cannot find CSV export file! + + + + CSV File Error + + + + Cannot open CSV file for writing! + + + + + Group + + Invalid + + + + + GyroDelegate + + %1° YAW + + + + %1° ROLL + + + + %1° PITCH + + + + + JsonParser + + Select JSON map file + + + + JSON files (*.json) + + + + JSON parse error + + + + JSON map file loaded successfully! + + + + File "%1" loaded into memory + + + + Cannot read JSON file + + + + Please check file permissions & location + + + + + QObject + + Failed to load welcome text :( + + + + :/messages/Welcome_EN.txt + + + + + SerialManager + + No Parity + + + + One + + + + No Flow Control + + + + No Device + + + + Received: %1 %2 + + + + Even Parity + + + + Odd Parity + + + + Space Parity + + + + Mark Parity + + + + One and Half + + + + Two + + + + Hardware Control + + + + Software Control + + + + Select Port + + + + + Toolbar + + Devices + + + + Console + + + + Widgets + + + + About + + + + CSV Export + + + + Open past CSV + + + + Open current CSV + + + + Dashboard + + + + + Updater + + Would you like to download the update now? + + + + Would you like to download the update now? This is a mandatory update, exiting now will close the application + + + + Version %1 of %2 has been released! + + + + No updates are available for the moment + + + + Congratulations! You are running the latest version of %1 + + + + diff --git a/assets/translations/es.qm b/assets/translations/es.qm new file mode 100644 index 00000000..c899cc94 Binary files /dev/null and b/assets/translations/es.qm differ diff --git a/assets/translations/es.ts b/assets/translations/es.ts new file mode 100644 index 00000000..3c95b981 --- /dev/null +++ b/assets/translations/es.ts @@ -0,0 +1,486 @@ + + + + + About + + About + Acerca de + + + Version %1 + Versión %1 + + + Copyright © 2020 %1, released under the MIT License. + Copyright © 2020 %1, distribuido bajo la licencia MIT. + + + The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + 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. + + + Contact author + Contactar al autor + + + Report bug + Reportar un error + + + Check for updates + Buscar actualizaciones + + + Documentation + Documentación + + + Close + Cerrar + + + Copyright © 2020-%1 %2, released under the MIT License. + Copyright © 2020-%1 %2, distribuido bajo la licencia MIT. + + + + AccelerometerDelegate + + G Units + Unidades G + + + %1 G MAX + %1 G MAX + + + %1 G MIN + %1 G MIN + + + %1 G ACT + %1 G ACT + + + Reset + Reajustar + + + + Console + + No data received so far... + No se han recibido datos hasta ahora ... + + + Autoscroll + Desplazamiento automático + + + Send data to device + Enviar datos al dispositivo + + + + DataGrid + + View + Vista + + + Horizontal Range + Rango Horizontal + + + Data Groups + Grupos de Datos + + + Data Plots + Gráficos de Datos + + + Data + Datos + + + + DeviceManager + + Communication Mode + Modo de comunicación + + + Auto (JSON from serial device) + Automático (JSON desde puerto serial) + + + Manual (use JSON map file) + Manual (usar archivo de mapa JSON) + + + Change map file (%1) + Cambiar archivo (%1) + + + Select map file + Seleccionar archivo de mapa + + + COM Port + Puerto COM + + + Baud Rate + Baudios + + + Data Bits + Bits de datos + + + Parity + Paridad + + + Stop Bits + Bits de parada + + + Flow Control + Control de flujo + + + + Downloader + + Updater + Actualizador + + + Downloading updates + Descargando actualizaciones + + + Time remaining: 0 minutes + Tiempo restante: 0 minutos + + + Open + Abrir + + + Stop + Cancelar + + + Time remaining + Tiempo restante + + + unknown + desconocido + + + Error + Error + + + Cannot find downloaded update! + No se puede encontrar el archivo descargado! + + + Close + Cerrar + + + Download complete! + Descarga completa! + + + The installer will open separately + El instalador se abrirá por separado + + + Click "OK" to begin installing the update + Haga clic en "Aceptar" para comenzar a instalar la actualización + + + In order to install the update, you may need to quit the application. + Para instalar la actualización, es posible que deba salir de la aplicación. + + + In order to install the update, you may need to quit the application. This is a mandatory update, exiting now will close the application + 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 + + + Click the "Open" button to apply the update + Haga clic en el botón "Abrir" para instalar la actualización + + + Are you sure you want to cancel the download? + ¿Estás seguro/a de que deseas cancelar la descarga? + + + Are you sure you want to cancel the download? This is a mandatory update, exiting now will close the application + ¿Estás seguro/a de que deseas cancelar la descarga? Esta es una actualización obligatoria, salir ahora cerrará la aplicación + + + %1 bytes + + + + %1 KB + + + + %1 MB + + + + of + de + + + Downloading Updates + Descargando actualizaciones + + + Time Remaining + Tiempo restante + + + Unknown + Desconocido + + + about %1 hours + alrededor de %1 horas + + + about one hour + alrededor de una hora + + + %1 minutes + %1 minutos + + + 1 minute + 1 minuto + + + %1 seconds + %1 segundos + + + 1 second + 1 segundo + + + + Export + + CSV file not open + Archivo CSV no abierto + + + Cannot find CSV export file! + ¡No se puede encontrar el archivo de exportación CSV! + + + CSV File Error + Error de archivo CSV + + + Cannot open CSV file for writing! + ¡No se puede abrir el archivo CSV en modo de escritura! + + + + Group + + Invalid + Inválido + + + + GyroDelegate + + %1° YAW + + + + %1° ROLL + + + + %1° PITCH + + + + + JsonParser + + Select JSON map file + Seleccionar mapa JSON + + + JSON files (*.json) + Archivos JSON (*.json) + + + JSON parse error + Error de lectura de JSON + + + JSON map file loaded successfully! + ¡El archivo de mapa JSON se cargó correctamente! + + + File "%1" loaded into memory + Archivo "%1" cargado en memoria + + + Cannot read JSON file + Error de lectura del archivo JSON + + + Please check file permissions & location + Verifique los permisos y la ubicación del archivo + + + + QObject + + Failed to load welcome text :( + Error al cargar el texto de bienvenida :( + + + :/messages/Welcome_EN.txt + :/messages/Welcome_ES.txt + + + + SerialManager + + No Parity + Sin Paridad + + + One + Uno + + + No Flow Control + Sin control de flujo + + + No Device + Sin Dispositivo + + + Received: %1 %2 + Recibido: %1 %2 + + + Even Parity + Par + + + Odd Parity + Inpar + + + Space Parity + Espacio + + + Mark Parity + Marca + + + One and Half + Uno y Medio + + + Two + Dos + + + Hardware Control + Controlado por hardware + + + Software Control + Controlado por software + + + Select Port + Seleccionar Puerto + + + + Toolbar + + Devices + Dispositivos + + + Console + Consola + + + Data Display + Visualización de Datos + + + Widgets + Widgets + + + About + Acerca de + + + CSV Export + Exportación CSV + + + Open past CSV + Abrir CSV pasado + + + Open current CSV + Abrir CSV actual + + + Dashboard + Tablero + + + + Updater + + Would you like to download the update now? + ¿Le gustaría descargar la actualización ahora? + + + Would you like to download the update now? This is a mandatory update, exiting now will close the application + ¿Le gustaría descargar la actualización ahora? Esta es una actualización obligatoria, salir ahora cerrará la aplicación + + + Version %1 of %2 has been released! + ¡Se ha lanzado la versión %1 de %2! + + + No updates are available for the moment + No hay actualizaciones disponibles por el momento + + + Congratulations! You are running the latest version of %1 + ¡Felicidades! Estás ejecutando la última versión de %1 + + + diff --git a/src/Translator.cpp b/src/Translator.cpp new file mode 100644 index 00000000..25ee3113 --- /dev/null +++ b/src/Translator.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020 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(); +} diff --git a/src/Translator.h b/src/Translator.h new file mode 100644 index 00000000..7e2ff82a --- /dev/null +++ b/src/Translator.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 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 +#include +#include + +#ifdef QT_QML_LIB +# include +#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 diff --git a/src/main.cpp b/src/main.cpp index 1080c950..ebe8fab9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ #include "GraphProvider.h" #include "SerialManager.h" +#include "Translator.h" #include "ModuleManager.h" /** @@ -93,6 +94,11 @@ int main(int argc, char **argv) qmlRegisterType("Group", 1, 0, "Group"); qmlRegisterType("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 QString welcomeText = QObject::tr("Failed to load welcome text :("); QFile file(QObject::tr(":/messages/Welcome_EN.txt"));