Kaydet (Commit) 1f4f5a55 authored tarafından Antonio Fernandez's avatar Antonio Fernandez Kaydeden (comit) Bjoern Michaelsen

Fixed crashes when executing some menu actions.

Change-Id: I80bb1ed74e823d4b66df05eb15c9b5ed2e58b7f6
üst 44192ffb
......@@ -63,15 +63,15 @@ struct _GLOActionGroupClass
GType g_lo_action_group_get_type (void) G_GNUC_CONST;
GLOActionGroup * g_lo_action_group_new (void);
GLOActionGroup * g_lo_action_group_new (gpointer frame);
void g_lo_action_group_insert (GLOActionGroup *group,
const gchar *action_name,
gpointer action_info);
gint item_id);
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,
......@@ -79,10 +79,7 @@ void g_lo_action_group_insert_stateful (GLOActionGroup
void g_lo_action_group_set_action_enabled (GLOActionGroup *group,
const gchar *action_name,
gboolean enabled);
gpointer g_lo_action_group_get_action_item (GLOActionGroup *group,
const gchar *action_name);
gboolean enabled);
void g_lo_action_group_remove (GLOActionGroup *group,
const gchar *action_name);
......
......@@ -89,6 +89,7 @@ public:
virtual GtkSalMenuItem* GetItemAtPos( unsigned nPos ) { return maItems[ nPos ]; }
virtual void SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; }
virtual GActionGroup* GetActionGroup() { return mpActionGroup; }
GtkSalMenu* GetMenuForItemCommand( gchar* aCommand );
void NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText );
void NativeSetItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommandStr );
......
......@@ -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
......
......@@ -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()
{
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment