vcl/inc/unx/gtk/gtksalmenu.hxx | 25 ++ vcl/unx/gtk/app/gtkinst.cxx | 9 - vcl/unx/gtk/window/gtksalmenu.cxx | 340 ++++++++++++++++++++++++++------------ 3 files changed, 264 insertions(+), 110 deletions(-)
New commits: commit fd842d453953c44a30db6c46d7b63aca8994daeb Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Wed Aug 1 16:52:50 2012 +0100 Internal native menu is created in steps, but is incomplete at the moment. Change-Id: I323b80b74218be853fe2893b3f328ff3ef74d4cb diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index 69fcec8..65c2bc8 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -35,22 +35,29 @@ #include <unx/salmenu.h> #include <gio/gio.h> +#include <vector> + +class GtkSalMenuItem; +class GtkSalMenuSection; class GtkSalMenu : public SalMenu { private: + sal_Bool mbMenuBar; - virtual void publishMenu(); + virtual void publishMenu( GMenuModel* ); public: + std::vector< GtkSalMenuSection* > maSections; + std::vector< GtkSalMenuItem* > maItems; + GtkSalMenuSection* mpCurrentSection; + Menu* mpVCLMenu; const GtkSalFrame* mpFrame; - GMenuModel* mpParentMenuModel; - GMenuModel* mpMenuModel; - GMenuModel* mpSectionMenuModel; gchar* aDBusMenubarPath; GDBusConnection* pSessionBus; + sal_Int32 mBusId; sal_Int32 mMenubarId; GtkSalMenu( sal_Bool bMenuBar ); @@ -72,6 +79,16 @@ public: virtual void Freeze(); }; +class GtkSalMenuItem; + +class GtkSalMenuSection +{ +public: + std::vector< GtkSalMenuItem* > maItems; + + virtual ~GtkSalMenuSection(); +}; + class GtkSalMenuItem : public SalMenuItem { public: diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx index e8ec95a..dceca0d 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -530,23 +530,20 @@ SalMenu* GtkInstance::CreateMenu( sal_Bool bMenuBar, Menu* pVCLMenu ) void GtkInstance::DestroyMenu( SalMenu* pMenu ) { (void)pMenu; + delete pMenu; OSL_ENSURE( pMenu == 0, "DestroyMenu called with non-native menus" ); } SalMenuItem* GtkInstance::CreateMenuItem( const SalItemParams* pItemData ) { - GtkSalMenuItem *pMenuItem = NULL; - -// if (pItemData->eType != MENUITEM_SEPARATOR) { - pMenuItem = new GtkSalMenuItem( pItemData ); -// } - + GtkSalMenuItem *pMenuItem = new GtkSalMenuItem( pItemData ); return static_cast<SalMenuItem*>( pMenuItem ); } void GtkInstance::DestroyMenuItem( SalMenuItem* pItem ) { (void)pItem; +// delete pItem; OSL_ENSURE( pItem == 0, "DestroyMenu called with non-native menus" ); } diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 9c3acdd..f612a23 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -20,35 +20,7 @@ quit (GSimpleAction *action, exit(1); } -void -gdk_x11_window_set_utf8_property (GdkWindow *window, - const gchar *name, - const gchar *value) -{ - GdkDisplay *display; - - //if (!WINDOW_IS_TOPLEVEL (window)) - //return; - - display = gdk_window_get_display (window); - - if (value != NULL) - { - XChangeProperty (GDK_DISPLAY_XDISPLAY (display), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, name), - gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, - PropModeReplace, (guchar *)value, strlen (value)); - } - else - { - XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, name)); - } -} - -GMenuModel* generateMenuModel( Menu *pVCLMenu ) +GMenuModel* generateMenuModel2( Menu *pVCLMenu ) { if (!pVCLMenu) return NULL; @@ -65,13 +37,17 @@ GMenuModel* generateMenuModel( Menu *pVCLMenu ) } else { sal_Int16 nId = pVCLMenu->GetItemId( i ); + // Menu item label rtl::OUString aTextLabel = pVCLMenu->GetItemText( nId ); rtl::OUString aText = aTextLabel.replace( '~', '_' ); rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8); + // Menu item accelerator key +// KeyCode accelKey = pVCLMenu->GetAccelKey( nId ); + GMenuItem *menuItem = g_menu_item_new( (char*) aConvertedText.getStr(), NULL); - GMenuModel *pSubmenu = generateMenuModel( pVCLMenu->GetPopupMenu( nId ) ); + GMenuModel *pSubmenu = generateMenuModel2( pVCLMenu->GetPopupMenu( nId ) ); g_menu_item_set_submenu( menuItem, pSubmenu ); @@ -84,16 +60,117 @@ GMenuModel* generateMenuModel( Menu *pVCLMenu ) return G_MENU_MODEL( pMenuModel ); } -void GtkSalMenu::publishMenu() +GMenuModel *generateMockMenuModel() +{ + 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 ); + + g_menu_append_section( fileMenu, NULL, G_MENU_MODEL(submenu)); + + g_menu_append (fileMenu, "Quit", "app.quit"); + + g_menu_append_submenu( menu, "Test", G_MENU_MODEL( fileMenu )); + + return G_MENU_MODEL( menu ); +} + +GMenuModel *generateMenuModel( GtkSalMenu* ); + +GMenuModel *generateSectionMenuModel( GtkSalMenuSection *pSection ) +{ + if ( !pSection ) + return NULL; + + GMenu *pSectionMenuModel = g_menu_new(); + + for (int i=0; i < pSection->maItems.size(); i++) { + GtkSalMenuItem *pSalMenuItem = pSection->maItems[ i ]; + GMenuItem *pMenuItem = pSalMenuItem->mpMenuItem; + + if (pSalMenuItem->mpSubMenu) { + GMenuModel *pSubmenu = generateMenuModel( pSalMenuItem->mpSubMenu ); + g_menu_item_set_submenu( pMenuItem, pSubmenu ); + } + + g_menu_append_item( pSectionMenuModel, pMenuItem ); + } + + return G_MENU_MODEL( pSectionMenuModel ); +} + +GMenuModel *generateMenuModel( GtkSalMenu *pMenu ) +{ + if ( !pMenu ) + return NULL; + + GMenu *pMenuModel = g_menu_new(); + + for (int i=0; i < pMenu->maItems.size(); i++) { + GtkSalMenuItem *pSalMenuItem = pMenu->maItems[ i ]; + GMenuItem *pMenuItem = pSalMenuItem->mpMenuItem; + + if (pSalMenuItem->mpSubMenu) { + GMenuModel *pSubmenu = generateMenuModel( pSalMenuItem->mpSubMenu ); + g_menu_item_set_submenu( pMenuItem, pSubmenu ); + } + + g_menu_append_item( pMenuModel, pMenuItem ); + } + + for (int i=0; i < pMenu->maSections.size(); i++) { + GtkSalMenuSection *pSection = pMenu->maSections[ i ]; + + GMenuModel *pSectionMenuModel = generateSectionMenuModel( pSection ); + + g_menu_append_section( pMenuModel, NULL, pSectionMenuModel ); + } + + return G_MENU_MODEL( pMenuModel ); +} + +void +gdk_x11_window_set_utf8_property (GdkWindow *window, + const gchar *name, + const gchar *value) +{ + GdkDisplay *display; + + //if (!WINDOW_IS_TOPLEVEL (window)) + //return; + + display = gdk_window_get_display (window); + + if (value != NULL) + { + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, name), + gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, + PropModeReplace, (guchar *)value, strlen (value)); + } + else + { + XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, name)); + } +} + +void GtkSalMenu::publishMenu( GMenuModel *pMenu ) { - 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"); + pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + if(!pSessionBus) puts ("Fail bus get"); + mBusId = g_bus_own_name_on_connection (pSessionBus, "org.libreoffice", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); + if(!mBusId) 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); + mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, "/org/libreoffice/menus/menubar", pMenu, NULL); if(!mMenubarId) puts("Fail export menubar"); // g_object_unref (menu); @@ -102,29 +179,33 @@ void GtkSalMenu::publishMenu() GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : mbMenuBar( bMenuBar ), mpVCLMenu( NULL ), - mpParentMenuModel( NULL ), - mpSectionMenuModel( NULL ), aDBusMenubarPath( NULL ), pSessionBus( NULL ), + mBusId( 0 ), 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 ); -// } + if (!bMenuBar) { + mpCurrentSection = new GtkSalMenuSection(); + maSections.push_back( mpCurrentSection ); + } } GtkSalMenu::~GtkSalMenu() { - if (mMenubarId) { + if ( mMenubarId ) { g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId ); } - g_object_unref( mpMenuModel ); - g_object_unref( mpParentMenuModel ); - g_object_unref( mpSectionMenuModel ); + if ( mBusId ) { + g_bus_unown_name( mBusId ); + } + + if ( pSessionBus ) { + g_dbus_connection_close_sync( pSessionBus, NULL, NULL ); + } + + maItems.clear(); + maSections.clear(); } sal_Bool GtkSalMenu::VisibleMenuBar() @@ -135,42 +216,51 @@ sal_Bool GtkSalMenu::VisibleMenuBar() void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) { cout << __FUNCTION__ << " pos: " << nPos << endl; -// GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( 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 ); -// } + GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); + + if ( pGtkSalMenuItem->mpMenuItem ) { + if ( mbMenuBar ) { +// if ( maItems.size() == 0 ) { + maItems.push_back( pGtkSalMenuItem ); +// } else { +// maItems.insert( maItems.begin() + nPos, pGtkSalMenuItem ); +// } + } else { +// if ( mpCurrentSection->maItems.size() == 0) { + mpCurrentSection->maItems.push_back( pGtkSalMenuItem ); +// } else { +// mpCurrentSection->maItems.insert( mpCurrentSection->maItems.begin() + nPos, pGtkSalMenuItem ); +// } + } + } else { + // If no mpMenuItem exists, then item is a separator. + mpCurrentSection = new GtkSalMenuSection(); + maSections.push_back( mpCurrentSection ); + } -// pGtkSalMenuItem->mpParentMenu = this; + pGtkSalMenuItem->mpParentMenu = this; } void GtkSalMenu::RemoveItem( unsigned nPos ) { - cout << __FUNCTION__ << endl; -// GMenuModel *pTargetMenu = (mbMenuBar) ? mpMenuModel : mpSectionMenuModel; -// g_menu_remove( G_MENU( pTargetMenu ), nPos ); + cout << __FUNCTION__ << " Item: " << nPos << endl; + +// if (nPos < maItems.size()) { +// std::vector< GtkSalMenuItem* >::iterator iterator; +// iterator = maItems.begin() + nPos; + +// maItems.erase( iterator, iterator ); +// } } void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) { cout << __FUNCTION__ << " Pos: " << nPos << endl; -// GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); -// GtkSalMenu *pGtkSubMenu = static_cast<GtkSalMenu*>( pSubMenu ); + GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); + GtkSalMenu *pGtkSubMenu = static_cast<GtkSalMenu*>( 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 ); + pGtkSalMenuItem->mpSubMenu = pGtkSubMenu; } void GtkSalMenu::SetFrame( const SalFrame* pFrame ) @@ -190,20 +280,6 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_WINDOW_OBJECT_PATH", "/org/libreoffice/windows"); // 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"); -// GMenu *fileMenu = g_menu_new(); -// GMenu *submenu = g_menu_new (); -// g_menu_append( submenu, "Option1", NULL ); -// g_menu_append( submenu, "Option2", NULL ); - -// g_menu_append_section( fileMenu, NULL, G_MENU_MODEL(submenu)); - -// g_menu_append (fileMenu, "Quit", "app.quit"); - -// g_menu_append_submenu( menu, "Test", G_MENU_MODEL( fileMenu )); } } @@ -220,20 +296,17 @@ 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<GtkSalMenuItem*>( pSalMenuItem ); + // Replace the "~" character with "_". + rtl::OUString aText = rText.replace( '~', '_' ); + rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8); -// GMenuItem *pMenuItem = G_MENU_ITEM( pGtkSalMenuItem->mpMenuItem ); + cout << "Setting label: " << aConvertedText.getStr() << endl; -// g_menu_item_set_label( pMenuItem, (char*) aConvertedText.getStr() ); + GtkSalMenuItem *pGtkSalMenuItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); -// GMenuModel *pMenuModel = (mbMenuBar) ? mpMenuModel : mpSectionMenuModel; + GMenuItem *pMenuItem = G_MENU_ITEM( pGtkSalMenuItem->mpMenuItem ); -// g_menu_remove( G_MENU( pMenuModel ), nPos ); -// g_menu_insert_item( G_MENU( pMenuModel ), nPos, pMenuItem ); + g_menu_item_set_label( pMenuItem, (char*) aConvertedText.getStr() ); } void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage) @@ -243,7 +316,14 @@ void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const I void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ) { - cout << __FUNCTION__ << endl; + cout << __FUNCTION__ << " KeyName: " << rKeyName << endl; + +// GtkSalMenuItem *pMenuItem = static_cast< GtkSalMenuItem* >( pSalMenuItem ); + +// rtl::OString aConvertedKeyName = OUStringToOString( rKeyName, RTL_TEXTENCODING_UTF8 ); + +// GVariant *gaKeyCode = g_variant_new_string( aConvertedKeyName.getStr() ); +// g_menu_item_set_attribute_value( pMenuItem->mpMenuItem, "accel", gaKeyCode ); } void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) @@ -251,11 +331,69 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) cout << __FUNCTION__ << endl; } +void printMenu( GtkSalMenu * ); + +void printSection ( GtkSalMenuSection *pSection ) +{ + if (pSection) { + for (int i = 0; i < pSection->maItems.size(); i++) { + GtkSalMenuItem *pSalMenuItem = static_cast< GtkSalMenuItem* >(pSection->maItems[ i ]); + cout << pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ) << endl; + + if (pSalMenuItem->mpSubMenu) { + cout << "--- Submenu ---" << endl; + printMenu( pSalMenuItem->mpSubMenu); + cout << "---------------" << endl; + } + } + } +} + +void printMenu( GtkSalMenu *pMenu ) +{ + if ( pMenu ) { + for (int i = 0; i < pMenu->maItems.size(); i++) { + GtkSalMenuItem *pSalMenuItem = static_cast< GtkSalMenuItem* >(pMenu->maItems[ i ]); + cout << pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ) << endl; + + if (pSalMenuItem->mpSubMenu) { + cout << "--- Submenu ---" << endl; + printMenu( pSalMenuItem->mpSubMenu); + cout << "---------------" << endl; + } + } + + for (int i = 0; i < pMenu->maSections.size(); i++) { + GtkSalMenuSection *pSalMenuSection = static_cast< GtkSalMenuSection* >(pMenu->maSections[ i ]); + + cout << "--- Submenu ---" << endl; + printSection( pSalMenuSection ); + cout << "---------------" << endl; + } + } +} + void GtkSalMenu::Freeze() { cout << __FUNCTION__ << endl; - mpMenuModel = generateMenuModel( mpVCLMenu ); - this->publishMenu(); + GMenuModel *mpMenuModel = generateMenuModel( this ); + this->publishMenu( mpMenuModel ); + g_object_unref( mpMenuModel ); + + cout << "==================== MENUBAR ===================" << endl; + printMenu( this ); + cout << "================================================" << endl; +} + +// ======================================================================= + +/* + * GtlSalMenuSection + */ + +GtkSalMenuSection::~GtkSalMenuSection() +{ + maItems.clear(); } // ======================================================================= @@ -280,5 +418,7 @@ GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) : GtkSalMenuItem::~GtkSalMenuItem() { - g_object_unref( mpMenuItem ); + if ( mpMenuItem ) { + g_object_unref( mpMenuItem ); + } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits