From d2e0a4603d4e3b2d1c6e7449e0809b59dd0de3b6 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 7 Oct 2021 17:08:45 +0200 Subject: [PATCH 1/3] Add KLazyLocalizedString as a replacement for the I18N_NOOP macros --- autotests/CMakeLists.txt | 5 + autotests/klazylocalizedstringtest.cpp | 77 ++++++++++ autotests/klocalizedstringtest.cpp | 11 ++ autotests/klocalizedstringtest.h | 2 + docs/programmers-guide.md | 49 +++--- src/i18n/CMakeLists.txt | 2 + src/i18n/klazylocalizedstring.cpp | 16 ++ src/i18n/klazylocalizedstring.h | 202 +++++++++++++++++++++++++ src/i18n/klocalizedstring.h | 2 + 9 files changed, 340 insertions(+), 26 deletions(-) create mode 100644 autotests/klazylocalizedstringtest.cpp create mode 100644 src/i18n/klazylocalizedstring.cpp create mode 100644 src/i18n/klazylocalizedstring.h diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index f7a10e8..e5c68ae 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -18,6 +18,11 @@ ecm_add_test(klocalizedstringtest.cpp # klocalizedstringtest needs the libintl include path target_include_directories(ki18n-klocalizedstringtest PRIVATE ${LibIntl_INCLUDE_DIRS}) +ecm_add_test(klazylocalizedstringtest.cpp + TEST_NAME "ki18n-klazylocalizedstringtest" + LINK_LIBRARIES Qt5::Test KF5::I18n +) + if (TARGET ktranscript) ecm_add_test(ktranscripttest.cpp testhelpers.cpp TEST_NAME "ki18n-ktranscripttest" diff --git a/autotests/klazylocalizedstringtest.cpp b/autotests/klazylocalizedstringtest.cpp new file mode 100644 index 0000000..4c5322d --- /dev/null +++ b/autotests/klazylocalizedstringtest.cpp @@ -0,0 +1,77 @@ +/* + SPDX-FileCopyrightText: 2021 Volker Krause + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include +#include + +#include + +#include + +class KLazyLocalizedStringTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testImplicitConversionToLocalizedString() + { + // this has to compile + KLocalizedString s = kli18n("message"); + s = kli18nc("context", "message"); + s = kli18np("singular", "plural"); + s = kli18ncp("context", "singular", "plural"); + s = klxi18n("message"); + s = klxi18nc("context", "message"); + s = klxi18np("singular", "plural"); + s = klxi18ncp("context", "singular", "plural"); + + // this should not compile + // s = kli18n(QStringLiteral("message").toUtf8().constData()); + // auto s2 = new KLazyLocalizedString("bla", "blub", "foo", false); + } + + void testEmpty() + { + KLocalizedString s = KLazyLocalizedString(); + QVERIFY(s.isEmpty()); + } + + void testStaticMessageTable() + { + struct { + int someProperty; + KLazyLocalizedString msg; + } static constexpr const msg_table[] = { + {0, kli18n("message")}, + {1, kli18nc("context", "message")}, + {2, kli18np("singular", "plural")}, + {3, kli18ncp("context", "singular", "plural")}, + {4, klxi18n("message")}, + {5, klxi18nc("context", "message")}, + {6, klxi18np("singular", "plural")}, + {7, klxi18ncp("context", "singular", "plural")}, + }; + + // direct access + for (const auto &entry : msg_table) { + QVERIFY(!KLocalizedString(entry.msg).toString().isEmpty()); + } + + // storing in a local variable + int max = 0; + KLazyLocalizedString ls; + for (const auto &entry : msg_table) { + if (entry.someProperty > max) { + max = entry.someProperty; + ls = entry.msg; + } + } + QVERIFY(!KLocalizedString(ls).toString().isEmpty()); + QCOMPARE(std::strcmp(ls.untranslatedText(), "singular"), 0); + } +}; + +QTEST_GUILESS_MAIN(KLazyLocalizedStringTest) + +#include "klazylocalizedstringtest.moc" diff --git a/autotests/klocalizedstringtest.cpp b/autotests/klocalizedstringtest.cpp index 47b9a28..44403e9 100644 --- a/autotests/klocalizedstringtest.cpp +++ b/autotests/klocalizedstringtest.cpp @@ -21,6 +21,7 @@ #include +#include #include #include @@ -525,4 +526,14 @@ void KLocalizedStringTest::testThreads() QThreadPool::globalInstance()->setMaxThreadCount(1); // delete those threads } +void KLocalizedStringTest::testLazy() +{ + if (!m_hasFrench) { + QSKIP("French test files not usable."); + } + KLocalizedString s = kli18n("Job"); + KLocalizedString::setLanguages({"fr"}); + QCOMPARE(s.toString(), QString::fromUtf8("Tâche")); +} + QTEST_MAIN(KLocalizedStringTest) diff --git a/autotests/klocalizedstringtest.h b/autotests/klocalizedstringtest.h index ed98449..75351d7 100644 --- a/autotests/klocalizedstringtest.h +++ b/autotests/klocalizedstringtest.h @@ -36,6 +36,8 @@ private Q_SLOTS: void untranslatedText(); void brokenTags(); + void testLazy(); + private: bool m_hasFrench; bool m_hasCatalan; diff --git a/docs/programmers-guide.md b/docs/programmers-guide.md index 836de54..31f6de7 100644 --- a/docs/programmers-guide.md +++ b/docs/programmers-guide.md @@ -397,7 +397,7 @@ and which handles text that should be translated has to delay the actual lookup in the catalog (like other locale-dependent actions), in one of two ways: either by using statically initialized character arrays wrapped in -`I18N_*` macros for extraction, and later making the +`kli18n*` functions for extraction, and later making the actual `i18n*` calls (see section \ref i18n_noop); or by using `ki18n*` calls to create `KLocalizedString` instances, which do not perform immediate catalog lookup, and later fetching @@ -955,30 +955,30 @@ translators into new languages. -### Extraction-Only Macros +### Extraction-Only Functions Sometimes it is convenient only to mark a message for extraction (into the catalog template, as described in \ref handle_extract), and to place the actual `i18n` call somewhere else. A typical case of this are global static initializers, where only POD types can be safely used. -For this purpose `I18N*_NOOP` macros are provided. +For this purpose `kli18n*` functions are provided. -The `I18N_NOOP` macro is the counterpart to `*i18n` calls, +The `kli18n` function is the counterpart to `*i18n` calls, and it is used like this: ~~~ typedef struct { - const char *description; + const KLazyLocalizedString description; const char *regExp; } term; -// Inert I18N_NOOP macros here... + static const term items[] = { - {I18N_NOOP("any character"), "."}, - {I18N_NOOP("start of line"), "^"}, - {I18N_NOOP("end of line"), "$"}, - {I18N_NOOP("repeats, zero or more times"), "*"}, + {kli18n("any character"), "."}, + {kli18n("start of line"), "^"}, + {kli18n("end of line"), "$"}, + {kli18n("repeats, zero or more times"), "*"}, ... }; @@ -989,38 +989,33 @@ void populatePatternMenu (QMenu *menu) for (uint i = 0; i < sizeof(items) / sizeof(items[0]); i++) { menu->addAction(new RegExpAction(menu, // ...actual i18n call here. - i18n(items[i].description), + KLocalizedString(items[i].description).toString(), items[i].regExp)); } } ~~~ -The `I18NC_NOOP` macro is the counterpart to `*i18nc` calls: +The `kli18nc` macro is the counterpart to `*i18nc` calls: ~~~ typedef struct { - const char *description, *abbrev; + const KLocalizedString abbrev; } unitDef; static const unitDef units[] = { - {I18N_NOOP2_NOSTRIP("unit for 2^10 bytes", "KiB")}, - {I18N_NOOP2_NOSTRIP("unit for 2^20 bytes", "MiB")}, + {kli18nc("unit for 2^10 bytes", "KiB")}, + {kli18nc("unit for 2^20 bytes", "MiB")}, ... } ... - QString unitAbbrev = i18nc(units[i].description, units[i].abbrev); + QString unitAbbrev = KLocalizedString(units[i].abbrev).toString(); ~~~ - -There are also two deprecated macros: -`I18N_NOOP2_NOSTRIP` is simply the old name of `I18NC_NOOP`; -`I18N_NOOP2` takes the context argument but discards it, -which means that the context must be repeated verbatim in -the corresponding `i18nc` call. - -In general, `I18N*_NOOP` macros make it harder to follow -i18n in the code, and should be avoided when possible. +Variants for singular/plural and with or without markup exist as well. +Unlike the `I18N_NOOP` macros they replace, mixing different variants +in the same message table is possible, e.g. to add a context to a few +messages when necessary. @@ -1128,7 +1123,7 @@ after the last `i18n` call in the public header: This will undefine all expansions of `*i18n*` into `*i18nd*`, leaving the client's environment clean. -If instead the public header contains only `I18N_NOOP*` macros, +If instead the public header contains only `kli18n*` function calls, defining `TRANSLATION_DOMAIN` is unnecessary in the first place, since actual `i18n` calls happen somewhere else. @@ -1306,6 +1301,7 @@ should look like this: -c i18n \ -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 \ -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \ +-kkli18n:1 -kkli18nc:1c,2 -kkli18np:1,2 -kkli18ncp:1c,2,3 \ -kI18N_NOOP:1 -kI18NC_NOOP:1c,2 \ --copyright-holder= \ --msgid-bugs-address= @@ -1327,6 +1323,7 @@ the following `-k` options should be added as well: ~~~ -kxi18n:1 -kxi18nc:1c,2 -kxi18np:1,2 -kxi18ncp:1c,2,3 \ -kkxi18n:1 -kkxi18nc:1c,2 -kkxi18np:1,2 -kkxi18ncp:1c,2,3 \ +-kklxi18n:1 -kklxi18nc:1c,2 -kklxi18np:1,2 -kklxi18ncp:1c,2,3 \ ~~~ diff --git a/src/i18n/CMakeLists.txt b/src/i18n/CMakeLists.txt index 986dfd4..0a8ba54 100644 --- a/src/i18n/CMakeLists.txt +++ b/src/i18n/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(KF5I18n) add_library(KF5::I18n ALIAS KF5I18n) target_sources(KF5I18n PRIVATE + klazylocalizedstring.cpp klocalizedstring.cpp klocalizedtranslator.cpp kcatalog.cpp @@ -57,6 +58,7 @@ install(TARGETS KF5I18n EXPORT KF5I18nTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS ecm_generate_headers(KI18n_HEADERS HEADER_NAMES + KLazyLocalizedString KLocalizedContext KLocalizedString KLocalizedTranslator diff --git a/src/i18n/klazylocalizedstring.cpp b/src/i18n/klazylocalizedstring.cpp new file mode 100644 index 0000000..e0a7c98 --- /dev/null +++ b/src/i18n/klazylocalizedstring.cpp @@ -0,0 +1,16 @@ +/* + SPDX-FileCopyrightText: 2021 Volker Krause + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "klazylocalizedstring.h" + +#include + +KLazyLocalizedString::operator KLocalizedString() const +{ + if (!m_text) { + return KLocalizedString(); + } + return KLocalizedString(nullptr, m_context, m_text, m_plural, m_markupAware); +} diff --git a/src/i18n/klazylocalizedstring.h b/src/i18n/klazylocalizedstring.h new file mode 100644 index 0000000..838a758 --- /dev/null +++ b/src/i18n/klazylocalizedstring.h @@ -0,0 +1,202 @@ +/* + SPDX-FileCopyrightText: 2021 Volker Krause + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef KLAZYLOCALIZEDSTRING_H +#define KLAZYLOCALIZEDSTRING_H + +#include "ki18n_export.h" + +#include + +class KLocalizedString; + +/** Lazy-initialized variant of KLocalizedString. + * This is a safer replacement for the I18N_NOOP set of macros and allows + * marking strings for extraction without runtime-initializing KLocalizedString instances, + * for example for storing in static data tables. + * + * Instances of KLazyLocalizedString cannot be created directly, but have to be obtained + * via the kli18n* functions (similar to KLocalizedString and the ki18n* functions). + * + * Example usage in a static message table: + * @code + * struct { + * MyClass::VehicleType type; + * KLazyLocalizedString msg; + * } static constexpr const vehicle_msg_table[] = { + * { MyClass::Train, kli18np("%1 train", "%1 trains") }, + * { MyClass::Bus, kli18ncp("the vehicle, not the USB one", "%1 bus", "%1 buses") }, + * ... + * }; + * + * ... + * + * const auto it = std::find_if(std::begin(vehicle_msg_table), std::end(vehicle_msg_table), [vehicleType](const auto &m) { return m.type == vehicleType; }); + * QString translatedMessage = KLocalizedString((*it).msg).subs(vehicleCount).toString(); + * @endcode + * + * @since 5.89 + */ +class KLazyLocalizedString +{ +public: + explicit constexpr inline KLazyLocalizedString() = default; + + /** Convert to a KLocalizedString to actually perform the translation and obtain a concrete string to show. */ + KI18N_EXPORT operator KLocalizedString() const; + + /** Returns the raw untranslated text as passed to @p kli18n*. */ + constexpr inline const char *untranslatedText() const + { + return m_text; + } + +private: + template + friend inline constexpr KLazyLocalizedString kli18n(const char (&text)[TextSize]); + template + friend constexpr inline KLazyLocalizedString kli18nc(const char (&context)[ContextSize], const char (&text)[TextSize]); + template + friend constexpr inline KLazyLocalizedString kli18np(const char (&singular)[SingularSize], const char (&plural)[PluralSize]); + template + friend constexpr inline KLazyLocalizedString + kli18ncp(const char (&context)[ContextSize], const char (&singular)[SingularSize], const char (&plural)[PluralSize]); + template + friend constexpr inline KLazyLocalizedString klxi18n(const char (&text)[TextSize]); + template + friend constexpr inline KLazyLocalizedString klxi18nc(const char (&context)[ContextSize], const char (&text)[TextSize]); + template + friend constexpr inline KLazyLocalizedString klxi18np(const char (&singular)[SingularSize], const char (&plural)[PluralSize]); + template + friend constexpr inline KLazyLocalizedString + klxi18ncp(const char (&context)[ContextSize], const char (&singular)[SingularSize], const char (&plural)[PluralSize]); + + constexpr inline KLazyLocalizedString(const char *context, const char *text, const char *plural, bool markupAware) + : m_context(context) + , m_text(text) + , m_plural(plural) + , m_markupAware(markupAware) + { + } + + const char *m_context = nullptr; + const char *m_text = nullptr; + const char *m_plural = nullptr; + bool m_markupAware = false; +}; + +/** + * Mark the string @p text for extraction. + * + * \param text string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString kli18n(const char (&text)[TextSize]) +{ + return KLazyLocalizedString(nullptr, text, nullptr, false); +} + +/** + * Mark the string @p text with @p context for extraction. + * + * \param context context of the string + * \param text string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString kli18nc(const char (&context)[ContextSize], const char (&text)[TextSize]) +{ + return KLazyLocalizedString(context, text, nullptr, false); +} + +/** + * Mark the string @p singular and @p plural for extraction. + * + * \param singular singular form of the string to translate + * \param plural plural form of the string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString kli18np(const char (&singular)[SingularSize], const char (&plural)[PluralSize]) +{ + return KLazyLocalizedString(nullptr, singular, plural, false); +} + +/** + * Mark the string @p singular and @p plural with @p context for extraction. + * + * \param context context of the string + * \param singular singular form of the string to translate + * \param plural plural form of the string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString kli18ncp(const char (&context)[ContextSize], const char (&singular)[SingularSize], const char (&plural)[PluralSize]) +{ + return KLazyLocalizedString(context, singular, plural, false); +} + +/** + * Mark the markup-aware string @p text for extraction. + * + * \param text string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString klxi18n(const char (&text)[TextSize]) +{ + return KLazyLocalizedString(nullptr, text, nullptr, true); +} + +/** + * Mark the markup-aware string @p text with @p context for extraction. + * + * \param context context of the string + * \param text string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString klxi18nc(const char (&context)[ContextSize], const char (&text)[TextSize]) +{ + return KLazyLocalizedString(context, text, nullptr, true); +} + +/** + * Mark the markup-aware string @p singular and @p plural for extraction. + * + * \param singular singular form of the string to translate + * \param plural plural form of the string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString klxi18np(const char (&singular)[SingularSize], const char (&plural)[PluralSize]) +{ + return KLazyLocalizedString(nullptr, singular, plural, true); +} + +/** + * Mark the markup-aware string @p singular and @p plural with @p context for extraction. + * + * \param context context of the string + * \param singular singular form of the string to translate + * \param plural plural form of the string to translate + * \return KLazyLocalizedString for deferred translation. + * \since 5.89 + */ +template +constexpr inline KLazyLocalizedString klxi18ncp(const char (&context)[ContextSize], const char (&singular)[SingularSize], const char (&plural)[PluralSize]) +{ + return KLazyLocalizedString(context, singular, plural, true); +} + +#endif // KLAZYLOCALIZEDSTRING_H diff --git a/src/i18n/klocalizedstring.h b/src/i18n/klocalizedstring.h index ff7cce2..d40314c 100644 --- a/src/i18n/klocalizedstring.h +++ b/src/i18n/klocalizedstring.h @@ -23,6 +23,7 @@ #include class KLocalizedStringPrivate; +class KLazyLocalizedString; /** * \file klocalizedstring.h @@ -87,6 +88,7 @@ class KLocalizedStringPrivate; class KI18N_EXPORT KLocalizedString { friend class KLocalizedStringPrivate; + friend class KLazyLocalizedString; friend KLocalizedString KI18N_EXPORT ki18n(const char *text); friend KLocalizedString KI18N_EXPORT ki18nc(const char *context, const char *text); -- GitLab From 81d4fb961a5563bd1f8783c9ed79538e20cc7efe Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 14 Oct 2021 17:27:21 +0200 Subject: [PATCH 2/3] Deprecate the I18N_NOOP macros in favor of KLazyLocalizedString --- src/i18n/klocalizedstring.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/i18n/klocalizedstring.h b/src/i18n/klocalizedstring.h index d40314c..f8ad081 100644 --- a/src/i18n/klocalizedstring.h +++ b/src/i18n/klocalizedstring.h @@ -29,24 +29,33 @@ class KLazyLocalizedString; * \file klocalizedstring.h */ +#if KI18N_ENABLE_DEPRECATED_SINCE(5, 89) #ifndef I18N_NOOP /** * Wrap string for extraction. * * See \ref i18n_noop for use cases. + * + * \deprecated since 5.89, use @c kli18n() instead. */ #define I18N_NOOP(text) text #endif +#endif +#if KI18N_ENABLE_DEPRECATED_SINCE(5, 89) #ifndef I18NC_NOOP /** * Wrap string with context for extraction. * * See \ref i18n_noop for use cases. + * + * \deprecated since 5.89, use @c kli18nc() instead. */ #define I18NC_NOOP(context, text) context, text #endif +#endif +#if KI18N_ENABLE_DEPRECATED_SINCE(5, 89) #ifndef I18N_NOOP2 /** * Wrap string with context for extraction, discarding context. @@ -55,10 +64,11 @@ class KLazyLocalizedString; * The preferred solution is to use I18NC_NOOP and store both @p context and @p text. * I18NC_NOOP2 exists for cases where storing the context is not possible. * - * \deprecated between 5.0 and 5.64, re-enabled in 5.65 + * \deprecated between 5.0 and 5.64, re-enabled in 5.65, re-deprecated in 5.89, use @p kli18nc() instead. */ #define I18N_NOOP2(context, text) text #endif +#endif #if KI18N_ENABLE_DEPRECATED_SINCE(5, 0) #ifndef I18N_NOOP2_NOSTRIP -- GitLab From 94582dd808386743631238ca958f9737e9571b9d Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Fri, 15 Oct 2021 16:27:35 +0200 Subject: [PATCH 3/3] Port Kuit keymap away from I18N_NOOP macro usage --- src/i18n/kuitmarkup.cpp | 117 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/src/i18n/kuitmarkup.cpp b/src/i18n/kuitmarkup.cpp index fc970bd..2d77b17 100644 --- a/src/i18n/kuitmarkup.cpp +++ b/src/i18n/kuitmarkup.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -185,6 +186,7 @@ public: void setUiMarkerData(); + void setKeyName(const KLazyLocalizedString &keyName); void setTextTransformData(); QString toKeyCombo(const QStringList &languages, const QString &shstr, Kuit::VisualFormat format); QString toInterfacePath(const QStringList &languages, const QString &inpstr, Kuit::VisualFormat format); @@ -302,6 +304,12 @@ void KuitStaticData::setUiMarkerData() SET_FORMAT(TermText, QStringLiteral("term")); } +void KuitStaticData::setKeyName(const KLazyLocalizedString &keyName) +{ + QString normname = QString::fromUtf8(keyName.untranslatedText()).trimmed().toLower(); + keyNames[normname] = keyName; +} + void KuitStaticData::setTextTransformData() { // i18n: Decide which string is used to delimit keys in a keyboard @@ -322,65 +330,56 @@ void KuitStaticData::setTextTransformData() // NOTE: The '→' glyph seems to be available in all widespread fonts. // Collect keyboard key names. -#undef SET_KEYNAME -#define SET_KEYNAME(rawname) do { \ - /* Normalize key, trim and all lower-case. */ \ - QString normname = QStringLiteral(rawname).trimmed().toLower(); \ - keyNames[normname] = ki18nc("keyboard-key-name", rawname); \ - } while (0) - // Now we need I18NC_NOOP that does remove context. -#undef I18NC_NOOP -#define I18NC_NOOP(ctxt, msg) msg - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Alt")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "AltGr")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Backspace")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "CapsLock")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Control")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Ctrl")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Del")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Delete")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Down")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "End")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Enter")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Esc")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Escape")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Home")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Hyper")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Ins")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Insert")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Left")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Menu")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Meta")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "NumLock")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PageDown")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PageUp")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PgDown")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PgUp")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PauseBreak")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PrintScreen")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "PrtScr")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Return")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Right")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "ScrollLock")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Shift")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Space")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Super")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "SysReq")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Tab")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Up")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "Win")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F1")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F2")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F3")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F4")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F5")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F6")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F7")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F8")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F9")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F10")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F11")); - SET_KEYNAME(I18NC_NOOP("keyboard-key-name", "F12")); + setKeyName(kli18nc("keyboard-key-name", "Alt")); + setKeyName(kli18nc("keyboard-key-name", "AltGr")); + setKeyName(kli18nc("keyboard-key-name", "Backspace")); + setKeyName(kli18nc("keyboard-key-name", "CapsLock")); + setKeyName(kli18nc("keyboard-key-name", "Control")); + setKeyName(kli18nc("keyboard-key-name", "Ctrl")); + setKeyName(kli18nc("keyboard-key-name", "Del")); + setKeyName(kli18nc("keyboard-key-name", "Delete")); + setKeyName(kli18nc("keyboard-key-name", "Down")); + setKeyName(kli18nc("keyboard-key-name", "End")); + setKeyName(kli18nc("keyboard-key-name", "Enter")); + setKeyName(kli18nc("keyboard-key-name", "Esc")); + setKeyName(kli18nc("keyboard-key-name", "Escape")); + setKeyName(kli18nc("keyboard-key-name", "Home")); + setKeyName(kli18nc("keyboard-key-name", "Hyper")); + setKeyName(kli18nc("keyboard-key-name", "Ins")); + setKeyName(kli18nc("keyboard-key-name", "Insert")); + setKeyName(kli18nc("keyboard-key-name", "Left")); + setKeyName(kli18nc("keyboard-key-name", "Menu")); + setKeyName(kli18nc("keyboard-key-name", "Meta")); + setKeyName(kli18nc("keyboard-key-name", "NumLock")); + setKeyName(kli18nc("keyboard-key-name", "PageDown")); + setKeyName(kli18nc("keyboard-key-name", "PageUp")); + setKeyName(kli18nc("keyboard-key-name", "PgDown")); + setKeyName(kli18nc("keyboard-key-name", "PgUp")); + setKeyName(kli18nc("keyboard-key-name", "PauseBreak")); + setKeyName(kli18nc("keyboard-key-name", "PrintScreen")); + setKeyName(kli18nc("keyboard-key-name", "PrtScr")); + setKeyName(kli18nc("keyboard-key-name", "Return")); + setKeyName(kli18nc("keyboard-key-name", "Right")); + setKeyName(kli18nc("keyboard-key-name", "ScrollLock")); + setKeyName(kli18nc("keyboard-key-name", "Shift")); + setKeyName(kli18nc("keyboard-key-name", "Space")); + setKeyName(kli18nc("keyboard-key-name", "Super")); + setKeyName(kli18nc("keyboard-key-name", "SysReq")); + setKeyName(kli18nc("keyboard-key-name", "Tab")); + setKeyName(kli18nc("keyboard-key-name", "Up")); + setKeyName(kli18nc("keyboard-key-name", "Win")); + setKeyName(kli18nc("keyboard-key-name", "F1")); + setKeyName(kli18nc("keyboard-key-name", "F2")); + setKeyName(kli18nc("keyboard-key-name", "F3")); + setKeyName(kli18nc("keyboard-key-name", "F4")); + setKeyName(kli18nc("keyboard-key-name", "F5")); + setKeyName(kli18nc("keyboard-key-name", "F6")); + setKeyName(kli18nc("keyboard-key-name", "F7")); + setKeyName(kli18nc("keyboard-key-name", "F8")); + setKeyName(kli18nc("keyboard-key-name", "F9")); + setKeyName(kli18nc("keyboard-key-name", "F10")); + setKeyName(kli18nc("keyboard-key-name", "F11")); + setKeyName(kli18nc("keyboard-key-name", "F12")); // TODO: Add rest of the key names? } // clang-format on -- GitLab