From 5bba51ad4b5ae69064c739be117fdf72b2702dd2 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 1 Jun 2024 12:22:37 +0200 Subject: [PATCH] Add translation support I've thought about supporting this in the past but it never actually was usable due to the usage of basically static variables in the header which can't be translated. So use QT_TRANSLATE_NOOP and make the user of the values translate it then. --- .builds/freebsd.yml | 1 + include/libopenrazer.h | 73 ++++++++------- include/libopenrazer/capability.h | 13 ++- meson.build | 16 ++++ src/capability.cpp | 4 +- src/misc.cpp | 12 +++ translations/de.ts | 112 ----------------------- translations/libopenrazer_de.ts | 143 ++++++++++++++++++++++++++++++ translations/meson.build | 8 ++ 9 files changed, 234 insertions(+), 148 deletions(-) delete mode 100644 translations/de.ts create mode 100644 translations/libopenrazer_de.ts create mode 100644 translations/meson.build diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index 6b67041..c2f4a8a 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -4,6 +4,7 @@ packages: - pkgconf - qt5-buildtools - qt5-dbus + - qt5-linguisttools - qt5-widgets - qt5-xml sources: diff --git a/include/libopenrazer.h b/include/libopenrazer.h index 78d1e36..9d09681 100644 --- a/include/libopenrazer.h +++ b/include/libopenrazer.h @@ -5,13 +5,16 @@ #ifndef LIBOPENRAZER_H #define LIBOPENRAZER_H +#include "libopenrazer/capability.h" #include "libopenrazer/dbusexception.h" #include "libopenrazer/device.h" #include "libopenrazer/led.h" #include "libopenrazer/manager.h" #include "libopenrazer/misc.h" #include "libopenrazer/openrazer.h" -#include "libopenrazer/capability.h" + +#include +#include // NOTE: DBus types -> Qt/C++ types: http://doc.qt.io/qt-5/qdbustypesystem.html#primitive-types @@ -26,43 +29,53 @@ namespace libopenrazer { * List of effects provided by OpenRazer. */ const QVector ledFxList { - Capability(::openrazer::Effect::Off, Led::tr("Off"), 0), - Capability(::openrazer::Effect::On, Led::tr("On"), 0), - Capability(::openrazer::Effect::Static, Led::tr("Static"), 1), - Capability(::openrazer::Effect::Breathing, Led::tr("Breathing"), 1), - Capability(::openrazer::Effect::BreathingDual, Led::tr("Breathing Dual"), 2), - Capability(::openrazer::Effect::BreathingRandom, Led::tr("Breathing Random"), 0), - Capability(::openrazer::Effect::BreathingMono, Led::tr("Breathing"), 0), - Capability(::openrazer::Effect::Blinking, Led::tr("Blinking"), 1), - Capability(::openrazer::Effect::Spectrum, Led::tr("Spectrum"), 0), - Capability(::openrazer::Effect::Wave, Led::tr("Wave"), 0), - Capability(::openrazer::Effect::Wheel, Led::tr("Wheel"), 0), - Capability(::openrazer::Effect::Reactive, Led::tr("Reactive"), 1), - Capability(::openrazer::Effect::Ripple, Led::tr("Ripple"), 1), - Capability(::openrazer::Effect::RippleRandom, Led::tr("Ripple Random"), 0), + Capability(::openrazer::Effect::Off, QT_TRANSLATE_NOOP("libopenrazer", "Off"), 0), + Capability(::openrazer::Effect::On, QT_TRANSLATE_NOOP("libopenrazer", "On"), 0), + Capability(::openrazer::Effect::Static, QT_TRANSLATE_NOOP("libopenrazer", "Static"), 1), + Capability(::openrazer::Effect::Breathing, QT_TRANSLATE_NOOP("libopenrazer", "Breathing"), 1), + Capability(::openrazer::Effect::BreathingDual, QT_TRANSLATE_NOOP("libopenrazer", "Breathing Dual"), 2), + Capability(::openrazer::Effect::BreathingRandom, QT_TRANSLATE_NOOP("libopenrazer", "Breathing Random"), 0), + Capability(::openrazer::Effect::BreathingMono, QT_TRANSLATE_NOOP("libopenrazer", "Breathing"), 0), + Capability(::openrazer::Effect::Blinking, QT_TRANSLATE_NOOP("libopenrazer", "Blinking"), 1), + Capability(::openrazer::Effect::Spectrum, QT_TRANSLATE_NOOP("libopenrazer", "Spectrum"), 0), + Capability(::openrazer::Effect::Wave, QT_TRANSLATE_NOOP("libopenrazer", "Wave"), 0), + Capability(::openrazer::Effect::Wheel, QT_TRANSLATE_NOOP("libopenrazer", "Wheel"), 0), + Capability(::openrazer::Effect::Reactive, QT_TRANSLATE_NOOP("libopenrazer", "Reactive"), 1), + Capability(::openrazer::Effect::Ripple, QT_TRANSLATE_NOOP("libopenrazer", "Ripple"), 1), + Capability(::openrazer::Effect::RippleRandom, QT_TRANSLATE_NOOP("libopenrazer", "Ripple Random"), 0), }; /*! * Mapping from openrazer::LedId to a human readable string + * + * This needs to be translated by the user! + * qApp->translate("libopenrazer", foo) */ -const QHash<::openrazer::LedId, QString> ledIdToStringTable { +const QHash<::openrazer::LedId, const char *> ledIdToStringTable { { ::openrazer::LedId::Unspecified, "" }, - { ::openrazer::LedId::ScrollWheelLED, Led::tr("Scroll Wheel") }, - { ::openrazer::LedId::BatteryLED, Led::tr("Battery") }, - { ::openrazer::LedId::LogoLED, Led::tr("Logo") }, - { ::openrazer::LedId::BacklightLED, Led::tr("Backlight") }, - { ::openrazer::LedId::MacroRecordingLED, Led::tr("Macro Recording") }, - { ::openrazer::LedId::GameModeLED, Led::tr("Game Mode") }, - { ::openrazer::LedId::KeymapRedLED, Led::tr("Keymap Red") }, - { ::openrazer::LedId::KeymapGreenLED, Led::tr("Keymap Green") }, - { ::openrazer::LedId::KeymapBlueLED, Led::tr("Keymap Blue") }, - { ::openrazer::LedId::RightSideLED, Led::tr("Right Side") }, - { ::openrazer::LedId::LeftSideLED, Led::tr("Left Side") }, - { ::openrazer::LedId::ChargingLED, Led::tr("Charging") }, - { ::openrazer::LedId::FastChargingLED, Led::tr("Fast Charging") }, - { ::openrazer::LedId::FullyChargedLED, Led::tr("Fully Charged") }, + { ::openrazer::LedId::ScrollWheelLED, QT_TRANSLATE_NOOP("libopenrazer", "Scroll Wheel") }, + { ::openrazer::LedId::BatteryLED, QT_TRANSLATE_NOOP("libopenrazer", "Battery") }, + { ::openrazer::LedId::LogoLED, QT_TRANSLATE_NOOP("libopenrazer", "Logo") }, + { ::openrazer::LedId::BacklightLED, QT_TRANSLATE_NOOP("libopenrazer", "Backlight") }, + { ::openrazer::LedId::MacroRecordingLED, QT_TRANSLATE_NOOP("libopenrazer", "Macro Recording") }, + { ::openrazer::LedId::GameModeLED, QT_TRANSLATE_NOOP("libopenrazer", "Game Mode") }, + { ::openrazer::LedId::KeymapRedLED, QT_TRANSLATE_NOOP("libopenrazer", "Keymap Red") }, + { ::openrazer::LedId::KeymapGreenLED, QT_TRANSLATE_NOOP("libopenrazer", "Keymap Green") }, + { ::openrazer::LedId::KeymapBlueLED, QT_TRANSLATE_NOOP("libopenrazer", "Keymap Blue") }, + { ::openrazer::LedId::RightSideLED, QT_TRANSLATE_NOOP("libopenrazer", "Right Side") }, + { ::openrazer::LedId::LeftSideLED, QT_TRANSLATE_NOOP("libopenrazer", "Left Side") }, + { ::openrazer::LedId::ChargingLED, QT_TRANSLATE_NOOP("libopenrazer", "Charging") }, + { ::openrazer::LedId::FastChargingLED, QT_TRANSLATE_NOOP("libopenrazer", "Fast Charging") }, + { ::openrazer::LedId::FullyChargedLED, QT_TRANSLATE_NOOP("libopenrazer", "Fully Charged") }, }; +/*! + * Load the translations into the given QTranslator object. + * + * This then needs to be installed into the QApplication! + */ +bool loadTranslations(QTranslator *translator); + } #endif // LIBOPENRAZER_H diff --git a/include/libopenrazer/capability.h b/include/libopenrazer/capability.h index 1601863..b20f5ab 100644 --- a/include/libopenrazer/capability.h +++ b/include/libopenrazer/capability.h @@ -5,6 +5,8 @@ #ifndef CAPABILITY_H #define CAPABILITY_H +#include "libopenrazer/openrazer.h" + namespace libopenrazer { /*! @@ -17,8 +19,8 @@ class Capability public: /// @cond Capability(); - Capability(::openrazer::Effect identifier, QString displayString, int numColors); - Capability(::openrazer::Effect, QString displayString); + Capability(::openrazer::Effect identifier, const char *displayString, int numColors); + Capability(::openrazer::Effect, const char *displayString); Capability(const Capability &other); ~Capability(); /// @endcond @@ -38,14 +40,17 @@ class Capability /*! * Returns a human-readable string describing the capability * + * This needs to be translated by the user! + * qApp->translate("libopenrazer", foo.getDisplayString()) + * * e.g. \c "Spectrum" */ - QString getDisplayString() const; + const char *getDisplayString() const; private: int numColors; ::openrazer::Effect identifier; - QString displayString; + const char *displayString; }; } diff --git a/meson.build b/meson.build index cf312e9..227f527 100644 --- a/meson.build +++ b/meson.build @@ -6,6 +6,22 @@ project('libopenrazer', qt = import('qt5') qt_dep = dependency('qt5', modules : ['Core', 'DBus', 'Gui', 'Xml']) +if build_machine.system() == 'darwin' + libopenrazer_data_dir = 'Contents/Resources' +else + libopenrazer_data_dir = get_option('datadir') / 'libopenrazer' +endif + +subdir('translations') + +conf_data = configuration_data({ + 'LIBOPENRAZER_VERSION' : '"' + meson.project_version() + '"', + 'LIBOPENRAZER_DATADIR' : '"' + get_option('prefix') / get_option('datadir') / 'libopenrazer' + '"', +}) + +configure_file(output : 'config.h', + configuration : conf_data) + sources = [ 'src/dbusexception.cpp', 'src/misc.cpp', diff --git a/src/capability.cpp b/src/capability.cpp index d56e555..3a8f8f5 100644 --- a/src/capability.cpp +++ b/src/capability.cpp @@ -12,7 +12,7 @@ Capability::Capability() this->displayString = ""; this->numColors = 0; } -Capability::Capability(::openrazer::Effect identifier, QString displayString, int numColors) +Capability::Capability(::openrazer::Effect identifier, const char *displayString, int numColors) { this->identifier = identifier; this->displayString = displayString; @@ -38,7 +38,7 @@ ::openrazer::Effect Capability::getIdentifier() const return identifier; } -QString Capability::getDisplayString() const +const char *Capability::getDisplayString() const { return displayString; } diff --git a/src/misc.cpp b/src/misc.cpp index c67baf1..c346829 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -2,9 +2,11 @@ // // SPDX-License-Identifier: GPL-3.0-or-later +#include "config.h" #include "libopenrazer.h" #include "libopenrazer_private.h" +#include #include #include @@ -51,4 +53,14 @@ QString fromCamelCase(const QString &s) return result.toLower(); } +bool loadTranslations(QTranslator *translator) +{ +#if defined(Q_OS_MACOS) + QString translationsDirectory = QCoreApplication::applicationDirPath() + "/../Resources/translations/"; +#else + QString translationsDirectory = QString(LIBOPENRAZER_DATADIR) + "/translations/"; +#endif + return translator->load(QLocale::system(), "libopenrazer", "_", translationsDirectory); +} + } diff --git a/translations/de.ts b/translations/de.ts deleted file mode 100644 index fd64966..0000000 --- a/translations/de.ts +++ /dev/null @@ -1,112 +0,0 @@ - - - - - libopenrazer::Led - - - Off - - - - - Static - - - - - Breathing - - - - - Breathing Dual - - - - - Breathing Random - - - - - Blinking - - - - - Spectrum - - - - - Wave - - - - - Reactive - - - - - Unspecified - - - - - Scroll Wheel - - - - - Battery - - - - - Logo - - - - - Backlight - - - - - Macro Recording - - - - - Game Mode - - - - - Keymap Red - - - - - Keymap Green - - - - - Keymap Blue - - - - - Right Side - - - - - Left Side - - - - diff --git a/translations/libopenrazer_de.ts b/translations/libopenrazer_de.ts new file mode 100644 index 0000000..dee6032 --- /dev/null +++ b/translations/libopenrazer_de.ts @@ -0,0 +1,143 @@ + + + + + libopenrazer + + + Off + Aus + + + + On + An + + + + Static + Statisch + + + + + Breathing + Atmen + + + + Breathing Dual + Atmen zweifach + + + + Breathing Random + Atmen zufällig + + + + Blinking + Blinken + + + + Spectrum + Spektrum + + + + Wave + Welle + + + + Wheel + Rad + + + + Reactive + Reaktiv + + + + Ripple + Rippel + + + + Ripple Random + Rippel zufällig + + + + Scroll Wheel + Scrollrad + + + + Battery + Batterie + + + + Logo + Logo + + + + Backlight + Hintergrundbeleuchtung + + + + Macro Recording + Makro-Aufnahme + + + + Game Mode + Spielmodus + + + + Keymap Red + Tastenzuordnung Rot + + + + Keymap Green + Tastenzuordnung Grün + + + + Keymap Blue + Tastenzuordnung Blau + + + + Right Side + Rechte Seite + + + + Left Side + Linke Seite + + + + Charging + Aufladung + + + + Fast Charging + Schnellaufladung + + + + Fully Charged + Voll aufgeladen + + + diff --git a/translations/meson.build b/translations/meson.build new file mode 100644 index 0000000..f1ab1e0 --- /dev/null +++ b/translations/meson.build @@ -0,0 +1,8 @@ +# Translations +ts_files = [ + 'libopenrazer_de.ts', +] +qt.compile_translations(ts_files : ts_files, + install : true, + install_dir : libopenrazer_data_dir / 'translations', + build_by_default : true)