vcl/inc/salmenu.hxx | 2 vcl/inc/unx/gtk/gtkframe.hxx | 161 +++---- vcl/inc/unx/gtk/gtksalmenu.hxx | 12 vcl/unx/gtk/window/gloactiongroup.cxx | 2 vcl/unx/gtk/window/gtkframe.cxx | 9 vcl/unx/gtk/window/gtksalmenu.cxx | 763 +++++++++++++++++----------------- 6 files changed, 481 insertions(+), 468 deletions(-)
New commits: commit a1036bd48b3d03798b300e879ec822ef7554fffa Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Fri Sep 21 13:09:14 2012 +0100 Total rework of how native menu is filled, but not finished yet. Change-Id: Ib59002d08f9debe2155bcf35c7069ac55f0e2106 diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx index 2f8d680..e09b7ce 100644 --- a/vcl/inc/salmenu.hxx +++ b/vcl/inc/salmenu.hxx @@ -91,7 +91,7 @@ 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 ) {} + virtual void SetItemCommand( unsigned, SalMenuItem*, const rtl::OUString& ) {} virtual void Freeze() {} // return an empty rectangle if not implemented diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index cd080d0..5c69476 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -246,20 +246,20 @@ class GtkSalFrame : public SalFrame static gboolean signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer ); static void signalDestroy( GtkWidget*, gpointer ); - void Center(); - void SetDefaultSize(); - void setAutoLock( bool bLock ); - void setScreenSaverTimeout( int nTimeout ); - - void doKeyCallback( guint state, - guint keyval, - guint16 hardware_keycode, - guint8 group, - guint32 time, - sal_Unicode aOrigCode, - bool bDown, - bool bSendRelease - ); + void Center(); + void SetDefaultSize(); + void setAutoLock( bool bLock ); + void setScreenSaverTimeout( int nTimeout ); + + void doKeyCallback( guint state, + guint keyval, + guint16 hardware_keycode, + guint8 group, + guint32 time, + sal_Unicode aOrigCode, + bool bDown, + bool bSendRelease + ); GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow ); @@ -310,120 +310,127 @@ public: // dispatches an event, returns true if dispatched // and false else; if true was returned the event should // be swallowed - bool Dispatch( const XEvent* pEvent ); - void grabPointer( sal_Bool bGrab, sal_Bool bOwnerEvents = sal_False ); - - GtkSalDisplay* getDisplay(); - GdkDisplay* getGdkDisplay(); - GtkWidget* getWindow() const { return m_pWindow; } - GtkFixed* getFixedContainer() const { return m_pFixedContainer; } - GdkWindow* getForeignParent() const { return m_pForeignParent; } - GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; } - GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; } - GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; } - GdkVisibilityState getVisibilityState() const - { return m_nVisibility; } - Pixmap getBackgroundPixmap() const { return m_hBackgroundPixmap; } - SalX11Screen getXScreenNumber() const { return m_nXScreen; } - int GetDisplayScreen() const { return maGeometry.nDisplayScreenNumber; } + bool Dispatch( const XEvent* pEvent ); + void grabPointer( sal_Bool bGrab, sal_Bool bOwnerEvents = sal_False ); + + GtkSalDisplay* getDisplay(); + GdkDisplay* getGdkDisplay(); + GtkWidget* getWindow() const { return m_pWindow; } + GtkFixed* getFixedContainer() const { return m_pFixedContainer; } + GdkWindow* getForeignParent() const { return m_pForeignParent; } + GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; } + GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; } + GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; } + GdkVisibilityState getVisibilityState() const { return m_nVisibility; } + Pixmap getBackgroundPixmap() const { return m_hBackgroundPixmap; } + SalX11Screen getXScreenNumber() const { return m_nXScreen; } + int GetDisplayScreen() const { return maGeometry.nDisplayScreenNumber; } void updateScreenNumber(); #if GTK_CHECK_VERSION(3,0,0) // only for gtk3 ... - void pushIgnoreDamage(); - void popIgnoreDamage(); - void renderArea( cairo_t *cr, cairo_rectangle_t *src ); + void pushIgnoreDamage(); + void popIgnoreDamage(); + void renderArea( cairo_t *cr, cairo_rectangle_t *src ); #endif virtual ~GtkSalFrame(); // SalGraphics or NULL, but two Graphics for all SalFrames // must be returned - virtual SalGraphics* GetGraphics(); - virtual void ReleaseGraphics( SalGraphics* pGraphics ); + virtual SalGraphics* GetGraphics(); + virtual void ReleaseGraphics( SalGraphics* pGraphics ); // Event must be destroyed, when Frame is destroyed // When Event is called, SalInstance::Yield() must be returned virtual sal_Bool PostEvent( void* pData ); - virtual void SetTitle( const rtl::OUString& rTitle ); - virtual void SetIcon( sal_uInt16 nIcon ); - virtual void SetMenu( SalMenu *pSalMenu ); - virtual SalMenu* GetMenu( void ); - virtual void DrawMenuBar(); - void SetWatcherId( sal_uInt32 watcherId ); - - virtual void SetExtendedFrameStyle( SalExtStyle nExtStyle ); + virtual void SetTitle( const rtl::OUString& rTitle ); + virtual void SetIcon( sal_uInt16 nIcon ); + virtual void SetMenu( SalMenu *pSalMenu ); + virtual SalMenu* GetMenu( void ); + virtual void DrawMenuBar(); + void SetWatcherId( sal_uInt32 watcherId ); + + unsigned m_nMenuModelExportId; + unsigned m_nActionGroupExportId; + GDBusConnection* m_pDBusConnection; + void SetMenuModelExportId( unsigned nExportId ) { m_nMenuModelExportId = nExportId; } + sal_uInt32 GetMenuModelExportId( void ) const { return m_nMenuModelExportId; } + void SetActionGroupExportId( unsigned nExportId ) { m_nActionGroupExportId = nExportId; } + sal_uInt32 GetActionGroupExportId( void ) const { return m_nActionGroupExportId; } + + virtual void SetExtendedFrameStyle( SalExtStyle nExtStyle ); // Before the window is visible, a resize event // must be sent with the correct size - virtual void Show( sal_Bool bVisible, sal_Bool bNoActivate = sal_False ); - virtual void Enable( sal_Bool bEnable ); + virtual void Show( sal_Bool bVisible, sal_Bool bNoActivate = sal_False ); + virtual void Enable( sal_Bool bEnable ); // Set ClientSize and Center the Window to the desktop // and send/post a resize message - virtual void SetMinClientSize( long nWidth, long nHeight ); - virtual void SetMaxClientSize( long nWidth, long nHeight ); - virtual void SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ); - virtual void GetClientSize( long& rWidth, long& rHeight ); - virtual void GetWorkArea( Rectangle& rRect ); - virtual SalFrame* GetParent() const; - virtual void SetWindowState( const SalFrameState* pState ); - virtual sal_Bool GetWindowState( SalFrameState* pState ); - virtual void ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay ); + virtual void SetMinClientSize( long nWidth, long nHeight ); + virtual void SetMaxClientSize( long nWidth, long nHeight ); + virtual void SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ); + virtual void GetClientSize( long& rWidth, long& rHeight ); + virtual void GetWorkArea( Rectangle& rRect ); + virtual SalFrame* GetParent() const; + virtual void SetWindowState( const SalFrameState* pState ); + virtual sal_Bool GetWindowState( SalFrameState* pState ); + virtual void ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay ); // Enable/Disable ScreenSaver, SystemAgents, ... - virtual void StartPresentation( sal_Bool bStart ); + virtual void StartPresentation( sal_Bool bStart ); // Show Window over all other Windows - virtual void SetAlwaysOnTop( sal_Bool bOnTop ); + virtual void SetAlwaysOnTop( sal_Bool bOnTop ); // Window to top and grab focus - virtual void ToTop( sal_uInt16 nFlags ); + virtual void ToTop( sal_uInt16 nFlags ); // this function can call with the same // pointer style - virtual void SetPointer( PointerStyle ePointerStyle ); - virtual void CaptureMouse( sal_Bool bMouse ); - virtual void SetPointerPos( long nX, long nY ); + virtual void SetPointer( PointerStyle ePointerStyle ); + virtual void CaptureMouse( sal_Bool bMouse ); + virtual void SetPointerPos( long nX, long nY ); // flush output buffer using SalFrame::Flush; - virtual void Flush(); + virtual void Flush(); // flush output buffer, wait till outstanding operations are done - virtual void Sync(); + virtual void Sync(); - virtual void SetInputContext( SalInputContext* pContext ); - virtual void EndExtTextInput( sal_uInt16 nFlags ); + virtual void SetInputContext( SalInputContext* pContext ); + virtual void EndExtTextInput( sal_uInt16 nFlags ); - virtual rtl::OUString GetKeyName( sal_uInt16 nKeyCode ); - virtual sal_Bool MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode ); + virtual rtl::OUString GetKeyName( sal_uInt16 nKeyCode ); + virtual sal_Bool MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode ); // returns the input language used for the last key stroke // may be LANGUAGE_DONTKNOW if not supported by the OS - virtual LanguageType GetInputLanguage(); + virtual LanguageType GetInputLanguage(); - virtual void UpdateSettings( AllSettings& rSettings ); + virtual void UpdateSettings( AllSettings& rSettings ); - virtual void Beep( SoundType eSoundType ); + virtual void Beep( SoundType eSoundType ); // returns system data (most prominent: window handle) virtual const SystemEnvData* GetSystemData() const; // get current modifier and button mask - virtual SalPointerState GetPointerState(); + virtual SalPointerState GetPointerState(); - virtual SalIndicatorState GetIndicatorState(); + virtual SalIndicatorState GetIndicatorState(); - virtual void SimulateKeyPress( sal_uInt16 nKeyCode ); + virtual void SimulateKeyPress( sal_uInt16 nKeyCode ); // set new parent window - virtual void SetParent( SalFrame* pNewParent ); + virtual void SetParent( SalFrame* pNewParent ); // reparent window to act as a plugin; implementation // may choose to use a new system window internally // return false to indicate failure - virtual bool SetPluginParent( SystemParentData* pNewParent ); + virtual bool SetPluginParent( SystemParentData* pNewParent ); - virtual void SetBackgroundBitmap( SalBitmap* ); + virtual void SetBackgroundBitmap( SalBitmap* ); - virtual void SetScreenNumber( unsigned int ); - virtual void SetApplicationID( const rtl::OUString &rWMClass ); + virtual void SetScreenNumber( unsigned int ); + virtual void SetApplicationID( const rtl::OUString &rWMClass ); // shaped system windows // set clip region to none (-> rectangular windows, normal state) diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index 56aed28..af02817 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -88,18 +88,6 @@ public: virtual void SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; } virtual GActionGroup* GetActionGroup() { return mpActionGroup; } - void NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText ); - void NativeSetItemCommand( unsigned nSection, - unsigned nItemPos, - sal_uInt16 nId, - const gchar* aCommand, - MenuItemBits nBits, - gboolean bChecked, - gboolean bIsSubmenu ); - void NativeSetEnableItem( gchar* aCommand, gboolean bEnable ); - void NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck ); - 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 ); diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx index d083703..37a2278 100644 --- a/vcl/unx/gtk/window/gloactiongroup.cxx +++ b/vcl/unx/gtk/window/gloactiongroup.cxx @@ -241,7 +241,7 @@ g_lo_action_group_change_state (GActionGroup *group, static void g_lo_action_group_activate (GActionGroup *group, const gchar *action_name, - GVariant *parameter) + GVariant */*parameter */) { GTK_YIELD_GRAB(); diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index d43371c..6c39412 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -535,6 +535,12 @@ GtkSalFrame::~GtkSalFrame() if ( m_nWatcherId > 0 ) g_bus_unwatch_name( m_nWatcherId ); + + if ( m_pDBusConnection && m_nMenuModelExportId > 0 ) + g_dbus_connection_unexport_menu_model( m_pDBusConnection, m_nMenuModelExportId ); + + if ( m_pDBusConnection && m_nActionGroupExportId > 0 ) + g_dbus_connection_unexport_action_group( m_pDBusConnection, m_nActionGroupExportId ); } void GtkSalFrame::moveWindow( long nX, long nY ) @@ -644,6 +650,9 @@ void GtkSalFrame::InitCommon() m_bSetFocusOnMap = false; m_pSalMenu = NULL; m_nWatcherId = 0; + m_nMenuModelExportId = 0; + m_nActionGroupExportId = 0; + m_pDBusConnection = NULL; gtk_widget_set_app_paintable( m_pWindow, TRUE ); gtk_widget_set_double_buffered( m_pWindow, FALSE ); diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 60942a5..2273b2a 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -34,6 +34,7 @@ using namespace std; +static sal_Bool bDBusIsAvailable = sal_False; static gchar* GetCommandForSpecialItem( GtkSalMenuItem* pSalMenuItem ) { @@ -50,117 +51,364 @@ static gchar* GetCommandForSpecialItem( GtkSalMenuItem* pSalMenuItem ) return aCommand; } -static void UpdateNativeMenu2( GtkSalMenu *pMenu ) +void ObjectDestroyedNotify( gpointer data ) { - if ( pMenu == NULL ) - return; + if ( data ) { + g_object_unref( data ); + } +} - Menu* pVCLMenu = pMenu->GetMenu(); - GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() ); - GActionGroup* pActionGroup = pMenu->GetActionGroup(); +void +gdk_x11_window_set_utf8_property (GdkWindow *window, + const gchar *name, + const gchar *value) +{ + GdkDisplay *display; - sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ); + //if (!WINDOW_IS_TOPLEVEL (window)) + //return; - if ( nLOMenuSize == 0 ) - g_lo_menu_new_section( pLOMenu, 0, NULL ); + display = gdk_window_get_display (window); - sal_uInt16 nSection = 0; - sal_uInt16 nItemPos = 0; - sal_uInt16 validItems = 0; - sal_uInt16 nItem; + 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)); + } +} - for ( nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) { - GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem ); - sal_uInt16 nId = pSalMenuItem->mnId; +// FIXME: Check for missing keys. Maybe translating keycodes would be safer... +rtl::OUString GetGtkKeyName( rtl::OUString keyName ) +{ + rtl::OUString aGtkKeyName(""); - if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) - { - nSection++; - nItemPos = 0; + sal_Int32 nIndex = 0; - if ( nLOMenuSize <= nSection ) - { - g_lo_menu_new_section( pLOMenu, nSection, NULL ); - nLOMenuSize++; - } + do + { + rtl::OUString token = keyName.getToken( 0, '+', nIndex ); - continue; + if ( token == "Ctrl" ) { + aGtkKeyName += "<Control>"; + } else if ( token == "Alt" ) { + aGtkKeyName += "<Alt>"; + } else if ( token == "Shift" ) { + aGtkKeyName += "<Shift>"; + } else { + aGtkKeyName += token; } + } while ( nIndex >= 0 ); - if ( nItemPos >= g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) - g_lo_menu_insert_in_section( pLOMenu, nSection, nItemPos, "EMPTY STRING" ); + return aGtkKeyName; +} - // 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 ); +// AppMenu watch functions. - // 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() ); +static gboolean PublishMenu( gpointer user_data ) +{ + GdkWindow* gdkWindow = GDK_WINDOW( user_data ); - // Force updating of native menu labels. - pMenu->NativeSetItemText( nSection, nItemPos, aText ); - pMenu->NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) ); + GMenuModel* pMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) ); + GActionGroup* pActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) ); - // Some items are special, so they have different commands. - if ( g_strcmp0( aNativeCommand, "" ) == 0 ) + 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. + GDBusConnection* pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + if( pSessionBus == NULL ) { + cout << "Failed to get session bus" << endl; + return FALSE; + } + + // Publish the menu. + if ( aDBusMenubarPath != NULL && pMenuModel != NULL ) + g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL); + + if ( aDBusPath != NULL && pActionGroup != NULL ) + g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pActionGroup, NULL); + + // Set window properties. + 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 ); + gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); + + g_free( aDBusPath ); + g_free( aDBusWindowPath ); + g_free( aDBusMenubarPath ); + + return FALSE; +} + +static void UpdateNativeMenu( GtkSalMenu* pMenu ); +gboolean GenerateMenu( gpointer user_data ); + +static void on_registrar_available( GDBusConnection* /*connection*/, + const gchar* /*name*/, + const gchar* /*name_owner*/, + gpointer user_data ) +{ + GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); + GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); + + if ( pSalMenu != NULL ) + { + MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() ); + + GtkWidget *pWidget = pSalFrame->getWindow(); + GdkWindow *gdkWindow = gtk_widget_get_window( pWidget ); + + if ( gdkWindow != NULL ) { - gchar *aSpecialItemCmd = GetCommandForSpecialItem( pSalMenuItem ); + GMenuModel* pMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) ); - if ( aSpecialItemCmd != NULL ) + if ( pMenuModel == NULL ) { - g_free( aNativeCommand ); - aNativeCommand = aSpecialItemCmd; + pMenuModel = G_MENU_MODEL( g_lo_menu_new() ); + g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", pMenuModel, ObjectDestroyedNotify ); + pSalMenu->SetMenuModel( pMenuModel ); } + + GActionGroup* pActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) ); + + if ( pActionGroup == NULL ) + { + pActionGroup = G_ACTION_GROUP( g_lo_action_group_new( pSalFrame ) ); + g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", pActionGroup, ObjectDestroyedNotify ); + pSalMenu->SetActionGroup( pActionGroup ); + } + +// PublishMenu( gdkWindow ); +// g_idle_add_full( G_PRIORITY_HIGH_IDLE, PublishMenu, (gpointer) gdkWindow, NULL ); +// g_timeout_add_full( G_PRIORITY_HIGH, 0, PublishMenu, (gpointer) gdkWindow, NULL ); + gdk_threads_add_timeout_full( G_PRIORITY_HIGH, 0, PublishMenu, (gpointer) gdkWindow, NULL ); + + bDBusIsAvailable = sal_True; + + if ( pMenuBar ) + pMenuBar->SetDisplayable( sal_False ); + +// GenerateMenu( pSalMenu ); +// g_idle_add_full( G_PRIORITY_HIGH_IDLE, GenerateMenu, pSalMenu, NULL ); +// g_timeout_add_full( G_PRIORITY_HIGH, 0, GenerateMenu, pSalMenu, NULL ); + gdk_threads_add_timeout_full( G_PRIORITY_HIGH, 0, GenerateMenu, pSalMenu, NULL ); +// UpdateNativeMenu( pSalMenu ); +// UpdateNativeSubMenu( pSalMenu ); } + } +} - if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == NULL ) +// This is called when the registrar becomes unavailable. It shows the menubar. +static void on_registrar_unavailable( GDBusConnection * /*connection*/, + const gchar * /*name*/, + gpointer user_data ) +{ + GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); + GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); + + if ( pSalMenu ) { + MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() ); + + bDBusIsAvailable = sal_False; + pMenuBar->SetDisplayable( sal_True ); + } +} + +/* + * Native menu methods + */ + +//static void InitNativeMenu( GtkSalFrame* pFrame ) +static gboolean InitNativeMenu( gpointer user_data ) +{ + GtkSalFrame* pFrame = (GtkSalFrame*) user_data; + + // Publish the menu only if AppMenu registrar is available. + guint 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, + (gpointer) pFrame, + NULL); + + pFrame->SetWatcherId( nWatcherId ); + return FALSE; +} + +static void NativeCheckItem( GLOMenu* pMenu, + GLOActionGroup* pActionGroup, + unsigned nSection, + unsigned nItemPos, + MenuItemBits bits, + gboolean bCheck ) +{ + if ( pActionGroup == NULL ) + return; + + gchar* aCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos ); + + if ( aCommand != NULL || g_strcmp0( aCommand, "" ) != 0 ) + { + GVariant *pCheckValue = NULL; + GVariant *pCurrentState = g_action_group_get_action_state( G_ACTION_GROUP( pActionGroup ), aCommand ); + + if ( bits & MIB_RADIOCHECK ) + { + pCheckValue = ( bCheck == TRUE ) ? g_variant_new_string( aCommand ) : g_variant_new_string( "" ); + } + else { - pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE ); - pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked ); - pMenu->NativeSetEnableItem( aNativeCommand, bEnabled ); + // By default, all checked items are checkmark buttons. + if ( bCheck == TRUE || ( ( bCheck == FALSE ) && pCurrentState != NULL ) ) + pCheckValue = g_variant_new_boolean( bCheck ); } - GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; + if ( pCheckValue != NULL && ( pCurrentState == NULL || g_variant_equal( pCurrentState, pCheckValue ) == FALSE ) ) + g_action_group_change_action_state( G_ACTION_GROUP( pActionGroup ), aCommand, pCheckValue ); - if ( pSubmenu && pSubmenu->GetMenu() ) - { - pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); + if ( pCurrentState ) + g_variant_unref( pCurrentState ); + } - GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); + if ( aCommand ) + g_free( aCommand ); +} - if ( pSubMenuModel == NULL ) - { - pSubMenuModel = g_lo_menu_new(); - g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) ); - } +static void NativeSetEnableItem( GLOActionGroup* pActionGroup, + gchar* aCommand, + gboolean bEnable ) +{ + if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bEnable ) + g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bEnable ); +} - g_object_unref( pSubMenuModel ); +static void NativeSetItemText( GLOMenu* pMenu, + unsigned nSection, + unsigned nItemPos, + const rtl::OUString& rText ) +{ + // Replace the '~' character with '_'. + rtl::OUString aText = rText.replace( '~', '_' ); + rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ); - pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) ); - pSubmenu->SetActionGroup( pActionGroup ); + // Update item text only when necessary. + gchar* aLabel = g_lo_menu_get_label_from_item_in_section( pMenu, nSection, nItemPos ); + + if ( aLabel == NULL || g_strcmp0( aLabel, aConvertedText.getStr() ) != 0 ) + g_lo_menu_set_label_to_item_in_section( pMenu, nSection, nItemPos, aConvertedText.getStr() ); + + if ( aLabel ) + g_free( aLabel ); +} + +static void NativeSetAccelerator( GLOMenu* pMenu, + unsigned nSection, + unsigned nItemPos, + const KeyCode& /* rKeyCode */, + const rtl::OUString& rKeyName ) +{ + if ( rKeyName.isEmpty() ) + return; + + rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 ); + + 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 ( pMenu, nSection, nItemPos, aAccelerator.getStr() ); + + if ( aCurrentAccel ) + g_free( aCurrentAccel ); +} + +static void NativeSetItemCommand( GLOMenu* pMenu, + GLOActionGroup* pActionGroup, + unsigned nSection, + unsigned nItemPos, + sal_uInt16 nId, + const gchar* aCommand, + MenuItemBits nBits, + gboolean bChecked, + gboolean bIsSubmenu ) +{ + GVariant *pTarget = NULL; + + if ( g_action_group_has_action( G_ACTION_GROUP( pActionGroup ), aCommand ) == FALSE ) { + if ( ( nBits & MIB_CHECKABLE ) || ( bIsSubmenu == TRUE ) ) + { + // Item is a checkmark button. + 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, bIsSubmenu, NULL, pStateType, NULL, pState ); } + else if ( nBits & MIB_RADIOCHECK ) + { + // Item is a radio button. + GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING ); + GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING ); + GVariant* pState = g_variant_new_string( "" ); + pTarget = g_variant_new_string( aCommand ); - g_free( aNativeCommand ); + 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, FALSE ); + } + } - nItemPos++; - validItems++; + // Menu item is not updated unless it's necessary. + gchar* aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos ); + + if ( aCurrentCommand == NULL || g_strcmp0( aCurrentCommand, aCommand ) != 0 ) + { + g_lo_menu_set_command_to_item_in_section( pMenu, nSection, nItemPos, aCommand ); + + gchar* aItemCommand = g_strconcat("win.", aCommand, NULL ); + + if ( bIsSubmenu == TRUE ) + g_lo_menu_set_submenu_action_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand ); + else + g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget ); + + g_free( aItemCommand ); } + + if ( aCurrentCommand ) + g_free( aCurrentCommand ); } -static void UpdateNativeMenu( GtkSalMenu* pMenu ) +/* + * Menu updating methods + */ + +static void UpdateNativeSubMenu( GtkSalMenu *pMenu ) { if ( pMenu == NULL ) return; +// SolarMutexGuard aGuard; + Menu* pVCLMenu = pMenu->GetMenu(); GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() ); - GActionGroup* pActionGroup = pMenu->GetActionGroup(); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( pMenu->GetActionGroup() ); sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ); @@ -207,8 +455,8 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) 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() ) ); + NativeSetItemText( pLOMenu, nSection, nItemPos, aText ); + NativeSetAccelerator( pLOMenu, nSection, nItemPos, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) ); // Some items are special, so they have different commands. if ( g_strcmp0( aNativeCommand, "" ) == 0 ) @@ -224,16 +472,16 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) 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 ); + NativeSetItemCommand( pLOMenu, pActionGroup, nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE ); + NativeCheckItem( pLOMenu, pActionGroup, nSection, nItemPos, itemBits, bChecked ); + NativeSetEnableItem( pActionGroup, aNativeCommand, bEnabled ); } GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; if ( pSubmenu && pSubmenu->GetMenu() ) { - pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); + NativeSetItemCommand( pLOMenu, pActionGroup, nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE ); GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); @@ -245,12 +493,8 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) g_object_unref( pSubMenuModel ); - pSubmenu->GetMenu()->Activate(); - pSubmenu->GetMenu()->Deactivate(); - pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) ); - pSubmenu->SetActionGroup( pActionGroup ); - UpdateNativeMenu( pSubmenu ); + pSubmenu->SetActionGroup( G_ACTION_GROUP( pActionGroup ) ); } g_free( aNativeCommand ); @@ -260,156 +504,75 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu ) } } -gboolean GenerateMenu(gpointer user_data) -{ - GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data ); - - UpdateNativeMenu( pSalMenu ); - - return TRUE; -} - -void ObjectDestroyedNotify( gpointer data ) -{ - if ( data ) { - g_object_unref( data ); - } -} - -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)); - } -} - -// FIXME: Check for missing keys. Maybe translating keycodes would be safer... -rtl::OUString GetGtkKeyName( rtl::OUString keyName ) +static void UpdateNativeMenu( GtkSalMenu* pMenu ) { - rtl::OUString aGtkKeyName(""); - - sal_Int32 nIndex = 0; - - do - { - rtl::OUString token = keyName.getToken( 0, '+', nIndex ); +// if ( pMenu == NULL ) +// return; - if ( token == "Ctrl" ) { - aGtkKeyName += "<Control>"; - } else if ( token == "Alt" ) { - aGtkKeyName += "<Alt>"; - } else if ( token == "Shift" ) { - aGtkKeyName += "<Shift>"; - } else { - aGtkKeyName += token; - } - } while ( nIndex >= 0 ); +// UpdateNativeSubMenu( pMenu ); - return aGtkKeyName; -} +// for ( sal_uInt16 nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) { +// GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem ); -// AppMenu watch functions. +// if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR ) +// continue; -static sal_Bool bDBusIsAvailable = sal_False; +// GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; -static void -on_registrar_available (GDBusConnection * /*connection*/, - const gchar * /*name*/, - const gchar * /*name_owner*/, - gpointer user_data) -{ - GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); - GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); +// if ( pSubmenu != NULL && pSubmenu->GetMenu() != NULL ) +// { +//// pSubmenu->GetMenu()->Activate(); +// Link aActivateHdl = pSubmenu->GetMenu()->GetActivateHdl(); +// aActivateHdl.Call( pSubmenu->GetMenu() ); - if ( pSalMenu != NULL ) - { - MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() ); +//// cout << "Activate" << endl; - GtkWidget *pWidget = pSalFrame->getWindow(); - GdkWindow *gdkWindow = gtk_widget_get_window( pWidget ); +// Link aDeactivateHdl = pSubmenu->GetMenu()->GetDeactivateHdl(); +// aDeactivateHdl.Call( pSubmenu->GetMenu() ); - if ( gdkWindow != NULL ) - { - GMenuModel* pMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) ); - GActionGroup* pActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) ); +//// cout << "Deactivate" << endl; - XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow ); +//// pSubmenu->GetMenu()->Deactivate(); +// UpdateNativeSubMenu( pSubmenu ); - 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 ); +//// cout << "Updated" << endl; - // Get a DBus session connection. - GDBusConnection* pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); +// } +// } - if( pSessionBus == NULL ) - return; + SolarMutexGuard aGuard; - // Publish the menu. - if ( aDBusMenubarPath != NULL && pMenuModel != NULL ) - g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL); + GLOMenu *pLOMenu = G_LO_MENU( pMenu->GetMenuModel() ); + GLOActionGroup * pLOActionGroup = G_LO_ACTION_GROUP( pMenu->GetActionGroup() ); - if ( aDBusPath != NULL && pActionGroup != NULL ) - g_dbus_connection_export_action_group( pSessionBus, aDBusPath, pActionGroup, NULL); + g_lo_menu_new_section( pLOMenu, 0, NULL ); - // Set window properties. - 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 ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); + for ( int i=0; i < 9; i++ ) { + gchar* menuStr = g_strdup_printf("Menu%d", i); - g_free( aDBusPath ); - g_free( aDBusWindowPath ); - g_free( aDBusMenubarPath ); + g_lo_menu_insert_in_section( pLOMenu, 0, i, menuStr); - bDBusIsAvailable = sal_True; + g_free(menuStr); - if ( pMenuBar ) - pMenuBar->SetDisplayable( sal_False ); - } + GLOMenu *pLOMenu1 = g_lo_menu_new(); + g_lo_menu_set_submenu_to_item_in_section( pLOMenu, 0, i, G_MENU_MODEL( pLOMenu1 ) ); + g_lo_menu_new_section( pLOMenu1, 0, NULL ); + g_lo_menu_insert_in_section( pLOMenu1, 0, 0, "Option1" ); + g_lo_menu_insert_in_section( pLOMenu1, 0, 1, "Option2" ); + g_lo_menu_insert_in_section( pLOMenu1, 0, 2, "Option3" ); + g_lo_menu_insert_in_section( pLOMenu1, 0, 3, "Option4" ); } - return; } -//This is called when the registrar becomes unavailable. It shows the menubar. -static void -on_registrar_unavailable (GDBusConnection * /*connection*/, - const gchar * /*name*/, - gpointer user_data) +gboolean GenerateMenu( gpointer user_data ) { - GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); - GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); - - if ( pSalMenu ) { - MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() ); + GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data ); - bDBusIsAvailable = sal_False; - pMenuBar->SetDisplayable( sal_True ); - } +// SolarMutexGuard aGuard; + UpdateNativeMenu( pSalMenu ); - return; + return FALSE; } /* @@ -431,8 +594,6 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : GtkSalMenu::~GtkSalMenu() { if ( mbMenuBar == sal_True ) { -// g_source_remove_by_user_data( this ); - ((GtkSalFrame*) mpFrame)->SetMenu( NULL ); if ( mpActionGroup ) { @@ -469,7 +630,7 @@ void GtkSalMenu::RemoveItem( unsigned nPos ) maItems.erase( maItems.begin() + nPos ); } -void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) +void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned ) { GtkSalMenuItem *pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem ); GtkSalMenu *pGtkSubMenu = static_cast< GtkSalMenu* >( pSubMenu ); @@ -495,32 +656,15 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) mpMenuModel = G_MENU_MODEL( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) ); mpActionGroup = G_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) ); - if ( mpMenuModel == NULL && mpActionGroup == NULL ) { - mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); - mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new( ( gpointer ) mpFrame ) ); - - g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", mpMenuModel, ObjectDestroyedNotify ); - g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", mpActionGroup, ObjectDestroyedNotify ); - - // Publish the menu only if AppMenu registrar is available. - guint 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, - (gpointer) mpFrame, - NULL); - - ( ( GtkSalFrame* ) mpFrame )->SetWatcherId( nWatcherId ); - } - - // 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 ); + if ( mpMenuModel == NULL && mpActionGroup == NULL ) +// InitNativeMenu( ( GtkSalFrame* ) pFrame ); +// g_idle_add_full( G_PRIORITY_HIGH_IDLE, InitNativeMenu, (gpointer) pFrame, NULL ); +// g_timeout_add_full( G_PRIORITY_HIGH, 0, InitNativeMenu, (gpointer) pFrame, NULL ); + gdk_threads_add_timeout_full( G_PRIORITY_HIGH, 0, InitNativeMenu, (gpointer) pFrame, NULL ); + else + // Generate the main menu structure. + GenerateMenu( this ); +// UpdateNativeMenu( this ); } } @@ -532,141 +676,6 @@ const GtkSalFrame* GtkSalMenu::GetFrame() const return pMenu ? pMenu->mpFrame : NULL; } -void GtkSalMenu::NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck ) -{ - if ( mpActionGroup == NULL ) - return; - - gchar* aCommand = g_lo_menu_get_command_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos ); - - if ( aCommand != NULL || g_strcmp0( aCommand, "" ) != 0 ) - { - GVariant *pCheckValue = NULL; - 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. - if ( bCheck == TRUE || ( ( bCheck == FALSE ) && pCurrentState != NULL ) ) - pCheckValue = g_variant_new_boolean( bCheck ); - } - - if ( pCheckValue != NULL && ( pCurrentState == NULL || g_variant_equal( pCurrentState, pCheckValue ) == FALSE ) ) - g_action_group_change_action_state( mpActionGroup, aCommand, pCheckValue ); - - if ( pCurrentState ) - g_variant_unref( pCurrentState ); - } - - if ( aCommand ) - g_free( aCommand ); -} - -void GtkSalMenu::NativeSetEnableItem( gchar* aCommand, gboolean bEnable ) -{ - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); - - if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bEnable ) - g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bEnable ); -} - -void GtkSalMenu::NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText ) -{ - // Replace the '~' character with '_'. - rtl::OUString aText = rText.replace( '~', '_' ); - rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ); - - // Update item text only when necessary. - gchar* aLabel = g_lo_menu_get_label_from_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos ); - - if ( aLabel == NULL || g_strcmp0( aLabel, aConvertedText.getStr() ) != 0 ) - g_lo_menu_set_label_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aConvertedText.getStr() ); - - if ( aLabel ) - g_free( aLabel ); -} - -void GtkSalMenu::NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ) -{ - if ( rKeyName.isEmpty() ) - return; - - rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 ); - - gchar* aCurrentAccel = g_lo_menu_get_accelerator_from_item_in_section( G_LO_MENU( mpMenuModel ), 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 ) - g_free( aCurrentAccel ); -} - -void GtkSalMenu::NativeSetItemCommand( unsigned nSection, - unsigned nItemPos, - sal_uInt16 nId, - const gchar* aCommand, - MenuItemBits nBits, - gboolean bChecked, - gboolean bIsSubmenu ) -{ - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); - - GVariant *pTarget = NULL; - - if ( g_action_group_has_action( mpActionGroup, aCommand ) == FALSE ) { - if ( ( nBits & MIB_CHECKABLE ) || ( bIsSubmenu == TRUE ) ) - { - // Item is a checkmark button. - 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, bIsSubmenu, NULL, pStateType, NULL, pState ); - } - else if ( nBits & MIB_RADIOCHECK ) - { - // Item is a radio button. - GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING ); - GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING ); - GVariant* pState = g_variant_new_string( "" ); - pTarget = g_variant_new_string( aCommand ); - - 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, FALSE ); - } - } - - GLOMenu* pMenu = G_LO_MENU( mpMenuModel ); - - // Menu item is not updated unless it's necessary. - gchar* aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, nItemPos ); - - if ( aCurrentCommand == NULL || g_strcmp0( aCurrentCommand, aCommand ) != 0 ) - { - g_lo_menu_set_command_to_item_in_section( pMenu, nSection, nItemPos, aCommand ); - - gchar* aItemCommand = g_strconcat("win.", aCommand, NULL ); - - if ( bIsSubmenu == TRUE ) - g_lo_menu_set_submenu_action_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand ); - else - g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget ); - - g_free( aItemCommand ); - } - - if ( aCurrentCommand ) - g_free( aCurrentCommand ); -} - GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu ) { GtkSalMenu* pMenu = NULL; @@ -719,7 +728,7 @@ void GtkSalMenu::Activate( const gchar* aMenuCommand ) if ( pSalSubMenu != NULL ) { pSalSubMenu->mpVCLMenu->Activate(); - UpdateNativeMenu2( pSalSubMenu ); + UpdateNativeSubMenu( pSalSubMenu ); } } @@ -735,31 +744,31 @@ void GtkSalMenu::Deactivate( const gchar* aMenuCommand ) } } -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 ) { } -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* ) { } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits