diff options
author | Antonio Fernandez <antonio.fernandez@aentos.es> | 2012-09-12 20:45:31 +0100 |
---|---|---|
committer | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2012-11-14 13:52:48 +0100 |
commit | 6b42d547cfbe87e934f65c74cb180f5f1c10c6c2 (patch) | |
tree | 8cea204a387f909f34e4210cd1fee2272b8ed55a | |
parent | b789263fb7bf537cc85d3df3022282ab8f32bccb (diff) |
Menus are generated on demand now, but with some issues.
Change-Id: Icec9b685e720a369cff4d2bbfc5bf4ba6614e390
-rw-r--r-- | vcl/inc/unx/gtk/gloactiongroup.h | 4 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtksalmenu.hxx | 4 | ||||
-rw-r--r-- | vcl/source/window/menu.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gloactiongroup.cxx | 59 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalmenu.cxx | 142 |
5 files changed, 189 insertions, 25 deletions
diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h index e0d783fe3778..61ec718d4cd3 100644 --- a/vcl/inc/unx/gtk/gloactiongroup.h +++ b/vcl/inc/unx/gtk/gloactiongroup.h @@ -67,11 +67,13 @@ GLOActionGroup * g_lo_action_group_new (gpointer void g_lo_action_group_insert (GLOActionGroup *group, const gchar *action_name, - gint item_id); + gint item_id, + gboolean submenu); void g_lo_action_group_insert_stateful (GLOActionGroup *group, const gchar *action_name, gint item_id, + gboolean submenu, const GVariantType *parameter_type, const GVariantType *state_type, GVariant *state_hint, diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index d7d59662f945..56aed28d8277 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -55,7 +55,7 @@ private: GMenuModel* mpMenuModel; GActionGroup* mpActionGroup; - GtkSalMenu* GetMenuForItemCommand( gchar* aCommand ); + GtkSalMenu* GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu ); public: GtkSalMenu( sal_Bool bMenuBar ); @@ -101,6 +101,8 @@ public: void NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ); void DispatchCommand( gint itemId, const gchar* aCommand ); + void Activate( const gchar* aMenuCommand ); + void Deactivate( const gchar* aMenuCommand ); }; class GtkSalMenuItem : public SalMenuItem diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 10bcdf66da3f..00abe068dfee 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -1135,8 +1135,7 @@ void Menu::Select() } } -// FIXME: Workaround to make GLOMenu without defining macros. -//#if defined(QUARTZ) +#if defined(QUARTZ) void Menu::ImplSelectWithStart( Menu* pSMenu ) { Menu* pOldStartedFrom = pStartedFrom; @@ -1147,7 +1146,7 @@ void Menu::ImplSelectWithStart( Menu* pSMenu ) pOldStartedFrom->pStartedFrom = pOldStartedStarted; pStartedFrom = pOldStartedFrom; } -//#endif +#endif void Menu::RequestHelp( const HelpEvent& ) { diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx index 171341dcd4a7..11173880774e 100644 --- a/vcl/unx/gtk/window/gloactiongroup.cxx +++ b/vcl/unx/gtk/window/gloactiongroup.cxx @@ -43,7 +43,8 @@ struct _GLOAction GObject parent_instance; gint item_id; // Menu item ID. - gboolean enabled; // TRUE if action is enabled, FALSE otherwise. + gboolean submenu; // TRUE if action is a submenu action. + gboolean enabled; // TRUE if action is enabled. GVariantType* parameter_type; // A GVariantType with the action parameter type. GVariantType* state_type; // A GVariantType with item state type GVariant* state_hint; // A GVariant with state hints. @@ -65,6 +66,7 @@ static void g_lo_action_init (GLOAction *action) { action->item_id = -1; + action->submenu = FALSE; action->enabled = TRUE; action->parameter_type = NULL; action->state_type = NULL; @@ -174,6 +176,30 @@ g_lo_action_group_query_action (GActionGroup *group, } static void +g_lo_action_group_perform_submenu_action (GLOActionGroup *group, + const gchar *action_name, + GVariant *state) +{ + GTK_YIELD_GRAB(); + + GtkSalFrame* pFrame = group->priv->frame; + + if (pFrame == NULL) + return; + + GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*> (pFrame->GetMenu()); + + if (pSalMenu != NULL) { + gboolean bState = g_variant_get_boolean (state); + + if (bState == TRUE) + pSalMenu->Activate (action_name); + else + pSalMenu->Deactivate (action_name); + } +} + +static void g_lo_action_group_change_state (GActionGroup *group, const gchar *action_name, GVariant *value) @@ -182,23 +208,29 @@ g_lo_action_group_change_state (GActionGroup *group, return; GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group); - GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name)); if (action == NULL) return; - if (action->state_type == NULL) - action->state_type = g_variant_type_copy(g_variant_get_type(value)); - - g_return_if_fail (g_variant_is_of_type(value, action->state_type) == TRUE); + if (action->submenu == TRUE) + { +// g_action_group_action_state_changed(group, action_name, value); + g_lo_action_group_perform_submenu_action (lo_group, action_name, value); + } + else + { + if (action->state_type == NULL) + action->state_type = g_variant_type_copy(g_variant_get_type(value)); - if (action->state) - g_variant_unref(action->state); + g_return_if_fail (g_variant_is_of_type(value, action->state_type) == TRUE); - action->state = g_variant_take_ref(value); + if (action->state) + g_variant_unref(action->state); - g_action_group_action_state_changed(group, action_name, value); + action->state = g_variant_take_ref(value); + g_action_group_action_state_changed(group, action_name, value); + } } static void @@ -226,15 +258,17 @@ g_lo_action_group_activate (GActionGroup *group, void g_lo_action_group_insert (GLOActionGroup *group, const gchar *action_name, - gint item_id) + gint item_id, + gboolean submenu) { - g_lo_action_group_insert_stateful (group, action_name, item_id, NULL, NULL, NULL, NULL); + g_lo_action_group_insert_stateful (group, action_name, item_id, submenu, NULL, NULL, NULL, NULL); } void g_lo_action_group_insert_stateful (GLOActionGroup *group, const gchar *action_name, gint item_id, + gboolean submenu, const GVariantType *parameter_type, const GVariantType *state_type, GVariant *state_hint, @@ -254,6 +288,7 @@ g_lo_action_group_insert_stateful (GLOActionGroup *group, g_hash_table_insert (group->priv->table, g_strdup (action_name), action); action->item_id = item_id; + action->submenu = submenu; if (parameter_type) action->parameter_type = (GVariantType*) parameter_type; diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 98c52e5786e7..1476e61c239b 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -50,6 +50,106 @@ static gchar* GetCommandForSpecialItem( GtkSalMenuItem* pSalMenuItem ) return aCommand; } +static void UpdateNativeMenu2( GtkSalMenu *pMenu ) +{ + if ( pMenu == NULL ) + return; + + Menu* pVCLMenu = pMenu->GetMenu(); + GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() ); + GActionGroup* pActionGroup = pMenu->GetActionGroup(); + + sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ); + + if ( nLOMenuSize == 0 ) + g_lo_menu_new_section( pLOMenu, 0, NULL ); + + sal_uInt16 nSection = 0; + sal_uInt16 nItemPos = 0; + sal_uInt16 validItems = 0; + sal_uInt16 nItem; + + for ( nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) { + GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem ); + sal_uInt16 nId = pSalMenuItem->mnId; + + if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) + { + nSection++; + nItemPos = 0; + + if ( nLOMenuSize <= nSection ) + { + g_lo_menu_new_section( pLOMenu, nSection, NULL ); + nLOMenuSize++; + } + + continue; + } + + if ( nItemPos >= g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) + g_lo_menu_insert_in_section( pLOMenu, nSection, nItemPos, "EMPTY STRING" ); + + // Get internal menu item values. + String aText = pVCLMenu->GetItemText( nId ); + rtl::OUString aCommand( pVCLMenu->GetItemCommand( nId ) ); + sal_Bool itemEnabled = pVCLMenu->IsItemEnabled( nId ); + KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId ); + sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId ); + MenuItemBits itemBits = pVCLMenu->GetItemBits( nId ); + + // Convert internal values to native values. + gboolean bChecked = ( itemChecked == sal_True ) ? TRUE : FALSE; + gboolean bEnabled = ( itemEnabled == sal_True ) ? TRUE : FALSE; + gchar* aNativeCommand = g_strdup( rtl::OUStringToOString( aCommand, RTL_TEXTENCODING_UTF8 ).getStr() ); + + // Force updating of native menu labels. + pMenu->NativeSetItemText( nSection, nItemPos, aText ); + pMenu->NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) ); + + // Some items are special, so they have different commands. + if ( g_strcmp0( aNativeCommand, "" ) == 0 ) + { + gchar *aSpecialItemCmd = GetCommandForSpecialItem( pSalMenuItem ); + + if ( aSpecialItemCmd != NULL ) + { + g_free( aNativeCommand ); + aNativeCommand = aSpecialItemCmd; + } + } + + if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == NULL ) + { + pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE ); + pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked ); + pMenu->NativeSetEnableItem( aNativeCommand, bEnabled ); + } + + GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; + + if ( pSubmenu && pSubmenu->GetMenu() ) + { + GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); + + if ( pSubMenuModel == NULL ) + { + pSubMenuModel = g_lo_menu_new(); + g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) ); + } + + pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); + pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) ); + pSubmenu->SetActionGroup( pActionGroup ); + } + + g_free( aNativeCommand ); + + nItemPos++; + validItems++; + } +} + static void UpdateNativeMenu( GtkSalMenu* pMenu ) { if ( pMenu == NULL ) @@ -406,10 +506,11 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) // Generate the main menu structure. GenerateMenu( this ); +// UpdateNativeMenu2( this ); // Refresh the menu every second. // This code is a workaround until required modifications in Gtk+ are available. - g_timeout_add_seconds( 1, GenerateMenu, this ); +// g_timeout_add_seconds( 1, GenerateMenu, this ); } } @@ -511,7 +612,7 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, 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, nId, NULL, pStateType, NULL, pState ); + g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, bIsSubmenu, NULL, pStateType, NULL, pState ); } else if ( nBits & MIB_RADIOCHECK ) { @@ -521,12 +622,12 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, GVariant* pState = g_variant_new_string( "" ); pTarget = g_variant_new_string( aCommand ); - g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, pParameterType, pStateType, NULL, pState ); + g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, FALSE, pParameterType, pStateType, NULL, pState ); } else { // Item is not special, so insert a stateless action. - g_lo_action_group_insert( pActionGroup, aCommand, nId ); + g_lo_action_group_insert( pActionGroup, aCommand, nId, FALSE ); } } @@ -553,7 +654,7 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, g_free( aCurrentCommand ); } -GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand ) +GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu ) { GtkSalMenu* pMenu = NULL; @@ -566,13 +667,13 @@ GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand ) if ( g_strcmp0( aItemCommandStr, aCommand ) == 0 ) { - pMenu = this; + pMenu = ( bGetSubmenu == TRUE ) ? pSalItem->mpSubMenu : this; break; } else { if ( pSalItem->mpSubMenu != NULL ) - pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand ); + pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand, bGetSubmenu ); if ( pMenu != NULL ) break; @@ -588,7 +689,7 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand ) if ( mbMenuBar != TRUE ) return; - GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aCommand ); + GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aCommand, FALSE ); Menu* pSubMenu = ( pSalSubMenu != NULL ) ? pSalSubMenu->GetMenu() : NULL; MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu ); @@ -596,6 +697,31 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand ) pMenuBar->HandleMenuCommandEvent( pSubMenu, itemId ); } +void GtkSalMenu::Activate( const gchar* aMenuCommand ) +{ + if ( mbMenuBar != TRUE ) + return; + + GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE ); + + if ( pSalSubMenu != NULL ) { + pSalSubMenu->mpVCLMenu->Activate(); + UpdateNativeMenu2( pSalSubMenu ); + } +} + +void GtkSalMenu::Deactivate( const gchar* aMenuCommand ) +{ + if ( mbMenuBar != TRUE ) + return; + + GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE ); + + if ( pSalSubMenu != NULL ) { + pSalSubMenu->mpVCLMenu->Deactivate(); + } +} + void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck ) { } |