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

Antonio Fernandez afernandez at kemper.freedesktop.org
Mon Aug 13 12:22:24 PDT 2012


 framework/inc/uielement/menubarmanager.hxx    |    2 
 framework/source/uielement/menubarmanager.cxx |   23 -
 vcl/inc/unx/gtk/glomenu.h                     |  187 +++++++----
 vcl/inc/unx/gtk/gtksalmenu.hxx                |    5 
 vcl/source/window/menu.cxx                    |   22 +
 vcl/unx/gtk/app/gtkinst.cxx                   |    2 
 vcl/unx/gtk/window/gloactiongroup.cxx         |   24 -
 vcl/unx/gtk/window/glomenu.cxx                |  421 +++++++++++++-------------
 vcl/unx/gtk/window/gtksalmenu.cxx             |  207 ++++++++----
 9 files changed, 483 insertions(+), 410 deletions(-)

New commits:
commit 0c4e826d896d6b0ceeb3ffa889333c4ccc7c511d
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Mon Aug 13 20:21:11 2012 +0100

    Menu is displayed correctly in additional instancesm but not in the main one.
    
    Change-Id: Id7d79e47efd73ddc2eeac285c28179a5aa9ecc37

diff --git a/framework/inc/uielement/menubarmanager.hxx b/framework/inc/uielement/menubarmanager.hxx
index e134431..59273e8 100644
--- a/framework/inc/uielement/menubarmanager.hxx
+++ b/framework/inc/uielement/menubarmanager.hxx
@@ -179,8 +179,6 @@ class MenuBarManager : public com::sun::star::frame::XStatusListener
         void SetItemContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rItemContainer );
         void GetPopupController( PopupControllerCache& rPopupController );
 
-        void GenerateFullMenuHierarchy( AbstractMenu* pMenu );
-
     protected:
         DECL_LINK(Highlight, void *);
         DECL_LINK( Activate, AbstractMenu * );
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
index 1072fd9..6f19829 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -2107,29 +2107,6 @@ void MenuBarManager::SetHdl()
                                                              UNO_QUERY );
 }
 
-void MenuBarManager::GenerateFullMenuHierarchy( AbstractMenu* pMenu )
-{
-    if (pMenu) {
-        for (int i=0; i < pMenu->GetItemCount(); i++)
-        {
-            sal_Int16 nId = pMenu->GetItemId( i );
-
-//            this->Activate( pMenu->GetPopupMenu( nId ) );
-//            this->Activate(pMenu);
-//            this->Deactivate(pMenu);
-
-            String aCommandLabel = pMenu->GetItemCommand( nId );
-            ::rtl::OUString aCommand( aCommandLabel );
-
-            String label = RetrieveLabelFromCommand( aCommandLabel );
-            pMenu->SetItemText( nId, label );
-
-            AddMenu( this, aCommand, nId );
-            GenerateFullMenuHierarchy( pMenu->GetPopupMenu( nId ) );
-        }
-    }
-}
-
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/gtk/glomenu.h b/vcl/inc/unx/gtk/glomenu.h
index d1df683..54c7b5b 100644
--- a/vcl/inc/unx/gtk/glomenu.h
+++ b/vcl/inc/unx/gtk/glomenu.h
@@ -1,87 +1,134 @@
-#ifndef GLOMENU_H
-#define GLOMENU_H
+/*
+ * Copyright © 2011 Canonical Ltd.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ *
+ * Author: Ryan Lortie <desrt at desrt.ca>
+ */
+
+#ifndef __G_LO_MENU_H__
+#define __G_LO_MENU_H__
 
-#include <glib-object.h>
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
 
-#define G_TYPE_LO_MENU                  (g_lo_menu_get_type())
-#define G_LO_MENU(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LO_MENU, GLOMenu))
-#define G_IS_LO_MENU(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LO_MENU))
+#define G_TYPE_LO_MENU          (g_lo_menu_get_type ())
+#define G_LO_MENU(inst)         (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+                                 G_TYPE_LO_MENU, GLOMenu))
+#define G_IS_LO_MENU(inst)      (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+                                 G_TYPE_LO_MENU))
 
-#define G_TYPE_LO_MENU_ITEM             (g_lo_menu_item_get_type())
-#define G_LO_MENU_ITEM(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LO_MENU_ITEM, GLOMenuItem))
-#define G_IS_LO_MENU_ITEM(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LO_MENU_ITEM))
+#define G_TYPE_LO_MENU_ITEM     (g_lo_menu_item_get_type ())
+#define G_LO_MENU_ITEM(inst)    (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+                                 G_TYPE_LO_MENU_ITEM, GLOMenuItem))
+#define G_IS_LO_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+                                 G_TYPE_LO_MENU_ITEM))
 
 typedef struct _GLOMenuItem GLOMenuItem;
 typedef struct _GLOMenu     GLOMenu;
 
 GLIB_AVAILABLE_IN_2_32
-GType           g_lo_menu_get_type                          (void) G_GNUC_CONST;
+GType       g_lo_menu_get_type                         (void) G_GNUC_CONST;
 GLIB_AVAILABLE_IN_2_32
+GLOMenu *     g_lo_menu_new                              (void);
+
+void        g_lo_menu_freeze                           (GLOMenu       *menu);
+
+void        g_lo_menu_insert_item                      (GLOMenu       *menu,
+                                                        gint         position,
+                                                        GLOMenuItem   *item);
+void        g_lo_menu_prepend_item                     (GLOMenu       *menu,
+                                                        GLOMenuItem   *item);
+void        g_lo_menu_append_item                      (GLOMenu       *menu,
+                                                        GLOMenuItem   *item);
+void        g_lo_menu_remove                           (GLOMenu       *menu,
+                                                        gint         position);
+
+void        g_lo_menu_insert                           (GLOMenu       *menu,
+                                                        gint         position,
+                                                        const gchar *label,
+                                                        const gchar *detailed_action);
+void        g_lo_menu_prepend                          (GLOMenu       *menu,
+                                                        const gchar *label,
+                                                        const gchar *detailed_action);
+void        g_lo_menu_append                           (GLOMenu       *menu,
+                                                        const gchar *label,
+                                                        const gchar *detailed_action);
+
+void        g_lo_menu_insert_section                   (GLOMenu       *menu,
+                                                        gint         position,
+                                                        const gchar *label,
+                                                        GMenuModel  *section);
+void        g_lo_menu_prepend_section                  (GLOMenu       *menu,
+                                                        const gchar *label,
+                                                        GMenuModel  *section);
+void        g_lo_menu_append_section                   (GLOMenu       *menu,
+                                                        const gchar *label,
+                                                        GMenuModel  *section);
+
+void        g_lo_menu_insert_submenu                   (GLOMenu       *menu,
+                                                        gint        position,
+                                                        const gchar *label,
+                                                        GMenuModel  *submenu);
+void        g_lo_menu_prepend_submenu                  (GLOMenu       *menu,
+                                                        const gchar *label,
+                                                        GMenuModel  *submenu);
+void        g_lo_menu_append_submenu                   (GLOMenu       *menu,
+                                                        const gchar *label,
+                                                        GMenuModel  *submenu);
+
+
+GType       g_lo_menu_item_get_type                    (void) G_GNUC_CONST;
+GLOMenuItem * g_lo_menu_item_new                         (const gchar *label,
+                                                        const gchar *detailed_action);
+
+GLOMenuItem * g_lo_menu_item_new_submenu                 (const gchar *label,
+                                                        GMenuModel  *submenu);
+
+GLOMenuItem * g_lo_menu_item_new_section                 (const gchar *label,
+                                                        GMenuModel  *section);
 
