diff options
author | Antonio Fernandez <antonio.fernandez@aentos.es> | 2012-08-20 09:44:24 +0100 |
---|---|---|
committer | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2012-11-14 13:52:43 +0100 |
commit | 25db814902b123a3d5e4708f0da3daf606f7537d (patch) | |
tree | 72bde7b93fa2cd39f596a529e7635792aed29630 /vcl | |
parent | 253e16488551a263603744696b03026177ff2845 (diff) |
Actions are generated during the item info filling.
Change-Id: I79be19a8ca565da9ca9bb8b31efc4e6e1463ba31
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/salmenu.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gloactiongroup.h | 3 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtksalmenu.hxx | 5 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gloactiongroup.cxx | 40 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalmenu.cxx | 222 |
5 files changed, 157 insertions, 115 deletions
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx index 50d4ed93e7fc..fcec96af5590 100644 --- a/vcl/inc/salmenu.hxx +++ b/vcl/inc/salmenu.hxx @@ -43,7 +43,7 @@ struct SalItemParams struct SalMenuButtonItem { - sal_uInt16 mnId; + sal_uInt16 mnId; Image maImage; rtl::OUString maToolTipText; diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h index a44dbaac5b05..852a40f6b15b 100644 --- a/vcl/inc/unx/gtk/gloactiongroup.h +++ b/vcl/inc/unx/gtk/gloactiongroup.h @@ -55,6 +55,9 @@ void g_lo_action_group_remove (GLOActionGroup *gro void g_lo_action_group_clear (GLOActionGroup *group); +void g_lo_action_group_merge (GLOActionGroup *input_group, + GLOActionGroup *output_group); + G_END_DECLS #endif // GLOACTIONGROUP_H diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index d5ee38f46e4f..c57d39d703db 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -56,8 +56,6 @@ private: std::vector< GtkSalMenuItem* > maItems; // DBus attributes - gchar* aDBusPath; - gchar* aDBusMenubarPath; GDBusConnection* pSessionBus; sal_Int32 mMenubarId; sal_Int32 mActionGroupId; @@ -67,8 +65,8 @@ private: GMenuModel* mpCurrentSection; GActionGroup* mpActionGroup; - virtual void publishMenu( GMenuModel*, GActionGroup* ); GtkSalMenuItem* GetSalMenuItem( sal_uInt16 nId ); + sal_Int16 GetSectionNumber( GMenuModel* pSection ); public: GtkSalMenu( sal_Bool bMenuBar ); @@ -108,6 +106,7 @@ public: virtual ~GtkSalMenuItem(); sal_uInt16 mnId; // Item ID + MenuItemBits mnBits; // Item bits sal_uInt16 mnPos; // Item position gchar* maCommand; // Item command Menu* mpVCLMenu; // VCL Menu into which this MenuItem is inserted diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx index 07919d7aeed9..51bf2f0b48f6 100644 --- a/vcl/unx/gtk/window/gloactiongroup.cxx +++ b/vcl/unx/gtk/window/gloactiongroup.cxx @@ -52,8 +52,6 @@ g_lo_action_group_query_action (GActionGroup *group, GVariant **state_hint, GVariant **state) { -// printf("%s - %s\n", __FUNCTION__, action_name); - GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group); GtkSalMenuItem* item_info; @@ -76,8 +74,14 @@ g_lo_action_group_query_action (GActionGroup *group, if (state_hint) *state_hint = NULL; - if (state) - *state = item_info->mpState; + if (state) { + if (item_info->mpState) { + g_variant_ref( item_info->mpState ); + *state = item_info->mpState; + } else { + *state = NULL; + } + } return TRUE; } @@ -103,7 +107,10 @@ g_lo_action_group_change_state (GActionGroup *group, } if (g_variant_is_of_type(value, item_info->mpStateType)) { - item_info->mpState = g_variant_ref_sink(value); + if (item_info->mpState) + g_variant_unref(item_info->mpState); + + item_info->mpState = g_variant_new_variant(value); g_action_group_action_state_changed(group, action_name, value); } } @@ -237,6 +244,7 @@ g_lo_action_group_set_action_enabled (GLOActionGroup *group, const gchar *action_name, gboolean enabled) { + cout << __FUNCTION__ << " - " << action_name << endl; g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); g_action_group_action_enabled_changed(G_ACTION_GROUP(group), @@ -263,11 +271,25 @@ g_lo_action_group_clear (GLOActionGroup *group) { g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - GList* keys = g_hash_table_get_keys(group->priv->table); + g_hash_table_remove_all(group->priv->table); +} - for ( GList* list = g_list_first(keys); list; list = g_list_next(list) ) { - gchar* action_name = (gchar*) list->data; +void +g_lo_action_group_merge (GLOActionGroup *input_group, + GLOActionGroup *output_group) +{ + g_return_if_fail (G_IS_LO_ACTION_GROUP (input_group)); + g_return_if_fail (G_IS_LO_ACTION_GROUP (output_group)); + g_return_if_fail (input_group != NULL); + g_return_if_fail (output_group != NULL); + + GHashTableIter iter; + gpointer key, value; - g_lo_action_group_remove( group, action_name ); + g_hash_table_iter_init (&iter, input_group->priv->table); + + while (g_hash_table_iter_next (&iter, &key, &value)) + { + g_lo_action_group_insert(output_group, (gchar*) key, value); } } diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 8467434661e1..a82dbe22d4df 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -35,26 +35,14 @@ isSpecialSubmenu (OUString command) return FALSE; } -void generateActions( GtkSalMenu* pMenu, GLOActionGroup* pActionGroup ) -{ - if ( !pMenu || !pActionGroup ) - return; - - for (sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++) { - GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( i ); - - if ( pSalMenuItem->maCommand ) { - g_lo_action_group_insert( pActionGroup, pSalMenuItem->maCommand, pSalMenuItem ); - } - - generateActions( pSalMenuItem->mpSubMenu, pActionGroup ); - } -} - void updateNativeMenu( GtkSalMenu* pMenu ) { if ( pMenu ) { for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); + + if ( !pSalMenuItem->mpVCLMenu ) + continue; + String aText = pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ); // Force updating of native menu labels. @@ -63,24 +51,11 @@ void updateNativeMenu( GtkSalMenu* pMenu ) { if ( pSalMenuItem->mpSubMenu && pSalMenuItem->mpSubMenu->GetMenu() ) { pSalMenuItem->mpSubMenu->GetMenu()->Activate(); updateNativeMenu( pSalMenuItem->mpSubMenu ); - pSalMenuItem->mpSubMenu->GetMenu()->Deactivate(); - } - } - } -} - -void updateSpecialMenus( GtkSalMenu *pMenu ) { - if ( pMenu ) { - for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { - GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); - - rtl::OUString aCommand = pSalMenuItem->mpVCLMenu->GetItemCommand( pSalMenuItem->mnId ); - if ( isSpecialSubmenu( aCommand ) ) { - updateNativeMenu( pSalMenuItem->mpSubMenu ); + // FIXME: Using Deactivate() let the menu to update itself correctly, but generates + // duplicated popup menus. +// pSalMenuItem->mpSubMenu->GetMenu()->Deactivate(); } - - updateSpecialMenus( pSalMenuItem->mpSubMenu ); } } } @@ -88,8 +63,7 @@ void updateSpecialMenus( GtkSalMenu *pMenu ) { gboolean GenerateMenu(gpointer user_data) { GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data ); - // We only update special menus periodically. - updateSpecialMenus( pSalMenu ); + updateNativeMenu( pSalMenu ); return TRUE; } @@ -128,32 +102,19 @@ gdk_x11_window_set_utf8_property (GdkWindow *window, } } -/* - * GtkSalMenu - */ - -void GtkSalMenu::publishMenu( GMenuModel *pMenu, GActionGroup *pActionGroup ) +GActionGroup* GetActionGroupFromMenubar( GtkSalMenu *pMenu ) { - if ( mMenubarId ) { - g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId ); - mMenubarId = 0; - } + GtkSalMenu *pSalMenu = pMenu; - if ( mActionGroupId ) { - g_dbus_connection_unexport_action_group( pSessionBus, mActionGroupId ); - mActionGroupId = 0; - } - - if ( aDBusMenubarPath ) { - mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenu, NULL); - if(!mMenubarId) puts("Fail export menubar"); - } + while ( pSalMenu && pSalMenu->GetParentSalMenu() ) + pSalMenu = pSalMenu->GetParentSalMenu(); - if ( aDBusPath ) { - mActionGroupId = g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pActionGroup, NULL); - } + return ( pSalMenu ) ? pSalMenu->GetActionGroup() : NULL; } +/* + * GtkSalMenu + */ GtkSalMenuItem* GtkSalMenu::GetSalMenuItem( sal_uInt16 nId ) { @@ -177,13 +138,25 @@ GtkSalMenuItem* GtkSalMenu::GetSalMenuItem( sal_uInt16 nId ) return NULL; } +sal_Int16 GtkSalMenu::GetSectionNumber( GMenuModel* pSection ) +{ + if ( pSection == NULL ) + return -1; + + for ( int i = 0; maSections.size(); i++ ) + { + if ( maSections[ i ] == pSection ) + return i; + } + + return -1; +} + GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : mbMenuBar( bMenuBar ), mpVCLMenu( NULL ), mpParentSalMenu( NULL ), mpFrame( NULL ), - aDBusPath( NULL ), - aDBusMenubarPath( NULL ), pSessionBus( NULL ), mMenubarId( 0 ), mActionGroupId ( 0 ), @@ -194,6 +167,8 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : maSections.push_back( mpCurrentSection ); if (bMenuBar) { + mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() ); + pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if(!pSessionBus) puts ("Fail bus get"); } else { @@ -221,9 +196,6 @@ GtkSalMenu::~GtkSalMenu() pSessionBus = NULL; - g_free( aDBusPath ); - g_free( aDBusMenubarPath ); - maSections.clear(); maItems.clear(); } @@ -237,12 +209,21 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) { GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); + maItems.push_back( pGtkSalMenuItem ); + if ( pGtkSalMenuItem->mpMenuItem ) { + if ( !mpCurrentSection ) { + mpCurrentSection = G_MENU_MODEL( g_lo_menu_new() ); + maSections.push_back( mpCurrentSection ); + + if ( mpMenuModel ) { + g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); + } + } + pGtkSalMenuItem->mpParentSection = mpCurrentSection; pGtkSalMenuItem->mnPos = g_menu_model_get_n_items( mpCurrentSection ); - maItems.push_back( pGtkSalMenuItem ); - g_lo_menu_insert_item( G_LO_MENU( mpCurrentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem ); } else { // If no mpMenuItem exists, then item is a separator. @@ -260,19 +241,33 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) void GtkSalMenu::RemoveItem( unsigned nPos ) { // FIXME: This method makes the application crash. -// if ( nPos < maItems.size() ) { -// GtkSalMenuItem* pSalMenuItem = maItems[ nPos ]; +// GtkSalMenuItem* pSalMenuItem = maItems[ nPos ]; + +// GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); +// if ( pActionGroup ) { +// g_lo_action_group_remove( pActionGroup, pSalMenuItem->maCommand ); +// } -// if ( pSalMenuItem->mpParentSection ) { +// cout << __FUNCTION__ << " - " << pSalMenuItem->mpParentSection << " - " << pSalMenuItem->mnPos << endl; + +// if ( pSalMenuItem->mpParentSection ) { +// if ( GetSectionNumber( pSalMenuItem->mpParentSection ) > -1 ) // g_lo_menu_remove( G_LO_MENU( pSalMenuItem->mpParentSection ), pSalMenuItem->mnPos ); -// } -// if ( mpActionGroup ) { -// g_lo_action_group_remove( G_LO_ACTION_GROUP( mpActionGroup ), pSalMenuItem->maCommand ); -// } +// if ( g_menu_model_get_n_items( pSalMenuItem->mpParentSection ) == 0 ) { +// sal_uInt16 nSection = GetSectionNumber( pSalMenuItem->mpParentSection ); + +// cout << "Removing section " << nSection << endl; + +// g_lo_menu_remove( G_LO_MENU( mpMenuModel ), nSection ); +// maSections.erase( maSections.begin() + nSection, maSections.begin() + nSection ); -// maItems.erase( maItems.begin() + nPos, maItems.begin() + nPos ); +// if ( pSalMenuItem->mpParentSection == mpCurrentSection ) +// mpCurrentSection = maSections.back(); +// } // } + +// maItems.erase( maItems.begin() + nPos, maItems.begin() + nPos ); } void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) @@ -300,40 +295,52 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) if (gdkWindow) { gpointer pMenu = g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ); - gpointer pActionGroup = g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) ); if ( pMenu && pActionGroup ) { mpMenuModel = G_MENU_MODEL( pMenu ); + + // Merge current action group with the exported one + g_lo_action_group_clear( pActionGroup ); + g_lo_action_group_merge( G_LO_ACTION_GROUP( mpActionGroup ), pActionGroup ); + g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) ); + g_object_unref( mpActionGroup ); + mpActionGroup = G_ACTION_GROUP( pActionGroup ); } else { mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); - mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() ); 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 ); XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow ); - aDBusPath = g_strdup_printf("/window/%lu", windowId); + gchar* aDBusPath = g_strdup_printf("/window/%lu", windowId); gchar* aDBusWindowPath = g_strdup_printf( "/window/%lu", windowId ); - aDBusMenubarPath = g_strdup_printf( "/window/%lu/menus/menubar", windowId ); + gchar* aDBusMenubarPath = g_strdup_printf( "/window/%lu/menus/menubar", windowId ); 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", "" ); 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( aDBusWindowPath ); - // Publish the menu. - publishMenu( mpMenuModel, mpActionGroup ); + if ( aDBusMenubarPath ) { + mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, mpMenuModel, NULL); + if(!mMenubarId) puts("Fail export menubar"); + } + + if ( aDBusPath ) { + mActionGroupId = g_dbus_connection_export_action_group( pSessionBus, aDBusPath, mpActionGroup, NULL); + } + + g_free( aDBusPath ); + g_free( aDBusWindowPath ); + g_free( aDBusMenubarPath ); } g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); - updateNativeMenu( this ); - generateActions( this, G_LO_ACTION_GROUP( mpActionGroup ) ); - // Refresh the menu every second. // This code is a workaround until required modifications in Gtk+ are available. g_timeout_add_seconds( 1, GenerateMenu, this ); @@ -350,33 +357,43 @@ const GtkSalFrame* GtkSalMenu::GetFrame() const void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck ) { - if ( mpActionGroup ) { - GtkSalMenuItem* pSalMenuItem = maItems[ nPos ]; - MenuItemBits itemBits = pSalMenuItem->mpVCLMenu->GetItemBits( pSalMenuItem->mnId ); +// cout << __FUNCTION__ << " - " << nPos << " - " << bCheck << endl; +// GActionGroup* pActionGroup = GetActionGroupFromMenubar( this ); - GVariant *pCheckValue = NULL; +// if ( !pActionGroup ) +// return; - if ( itemBits & MIB_CHECKABLE ) { - gboolean bCheckedValue = ( bCheck == sal_True ) ? TRUE : FALSE; - pCheckValue = g_variant_new_boolean( bCheckedValue ); - } +// GtkSalMenuItem* pSalMenuItem = maItems[ nPos ]; - g_action_group_change_action_state( mpActionGroup, pSalMenuItem->maCommand, pCheckValue ); - } +// if ( !pSalMenuItem || pSalMenuItem->mpSubMenu ) +// return; + +// MenuItemBits itemBits = pSalMenuItem->mnBits; +// GVariant *pCheckValue = NULL; + +// if ( itemBits & MIB_CHECKABLE ) { +// gboolean bCheckedValue = ( bCheck == sal_True ) ? TRUE : FALSE; +// pCheckValue = g_variant_new_boolean( bCheckedValue ); +// } + +// if ( pCheckValue ) +// g_action_group_change_action_state( pActionGroup, pSalMenuItem->maCommand, pCheckValue ); } void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable ) { -// if ( mpActionGroup ) { -// sal_uInt16 itemId = mpVCLMenu->GetItemId( nPos ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); -// GtkSalMenuItem *pSalMenuItem = GetSalMenuItem( itemId ); + if ( pActionGroup ) { + GtkSalMenuItem* pSalMenuItem = maItems[ nPos ]; -// if ( pSalMenuItem ) { -// gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE; -// g_lo_action_group_set_action_enabled( G_LO_ACTION_GROUP( mpActionGroup ), pSalMenuItem->maCommand, bItemEnabled ); -// } -// } + gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE; + + if ( g_strcmp0( pSalMenuItem->maCommand, "" ) == 0 ) + return; + + g_lo_action_group_set_action_enabled( pActionGroup, pSalMenuItem->maCommand, bItemEnabled ); + } } void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText ) @@ -429,8 +446,9 @@ void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const pGtkSalMenuItem->maCommand = g_strdup( aOCommandStr.getStr() ); - if ( !pGtkSalMenuItem->mpVCLMenu->GetPopupMenu( pGtkSalMenuItem->mnId ) && mpActionGroup ) { - g_lo_action_group_insert( G_LO_ACTION_GROUP( mpActionGroup ), pGtkSalMenuItem->maCommand, pGtkSalMenuItem ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); + if ( !pGtkSalMenuItem->mpVCLMenu->GetPopupMenu( pGtkSalMenuItem->mnId ) && pActionGroup ) { + g_lo_action_group_insert( pActionGroup, pGtkSalMenuItem->maCommand, pGtkSalMenuItem ); } gchar* aItemCommand = g_strconcat("win.", pGtkSalMenuItem->maCommand, NULL ); @@ -452,8 +470,6 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) void GtkSalMenu::Freeze() { - updateNativeMenu( this ); - generateActions( this, G_LO_ACTION_GROUP( mpActionGroup ) ); } // ======================================================================= @@ -464,6 +480,7 @@ void GtkSalMenu::Freeze() GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) : mnId( pItemData->nId ), + mnBits( pItemData->nBits ), mnPos( 0 ), maCommand( NULL ), mpVCLMenu( pItemData->pMenu ), @@ -486,6 +503,7 @@ GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) : GtkSalMenuItem::~GtkSalMenuItem() { + if ( mpMenuItem ) { g_object_unref( mpMenuItem ); g_free( maCommand ); |