From 18a8b8d43577941388fa40666641f628860d6f7a Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Wed, 7 Feb 2024 08:03:16 +0300 Subject: [PATCH] kxkb: utilize a translations provseided by xkeyboard-config xkeyboard-config package comes with a message catalogue of its own to translate locale, keyboard model and xkb option names. It would be easier and more robust to utilize it instead of redoing all translation in-house. Signed-off-by: Alexander Golubev --- CMakeLists.txt | 2 ++ ConfigureChecks.cmake | 14 ++++++++++++++ config.h.cmake | 2 ++ kxkb/kcmlayout.cpp | 20 +++++++++++--------- kxkb/kcmmisc.cpp | 1 + kxkb/kxkb.cpp | 1 + kxkb/rules.cpp | 9 ++++++++- kxkb/rules.h | 4 ++++ kxkb/x11helper.cpp | 27 +++++++++++++-------------- kxkb/x11helper.h | 2 ++ 10 files changed, 58 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6dc8adc20..a7de8d9a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,7 @@ option( WITH_TDEHWLIB "Enable TDE hardware library support" ${WITH_ALL_OPTIONS} option( WITH_UPOWER "Enable UPOWER support" ${WITH_ALL_OPTIONS} ) option( WITH_ELFICON "Enable ELF embedded metadata support" ${WITH_ALL_OPTIONS} ) option( WITH_GCC_VISIBILITY "Enable fvisibility and fvisibility-inlines-hidden" ${WITH_ALL_OPTIONS} ) +option( WITH_XKB_TRANSLATIONS "Use translations for xkb messages provided by xkeyboard-config" ON ) ##### options comments ########################## @@ -155,6 +156,7 @@ option( WITH_GCC_VISIBILITY "Enable fvisibility and fvisibility-inlines-hidden" # WITH_PCRE affects twin/compot-tde # WITH_SUDO_TDESU_BACKEND affects tdesu # WITH_SUDO_KONSOLE_SUPER_USER_COMMAND affects launching Konsole super user sessions +# WITH_XKB_TRANSLATIONS affects kxkb # NOTE: WITH_SHADOW and WITH_PAM shouldn't be set concurrently # WITH_PAM will override WITH_SHADOW diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 12185432a..b72d866df 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -563,6 +563,20 @@ if( BUILD_KXKB ) message( STATUS "No additional XKb rules directory found" ) endif( ) + if( WITH_XKB_TRANSLATIONS ) + if( NOT XKB_CONFIG_LOCALE_DIR ) + pkg_get_variable( XKB_CONFIG_DATADIR xkeyboard-config datadir ) + if( XKB_CONFIG_DATADIR ) + set( XKB_CONFIG_LOCALE_DIR "${XKB_CONFIG_DATADIR}/locale" CACHE INTERNAL "" ) + message( STATUS "Found xkeybord-config locale dir: ${XKB_CONFIG_LOCALE_DIR}" ) + endif( ) + endif( ) + + if( NOT XKB_CONFIG_LOCALE_DIR ) + tde_message_fatal( "Translations for xkb messages were requested but the xkeyboard-config locale directory could not be determined." ) + endif( ) + endif( ) + endif( ) if( BUILD_KCONTROL OR BUILD_TDM ) diff --git a/config.h.cmake b/config.h.cmake index 3324456f3..fcee849e3 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -245,7 +245,9 @@ unsigned long strlcpy(char*, const char*, unsigned long); #cmakedefine XLIBDIR "@XLIBDIR@" // kxkb +#cmakedefine WITH_XKB_TRANSLATIONS 1 #cmakedefine X11_XKB_RULES_DIR "@X11_XKB_RULES_DIR@" +#cmakedefine XKB_CONFIG_LOCALE_DIR "@XKB_CONFIG_LOCALE_DIR@" // tdm, kcontrol #cmakedefine WITH_XRANDR "@WITH_XRANDR@" diff --git a/kxkb/kcmlayout.cpp b/kxkb/kcmlayout.cpp index fb4d5d063..f9fbf3c59 100644 --- a/kxkb/kcmlayout.cpp +++ b/kxkb/kcmlayout.cpp @@ -36,6 +36,7 @@ #include "pixmap.h" #include "kcmmisc.h" #include "kcmlayoutwidget.h" +#include "x11helper.h" #include "kcmlayout.h" #include "kcmlayout.moc" @@ -105,6 +106,7 @@ LayoutConfig::LayoutConfig(TQWidget *parent, const char *name) m_rules(NULL), m_forceGrpOverwrite(false) { + X11Helper::initializeTranslations(); TQVBoxLayout *main = new TQVBoxLayout(this, 0, KDialog::spacingHint()); widget = new LayoutConfigWidget(this, "widget"); @@ -244,7 +246,7 @@ void LayoutConfig::initUI() { const char *hkOpt = tqstrdup(TQString("grp:" + (*hk)).ascii()); const char *hkDesc = allOptions[hkOpt]; if (hkDesc != 0) { // the option exists - widget->comboHotkey->insertItem(i18n(hkDesc)); + widget->comboHotkey->insertItem(XkbRules::trOpt(hkDesc)); } } widget->comboHotkey->insertItem(i18n("None")); @@ -315,7 +317,7 @@ void LayoutConfig::initUI() { foundGrp = true; } - OptionListItem *item = m_optionGroups[i18n(optionKey.latin1())]; + OptionListItem *item = m_optionGroups[optionKey]; if (item != NULL) { OptionListItem *child = item->findChildItem( option ); @@ -686,25 +688,25 @@ TQWidget* LayoutConfig::makeOptionsTab() { if( it.currentKey() == "ctrl" || it.currentKey() == "caps" || it.currentKey() == "altwin") { - parent = new OptionListItem(listView, i18n( it.current() ), + parent = new OptionListItem(listView, XkbRules::trOpt( it.current() ), TQCheckListItem::RadioButtonController, it.currentKey()); OptionListItem *item = new OptionListItem(parent, i18n( "None" ), TQCheckListItem::RadioButton, "none"); item->setState(TQCheckListItem::On); } else if (it.currentKey() == "grp") { - parent = new OptionListItem(listView, i18n(it.current()), + parent = new OptionListItem(listView, XkbRules::trOpt(it.current()), TQCheckListItem::RadioButtonController, it.currentKey()); parent->setSelectable(false); OptionListItem *item = new OptionListItem(parent, i18n("None"), TQCheckListItem::CheckBox, "grp:none"); } else { - parent = new OptionListItem(listView, i18n( it.current() ), + parent = new OptionListItem(listView, XkbRules::trOpt( it.current() ), TQCheckListItem::CheckBoxController, it.currentKey()); } parent->setOpen(true); - m_optionGroups.insert(i18n(it.currentKey().local8Bit()), parent); + m_optionGroups.insert(it.currentKey(), parent); } } @@ -724,10 +726,10 @@ TQWidget* LayoutConfig::makeOptionsTab() text = text.replace( "Cap$", "Caps." ); if ( parent->type() == TQCheckListItem::CheckBoxController || key.startsWith("grp:")) - new OptionListItem(parent, i18n(text.utf8()), + new OptionListItem(parent, XkbRules::trOpt(text), TQCheckListItem::CheckBox, key); else - new OptionListItem(parent, i18n(text.utf8()), + new OptionListItem(parent, XkbRules::trOpt(text), TQCheckListItem::RadioButton, key); } } @@ -1333,7 +1335,7 @@ extern "C" //these seem to be new in XFree86 4.4.0 I18N_NOOP("Shift with numpad keys works as in MS Windows."); - I18N_NOOP("Special keys (Ctrl+Alt+) handled in a server."); + I18N_NOOP("Special keys (Ctrl+Alt+<key>) handled in a server."); I18N_NOOP("Miscellaneous compatibility options"); I18N_NOOP("Right Control key works as Right Alt"); diff --git a/kxkb/kcmmisc.cpp b/kxkb/kcmmisc.cpp index 6c7caa36e..c23b3cf6c 100644 --- a/kxkb/kcmmisc.cpp +++ b/kxkb/kcmmisc.cpp @@ -48,6 +48,7 @@ #include "kcmmisc.h" #include "kcmmiscwidget.h" +#include "x11helper.h" #include KeyboardConfig::KeyboardConfig (TQWidget * parent, const char *) diff --git a/kxkb/kxkb.cpp b/kxkb/kxkb.cpp index 6a90aa0dd..34ed19334 100644 --- a/kxkb/kxkb.cpp +++ b/kxkb/kxkb.cpp @@ -68,6 +68,7 @@ KXKBApp::KXKBApp(bool allowStyles, bool GUIenabled) m_tray(NULL), kWinModule(NULL) { + X11Helper::initializeTranslations(); m_extension = new XKBExtension(); if( !m_extension->init() ) { kdDebug() << "xkb initialization failed, exiting..." << endl; diff --git a/kxkb/rules.cpp b/kxkb/rules.cpp index 442a78c00..ab89b4f17 100644 --- a/kxkb/rules.cpp +++ b/kxkb/rules.cpp @@ -79,4 +79,11 @@ TQString XkbRules::getLayoutName(LayoutUnit layout) const { fullName += " (" + layout.variant + ")"; } return fullName; -} \ No newline at end of file +} + +TQString XkbRules::trOpt(TQString opt) { + // xkeyboard-config's translation is generated directly from the xml and has some querks + // like sustitution for the '<' and '>'. We will have to workaroung those manually: + TQString translated = i18n(opt.replace("<", "<").replace(">", ">").utf8()); + return translated.replace("<", "<").replace(">", ">"); +} diff --git a/kxkb/rules.h b/kxkb/rules.h index e7a6e8840..0a68f3dbf 100644 --- a/kxkb/rules.h +++ b/kxkb/rules.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "layoutunit.h" @@ -21,6 +22,9 @@ public: TQString getLayoutName(LayoutUnit layout) const; + /// A helper to translate option description + static TQString trOpt(TQString opt); + protected: void loadRules(TQString filename, bool layoutsOnly=false); diff --git a/kxkb/x11helper.cpp b/kxkb/x11helper.cpp index 2663bf4d4..90e29d9e2 100644 --- a/kxkb/x11helper.cpp +++ b/kxkb/x11helper.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include @@ -214,25 +216,12 @@ X11Helper::loadRules(const TQString& file, bool layoutsOnly) { // workaround for empty 'compose' options group description if( rulesInfo->options.find("compose:menu") && !rulesInfo->options.find("compose") ) { - rulesInfo->options.replace("compose", "Compose Key Position"); + rulesInfo->options.replace("compose", I18N_NOOP("Compose Key Position")); } } for(TQDictIterator it(rulesInfo->options) ; it.current() != NULL; ++it ) { - // HACK 2023/06/01 some descriptions in xkb rule files have "< >" in place - // of an actual key name, both in *.lst and *.xml files - TQString descFix = TQString::null; - if (it.currentKey().contains("lsgt_switch")) { - descFix = TQString(it.current()).replace("< >", "LSGT"); - } - else if (it.currentKey().startsWith("compose:102")) { - descFix = TQString(it.current()).replace("< >", "102"); - } - if (!descFix.isNull()) { - rulesInfo->options.replace(it.currentKey(), tqstrdup(descFix.ascii())); - } - // Add missing option groups TQString option(it.currentKey()); int columnPos = option.find(":"); @@ -403,3 +392,13 @@ bool X11Helper::areSingleGroupsSupported() { return true; //TODO: } + +void X11Helper::initializeTranslations() { + // TDE is usually installed into some non-standard prefix and by default system-wide locale + // dirs are not considered when searching for gettext message catalogues, so we have to add + // it explicitly. +#ifdef WITH_XKB_TRANSLATIONS + TDEGlobal::dirs()->addResourceDir("locale", XKB_CONFIG_LOCALE_DIR); + TDEGlobal::locale()->insertCatalogue("xkeyboard-config"); +#endif +} diff --git a/kxkb/x11helper.h b/kxkb/x11helper.h index 042fb4ce5..8315dc446 100644 --- a/kxkb/x11helper.h +++ b/kxkb/x11helper.h @@ -3,6 +3,7 @@ #include #include +#include struct RulesInfo { @@ -36,6 +37,7 @@ public: static bool areLayoutsClean() { return m_layoutsClean; } static bool areSingleGroupsSupported(); + static void initializeTranslations(); }; #endif /*X11HELPER_H_*/