-GLOMenu *       g_lo_menu_new                               (void);
-void            g_lo_menu_insert_item                       (GLOMenu        *menu,
-                                                             gint            position,
-                                                             GLOMenuItem    *item);
-void            g_lo_menu_insert                            (GLOMenu        *menu,
-                                                             gint            position,
-                                                             const gchar    *label,
-                                                             const gchar    *detailed_action);
-void            g_lo_menu_append                            (GLOMenu        *menu,
-                                                             const gchar    *label,
-                                                             const gchar    *detailed_action);
-void            g_lo_menu_append_item                       (GLOMenu        *menu,
-                                                             GLOMenuItem    *item);
-void            g_lo_menu_insert_section                    (GLOMenu        *menu,
-                                                             gint            position,
-                                                             const gchar    *label,
-                                                             GMenuModel     *section);
-void            g_lo_menu_prepend_section                   (GLOMenu        *menu,
-                                                             const gchar    *label,
-                                                             GMenuModel     *section);
-void            g_lo_menu_append_section                    (GLOMenu        *menu,
-                                                             const gchar    *label,
-                                                             GMenuModel     *section);
-void            g_lo_menu_insert_submenu                    (GLOMenu        *menu,
-                                                             gint            position,
-                                                             const gchar    *label,
-                                                             GMenuModel     *submenu);
-void            g_lo_menu_append_submenu                    (GLOMenu        *menu,
-                                                             const gchar    *label,
-                                                             GMenuModel     *submenu);
-
-GType           g_lo_menu_item_get_type                     (void) G_GNUC_CONST;
-GLOMenuItem *   g_lo_menu_item_new                          (const gchar    *label,
-                                                             const gchar    *detailed_action);
-GLOMenuItem *   g_lo_menu_item_new_submenu                  (const gchar    *label,
-                                                             GMenuModel     *submenu);
-GLOMenuItem *   g_lo_menu_item_new_section                  (const gchar    *label,
-                                                             GMenuModel     *section);
-void            g_lo_menu_item_set_attribute_value          (GLOMenuItem    *menu_item,
-                                                             const gchar    *attribute,
-                                                             GVariant       *value);
-void            g_lo_menu_item_set_link                     (GLOMenuItem    *menu_item,
-                                                             const gchar    *link,
-                                                             GMenuModel     *model);
-void            g_lo_menu_item_set_label                    (GLOMenuItem    *menu_item,
-                                                             const gchar    *label);
-void            g_lo_menu_item_set_submenu                  (GLOMenuItem    *menu_item,
-                                                             GMenuModel     *submenu);
-void            g_lo_menu_item_set_section                  (GLOMenuItem    *menu_item,
-                                                             GMenuModel     *section);
-void            g_lo_menu_item_set_action_and_target_value  (GLOMenuItem    *menu_item,
-                                                             const gchar    *action,
-                                                             GVariant       *target_value);
-void            g_lo_menu_item_set_action_and_target        (GLOMenuItem    *menu_item,
-                                                             const gchar    *action,
-                                                             const gchar    *format_string,
-                                                             ...);
-void            g_lo_menu_item_set_detailed_action          (GLOMenuItem    *menu_item,
-                                                             const gchar    *detailed_action);
+void        g_lo_menu_item_set_attribute_value         (GLOMenuItem   *menu_item,
+                                                        const gchar *attribute,
+                                                        GVariant    *value);
+void        g_lo_menu_item_set_attribute               (GLOMenuItem   *menu_item,
+                                                        const gchar *attribute,
+                                                        const gchar *format_string,
+                                                        ...);
+void        g_lo_menu_item_set_link                    (GLOMenuItem   *menu_item,
+                                                        const gchar *link,
+                                                        GMenuModel  *model);
+void        g_lo_menu_item_set_label                   (GLOMenuItem   *menu_item,
+                                                     const gchar *label);
+void        g_lo_menu_item_set_submenu                 (GLOMenuItem   *menu_item,
+                                                     GMenuModel  *submenu);
+void        g_lo_menu_item_set_section                 (GLOMenuItem   *menu_item,
+                                                     GMenuModel  *section);
+void        g_lo_menu_item_set_action_and_target_value (GLOMenuItem   *menu_item,
+                                                     const gchar *action,
+                                                     GVariant    *target_value);
+void        g_lo_menu_item_set_action_and_target       (GLOMenuItem   *menu_item,
+                                                     const gchar *action,
+                                                     const gchar *format_string,
+                                                     ...);
+void        g_lo_menu_item_set_detailed_action         (GLOMenuItem   *menu_item,
+                                                     const gchar *detailed_action);
 
 G_END_DECLS
 
+#endif /* __G_LO_MENU_H__ */
 
-#endif // GLOMENU_H
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 3d1073b..67adec4 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -62,6 +62,7 @@ public:
     const GtkSalFrame*                      mpFrame;
 
     // DBus variables
+    gchar*                                  aDBusPath;
     gchar*                                  aDBusMenubarPath;
     GDBusConnection*                        pSessionBus;
     sal_Int32                               mBusId;
@@ -71,8 +72,6 @@ public:
     // GMenuModel attributes
     GMenuModel*                             mpMenuModel;
     GMenuModel*                             mpCurrentSection;
-//    GLOMenu*                                mpParentMenuModel;
-//    std::vector< GLOMenu* >                 maSectionMenus;
 
     GtkSalMenu( sal_Bool bMenuBar );
     virtual ~GtkSalMenu();
@@ -109,7 +108,7 @@ public:
     GtkSalMenu*         mpParentMenu;         // The menu in which this menu item is inserted
     GtkSalMenu*         mpSubMenu;            // Sub menu of this item (if defined)
     GMenuModel*         mpParentSection;      // Section where this item is added.
-    GMenuItem*          mpMenuItem;           // The GMenuItem
+    GLOMenuItem*        mpMenuItem;           // The GMenuItem
     GAction*            mpAction;             // The GAction associated with this item
 };
 
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 2361a18..3a14ca6 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -6091,6 +6091,7 @@ void printMenu( AbstractMenu* pMenu ) {
 
                 if (itemData->pSubMenu) {
                     cout << ">> SUBMENU <<" << endl;
+                    //FIXME: This callback would introduce some noise in accessibility software.
                     itemData->pSubMenu->Activate();
                     printMenu( itemData->pSubMenu );
                 }
@@ -6099,9 +6100,26 @@ void printMenu( AbstractMenu* pMenu ) {
     }
 }
 
+void generateMenuHierarchy( AbstractMenu* pMenu ) {
+    if ( pMenu ) {
+        sal_uInt16 itemCount = pMenu->GetItemCount();
+        MenuItemList *items = ((Menu*)pMenu)->GetItemList();
+
+        for (int i=0; i < itemCount; i++) {
+            MenuItemData *itemData = items->GetDataFromPos(i);
+
+            if (itemData->pSubMenu) {
+                itemData->pSubMenu->Activate();
+                generateMenuHierarchy( itemData->pSubMenu );
+            }
+        }
+    }
+}
+
 void Menu::Freeze() {
-    printMenu( this );
-    cout << "============================================================" << endl;
+//    printMenu( this );
+    generateMenuHierarchy( this );
+//    cout << "============================================================" << endl;
 
     SalMenu *pSalMenu = ImplGetSalMenu();
 
diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx
index dceca0d..103eb70 100644
--- a/vcl/unx/gtk/app/gtkinst.cxx
+++ b/vcl/unx/gtk/app/gtkinst.cxx
@@ -544,7 +544,7 @@ void GtkInstance::DestroyMenuItem( SalMenuItem* pItem )
 {
     (void)pItem;
 //    delete pItem;
-    OSL_ENSURE( pItem == 0, "DestroyMenu called with non-native menus" );
+//    OSL_ENSURE( pItem == 0, "DestroyMenu called with non-native menus" );
 }
 
 SalTimer* GtkInstance::CreateSalTimer()
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
index dc3fb39..b728e4a 100644
--- a/vcl/unx/gtk/window/gloactiongroup.cxx
+++ b/vcl/unx/gtk/window/gloactiongroup.cxx
@@ -25,7 +25,6 @@ G_DEFINE_TYPE_WITH_CODE (GLOActionGroup,
 static gchar **
 g_lo_action_group_list_actions (GActionGroup *group)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
     GHashTableIter iter;
     gint n, i = 0;
@@ -53,7 +52,6 @@ g_lo_action_group_query_action (GActionGroup        *group,
                                 GVariant           **state_hint,
                                 GVariant           **state)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
     GAction *action;
 
@@ -85,7 +83,6 @@ g_lo_action_group_change_state (GActionGroup *group,
                                 const gchar  *action_name,
                                 GVariant     *value)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
     GAction *action;
 
@@ -102,9 +99,6 @@ g_lo_action_group_activate (GActionGroup *group,
                             const gchar  *action_name,
                             GVariant     *parameter)
 {
-
-
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
     GAction *action;
 
@@ -114,8 +108,6 @@ g_lo_action_group_activate (GActionGroup *group,
         return;
 
     g_action_activate (action, parameter);
-
-
 }
 
 static void
@@ -123,7 +115,6 @@ action_enabled_notify (GAction     *action,
                        GParamSpec  *pspec,
                        gpointer     user_data)
 {
-    puts(__FUNCTION__);
     g_action_group_action_enabled_changed (G_ACTION_GROUP( user_data ),
                                            g_action_get_name (action),
                                            g_action_get_enabled (action));
@@ -134,7 +125,6 @@ action_state_notify (GAction    *action,
                      GParamSpec *pspec,
                      gpointer    user_data)
 {
-    puts(__FUNCTION__);
     GVariant *value;
 
     value = g_action_get_state (action);
@@ -149,7 +139,6 @@ g_lo_action_group_disconnect (gpointer key,
                               gpointer value,
                               gpointer user_data)
 {
-    puts(__FUNCTION__);
     g_signal_handlers_disconnect_by_func (value, (gpointer) action_enabled_notify,
                                           user_data);
     g_signal_handlers_disconnect_by_func (value, (gpointer) action_state_notify,
@@ -160,7 +149,6 @@ static GAction *
 g_lo_action_group_lookup_action (GActionMap     *action_map,
                                  const gchar    *action_name)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (action_map);
 
     return G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
@@ -170,7 +158,6 @@ static void
 g_lo_action_group_add_action (GActionMap *action_map,
                               GAction    *action)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (action_map);
     const gchar *action_name;
     GAction *old_action;
@@ -206,7 +193,6 @@ static void
 g_lo_action_group_remove_action (GActionMap  *action_map,
                                  const gchar *action_name)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (action_map);
     GAction *action;
 
@@ -223,7 +209,6 @@ g_lo_action_group_remove_action (GActionMap  *action_map,
 static void
 g_lo_action_group_finalize (GObject *object)
 {
-    puts(__FUNCTION__);
     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (object);
 
     g_hash_table_foreach (loGroup->priv->table,
@@ -238,7 +223,6 @@ g_lo_action_group_finalize (GObject *object)
 static void
 g_lo_action_group_init (GLOActionGroup *group)
 {
-    puts(__FUNCTION__);
     group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
                                                  G_TYPE_LO_ACTION_GROUP,
                                                  GLOActionGroupPrivate);
@@ -249,7 +233,6 @@ g_lo_action_group_init (GLOActionGroup *group)
 static void
 g_lo_action_group_class_init (GLOActionGroupClass *klass)
 {
-    puts(__FUNCTION__);
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
     object_class->finalize = g_lo_action_group_finalize;
@@ -260,7 +243,6 @@ g_lo_action_group_class_init (GLOActionGroupClass *klass)
 static void
 g_lo_action_group_iface_init (GActionGroupInterface *iface)
 {
-    puts(__FUNCTION__);
     iface->list_actions = g_lo_action_group_list_actions;
     iface->query_action = g_lo_action_group_query_action;
     iface->change_action_state = g_lo_action_group_change_state;
@@ -270,7 +252,6 @@ g_lo_action_group_iface_init (GActionGroupInterface *iface)
 static void
 g_lo_action_group_map_iface_init (GActionMapInterface *iface)
 {
-    puts(__FUNCTION__);
     iface->add_action = g_lo_action_group_add_action;
     iface->remove_action = g_lo_action_group_remove_action;
     iface->lookup_action = g_lo_action_group_lookup_action;
@@ -279,7 +260,6 @@ g_lo_action_group_map_iface_init (GActionMapInterface *iface)
 GLOActionGroup *
 g_lo_action_group_new (void)
 {
-    puts(__FUNCTION__);
     return G_LO_ACTION_GROUP( g_object_new (G_TYPE_LO_ACTION_GROUP, NULL) );
 }
 
@@ -287,7 +267,6 @@ GAction *
 g_lo_action_group_lookup (GLOActionGroup *group,
                           const gchar    *action_name)
 {
-    puts(__FUNCTION__);
     g_return_val_if_fail (G_IS_LO_ACTION_GROUP (group), NULL);
 
     return g_action_map_lookup_action (G_ACTION_MAP (group), action_name);
@@ -297,7 +276,6 @@ void
 g_lo_action_group_insert (GLOActionGroup *group,
                           GAction        *action)
 {
-    puts(__FUNCTION__);
     g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
 
     g_action_map_add_action (G_ACTION_MAP (group), action);
@@ -307,7 +285,6 @@ void
 g_lo_action_group_remove (GLOActionGroup *group,
                           const gchar    *action_name)
 {
-    puts(__FUNCTION__);
     g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
 
     g_action_map_remove_action (G_ACTION_MAP (group), action_name);
@@ -319,7 +296,6 @@ g_lo_action_group_add_entries (GLOActionGroup     *group,
                                gint                n_entries,
                                gpointer            user_data)
 {
-    puts(__FUNCTION__);
     g_action_map_add_action_entries (G_ACTION_MAP (group), entries, n_entries, user_data);
 }
 
diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx
index 0da7245..7ada474 100644
--- a/vcl/unx/gtk/window/glomenu.cxx
+++ b/vcl/unx/gtk/window/glomenu.cxx
@@ -1,53 +1,72 @@
+/*
+ * Copyright © 2011 Canonical Ltd.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ *
+ * Author: Ryan Lortie <desrt at desrt.ca>
+ */
+
 #include <stdio.h>
 #include <string.h>
 
 #include <unx/gtk/glomenu.h>
 
+
 struct _GLOMenuItem
 {
-  GObject parent_instance;
+    GObject parent_instance;
 
-  GHashTable *attributes;
-  GHashTable *links;
-  gboolean    cow;
+    GHashTable *attributes;
+    GHashTable *links;
+    gboolean    cow;
 };
 
 typedef GObjectClass GLOMenuItemClass;
 
-
 struct _GLOMenu
 {
-    GMenuModel  parent_instance;
+    GMenuModel parent_instance;
 
-    GArray      *items;
-//    gboolean    mutable;
+    GArray   *items;
+//    gboolean  mutable;
 };
 
 typedef GMenuModelClass GLOMenuClass;
 
-G_DEFINE_TYPE (GLOMenu, g_lo_menu, G_TYPE_MENU_MODEL);
-G_DEFINE_TYPE (GLOMenuItem, g_lo_menu_item, G_TYPE_OBJECT);
+G_DEFINE_TYPE (GLOMenu, g_lo_menu, G_TYPE_MENU_MODEL)
+G_DEFINE_TYPE (GLOMenuItem, g_lo_menu_item, G_TYPE_OBJECT)
 
 struct item
 {
-  GHashTable *attributes;
-  GHashTable *links;
+    GHashTable *attributes;
+    GHashTable *links;
 };
 
 static gboolean
 g_lo_menu_is_mutable (GMenuModel *model)
 {
-    puts(__FUNCTION__);
-//  GMenu *menu = G_MENU (model);
+//    GMenu *menu = G_MENU (model);
 
-//  return menu->mutable;
+//    return menu->mutable;
     return TRUE;
 }
 
 static gint
 g_lo_menu_get_n_items (GMenuModel *model)
 {
-    puts(__FUNCTION__);
     GLOMenu *menu = G_LO_MENU (model);
 
     return menu->items->len;
@@ -55,10 +74,9 @@ g_lo_menu_get_n_items (GMenuModel *model)
 
 static void
 g_lo_menu_get_item_attributes (GMenuModel  *model,
-                               gint         position,
-                               GHashTable **table)
+                            gint         position,
+                            GHashTable **table)
 {
-    puts(__FUNCTION__);
     GLOMenu *menu = G_LO_MENU (model);
 
     *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).attributes);
@@ -66,87 +84,69 @@ g_lo_menu_get_item_attributes (GMenuModel  *model,
 
 static void
 g_lo_menu_get_item_links (GMenuModel  *model,
-                          gint         position,
-                          GHashTable **table)
+                       gint         position,
+                       GHashTable **table)
 {
-    puts(__FUNCTION__);
     GLOMenu *menu = G_LO_MENU (model);
 
     *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).links);
 }
 
-static GMenuLinkIter *
-g_lo_menu_real_iterate_item_links (GMenuModel *model,
-                                      gint        item_index)
+void
+g_lo_menu_insert_item (GLOMenu     *menu,
+                    gint       position,
+                    GLOMenuItem *item)
 {
-    puts(__FUNCTION__);
-    GHashTable *table = NULL;
-    GMenuLinkIter *result;
+    struct item new_item;
 
-    G_MENU_MODEL_GET_CLASS (model)
-            ->get_item_links (model, item_index, &table);
+    g_return_if_fail (G_IS_LO_MENU (menu));
+    g_return_if_fail (G_IS_LO_MENU_ITEM (item));
 
-    if (table)
-    {
-//        GMenuLinkHashIter *iter = g_object_new (g_menu_link_hash_iter_get_type (), NULL);
-//        g_hash_table_iter_init (&iter->iter, table);
-//        iter->table = g_hash_table_ref (table);
-//        result = G_MENU_LINK_ITER (iter);
-    }
-    else
-    {
-        g_critical ("GMenuModel implementation '%s' doesn't override iterate_item_links() "
-                    "and fails to return sane values from get_item_links()",
-                    G_OBJECT_TYPE_NAME (model));
-        result = NULL;
-    }
+    if (position < 0 || position > (gint) menu->items->len)
+        position = menu->items->len;
 
-    if (table != NULL)
-        g_hash_table_unref (table);
+    new_item.attributes = g_hash_table_ref (item->attributes);
+    new_item.links = g_hash_table_ref (item->links);
+    item->cow = TRUE;
 
-    return result;
+    g_array_insert_val (menu->items, position, new_item);
+    g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1);
 }
 
-static GMenuModel *
-g_lo_menu_real_get_item_link (GMenuModel  *model,
-                                 gint         item_index,
-                                 const gchar *link)
+void
+g_lo_menu_prepend_item (GLOMenu     *menu,
+                     GLOMenuItem *item)
 {
-    puts(__FUNCTION__);
-    GHashTable *table = NULL;
-    GMenuModel *value = NULL;
-
-    G_MENU_MODEL_GET_CLASS (model)
-            ->get_item_links (model, item_index, &table);
-
-    if (table != NULL)
-        value = G_MENU_MODEL( g_hash_table_lookup (table, link) );
-    else
-        g_assert_not_reached ();
+    g_lo_menu_insert_item (menu, 0, item);
+}
 
-    if (value != NULL)
-        g_object_ref (value);
+void
+g_lo_menu_append_item (GLOMenu     *menu,
+                    GLOMenuItem *item)
+{
+    g_lo_menu_insert_item (menu, -1, item);
+}
 
-    if (table != NULL)
-        g_hash_table_unref (table);
+void
+g_lo_menu_freeze (GLOMenu *menu)
+{
+    g_return_if_fail (G_IS_LO_MENU (menu));
 
-    return value;
+//    menu->mutable = FALSE;
 }
 
 GLOMenu *
 g_lo_menu_new (void)
 {
-    puts(__FUNCTION__);
     return G_LO_MENU( g_object_new (G_TYPE_LO_MENU, NULL) );
 }
 
 void
-g_lo_menu_insert (GLOMenu       *menu,
-                  gint           position,
-                  const gchar   *label,
-                  const gchar   *detailed_action)
+g_lo_menu_insert (GLOMenu     *menu,
+                  gint         position,
+                  const gchar *label,
+                  const gchar *detailed_action)
 {
-    puts(__FUNCTION__);
     GLOMenuItem *menu_item;
 
     menu_item = g_lo_menu_item_new (label, detailed_action);
@@ -155,19 +155,26 @@ g_lo_menu_insert (GLOMenu       *menu,
 }
 
 void
-g_lo_menu_append (GLOMenu       *menu,
-                  const gchar   *label,
-                  const gchar   *detailed_action)
+g_lo_menu_prepend (GLOMenu     *menu,
+                   const gchar *label,
+                   const gchar *detailed_action)
+{
+    g_lo_menu_insert (menu, 0, label, detailed_action);
+}
+
+void
+g_lo_menu_append (GLOMenu     *menu,
+                  const gchar *label,
+                  const gchar *detailed_action)
 {
-    puts(__FUNCTION__);
     g_lo_menu_insert (menu, -1, label, detailed_action);
 }
 
 void
-g_lo_menu_insert_section (GLOMenu       *menu,
-                          gint          position,
-                          const gchar   *label,
-                          GMenuModel    *section)
+g_lo_menu_insert_section (GLOMenu     *menu,
+                          gint         position,
+                          const gchar *label,
+                          GMenuModel  *section)
 {
     GLOMenuItem *menu_item;
 
@@ -177,28 +184,26 @@ g_lo_menu_insert_section (GLOMenu       *menu,
 }
 
 void
-g_lo_menu_prepend_section (GLOMenu      *menu,
-                           const gchar  *label,
-                           GMenuModel   *section)
+g_lo_menu_prepend_section (GLOMenu     *menu,
+                           const gchar *label,
+                           GMenuModel  *section)
 {
     g_lo_menu_insert_section (menu, 0, label, section);
 }
 
 void
-g_lo_menu_append_section (GLOMenu       *menu,
-                          const gchar   *label,
-                          GMenuModel    *section)
+g_lo_menu_append_section (GLOMenu     *menu,
+                          const gchar *label,
+                          GMenuModel  *section)
 {
     g_lo_menu_insert_section (menu, -1, label, section);
 }
 
-
-
 void
-g_lo_menu_insert_submenu (GLOMenu       *menu,
-                          gint           position,
-                          const gchar   *label,
-                          GMenuModel    *submenu)
+g_lo_menu_insert_submenu (GLOMenu     *menu,
+                          gint         position,
+                          const gchar *label,
+                          GMenuModel  *submenu)
 {
     GLOMenuItem *menu_item;
 
@@ -208,36 +213,46 @@ g_lo_menu_insert_submenu (GLOMenu       *menu,
 }
 
 void
-g_lo_menu_append_submenu (GLOMenu       *menu,
-                          const gchar   *label,
-                          GMenuModel    *submenu)
+g_lo_menu_prepend_submenu (GLOMenu     *menu,
+                           const gchar *label,
+                           GMenuModel  *submenu)
+{
+    g_lo_menu_insert_submenu (menu, 0, label, submenu);
+}
+
+void
+g_lo_menu_append_submenu (GLOMenu     *menu,
+                          const gchar *label,
+                          GMenuModel  *submenu)
 {
-    puts(__FUNCTION__);
     g_lo_menu_insert_submenu (menu, -1, label, submenu);
 }
 
 static void
 g_lo_menu_clear_item (struct item *item)
 {
-    puts(__FUNCTION__);
     if (item->attributes != NULL)
         g_hash_table_unref (item->attributes);
     if (item->links != NULL)
         g_hash_table_unref (item->links);
 }
 
-static void
-g_lo_menu_dispose (GObject *gobject)
+void
+g_lo_menu_remove (GLOMenu *menu,
+                  gint     position)
 {
-    puts(__FUNCTION__);
-    G_OBJECT_CLASS (g_lo_menu_parent_class)->dispose (gobject);
+    g_return_if_fail (G_IS_LO_MENU (menu));
+    g_return_if_fail (0 <= position && position < (gint) menu->items->len);
+
+    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);
 }
 
 static void
-g_lo_menu_finalize (GObject *gobject)
+g_lo_menu_finalize (GObject *object)
 {
-    puts(__FUNCTION__);
-    GLOMenu *menu = G_LO_MENU (gobject);
+    GLOMenu *menu = G_LO_MENU (object);
     struct item *items;
     gint n_items;
     gint i;
@@ -248,13 +263,20 @@ g_lo_menu_finalize (GObject *gobject)
         g_lo_menu_clear_item (&items[i]);
     g_free (items);
 
-    G_OBJECT_CLASS (g_lo_menu_parent_class)->finalize (gobject);
+    G_OBJECT_CLASS (g_lo_menu_parent_class)
+            ->finalize (object);
+}
+
+static void
+g_lo_menu_init (GLOMenu *menu)
+{
+    menu->items = g_array_new (FALSE, FALSE, sizeof (struct item));
+//    menu->mutable = TRUE;
 }
 
 static void
 g_lo_menu_class_init (GLOMenuClass *klass)
 {
-    puts(__FUNCTION__);
     GMenuModelClass *model_class = G_MENU_MODEL_CLASS (klass);
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
@@ -264,94 +286,52 @@ g_lo_menu_class_init (GLOMenuClass *klass)
     model_class->get_n_items = g_lo_menu_get_n_items;
     model_class->get_item_attributes = g_lo_menu_get_item_attributes;
     model_class->get_item_links = g_lo_menu_get_item_links;
-    model_class->iterate_item_links = g_lo_menu_real_iterate_item_links;
-    model_class->get_item_link = g_lo_menu_real_get_item_link;
 }
 
-static void
-g_lo_menu_init (GLOMenu *self)
-{
-    puts(__FUNCTION__);
-    self->items = g_array_new (FALSE, FALSE, sizeof (struct item));
-}
-
-void
-g_lo_menu_insert_item (GLOMenu      *menu,
-                       gint          position,
-                       GLOMenuItem  *item)
-{
-    puts(__FUNCTION__);
-    struct item new_item;
-
-    g_return_if_fail (G_IS_LO_MENU (menu));
-    g_return_if_fail (G_IS_LO_MENU_ITEM (item));
-
-    if (position < 0 || position > menu->items->len)
-      position = menu->items->len;
-
-    new_item.attributes = g_hash_table_ref (item->attributes);
-    new_item.links = g_hash_table_ref (item->links);
-    item->cow = TRUE;
-
-    g_array_insert_val (menu->items, position, new_item);
-    g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1);
-}
-
-void
-g_lo_menu_append_item (GLOMenu      *menu,
-                       GLOMenuItem  *item)
-{
-  g_lo_menu_insert_item (menu, -1, item);
-}
-
-/*
- * GLOMenuItem
- */
 
 static void
 g_lo_menu_item_clear_cow (GLOMenuItem *menu_item)
 {
-  if (menu_item->cow)
+    if (menu_item->cow)
     {
-      GHashTableIter iter;
-      GHashTable *newHash;
-      gpointer key;
-      gpointer val;
-
-      newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
-      g_hash_table_iter_init (&iter, menu_item->attributes);
-      while (g_hash_table_iter_next (&iter, &key, &val))
-          g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_variant_ref ((GVariant*) val));
-      g_hash_table_unref (menu_item->attributes);
-      menu_item->attributes = newHash;
-
-      newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
-      g_hash_table_iter_init (&iter, menu_item->links);
-      while (g_hash_table_iter_next (&iter, &key, &val))
-        g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_object_ref ((GVariant*) val));
-      g_hash_table_unref (menu_item->links);
-      menu_item->links = newHash;
-
-      menu_item->cow = FALSE;
+        GHashTableIter iter;
+        GHashTable *newHash;
+        gpointer key;
+        gpointer val;
+
+        newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
+        g_hash_table_iter_init (&iter, menu_item->attributes);
+        while (g_hash_table_iter_next (&iter, &key, &val))
+            g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_variant_ref ((GVariant*) val));
+        g_hash_table_unref (menu_item->attributes);
+        menu_item->attributes = newHash;
+
+        newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
+        g_hash_table_iter_init (&iter, menu_item->links);
+        while (g_hash_table_iter_next (&iter, &key, &val))
+            g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_object_ref (val));
+        g_hash_table_unref (menu_item->links);
+        menu_item->links = newHash;
+
+        menu_item->cow = FALSE;
     }
 }
 
 static void
 g_lo_menu_item_finalize (GObject *object)
 {
-    puts(__FUNCTION__);
     GLOMenuItem *menu_item = G_LO_MENU_ITEM (object);
 
     g_hash_table_unref (menu_item->attributes);
     g_hash_table_unref (menu_item->links);
 
-    G_OBJECT_CLASS (g_lo_menu_item_parent_class)->finalize (object);
+    G_OBJECT_CLASS (g_lo_menu_item_parent_class)
+            ->finalize (object);
 }
 
 static void
 g_lo_menu_item_init (GLOMenuItem *menu_item)
 {
-    puts(__FUNCTION__);
     menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
     menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
     menu_item->cow = FALSE;
@@ -360,10 +340,16 @@ g_lo_menu_item_init (GLOMenuItem *menu_item)
 static void
 g_lo_menu_item_class_init (GLOMenuItemClass *klass)
 {
-    puts(__FUNCTION__);
     klass->finalize = g_lo_menu_item_finalize;
 }
 
+/* We treat attribute names the same as GSettings keys:
+ * - only lowercase ascii, digits and '-'
+ * - must start with lowercase
+ * - must not end with '-'
+ * - no consecutive '-'
+ * - not longer than 1024 chars
+ */
 static gboolean
 valid_attribute_name (const gchar *name)
 {
@@ -397,7 +383,6 @@ g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item,
                                     const gchar *attribute,
                                     GVariant    *value)
 {
-    puts(__FUNCTION__);
     g_return_if_fail (G_IS_LO_MENU_ITEM (menu_item));
     g_return_if_fail (attribute != NULL);
     g_return_if_fail (valid_attribute_name (attribute));
@@ -411,6 +396,28 @@ g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item,
 }
 
 void
+g_lo_menu_item_set_attribute (GLOMenuItem *menu_item,
+                              const gchar *attribute,
+                              const gchar *format_string,
+                              ...)
+{
+    GVariant *value;
+
+    if (format_string != NULL)
+    {
+        va_list ap;
+
+        va_start (ap, format_string);
+        value = g_variant_new_va (format_string, NULL, &ap);
+        va_end (ap);
+    }
+    else
+        value = NULL;
+
+    g_lo_menu_item_set_attribute_value (menu_item, attribute, value);
+}
+
+void
 g_lo_menu_item_set_link (GLOMenuItem *menu_item,
                          const gchar *link,
                          GMenuModel  *model)
@@ -428,10 +435,9 @@ g_lo_menu_item_set_link (GLOMenuItem *menu_item,
 }
 
 void
-g_lo_menu_item_set_label (GLOMenuItem   *menu_item,
-                          const gchar   *label)
+g_lo_menu_item_set_label (GLOMenuItem *menu_item,
+                          const gchar *label)
 {
-    puts(__FUNCTION__);
     GVariant *value;
 
     if (label != NULL)
@@ -461,49 +467,48 @@ g_lo_menu_item_set_action_and_target_value (GLOMenuItem *menu_item,
                                             const gchar *action,
                                             GVariant    *target_value)
 {
-  GVariant *action_value;
+    GVariant *action_value;
 
-  if (action != NULL)
+    if (action != NULL)
     {
-      action_value = g_variant_new_string (action);
+        action_value = g_variant_new_string (action);
     }
-  else
+    else
     {
-      action_value = NULL;
-      target_value = NULL;
+        action_value = NULL;
+        target_value = NULL;
     }
 
-  g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ACTION, action_value);
-  g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_TARGET, target_value);
+    g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ACTION, action_value);
+    g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_TARGET, target_value);
 }
 
 void
-g_lo_menu_item_set_action_and_target (GLOMenuItem   *menu_item,
-                                      const gchar   *action,
-                                      const gchar   *format_string,
+g_lo_menu_item_set_action_and_target (GLOMenuItem *menu_item,
+                                      const gchar *action,
+                                      const gchar *format_string,
                                       ...)
 {
-  GVariant *value;
+    GVariant *value;
 
-  if (format_string != NULL)
+    if (format_string != NULL)
     {
-      va_list ap;
+        va_list ap;
 
-      va_start (ap, format_string);
-      value = g_variant_new_va (format_string, NULL, &ap);
-      va_end (ap);
+        va_start (ap, format_string);
+        value = g_variant_new_va (format_string, NULL, &ap);
+        va_end (ap);
     }
-  else
-    value = NULL;
+    else
+        value = NULL;
 
-  g_lo_menu_item_set_action_and_target_value (menu_item, action, value);
+    g_lo_menu_item_set_action_and_target_value (menu_item, action, value);
 }
 
 void
 g_lo_menu_item_set_detailed_action (GLOMenuItem *menu_item,
                                     const gchar *detailed_action)
 {
-    puts(__FUNCTION__);
     const gchar *sep;
 
     sep = strstr (detailed_action, "::");
@@ -525,16 +530,15 @@ GLOMenuItem *
 g_lo_menu_item_new (const gchar *label,
                     const gchar *detailed_action)
 {
-    puts(__FUNCTION__);
     GLOMenuItem *menu_item;
 
     menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
 
     if (label != NULL)
-      g_lo_menu_item_set_label (menu_item, label);
+        g_lo_menu_item_set_label (menu_item, label);
 
     if (detailed_action != NULL)
-      g_lo_menu_item_set_detailed_action (menu_item, detailed_action);
+        g_lo_menu_item_set_detailed_action (menu_item, detailed_action);
 
     return menu_item;
 }
@@ -543,16 +547,16 @@ GLOMenuItem *
 g_lo_menu_item_new_submenu (const gchar *label,
                             GMenuModel  *submenu)
 {
-  GLOMenuItem *menu_item;
+    GLOMenuItem *menu_item;
 
-  menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
+    menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
 
-  if (label != NULL)
-    g_lo_menu_item_set_label (menu_item, label);
+    if (label != NULL)
+        g_lo_menu_item_set_label (menu_item, label);
 
-  g_lo_menu_item_set_submenu (menu_item, submenu);
+    g_lo_menu_item_set_submenu (menu_item, submenu);
 
-  return menu_item;
+    return menu_item;
 }
 
 GLOMenuItem *
@@ -561,7 +565,7 @@ g_lo_menu_item_new_section (const gchar *label,
 {
     GLOMenuItem *menu_item;
 
-    menu_item = G_LO_MENU_ITEM ( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
+    menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
 
     if (label != NULL)
         g_lo_menu_item_set_label (menu_item, label);
@@ -571,4 +575,3 @@ g_lo_menu_item_new_section (const gchar *label,
     return menu_item;
 }
 
-
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 08aa521..c0a69c1 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -11,8 +11,32 @@
 
 using namespace std;
 
-#define GTK_MENU_BUS_NAME   "org.libreoffice"
-#define GTK_MENU_OBJ_PATH   "/org/libreoffice"
+#define GTK_MENU_BUS_NAME_PREFIX   "org.libreoffice"
+#define GTK_MENU_OBJ_PATH_PREFIX   "/org/libreoffice"
+
+//Some menus are special, this is the list of them
+gboolean
+isSpecialSubmenu (OUString command)
+{
+    const gchar * specialSubmenus[11] = {".uno:CharFontName",
+                                         ".uno:FontHeight",
+                                         ".uno:ObjectMenue",
+                                         ".uno:InsertPageHeader",
+                                         ".uno:InsertPageFooter",
+                                         ".uno:ChangeControlType",
+                                         ".uno:AvailableToolbars",
+                                         ".uno:ScriptOrganizer",
+                                         ".uno:RecentFileList",
+                                         ".uno:AddDirect",
+                                         ".uno:AutoPilotMenu"};
+
+    for (gint i = 0; i < 11; i++)
+    {
+        if (command.equals (OUString::createFromAscii (specialSubmenus[i])))
+            return TRUE;
+    }
+    return FALSE;
+}
 
 static void
 dispatchAction (GSimpleAction   *action,
@@ -58,12 +82,34 @@ dispatchAction (GSimpleAction   *action,
                         pParentMenu = pParentMenu->mpParentSalMenu;
                     }
 
-                    pPopupMenu->SetSelectedEntry( pSalMenuItem->mnId );
-                    pPopupMenu->ImplSelectWithStart( pCurMenu );
+//                    pPopupMenu->SetSelectedEntry( pSalMenuItem->mnId );
+//                    pPopupMenu->ImplSelectWithStart( pCurMenu );
+                    ((MenuBar*) pCurMenu)->HandleMenuCommandEvent( pCurMenu, pSalMenuItem->mnId );
                 }
                 else
                     OSL_FAIL( "menubar item without frame !" );
             }
+        } else {
+            rtl::OUString aActionName = rtl::OUString::createFromAscii( g_action_get_name( G_ACTION( action ) ) );
+
+            if ( isSpecialSubmenu( aActionName ) ) {
+                PopupMenu * pPopupMenu = dynamic_cast<PopupMenu *>(pSalMenuItem->mpVCLMenu);
+                if( pPopupMenu )
+                {
+                    GtkSalMenu* pParentMenu = pSalMenuItem->mpParentMenu;
+                    Menu* pCurMenu = pSalMenuItem->mpVCLMenu;
+                    while( pParentMenu && pParentMenu->mpVCLMenu )
+                    {
+                        pCurMenu = pParentMenu->mpVCLMenu;
+                        pParentMenu = pParentMenu->mpParentSalMenu;
+                    }
+
+                    ((MenuBar*) pCurMenu)->HandleMenuActivateEvent( pSalMenuItem->mpVCLMenu );
+//                    pPopupMenu->SetSelectedEntry( pSalMenuItem->mnId );
+//                    pPopupMenu->ImplActivateWithStart( pCurMenu );
+//                    //                pSalMenuItem->mpVCLMenu->Activate();
+                }
+            }
         }
     }
 }
@@ -114,18 +160,24 @@ gdk_x11_window_set_utf8_property  (GdkWindow *window,
 
 void GtkSalMenu::publishMenu( GMenuModel *pMenu, GActionGroup *pActionGroup )
 {
-//        guint appmenuID = g_dbus_connection_export_menu_model (bus, "/org/libreoffice/menus/appmenu", mpMenuModel, NULL);
-//        if(!appmenuID) puts("Fail export appmenu");
-
     if ( mMenubarId ) {
         g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId );
-        mbMenuBar = 0;
+        mMenubarId = 0;
     }
 
-    mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, "/org/libreoffice/menus/menubar", pMenu, NULL);
-    if(!mMenubarId) puts("Fail export menubar");
+    if ( mActionGroupId ) {
+        g_dbus_connection_unexport_action_group( pSessionBus, mActionGroupId );
+        mActionGroupId = 0;
+    }
 
-    g_dbus_connection_export_action_group( pSessionBus, GTK_MENU_OBJ_PATH, pActionGroup, NULL);
+    if ( aDBusMenubarPath ) {
+        mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenu, NULL);
+        if(!mMenubarId) puts("Fail export menubar");
+    }
+
+    if ( aDBusPath ) {
+        mActionGroupId = g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pActionGroup, NULL);
+    }
 }
 
 
@@ -157,41 +209,68 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
     mpVCLMenu( NULL ),
     mpParentSalMenu( NULL ),
     mpFrame( NULL ),
+    aDBusPath( NULL ),
     aDBusMenubarPath( NULL ),
     pSessionBus( NULL ),
     mBusId( 0 ),
     mMenubarId( 0 ),
     mActionGroupId ( 0 )
 {
-    mpCurrentSection = G_MENU_MODEL( g_menu_new() );
+    mpCurrentSection = G_MENU_MODEL( g_lo_menu_new() );
     maSections.push_back( mpCurrentSection );
 
-    mpMenuModel = G_MENU_MODEL( g_menu_new() );
-    g_menu_append_section( G_MENU( mpMenuModel ), NULL, mpCurrentSection );
+    mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
+    g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection );
 
     if (bMenuBar) {
         pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
         if(!pSessionBus) puts ("Fail bus get");
 
-        mBusId = g_bus_own_name_on_connection (pSessionBus, GTK_MENU_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
-        if(!mBusId) puts ("Fail own name");
+//        mBusId = g_bus_own_name_on_connection (pSessionBus, "", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
+//        if(!mBusId) puts ("Fail own name");
     }
 }
 
 GtkSalMenu::~GtkSalMenu()
 {
+    if ( mpFrame ) {
+        GtkWidget *widget = GTK_WIDGET( mpFrame->getWindow() );
+        GdkWindow *gdkWindow = gtk_widget_get_window( widget );
+        if (gdkWindow) {
+            gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", NULL );
+            gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", NULL );
+            gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", NULL );
+            gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", NULL );
+        }
+    }
+
     if ( mMenubarId ) {
         g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId );
+        mMenubarId = 0;
     }
 
-    if ( mBusId ) {
-        g_bus_unown_name( mBusId );
+    if ( mActionGroupId ) {
+        g_dbus_connection_unexport_action_group( pSessionBus, mActionGroupId );
+        mActionGroupId = 0;
     }
 
     if ( pSessionBus ) {
-        g_dbus_connection_close_sync( pSessionBus, NULL, NULL );
+        g_dbus_connection_flush_sync( pSessionBus, NULL, NULL );
     }
 
+//    if ( mBusId ) {
+//        g_bus_unown_name( mBusId );
+//    }
+
+//    if ( pSessionBus ) {
+//        g_dbus_connection_close_sync( pSessionBus, NULL, NULL );
+//        pSessionBus = NULL;
+//        mMenubarId = 0;
+//        mActionGroupId = 0;
+//    }
+
+    pSessionBus = NULL;
+
     maSections.clear();
     maItems.clear();
 
@@ -206,7 +285,6 @@ sal_Bool GtkSalMenu::VisibleMenuBar()
 
 void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
 {
-    cout << __FUNCTION__ << "  pos: " << nPos << " item: " << pSalMenuItem << " menu: " << this << endl;
     GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem );
 
     if ( pGtkSalMenuItem->mpMenuItem ) {
@@ -216,14 +294,12 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
 
         maItems.push_back( pGtkSalMenuItem );
 
-        g_menu_insert_item( G_MENU( mpCurrentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem );
-
-//        g_menu_append_item( G_MENU( mpCurrentSection ), pGtkSalMenuItem->mpMenuItem );
+        g_lo_menu_insert_item( G_LO_MENU( mpCurrentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem );
     } else {
         // If no mpMenuItem exists, then item is a separator.
-        mpCurrentSection = G_MENU_MODEL( g_menu_new() );
+        mpCurrentSection = G_MENU_MODEL( g_lo_menu_new() );
         maSections.push_back( mpCurrentSection );
-        g_menu_append_section( G_MENU( mpMenuModel ), NULL, mpCurrentSection );
+        g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection );
     }
 
     pGtkSalMenuItem->mpParentMenu = this;
@@ -231,30 +307,17 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
 
 void GtkSalMenu::RemoveItem( unsigned nPos )
 {
-    cout << __FUNCTION__ << " Item: " << nPos << endl;
-
-//    if (nPos < maItems.size()) {
-//        GtkSalMenuItem *pSalMenuItem = maItems[ nPos ];
-
-//        g_menu_remove( G_MENU( pSalMenuItem->mpParentSection ), nPos );
-
-//        std::vector< GtkSalMenuItem* >::iterator iterator;
-//        iterator = maItems.begin() + nPos;
-
-//        maItems.erase( iterator, iterator );
-//    }
+//    cout << __FUNCTION__ << " Item: " << nPos << endl;
 }
 
 void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos )
 {
-    cout << __FUNCTION__ << "  Pos: " << nPos << endl;
-
     GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem );
     GtkSalMenu *pGtkSubMenu = static_cast<GtkSalMenu*>( pSubMenu );
 
     if ( pGtkSubMenu ) {
         pGtkSalMenuItem->mpSubMenu = pGtkSubMenu;
-        g_menu_item_set_submenu( pGtkSalMenuItem->mpMenuItem, pGtkSubMenu->mpMenuModel );
+        g_lo_menu_item_set_submenu( pGtkSalMenuItem->mpMenuItem, pGtkSubMenu->mpMenuModel );
 
         if ( !pGtkSubMenu->mpParentSalMenu ) {
             pGtkSubMenu->mpParentSalMenu = this;
@@ -275,18 +338,27 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
     if (gdkWindow) {
         XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow );
 
-        gchar *aWindowObjectPath = g_strdup_printf( "%s/window/%lu", GTK_MENU_OBJ_PATH, windowId );
-        gchar *aMenubarObjectPath = g_strconcat( GTK_MENU_OBJ_PATH, "/menus/menubar", NULL );
+//        gchar* aGtkMenuObjPath = GTK_MENU_OBJ_PATH_PREFIX;
+//        gchar* aGtkMenuObjPath = (gchar*) g_dbus_connection_get_unique_name( pSessionBus );
+        gchar *aGtkMenuObjPath = "";
+
+        aDBusPath = g_strdup_printf("%s/window/%lu", aGtkMenuObjPath, windowId);
+        gchar* aDBusWindowPath = g_strdup_printf( "%s/window/%lu", aGtkMenuObjPath, windowId );
+        aDBusMenubarPath = g_strdup_printf( "%s/window/%lu/menus/menubar", aGtkMenuObjPath, windowId );
+
+        puts(aDBusPath);
+        puts(aDBusWindowPath);
+        puts(aDBusMenubarPath);
+
+        puts(g_dbus_connection_get_unique_name( pSessionBus ));
 
-//        gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice");
         gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) );
-        gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", GTK_MENU_OBJ_PATH );
-        gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aWindowObjectPath );
-//        gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_APP_MENU_OBJECT_PATH", "/org/libreoffice/menus/appmenu");
-        gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aMenubarObjectPath );
+        gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", aGtkMenuObjPath );
+        gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath );
+        gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath );
 
-        g_free( aWindowObjectPath );
-        g_free( aMenubarObjectPath );
+        // Try to publish the menu with the right bus data.
+        Freeze();
     }
 }
 
@@ -300,13 +372,10 @@ const GtkSalFrame* GtkSalMenu::getFrame() const
 
 void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
 {
-    cout << __FUNCTION__ << endl;
 }
 
 void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
 {
-    cout << __FUNCTION__ << endl;
-
     sal_uInt16 itemId = mpVCLMenu->GetItemId( nPos );
 
     GtkSalMenuItem *pSalMenuItem = GetSalMenuItem( itemId );
@@ -319,40 +388,30 @@ void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
 
 void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText )
 {
-    cout << __FUNCTION__ << endl;
     // Replace the "~" character with "_".
     rtl::OUString aText = rText.replace( '~', '_' );
     rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8);
 
-    cout << "Setting label: " << aConvertedText.getStr() << endl;
+//    cout << "Setting label: " << aConvertedText.getStr() << endl;
 
     GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem );
 
-    GMenuItem *pMenuItem = G_MENU_ITEM( pGtkSalMenuItem->mpMenuItem );
+    GLOMenuItem *pMenuItem = G_LO_MENU_ITEM( pGtkSalMenuItem->mpMenuItem );
 
-    g_menu_item_set_label( pMenuItem, aConvertedText.getStr() );
+    g_lo_menu_item_set_label( pMenuItem, aConvertedText.getStr() );
 
     if ( pGtkSalMenuItem->mpParentSection ) {
-        g_menu_remove( G_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos );
-        g_menu_insert_item( G_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem );
+        g_lo_menu_remove( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos );
+        g_lo_menu_insert_item( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem );
     }
 }
 
 void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage)
 {
-    cout << __FUNCTION__ << endl;
 }
 
 void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName )
 {
-    cout << __FUNCTION__ << " KeyName: " << rKeyName << endl;
-
-//    GtkSalMenuItem *pMenuItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
-
-//    rtl::OString aConvertedKeyName = OUStringToOString( rKeyName, RTL_TEXTENCODING_UTF8 );
-
-//    GVariant *gaKeyCode = g_variant_new_string( aConvertedKeyName.getStr() );
-//    g_menu_item_set_attribute_value( pMenuItem->mpMenuItem, "accel", gaKeyCode );
 }
 
 void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr )
@@ -374,23 +433,21 @@ void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const
     pGtkSalMenuItem->mpAction = G_ACTION( pAction );
 
 
-    rtl::OString aItemCommand = "app." + aOCommandStr;
-    g_menu_item_set_action_and_target( pGtkSalMenuItem->mpMenuItem, aItemCommand.getStr(), NULL );
+    rtl::OString aItemCommand = "win." + aOCommandStr;
+    g_lo_menu_item_set_action_and_target( pGtkSalMenuItem->mpMenuItem, aItemCommand.getStr(), NULL );
 
     if ( pGtkSalMenuItem->mpParentSection ) {
-        g_menu_remove( G_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos );
-        g_menu_insert_item( G_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem );
+        g_lo_menu_remove( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos );
+        g_lo_menu_insert_item( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem );
     }
 }
 
 void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
 {
-    cout << __FUNCTION__ << endl;
 }
 
 bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, sal_uLong nFlags)
 {
-    cout << __FUNCTION__ << endl;
     return TRUE;
 }
 
@@ -425,10 +482,8 @@ GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) :
     mpMenuItem( NULL ),
     mpAction( NULL )
 {
-    cout << __FUNCTION__ << "Type: " << (sal_uInt16) pItemData->eType << endl;
-
     if ( pItemData->eType != MENUITEM_SEPARATOR ) {
-        mpMenuItem = g_menu_item_new( "b", NULL );
+        mpMenuItem = g_lo_menu_item_new( "EMPTY STRING", NULL );
     }
 }
 


More information about the Libreoffice-commits mailing list