summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/unx/gtk/gtksalmenu.hxx25
-rw-r--r--vcl/unx/gtk/app/gtkinst.cxx9
-rw-r--r--vcl/unx/gtk/window/gtksalmenu.cxx340
3 files changed, 264 insertions, 110 deletions
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 69fcec834cb9..65c2bc8051e8 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 f8d49d1b962d..8db4066f2aeb 100644
--- a/vcl/unx/gtk/app/gtkinst.cxx
+++ b/vcl/unx/gtk/app/gtkinst.cxx
@@ -521,23 +521,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 9c3acddc938c..f612a23a7013 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 );
+ }
}