[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[SCM] LibreOffice packaging repository branch, ubuntu-quantal-3.6, updated. libreoffice_3.6.1_rc2-1-72-g8fd97c9



The following commit has been merged in the ubuntu-quantal-3.6 branch:
commit bae493932aac0b50a17790cb8960dca2a59f0332
Author: Bjoern Michaelsen <bjoern.michaelsen@canonical.com>
Date:   Fri Sep 21 12:45:35 2012 +0200

    update unitymenus to commit 22774aff3f1d4b2a09d713555e0180a3eded3155

diff --git a/changelog b/changelog
index bfa26ca..7e2773e 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,9 @@
+libreoffice (1:3.6.1~rc2-1ubuntu6~ppa1) quantal; urgency=low
+
+  * update unitymenus to commit 22774aff3f1d4b2a09d713555e0180a3eded3155
+
+ -- Bjoern Michaelsen <bjoern.michaelsen@canonical.com>  Fri, 21 Sep 2012 12:41:14 +0200
+
 libreoffice (1:3.6.1~rc2-1ubuntu5) quantal; urgency=low
 
   * update unitymenus to commit a12a4a6befd8688495b966fb4741f61242740389
diff --git a/patches/unitymenus.diff b/patches/unitymenus.diff
index 614588f..a7b3257 100644
--- a/patches/unitymenus.diff
+++ b/patches/unitymenus.diff
@@ -1,10 +1,10 @@
-commit b999fa88dd114693be3e2db6581eefacaaa637ea
+commit b6a6cf9ae5fb25b19865fc283e16a379dac68e59
 Author: Antonio Fernandez <antonio.fernandez@aentos.es>
-Date:   Tue Sep 11 12:21:28 2012 +0100
+Date:   Wed Sep 19 20:05:56 2012 +0100
 
-    Fixed crashes when executing some menu actions.
+    Fixed a crash updating the menu after opening an application from main screen.
     
-    Change-Id: I80bb1ed74e823d4b66df05eb15c9b5ed2e58b7f6
+    Change-Id: If7b603dca5aa33e50a63e04fda3bce594840cc57
  framework/inc/classes/menumanager.hxx         |   22 +-
  framework/inc/uielement/menubarmanager.hxx    |   24 +-
  framework/inc/uielement/menubarmerger.hxx     |   16 +-
@@ -17,23 +17,23 @@ Date:   Tue Sep 11 12:21:28 2012 +0100
  vcl/Library_vclplug_gtk.mk                    |   11 +-
  vcl/Library_vclplug_gtk3.mk                   |    3 +
  vcl/inc/salmenu.hxx                           |    7 +-
- vcl/inc/unx/gtk/gloactiongroup.h              |   93 ++++
- vcl/inc/unx/gtk/glomenu.h                     |  138 ++++++
+ vcl/inc/unx/gtk/gloactiongroup.h              |   95 +++
+ vcl/inc/unx/gtk/glomenu.h                     |  144 +++++
  vcl/inc/unx/gtk/gtkframe.hxx                  |    5 +
  vcl/inc/unx/gtk/gtkinst.hxx                   |    5 +-
- vcl/inc/unx/gtk/gtksalmenu.hxx                |  117 +++++
+ vcl/inc/unx/gtk/gtksalmenu.hxx                |  123 ++++
  vcl/inc/unx/salmenu.h                         |    8 +-
- vcl/inc/vcl/menu.hxx                          |  156 +++++--
- vcl/source/window/menu.cxx                    |   21 +-
- vcl/unx/gtk/app/gtkinst.cxx                   |   30 ++
- vcl/unx/gtk/window/gloactiongroup.cxx         |  378 +++++++++++++++
- vcl/unx/gtk/window/glomenu.cxx                |  590 ++++++++++++++++++++++++
+ vcl/inc/vcl/menu.hxx                          |  156 ++++-
+ vcl/source/window/menu.cxx                    |   16 +-
+ vcl/unx/gtk/app/gtkinst.cxx                   |   30 +
+ vcl/unx/gtk/window/gloactiongroup.cxx         |  408 +++++++++++++
+ vcl/unx/gtk/window/glomenu.cxx                |  653 ++++++++++++++++++++
  vcl/unx/gtk/window/gtkframe.cxx               |   18 +-
- vcl/unx/gtk/window/gtksalmenu.cxx             |  612 +++++++++++++++++++++++++
+ vcl/unx/gtk/window/gtksalmenu.cxx             |  789 +++++++++++++++++++++++++
  vcl/unx/gtk3/window/gtk3gloactiongroup.cxx    |    2 +
  vcl/unx/gtk3/window/gtk3glomenu.cxx           |    2 +
  vcl/unx/gtk3/window/gtk3gtksalmenu.cxx        |    2 +
- 28 files changed, 2240 insertions(+), 112 deletions(-)
+ 28 files changed, 2521 insertions(+), 110 deletions(-)
 diff --git a/framework/inc/classes/menumanager.hxx b/framework/inc/classes/menumanager.hxx
 index 3ac4588..56ecc90 100644
 --- a/framework/inc/classes/menumanager.hxx
@@ -642,7 +642,7 @@ diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk
 index 120199c..fd66689 100644
 --- a/vcl/Library_vclplug_gtk3.mk
 +++ b/vcl/Library_vclplug_gtk3.mk
-@@ -111,6 +111,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\
+@@ -110,6 +110,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\
      vcl/unx/gtk3/gdi/gtk3salprn-gtk \
      vcl/unx/gtk3/window/gtk3gtkframe \
      vcl/unx/gtk3/window/gtk3gtkobject \
@@ -686,10 +686,10 @@ index 1d14a7e..2f8d680 100644
      // but rectangle cannot be determined
 diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h
 new file mode 100644
-index 0000000..e0d783f
+index 0000000..61ec718
 --- /dev/null
 +++ b/vcl/inc/unx/gtk/gloactiongroup.h
-@@ -0,0 +1,93 @@
+@@ -0,0 +1,95 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +
 +/*
@@ -759,11 +759,13 @@ index 0000000..e0d783f
 +
 +void                g_lo_action_group_insert                (GLOActionGroup     *group,
 +                                                             const gchar        *action_name,
-+                                                             gint                item_id);
++                                                             gint                item_id,
++                                                             gboolean            submenu);
 +
 +void                g_lo_action_group_insert_stateful       (GLOActionGroup     *group,
 +                                                             const gchar        *action_name,
 +                                                             gint                item_id,
++                                                             gboolean            submenu,
 +                                                             const GVariantType *parameter_type,
 +                                                             const GVariantType *state_type,
 +                                                             GVariant           *state_hint,
@@ -785,10 +787,10 @@ index 0000000..e0d783f
 +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 diff --git a/vcl/inc/unx/gtk/glomenu.h b/vcl/inc/unx/gtk/glomenu.h
 new file mode 100644
-index 0000000..c45be50
+index 0000000..4c7c3e5
 --- /dev/null
 +++ b/vcl/inc/unx/gtk/glomenu.h
-@@ -0,0 +1,138 @@
+@@ -0,0 +1,144 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +
 +/*
@@ -819,6 +821,7 @@ index 0000000..c45be50
 +
 +#define G_LO_MENU_ATTRIBUTE_ACCELERATOR     "accel"
 +#define G_LO_MENU_ATTRIBUTE_COMMAND         "command"
++#define G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION  "submenu-action"
 +
 +G_BEGIN_DECLS
 +
@@ -919,6 +922,11 @@ index 0000000..c45be50
 +                                                                         gint         section,
 +                                                                         gint         position);
 +
++void        g_lo_menu_set_submenu_action_to_item_in_section             (GLOMenu     *menu,
++                                                                         gint         section,
++                                                                         gint         position,
++                                                                         const gchar *action);
++
 +GLOMenu *   g_lo_menu_get_menu_containing_item                          (GLOMenu     *menu,
 +                                                                         gint         item_id);
 +
@@ -976,10 +984,10 @@ index 89743ca..efe8f16 100644
      bool                        IsTimerExpired();
 diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
 new file mode 100644
-index 0000000..f746b4b
+index 0000000..56aed28
 --- /dev/null
 +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
-@@ -0,0 +1,117 @@
+@@ -0,0 +1,123 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +
 +/*
@@ -1037,14 +1045,12 @@ index 0000000..f746b4b
 +    GMenuModel*                     mpMenuModel;
 +    GActionGroup*                   mpActionGroup;
 +
-+    sal_Int32                   GetPositionFromItem( GtkSalMenuItem* pSalMenuItem );
-+    void                        GetItemSectionAndPosition( unsigned nPos, unsigned *insertSection, unsigned *insertPos );
++    GtkSalMenu*                 GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu );
 +
 +public:
 +    GtkSalMenu( sal_Bool bMenuBar );
 +    virtual ~GtkSalMenu();
 +
-+    virtual void                SetVisibleMenuBar( sal_Bool bVisible );
 +    virtual sal_Bool            VisibleMenuBar();   // must return TRUE to actually DISPLAY native menu bars
 +                                                    // otherwise only menu messages are processed (eg, OLE on Windows)
 +
@@ -1071,13 +1077,22 @@ index 0000000..f746b4b
 +    virtual GtkSalMenuItem*     GetItemAtPos( unsigned nPos ) { return maItems[ nPos ]; }
 +    virtual void                SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; }
 +    virtual GActionGroup*       GetActionGroup() { return mpActionGroup; }
-+    GtkSalMenu*                 GetMenuForItemCommand( gchar* aCommand );
 +
 +    void                        NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText );
-+    void                        NativeSetItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommandStr );
++    void                        NativeSetItemCommand( unsigned nSection,
++                                                      unsigned nItemPos,
++                                                      sal_uInt16 nId,
++                                                      const gchar* aCommand,
++                                                      MenuItemBits nBits,
++                                                      gboolean bChecked,
++                                                      gboolean bIsSubmenu );
 +    void                        NativeSetEnableItem( gchar* aCommand, gboolean bEnable );
 +    void                        NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck );
 +    void                        NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName );
++
++    void                        DispatchCommand( gint itemId, const gchar* aCommand );
++    void                        Activate( const gchar* aMenuCommand );
++    void                        Deactivate( const gchar* aMenuCommand );
 +};
 +
 +class GtkSalMenuItem : public SalMenuItem
@@ -1087,7 +1102,6 @@ index 0000000..f746b4b
 +    virtual ~GtkSalMenuItem();
 +
 +    sal_uInt16          mnId;               // Item ID
-+    MenuItemBits        mnBits;             // Item bits
 +    MenuItemType        mnType;             // Item type
 +    Menu*               mpVCLMenu;          // VCL Menu into which this MenuItem is inserted
 +    GtkSalMenu*         mpParentMenu;       // The menu in which this menu item is inserted
@@ -1387,29 +1401,10 @@ index c9388ee..7538faf 100644
      // highlight link will be called with a MenuBarButtonHighlightArg
      // the bHighlight member of that struct shall contain the new state
 diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
-index 3b4ac0d..e921805 100644
+index 3b4ac0d..7fc74e4 100644
 --- a/vcl/source/window/menu.cxx
 +++ b/vcl/source/window/menu.cxx
-@@ -1146,7 +1146,8 @@ void Menu::Select()
-     }
- }
- 
--#if defined(QUARTZ)
-+// FIXME: Workaround to make GLOMenu without defining macros.
-+//#if defined(QUARTZ)
- void Menu::ImplSelectWithStart( Menu* pSMenu )
- {
-     Menu* pOldStartedFrom = pStartedFrom;
-@@ -1157,7 +1158,7 @@ void Menu::ImplSelectWithStart( Menu* pSMenu )
-         pOldStartedFrom->pStartedFrom = pOldStartedStarted;
-     pStartedFrom = pOldStartedFrom;
- }
--#endif
-+//#endif
- 
- void Menu::RequestHelp( const HelpEvent& )
- {
-@@ -1958,10 +1959,15 @@ sal_Bool Menu::GetItemImageMirrorMode( sal_uInt16 nItemId ) const
+@@ -1958,10 +1958,15 @@ sal_Bool Menu::GetItemImageMirrorMode( sal_uInt16 nItemId ) const
  
  void Menu::SetItemCommand( sal_uInt16 nItemId, const String& rCommand )
  {
@@ -1426,7 +1421,7 @@ index 3b4ac0d..e921805 100644
  }
  
  const XubString& Menu::GetItemCommand( sal_uInt16 nItemId ) const
-@@ -3238,6 +3244,15 @@ void Menu::HighlightItem( sal_uInt16 nItemPos )
+@@ -3238,6 +3243,15 @@ void Menu::HighlightItem( sal_uInt16 nItemPos )
      }
  }
  
@@ -1492,10 +1487,10 @@ index 845e2fc..2738e20 100644
      GtkSalTimer *pTimer = new GtkSalTimer();
 diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
 new file mode 100644
-index 0000000..33e756c
+index 0000000..d083703
 --- /dev/null
 +++ b/vcl/unx/gtk/window/gloactiongroup.cxx
-@@ -0,0 +1,378 @@
+@@ -0,0 +1,408 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +
 +/*
@@ -1524,7 +1519,6 @@ index 0000000..33e756c
 +#include <unx/gtk/gtkinst.hxx>
 +#include <unx/gtk/gtkframe.hxx>
 +#include <unx/gtk/gtksalmenu.hxx>
-+#include <vcl/menu.hxx>
 +
 +
 +/*
@@ -1542,7 +1536,8 @@ index 0000000..33e756c
 +    GObject         parent_instance;
 +
 +    gint            item_id;            // Menu item ID.
-+    gboolean        enabled;            // TRUE if action is enabled, FALSE otherwise.
++    gboolean        submenu;            // TRUE if action is a submenu action.
++    gboolean        enabled;            // TRUE if action is enabled.
 +    GVariantType*   parameter_type;     // A GVariantType with the action parameter type.
 +    GVariantType*   state_type;         // A GVariantType with item state type
 +    GVariant*       state_hint;         // A GVariant with state hints.
@@ -1564,6 +1559,7 @@ index 0000000..33e756c
 +g_lo_action_init (GLOAction *action)
 +{
 +    action->item_id = -1;
++    action->submenu = FALSE;
 +    action->enabled = TRUE;
 +    action->parameter_type = NULL;
 +    action->state_type = NULL;
@@ -1657,51 +1653,82 @@ index 0000000..33e756c
 +    if (enabled)
 +        *enabled = action->enabled;
 +
-+    if (parameter_type) {
++    if (parameter_type)
 +        *parameter_type = action->parameter_type;
-+    }
 +
-+    if (state_type) {
++    if (state_type)
 +        *state_type = action->state_type;
-+    }
 +
-+    if (state_hint) {
-+        *state_hint = (action->state_hint) ? g_variant_ref(action->state_hint) : NULL;
-+    }
++    if (state_hint)
++        *state_hint = (action->state_hint) ? g_variant_ref (action->state_hint) : NULL;
 +
-+    if (state) {
-+        *state = (action->state) ? g_variant_ref(action->state) : NULL;
-+    }
++    if (state)
++        *state = (action->state) ? g_variant_ref (action->state) : NULL;
 +
 +    return TRUE;
 +}
 +
 +static void
++g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
++                                          const gchar    *action_name,
++                                          GVariant       *state)
++{
++    GTK_YIELD_GRAB();
++
++    GtkSalFrame* pFrame = group->priv->frame;
++
++    if (pFrame == NULL)
++        return;
++
++    GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*> (pFrame->GetMenu());
++
++    if (pSalMenu != NULL) {
++        gboolean bState = g_variant_get_boolean (state);
++
++        if (bState == TRUE)
++            pSalMenu->Activate (action_name);
++        else
++            pSalMenu->Deactivate (action_name);
++    }
++}
++
++static void
 +g_lo_action_group_change_state (GActionGroup *group,
 +                                const gchar  *action_name,
 +                                GVariant     *value)
 +{
-+    if (!action_name || !value)
-+        return;
-+
-+    GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group);
++    g_return_if_fail (value != NULL);
 +
-+    GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
++    g_variant_ref_sink (value);
 +
-+    if (action == NULL)
-+        return;
++    if (action_name != NULL)
++    {
++        GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group);
++        GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
 +
-+    if (action->state_type == NULL)
-+        action->state_type = g_variant_type_copy(g_variant_get_type(value));
++        if (action != NULL)
++        {
++            if (action->submenu == TRUE)
++                g_lo_action_group_perform_submenu_action (lo_group, action_name, value);
++            else
++            {
++                if (action->state_type == NULL)
++                    action->state_type = g_variant_type_copy (g_variant_get_type(value));
 +
-+    g_return_if_fail (g_variant_is_of_type(value, action->state_type) == TRUE);
++                if (g_variant_is_of_type (value, action->state_type) == TRUE)
++                {
++                    if (action->state)
++                        g_variant_unref(action->state);
 +
-+    if (action->state)
-+        g_variant_unref(action->state);
++                    action->state = g_variant_ref (value);
 +
-+    action->state = g_variant_take_ref(value);
++                    g_action_group_action_state_changed (group, action_name, value);
++                }
++            }
++        }
++    }
 +
-+    g_action_group_action_state_changed(group, action_name, value);
++    g_variant_unref (value);
 +}
 +
 +static void
@@ -1712,38 +1739,34 @@ index 0000000..33e756c
 +    GTK_YIELD_GRAB();
 +
 +    GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
-+    GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
-+
 +    GtkSalFrame *pFrame = lo_group->priv->frame;
 +
-+    if ( pFrame == NULL )
-+        return;
-+
-+    GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() );
-+
-+    if ( pSalMenu == NULL )
-+        return;
-+
-+    GtkSalMenu* pSalSubMenu = pSalMenu->GetMenuForItemCommand( (gchar*) action_name );
-+    Menu* pSubMenu = ( pSalMenu != NULL ) ? pSalSubMenu->GetMenu() : NULL;
-+
-+    MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() );
++    if ( pFrame != NULL )
++    {
++        GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() );
 +
-+    pMenuBar->HandleMenuCommandEvent( pSubMenu, action->item_id );
++        if ( pSalMenu != NULL )
++        {
++            GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
++            pSalMenu->DispatchCommand( action->item_id, action_name );
++        }
++    }
 +}
 +
 +void
 +g_lo_action_group_insert (GLOActionGroup *group,
 +                          const gchar    *action_name,
-+                          gint            item_id)
++                          gint            item_id,
++                          gboolean        submenu)
 +{
-+    g_lo_action_group_insert_stateful (group, action_name, item_id, NULL, NULL, NULL, NULL);
++    g_lo_action_group_insert_stateful (group, action_name, item_id, submenu, NULL, NULL, NULL, NULL);
 +}
 +
 +void
 +g_lo_action_group_insert_stateful (GLOActionGroup     *group,
 +                                   const gchar        *action_name,
 +                                   gint                item_id,
++                                   gboolean            submenu,
 +                                   const GVariantType *parameter_type,
 +                                   const GVariantType *state_type,
 +                                   GVariant           *state_hint,
@@ -1756,13 +1779,15 @@ index 0000000..33e756c
 +    if (old_action == NULL || old_action->item_id != item_id)
 +    {
 +        if (old_action != NULL)
-+            g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
++            g_lo_action_group_remove (group, action_name);
++//            g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
 +
 +        GLOAction* action = g_lo_action_new();
 +
 +        g_hash_table_insert (group->priv->table, g_strdup (action_name), action);
 +
 +        action->item_id = item_id;
++        action->submenu = submenu;
 +
 +        if (parameter_type)
 +            action->parameter_type = (GVariantType*) parameter_type;
@@ -1771,10 +1796,10 @@ index 0000000..33e756c
 +            action->state_type = (GVariantType*) state_type;
 +
 +        if (state_hint)
-+            action->state_hint = g_variant_take_ref (state_hint);
++            action->state_hint = g_variant_ref_sink (state_hint);
 +
 +        if (state)
-+            action->state = g_variant_take_ref (state);
++            action->state = g_variant_ref_sink (state);
 +
 +        g_action_group_action_added (G_ACTION_GROUP (group), action_name);
 +    }
@@ -1876,10 +1901,10 @@ index 0000000..33e756c
 +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx
 new file mode 100644
-index 0000000..9c0f835
+index 0000000..2ecf23a
 --- /dev/null
 +++ b/vcl/unx/gtk/window/glomenu.cxx
-@@ -0,0 +1,590 @@
+@@ -0,0 +1,653 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +
 +/*
@@ -1988,13 +2013,20 @@ index 0000000..9c0f835
 +}
 +
 +gint
-+g_lo_menu_get_n_items_from_section (GLOMenu     *menu,
-+                                    gint         section)
++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));
++    g_return_val_if_fail (0 <= section && section < (gint) menu->items->len, -1);
++
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
++
++    g_return_val_if_fail (model != NULL, -1);
++
++    gint length = model->items->len;
 +
-+    return model->items->len;
++    g_object_unref (model);
++
++    return length;
 +}
 +
 +static void
@@ -2018,9 +2050,9 @@ index 0000000..9c0f835
 +}
 +
 +void
-+g_lo_menu_insert (GLOMenu        *menu,
-+                  gint            position,
-+                  const gchar    *label)
++g_lo_menu_insert (GLOMenu     *menu,
++                  gint         position,
++                  const gchar *label)
 +{
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +
@@ -2039,20 +2071,21 @@ index 0000000..9c0f835
 +}
 +
 +void
-+g_lo_menu_insert_in_section (GLOMenu        *menu,
-+                             gint            section,
-+                             gint            position,
-+                             const gchar    *label)
++g_lo_menu_insert_in_section (GLOMenu     *menu,
++                             gint         section,
++                             gint         position,
++                             const gchar *label)
 +{
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +    g_return_if_fail (0 <= section && section < (gint) menu->items->len);
 +
-+    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));
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
 +    g_lo_menu_insert (model, position, label);
++
++    g_object_unref (model);
 +}
 +
 +GLOMenu *
@@ -2071,7 +2104,7 @@ index 0000000..9c0f835
 +    g_return_if_fail (attribute != NULL);
 +    g_return_if_fail (valid_attribute_name (attribute));
 +
-+    if (position >= menu->items->len)
++    if (position >= (gint) menu->items->len)
 +        return;
 +
 +    struct item menu_item = g_array_index (menu->items, struct item, position);
@@ -2080,7 +2113,27 @@ index 0000000..9c0f835
 +        g_hash_table_insert (menu_item.attributes, g_strdup (attribute), g_variant_ref_sink (value));
 +    else
 +        g_hash_table_remove (menu_item.attributes, attribute);
++}
++
++GVariant*
++g_lo_menu_get_attribute_value_from_item_in_section (GLOMenu            *menu,
++                                                    gint                section,
++                                                    gint                position,
++                                                    const gchar        *attribute,
++                                                    const GVariantType *type)
++{
++    GMenuModel *model = G_MENU_MODEL (g_lo_menu_get_section (menu, section));
 +
++    g_return_val_if_fail (model != NULL, NULL);
++
++    GVariant *value = g_menu_model_get_item_attribute_value (model,
++                                                             position,
++                                                             attribute,
++                                                             type);
++
++    g_object_unref (model);
++
++    return value;
 +}
 +
 +void
@@ -2108,8 +2161,7 @@ index 0000000..9c0f835
 +{
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +
-+    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));
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
@@ -2117,29 +2169,32 @@ index 0000000..9c0f835
 +
 +    // Notify the update.
 +    g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1);
++
++    g_object_unref (model);
 +}
 +
 +gchar *
-+g_lo_menu_get_label_from_item_in_section (GLOMenu     *menu,
-+                                          gint         section,
-+                                          gint         position)
++g_lo_menu_get_label_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);
++    GVariant *label_value = g_lo_menu_get_attribute_value_from_item_in_section (menu,
++                                                                                section,
++                                                                                position,
++                                                                                G_MENU_ATTRIBUTE_LABEL,
++                                                                                G_VARIANT_TYPE_STRING);
 +
-+    g_return_val_if_fail (model != NULL, NULL);
++    gchar *label = NULL;
 +
-+    GVariant *current_label = g_menu_model_get_item_attribute_value (G_MENU_MODEL(model),
-+                                                                     position,
-+                                                                     G_MENU_ATTRIBUTE_LABEL,
-+                                                                     G_VARIANT_TYPE_STRING);
++    if (label_value)
++    {
++        label = g_variant_dup_string (label_value, NULL);
++        g_variant_unref (label_value);
++    }
 +
-+    if (current_label)
-+        return g_strdup (g_variant_get_string (current_label, NULL));
-+    else
-+        return NULL;
++    return label;
 +}
 +
 +void
@@ -2164,6 +2219,8 @@ index 0000000..9c0f835
 +
 +    g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_ACTION, action_value);
 +    g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_TARGET, target_value);
++
++    g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 1);
 +}
 +
 +void
@@ -2175,16 +2232,13 @@ index 0000000..9c0f835
 +{
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +
-+    struct item menu_item = g_array_index (menu->items, struct item, section);
-+
-+    GLOMenu *model = G_LO_MENU (g_hash_table_lookup (menu_item.links, G_MENU_LINK_SECTION));
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
 +    g_lo_menu_set_action_and_target_value (model, position, command, target_value);
 +
-+    // Notify the update.
-+    g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1);
++    g_object_unref (model);
 +}
 +
 +void
@@ -2195,8 +2249,7 @@ index 0000000..9c0f835
 +{
 +    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);
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
@@ -2207,33 +2260,36 @@ index 0000000..9c0f835
 +    else
 +        value = NULL;
 +
-+    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_ACCELERATOR, value);
++    g_lo_menu_set_attribute_value (model, position, G_LO_MENU_ATTRIBUTE_ACCELERATOR, value);
 +
 +    // Notify the update.
-+    g_menu_model_items_changed (model, position, 1, 1);
++    g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1);
++
++    g_object_unref (model);
 +}
 +
 +gchar *
-+g_lo_menu_get_accelerator_from_item_in_section (GLOMenu     *menu,
-+                                                gint         section,
-+                                                gint         position)
++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);
++    GVariant *accel_value = g_lo_menu_get_attribute_value_from_item_in_section (menu,
++                                                                                section,
++                                                                                position,
++                                                                                G_LO_MENU_ATTRIBUTE_ACCELERATOR,
++                                                                                G_VARIANT_TYPE_STRING);
 +
-+    g_return_val_if_fail (model != NULL, NULL);
++    gchar *accel = NULL;
 +
-+    GVariant *current_accel = g_menu_model_get_item_attribute_value (model,
-+                                                                     position,
-+                                                                     G_LO_MENU_ATTRIBUTE_ACCELERATOR,
-+                                                                     G_VARIANT_TYPE_STRING);
++    if (accel_value != NULL)
++    {
++        accel = g_variant_dup_string (accel_value, NULL);
++        g_variant_unref (accel_value);
++    }
 +
-+    if (current_accel)
-+        return g_strdup (g_variant_get_string (current_accel, NULL));
-+    else
-+        return NULL;
++    return accel;
 +}
 +
 +void
@@ -2244,8 +2300,7 @@ index 0000000..9c0f835
 +{
 +    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);
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
@@ -2256,33 +2311,36 @@ index 0000000..9c0f835
 +    else
 +        value = NULL;
 +
-+    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_COMMAND, value);
++    g_lo_menu_set_attribute_value (model, position, G_LO_MENU_ATTRIBUTE_COMMAND, value);
 +
 +    // Notify the update.
-+    g_menu_model_items_changed (model, position, 1, 1);
++    g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1);
++
++    g_object_unref (model);
 +}
 +
 +gchar *
-+g_lo_menu_get_command_from_item_in_section (GLOMenu     *menu,
-+                                            gint         section,
-+                                            gint         position)
++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);
++    GVariant *command_value = g_lo_menu_get_attribute_value_from_item_in_section (menu,
++                                                                                  section,
++                                                                                  position,
++                                                                                  G_LO_MENU_ATTRIBUTE_COMMAND,
++                                                                                  G_VARIANT_TYPE_STRING);
 +
-+    g_return_val_if_fail (model != NULL, NULL);
++    gchar *command = NULL;
 +
-+    GVariant *command = g_menu_model_get_item_attribute_value (model,
-+                                                               position,
-+                                                               G_LO_MENU_ATTRIBUTE_COMMAND,
-+                                                               G_VARIANT_TYPE_STRING);
++    if (command_value != NULL)
++    {
++        command = g_variant_dup_string (command_value, NULL);
++        g_variant_unref (command_value);
++    }
 +
-+    if (command)
-+        return g_strdup (g_variant_get_string (command, NULL));
-+    else
-+        return NULL;
++    return command;
 +}
 +
 +void
@@ -2307,10 +2365,10 @@ index 0000000..9c0f835
 +}
 +
 +void
-+g_lo_menu_insert_section (GLOMenu *menu,
-+                          gint position,
++g_lo_menu_insert_section (GLOMenu     *menu,
++                          gint         position,
 +                          const gchar *label,
-+                          GMenuModel* section)
++                          GMenuModel  *section)
 +{
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +
@@ -2319,7 +2377,7 @@ index 0000000..9c0f835
 +
 +    struct item menu_item;
 +
-+    g_lo_menu_struct_item_init(&menu_item);
++    g_lo_menu_struct_item_init (&menu_item);
 +
 +    g_array_insert_val (menu->items, position, menu_item);
 +
@@ -2362,8 +2420,7 @@ index 0000000..9c0f835
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +    g_return_if_fail (0 <= section && section < (gint) menu->items->len);
 +
-+    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));
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
@@ -2371,18 +2428,19 @@ index 0000000..9c0f835
 +
 +    // Notify the update.
 +    g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1);
++
++    g_object_unref (model);
 +}
 +
 +GLOMenu *
-+g_lo_menu_get_submenu_from_item_in_section (GLOMenu     *menu,
-+                                            gint         section,
-+                                            gint         position)
++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));
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_val_if_fail (model != NULL, NULL);
 +
@@ -2391,9 +2449,38 @@ index 0000000..9c0f835
 +    if (0 <= position && position < (gint) model->items->len)
 +        submenu = g_menu_model_get_item_link (G_MENU_MODEL (model), position, G_MENU_LINK_SUBMENU);
 +
++    g_object_unref (model);
++
 +    return G_LO_MENU (submenu);
 +}
 +
++void
++g_lo_menu_set_submenu_action_to_item_in_section (GLOMenu     *menu,
++                                                 gint         section,
++                                                 gint         position,
++                                                 const gchar *action)
++{
++    g_return_if_fail (G_IS_LO_MENU (menu));
++
++    GMenuModel *model = G_MENU_MODEL (g_lo_menu_get_section (menu, section));
++
++    g_return_if_fail (model != NULL);
++
++    GVariant *value;
++
++    if (action != NULL)
++        value = g_variant_new_string (action);
++    else
++        value = NULL;
++
++    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION, value);
++
++    // Notify the update.
++    g_menu_model_items_changed (model, position, 1, 1);
++
++    g_object_unref (model);
++}
++
 +static void
 +g_lo_menu_clear_item (struct item *menu_item)
 +{
@@ -2410,9 +2497,9 @@ index 0000000..9c0f835
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +    g_return_if_fail (0 <= position && position < (gint) menu->items->len);
 +
++    g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0);
 +    g_lo_menu_clear_item (&g_array_index (menu->items, struct item, position));
 +    g_array_remove_index (menu->items, position);
-+    g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0);
 +}
 +
 +void
@@ -2423,12 +2510,13 @@ index 0000000..9c0f835
 +    g_return_if_fail (G_IS_LO_MENU (menu));
 +    g_return_if_fail (0 <= section && section < (gint) menu->items->len);
 +
-+    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));
++    GLOMenu *model = g_lo_menu_get_section (menu, section);
 +
 +    g_return_if_fail (model != NULL);
 +
 +    g_lo_menu_remove (model, position);
++
++    g_object_unref (model);
 +}
 +
 +static void
@@ -2522,10 +2610,10 @@ index 36be0b2..d43371c 100644
      long nX, nY;
 diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
 new file mode 100644
-index 0000000..b61af31
+index 0000000..60942a5
 --- /dev/null
 +++ b/vcl/unx/gtk/window/gtksalmenu.cxx
-@@ -0,0 +1,612 @@
+@@ -0,0 +1,789 @@
 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +/*
 + * Copyright © 2011 Canonical Ltd.
@@ -2548,7 +2636,7 @@ index 0000000..b61af31
 + * Author: Antonio Fernández <antonio.fernandez@aentos.es>
 + */
 +
-+#include "unx/gtk/gtksalmenu.hxx"
++#include <unx/gtk/gtksalmenu.hxx>
 +
 +//#include <gtk/gtk.h>
 +#include <unx/gtk/glomenu.h>
@@ -2556,12 +2644,29 @@ index 0000000..b61af31
 +#include <vcl/menu.hxx>
 +#include <unx/gtk/gtkinst.hxx>
 +
++#include <framework/menuconfiguration.hxx>
++
 +#include <iostream>
 +
 +using namespace std;
 +
 +
-+static void UpdateNativeMenu( GtkSalMenu* pMenu )
++static gchar* GetCommandForSpecialItem( GtkSalMenuItem* pSalMenuItem )
++{
++    gchar* aCommand = NULL;
++
++    sal_uInt16 nId = pSalMenuItem->mnId;
++
++    // If item belongs to window list, generate a command with "window-(id)" format.
++    if ( ( nId >= START_ITEMID_WINDOWLIST ) && ( nId <= END_ITEMID_WINDOWLIST ) )
++    {
++        aCommand = g_strdup_printf( "window-%d", nId );
++    }
++
++    return aCommand;
++}
++
++static void UpdateNativeMenu2( GtkSalMenu *pMenu )
 +{
 +    if ( pMenu == NULL )
 +        return;
@@ -2618,21 +2723,134 @@ index 0000000..b61af31
 +        pMenu->NativeSetItemText( nSection, nItemPos, aText );
 +        pMenu->NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
 +
++        // Some items are special, so they have different commands.
++        if ( g_strcmp0( aNativeCommand, "" ) == 0 )
++        {
++            gchar *aSpecialItemCmd = GetCommandForSpecialItem( pSalMenuItem );
++
++            if ( aSpecialItemCmd != NULL )
++            {
++                g_free( aNativeCommand );
++                aNativeCommand = aSpecialItemCmd;
++            }
++        }
++
 +        if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == NULL )
 +        {
-+            pMenu->NativeSetItemCommand( nSection, nItemPos, pSalMenuItem, aNativeCommand );
++            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE );
++            pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked );
 +            pMenu->NativeSetEnableItem( aNativeCommand, bEnabled );
++        }
++
++        GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
++
++        if ( pSubmenu && pSubmenu->GetMenu() )
++        {
++            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE );
++
++            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 ) );
++            }
++
++            g_object_unref( pSubMenuModel );
 +
-+            if ( ( itemBits & MIB_CHECKABLE ) || ( itemBits & MIB_RADIOCHECK ) )
-+                pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked );
++            pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
++            pSubmenu->SetActionGroup( pActionGroup );
 +        }
 +
 +        g_free( aNativeCommand );
 +
++        nItemPos++;
++        validItems++;
++    }
++}
++
++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 ( 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" );
++
++        // Get internal menu item values.
++        String aText = pVCLMenu->GetItemText( nId );
++        rtl::OUString aCommand( pVCLMenu->GetItemCommand( nId ) );
++        sal_Bool itemEnabled = pVCLMenu->IsItemEnabled( nId );
++        KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId );
++        sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId );
++        MenuItemBits itemBits = pVCLMenu->GetItemBits( 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->NativeSetItemText( nSection, nItemPos, aText );
++        pMenu->NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
++
++        // Some items are special, so they have different commands.
++        if ( g_strcmp0( aNativeCommand, "" ) == 0 )
++        {
++            gchar *aSpecialItemCmd = GetCommandForSpecialItem( pSalMenuItem );
++
++            if ( aSpecialItemCmd != NULL )
++            {
++                g_free( aNativeCommand );
++                aNativeCommand = aSpecialItemCmd;
++            }
++        }
++
++        if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == NULL )
++        {
++            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE );
++            pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked );
++            pMenu->NativeSetEnableItem( aNativeCommand, bEnabled );
++        }
++
 +        GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
 +
 +        if ( pSubmenu && pSubmenu->GetMenu() )
 +        {
++            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE );
++
 +            GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos );
 +
 +            if ( pSubMenuModel == NULL )
@@ -2641,15 +2859,18 @@ index 0000000..b61af31
 +                g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) );
 +            }
 +
++            g_object_unref( pSubMenuModel );
++
 +            pSubmenu->GetMenu()->Activate();
++            pSubmenu->GetMenu()->Deactivate();
 +
 +            pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
 +            pSubmenu->SetActionGroup( pActionGroup );
 +            UpdateNativeMenu( pSubmenu );
-+
-+            pSubmenu->GetMenu()->Deactivate();
 +        }
 +
++        g_free( aNativeCommand );
++
 +        nItemPos++;
 +        validItems++;
 +    }
@@ -2746,6 +2967,9 @@ index 0000000..b61af31
 +
 +        if ( gdkWindow != NULL )
 +        {
++            GMenuModel* pMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) );
++            GActionGroup* pActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) );
++
 +            XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow );
 +
 +            gchar* aDBusPath = g_strdup_printf("/window/%lu", windowId);
@@ -2759,11 +2983,11 @@ index 0000000..b61af31
 +                return;
 +
 +            // Publish the menu.
-+            if ( aDBusMenubarPath != NULL )
-+                g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pSalMenu->GetMenuModel(), NULL);
++            if ( aDBusMenubarPath != NULL && pMenuModel != NULL )
++                g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL);
 +
-+            if ( aDBusPath != NULL )
-+                g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pSalMenu->GetActionGroup(), NULL);
++            if ( aDBusPath != NULL && pActionGroup != NULL )
++                g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pActionGroup, NULL);
 +
 +            // Set window properties.
 +            gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) );
@@ -2776,8 +3000,9 @@ index 0000000..b61af31
 +            g_free( aDBusMenubarPath );
 +
 +            bDBusIsAvailable = sal_True;
-+            pSalMenu->SetVisibleMenuBar( sal_True );
-+            pMenuBar->SetDisplayable( sal_False );
++
++            if ( pMenuBar )
++                pMenuBar->SetDisplayable( sal_False );
 +        }
 +    }
 +
@@ -2797,7 +3022,6 @@ index 0000000..b61af31
 +        MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() );
 +
 +        bDBusIsAvailable = sal_False;
-+        pSalMenu->SetVisibleMenuBar( sal_False );
 +        pMenuBar->SetDisplayable( sal_True );
 +    }
 +
@@ -2823,7 +3047,7 @@ index 0000000..b61af31
 +GtkSalMenu::~GtkSalMenu()
 +{
 +    if ( mbMenuBar == sal_True ) {
-+        g_source_remove_by_user_data( this );
++//        g_source_remove_by_user_data( this );
 +
 +        ((GtkSalFrame*) mpFrame)->SetMenu( NULL );
 +
@@ -2839,14 +3063,8 @@ index 0000000..b61af31
 +    maItems.clear();
 +}
 +
-+void GtkSalMenu::SetVisibleMenuBar( sal_Bool bVisible )
-+{
-+//    mbVisible = bVisible;
-+}
-+
 +sal_Bool GtkSalMenu::VisibleMenuBar()
 +{
-+//    return mbVisible;
 +    return bDBusIsAvailable;
 +}
 +
@@ -2889,7 +3107,7 @@ index 0000000..b61af31
 +
 +    GdkWindow *gdkWindow = gtk_widget_get_window( widget );
 +
-+    if (gdkWindow) {
++    if ( gdkWindow != NULL ) {
 +        mpMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) );
 +        mpActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) );
 +
