[PATCH] fdo#50415 and fdo#34638 Fix Shortcut names are not localized on Linux

Thomas Arnhold thomas at arnhold.org
Mon Jun 4 09:21:58 PDT 2012


This partially reverts commit 2233aa52da14ec85331aee1163b885fe9a9fb507

Before the keyboard name was used to determine the target language
for translation of UI shortcuts. With this patch the UI locale
is used to determine the language.

Related to:
- 8d9e2d9a211f710e91ac7c607fea25895282d245
- 04b9c2f633f0be1b676933943bdd0b1dc58b5471

Change-Id: I14c6759dc405db490d210a78ce19e1416efb7ac7
---
 vcl/Library_vclplug_gen.mk          |    1 +
 vcl/inc/unx/saldisp.hxx             |    9 +
 vcl/unx/generic/app/keysymnames.cxx |  372 +++++++++++++++++++++++++++++++++++
 vcl/unx/generic/app/saldisp.cxx     |   21 +-
 4 files changed, 396 insertions(+), 7 deletions(-)
 create mode 100644 vcl/unx/generic/app/keysymnames.cxx

diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 3ff257a..c018a9d 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -73,6 +73,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
     vcl/unx/generic/app/i18n_status \
     vcl/unx/generic/app/i18n_wrp \
     vcl/unx/generic/app/i18n_xkb \
+    vcl/unx/generic/app/keysymnames \
     vcl/unx/generic/app/randrwrapper \
     vcl/unx/generic/app/saldata \
     vcl/unx/generic/app/saldisp \
diff --git a/vcl/inc/unx/saldisp.hxx b/vcl/inc/unx/saldisp.hxx
index fce2a68..c83b42b 100644
--- a/vcl/inc/unx/saldisp.hxx
+++ b/vcl/inc/unx/saldisp.hxx
@@ -434,6 +434,15 @@ public:
     void                SetupInput( SalI18N_InputMethod *pInputMethod );
 };
 
+
+// get foreign key names
+namespace vcl_sal {
+    rtl::OUString getKeysymReplacementName(
+        rtl::OUString pLang,
+        KeySym nSymbol );
+}
+
+
 #endif // _SV_SALDISP_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/keysymnames.cxx b/vcl/unx/generic/app/keysymnames.cxx
new file mode 100644
index 0000000..bc1d705
--- /dev/null
+++ b/vcl/unx/generic/app/keysymnames.cxx
@@ -0,0 +1,372 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if !defined(SOLARIS) && !defined(AIX)
+#include <tools/prex.h>
+#include <X11/XKBlib.h>
+#include <tools/postx.h>
+#endif
+
+#include <unx/saldisp.hxx>
+#include <X11/keysym.h>
+#include <sal/macros.h>
+
+#if !defined (SunXK_Undo)
+#define SunXK_Undo      0x0000FF65  // XK_Undo
+#define SunXK_Again     0x0000FF66  // XK_Redo
+#define SunXK_Find      0x0000FF68  // XK_Find
+#define SunXK_Stop      0x0000FF69  // XK_Cancel
+#define SunXK_Props     0x1005FF70
+#define SunXK_Front     0x1005FF71
+#define SunXK_Copy      0x1005FF72
+#define SunXK_Open      0x1005FF73
+#define SunXK_Paste     0x1005FF74
+#define SunXK_Cut       0x1005FF75
+#endif
+
+#include <string.h>
+#include <rtl/ustring.hxx>
+
+namespace vcl_sal {
+
+    struct KeysymNameReplacement
+    {
+        KeySym          aSymbol;
+        const char*     pName;
+    };
+
+    struct KeyboardReplacements
+    {
+        const char*                     pLangName;
+        const KeysymNameReplacement*    pReplacements;
+        int                             nReplacements;
+    };
+
+    // ====================================================================
+    //
+    // CAUTION CAUTION CAUTION
+    // every string value in the replacements tables must be in UTF8
+    // be careful with your editor !
+    //
+    // ====================================================================
+
+    static const struct KeysymNameReplacement aImplReplacements_English[] =
+    {
+        { XK_Control_L, "Ctrl" },
+        { XK_Control_R, "Ctrl" },
+        { XK_Escape, "Esc" },
+        { XK_space, "Space" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Turkish[] =
+    {
+        { XK_Control_L, "Ctrl" },
+        { XK_Control_R, "Ctrl" },
+        { XK_Right, "SaÄŸ" },
+        { XK_Left, "Sol" },
+        { XK_Up, "Yukarı" },
+        { XK_Down, "Aşağı" },
+        { XK_space, "BoÅŸluk" }
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Russian[] =
+    {
+        { XK_Right, "Вправо" },
+        { XK_Left, "Влево" },
+        { XK_Up, "Вверх" },
+        { XK_Down, "Вниз" },
+        { XK_space, "Пробел" }
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_German[] =
+    {
+        { XK_Control_L, "Strg" },
+        { XK_Control_R, "Strg" },
+        { XK_Shift_L, "Umschalt" },
+        { XK_Shift_R, "Umschalt" },
+        { XK_Alt_L, "Alt" },
+        { XK_Alt_R, "Alt Gr" },
+        { XK_Page_Up, "Bild auf" },
+        { XK_Page_Down, "Bild ab" },
+        { XK_End, "Ende" },
+        { XK_Home, "Pos 1" },
+        { XK_Insert, "Einfg" },
+        { XK_Delete, "Entf" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Rechts" },
+        { XK_Left, "Links" },
+        { XK_Up, "Oben" },
+        { XK_Down, "Unten" },
+        { XK_BackSpace, "Rückschritt" },
+        { XK_Return, "Eingabe" },
+        { XK_slash, "Schrägstrich" },
+        { XK_space, "Leertaste" },
+        { SunXK_Stop,  "Stop" },
+        { SunXK_Again, "Wiederholen" },
+        { SunXK_Props, "Eigenschaften" },
+        { SunXK_Undo,  "Zurücknehmen" },
+        { SunXK_Front, "Vordergrund" },
+        { SunXK_Copy,  "Kopieren" },
+        { SunXK_Open,  "Öffnen" },
+        { SunXK_Paste, "Einsetzen" },
+        { SunXK_Find,  "Suchen" },
+        { SunXK_Cut,   "Ausschneiden" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_French[] =
+    {
+        { XK_Shift_L, "Maj" },
+        { XK_Shift_R, "Maj" },
+        { XK_Page_Up, "Pg. Préc" },
+        { XK_Page_Down, "Pg. Suiv" },
+        { XK_End, "Fin" },
+        { XK_Home, "Origine" },
+        { XK_Insert, "Insérer" },
+        { XK_Delete, "Suppr" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Droite" },
+        { XK_Left, "Gauche" },
+        { XK_Up, "Haut" },
+        { XK_Down, "Bas" },
+        { XK_BackSpace, "Ret. Arr" },
+        { XK_Return, "Retour" },
+        { XK_KP_Enter, "Entrée" },
+        { SunXK_Stop,  "Stop" },
+        { SunXK_Again, "Encore" },
+        { SunXK_Props, "Props" },
+        { SunXK_Undo,  "Annuler" },
+        { SunXK_Front, "Devant" },
+        { SunXK_Copy,  "Copy" },
+        { SunXK_Open,  "Ouvrir" },
+        { SunXK_Paste, "Coller" },
+        { SunXK_Find,  "Cher." },
+        { SunXK_Cut,   "Couper" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Italian[] =
+    {
+        { XK_Shift_L, "Maiusc" },
+        { XK_Shift_R, "Maiusc" },
+        { XK_Page_Up, "PgSu" },
+        { XK_Page_Down, "PgGiu" },
+        { XK_End, "Fine" },
+        { XK_Insert, "Ins" },
+        { XK_Delete, "Canc" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "A destra" },
+        { XK_Left, "A sinistra" },
+        { XK_Up, "Sposta verso l'alto" },
+        { XK_Down, "Sposta verso il basso" },
+        { XK_BackSpace, "Backspace" },
+        { XK_Return, "Invio" },
+        { XK_space, "Spazio" },
+        { SunXK_Stop,  "Stop" },
+        { SunXK_Again, "Ancora" },
+        { SunXK_Props, "Proprietà" },
+        { SunXK_Undo,  "Annulla" },
+        { SunXK_Front, "Davanti" },
+        { SunXK_Copy,  "Copia" },
+        { SunXK_Open,  "Apri" },
+        { SunXK_Paste, "Incolla" },
+        { SunXK_Find,  "Trova" },
+        { SunXK_Cut,   "Taglia" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Dutch[] =
+    {
+        { XK_Page_Up, "PageUp" },
+        { XK_Page_Down, "PageDown" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Rechts" },
+        { XK_Left, "Links" },
+        { XK_Up, "Boven" },
+        { XK_Down, "Onder" },
+        { XK_BackSpace, "Backspace" },
+        { XK_Return, "Return" },
+        { XK_space, "Spatiebalk" },
+        { SunXK_Stop,  "Stop" },
+        { SunXK_Again, "Again" },
+        { SunXK_Props, "Props" },
+        { SunXK_Undo,  "Undo" },
+        { SunXK_Front, "Front" },
+        { SunXK_Copy,  "Copy" },
+        { SunXK_Open,  "Open" },
+        { SunXK_Paste, "Paste" },
+        { SunXK_Find,  "Find" },
+        { SunXK_Cut,   "Cut" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Norwegian[] =
+    {
+        { XK_Shift_L, "Skift" },
+        { XK_Shift_R, "Skift" },
+        { XK_Page_Up, "PageUp" },
+        { XK_Page_Down, "PageDown" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Hyre" },
+        { XK_Left, "Venstre" },
+        { XK_Up, "Opp" },
+        { XK_Down, "Ned" },
+        { XK_BackSpace, "Tilbake" },
+        { XK_Return, "Enter" },
+        { SunXK_Stop,  "Avbryt" },
+        { SunXK_Again, "Gjenta" },
+        { SunXK_Props, "Egenskaper" },
+        { SunXK_Undo,  "Angre" },
+        { SunXK_Front, "Front" },
+        { SunXK_Copy,  "Kopi" },
+        { SunXK_Open,  "Ã…pne" },
+        { SunXK_Paste, "Lim" },
+        { SunXK_Find,  "Søk" },
+        { SunXK_Cut,   "Klipp" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Swedish[] =
+    {
+        { XK_Shift_L, "Skift" },
+        { XK_Shift_R, "Skift" },
+        { XK_Page_Up, "PageUp" },
+        { XK_Page_Down, "PageDown" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Höger" },
+        { XK_Left, "Vänster" },
+        { XK_Up, "Up" },
+        { XK_Down, "Ned" },
+        { XK_BackSpace, "Backsteg" },
+        { XK_Return, "Retur" },
+        { XK_space, "Blank" },
+        { SunXK_Stop,  "Avbryt" },
+        { SunXK_Again, "Upprepa" },
+        { SunXK_Props, "Egenskaper" },
+        { SunXK_Undo,  "Ã…ngra" },
+        { SunXK_Front, "Fram" },
+        { SunXK_Copy,  "Kopiera" },
+        { SunXK_Open,  "Öppna" },
+        { SunXK_Paste, "Klistra in" },
+        { SunXK_Find,  "Sök" },
+        { SunXK_Cut,   "Klipp ut" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Portuguese[] =
+    {
+        { XK_Page_Up, "PageUp" },
+        { XK_Page_Down, "PageDown" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Direita" },
+        { XK_Left, "Esquerda" },
+        { XK_Up, "Acima" },
+        { XK_Down, "Abaixo" },
+        { XK_BackSpace, "Backspace" },
+        { XK_Return, "Enter" },
+        { XK_slash, "Barra" },
+        { SunXK_Stop,  "Stop" },
+        { SunXK_Again, "Again" },
+        { SunXK_Props, "Props" },
+        { SunXK_Undo,  "Undo" },
+        { SunXK_Front, "Front" },
+        { SunXK_Copy,  "Copy" },
+        { SunXK_Open,  "Open" },
+        { SunXK_Paste, "Paste" },
+        { SunXK_Find,  "Find" },
+        { SunXK_Cut,   "Cut" },
+    };
+
+    static const struct KeysymNameReplacement aImplReplacements_Spanish[] =
+    {
+        { XK_Shift_L, "Mayús" },
+        { XK_Shift_R, "Mayús" },
+        { XK_Page_Up, "RePág" },
+        { XK_Page_Down, "AvPág" },
+        { XK_End, "Fin" },
+        { XK_Home, "Inicio" },
+        { XK_Delete, "Supr" },
+        { XK_Escape, "Esc" },
+        { XK_Right, "Hacia la derecha" },
+        { XK_Left, "Hacia la izquierda" },
+        { XK_Up, "Hacia arriba" },
+        { XK_Down, "Hacia abajo" },
+        { XK_BackSpace, "Ret" },
+        { XK_Return, "Entrada" },
+        { XK_space, "Espacio" },
+        { XK_KP_Enter, "Intro" },
+        { SunXK_Stop,  "Stop" },
+        { SunXK_Again, "Repetir" },
+        { SunXK_Props, "Props" },
+        { SunXK_Undo,  "Anular" },
+        { SunXK_Front, "Delante" },
+        { SunXK_Copy,  "Copiar" },
+        { SunXK_Open,  "Abrir" },
+        { SunXK_Paste, "Pegar" },
+        { SunXK_Find,  "Buscar" },
+        { SunXK_Cut,   "Cortar" },
+    };
+
+    static const struct KeyboardReplacements aKeyboards[] =
+    {
+        { "de", aImplReplacements_German, SAL_N_ELEMENTS(aImplReplacements_German) },
+        { "es", aImplReplacements_Spanish, SAL_N_ELEMENTS(aImplReplacements_Spanish) },
+        { "fr", aImplReplacements_French, SAL_N_ELEMENTS(aImplReplacements_French) },
+        { "it", aImplReplacements_Italian, SAL_N_ELEMENTS(aImplReplacements_Italian) },
+        { "nl", aImplReplacements_Dutch, SAL_N_ELEMENTS(aImplReplacements_Dutch) },
+        { "no", aImplReplacements_Norwegian, SAL_N_ELEMENTS(aImplReplacements_Norwegian) },
+        { "pt", aImplReplacements_Portuguese, SAL_N_ELEMENTS(aImplReplacements_Portuguese) },
+        { "ru", aImplReplacements_Russian, SAL_N_ELEMENTS(aImplReplacements_Russian) },
+        { "sv", aImplReplacements_Swedish, SAL_N_ELEMENTS(aImplReplacements_Swedish) },
+        { "tr", aImplReplacements_Turkish, SAL_N_ELEMENTS(aImplReplacements_Turkish) },
+    };
+
+    // translate keycodes, used within the displayed menu shortcuts
+    rtl::OUString getKeysymReplacementName( rtl::OUString pLang, KeySym nSymbol )
+    {
+        for( unsigned int n = 0; n < SAL_N_ELEMENTS(aKeyboards); n++ )
+        {
+            if( pLang.equalsAscii( aKeyboards[n].pLangName ) )
+            {
+                const struct KeysymNameReplacement* pRepl = aKeyboards[n].pReplacements;
+                for( int m = aKeyboards[n].nReplacements ; m ; )
+                {
+                    if( nSymbol == pRepl[--m].aSymbol )
+                        return rtl::OUString( pRepl[m].pName, strlen(pRepl[m].pName), RTL_TEXTENCODING_UTF8 );
+                }
+            }
+        }
+
+        // try english fallbacks
+        const struct KeysymNameReplacement* pRepl = aImplReplacements_English;
+        for( int m = SAL_N_ELEMENTS(aImplReplacements_English); m ; )
+        {
+            if( nSymbol == pRepl[--m].aSymbol )
+                return rtl::OUString( pRepl[m].pName, strlen(pRepl[m].pName), RTL_TEXTENCODING_UTF8 );
+        }
+
+        return rtl::OUString();
+    }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx
index ee4f094..2c34fd0 100644
--- a/vcl/unx/generic/app/saldisp.cxx
+++ b/vcl/unx/generic/app/saldisp.cxx
@@ -66,6 +66,9 @@ Status XineramaGetInfo(Display*, int, XRectangle*, unsigned char*, int*);
 
 #include <tools/postx.h>
 
+#include <svtools/langhelp.hxx>
+#include <vcl/svapp.hxx>
+
 #include <unx/salunx.h>
 #include <sal/types.h>
 #include "unx/i18n_im.hxx"
@@ -755,6 +758,7 @@ sal_uInt16 SalDisplay::GetIndicatorState() const
 
 rtl::OUString SalDisplay::GetKeyNameFromKeySym( KeySym nKeySym ) const
 {
+    rtl::OUString aLang = Application::GetSettings().GetUILocale().Language;
     rtl::OUString aRet;
 
     // return an empty string for keysyms that are not bound to
@@ -766,13 +770,16 @@ rtl::OUString SalDisplay::GetKeyNameFromKeySym( KeySym nKeySym ) const
             aRet = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "???" ) );
         else
         {
-            const char *pString = XKeysymToString( nKeySym );
-            int n = strlen( pString );
-
-            if( n > 2 && pString[n-2] == '_' )
-                aRet = rtl::OUString( pString, n-2, RTL_TEXTENCODING_ISO_8859_1 );
-            else
-                aRet = rtl::OUString( pString, n, RTL_TEXTENCODING_ISO_8859_1 );
+            aRet = ::vcl_sal::getKeysymReplacementName( aLang, nKeySym );
+            if( aRet.isEmpty() )
+            {
+                const char *pString = XKeysymToString( nKeySym );
+                int n = strlen( pString );
+                if( n > 2 && pString[n-2] == '_' )
+                    aRet = rtl::OUString( pString, n-2, RTL_TEXTENCODING_ISO_8859_1 );
+                else
+                    aRet = rtl::OUString( pString, n, RTL_TEXTENCODING_ISO_8859_1 );
+            }
         }
     }
     return aRet;
-- 
1.7.10.3


--------------030801030808010503060906
Content-Type: text/x-patch;
 name="0001-libo3.5.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="0001-libo3.5.patch"



More information about the LibreOffice mailing list