From c8635ff858e85031780c36258321bf7c51d4c2ff Mon Sep 17 00:00:00 2001 From: Antonio Fernandez Date: Wed, 1 Aug 2012 11:05:53 +0100 Subject: Native menu is completely build in one step. Change-Id: I772c267b3c136e6baab2623dbf5538b5076d43ff --- vcl/inc/salmenu.hxx | 3 +- vcl/inc/unx/gtk/gtksalmenu.hxx | 7 +- vcl/source/window/menu.cxx | 66 ++----------- vcl/unx/gtk/app/gtkinst.cxx | 10 +- vcl/unx/gtk/window/gtksalmenu.cxx | 191 +++++++++++++++++++++++++------------- 5 files changed, 150 insertions(+), 127 deletions(-) diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx index 010fe1662542..83f6fdc25641 100644 --- a/vcl/inc/salmenu.hxx +++ b/vcl/inc/salmenu.hxx @@ -32,7 +32,7 @@ class SalFrame; struct SalItemParams { - sal_uInt16 nId; // item Id + sal_uInt16 nId; // item Id MenuItemType eType; // MenuItem-Type MenuItemBits nBits; // MenuItem-Bits Menu* pMenu; // Pointer to Menu @@ -81,6 +81,7 @@ public: virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, sal_uLong nFlags); virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure virtual void RemoveMenuBarButton( sal_uInt16 nId ); + virtual void Freeze() {} // return an empty rectangle if not implemented // return Rectangle( Point( -1, -1 ), Size( 1, 1 ) ) if menu bar buttons implemented diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index c925a99da960..69fcec834cb9 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -39,15 +39,19 @@ class GtkSalMenu : public SalMenu { private: - sal_Bool mbMenuBar; + sal_Bool mbMenuBar; + + virtual void publishMenu(); public: Menu* mpVCLMenu; const GtkSalFrame* mpFrame; GMenuModel* mpParentMenuModel; GMenuModel* mpMenuModel; + GMenuModel* mpSectionMenuModel; gchar* aDBusMenubarPath; GDBusConnection* pSessionBus; + sal_Int32 mMenubarId; GtkSalMenu( sal_Bool bMenuBar ); virtual ~GtkSalMenu(); @@ -65,6 +69,7 @@ public: virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage); virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ); virtual void GetSystemMenuData( SystemMenuData* pData ); + virtual void Freeze(); }; class GtkSalMenuItem : public SalMenuItem diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 103719a54659..bd9ca95b3c96 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -6040,66 +6040,9 @@ ImplMenuDelData::~ImplMenuDelData() } #include -#include using namespace std; -GMenu* generateMenuBar( AbstractMenu *pMenu ) -{ - GMenu *menu = g_menu_new(); - - g_menu_append(menu, "Submenu1", NULL); - - return menu; -} - -#define BUS_NAME "org.libreoffice.LibreOffice" -#define OBJ_PATH "/org/libreoffice/LibreOffice" - -void publishMenu( GMenuModel *menu ) -{ - GActionGroup *group; - GDBusConnection *bus; - GError *error = NULL; - gchar *path; - guint id; - - bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); - group = G_ACTION_GROUP( g_simple_action_group_new() ); - - // g_print ("Exporting menus on the bus...\n"); - // if (!g_dbus_connection_export_menu_model (bus, OBJ_PATH, menu, &error)) - // { - // g_warning ("Menu export failed: %s", error->message); - // exit (1); - // } - // g_print ("Exporting actions on the bus...\n"); - // if (!g_dbus_connection_export_action_group (bus, OBJ_PATH, group, &error)) - // { - // g_warning ("Action export failed: %s", error->message); - // exit (1); - // } - - g_bus_own_name_on_connection (bus, BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); - - - /* export the new menu, if there is one */ - if (menu != NULL) - { - /* try getting the preferred name */ - path = g_strconcat (OBJ_PATH, "/menus/", "menubar", NULL); - id = g_dbus_connection_export_menu_model (bus, path, menu, NULL); - - /* keep trying until we get a working name... */ - for (int i = 0; id == 0; i++) - { - g_free (path); - path = g_strdup_printf ("%s/menus/%s%d",OBJ_PATH, "menubar", i); - id = g_dbus_connection_export_menu_model (bus, path, menu, NULL); - } - } -} - void printMenu( AbstractMenu* pMenu ) { if ( pMenu ) { sal_uInt16 itemCount = pMenu->GetItemCount(); @@ -6128,10 +6071,13 @@ void printMenu( AbstractMenu* pMenu ) { void Menu::Freeze() { printMenu( this ); - -// GMenuModel *menu = G_MENU_MODEL( generateMenuBar(this) ); -// publishMenu( menu ); cout << "============================================================" << endl; + + SalMenu *pSalMenu = ImplGetSalMenu(); + + if ( pSalMenu ) { + pSalMenu->Freeze(); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx index 40cd21380e2a..f8d49d1b962d 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -524,9 +524,15 @@ void GtkInstance::DestroyMenu( SalMenu* pMenu ) OSL_ENSURE( pMenu == 0, "DestroyMenu called with non-native menus" ); } -SalMenuItem* GtkInstance::CreateMenuItem( const SalItemParams* ) +SalMenuItem* GtkInstance::CreateMenuItem( const SalItemParams* pItemData ) { - return NULL; + GtkSalMenuItem *pMenuItem = NULL; + +// if (pItemData->eType != MENUITEM_SEPARATOR) { + pMenuItem = new GtkSalMenuItem( pItemData ); +// } + + return static_cast( pMenuItem ); } void GtkInstance::DestroyMenuItem( SalMenuItem* pItem ) diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 823a9c62152d..9c3acddc938c 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -20,40 +20,6 @@ quit (GSimpleAction *action, exit(1); } -void publishMenu( GtkSalMenu* pMenu ) -{ - GActionGroup *group; - GDBusConnection *bus; - GError *error = NULL; - gchar *path; - guint id; - - if (pMenu->pSessionBus && pMenu->aDBusMenubarPath) { - GSimpleActionGroup *simpleGroup = g_simple_action_group_new(); -// GSimpleAction *action = g_simple_action_new("quit" ); -// g_simple_action_group_insert( simpleGroup, G_ACTION( action ) ); - - group = G_ACTION_GROUP( simpleGroup ); - - - g_print ("Exporting menus on the bus...\n"); -// path = g_strconcat (OBJ_PATH, "/menus/", "menubar", NULL); - if (!g_dbus_connection_export_menu_model (pMenu->pSessionBus, pMenu->aDBusMenubarPath, pMenu->mpMenuModel, &error)) - { - g_warning ("Menu export failed: %s", error->message); - // exit (1); - } - g_print ("Exporting actions on the bus...\n"); - if (!g_dbus_connection_export_action_group (pMenu->pSessionBus, OBJ_PATH, group, &error)) - { - g_warning ("Action export failed: %s", error->message); - // exit (1); - } - - g_bus_own_name_on_connection (pMenu->pSessionBus, BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); - } -} - void gdk_x11_window_set_utf8_property (GdkWindow *window, const gchar *name, @@ -82,32 +48,83 @@ gdk_x11_window_set_utf8_property (GdkWindow *window, } } -GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : - mbMenuBar( bMenuBar ), - mpVCLMenu( NULL ), - mpParentMenuModel( NULL ), - aDBusMenubarPath( NULL ), - pSessionBus( NULL ) +GMenuModel* generateMenuModel( Menu *pVCLMenu ) { - mpMenuModel = G_MENU_MODEL( g_menu_new() ); + if (!pVCLMenu) + return NULL; + + GMenu *pMenuModel = g_menu_new(); + GMenu *pSectionMenuModel = g_menu_new(); + + for (int i = 0; i < pVCLMenu->GetItemCount(); i++) { + MenuItemType itemType = pVCLMenu->GetItemType( i ); - if (bMenuBar) { -// pSessionBus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); + if ( itemType == MENUITEM_SEPARATOR ) { + g_menu_append_section( pMenuModel, NULL, G_MENU_MODEL( pSectionMenuModel ) ); + pSectionMenuModel = g_menu_new(); + } else { + sal_Int16 nId = pVCLMenu->GetItemId( i ); -// aDBusMenubarPath = g_strconcat (OBJ_PATH, "/menus/", "menubar", NULL); + rtl::OUString aTextLabel = pVCLMenu->GetItemText( nId ); + rtl::OUString aText = aTextLabel.replace( '~', '_' ); + rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8); -// GMenu *menu = G_MENU( mpMenuModel ); + GMenuItem *menuItem = g_menu_item_new( (char*) aConvertedText.getStr(), NULL); -// g_menu_append( menu, "Menu1", "app.quit"); + GMenuModel *pSubmenu = generateMenuModel( pVCLMenu->GetPopupMenu( nId ) ); -// publishMenu( this ); + g_menu_item_set_submenu( menuItem, pSubmenu ); + + g_menu_append_item( pSectionMenuModel, menuItem ); + } } + + g_menu_append_section( pMenuModel, NULL, G_MENU_MODEL( pSectionMenuModel ) ); + + return G_MENU_MODEL( pMenuModel ); +} + +void GtkSalMenu::publishMenu() +{ + GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + if(!bus) puts ("Fail bus get"); + guint bid = g_bus_own_name_on_connection (bus, "org.libreoffice", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); + if(!bid) puts ("Fail own name"); + +// guint appmenuID = g_dbus_connection_export_menu_model (bus, "/org/libreoffice/menus/appmenu", mpMenuModel, NULL); +// if(!appmenuID) puts("Fail export appmenu"); + mMenubarId = g_dbus_connection_export_menu_model (bus, "/org/libreoffice/menus/menubar", mpMenuModel, NULL); + if(!mMenubarId) puts("Fail export menubar"); + +// g_object_unref (menu); +} + +GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : + mbMenuBar( bMenuBar ), + mpVCLMenu( NULL ), + mpParentMenuModel( NULL ), + mpSectionMenuModel( NULL ), + aDBusMenubarPath( NULL ), + pSessionBus( NULL ), + mMenubarId( 0 ) +{ +// mpMenuModel = G_MENU_MODEL( g_menu_new() ); + +// if (!bMenuBar) { +// mpSectionMenuModel = G_MENU_MODEL( g_menu_new() ); +// g_menu_append_section( G_MENU( mpMenuModel ), NULL, mpSectionMenuModel ); +// } } GtkSalMenu::~GtkSalMenu() { + if (mMenubarId) { + g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId ); + } + g_object_unref( mpMenuModel ); g_object_unref( mpParentMenuModel ); + g_object_unref( mpSectionMenuModel ); } sal_Bool GtkSalMenu::VisibleMenuBar() @@ -117,17 +134,43 @@ sal_Bool GtkSalMenu::VisibleMenuBar() void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) { - cout << __FUNCTION__ << endl; + cout << __FUNCTION__ << " pos: " << nPos << endl; +// GtkSalMenuItem *pGtkSalMenuItem = static_cast( pSalMenuItem ); + +// if ( pGtkSalMenuItem->mpMenuItem ) { +// GMenuModel *pTargetMenu = (mbMenuBar) ? mpMenuModel : mpSectionMenuModel; +// g_menu_insert_item( G_MENU( pTargetMenu ), nPos, G_MENU_ITEM( pGtkSalMenuItem->mpMenuItem ) ); +// } else { +// // If no mpMenuItem exists, then item is a separator. +// mpSectionMenuModel = G_MENU_MODEL( g_menu_new() ); +// g_menu_append_section( G_MENU( mpMenuModel ), NULL, mpSectionMenuModel ); +// } + +// pGtkSalMenuItem->mpParentMenu = this; } void GtkSalMenu::RemoveItem( unsigned nPos ) { cout << __FUNCTION__ << endl; +// GMenuModel *pTargetMenu = (mbMenuBar) ? mpMenuModel : mpSectionMenuModel; +// g_menu_remove( G_MENU( pTargetMenu ), nPos ); } void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) { - cout << __FUNCTION__ << endl; + cout << __FUNCTION__ << " Pos: " << nPos << endl; + +// GtkSalMenuItem *pGtkSalMenuItem = static_cast( pSalMenuItem ); +// GtkSalMenu *pGtkSubMenu = static_cast( pSubMenu ); + +// pGtkSalMenuItem->mpSubMenu = pGtkSubMenu; + +// GMenuItem *pMenuItem = G_MENU_ITEM( pGtkSalMenuItem->mpMenuItem ); +// g_menu_item_set_submenu( pMenuItem, pGtkSubMenu->mpMenuModel ); + +// GMenuModel *pParentMenu = (mbMenuBar) ? mpMenuModel : mpSectionMenuModel; +// g_menu_remove( G_MENU( pParentMenu ), nPos ); +// g_menu_insert_item( G_MENU( pParentMenu ), nPos, pMenuItem ); } void GtkSalMenu::SetFrame( const SalFrame* pFrame ) @@ -148,22 +191,19 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) // 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", "/org/libreoffice/menus/menubar"); - GMenu *menu = g_menu_new (); - // g_menu_append (menu, "Add", "app.add"); - // g_menu_append (menu, "Del", "app.del"); - g_menu_append (menu, "Quit", "app.quit"); +// GMenu *menu = g_menu_new (); +//// g_menu_append (menu, "Add", "app.add"); +//// g_menu_append (menu, "Del", "app.del"); +// GMenu *fileMenu = g_menu_new(); +// GMenu *submenu = g_menu_new (); +// g_menu_append( submenu, "Option1", NULL ); +// g_menu_append( submenu, "Option2", NULL ); - GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - if(!bus) puts ("Fail bus get"); - guint bid = g_bus_own_name_on_connection (bus, "org.libreoffice", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); - if(!bid) puts ("Fail own name"); +// g_menu_append_section( fileMenu, NULL, G_MENU_MODEL(submenu)); - guint appmenuID = g_dbus_connection_export_menu_model (bus, "/org/libreoffice/menus/appmenu", G_MENU_MODEL (menu), NULL); - if(!appmenuID) puts("Fail export appmenu"); - guint menubarID = g_dbus_connection_export_menu_model (bus, "/org/libreoffice/menus/menubar", G_MENU_MODEL (menu), NULL); - if(!menubarID) puts("Fail export menubar"); +// g_menu_append (fileMenu, "Quit", "app.quit"); - g_object_unref (menu); +// g_menu_append_submenu( menu, "Test", G_MENU_MODEL( fileMenu )); } } @@ -180,6 +220,20 @@ 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); + +// GtkSalMenuItem *pGtkSalMenuItem = static_cast( pSalMenuItem ); + +// GMenuItem *pMenuItem = G_MENU_ITEM( pGtkSalMenuItem->mpMenuItem ); + +// g_menu_item_set_label( pMenuItem, (char*) aConvertedText.getStr() ); + +// GMenuModel *pMenuModel = (mbMenuBar) ? mpMenuModel : mpSectionMenuModel; + +// g_menu_remove( G_MENU( pMenuModel ), nPos ); +// g_menu_insert_item( G_MENU( pMenuModel ), nPos, pMenuItem ); } void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage) @@ -197,6 +251,13 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) cout << __FUNCTION__ << endl; } +void GtkSalMenu::Freeze() +{ + cout << __FUNCTION__ << endl; + mpMenuModel = generateMenuModel( mpVCLMenu ); + this->publishMenu(); +} + // ======================================================================= /* @@ -210,7 +271,11 @@ GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) : mpSubMenu( NULL ), mpMenuItem( NULL ) { - mpMenuItem = g_menu_item_new("", NULL); + cout << __FUNCTION__ << "Type: " << pItemData->eType << endl; + + if ( pItemData->eType != MENUITEM_SEPARATOR ) { + mpMenuItem = g_menu_item_new( "b", NULL ); + } } GtkSalMenuItem::~GtkSalMenuItem() -- cgit