[Libreoffice-commits] core.git: include/vcl vcl/source vcl/unx

Caolán McNamara caolanm at redhat.com
Fri Apr 13 23:53:51 UTC 2018


 include/vcl/mnemonic.hxx       |    5 -
 vcl/source/window/mnemonic.cxx |   13 +-
 vcl/unx/gtk3/gtk3gtkinst.cxx   |  184 ++++++++++++++++++++++++++++-------------
 3 files changed, 139 insertions(+), 63 deletions(-)

New commits:
commit 9c8a6a4396ebbe8ecb15591cc291c388c82c8ed6
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Apr 13 15:31:44 2018 +0100

    gtk3: generate missing mnemonics
    
    Change-Id: Ib0e94b8484dabb7e859c53aeb0e4adf75727fcd6
    Reviewed-on: https://gerrit.libreoffice.org/52839
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/vcl/mnemonic.hxx b/include/vcl/mnemonic.hxx
index bf2591aff8f4..f7db3a3095fb 100644
--- a/include/vcl/mnemonic.hxx
+++ b/include/vcl/mnemonic.hxx
@@ -51,15 +51,16 @@
 
 class VCL_DLLPUBLIC MnemonicGenerator
 {
+    sal_Unicode m_cMnemonic;
     // 0 == Mnemonic; >0 == count of characters
     sal_uInt8               maMnemonics[MAX_MNEMONICS];
     css::uno::Reference< css::i18n::XCharacterClassification > mxCharClass;
 
     SAL_DLLPRIVATE static sal_uInt16 ImplGetMnemonicIndex( sal_Unicode c );
-    SAL_DLLPRIVATE static sal_Unicode ImplFindMnemonic( const OUString& rKey );
+    SAL_DLLPRIVATE sal_Unicode ImplFindMnemonic( const OUString& rKey );
 
 public:
-                        MnemonicGenerator();
+                        MnemonicGenerator(sal_Unicode cMnemonic = MNEMONIC_CHAR);
 
     void                RegisterMnemonic( const OUString& rKey );
     OUString            CreateMnemonic( const OUString& rKey );
diff --git a/vcl/source/window/mnemonic.cxx b/vcl/source/window/mnemonic.cxx
index fe26cd14c152..43db6dea1493 100644
--- a/vcl/source/window/mnemonic.cxx
+++ b/vcl/source/window/mnemonic.cxx
@@ -28,7 +28,8 @@
 
 using namespace ::com::sun::star;
 
-MnemonicGenerator::MnemonicGenerator()
+MnemonicGenerator::MnemonicGenerator(sal_Unicode cMnemonic)
+    : m_cMnemonic(cMnemonic)
 {
     memset( maMnemonics, 1, sizeof( maMnemonics ) );
 }
@@ -59,10 +60,10 @@ sal_uInt16 MnemonicGenerator::ImplGetMnemonicIndex( sal_Unicode c )
 sal_Unicode MnemonicGenerator::ImplFindMnemonic( const OUString& rKey )
 {
     sal_Int32 nIndex = 0;
-    while ( (nIndex = rKey.indexOf( MNEMONIC_CHAR, nIndex )) != -1 )
+    while ( (nIndex = rKey.indexOf( m_cMnemonic, nIndex )) != -1 )
     {
         sal_Unicode cMnemonic = rKey[ nIndex+1 ];
-        if ( cMnemonic != MNEMONIC_CHAR )
+        if ( cMnemonic != m_cMnemonic )
             return cMnemonic;
         nIndex += 2;
     }
@@ -187,7 +188,7 @@ OUString MnemonicGenerator::CreateMnemonic( const OUString& _rKey )
                 if ( maMnemonics[nMnemonicIndex] )
                 {
                     maMnemonics[nMnemonicIndex] = 0;
-                    rKey = rKey.replaceAt( nIndex, 0, OUString(MNEMONIC_CHAR) );
+                    rKey = rKey.replaceAt( nIndex, 0, OUString(m_cMnemonic) );
                     bChanged = true;
                     break;
                 }
@@ -239,7 +240,7 @@ OUString MnemonicGenerator::CreateMnemonic( const OUString& _rKey )
             if ( nBestCount != 0xFFFF )
             {
                 maMnemonics[nBestMnemonicIndex] = 0;
-                rKey = rKey.replaceAt( nBestIndex, 0, OUString(MNEMONIC_CHAR) );
+                rKey = rKey.replaceAt( nBestIndex, 0, OUString(m_cMnemonic) );
                 bChanged = true;
             }
         }
@@ -260,7 +261,7 @@ OUString MnemonicGenerator::CreateMnemonic( const OUString& _rKey )
                 {
                     maMnemonics[nMnemonicIndex] = 0;
                     OUString aStr = OUStringBuffer().
-                        append('(').append(MNEMONIC_CHAR).append(sal_Unicode(rtl::toAsciiUpperCase(c))).
+                        append('(').append(m_cMnemonic).append(sal_Unicode(rtl::toAsciiUpperCase(c))).
                         append(')').makeStringAndClear();
                     nIndex = rKey.getLength();
                     if( nIndex >= 2 )
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 957b58fcc083..9425d93fa63e 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -31,6 +31,7 @@
 #include <rtl/bootstrap.hxx>
 #include <tools/fract.hxx>
 #include <tools/stream.hxx>
+#include <vcl/mnemonic.hxx>
 #include <vcl/pngwrite.hxx>
 #include <vcl/weld.hxx>
 
@@ -2343,6 +2344,31 @@ public:
     }
 };
 
+namespace
+{
+    OUString get_label(GtkLabel* pLabel)
+    {
+        const gchar* pStr = gtk_label_get_label(pLabel);
+        return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+    }
+
+    void set_label(GtkLabel* pLabel, const OUString& rText)
+    {
+        gtk_label_set_label(pLabel, MapToGtkAccelerator(rText).getStr());
+    }
+
+    OUString get_label(GtkButton* pButton)
+    {
+        const gchar* pStr = gtk_button_get_label(pButton);
+        return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+    }
+
+    void set_label(GtkButton* pButton, const OUString& rText)
+    {
+        gtk_button_set_label(pButton, MapToGtkAccelerator(rText).getStr());
+    }
+}
+
 class GtkInstanceButton : public GtkInstanceContainer, public virtual weld::Button
 {
 private:
@@ -2367,13 +2393,12 @@ public:
 
     virtual void set_label(const OUString& rText) override
     {
-        gtk_button_set_label(m_pButton, MapToGtkAccelerator(rText).getStr());
+        ::set_label(m_pButton, rText);
     }
 
     virtual OUString get_label() const override
     {
-        const gchar* pStr = gtk_button_get_label(m_pButton);
-        return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+        return ::get_label(m_pButton);
     }
 
     virtual void clicked() override
@@ -3101,13 +3126,12 @@ public:
 
     virtual void set_label(const OUString& rText) override
     {
-        gtk_label_set_label(m_pLabel, MapToGtkAccelerator(rText).getStr());
+        ::set_label(m_pLabel, rText);
     }
 
     virtual OUString get_label() const override
     {
-        const char* pLabel = gtk_label_get_label(m_pLabel);
-        return OUString(pLabel, strlen(pLabel), RTL_TEXTENCODING_UTF8);
+        return ::get_label(m_pLabel);
     }
 };
 
@@ -3868,13 +3892,52 @@ namespace
 
         return false;
     }
+}
 
-    void postprocess(gpointer data, gpointer user_data)
+namespace
+{
+
+AtkObject* (*default_drawing_area_get_accessible)(GtkWidget *widget);
+
+AtkObject* drawing_area_get_accessibity(GtkWidget *pWidget)
+{
+    void* pData = g_object_get_data(G_OBJECT(pWidget), "g-lo-GtkInstanceDrawingArea");
+    GtkInstanceDrawingArea* pDrawingArea = static_cast<GtkInstanceDrawingArea*>(pData);
+    AtkObject *pAtkObj = pDrawingArea ? pDrawingArea->GetAtkObject() : nullptr;
+    if (pAtkObj)
+        return pAtkObj;
+    return default_drawing_area_get_accessible(pWidget);
+}
+
+void ensure_intercept_drawing_area_accessibility()
+{
+    static bool bDone;
+    if (!bDone)
+    {
+        gpointer pClass = g_type_class_ref(GTK_TYPE_DRAWING_AREA);
+        GtkWidgetClass* pWidgetClass = GTK_WIDGET_CLASS(pClass);
+        default_drawing_area_get_accessible = pWidgetClass->get_accessible;
+        pWidgetClass->get_accessible = drawing_area_get_accessibity;
+        g_type_class_unref(pClass);
+        bDone = true;
+    }
+}
+
+}
+
+class GtkInstanceBuilder : public weld::Builder
+{
+private:
+    OUString m_sHelpRoot;
+    OString m_aUtf8HelpRoot;
+    GtkBuilder* m_pBuilder;
+    GSList* m_pObjectList;
+    GtkWidget* m_pParentWidget;
+    std::vector<GtkButton*> m_aMnemonicButtons;
+    std::vector<GtkLabel*> m_aMnemonicLabels;
+
+    void postprocess_widget(GtkWidget* pWidget)
     {
-        GObject* pObject = static_cast<GObject*>(data);
-        if (!GTK_IS_WIDGET(pObject))
-            return;
-        OString* pHelpRoot = static_cast<OString*>(user_data);
         //fixup icons
         //wanted: better way to do this, e.g. make gtk use gio for
         //loading from a filename and provide gio protocol handler
@@ -3882,9 +3945,9 @@ namespace
         //
         //unpack the images and keep them as dirs and just
         //add the paths to the gtk icon theme dir
-        if (GTK_IS_IMAGE(pObject))
+        if (GTK_IS_IMAGE(pWidget))
         {
-            GtkImage* pImage = GTK_IMAGE(pObject);
+            GtkImage* pImage = GTK_IMAGE(pWidget);
             const gchar* icon_name;
             gtk_image_get_icon_name(pImage, &icon_name, nullptr);
             GtkIconSize size;
@@ -3909,61 +3972,41 @@ namespace
             }
         }
         //set helpids
-        GtkWidget* pWidget = GTK_WIDGET(pObject);
         const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pWidget));
         size_t nLen = pStr ? strlen(pStr) : 0;
         if (!nLen)
             return;
-        OString sHelpId = *pHelpRoot + OString(pStr, nLen);
+        OString sHelpId = m_aUtf8HelpRoot + OString(pStr, nLen);
         set_help_id(pWidget, sHelpId);
         //hook up for extended help
         const ImplSVData* pSVData = ImplGetSVData();
         if (pSVData->maHelpData.mbBalloonHelp && !GTK_IS_DIALOG(pWidget))
         {
             gtk_widget_set_has_tooltip(pWidget, true);
-            g_signal_connect(pObject, "query-tooltip", G_CALLBACK(signalTooltipQuery), nullptr);
+            g_signal_connect(pWidget, "query-tooltip", G_CALLBACK(signalTooltipQuery), nullptr);
         }
-    }
-}
 
-namespace
-{
-
-AtkObject* (*default_drawing_area_get_accessible)(GtkWidget *widget);
-
-AtkObject* drawing_area_get_accessibity(GtkWidget *pWidget)
-{
-    void* pData = g_object_get_data(G_OBJECT(pWidget), "g-lo-GtkInstanceDrawingArea");
-    GtkInstanceDrawingArea* pDrawingArea = static_cast<GtkInstanceDrawingArea*>(pData);
-    AtkObject *pAtkObj = pDrawingArea ? pDrawingArea->GetAtkObject() : nullptr;
-    if (pAtkObj)
-        return pAtkObj;
-    return default_drawing_area_get_accessible(pWidget);
-}
+        //missing mnemonics
+        if (GTK_IS_BUTTON(pWidget))
+        {
+            if (gtk_button_get_use_underline(GTK_BUTTON(pWidget)))
+                m_aMnemonicButtons.push_back(GTK_BUTTON(pWidget));
+        }
+        else if (GTK_IS_LABEL(pWidget))
+        {
+            if (gtk_label_get_use_underline(GTK_LABEL(pWidget)))
+                m_aMnemonicLabels.push_back(GTK_LABEL(pWidget));
+        }
+    }
 
-void ensure_intercept_drawing_area_accessibility()
-{
-    static bool bDone;
-    if (!bDone)
+    static void postprocess(gpointer data, gpointer user_data)
     {
-        gpointer pClass = g_type_class_ref(GTK_TYPE_DRAWING_AREA);
-        GtkWidgetClass* pWidgetClass = GTK_WIDGET_CLASS(pClass);
-        default_drawing_area_get_accessible = pWidgetClass->get_accessible;
-        pWidgetClass->get_accessible = drawing_area_get_accessibity;
-        g_type_class_unref(pClass);
-        bDone = true;
+        GObject* pObject = static_cast<GObject*>(data);
+        if (!GTK_IS_WIDGET(pObject))
+            return;
+        GtkInstanceBuilder* pThis = static_cast<GtkInstanceBuilder*>(user_data);
+        pThis->postprocess_widget(GTK_WIDGET(pObject));
     }
-}
-
-}
-
-class GtkInstanceBuilder : public weld::Builder
-{
-private:
-    OUString m_sHelpRoot;
-    GtkBuilder* m_pBuilder;
-    GSList* m_pObjectList;
-    GtkWidget* m_pParentWidget;
 public:
     GtkInstanceBuilder(GtkWidget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
         : weld::Builder(rUIFile)
@@ -3981,10 +4024,41 @@ public:
         if (nIdx != -1)
             m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
         m_sHelpRoot = m_sHelpRoot + OUString('/');
+        m_aUtf8HelpRoot = OUStringToOString(m_sHelpRoot, RTL_TEXTENCODING_UTF8);
 
         m_pObjectList = gtk_builder_get_objects(m_pBuilder);
-        OString aUtf8HelpRoot(OUStringToOString(m_sHelpRoot, RTL_TEXTENCODING_UTF8));
-        g_slist_foreach(m_pObjectList, postprocess, &aUtf8HelpRoot);
+        g_slist_foreach(m_pObjectList, postprocess, this);
+
+        GenerateMissingMnemonics();
+    }
+
+    void GenerateMissingMnemonics()
+    {
+        MnemonicGenerator aMnemonicGenerator('_');
+        for (const auto a : m_aMnemonicButtons)
+            aMnemonicGenerator.RegisterMnemonic(get_label(a));
+        for (const auto a : m_aMnemonicLabels)
+            aMnemonicGenerator.RegisterMnemonic(get_label(a));
+
+        for (const auto a : m_aMnemonicButtons)
+        {
+            OUString aLabel(get_label(a));
+            OUString aNewLabel = aMnemonicGenerator.CreateMnemonic(aLabel);
+            if (aLabel == aNewLabel)
+                continue;
+            set_label(a, aNewLabel);
+        }
+        for (const auto a : m_aMnemonicLabels)
+        {
+            OUString aLabel(get_label(a));
+            OUString aNewLabel = aMnemonicGenerator.CreateMnemonic(aLabel);
+            if (aLabel == aNewLabel)
+                continue;
+            set_label(a, aNewLabel);
+        }
+
+        m_aMnemonicLabels.clear();
+        m_aMnemonicButtons.clear();
     }
 
     virtual ~GtkInstanceBuilder() override


More information about the Libreoffice-commits mailing list