vcl/inc/salmenu.hxx | 6 vcl/inc/unx/gtk/gtksalmenu.hxx | 24 +- vcl/source/window/menu.cxx | 6 vcl/unx/gtk/window/gloactiongroup.cxx | 15 + vcl/unx/gtk/window/gtkframe.cxx | 81 ++++--- vcl/unx/gtk/window/gtksalmenu.cxx | 392 +++++++++++++++++++++++++--------- 6 files changed, 375 insertions(+), 149 deletions(-)
New commits: commit eabf9c8f3737dc703c44e464b51d6b8044926ba7 Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Thu Oct 4 16:48:04 2012 +0100 Menus are now correctly built. Change-Id: I1a4f5750c37ddfc4b4949033138efbd2372f01c5 diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index d3e9169..3a8a79e 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -521,36 +521,35 @@ static void ObjectDestroyedNotify( gpointer data ) } } -void ensure_dbus_setup(GdkWindow* gdkWindow, GtkSalFrame* pSalFrame) +void ensure_dbus_setup( GdkWindow* gdkWindow, GtkSalFrame* pSalFrame ) { if ( gdkWindow != NULL && g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) == NULL ) { - GMenuModel* pMenuModel = G_MENU_MODEL(g_lo_menu_new()); - GActionGroup* pActionGroup = ((GActionGroup*)g_lo_action_group_new(reinterpret_cast<gpointer>(pSalFrame))); - XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow ); - gchar* aDBusPath = g_strdup_printf("/window/%lu", windowId); - gchar* aDBusWindowPath = g_strdup_printf( "/window/%lu", windowId ); - gchar* aDBusMenubarPath = g_strdup_printf( "/window/%lu/menus/menubar", windowId ); // Get a DBus session connection. if(!pSessionBus) pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if( pSessionBus == NULL ) return; + + // Create menu model and action group attached to this frame. + GMenuModel* pMenuModel = G_MENU_MODEL( g_lo_menu_new() ); + GActionGroup* pActionGroup = ( ( GActionGroup* ) g_lo_action_group_new( reinterpret_cast< gpointer >( pSalFrame ) ) ); + + // Generate menu paths. + XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow ); + gchar* aDBusPath = g_strdup_printf("/window/%lu", windowId); + gchar* aDBusWindowPath = g_strdup_printf( "/window/%lu", windowId ); + gchar* aDBusMenubarPath = g_strdup_printf( "/window/%lu/menus/menubar", windowId ); + + // Publish the menu model and the action group. SAL_INFO("vcl.unity", "exporting menu model at " << pMenuModel << " for window " << windowId); pSalFrame->m_nMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL); pSalFrame->m_nActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pActionGroup, NULL); // Set window properties. - g_object_set_data_full( - G_OBJECT(gdkWindow), - "g-lo-menubar", - pMenuModel, - ObjectDestroyedNotify); - g_object_set_data_full( - G_OBJECT(gdkWindow), - "g-lo-action-group", - pActionGroup, - ObjectDestroyedNotify); + g_object_set_data_full( G_OBJECT(gdkWindow), "g-lo-menubar", pMenuModel, ObjectDestroyedNotify); + g_object_set_data_full( G_OBJECT(gdkWindow), "g-lo-action-group", pActionGroup, ObjectDestroyedNotify); + 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 ); @@ -562,10 +561,10 @@ void ensure_dbus_setup(GdkWindow* gdkWindow, GtkSalFrame* pSalFrame) } } -void on_registrar_available (GDBusConnection * /*connection*/, - const gchar * /*name*/, - const gchar * /*name_owner*/, - gpointer user_data) +void on_registrar_available( GDBusConnection * /*connection*/, + const gchar * /*name*/, + const gchar * /*name_owner*/, + gpointer user_data ) { SolarMutexGuard aGuard; GtkSalFrame* pSalFrame = reinterpret_cast< GtkSalFrame* >( user_data ); @@ -604,17 +603,31 @@ void on_registrar_unavailable (GDBusConnection * /*connection*/, void GtkSalFrame::EnsureAppMenuWatch() { SolarMutexGuard aGuard; - if(m_nWatcherId) - g_bus_unwatch_name(m_nWatcherId); + + if ( m_nWatcherId ) + //g_bus_unwatch_name( m_nWatcherId ); + return; + + + // Get a DBus session connection. + if ( pSessionBus == NULL ) + { + pSessionBus = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, NULL ); + + if ( pSessionBus == NULL ) + return; + } + // Publish the menu only if AppMenu registrar is available. - m_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, - static_cast<GtkSalFrame*>(this), - NULL); - ensure_dbus_setup(gtk_widget_get_window(GTK_WIDGET(m_pWindow)), static_cast<GtkSalFrame*>(this)); + m_nWatcherId = g_bus_watch_name_on_connection( pSessionBus, + "com.canonical.AppMenu.Registrar", + G_BUS_NAME_WATCHER_FLAGS_NONE, + on_registrar_available, + on_registrar_unavailable, + static_cast<GtkSalFrame*>(this), + NULL ); + + ensure_dbus_setup( gtk_widget_get_window(GTK_WIDGET(m_pWindow)), static_cast<GtkSalFrame*>(this) ); } GtkSalFrame::~GtkSalFrame() @@ -673,7 +686,8 @@ GtkSalFrame::~GtkSalFrame() g_dbus_connection_unexport_menu_model(pSessionBus, m_nMenuExportId); GLOMenu* pMenuModel = G_LO_MENU(g_object_get_data( G_OBJECT( m_pWindow ), "g-lo-menubar" )); if(pMenuModel) - g_lo_menu_remove(pMenuModel,0); + //g_lo_menu_remove(pMenuModel,0); + g_object_unref( pMenuModel ); } if(m_nActionGroupExportId) { @@ -681,7 +695,8 @@ GtkSalFrame::~GtkSalFrame() g_dbus_connection_unexport_action_group(pSessionBus, m_nActionGroupExportId); GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP(g_object_get_data( G_OBJECT( m_pWindow ), "g-lo-action-group" )); if(pActionGroup) - g_lo_action_group_clear( pActionGroup ); + //g_lo_action_group_clear( pActionGroup ); + g_object_unref( pActionGroup ); } gtk_widget_destroy( m_pWindow ); } diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 43f04f5..1fd2e6f 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -246,9 +246,9 @@ void GtkSalMenu::UpdateNativeMenu() // SolarMutexGuard aGuard; - Menu* pVCLMenu = mpVCLMenu; // pMenu->GetMenu(); - GLOMenu* pLOMenu = G_LO_MENU( mpMenuModel ); // G_LO_MENU( pMenu->GetMenuModel() ); - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); // G_LO_ACTION_GROUP( pMenu->GetActionGroup() ); + Menu* pVCLMenu = mpVCLMenu; + GLOMenu* pLOMenu = G_LO_MENU( mpMenuModel ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); GList *pOldCommandList = NULL; GList *pNewCommandList = NULL; @@ -335,14 +335,13 @@ void GtkSalMenu::UpdateNativeMenu() } GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; - GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); if ( pSubmenu && pSubmenu->GetMenu() ) { NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) ); - //GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); + GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); if ( pSubMenuModel == NULL ) { @@ -360,24 +359,16 @@ void GtkSalMenu::UpdateNativeMenu() pSubmenu->UpdateNativeMenu(); } - else if (pSubMenuModel) - { - g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, NULL ); - }; +// else if (pSubMenuModel) +// { +// g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, NULL ); +// }; g_free( aNativeCommand ); ++nItemPos; ++validItems; } -// while ( nItemPos < g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) -// g_lo_menu_remove_from_section( pLOMenu, nSection, nItemPos ); -// ++nSection; -// if ( nSection < g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ) ) -// { -// SAL_INFO("vcl.unity", "nSection " << nSection << " model sections " << g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) )); -// g_lo_menu_remove(pLOMenu, nSection ); -// } // Delete extra items in last section. RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems ); @@ -404,11 +395,6 @@ void GtkSalMenu::DisconnectFrame() * GtkSalMenu */ -//void GtkSalMenu::UpdateNativeMenu() -//{ -// UpdateNativeSubMenu(); -//} - GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : mbMenuBar( bMenuBar ), mpVCLMenu( NULL ), @@ -421,9 +407,8 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : GtkSalMenu::~GtkSalMenu() { - if ( mbMenuBar == sal_True ) { + if ( mbMenuBar == sal_True ) ((GtkSalFrame*) mpFrame)->SetMenu( NULL ); - } maItems.clear(); } @@ -469,24 +454,40 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) SAL_INFO("vcl.unity", "GtkSalMenu set to frame"); mpFrame = static_cast< const GtkSalFrame* >( pFrame ); GtkSalFrame* pFrameNonConst = const_cast<GtkSalFrame*>(mpFrame); + // if we had a menu on the GtkSalMenu we have to free it as we generate a // full menu anyway and we might need to reuse an existing model and // actiongroup - if(mpMenuModel) - { - g_object_unref(G_OBJECT(mpMenuModel)); - mpMenuModel = NULL; - } - if(mpActionGroup) - { - g_object_unref(G_OBJECT(mpActionGroup)); - mpActionGroup = NULL; - } +// if(mpMenuModel) +// { +// g_object_unref(G_OBJECT(mpMenuModel)); +// mpMenuModel = NULL; +// } + +// if(mpActionGroup) +// { +// g_object_unref(G_OBJECT(mpActionGroup)); +// mpActionGroup = NULL; +// } pFrameNonConst->SetMenu( this ); mpFrame = static_cast< const GtkSalFrame* >( pFrame ); pFrameNonConst->EnsureAppMenuWatch(); + + // Clean menu model and action group if needed. + GObject* pWindow = G_OBJECT( gtk_widget_get_window( GTK_WIDGET( pFrameNonConst->getWindow() ) ) ); + GLOMenu* pMenuModel = G_LO_MENU( g_object_get_data( pWindow, "g-lo-menubar" ) ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( g_object_get_data( pWindow, "g-lo-action-group" ) ); + + if ( pMenuModel && g_menu_model_get_n_items( G_MENU_MODEL( pMenuModel ) ) > 0 ) + g_lo_menu_remove( pMenuModel, 0 ); + + if ( pActionGroup ) + g_lo_action_group_clear( pActionGroup ); + + // Generate the main menu structure. UpdateNativeMenu(); + } const GtkSalFrame* GtkSalMenu::GetFrame() const @@ -723,11 +724,11 @@ sal_Bool GtkSalMenu::IsItemVisible( unsigned nPos ) return bVisible; } -void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck ) +void GtkSalMenu::CheckItem( unsigned, sal_Bool ) { } -void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable ) +void GtkSalMenu::EnableItem( unsigned, sal_Bool ) { } @@ -738,23 +739,23 @@ void GtkSalMenu::ShowItem( unsigned nPos, sal_Bool bShow ) } -void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText ) +void GtkSalMenu::SetItemText( unsigned, SalMenuItem*, const rtl::OUString& ) { } -void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage) +void GtkSalMenu::SetItemImage( unsigned, SalMenuItem*, const Image& ) { } -void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ) +void GtkSalMenu::SetAccelerator( unsigned, SalMenuItem*, const KeyCode&, const rtl::OUString& ) { } -void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr ) +void GtkSalMenu::SetItemCommand( unsigned, SalMenuItem*, const rtl::OUString& ) { } -void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) +void GtkSalMenu::GetSystemMenuData( SystemMenuData* ) { } commit bda9f461601c7fb200a9f638292d041ab66add8b Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Thu Sep 27 11:28:44 2012 +0100 All special items are now correctly displayed. Change-Id: Ifce96d3e740a7ac89132dd23f9f51447e4372716 diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index d99d73a..7dadbfc 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -104,6 +104,7 @@ public: void Deactivate( const gchar* aMenuCommand ); void DisconnectFrame(); void UpdateNativeMenu(); +// void UpdateNativeSubMenu(); bool PrepUpdate(); }; diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index bf41af8..1115111 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -3244,7 +3244,8 @@ void Menu::HighlightItem( sal_uInt16 nItemPos ) } } -void Menu::Freeze() { +void Menu::Freeze(void) +{ SalMenu *pSalMenu = ImplGetSalMenu(); if ( pSalMenu ) { diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx index d083703..756779a 100644 --- a/vcl/unx/gtk/window/gloactiongroup.cxx +++ b/vcl/unx/gtk/window/gloactiongroup.cxx @@ -219,8 +219,15 @@ g_lo_action_group_change_state (GActionGroup *group, g_lo_action_group_perform_submenu_action (lo_group, action_name, value); else { + gboolean is_new = FALSE; + + /* If action already exists but has no state, it should be removed and added again. */ if (action->state_type == NULL) + { + g_action_group_action_removed (G_ACTION_GROUP (group), action_name); action->state_type = g_variant_type_copy (g_variant_get_type(value)); + is_new = TRUE; + } if (g_variant_is_of_type (value, action->state_type) == TRUE) { @@ -229,7 +236,10 @@ g_lo_action_group_change_state (GActionGroup *group, action->state = g_variant_ref (value); - g_action_group_action_state_changed (group, action_name, value); + if (is_new) + g_action_group_action_added (G_ACTION_GROUP (group), action_name); + else + g_action_group_action_state_changed (group, action_name, value); } } } @@ -248,6 +258,9 @@ g_lo_action_group_activate (GActionGroup *group, GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group); GtkSalFrame *pFrame = lo_group->priv->frame; + if ( parameter != NULL ) + g_action_group_change_action_state( group, action_name, parameter ); + if ( pFrame != NULL ) { GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() ); diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index a31ab1a..43f04f5 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -136,7 +136,7 @@ static void KeyCodeToGdkKey ( const KeyCode& rKeyCode, guint* pGdkKeyCode, GdkMo bool GtkSalMenu::PrepUpdate() { const GtkSalFrame* pFrame = GetFrame(); - if (!pFrame) + if (pFrame) { const GObject* pWindow = G_OBJECT(gtk_widget_get_window( GTK_WIDGET(pFrame->getWindow()) )); if(!pWindow) @@ -150,12 +150,17 @@ bool GtkSalMenu::PrepUpdate() { mpMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( pWindow ), "g-lo-menubar" ) ); mpActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( pWindow ), "g-lo-action-group" ) ); - } - if(!mpMenuModel || !mpActionGroup) - return false; + + if(!mpMenuModel || !mpActionGroup) + return false; + } + SAL_INFO("vcl.unity", "updating menu model" << mpMenuModel); + return true; } + + return false; } /* @@ -234,16 +239,16 @@ void RemoveUnusedCommands( GLOActionGroup* pActionGroup, GList* pOldCommandList, } } -static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) +void GtkSalMenu::UpdateNativeMenu() { - if(!PrepUpdate()) + if( !PrepUpdate() ) return; // SolarMutexGuard aGuard; - Menu* pVCLMenu = pMenu->GetMenu(); - GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() ); - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( pMenu->GetActionGroup() ); + Menu* pVCLMenu = mpVCLMenu; // pMenu->GetMenu(); + GLOMenu* pLOMenu = G_LO_MENU( mpMenuModel ); // G_LO_MENU( pMenu->GetMenuModel() ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); // G_LO_ACTION_GROUP( pMenu->GetActionGroup() ); GList *pOldCommandList = NULL; GList *pNewCommandList = NULL; @@ -257,11 +262,11 @@ static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) sal_Int32 validItems = 0; sal_Int32 nItem; - for ( nItem = 0; nItem < ( sal_Int32 ) pMenu->GetItemCount(); nItem++ ) { - if ( pMenu->IsItemVisible( nItem ) == sal_False ) + for ( nItem = 0; nItem < ( sal_Int32 ) GetItemCount(); nItem++ ) { + if ( IsItemVisible( nItem ) == sal_False ) continue; - GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem ); + GtkSalMenuItem *pSalMenuItem = GetItemAtPos( nItem ); sal_uInt16 nId = pSalMenuItem->mnId; if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) @@ -337,7 +342,7 @@ static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) ); - GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); + //GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); if ( pSubMenuModel == NULL ) { @@ -347,11 +352,12 @@ static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) g_object_unref( pSubMenuModel ); + pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) ); + pSubmenu->SetActionGroup( G_ACTION_GROUP( pActionGroup ) ); + pSubmenu->GetMenu()->Activate(); pSubmenu->GetMenu()->Deactivate(); - pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) ); - pSubmenu->SetActionGroup( pActionGroup ); pSubmenu->UpdateNativeMenu(); } else if (pSubMenuModel) @@ -364,14 +370,14 @@ static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) ++nItemPos; ++validItems; } - while ( nItemPos < g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) - g_lo_menu_remove_from_section( pLOMenu, nSection, nItemPos ); - ++nSection; - if ( nSection < g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ) ) - { - SAL_INFO("vcl.unity", "nSection " << nSection << " model sections " << g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) )); - g_lo_menu_remove(pLOMenu, nSection ); - } +// while ( nItemPos < g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) +// g_lo_menu_remove_from_section( pLOMenu, nSection, nItemPos ); +// ++nSection; +// if ( nSection < g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ) ) +// { +// SAL_INFO("vcl.unity", "nSection " << nSection << " model sections " << g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) )); +// g_lo_menu_remove(pLOMenu, nSection ); +// } // Delete extra items in last section. RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems ); @@ -392,20 +398,17 @@ void GtkSalMenu::DisconnectFrame() mpFrame = NULL; } } - -void ObjectDestroyedNotify( gpointer data ) -{ - if ( data ) { - g_object_unref( data ); - } -} - /* * GtkSalMenu */ +//void GtkSalMenu::UpdateNativeMenu() +//{ +// UpdateNativeSubMenu(); +//} + GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : mbMenuBar( bMenuBar ), mpVCLMenu( NULL ), @@ -419,8 +422,6 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : GtkSalMenu::~GtkSalMenu() { if ( mbMenuBar == sal_True ) { -// g_source_remove_by_user_data( this ); - ((GtkSalFrame*) mpFrame)->SetMenu( NULL ); } @@ -499,6 +500,7 @@ const GtkSalFrame* GtkSalMenu::GetFrame() const void GtkSalMenu::NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck ) { SolarMutexGuard aGuard; + if ( mpActionGroup == NULL ) return; @@ -510,9 +512,7 @@ void GtkSalMenu::NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItem GVariant *pCurrentState = g_action_group_get_action_state( mpActionGroup, aCommand ); if ( bits & MIB_RADIOCHECK ) - { pCheckValue = ( bCheck == TRUE ) ? g_variant_new_string( aCommand ) : g_variant_new_string( "" ); - } else { // By default, all checked items are checkmark buttons. @@ -523,7 +523,7 @@ void GtkSalMenu::NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItem if ( pCheckValue != NULL && ( pCurrentState == NULL || g_variant_equal( pCurrentState, pCheckValue ) == FALSE ) ) g_action_group_change_action_state( mpActionGroup, aCommand, pCheckValue ); - if ( pCurrentState ) + if ( pCurrentState != NULL ) g_variant_unref( pCurrentState ); } @@ -571,10 +571,10 @@ void GtkSalMenu::NativeSetAccelerator( unsigned nSection, unsigned nItemPos, con gchar* aAccelerator = gtk_accelerator_name( nKeyCode, nModifiers ); - gchar* aCurrentAccel = g_lo_menu_get_accelerator_from_item_in_section( pMenu, nSection, nItemPos ); + gchar* aCurrentAccel = g_lo_menu_get_accelerator_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos ); if ( aCurrentAccel == NULL && g_strcmp0( aCurrentAccel, aAccelerator ) != 0 ) - g_lo_menu_set_accelerator_to_item_in_section ( pMenu, nSection, nItemPos, aAccelerator ); + g_lo_menu_set_accelerator_to_item_in_section ( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aAccelerator ); g_free( aAccelerator ); } commit 1f6be4b90cbade793ad5d6adcc326523902f695e Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Tue Sep 25 15:08:57 2012 +0100 Spare items and its actions are now removed. Change-Id: Idb46b5dec4351e16c5c49a355c7d3cde3aab0789 diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index 1c4a326..d99d73a 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -24,15 +24,14 @@ #ifndef GTKSALMENU_HXX #define GTKSALMENU_HXX -#include <vcl/sv.h> -#include <vcl/bitmap.hxx> -#include <unx/gtk/gtkframe.hxx> -#include <unx/salmenu.h> - +#include <vector> #include <gio/gio.h> -#include "glomenu.h" -#include "gloactiongroup.h" +#include <unx/salmenu.h> +#include <unx/gtk/gtkframe.hxx> +#include <unx/gtk/glomenu.h> +#include <unx/gtk/gloactiongroup.h> +#include <vcl/sv.h> class MenuItemList; diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index c8ba23d..a31ab1a 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -158,13 +158,94 @@ bool GtkSalMenu::PrepUpdate() } } -void GtkSalMenu::UpdateNativeMenu( ) +/* + * Menu updating methods + */ + +void RemoveSpareItemsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, unsigned nSection, unsigned nValidItems ) +{ + sal_Int32 nSectionItems = g_lo_menu_get_n_items_from_section( pMenu, nSection ); + + while ( nSectionItems > (sal_Int32) nValidItems ) + { + gchar* aCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, --nSectionItems ); + + if ( aCommand != NULL && pOldCommandList != NULL ) + *pOldCommandList = g_list_append( *pOldCommandList, g_strdup( aCommand ) ); + + g_free( aCommand ); + + g_lo_menu_remove_from_section( pMenu, nSection, nSectionItems ); + } +} + +void RemoveSpareSectionsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, unsigned nLastSection ) +{ + if ( pMenu == NULL || pOldCommandList == NULL ) + return; + + sal_Int32 n = g_menu_model_get_n_items( G_MENU_MODEL( pMenu ) ) - 1; + + for ( ; n > (sal_Int32) nLastSection; n-- ) + { + RemoveSpareItemsFromNativeMenu( pMenu, pOldCommandList, n, 0 ); + g_lo_menu_remove( pMenu, n ); + } +} + +gint CompareStr( gpointer str1, gpointer str2 ) +{ + return g_strcmp0( (const gchar*) str1, (const gchar*) str2 ); +} + +void RemoveUnusedCommands( GLOActionGroup* pActionGroup, GList* pOldCommandList, GList* pNewCommandList ) +{ + if ( pActionGroup == NULL || pOldCommandList == NULL ) + return; + + while ( pNewCommandList != NULL ) + { + GList* pNewCommand = g_list_first( pNewCommandList ); + pNewCommandList = g_list_remove_link( pNewCommandList, pNewCommand ); + + gpointer aCommand = g_list_nth_data( pNewCommand, 0 ); + + GList* pOldCommand = g_list_find_custom( pOldCommandList, aCommand, (GCompareFunc) CompareStr ); + + if ( pOldCommand != NULL ) + { + pOldCommandList = g_list_remove_link( pOldCommandList, pOldCommand ); + g_list_free_full( pOldCommand, g_free ); + } + + g_list_free_full( pNewCommand, g_free ); + } + + while ( pOldCommandList != NULL ) + { + GList* pCommand = g_list_first( pOldCommandList ); + pOldCommandList = g_list_remove_link( pOldCommandList, pCommand ); + + gchar* aCommand = (gchar*) g_list_nth_data( pCommand, 0 ); + + g_lo_action_group_remove( pActionGroup, aCommand ); + + g_list_free_full( pCommand, g_free ); + } +} + +static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) { if(!PrepUpdate()) return; - Menu* pVCLMenu = GetMenu(); - GLOMenu* pLOMenu = G_LO_MENU( GetMenuModel() ); - GActionGroup* pActionGroup = GetActionGroup(); + +// SolarMutexGuard aGuard; + + Menu* pVCLMenu = pMenu->GetMenu(); + GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( pMenu->GetActionGroup() ); + GList *pOldCommandList = NULL; + GList *pNewCommandList = NULL; sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ); @@ -186,11 +267,7 @@ void GtkSalMenu::UpdateNativeMenu( ) if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) { // Delete extra items from current section. - sal_uInt16 nSectionItems = g_lo_menu_get_n_items_from_section( pLOMenu, nSection ); - - while ( nSectionItems > validItems ) - // FIXME Remove associated command if needed. - g_lo_menu_remove_from_section( pLOMenu, nSection, --nSectionItems ); + RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems ); nSection++; nItemPos = 0; @@ -221,6 +298,12 @@ void GtkSalMenu::UpdateNativeMenu( ) gboolean bEnabled = ( itemEnabled == sal_True ) ? TRUE : FALSE; gchar* aNativeCommand = g_strdup( rtl::OUStringToOString( aCommand, RTL_TEXTENCODING_UTF8 ).getStr() ); + // Store current item command in command list. + gchar *aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pLOMenu, nSection, nItemPos ); + + if ( aCurrentCommand != NULL ) + pOldCommandList = g_list_append( pOldCommandList, aCurrentCommand ); + // Force updating of native menu labels. NativeSetItemText( nSection, nItemPos, aText ); NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( GetFrame()->GetWindow() ) ); @@ -242,6 +325,8 @@ void GtkSalMenu::UpdateNativeMenu( ) NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE ); NativeCheckItem( nSection, nItemPos, itemBits, bChecked ); NativeSetEnableItem( aNativeCommand, bEnabled ); + + pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) ); } GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; @@ -250,6 +335,10 @@ void GtkSalMenu::UpdateNativeMenu( ) if ( pSubmenu && pSubmenu->GetMenu() ) { NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); + pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) ); + + GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); + if ( pSubMenuModel == NULL ) { pSubMenuModel = g_lo_menu_new(); @@ -285,15 +374,13 @@ void GtkSalMenu::UpdateNativeMenu( ) } // Delete extra items in last section. - sal_Int32 nSectionItems = (sal_Int32) g_lo_menu_get_n_items_from_section( pLOMenu, nSection ); - - while ( nSectionItems > validItems ) - g_lo_menu_remove_from_section( pLOMenu, nSection, --nSectionItems ); + RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems ); // Delete extra sections. - for ( sal_Int32 n = nLOMenuSize - 1; n > nSection; ) - // FIXME Remove associated command if needed. - g_lo_menu_remove( pLOMenu, n-- ); + RemoveSpareSectionsFromNativeMenu( pLOMenu, &pOldCommandList, nSection ); + + // Delete unused commands. + RemoveUnusedCommands( pActionGroup, pOldCommandList, pNewCommandList ); } void GtkSalMenu::DisconnectFrame() @@ -607,7 +694,8 @@ void GtkSalMenu::Activate( const gchar* aMenuCommand ) GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE ); if ( pSalSubMenu != NULL ) { - pSalSubMenu->mpVCLMenu->Activate(); + MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu ); + pMenuBar->HandleMenuActivateEvent( pSalSubMenu->mpVCLMenu ); pSalSubMenu->UpdateNativeMenu(); } } @@ -620,7 +708,8 @@ void GtkSalMenu::Deactivate( const gchar* aMenuCommand ) GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE ); if ( pSalSubMenu != NULL ) { - pSalSubMenu->mpVCLMenu->Deactivate(); + MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu ); + pMenuBar->HandleMenuDeActivateEvent( pSalSubMenu->mpVCLMenu ); } } commit 25d637eb322f4aa37e5048e3d46fac62fb0f40be Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Mon Sep 24 16:20:57 2012 +0100 Extra menu items are removed when needed, but not their actions. Change-Id: If817b03cc7b30bfeb751e47fff4aa571fdaaafdc diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index acd176c..c8ba23d 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -171,12 +171,12 @@ void GtkSalMenu::UpdateNativeMenu( ) if ( nLOMenuSize == 0 ) g_lo_menu_new_section( pLOMenu, 0, NULL ); - sal_uInt16 nSection = 0; - sal_uInt16 nItemPos = 0; - sal_uInt16 validItems = 0; - sal_uInt16 nItem; + sal_Int32 nSection = 0; + sal_Int32 nItemPos = 0; + sal_Int32 validItems = 0; + sal_Int32 nItem; - for ( nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) { + for ( nItem = 0; nItem < ( sal_Int32 ) pMenu->GetItemCount(); nItem++ ) { if ( pMenu->IsItemVisible( nItem ) == sal_False ) continue; @@ -185,9 +185,13 @@ void GtkSalMenu::UpdateNativeMenu( ) if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) { - while ( nItemPos < g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) - g_lo_menu_remove_from_section( pLOMenu, nSection, nItemPos ); - + // Delete extra items from current section. + sal_uInt16 nSectionItems = g_lo_menu_get_n_items_from_section( pLOMenu, nSection ); + + while ( nSectionItems > validItems ) + // FIXME Remove associated command if needed. + g_lo_menu_remove_from_section( pLOMenu, nSection, --nSectionItems ); + nSection++; nItemPos = 0; validItems = 0; @@ -279,6 +283,17 @@ void GtkSalMenu::UpdateNativeMenu( ) SAL_INFO("vcl.unity", "nSection " << nSection << " model sections " << g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) )); g_lo_menu_remove(pLOMenu, nSection ); } + + // Delete extra items in last section. + sal_Int32 nSectionItems = (sal_Int32) g_lo_menu_get_n_items_from_section( pLOMenu, nSection ); + + while ( nSectionItems > validItems ) + g_lo_menu_remove_from_section( pLOMenu, nSection, --nSectionItems ); + + // Delete extra sections. + for ( sal_Int32 n = nLOMenuSize - 1; n > nSection; ) + // FIXME Remove associated command if needed. + g_lo_menu_remove( pLOMenu, n-- ); } void GtkSalMenu::DisconnectFrame() @@ -630,7 +645,7 @@ void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable ) void GtkSalMenu::ShowItem( unsigned nPos, sal_Bool bShow ) { if ( nPos < maItems.size() ) - ( ( GtkSalMenuItem* ) maItems[ nPos ])->mbVisible = bShow; + ( ( GtkSalMenuItem* ) maItems[ nPos ] )->mbVisible = bShow; } commit cb099858d57d153dd8f56416acccdafad1b71887 Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Mon Sep 24 13:11:45 2012 +0100 Hidden items are not shown anymore. Change-Id: I957c8c7690321be58e8daaf2fb65ebef136d95bc diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx index 2f8d680..3411cb2 100644 --- a/vcl/inc/salmenu.hxx +++ b/vcl/inc/salmenu.hxx @@ -75,7 +75,7 @@ public: virtual ~SalMenu(); virtual sal_Bool VisibleMenuBar() = 0; // must return sal_True to actually DISPLAY native menu bars - // otherwise only menu messages are processed (eg, OLE on Windows) + // otherwise only menu messages are processed (eg, OLE on Windows) virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) = 0; virtual void RemoveItem( unsigned nPos ) = 0; @@ -91,7 +91,9 @@ public: virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure virtual void RemoveMenuBarButton( sal_uInt16 nId ); - virtual void SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr ) {} + // FIXME: Make the other VCL native backends to work with these new methods. + virtual void SetItemCommand( unsigned, SalMenuItem*, const rtl::OUString& ) {} + virtual void ShowItem( unsigned nPos, sal_Bool bShow ) { EnableItem( nPos, bShow ); } virtual void Freeze() {} // return an empty rectangle if not implemented diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index e9ffb01..1c4a326 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -69,6 +69,7 @@ public: virtual const GtkSalFrame* GetFrame() const; virtual void CheckItem( unsigned nPos, sal_Bool bCheck ); virtual void EnableItem( unsigned nPos, sal_Bool bEnable ); + virtual void ShowItem( unsigned nPos, sal_Bool bShow ); virtual void SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText ); virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage); virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ); @@ -85,6 +86,7 @@ public: virtual GtkSalMenuItem* GetItemAtPos( unsigned nPos ) { return maItems[ nPos ]; } virtual void SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; } virtual GActionGroup* GetActionGroup() { return mpActionGroup; } + virtual sal_Bool IsItemVisible( unsigned nPos ); void NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText ); void NativeSetItemCommand( unsigned nSection, @@ -114,9 +116,10 @@ public: sal_uInt16 mnId; // Item ID MenuItemType mnType; // Item type - Menu* mpVCLMenu; // VCL Menu into which this MenuItem is inserted - GtkSalMenu* mpParentMenu; // The menu in which this menu item is inserted - GtkSalMenu* mpSubMenu; // Sub menu of this item (if defined) + sal_Bool mbVisible; // Item visibility. + Menu* mpVCLMenu; // VCL Menu into which this menu item is inserted + GtkSalMenu* mpParentMenu; // The menu into which this menu item is inserted + GtkSalMenu* mpSubMenu; // Submenu of this item (if defined) }; #endif // GTKSALMENU_HXX diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 7fc74e4..bf41af8 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -1811,7 +1811,8 @@ void Menu::ShowItem( sal_uInt16 nItemId, sal_Bool bVisible ) // as long as there is no support to hide native menu entries, we just disable them // TODO: add support to show/hide native menu entries if( ImplGetSalMenu() ) - ImplGetSalMenu()->EnableItem( nPos, bVisible ); +// ImplGetSalMenu()->EnableItem( nPos, bVisible ); + ImplGetSalMenu()->ShowItem( nPos, bVisible ); } } diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index bad553e..acd176c 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -31,6 +31,8 @@ # include <gdk/gdkkeysyms-compat.h> #endif +#include <svtools/menuoptions.hxx> + #include <framework/menuconfiguration.hxx> #include <sal/log.hxx> @@ -136,23 +138,24 @@ bool GtkSalMenu::PrepUpdate() const GtkSalFrame* pFrame = GetFrame(); if (!pFrame) { - const GObject* pWindow = G_OBJECT(gtk_widget_get_window( GTK_WIDGET(pFrame->getWindow()) )); - if(!pWindow) - { - SAL_INFO("vcl.unity", "not updating menu model, I have no frame " << mpMenuModel); - return false; - } + const GObject* pWindow = G_OBJECT(gtk_widget_get_window( GTK_WIDGET(pFrame->getWindow()) )); + if(!pWindow) + { + SAL_INFO("vcl.unity", "not updating menu model, I have no frame " << mpMenuModel); + return false; + } - // the root menu does not have its own model and has to use the one owned by the frame - if(mbMenuBar) - { - mpMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( pWindow ), "g-lo-menubar" ) ); - mpActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( pWindow ), "g-lo-action-group" ) ); + // the root menu does not have its own model and has to use the one owned by the frame + if(mbMenuBar) + { + mpMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( pWindow ), "g-lo-menubar" ) ); + mpActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( pWindow ), "g-lo-action-group" ) ); + } + if(!mpMenuModel || !mpActionGroup) + return false; + SAL_INFO("vcl.unity", "updating menu model" << mpMenuModel); + return true; } - if(!mpMenuModel || !mpActionGroup) - return false; - SAL_INFO("vcl.unity", "updating menu model" << mpMenuModel); - return true; } void GtkSalMenu::UpdateNativeMenu( ) @@ -173,16 +176,21 @@ void GtkSalMenu::UpdateNativeMenu( ) sal_uInt16 validItems = 0; sal_uInt16 nItem; - for ( nItem = 0; nItem < GetItemCount(); nItem++ ) { - GtkSalMenuItem *pSalMenuItem = GetItemAtPos( nItem ); + for ( nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) { + if ( pMenu->IsItemVisible( nItem ) == sal_False ) + continue; + + GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem ); sal_uInt16 nId = pSalMenuItem->mnId; if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) { while ( nItemPos < g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) g_lo_menu_remove_from_section( pLOMenu, nSection, nItemPos ); + nSection++; nItemPos = 0; + validItems = 0; if ( nLOMenuSize <= nSection ) { @@ -601,6 +609,16 @@ void GtkSalMenu::Deactivate( const gchar* aMenuCommand ) } } +sal_Bool GtkSalMenu::IsItemVisible( unsigned nPos ) +{ + sal_Bool bVisible = sal_False; + + if ( nPos < maItems.size() ) + bVisible = ( ( GtkSalMenuItem* ) maItems[ nPos ])->mbVisible; + + return bVisible; +} + void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck ) { } @@ -609,6 +627,13 @@ void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable ) { } +void GtkSalMenu::ShowItem( unsigned nPos, sal_Bool bShow ) +{ + if ( nPos < maItems.size() ) + ( ( GtkSalMenuItem* ) maItems[ nPos ])->mbVisible = bShow; +} + + void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText ) { } @@ -642,6 +667,7 @@ void GtkSalMenu::Freeze() GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) : mnId( pItemData->nId ), mnType( pItemData->eType ), + mbVisible( sal_True ), mpVCLMenu( pItemData->pMenu ), mpParentMenu( NULL ), mpSubMenu( NULL ) commit 82c4e77a75835049f11f46962c70f82fca5bf4c7 Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Sat Sep 22 20:21:44 2012 +0100 All accelerators should be displayed now. Change-Id: I4599e9f23ba0b1150a3a24cb5d10736895c38891 diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index c798d41..e9ffb01 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -45,7 +45,6 @@ private: std::vector< GtkSalMenuItem* > maItems; sal_Bool mbMenuBar; - sal_Bool mbVisible; Menu* mpVCLMenu; GtkSalMenu* mpParentSalMenu; const GtkSalFrame* mpFrame; diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index fc568d3..bad553e 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -22,12 +22,15 @@ #include <unx/gtk/gtksalmenu.hxx> -//#include <gtk/gtk.h> #include <unx/gtk/glomenu.h> #include <unx/gtk/gloactiongroup.h> #include <vcl/menu.hxx> #include <unx/gtk/gtkinst.hxx> +#if GTK_CHECK_VERSION(3,0,0) +# include <gdk/gdkkeysyms-compat.h> +#endif + #include <framework/menuconfiguration.hxx> #include <sal/log.hxx> @@ -47,29 +50,85 @@ static gchar* GetCommandForSpecialItem( GtkSalMenuItem* pSalMenuItem ) return aCommand; } -// FIXME: Check for missing keys. Maybe translating keycodes would be safer... -rtl::OUString GetGtkKeyName( rtl::OUString keyName ) +static void KeyCodeToGdkKey ( const KeyCode& rKeyCode, guint* pGdkKeyCode, GdkModifierType *pGdkModifiers ) { - rtl::OUString aGtkKeyName(""); + if ( pGdkKeyCode == NULL || pGdkModifiers == NULL ) + return; + + // Get GDK key modifiers + GdkModifierType nModifiers = (GdkModifierType) 0; + + if ( rKeyCode.IsShift() ) + nModifiers = (GdkModifierType) ( nModifiers | GDK_SHIFT_MASK ); + + if ( rKeyCode.IsMod1() ) + nModifiers = (GdkModifierType) ( nModifiers | GDK_CONTROL_MASK ); - sal_Int32 nIndex = 0; + if ( rKeyCode.IsMod2() ) + nModifiers = (GdkModifierType) ( nModifiers | GDK_MOD1_MASK ); - do + *pGdkModifiers = nModifiers; + + // Get GDK keycode. + guint nKeyCode = 0; + + guint nCode = rKeyCode.GetCode(); + + if ( nCode >= KEY_0 && nCode <= KEY_9 ) + nKeyCode = ( nCode - KEY_0 ) + GDK_0; + else if ( nCode >= KEY_A && nCode <= KEY_Z ) + nKeyCode = ( nCode - KEY_A ) + GDK_A; + else if ( nCode >= KEY_F1 && nCode <= KEY_F26 ) + nKeyCode = ( nCode - KEY_F1 ) + GDK_F1; + else { - rtl::OUString token = keyName.getToken( 0, '+', nIndex ); - - if ( token == "Ctrl" ) { - aGtkKeyName += "<Control>"; - } else if ( token == "Alt" ) { - aGtkKeyName += "<Alt>"; - } else if ( token == "Shift" ) { - aGtkKeyName += "<Shift>"; - } else { - aGtkKeyName += token; + switch( nCode ) + { + case KEY_DOWN: nKeyCode = GDK_Down; break; + case KEY_UP: nKeyCode = GDK_Up; break; + case KEY_LEFT: nKeyCode = GDK_Left; break; + case KEY_RIGHT: nKeyCode = GDK_Right; break; + case KEY_HOME: nKeyCode = GDK_Home; break; + case KEY_END: nKeyCode = GDK_End; break; + case KEY_PAGEUP: nKeyCode = GDK_Page_Up; break; + case KEY_PAGEDOWN: nKeyCode = GDK_Page_Down; break; + case KEY_RETURN: nKeyCode = GDK_Return; break; + case KEY_ESCAPE: nKeyCode = GDK_Escape; break; + case KEY_TAB: nKeyCode = GDK_Tab; break; + case KEY_BACKSPACE: nKeyCode = GDK_BackSpace; break; + case KEY_SPACE: nKeyCode = GDK_space; break; + case KEY_INSERT: nKeyCode = GDK_Insert; break; + case KEY_DELETE: nKeyCode = GDK_Delete; break; + case KEY_ADD: nKeyCode = GDK_plus; break; + case KEY_SUBTRACT: nKeyCode = GDK_minus; break; + case KEY_MULTIPLY: nKeyCode = GDK_asterisk; break; + case KEY_DIVIDE: nKeyCode = GDK_slash; break; + case KEY_POINT: nKeyCode = GDK_period; break; + case KEY_COMMA: nKeyCode = GDK_comma; break; + case KEY_LESS: nKeyCode = GDK_less; break; + case KEY_GREATER: nKeyCode = GDK_greater; break; + case KEY_EQUAL: nKeyCode = GDK_equal; break; + case KEY_FIND: nKeyCode = GDK_Find; break; + case KEY_CONTEXTMENU: nKeyCode = GDK_Menu; break; + case KEY_HELP: nKeyCode = GDK_Help; break; + case KEY_UNDO: nKeyCode = GDK_Undo; break; + case KEY_REPEAT: nKeyCode = GDK_Redo; break; + case KEY_DECIMAL: nKeyCode = GDK_KP_Decimal; break; + case KEY_TILDE: nKeyCode = GDK_asciitilde; break; + case KEY_QUOTELEFT: nKeyCode = GDK_quoteleft; break; + case KEY_BRACKETLEFT: nKeyCode = GDK_bracketleft; break; + case KEY_BRACKETRIGHT: nKeyCode = GDK_bracketright; break; + case KEY_SEMICOLON: nKeyCode = GDK_semicolon; break; + + // Special cases + case KEY_COPY: nKeyCode = GDK_Copy; break; + case KEY_CUT: nKeyCode = GDK_Cut; break; + case KEY_PASTE: nKeyCode = GDK_Paste; break; + case KEY_OPEN: nKeyCode = GDK_Open; break; } - } while ( nIndex >= 0 ); + } - return aGtkKeyName; + *pGdkKeyCode = nKeyCode; } bool GtkSalMenu::PrepUpdate() @@ -77,15 +136,13 @@ bool GtkSalMenu::PrepUpdate() const GtkSalFrame* pFrame = GetFrame(); if (!pFrame) { - SAL_INFO("vcl.unity", "not updating menu model, I have no frame " << mpMenuModel); - return false; - } const GObject* pWindow = G_OBJECT(gtk_widget_get_window( GTK_WIDGET(pFrame->getWindow()) )); if(!pWindow) { SAL_INFO("vcl.unity", "not updating menu model, I have no frame " << mpMenuModel); return false; } + // the root menu does not have its own model and has to use the one owned by the frame if(mbMenuBar) { @@ -241,7 +298,6 @@ void ObjectDestroyedNotify( gpointer data ) GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : mbMenuBar( bMenuBar ), - mbVisible( sal_False ), mpVCLMenu( NULL ), mpParentSalMenu( NULL ), mpFrame( NULL ), @@ -394,18 +450,23 @@ void GtkSalMenu::NativeSetItemText( unsigned nSection, unsigned nItemPos, const void GtkSalMenu::NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ) { SolarMutexGuard aGuard; + if ( rKeyName.isEmpty() ) return; - rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 ); + guint nKeyCode; + GdkModifierType nModifiers; + + KeyCodeToGdkKey( rKeyCode, &nKeyCode, &nModifiers ); + + gchar* aAccelerator = gtk_accelerator_name( nKeyCode, nModifiers ); - gchar* aCurrentAccel = g_lo_menu_get_accelerator_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos ); + gchar* aCurrentAccel = g_lo_menu_get_accelerator_from_item_in_section( pMenu, nSection, nItemPos ); - if ( aCurrentAccel == NULL && g_strcmp0( aCurrentAccel, aAccelerator.getStr() ) != 0 ) - g_lo_menu_set_accelerator_to_item_in_section ( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aAccelerator.getStr() ); + if ( aCurrentAccel == NULL && g_strcmp0( aCurrentAccel, aAccelerator ) != 0 ) + g_lo_menu_set_accelerator_to_item_in_section ( pMenu, nSection, nItemPos, aAccelerator ); - if ( aCurrentAccel ) - g_free( aCurrentAccel ); + g_free( aAccelerator ); } void GtkSalMenu::NativeSetItemCommand( unsigned nSection, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits