summaryrefslogtreecommitdiff
path: root/vcl/unx/gtk
diff options
context:
space:
mode:
authorAntonio Fernandez <antonio.fernandez@aentos.es>2012-09-11 12:21:28 +0100
committerBjoern Michaelsen <bjoern.michaelsen@canonical.com>2012-11-14 13:52:47 +0100
commit1f4f5a55556dae157eaeec14d34f3f706d93b983 (patch)
tree27d068139820f6822b323d0037983ab326e716e6 /vcl/unx/gtk
parent44192ffba03ffe5b1f387f90893dc0ca22bc8762 (diff)
Fixed crashes when executing some menu actions.
Change-Id: I80bb1ed74e823d4b66df05eb15c9b5ed2e58b7f6
Diffstat (limited to 'vcl/unx/gtk')
-rw-r--r--vcl/unx/gtk/window/gloactiongroup.cxx105
-rw-r--r--vcl/unx/gtk/window/gtksalmenu.cxx50
2 files changed, 71 insertions, 84 deletions
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
index d7eafbfc2c53..33e756c14229 100644
--- a/vcl/unx/gtk/window/gloactiongroup.cxx
+++ b/vcl/unx/gtk/window/gloactiongroup.cxx
@@ -28,10 +28,6 @@
#include <unx/gtk/gtksalmenu.hxx>
#include <vcl/menu.hxx>
-#include <stdio.h>
-#include <iostream>
-
-using namespace std;
/*
* GLOAction
@@ -47,7 +43,7 @@ struct _GLOAction
{
GObject parent_instance;
- GtkSalMenuItem* item; // A pointer to the menu item.
+ gint item_id; // Menu item ID.
gboolean enabled; // TRUE if action is enabled, FALSE otherwise.
GVariantType* parameter_type; // A GVariantType with the action parameter type.
GVariantType* state_type; // A GVariantType with item state type
@@ -69,7 +65,7 @@ g_lo_action_new (void)
static void
g_lo_action_init (GLOAction *action)
{
- action->item = NULL;
+ action->item_id = -1;
action->enabled = TRUE;
action->parameter_type = NULL;
action->state_type = NULL;
@@ -82,8 +78,6 @@ g_lo_action_finalize (GObject *object)
{
GLOAction* action = G_LO_ACTION(object);
- action->item = NULL;
-
if (action->parameter_type)
g_variant_type_free (action->parameter_type);
@@ -113,7 +107,8 @@ g_lo_action_class_init (GLOActionClass *klass)
struct _GLOActionGroupPrivate
{
- GHashTable *table; /* string -> GtkSalMenuItem* */
+ GHashTable *table; /* string -> GLOAction */
+ GtkSalFrame *frame; /* Frame to which GActionGroup is associated. */
};
static void g_lo_action_group_iface_init (GActionGroupInterface *);
@@ -218,67 +213,39 @@ g_lo_action_group_activate (GActionGroup *group,
{
GTK_YIELD_GRAB();
- GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
- GLOAction* action = G_LO_ACTION (g_hash_table_lookup (loGroup->priv->table, action_name));
- GtkSalMenuItem *pSalMenuItem = action->item;
+ GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
+ GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
- if (pSalMenuItem == NULL || pSalMenuItem->mpSubMenu )
+ GtkSalFrame *pFrame = lo_group->priv->frame;
+
+ if ( pFrame == NULL )
return;
- const GtkSalFrame *pFrame = pSalMenuItem->mpParentMenu ? pSalMenuItem->mpParentMenu->GetFrame() : NULL;
+ GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() );
- if ( pFrame && !pFrame->GetParent() ) {
- ((PopupMenu*) pSalMenuItem->mpVCLMenu)->SetSelectedEntry( pSalMenuItem->mnId );
- SalMenuEvent aMenuEvt( pSalMenuItem->mnId, pSalMenuItem->mpVCLMenu );
- pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt );
- }
- else if ( pSalMenuItem->mpVCLMenu )
- {
- // if an item from submenu was selected. the corresponding Window does not exist because
- // we use native popup menus, so we have to set the selected menuitem directly
- // incidentally this of course works for top level popup menus, too
- PopupMenu * pPopupMenu = dynamic_cast<PopupMenu *>(pSalMenuItem->mpVCLMenu);
- if( pPopupMenu )
- {
- // FIXME: revise this ugly code
-
- // select handlers in vcl are dispatch on the original menu
- // if not consumed by the select handler of the current menu
- // however since only the starting menu ever came into Execute
- // the hierarchy is not build up. Workaround this by getting
- // the menu it should have been
-
- // get started from hierarchy in vcl menus
- GtkSalMenu* pParentMenu = pSalMenuItem->mpParentMenu;
- Menu* pCurMenu = pSalMenuItem->mpVCLMenu;
- while( pParentMenu && pParentMenu->GetMenu() )
- {
- pCurMenu = pParentMenu->GetMenu();
- pParentMenu = pParentMenu->GetParentSalMenu();
- }
-
- pPopupMenu->SetSelectedEntry( pSalMenuItem->mnId );
- pPopupMenu->ImplSelectWithStart( pCurMenu );
- }
- else
- {
- OSL_FAIL( "menubar item without frame !" );
- }
- }
+ if ( pSalMenu == NULL )
+ return;
+
+ GtkSalMenu* pSalSubMenu = pSalMenu->GetMenuForItemCommand( (gchar*) action_name );
+ Menu* pSubMenu = ( pSalMenu != NULL ) ? pSalSubMenu->GetMenu() : NULL;
+
+ MenuBar* pMenuBar = static_cast< MenuBar* >( pSalMenu->GetMenu() );
+
+ pMenuBar->HandleMenuCommandEvent( pSubMenu, action->item_id );
}
void
g_lo_action_group_insert (GLOActionGroup *group,
const gchar *action_name,
- gpointer action_info)
+ gint item_id)
{
- g_lo_action_group_insert_stateful (group, action_name, action_info, NULL, NULL, NULL, NULL);
+ g_lo_action_group_insert_stateful (group, action_name, item_id, NULL, NULL, NULL, NULL);
}
void
g_lo_action_group_insert_stateful (GLOActionGroup *group,
const gchar *action_name,
- gpointer action_info,
+ gint item_id,
const GVariantType *parameter_type,
const GVariantType *state_type,
GVariant *state_hint,
@@ -288,7 +255,7 @@ g_lo_action_group_insert_stateful (GLOActionGroup *group,
GLOAction* old_action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
- if (old_action == NULL || old_action->item != action_info)
+ if (old_action == NULL || old_action->item_id != item_id)
{
if (old_action != NULL)
g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
@@ -297,7 +264,7 @@ g_lo_action_group_insert_stateful (GLOActionGroup *group,
g_hash_table_insert (group->priv->table, g_strdup (action_name), action);
- action->item = static_cast< GtkSalMenuItem* >( action_info );
+ action->item_id = item_id;
if (parameter_type)
action->parameter_type = (GVariantType*) parameter_type;
@@ -333,6 +300,7 @@ g_lo_action_group_init (GLOActionGroup *group)
GLOActionGroupPrivate);
group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
+ group->priv->frame = NULL;
}
static void
@@ -355,9 +323,12 @@ g_lo_action_group_iface_init (GActionGroupInterface *iface)
}
GLOActionGroup *
-g_lo_action_group_new (void)
+g_lo_action_group_new (gpointer frame)
{
- return G_LO_ACTION_GROUP( g_object_new (G_TYPE_LO_ACTION_GROUP, NULL) );
+ GLOActionGroup* group = G_LO_ACTION_GROUP (g_object_new (G_TYPE_LO_ACTION_GROUP, NULL));
+ group->priv->frame = static_cast< GtkSalFrame* > (frame);
+
+ return group;
}
void
@@ -375,21 +346,7 @@ g_lo_action_group_set_action_enabled (GLOActionGroup *group,
action->enabled = enabled;
- g_action_group_action_enabled_changed(G_ACTION_GROUP(group),
- action_name,
- enabled);
-}
-
-gpointer
-g_lo_action_group_get_action_item (GLOActionGroup *group,
- const gchar *action_name)
-{
- g_return_val_if_fail (G_IS_LO_ACTION_GROUP (group), NULL);
- g_return_val_if_fail (action_name != NULL, NULL);
-
- GLOAction* action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
-
- return (action != NULL) ? action->item : NULL;
+ g_action_group_action_enabled_changed (G_ACTION_GROUP (group), action_name, enabled);
}
void
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 19ca8893a811..b61af316f4ab 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -367,19 +367,19 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
if ( mpMenuModel == NULL && mpActionGroup == NULL ) {
mpMenuModel = G_MENU_MODEL( g_lo_menu_new() );
- mpActionGroup = G_ACTION_GROUP( g_lo_action_group_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);
+ "com.canonical.AppMenu.Registrar",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ on_registrar_available,
+ on_registrar_unavailable,
+ (gpointer) mpFrame,
+ NULL);
( ( GtkSalFrame* ) mpFrame )->SetWatcherId( nWatcherId );
}
@@ -512,7 +512,7 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, Gtk
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, pItem, NULL, pStateType, NULL, pState );
+ g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, NULL, pStateType, NULL, pState );
}
else if ( bits & MIB_RADIOCHECK )
{
@@ -522,12 +522,12 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, Gtk
GVariant* pState = g_variant_new_string( "" );
pTarget = g_variant_new_string( aCommand );
- g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState );
+ g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, pParameterType, pStateType, NULL, pState );
}
else
{
// Item is not special, so insert a stateless action.
- g_lo_action_group_insert( pActionGroup, aCommand, pItem );
+ g_lo_action_group_insert( pActionGroup, aCommand, pItem->mnId );
}
}
@@ -555,6 +555,36 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
{
}
+GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand )
+{
+ GtkSalMenu* pMenu = NULL;
+
+ for ( sal_uInt16 nPos = 0; nPos < maItems.size(); nPos++ )
+ {
+ GtkSalMenuItem *pSalItem = maItems[ nPos ];
+
+ String aItemCommand = mpVCLMenu->GetItemCommand( pSalItem->mnId );
+
+ gchar* aItemCommandStr = (gchar*) rtl::OUStringToOString( aItemCommand, RTL_TEXTENCODING_UTF8 ).getStr();
+
+ if ( g_strcmp0( aItemCommandStr, aCommand ) == 0 )
+ {
+ pMenu = this;
+ break;
+ }
+ else
+ {
+ if ( pSalItem->mpSubMenu != NULL )
+ pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand );
+
+ if ( pMenu != NULL )
+ break;
+ }
+ }
+
+ return pMenu;
+}
+
void GtkSalMenu::Freeze()
{
}