[Libreoffice-commits] .: Branch 'feature/unitymenus' - 2 commits - framework/source vcl/inc vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Aug 30 03:26:50 PDT 2012


 framework/source/uielement/menubarmanager.cxx |    2 
 vcl/inc/unx/gtk/gloactiongroup.h              |   26 -
 vcl/inc/unx/gtk/glomenu.h                     |   24 +
 vcl/inc/unx/gtk/gtksalmenu.hxx                |   12 
 vcl/unx/gtk/window/glomenu.cxx                |  124 ++++++-
 vcl/unx/gtk/window/gtksalmenu.cxx             |  427 ++++++++++++--------------
 6 files changed, 361 insertions(+), 254 deletions(-)

New commits:
commit e85105992eb73690914cf2a65de69becae3f7d87
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Wed Aug 29 14:41:01 2012 +0100

    New menu is now correctly displayed, but still have some problems.
    
    Change-Id: Ic69451bf9a4e5f63c4f0050b5967b8f2fc28d7cb

diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 236bab6..5525b19 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -85,6 +85,10 @@ public:
     virtual GtkSalMenuItem*     GetItemAtPos( unsigned nPos ) { return maItems[ nPos ]; }
     virtual void                SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; }
     virtual GActionGroup*       GetActionGroup() { return mpActionGroup; }
+
+    virtual void                SetNativeItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText );
+    virtual void                SetNativeItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommandStr );
+    virtual void                SetNativeEnableItem( gchar* aCommand, gboolean bEnable );
 };
 
 class GtkSalMenuItem : public SalMenuItem
diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx
index 962e84f..657d0c2 100644
--- a/vcl/unx/gtk/window/glomenu.cxx
+++ b/vcl/unx/gtk/window/glomenu.cxx
@@ -488,6 +488,9 @@ g_lo_menu_set_submenu_to_item_in_section (GLOMenu    *menu,
     g_return_if_fail (model != NULL);
 
     g_lo_menu_set_link (model, position, G_MENU_LINK_SUBMENU, submenu);
+
+    // Notify the update.
+    g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1);
 }
 
 GLOMenu *
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 789547a..4f6dda2 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -92,7 +92,8 @@ using namespace std;
 //    }
 //}
 
-static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
+static void UpdateNativeMenu( GtkSalMenu* pMenu )
+{
     if ( pMenu == NULL )
         return;
 
@@ -119,7 +120,8 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
             nSection++;
             nItemPos = 0;
 
-            if ( nLOMenuSize <= nSection ) {
+            if ( nLOMenuSize <= nSection )
+            {
                 g_lo_menu_new_section( pLOMenu, nSection, NULL );
                 nLOMenuSize++;
             }
@@ -130,34 +132,49 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
         if ( nItemPos >= g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) )
             g_lo_menu_insert_in_section( pLOMenu, nSection, nItemPos, "EMPTY STRING" );
 
+        // Get internal menu item values.
         String aText = pVCLMenu->GetItemText( nId );
-        String aCommand = pVCLMenu->GetItemCommand( nId );
+        rtl::OUString aCommand( pVCLMenu->GetItemCommand( nId ) );
         sal_Bool itemEnabled = pVCLMenu->IsItemEnabled( nId );
         KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId );
         sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId );
 
+        // Convert internal values to native values.
+        gboolean bChecked = ( itemChecked == sal_True ) ? TRUE : FALSE;
+        gboolean bEnabled = ( itemEnabled == sal_True ) ? TRUE : FALSE;
+        gchar* aNativeCommand = g_strdup( rtl::OUStringToOString( aCommand, RTL_TEXTENCODING_UTF8 ).getStr() );
+
         // Force updating of native menu labels.
-        pMenu->SetItemCommand( nItem, pSalMenuItem, aCommand );
-        pMenu->SetItemText( nItem, pSalMenuItem, aText );
-        pMenu->EnableItem( nItem, itemEnabled );
+        pMenu->SetNativeItemText( nSection, nItemPos, aText );
         pMenu->SetAccelerator( nItem, pSalMenuItem, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
-        pMenu->CheckItem( nItem, itemChecked );
+
+        if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpVCLMenu->GetPopupMenu( nId ) == NULL )
+        {
+            pMenu->SetNativeItemCommand( nSection, nItemPos, pSalMenuItem, aNativeCommand );
+            pMenu->SetNativeEnableItem( aNativeCommand, bEnabled );
+//            pMenu->CheckItem( nItem, itemChecked );
+        }
+
+        g_free( aNativeCommand );
 
         GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
 
-        if ( pSubmenu && pSubmenu->GetMenu() ) {
+        if ( pSubmenu && pSubmenu->GetMenu() )
+        {
             GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos );
 
-            if ( pSubMenuModel == NULL ) {
+            if ( pSubMenuModel == NULL )
+            {
                 pSubMenuModel = g_lo_menu_new();
                 g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) );
             }
 
+            pSubmenu->GetMenu()->Activate();
+
             pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
             pSubmenu->SetActionGroup( pActionGroup );
-
-            pSubmenu->GetMenu()->Activate();
             UpdateNativeMenu( pSubmenu );
+
             pSubmenu->GetMenu()->Deactivate();
         }
 
@@ -166,7 +183,8 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
     }
 }
 
-gboolean GenerateMenu(gpointer user_data) {
+gboolean GenerateMenu(gpointer user_data)
+{
     GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data );
 
     UpdateNativeMenu( pSalMenu );
@@ -174,7 +192,8 @@ gboolean GenerateMenu(gpointer user_data) {
     return TRUE;
 }
 
-void ObjectDestroyedNotify( gpointer data ) {
+void ObjectDestroyedNotify( gpointer data )
+{
     if ( data ) {
         g_object_unref( data );
     }
@@ -208,16 +227,6 @@ gdk_x11_window_set_utf8_property  (GdkWindow *window,
     }
 }
 
-GActionGroup* GetActionGroupFromMenubar( GtkSalMenu *pMenu )
-{
-    GtkSalMenu *pSalMenu = pMenu;
-
-    while ( pSalMenu && pSalMenu->GetParentSalMenu() )
-        pSalMenu = pSalMenu->GetParentSalMenu();
-
-    return ( pSalMenu ) ? pSalMenu->GetActionGroup() : NULL;
-}
-
 // FIXME: Check for missing keys. Maybe translating keycodes would be safer...
 rtl::OUString GetGtkKeyName( rtl::OUString keyName )
 {
@@ -290,45 +299,6 @@ rtl::OUString GetGtkKeyName( rtl::OUString keyName )
  * GtkSalMenu
  */
 
-sal_Int32 GtkSalMenu::GetPositionFromItem( GtkSalMenuItem* pSalMenuItem )
-{
-    for ( sal_uInt16 i = 0; i < maItems.size(); i++ )
-    {
-        GtkSalMenuItem* pItem = maItems[ i ];
-
-        if ( pSalMenuItem->mnId == pItem->mnId && pSalMenuItem->mnType == pItem->mnType )
-            return i;
-    }
-
-    return -1;
-}
-
-// FIXME: Iterating through the whole list everytime is slow, but works. Some fine tuning would be required here...
-void GtkSalMenu::GetItemSectionAndPosition( unsigned nPos, unsigned *insertSection, unsigned *insertPos )
-{
-    if ( mpVCLMenu == NULL || nPos >= mpVCLMenu->GetItemCount() )
-    {
-        *insertSection = g_menu_model_get_n_items( mpMenuModel ) - 1;
-        *insertPos = MENU_APPEND;
-    }
-    else
-    {
-        unsigned nItem;
-        gint nItemPos;
-
-        for ( nItem = 0, *insertSection = 0, nItemPos = -1; nItem <= nPos; nItem++ )
-        {
-            if ( mpVCLMenu->GetItemType( nItem ) == MENUITEM_SEPARATOR ) {
-                (*insertSection)++;
-                nItemPos = -1;
-            } else
-                nItemPos++;
-        }
-
-        *insertPos = nItemPos;
-    }
-}
-
 GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
     mbMenuBar( bMenuBar ),
     mpVCLMenu( NULL ),
@@ -337,25 +307,21 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
     mpMenuModel( NULL ),
     mpActionGroup( NULL )
 {
-    cout << this << " - " << __FUNCTION__ << endl;
-//    mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
-//    g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), 0, NULL);
 }
 
 GtkSalMenu::~GtkSalMenu()
 {
-    cout << this << " - " << __FUNCTION__ << endl;
+    if ( mbMenuBar == sal_True ) {
+        g_source_remove_by_user_data( this );
 
-//    if ( mpActionGroup ) {
-//        g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) );
-//    }
+        if ( mpActionGroup ) {
+            g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) );
+        }
 
-//    if ( mbMenuBar ) {
-//        g_source_remove_by_user_data( this );
-//        g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 );
-//    } else {
-//        g_object_unref( mpMenuModel );
-//    }
+        if ( mpMenuModel ) {
+            g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 );
+        }
+    }
 
     maItems.clear();
 }
@@ -367,7 +333,6 @@ sal_Bool GtkSalMenu::VisibleMenuBar()
 
 void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
 {
-    cout << this << " - " << __FUNCTION__ << endl;
     GtkSalMenuItem *pItem = static_cast<GtkSalMenuItem*>( pSalMenuItem );
 
     if ( nPos == MENU_APPEND )
@@ -376,53 +341,10 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
         maItems.insert( maItems.begin() + nPos, pItem );
 
     pItem->mpParentMenu = this;
-
-//    if ( pItem->mnType != MENUITEM_SEPARATOR )
-//    {
-//        unsigned nInsertSection, nInsertPos;
-//        GetItemSectionAndPosition( nPos, &nInsertSection, &nInsertPos );
-
-//        //            g_lo_menu_insert_in_section( G_LO_MENU( mpMenuModel ), nInsertSection, nInsertPos, "EMPTY STRING" );
-//    }
-//    else
-//    {
-//        //            g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), MENU_APPEND, NULL );
-//    }
 }
 
 void GtkSalMenu::RemoveItem( unsigned nPos )
 {
-    cout << this << " - " << __FUNCTION__ << endl;
-//    GLOMenu* pMenu = G_LO_MENU( mpMenuModel );
-//    GtkSalMenuItem *pItem = maItems[ nPos ];
-
-    // If item is a separator, the last section of the menu is removed.
-//    if ( pItem->mnType != MENUITEM_SEPARATOR )
-//    {
-//        unsigned nSection, nItemPos;
-//        GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
-
-//        gchar* aCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos );
-
-//        if ( aCommand ) {
-//            GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
-
-//            if ( pActionGroup != NULL )
-//                g_lo_action_group_remove( pActionGroup, aCommand );
-
-//            g_free( aCommand );
-//        }
-
-//        g_lo_menu_remove_from_section( pMenu, nSection, nItemPos );
-//    }
-//    else
-//    {
-//        gint nSection = g_menu_model_get_n_items( mpMenuModel ) - 1;
-
-//        if ( nSection > 0 )
-//            g_lo_menu_remove( pMenu, nSection );
-//    }
-
     maItems.erase( maItems.begin() + nPos );
 }
 
@@ -434,16 +356,8 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig
     if ( pGtkSubMenu == NULL )
         return;
 
-    cout << this << " - " << __FUNCTION__ << " - " << nPos << " - " << pSubMenu << endl;
-
     pGtkSubMenu->mpParentSalMenu = this;
     pItem->mpSubMenu = pGtkSubMenu;
-
-    // Update item in GMenuModel.
-    unsigned nSection, nItemPos;
-    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
-
-    g_lo_menu_set_submenu_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, pGtkSubMenu->mpMenuModel );
 }
 
 void GtkSalMenu::SetFrame( const SalFrame* pFrame )
@@ -500,12 +414,14 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
         }
 
         // Menubar has only one section, so we put it on the exported menu.
-        //        g_lo_menu_insert_section( pMainMenu, 0, NULL, mpMenuModel );
-        mpMenuModel = G_MENU_MODEL( pMainMenu );
+//        mpMenuModel = G_MENU_MODEL( pMainMenu );
+        mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
+        g_lo_menu_insert_section( pMainMenu, 0, NULL, mpMenuModel );
+//        g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), 0, NULL );
         mpActionGroup = G_ACTION_GROUP( pActionGroup );
 
-//        UpdateNativeMenu( this );
-//        UpdateNativeMenu( this );
+//        GenerateMenu( this );
+//        GenerateMenu( this );
 
         // Refresh the menu every second.
         // This code is a workaround until required modifications in Gtk+ are available.
@@ -574,43 +490,34 @@ void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
 
 void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
 {
-//    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
-
-//    if ( pActionGroup == NULL )
-//        return;
-
-//    sal_uInt16 nId = mpVCLMenu->GetItemId( nPos );
-//    rtl::OUString aOUCommand = mpVCLMenu->GetItemCommand( nId );
-
-//    if ( aOUCommand == NULL || aOUCommand.isEmpty() )
-//        return;
-
-//    gchar* aCommand = (gchar*) rtl::OUStringToOString( aOUCommand, RTL_TEXTENCODING_UTF8 ).getStr();
+}
 
-//    gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE;
+void GtkSalMenu::SetNativeEnableItem( gchar* aCommand, gboolean bEnable )
+{
+    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup );
 
-//    if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bItemEnabled )
-//        g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bItemEnabled );
+    if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bEnable )
+        g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bEnable );
 }
 
 void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText )
 {
-    cout << this << " - " << __FUNCTION__ << endl;
-//    // Replace the "~" character with "_".
-//    rtl::OUString aText = rText.replace( '~', '_' );
-//    rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 );
+}
 
-//    unsigned nSection, nItemPos;
-//    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
+void GtkSalMenu::SetNativeItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText )
+{
+    // Replace the "~" character with "_".
+    rtl::OUString aText = rText.replace( '~', '_' );
+    rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 );
 
-//    // Update item text only when necessary.
-//    gchar* aLabel = g_lo_menu_get_label_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos );
+    // Update item text only when necessary.
+    gchar* aLabel = g_lo_menu_get_label_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos );
 
-//    if ( aLabel == NULL || g_strcmp0( aLabel, aConvertedText.getStr() ) != 0 )
-//        g_lo_menu_set_label_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aConvertedText.getStr() );
+    if ( aLabel == NULL || g_strcmp0( aLabel, aConvertedText.getStr() ) != 0 )
+        g_lo_menu_set_label_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aConvertedText.getStr() );
 
-//    if ( aLabel )
-//        g_free( aLabel );
+    if ( aLabel )
+        g_free( aLabel );
 }
 
 void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage)
@@ -619,7 +526,6 @@ void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const I
 
 void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName )
 {
-    cout << this << " - " << __FUNCTION__ << endl;
 //    if ( rKeyName.isEmpty() )
 //        return;
 
@@ -639,75 +545,65 @@ void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const
 
 void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr )
 {
-    cout << this << " - " << __FUNCTION__ << endl;
-//    GtkSalMenuItem* pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
-
-//    if ( pItem->mnType == MENUITEM_SEPARATOR ||
-//         pItem->mpVCLMenu->GetPopupMenu( pItem->mnId ) != NULL ||
-//         aCommandStr.isEmpty() )
-//        return;
-
-//    gchar* aCommand = (gchar*) rtl::OUStringToOString( aCommandStr, RTL_TEXTENCODING_UTF8 ).getStr();
-
-//    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
-//    if ( pActionGroup == NULL )
-//        return;
+}
 
-//    GVariant *pTarget = NULL;
+void GtkSalMenu::SetNativeItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommand )
+{
+    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup );
 
-//    if ( g_action_group_has_action( G_ACTION_GROUP( pActionGroup ), aCommand ) == FALSE ) {
-//        gboolean bChecked = ( pItem->mpVCLMenu->IsItemChecked( pItem->mnId ) ) ? TRUE : FALSE;
+    GVariant *pTarget = NULL;
 
-//        // FIXME: Why pItem->mnBits differs from GetItemBits value?
-//        MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
+    if ( g_action_group_has_action( mpActionGroup, aCommand ) == FALSE ) {
+        gboolean bChecked = ( pItem->mpVCLMenu->IsItemChecked( pItem->mnId ) ) ? TRUE : FALSE;
 
-//        if ( bits & MIB_CHECKABLE )
-//        {
-//            // Item is a checkmark button.
-//            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
-//            GVariant* pState = g_variant_new_boolean( bChecked );
+        // FIXME: Why pItem->mnBits differs from GetItemBits value?
+        MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
 
-//            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, NULL, pStateType, NULL, pState );
-//        }
-//        else if ( bits & MIB_RADIOCHECK )
-//        {
-//            // Item is a radio button.
-//            GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
-//            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
-//            //        GVariant* pStateHint = GetRadioButtonHints( pItem );
-//            GVariant* pState = g_variant_new_string( "" );
-//            pTarget = g_variant_new_string( aCommand );
-
-//            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState );
-//        }
-//        else
-//        {
-//            // Item is not special, so insert a stateless action.
-//            g_lo_action_group_insert( pActionGroup, aCommand, pItem );
-//        }
-//    }
+        if ( bits & MIB_CHECKABLE )
+        {
+            // Item is a checkmark button.
+            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
+            GVariant* pState = g_variant_new_boolean( bChecked );
 
-//    GLOMenu* pMenu = G_LO_MENU( mpMenuModel );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, NULL, pStateType, NULL, pState );
+        }
+        else if ( bits & MIB_RADIOCHECK )
+        {
+            // Item is a radio button.
+            GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
+            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
+            //        GVariant* pStateHint = GetRadioButtonHints( pItem );
+            GVariant* pState = g_variant_new_string( "" );
+            pTarget = g_variant_new_string( aCommand );
+
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState );
+        }
+        else
+        {
+            // Item is not special, so insert a stateless action.
+            g_lo_action_group_insert( pActionGroup, aCommand, pItem );
+        }
+    }
 
-//    // Menu item is not updated unless it's necessary.
-//    unsigned nSection, nItemPos;
-//    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
+    GLOMenu* pMenu = G_LO_MENU( mpMenuModel );
 
-//    gchar* aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos );
+    // Menu item is not updated unless it's necessary.
+    gchar* aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos );
 
-//    if ( aCurrentCommand == NULL || g_strcmp0( aCurrentCommand, aCommand ) != 0 )
-//    {
-//        g_lo_menu_set_accelerator_to_item_in_section( pMenu, nSection, nItemPos, aCommand );
+    if ( aCurrentCommand == NULL || g_strcmp0( aCurrentCommand, aCommand ) != 0 )
+    {
+        cout << __FUNCTION__ << endl;
+        g_lo_menu_set_command_to_item_in_section( pMenu, nSection, nItemPos, aCommand );
 
-//        gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
+        gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
 
-//        g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
+        g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
 
-//        g_free( aItemCommand );
-//    }
+        g_free( aItemCommand );
+    }
 
-//    if ( aCurrentCommand )
-//        g_free( aCurrentCommand );
+    if ( aCurrentCommand )
+        g_free( aCurrentCommand );
 }
 
 void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
commit 5282906c0ad5b902af9633f2f71525262a7467ee
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Tue Aug 28 18:36:26 2012 +0100

    Menu is now generated in one step. DBus traffic improvements.
    
    Change-Id: I67e2b804fb0b7af854f695b1a0c7e8354fe91d0b

diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
index 6f19829..7d4b8d9 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -1006,7 +1006,7 @@ IMPL_LINK( MenuBarManager, Activate, AbstractMenu *, pMenu )
     }
 
     // Freeze the menu
-//    m_pVCLMenu->Freeze();
+    m_pVCLMenu->Freeze();
 
     return 1;
 }
diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h
index 4392e18..f01aa4a 100644
--- a/vcl/inc/unx/gtk/gloactiongroup.h
+++ b/vcl/inc/unx/gtk/gloactiongroup.h
@@ -65,9 +65,9 @@ GType               g_lo_action_group_get_type              (void) G_GNUC_CONST;
 
 GLOActionGroup *    g_lo_action_group_new                   (void);
 
-void                g_lo_action_group_insert                (GLOActionGroup *group,
-                                                             const gchar    *action_name,
-                                                             gpointer        action_info);
+void                g_lo_action_group_insert                (GLOActionGroup     *group,
+                                                             const gchar        *action_name,
+                                                             gpointer            action_info);
 
 void                g_lo_action_group_insert_stateful       (GLOActionGroup     *group,
                                                              const gchar        *action_name,
@@ -77,20 +77,20 @@ void                g_lo_action_group_insert_stateful       (GLOActionGroup
                                                              GVariant           *state_hint,
                                                              GVariant           *state);
 
-void                g_lo_action_group_set_action_enabled    (GLOActionGroup *group,
-                                                             const gchar    *action_name,
-                                                             gboolean        enabled);
+void                g_lo_action_group_set_action_enabled    (GLOActionGroup     *group,
+                                                             const gchar        *action_name,
+                                                             gboolean           enabled);
 
-gpointer            g_lo_action_group_get_action_item       (GLOActionGroup *group,
-                                                             const gchar    *action_name);
+gpointer            g_lo_action_group_get_action_item       (GLOActionGroup     *group,
+                                                             const gchar        *action_name);
 
-void                g_lo_action_group_remove                (GLOActionGroup *group,
-                                                             const gchar    *action_name);
+void                g_lo_action_group_remove                (GLOActionGroup     *group,
+                                                             const gchar        *action_name);
 
-void                g_lo_action_group_clear                 (GLOActionGroup *group);
+void                g_lo_action_group_clear                 (GLOActionGroup     *group);
 
-void                g_lo_action_group_merge                 (GLOActionGroup *input_group,
-                                                             GLOActionGroup *output_group);
+void                g_lo_action_group_merge                 (GLOActionGroup     *input_group,
+                                                             GLOActionGroup     *output_group);
 
 G_END_DECLS
 
diff --git a/vcl/inc/unx/gtk/glomenu.h b/vcl/inc/unx/gtk/glomenu.h
index 21c048f..c45be50 100644
--- a/vcl/inc/unx/gtk/glomenu.h
+++ b/vcl/inc/unx/gtk/glomenu.h
@@ -27,6 +27,7 @@
 #include <gio/gio.h>
 
 #define G_LO_MENU_ATTRIBUTE_ACCELERATOR     "accel"
+#define G_LO_MENU_ATTRIBUTE_COMMAND         "command"
 
 G_BEGIN_DECLS
 
@@ -45,6 +46,9 @@ GType       g_lo_menu_get_type                                          (void) G
 GLIB_AVAILABLE_IN_2_32
 GLOMenu *   g_lo_menu_new                                               (void);
 
+gint       g_lo_menu_get_n_items_from_section                           (GLOMenu     *menu,
+                                                                         gint         section);
+
 void        g_lo_menu_insert                                            (GLOMenu     *menu,
                                                                          gint         position,
                                                                          const char  *label);
@@ -97,16 +101,36 @@ void        g_lo_menu_set_action_and_target_value_to_item_in_section    (GLOMenu
                                                                          const gchar *command,
                                                                          GVariant    *target_value);
 
+void        g_lo_menu_set_command_to_item_in_section                    (GLOMenu     *menu,
+                                                                         gint         section,
+                                                                         gint         position,
+                                                                         const gchar *command);
+
+gchar *     g_lo_menu_get_command_from_item_in_section                  (GLOMenu     *menu,
+                                                                         gint         section,
+                                                                         gint         position);
+
 void        g_lo_menu_set_accelerator_to_item_in_section                (GLOMenu     *menu,
                                                                          gint         section,
                                                                          gint         position,
                                                                          const gchar *accelerator);
 
+gchar *     g_lo_menu_get_accelerator_from_item_in_section              (GLOMenu     *menu,
+                                                                         gint         section,
+                                                                         gint         position);
+
 void        g_lo_menu_set_submenu_to_item_in_section                    (GLOMenu     *menu,
                                                                          gint         section,
                                                                          gint         position,
                                                                          GMenuModel  *submenu);
 
+GLOMenu *   g_lo_menu_get_submenu_from_item_in_section                  (GLOMenu     *menu,
+                                                                         gint         section,
+                                                                         gint         position);
+
+GLOMenu *   g_lo_menu_get_menu_containing_item                          (GLOMenu     *menu,
+                                                                         gint         item_id);
+
 G_END_DECLS
 
 #endif /* __G_LO_MENU_H__ */
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 324b430..236bab6 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -52,6 +52,7 @@ private:
     GMenuModel*                     mpMenuModel;
     GActionGroup*                   mpActionGroup;
 
+    sal_Int32       GetPositionFromItem( GtkSalMenuItem* pSalMenuItem );
     void            GetItemSectionAndPosition( unsigned nPos, unsigned *insertSection, unsigned *insertPos );
 
 public:
@@ -78,9 +79,11 @@ public:
     virtual void                SetMenu( Menu* pMenu ) { mpVCLMenu = pMenu; }
     virtual Menu*               GetMenu() { return mpVCLMenu; }
     virtual GtkSalMenu*         GetParentSalMenu() { return mpParentSalMenu; }
+    virtual void                SetMenuModel( GMenuModel* pMenuModel ) { mpMenuModel = pMenuModel; }
     virtual GMenuModel*         GetMenuModel() { return mpMenuModel; }
     virtual unsigned            GetItemCount() { return maItems.size(); }
     virtual GtkSalMenuItem*     GetItemAtPos( unsigned nPos ) { return maItems[ nPos ]; }
+    virtual void                SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; }
     virtual GActionGroup*       GetActionGroup() { return mpActionGroup; }
 };
 
@@ -96,11 +99,6 @@ public:
     Menu*               mpVCLMenu;          // VCL Menu into which this MenuItem is inserted
     GtkSalMenu*         mpParentMenu;       // The menu in which this menu item is inserted
     GtkSalMenu*         mpSubMenu;          // Sub menu of this item (if defined)
-
-    // FIXME: Most of this info should be retrieved from the GMenuModel, but doing that crashes the application at the moment.
-    gchar*              maCommand;          // Item command
-    gchar*              maLabel;            // Item label
-    gchar*              maAccel;            // Item accelerator
 };
 
 #endif // GTKSALMENU_HXX
diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx
index 77be471..962e84f 100644
--- a/vcl/unx/gtk/window/glomenu.cxx
+++ b/vcl/unx/gtk/window/glomenu.cxx
@@ -107,6 +107,16 @@ g_lo_menu_get_n_items (GMenuModel *model)
     return menu->items->len;
 }
 
+gint
+g_lo_menu_get_n_items_from_section (GLOMenu     *menu,
+                                    gint         section)
+{
+    GLOMenu *model = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                                ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION));
+
+    return model->items->len;
+}
+
 static void
 g_lo_menu_get_item_attributes (GMenuModel  *model,
                                gint         position,
@@ -236,19 +246,18 @@ g_lo_menu_get_label_from_item_in_section (GLOMenu     *menu,
 {
     g_return_val_if_fail (G_IS_LO_MENU (menu), NULL);
 
-    GLOMenu *model = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
-                                ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION));
+    GMenuModel *model = G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                        ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION);
 
     g_return_val_if_fail (model != NULL, NULL);
 
-    struct item menu_item = g_array_index (model->items, struct item, position);
-
-
-
-    GVariant *current_label = (GVariant*) g_hash_table_lookup (menu_item.attributes, G_MENU_ATTRIBUTE_LABEL);
+    GVariant *current_label = g_menu_model_get_item_attribute_value (G_MENU_MODEL(model),
+                                                                     position,
+                                                                     G_MENU_ATTRIBUTE_LABEL,
+                                                                     G_VARIANT_TYPE_STRING);
 
     if (current_label)
-        return (gchar*) g_variant_get_string (current_label, NULL);
+        return g_strdup (g_variant_get_string (current_label, NULL));
     else
         return NULL;
 }
@@ -318,12 +327,84 @@ g_lo_menu_set_accelerator_to_item_in_section (GLOMenu     *menu,
     else
         value = NULL;
 
-    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, "accel", value);
+    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_ACCELERATOR, value);
+
+    // Notify the update.
+    g_menu_model_items_changed (model, position, 1, 1);
+}
+
+gchar *
+g_lo_menu_get_accelerator_from_item_in_section (GLOMenu     *menu,
+                                                gint         section,
+                                                gint         position)
+{
+    g_return_val_if_fail (G_IS_LO_MENU (menu), NULL);
+
+    GMenuModel *model = G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                        ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION);
+
+    g_return_val_if_fail (model != NULL, NULL);
+
+    GVariant *current_accel = g_menu_model_get_item_attribute_value (model,
+                                                                     position,
+                                                                     G_LO_MENU_ATTRIBUTE_ACCELERATOR,
+                                                                     G_VARIANT_TYPE_STRING);
+
+    if (current_accel)
+        return g_strdup (g_variant_get_string (current_accel, NULL));
+    else
+        return NULL;
+}
+
+void
+g_lo_menu_set_command_to_item_in_section (GLOMenu     *menu,
+                                          gint         section,
+                                          gint         position,
+                                          const gchar *command)
+{
+    g_return_if_fail (G_IS_LO_MENU (menu));
+
+    GMenuModel *model = G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                        ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION);
+
+    g_return_if_fail (model != NULL);
+
+    GVariant *value;
+
+    if (command != NULL)
+        value = g_variant_new_string (command);
+    else
+        value = NULL;
+
+    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_COMMAND, value);
 
     // Notify the update.
     g_menu_model_items_changed (model, position, 1, 1);
 }
 
+gchar *
+g_lo_menu_get_command_from_item_in_section (GLOMenu     *menu,
+                                            gint         section,
+                                            gint         position)
+{
+    g_return_val_if_fail (G_IS_LO_MENU (menu), NULL);
+
+    GMenuModel *model = G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                        ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION);
+
+    g_return_val_if_fail (model != NULL, NULL);
+
+    GVariant *command = g_menu_model_get_item_attribute_value (model,
+                                                               position,
+                                                               G_LO_MENU_ATTRIBUTE_COMMAND,
+                                                               G_VARIANT_TYPE_STRING);
+
+    if (command)
+        return g_strdup (g_variant_get_string (command, NULL));
+    else
+        return NULL;
+}
+
 void
 g_lo_menu_set_link (GLOMenu     *menu,
                     gint         position,
@@ -398,7 +479,6 @@ g_lo_menu_set_submenu_to_item_in_section (GLOMenu    *menu,
                                           gint        position,
                                           GMenuModel *submenu)
 {
-//    puts(__FUNCTION__);
     g_return_if_fail (G_IS_LO_MENU (menu));
     g_return_if_fail (0 <= section && section < (gint) menu->items->len);
 
@@ -410,6 +490,27 @@ g_lo_menu_set_submenu_to_item_in_section (GLOMenu    *menu,
     g_lo_menu_set_link (model, position, G_MENU_LINK_SUBMENU, submenu);
 }
 
+GLOMenu *
+g_lo_menu_get_submenu_from_item_in_section (GLOMenu     *menu,
+                                            gint         section,
+                                            gint         position)
+{
+    g_return_val_if_fail (G_IS_LO_MENU (menu), NULL);
+    g_return_val_if_fail (0 <= section && section < (gint) menu->items->len, NULL);
+
+    GLOMenu *model = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                                ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION));
+
+    g_return_val_if_fail (model != NULL, NULL);
+
+    GMenuModel *submenu = NULL;
+
+    if (0 <= position && position < (gint) model->items->len)
+        submenu = g_menu_model_get_item_link (G_MENU_MODEL (model), position, G_MENU_LINK_SUBMENU);
+
+    return G_LO_MENU (submenu);
+}
+
 static void
 g_lo_menu_clear_item (struct item *menu_item)
 {
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 712f868..789547a 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -56,18 +56,79 @@ using namespace std;
 //    return FALSE;
 //}
 
+//static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
+//    if ( pMenu == NULL )
+//        return;
+
+//    Menu* pVCLMenu = pMenu->GetMenu();
+
+//    for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) {
+//        GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( i );
+//        sal_uInt16 nId = pSalMenuItem->mnId;
+
+//        if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR )
+//            continue;
+
+//        String aText = pVCLMenu->GetItemText( nId );
+//        String aCommand = pVCLMenu->GetItemCommand( nId );
+//        sal_Bool itemEnabled = pVCLMenu->IsItemEnabled( nId );
+//        KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId );
+//        sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId );
+
+//        // Force updating of native menu labels.
+//        pMenu->SetItemCommand( i, pSalMenuItem, aCommand );
+//        pMenu->SetItemText( i, pSalMenuItem, aText );
+//        pMenu->EnableItem( i, itemEnabled );
+//        pMenu->SetAccelerator( i, pSalMenuItem, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
+//        pMenu->CheckItem( i, itemChecked );
+
+//        GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
+
+//        if ( pSubmenu && pSubmenu->GetMenu() ) {
+//            pSubmenu->GetMenu()->Activate();
+//            pSubmenu->GetMenu()->Deactivate();
+//            UpdateNativeMenu( pSubmenu );
+//        }
+//    }
+//}
+
 static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
     if ( pMenu == NULL )
         return;
 
     Menu* pVCLMenu = pMenu->GetMenu();
+    GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() );
+    GActionGroup* pActionGroup = pMenu->GetActionGroup();
+
+    sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) );
+
+    if ( nLOMenuSize == 0 )
+        g_lo_menu_new_section( pLOMenu, 0, NULL );
+
+    sal_uInt16 nSection = 0;
+    sal_uInt16 nItemPos = 0;
+    sal_uInt16 validItems = 0;
+    sal_uInt16 nItem;
 
-    for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) {
-        GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( i );
+    for ( nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) {
+        GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem );
         sal_uInt16 nId = pSalMenuItem->mnId;
 
         if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR )
+        {
+            nSection++;
+            nItemPos = 0;
+
+            if ( nLOMenuSize <= nSection ) {
+                g_lo_menu_new_section( pLOMenu, nSection, NULL );
+                nLOMenuSize++;
+            }
+
             continue;
+        }
+
+        if ( nItemPos >= g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) )
+            g_lo_menu_insert_in_section( pLOMenu, nSection, nItemPos, "EMPTY STRING" );
 
         String aText = pVCLMenu->GetItemText( nId );
         String aCommand = pVCLMenu->GetItemCommand( nId );
@@ -76,19 +137,32 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) {
         sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId );
 
         // Force updating of native menu labels.
-        pMenu->SetItemCommand( i, pSalMenuItem, aCommand );
-        pMenu->SetItemText( i, pSalMenuItem, aText );
-        pMenu->EnableItem( i, itemEnabled );
-        pMenu->SetAccelerator( i, pSalMenuItem, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
-        pMenu->CheckItem( i, itemChecked );
+        pMenu->SetItemCommand( nItem, pSalMenuItem, aCommand );
+        pMenu->SetItemText( nItem, pSalMenuItem, aText );
+        pMenu->EnableItem( nItem, itemEnabled );
+        pMenu->SetAccelerator( nItem, pSalMenuItem, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
+        pMenu->CheckItem( nItem, itemChecked );
 
         GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
 
         if ( pSubmenu && pSubmenu->GetMenu() ) {
+            GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos );
+
+            if ( pSubMenuModel == NULL ) {
+                pSubMenuModel = g_lo_menu_new();
+                g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) );
+            }
+
+            pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
+            pSubmenu->SetActionGroup( pActionGroup );
+
             pSubmenu->GetMenu()->Activate();
-            pSubmenu->GetMenu()->Deactivate();
             UpdateNativeMenu( pSubmenu );
+            pSubmenu->GetMenu()->Deactivate();
         }
+
+        nItemPos++;
+        validItems++;
     }
 }
 
@@ -216,6 +290,19 @@ rtl::OUString GetGtkKeyName( rtl::OUString keyName )
  * GtkSalMenu
  */
 
+sal_Int32 GtkSalMenu::GetPositionFromItem( GtkSalMenuItem* pSalMenuItem )
+{
+    for ( sal_uInt16 i = 0; i < maItems.size(); i++ )
+    {
+        GtkSalMenuItem* pItem = maItems[ i ];
+
+        if ( pSalMenuItem->mnId == pItem->mnId && pSalMenuItem->mnType == pItem->mnType )
+            return i;
+    }
+
+    return -1;
+}
+
 // FIXME: Iterating through the whole list everytime is slow, but works. Some fine tuning would be required here...
 void GtkSalMenu::GetItemSectionAndPosition( unsigned nPos, unsigned *insertSection, unsigned *insertPos )
 {
@@ -250,33 +337,37 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
     mpMenuModel( NULL ),
     mpActionGroup( NULL )
 {
-    mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
-    g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), 0, NULL);
+    cout << this << " - " << __FUNCTION__ << endl;
+//    mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
+//    g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), 0, NULL);
 }
 
 GtkSalMenu::~GtkSalMenu()
 {
-    if ( mpActionGroup ) {
-        g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) );
-    }
+    cout << this << " - " << __FUNCTION__ << endl;
 
-    if ( mbMenuBar ) {
-        g_source_remove_by_user_data( this );
-        g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 );
-    } else {
-        g_object_unref( mpMenuModel );
-    }
+//    if ( mpActionGroup ) {
+//        g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) );
+//    }
+
+//    if ( mbMenuBar ) {
+//        g_source_remove_by_user_data( this );
+//        g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 );
+//    } else {
+//        g_object_unref( mpMenuModel );
+//    }
 
     maItems.clear();
 }
 
 sal_Bool GtkSalMenu::VisibleMenuBar()
 {
-    return sal_True;
+    return sal_False;
 }
 
 void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
 {
+    cout << this << " - " << __FUNCTION__ << endl;
     GtkSalMenuItem *pItem = static_cast<GtkSalMenuItem*>( pSalMenuItem );
 
     if ( nPos == MENU_APPEND )
@@ -286,49 +377,51 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
 
     pItem->mpParentMenu = this;
 
-    if ( pItem->mnType != MENUITEM_SEPARATOR )
-    {
-        unsigned nInsertSection, nInsertPos;
-        GetItemSectionAndPosition( nPos, &nInsertSection, &nInsertPos );
+//    if ( pItem->mnType != MENUITEM_SEPARATOR )
+//    {
+//        unsigned nInsertSection, nInsertPos;
+//        GetItemSectionAndPosition( nPos, &nInsertSection, &nInsertPos );
 
-        g_lo_menu_insert_in_section( G_LO_MENU( mpMenuModel ), nInsertSection, nInsertPos, "EMPTY STRING" );
-    }
-    else
-    {
-        g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), MENU_APPEND, NULL );
-    }
+//        //            g_lo_menu_insert_in_section( G_LO_MENU( mpMenuModel ), nInsertSection, nInsertPos, "EMPTY STRING" );
+//    }
+//    else
+//    {
+//        //            g_lo_menu_new_section( G_LO_MENU( mpMenuModel ), MENU_APPEND, NULL );
+//    }
 }
 
 void GtkSalMenu::RemoveItem( unsigned nPos )
 {
-    GLOMenu* pMenu = G_LO_MENU( mpMenuModel );
-    GtkSalMenuItem *pItem = maItems[ nPos ];
+    cout << this << " - " << __FUNCTION__ << endl;
+//    GLOMenu* pMenu = G_LO_MENU( mpMenuModel );
+//    GtkSalMenuItem *pItem = maItems[ nPos ];
 
     // If item is a separator, the last section of the menu is removed.
-    if ( pItem->mnType != MENUITEM_SEPARATOR )
-    {
-        if ( pItem->maCommand ) {
-            GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
+//    if ( pItem->mnType != MENUITEM_SEPARATOR )
+//    {
+//        unsigned nSection, nItemPos;
+//        GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
 
-            if ( pActionGroup != NULL )
-                g_lo_action_group_remove( pActionGroup, pItem->maCommand );
+//        gchar* aCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos );
 
-            g_free ( pItem->maCommand );
-            pItem->maCommand = NULL;
-        }
+//        if ( aCommand ) {
+//            GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
 
-        unsigned nSection, nItemPos;
-        GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
+//            if ( pActionGroup != NULL )
+//                g_lo_action_group_remove( pActionGroup, aCommand );
 
-        g_lo_menu_remove_from_section( pMenu, nSection, nItemPos );
-    }
-    else
-    {
-        gint nSection = g_menu_model_get_n_items( mpMenuModel ) - 1;
+//            g_free( aCommand );
+//        }
 
-        if ( nSection > 0 )
-            g_lo_menu_remove( pMenu, nSection );
-    }
+//        g_lo_menu_remove_from_section( pMenu, nSection, nItemPos );
+//    }
+//    else
+//    {
+//        gint nSection = g_menu_model_get_n_items( mpMenuModel ) - 1;
+
+//        if ( nSection > 0 )
+//            g_lo_menu_remove( pMenu, nSection );
+//    }
 
     maItems.erase( maItems.begin() + nPos );
 }
@@ -341,6 +434,8 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig
     if ( pGtkSubMenu == NULL )
         return;
 
+    cout << this << " - " << __FUNCTION__ << " - " << nPos << " - " << pSubMenu << endl;
+
     pGtkSubMenu->mpParentSalMenu = this;
     pItem->mpSubMenu = pGtkSubMenu;
 
@@ -405,7 +500,8 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
         }
 
         // Menubar has only one section, so we put it on the exported menu.
-        g_lo_menu_insert_section( pMainMenu, 0, NULL, mpMenuModel );
+        //        g_lo_menu_insert_section( pMainMenu, 0, NULL, mpMenuModel );
+        mpMenuModel = G_MENU_MODEL( pMainMenu );
         mpActionGroup = G_ACTION_GROUP( pActionGroup );
 
 //        UpdateNativeMenu( this );
@@ -427,92 +523,94 @@ const GtkSalFrame* GtkSalMenu::GetFrame() const
 
 void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
 {
-    GtkSalMenuItem* pItem = maItems[ nPos ];
+//    GtkSalMenuItem* pItem = maItems[ nPos ];
 
-    if ( pItem->mpSubMenu )
-        return;
+//    if ( pItem->mpSubMenu )
+//        return;
 
-    if ( pItem->maCommand == NULL || g_strcmp0( pItem->maCommand, "" ) == 0 )
-        return;
+//    unsigned nSection, nItemPos;
+//    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
 
-    GActionGroup* pActionGroup = GetActionGroupFromMenubar( this );
+//    gchar* aCommand = g_lo_menu_get_command_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos );
 
-    if ( !pActionGroup )
-        return;
+//    if ( aCommand == NULL && g_strcmp0( aCommand, "" ) != 0 )
+//    {
+//        GActionGroup* pActionGroup = GetActionGroupFromMenubar( this );
 
-    GVariant *pCheckValue = NULL;
-    gboolean bCheckedValue = ( bCheck == sal_True ) ? TRUE : FALSE;
+//        if ( pActionGroup != NULL )
+//        {
 
-    // FIXME: Why pItem->mnBits differs from GetItemBits value?
-    MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
+//            GVariant *pCheckValue = NULL;
+//            gboolean bCheckedValue = ( bCheck == sal_True ) ? TRUE : FALSE;
 
-    if ( bits & MIB_CHECKABLE ) {
-        GVariant* pState = g_action_group_get_action_state( pActionGroup, pItem->maCommand );
-        gboolean bCurrentState = g_variant_get_boolean( pState );
+//            // FIXME: Why pItem->mnBits differs from GetItemBits value?
+//            MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
 
-        if ( bCurrentState != bCheck )
-            pCheckValue = g_variant_new_boolean( bCheckedValue );
-    }
-    else if ( bits & MIB_RADIOCHECK )
-    {
-        GVariant* pState = g_action_group_get_action_state( pActionGroup, pItem->maCommand );
-        gchar* aCurrentState = (gchar*) g_variant_get_string( pState, NULL );
-        gboolean bCurrentState = g_strcmp0( aCurrentState, "" ) != 0;
+//            if ( bits & MIB_CHECKABLE ) {
+//                GVariant* pState = g_action_group_get_action_state( pActionGroup, aCommand );
+//                gboolean bCurrentState = g_variant_get_boolean( pState );
 
-        if ( bCurrentState != bCheck )
-            pCheckValue = (bCheckedValue) ? g_variant_new_string( pItem->maCommand ) : g_variant_new_string( "" );
-    }
+//                if ( bCurrentState != bCheck )
+//                    pCheckValue = g_variant_new_boolean( bCheckedValue );
+//            }
+//            else if ( bits & MIB_RADIOCHECK )
+//            {
+//                GVariant* pState = g_action_group_get_action_state( pActionGroup, aCommand );
+//                gchar* aCurrentState = (gchar*) g_variant_get_string( pState, NULL );
+//                gboolean bCurrentState = g_strcmp0( aCurrentState, "" ) != 0;
 
-    if ( pCheckValue )
-        g_action_group_change_action_state( pActionGroup, pItem->maCommand, pCheckValue );
+//                if ( bCurrentState != bCheck )
+//                    pCheckValue = (bCheckedValue) ? g_variant_new_string( aCommand ) : g_variant_new_string( "" );
+//            }
+
+//            if ( pCheckValue )
+//                g_action_group_change_action_state( pActionGroup, aCommand, pCheckValue );
+//        }
+//    }
+
+//    if ( aCommand )
+//        g_free( aCommand );
 }
 
 void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
 {
-    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
+//    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
 
-    if ( pActionGroup == NULL )
-        return;
+//    if ( pActionGroup == NULL )
+//        return;
 
-    sal_uInt16 nId = mpVCLMenu->GetItemId( nPos );
-    rtl::OUString aOUCommand = mpVCLMenu->GetItemCommand( nId );
+//    sal_uInt16 nId = mpVCLMenu->GetItemId( nPos );
+//    rtl::OUString aOUCommand = mpVCLMenu->GetItemCommand( nId );
 
-    if ( aOUCommand == NULL || aOUCommand.isEmpty() )
-        return;
+//    if ( aOUCommand == NULL || aOUCommand.isEmpty() )
+//        return;
 
-    gchar* aCommand = (gchar*) rtl::OUStringToOString( aOUCommand, RTL_TEXTENCODING_UTF8 ).getStr();
+//    gchar* aCommand = (gchar*) rtl::OUStringToOString( aOUCommand, RTL_TEXTENCODING_UTF8 ).getStr();
 
-    gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE;
+//    gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE;
 
-    if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bItemEnabled )
-        g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bItemEnabled );
+//    if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bItemEnabled )
+//        g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bItemEnabled );
 }
 
 void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText )
 {
-    // Replace the "~" character with "_".
-    rtl::OUString aText = rText.replace( '~', '_' );
-    rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 );
-
-    unsigned nSection, nItemPos;
-    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
-
-    // Update item text only when necessary.
-    sal_Bool bSetLabel = sal_True;
+    cout << this << " - " << __FUNCTION__ << endl;
+//    // Replace the "~" character with "_".
+//    rtl::OUString aText = rText.replace( '~', '_' );
+//    rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 );
 
-    GtkSalMenuItem* pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
+//    unsigned nSection, nItemPos;
+//    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
 
-    // FIXME: It would be better retrieving the label from the menu itself, but it currently crashes the app.
-    if ( pItem->maLabel && g_strcmp0( pItem->maLabel, aConvertedText.getStr() ) == 0 )
-        bSetLabel = sal_False;
+//    // Update item text only when necessary.
+//    gchar* aLabel = g_lo_menu_get_label_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos );
 
-    if ( bSetLabel == sal_True ) {
-        if ( pItem->maLabel )
-            g_free( pItem->maLabel );
+//    if ( aLabel == NULL || g_strcmp0( aLabel, aConvertedText.getStr() ) != 0 )
+//        g_lo_menu_set_label_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aConvertedText.getStr() );
 
-        pItem->maLabel = g_strdup( aConvertedText.getStr() );
-        g_lo_menu_set_label_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, pItem->maLabel );
-    }
+//    if ( aLabel )
+//        g_free( aLabel );
 }
 
 void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage)
@@ -521,101 +619,95 @@ void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const I
 
 void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName )
 {
-    GtkSalMenuItem *pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
-
-    if ( rKeyName.isEmpty() )
-        return;
+    cout << this << " - " << __FUNCTION__ << endl;
+//    if ( rKeyName.isEmpty() )
+//        return;
 
-    rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 );
+//    rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 );
 
-    unsigned nSection, nItemPos;
-    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
+//    unsigned nSection, nItemPos;
+//    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
 
-    sal_Bool bSetAccel = sal_True;
+//    gchar* aCurrentAccel = g_lo_menu_get_accelerator_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos );
 
-    if ( pItem->maAccel && g_strcmp0( pItem->maAccel, aAccelerator.getStr() ) == 0 )
-            bSetAccel = sal_False;
+//    if ( aCurrentAccel == NULL && g_strcmp0( aCurrentAccel, aAccelerator.getStr() ) != 0 )
+//        g_lo_menu_set_accelerator_to_item_in_section ( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aAccelerator.getStr() );
 
-    if ( bSetAccel == sal_True ) {
-        if (pItem->maAccel)
-            g_free( pItem->maAccel );
-
-        pItem->maAccel = g_strdup( aAccelerator.getStr() );
-        g_lo_menu_set_accelerator_to_item_in_section ( G_LO_MENU( mpMenuModel ), nSection, nItemPos, pItem->maAccel );
-    }
+//    if ( aCurrentAccel )
+//        g_free( aCurrentAccel );
 }
 
 void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr )
 {
-    GtkSalMenuItem* pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
+    cout << this << " - " << __FUNCTION__ << endl;
+//    GtkSalMenuItem* pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
 
-    if ( pItem->mnType == MENUITEM_SEPARATOR ||
-         pItem->mpVCLMenu->GetPopupMenu( pItem->mnId ) != NULL ||
-         aCommandStr.isEmpty() )
-        return;
+//    if ( pItem->mnType == MENUITEM_SEPARATOR ||
+//         pItem->mpVCLMenu->GetPopupMenu( pItem->mnId ) != NULL ||
+//         aCommandStr.isEmpty() )
+//        return;
 
-    gchar* aCommand = (gchar*) rtl::OUStringToOString( aCommandStr, RTL_TEXTENCODING_UTF8 ).getStr();
+//    gchar* aCommand = (gchar*) rtl::OUStringToOString( aCommandStr, RTL_TEXTENCODING_UTF8 ).getStr();
 
-    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
-    if ( pActionGroup == NULL )
-        return;
+//    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) );
+//    if ( pActionGroup == NULL )
+//        return;
 
-    GVariant *pTarget = NULL;
+//    GVariant *pTarget = NULL;
 
-    if ( g_action_group_has_action( G_ACTION_GROUP( pActionGroup ), aCommand ) == FALSE ) {
-        gboolean bChecked = ( pItem->mpVCLMenu->IsItemChecked( pItem->mnId ) ) ? TRUE : FALSE;
+//    if ( g_action_group_has_action( G_ACTION_GROUP( pActionGroup ), aCommand ) == FALSE ) {
+//        gboolean bChecked = ( pItem->mpVCLMenu->IsItemChecked( pItem->mnId ) ) ? TRUE : FALSE;
 
-        // FIXME: Why pItem->mnBits differs from GetItemBits value?
-        MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
+//        // FIXME: Why pItem->mnBits differs from GetItemBits value?
+//        MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
 
-        if ( bits & MIB_CHECKABLE )
-        {
-            // Item is a checkmark button.
-            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
-            GVariant* pState = g_variant_new_boolean( bChecked );
-
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, NULL, pStateType, NULL, pState );
-        }
-        else if ( bits & MIB_RADIOCHECK )
-        {
-            // Item is a radio button.
-            GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
-            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
-            //        GVariant* pStateHint = GetRadioButtonHints( pItem );
-            GVariant* pState = g_variant_new_string( "" );
-            pTarget = g_variant_new_string( aCommand );
-
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState );
-        }
-        else
-        {
-            // Item is not special, so insert a stateless action.
-            g_lo_action_group_insert( pActionGroup, aCommand, pItem );
-        }
-    }
+//        if ( bits & MIB_CHECKABLE )
+//        {
+//            // Item is a checkmark button.
+//            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
+//            GVariant* pState = g_variant_new_boolean( bChecked );
 
-    // Menu item is not updated unless it's necessary.
-    if ( ( pItem->maCommand != NULL ) && ( g_strcmp0( pItem->maCommand, aCommand ) == 0 ) )
-        return;
+//            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, NULL, pStateType, NULL, pState );
+//        }
+//        else if ( bits & MIB_RADIOCHECK )
+//        {
+//            // Item is a radio button.
+//            GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
+//            GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
+//            //        GVariant* pStateHint = GetRadioButtonHints( pItem );
+//            GVariant* pState = g_variant_new_string( "" );
+//            pTarget = g_variant_new_string( aCommand );
+
+//            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState );
+//        }
+//        else
+//        {
+//            // Item is not special, so insert a stateless action.
+//            g_lo_action_group_insert( pActionGroup, aCommand, pItem );
+//        }
+//    }
 
-    if ( pItem->maCommand != NULL )
-        g_free( pItem->maCommand );
+//    GLOMenu* pMenu = G_LO_MENU( mpMenuModel );
 
-    pItem->maCommand = g_strdup( aCommand );
+//    // Menu item is not updated unless it's necessary.
+//    unsigned nSection, nItemPos;
+//    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
 
-    unsigned nSection, nItemPos;
-    GetItemSectionAndPosition( nPos, &nSection, &nItemPos );
+//    gchar* aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos );
 
-    gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
+//    if ( aCurrentCommand == NULL || g_strcmp0( aCurrentCommand, aCommand ) != 0 )
+//    {
+//        g_lo_menu_set_accelerator_to_item_in_section( pMenu, nSection, nItemPos, aCommand );
 
-    if ( pItem->maCommand )
-        g_free( pItem->maCommand );
+//        gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
 
-    pItem->maCommand = g_strdup( aCommand );
+//        g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
 
-    g_lo_menu_set_action_and_target_value_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aItemCommand, pTarget );
+//        g_free( aItemCommand );
+//    }
 
-    g_free( aItemCommand );
+//    if ( aCurrentCommand )
+//        g_free( aCurrentCommand );
 }
 
 void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
@@ -638,23 +730,12 @@ GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) :
     mnType( pItemData->eType ),
     mpVCLMenu( pItemData->pMenu ),
     mpParentMenu( NULL ),
-    mpSubMenu( NULL ),
-    maCommand( NULL ),
-    maLabel( NULL ),
-    maAccel( NULL )
+    mpSubMenu( NULL )
 {
 }
 
 GtkSalMenuItem::~GtkSalMenuItem()
 {
-    if ( maCommand )
-        g_free( maCommand );
-
-    if ( maLabel )
-        g_free( maLabel );
-
-    if ( maAccel )
-        g_free( maAccel );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list