@@ -2913,11 +3131,12 @@ index 0000000..b61af31
 +        }
 +
 +        // Generate the main menu structure.
-+//        GenerateMenu( this );
++        GenerateMenu( this );
++//        UpdateNativeMenu2( this );
 +
 +        // Refresh the menu every second.
 +        // This code is a workaround until required modifications in Gtk+ are available.
-+        g_timeout_add_seconds( 1, GenerateMenu, this );
++//        g_timeout_add_seconds( 1, GenerateMenu, this );
 +    }
 +}
 +
@@ -2929,10 +3148,6 @@ index 0000000..b61af31
 +    return pMenu ? pMenu->mpFrame : NULL;
 +}
 +
-+void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
-+{
-+}
-+
 +void GtkSalMenu::NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck )
 +{
 +    if ( mpActionGroup == NULL )
@@ -2945,27 +3160,28 @@ index 0000000..b61af31
 +        GVariant *pCheckValue = NULL;
 +        GVariant *pCurrentState = g_action_group_get_action_state( mpActionGroup, aCommand );
 +
-+        if ( bits & MIB_CHECKABLE )
++        if ( bits & MIB_RADIOCHECK )
 +        {
-+            pCheckValue = g_variant_new_boolean( bCheck );
++            pCheckValue = ( bCheck == TRUE ) ? g_variant_new_string( aCommand ) : g_variant_new_string( "" );
 +        }
-+        else if ( bits & MIB_RADIOCHECK )
++        else
 +        {
-+            pCheckValue = ( bCheck == TRUE ) ? g_variant_new_string( aCommand ) : g_variant_new_string( "" );
++            // By default, all checked items are checkmark buttons.
++            if ( bCheck == TRUE || ( ( bCheck == FALSE ) && pCurrentState != NULL ) )
++                pCheckValue = g_variant_new_boolean( bCheck );
 +        }
 +
-+        if ( pCurrentState == NULL || g_variant_equal( pCurrentState, pCheckValue) == FALSE )
++        if ( pCheckValue != NULL && ( pCurrentState == NULL || g_variant_equal( pCurrentState, pCheckValue ) == FALSE ) )
 +            g_action_group_change_action_state( mpActionGroup, aCommand, pCheckValue );
++
++        if ( pCurrentState )
++            g_variant_unref( pCurrentState );
 +    }
 +
 +    if ( aCommand )
 +        g_free( aCommand );
 +}
 +
-+void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
-+{
-+}
-+
 +void GtkSalMenu::NativeSetEnableItem( gchar* aCommand, gboolean bEnable )
 +{
 +    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup );
@@ -2974,13 +3190,9 @@ index 0000000..b61af31
 +        g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bEnable );
 +}
 +
-+void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText )
-+{
-+}
-+
 +void GtkSalMenu::NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText )
 +{
-+    // Replace the "~" character with "_".
++    // Replace the '~' character with '_'.
 +    rtl::OUString aText = rText.replace( '~', '_' );
 +    rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 );
 +
@@ -2994,14 +3206,6 @@ index 0000000..b61af31
 +        g_free( aLabel );
 +}
 +
-+void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage)
-+{
-+}
-+
-+void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName )
-+{
-+}
-+
 +void GtkSalMenu::NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName )
 +{
 +    if ( rKeyName.isEmpty() )
@@ -3018,31 +3222,28 @@ index 0000000..b61af31
 +        g_free( aCurrentAccel );
 +}
 +
-+void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr )
-+{
-+}
-+
-+void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommand )
++void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
++                                       unsigned nItemPos,
++                                       sal_uInt16 nId,
++                                       const gchar* aCommand,
++                                       MenuItemBits nBits,
++                                       gboolean bChecked,
++                                       gboolean bIsSubmenu )
 +{
 +    GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup );
 +
 +    GVariant *pTarget = NULL;
 +
 +    if ( g_action_group_has_action( mpActionGroup, 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 );
-+
-+        if ( bits & MIB_CHECKABLE )
++        if ( ( nBits & MIB_CHECKABLE ) || ( bIsSubmenu == TRUE ) )
 +        {
 +            // 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->mnId, NULL, pStateType, NULL, pState );
++            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, bIsSubmenu, NULL, pStateType, NULL, pState );
 +        }
-+        else if ( bits & MIB_RADIOCHECK )
++        else if ( nBits & MIB_RADIOCHECK )
 +        {
 +            // Item is a radio button.
 +            GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
@@ -3050,12 +3251,12 @@ index 0000000..b61af31
 +            GVariant* pState = g_variant_new_string( "" );
 +            pTarget = g_variant_new_string( aCommand );
 +
-+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, pParameterType, pStateType, NULL, pState );
++            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, FALSE, pParameterType, pStateType, NULL, pState );
 +        }
 +        else
 +        {
 +            // Item is not special, so insert a stateless action.
-+            g_lo_action_group_insert( pActionGroup, aCommand, pItem->mnId );
++            g_lo_action_group_insert( pActionGroup, aCommand, nId, FALSE );
 +        }
 +    }
 +
@@ -3070,7 +3271,10 @@ index 0000000..b61af31
 +
 +        gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
 +
-+        g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
++        if ( bIsSubmenu == TRUE )
++            g_lo_menu_set_submenu_action_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand );
++        else
++            g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
 +
 +        g_free( aItemCommand );
 +    }
@@ -3079,11 +3283,7 @@ index 0000000..b61af31
 +        g_free( aCurrentCommand );
 +}
 +
-+void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
-+{
-+}
-+
-+GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand )
++GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu )
 +{
 +    GtkSalMenu* pMenu = NULL;
 +
@@ -3092,18 +3292,17 @@ index 0000000..b61af31
 +        GtkSalMenuItem *pSalItem = maItems[ nPos ];
 +
 +        String aItemCommand = mpVCLMenu->GetItemCommand( pSalItem->mnId );
-+
 +        gchar* aItemCommandStr = (gchar*) rtl::OUStringToOString( aItemCommand, RTL_TEXTENCODING_UTF8 ).getStr();
 +
 +        if ( g_strcmp0( aItemCommandStr, aCommand ) == 0 )
 +        {
-+            pMenu = this;
++            pMenu = ( bGetSubmenu == TRUE ) ? pSalItem->mpSubMenu : this;
 +            break;
 +        }
 +        else
 +        {
 +            if ( pSalItem->mpSubMenu != NULL )
-+                pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand );
++                pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand, bGetSubmenu );
 +
 +            if ( pMenu != NULL )
 +               break;
@@ -3113,6 +3312,73 @@ index 0000000..b61af31
 +    return pMenu;
 +}
 +
++void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
++{
++    // Only the menubar is allowed to dispatch commands.
++    if ( mbMenuBar != TRUE )
++        return;
++
++    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aCommand, FALSE );
++    Menu* pSubMenu = ( pSalSubMenu != NULL ) ? pSalSubMenu->GetMenu() : NULL;
++
++    MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu );
++
++    pMenuBar->HandleMenuCommandEvent( pSubMenu, itemId );
++}
++
++void GtkSalMenu::Activate( const gchar* aMenuCommand )
++{
++    if ( mbMenuBar != TRUE )
++        return;
++
++    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE );
++
++    if ( pSalSubMenu != NULL ) {
++        pSalSubMenu->mpVCLMenu->Activate();
++        UpdateNativeMenu2( pSalSubMenu );
++    }
++}
++
++void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
++{
++    if ( mbMenuBar != TRUE )
++        return;
++
++    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE );
++
++    if ( pSalSubMenu != NULL ) {
++        pSalSubMenu->mpVCLMenu->Deactivate();
++    }
++}
++
++void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
++{
++}
++
++void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
++{
++}
++
++void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText )
++{
++}
++
++void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage)
++{
++}
++
++void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName )
++{
++}
++
++void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr )
++{
++}
++
++void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
++{
++}
++
 +void GtkSalMenu::Freeze()
 +{
 +}
@@ -3125,7 +3391,6 @@ index 0000000..b61af31
 +
 +GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) :
 +    mnId( pItemData->nId ),
-+    mnBits( pItemData->nBits ),
 +    mnType( pItemData->eType ),
 +    mpVCLMenu( pItemData->pMenu ),
 +    mpParentMenu( NULL ),

-- 
LibreOffice packaging repository


Reply to: