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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Sep 11 04:22:58 PDT 2012


 vcl/inc/unx/gtk/gloactiongroup.h      |   11 +--
 vcl/inc/unx/gtk/gtksalmenu.hxx        |    1 
 vcl/unx/gtk/window/gloactiongroup.cxx |  105 ++++++++++------------------------
 vcl/unx/gtk/window/gtksalmenu.cxx     |   50 ++++++++++++----
 4 files changed, 76 insertions(+), 91 deletions(-)

New commits:
commit a12a4a6befd8688495b966fb4741f61242740389
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Tue Sep 11 12:21:28 2012 +0100

    Fixed crashes when executing some menu actions.
    
    Change-Id: I80bb1ed74e823d4b66df05eb15c9b5ed2e58b7f6

diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h
index bc4d59d..e0d783f 100644
--- a/vcl/inc/unx/gtk/gloactiongroup.h
+++ b/vcl/inc/unx/gtk/gloactiongroup.h
@@ -63,15 +63,15 @@ struct _GLOActionGroupClass
 
 GType               g_lo_action_group_get_type              (void) G_GNUC_CONST;
 
-GLOActionGroup *    g_lo_action_group_new                   (void);
+GLOActionGroup *    g_lo_action_group_new                   (gpointer           frame);
 
 void                g_lo_action_group_insert                (GLOActionGroup     *group,
                                                              const gchar        *action_name,
-                                                             gpointer            action_info);
+                                                             gint                item_id);
 
 void                g_lo_action_group_insert_stateful       (GLOActionGroup     *group,
                                                              const gchar        *action_name,
-                                                             gpointer            action_info,
+                                                             gint                item_id,
                                                              const GVariantType *parameter_type,
                                                              const GVariantType *state_type,
                                                              GVariant           *state_hint,
@@ -79,10 +79,7 @@ void                g_lo_action_group_insert_stateful       (GLOActionGroup
 
 void                g_lo_action_group_set_action_enabled    (GLOActionGroup     *group,
                                                              const gchar        *action_name,
-                                                             gboolean           enabled);
-
-gpointer            g_lo_action_group_get_action_item       (GLOActionGroup     *group,
-                                                             const gchar        *action_name);
+                                                             gboolean            enabled);
 
 void                g_lo_action_group_remove                (GLOActionGroup     *group,
                                                              const gchar        *action_name);
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index ddb6a6b..f746b4b 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -89,6 +89,7 @@ public:
     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 );
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
index d7eafbf..33e756c 100644
--- a/vcl/unx/gtk/window/gloactiongroup.cxx
+++ b/vcl/unx/gtk/window/gloactiongroup.cxx
@@ -28,10 +28,6 @@
 #include <unx/gtk/gtksalmenu.hxx>
 #include <vcl/menu.hxx>
 
-#include <stdio.h>
-#include <iostream>
-
-using namespace std;
 
 /*
  * GLOAction
@@ -47,7 +43,7 @@ struct _GLOAction
 {
     GObject         parent_instance;
 
-    GtkSalMenuItem* item;               // A pointer to the menu item.
+    gint            item_id;            // Menu item ID.
     gboolean        enabled;            // TRUE if action is enabled, FALSE otherwise.
     GVariantType*   parameter_type;     // A GVariantType with the action parameter type.
     GVariantType*   state_type;         // A GVariantType with item state type
@@ -69,7 +65,7 @@ g_lo_action_new (void)
 static void
 g_lo_action_init (GLOAction *action)
 {
-    action->item = NULL;
+    action->item_id = -1;
     action->enabled = TRUE;
     action->parameter_type = NULL;
     action->state_type = NULL;
@@ -82,8 +78,6 @@ g_lo_action_finalize (GObject *object)
 {
     GLOAction* action = G_LO_ACTION(object);
 
-    action->item = NULL;
-
     if (action->parameter_type)
         g_variant_type_free (action->parameter_type);
 
@@ -113,7 +107,8 @@ g_lo_action_class_init (GLOActionClass *klass)
 
 struct _GLOActionGroupPrivate
 {
-    GHashTable *table;  /* string -> GtkSalMenuItem* */
+    GHashTable  *table;  /* string -> GLOAction */
+    GtkSalFrame *frame;  /* Frame to which GActionGroup is associated. */
 };
 
 static void g_lo_action_group_iface_init (GActionGroupInterface *);
@@ -218,67 +213,39 @@ g_lo_action_group_activate (GActionGroup *group,
 {
     GTK_YIELD_GRAB();
 
-    GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
-    GLOAction* action = G_LO_ACTION (g_hash_table_lookup (loGroup->priv->table, action_name));
-    GtkSalMenuItem *pSalMenuItem = action->item;
+    GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
+    GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
 
-    if (pSalMenuItem == NULL || pSalMenuItem->mpSubMenu )
+    GtkSalFrame *pFrame = lo_group->priv->frame;
+
+    if ( pFrame == NULL )
         return;
 
-    const GtkSalFrame *pFrame = pSalMenuItem->mpParentMenu ? pSalMenuItem->mpParentMenu->GetFrame() : NULL;
+    GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() );
 
-    if ( pFrame && !pFrame->GetParent() ) {
-        ((PopupMenu*) pSalMenuItem->mpVCLMenu)->SetSelectedEntry( pSalMenuItem->mnId );
-        SalMenuEvent aMenuEvt( pSalMenuItem->mnId, pSalMenuItem->mpVCLMenu );
-        pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt );
-    }
-    else if ( pSalMenuItem->mpVCLMenu )
-    {
-        // if an item from submenu was selected. the corresponding Window does not exist because
-        // we use native popup menus, so we have to set the selected menuitem directly
-        // incidentally this of course works for top level popup menus, too
-        PopupMenu * pPopupMenu = dynamic_cast<PopupMenu *>(pSalMenuItem->mpVCLMenu);
-        if( pPopupMenu )
-        {
-            // FIXME: revise this ugly code
-
-            // select handlers in vcl are dispatch on the original menu
-            // if not consumed by the select handler of the current menu
-            // however since only the starting menu ever came into Execute
-            // the hierarchy is not build up. Workaround this by getting
-            // the menu it should have been
-
-            // get started from hierarchy in vcl menus
-            GtkSalMenu* pParentMenu = pSalMenuItem->mpParentMenu;
-            Menu* pCurMenu = pSalMenuItem->mpVCLMenu;
-            while( pParentMenu && pParentMenu->GetMenu() )
-            {
-                pCurMenu = pParentMenu->GetMenu();
-                pParentMenu = pParentMenu->GetParentSalMenu();
-            }
-
-            pPopupMenu->SetSelectedEntry( pSalMenuItem->mnId );
-            pPopupMenu->ImplSelectWithStart( pCurMenu );
-        }
-        else
-        {
-            OSL_FAIL( "menubar item without frame !" );
-        }
-    }
+    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() );
+
+    pMenuBar->HandleMenuCommandEvent( pSubMenu, action->item_id );
 }
 
 void
 g_lo_action_group_insert (GLOActionGroup *group,
                           const gchar    *action_name,
-                          gpointer        action_info)
+                          gint            item_id)
 {
-    g_lo_action_group_insert_stateful (group, action_name, action_info, NULL, NULL, NULL, NULL);
+    g_lo_action_group_insert_stateful (group, action_name, item_id, NULL, NULL, NULL, NULL);
 }
 
 void
 g_lo_action_group_insert_stateful (GLOActionGroup     *group,
                                    const gchar        *action_name,
-                                   gpointer            action_info,
+                                   gint                item_id,
                                    const GVariantType *parameter_type,
                                    const GVariantType *state_type,
                                    GVariant           *state_hint,
@@ -288,7 +255,7 @@ g_lo_action_group_insert_stateful (GLOActionGroup     *group,
 
     GLOAction* old_action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
 
-    if (old_action == NULL || old_action->item != action_info)
+    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);
@@ -297,7 +264,7 @@ g_lo_action_group_insert_stateful (GLOActionGroup     *group,
 
         g_hash_table_insert (group->priv->table, g_strdup (action_name), action);
 
-        action->item = static_cast< GtkSalMenuItem* >( action_info );
+        action->item_id = item_id;
 
         if (parameter_type)
             action->parameter_type = (GVariantType*) parameter_type;
@@ -333,6 +300,7 @@ g_lo_action_group_init (GLOActionGroup *group)
                                                  GLOActionGroupPrivate);
     group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   g_free, g_object_unref);
+    group->priv->frame = NULL;
 }
 
 static void
@@ -355,9 +323,12 @@ g_lo_action_group_iface_init (GActionGroupInterface *iface)
 }
 
 GLOActionGroup *
-g_lo_action_group_new (void)
+g_lo_action_group_new (gpointer frame)
 {
-    return G_LO_ACTION_GROUP( g_object_new (G_TYPE_LO_ACTION_GROUP, NULL) );
+    GLOActionGroup* group = G_LO_ACTION_GROUP (g_object_new (G_TYPE_LO_ACTION_GROUP, NULL));
+    group->priv->frame = static_cast< GtkSalFrame* > (frame);
+
+    return group;
 }
 
 void
@@ -375,21 +346,7 @@ g_lo_action_group_set_action_enabled (GLOActionGroup *group,
 
     action->enabled = enabled;
 
-    g_action_group_action_enabled_changed(G_ACTION_GROUP(group),
-                                          action_name,
-                                          enabled);
-}
-
-gpointer
-g_lo_action_group_get_action_item (GLOActionGroup *group,
-                                   const gchar    *action_name)
-{
-    g_return_val_if_fail (G_IS_LO_ACTION_GROUP (group), NULL);
-    g_return_val_if_fail (action_name != NULL, NULL);
-
-    GLOAction* action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
-
-    return (action != NULL) ? action->item : NULL;
+    g_action_group_action_enabled_changed (G_ACTION_GROUP (group), action_name, enabled);
 }
 
 void
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 19ca889..b61af31 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -367,19 +367,19 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
 
         if ( mpMenuModel == NULL && mpActionGroup == NULL ) {
             mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
-            mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() );
+            mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new( ( gpointer ) mpFrame ) );
 
             g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", mpMenuModel, ObjectDestroyedNotify );
             g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", mpActionGroup, ObjectDestroyedNotify );
 
             // Publish the menu only if AppMenu registrar is available.
             guint nWatcherId = g_bus_watch_name (G_BUS_TYPE_SESSION,
-                                           "com.canonical.AppMenu.Registrar",
-                                           G_BUS_NAME_WATCHER_FLAGS_NONE,
-                                           on_registrar_available,
-                                           on_registrar_unavailable,
-                                           (gpointer) mpFrame,
-                                           NULL);
+                                                 "com.canonical.AppMenu.Registrar",
+                                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                                 on_registrar_available,
+                                                 on_registrar_unavailable,
+                                                 (gpointer) mpFrame,
+                                                 NULL);
 
             ( ( GtkSalFrame* ) mpFrame )->SetWatcherId( nWatcherId );
         }
@@ -512,7 +512,7 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, Gtk
             GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
             GVariant* pState = g_variant_new_boolean( bChecked );
 
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, NULL, pStateType, NULL, pState );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, NULL, pStateType, NULL, pState );
         }
         else if ( bits & MIB_RADIOCHECK )
         {
@@ -522,12 +522,12 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, Gtk
             GVariant* pState = g_variant_new_string( "" );
             pTarget = g_variant_new_string( aCommand );
 
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, pParameterType, pStateType, NULL, pState );
         }
         else
         {
             // Item is not special, so insert a stateless action.
-            g_lo_action_group_insert( pActionGroup, aCommand, pItem );
+            g_lo_action_group_insert( pActionGroup, aCommand, pItem->mnId );
         }
     }
 
@@ -555,6 +555,36 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
 {
 }
 
+GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand )
+{
+    GtkSalMenu* pMenu = NULL;
+
+    for ( sal_uInt16 nPos = 0; nPos < maItems.size(); nPos++ )
+    {
+        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;
+            break;
+        }
+        else
+        {
+            if ( pSalItem->mpSubMenu != NULL )
+                pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand );
+
+            if ( pMenu != NULL )
+               break;
+        }
+    }
+
+    return pMenu;
+}
+
 void GtkSalMenu::Freeze()
 {
 }


More information about the Libreoffice-commits mailing list