diff options
author | Antonio Fernandez <antonio.fernandez@aentos.es> | 2012-08-25 22:44:09 +0100 |
---|---|---|
committer | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2012-11-14 13:52:44 +0100 |
commit | 73f0064fbcbe28ad8aecd1c41637cec18776908c (patch) | |
tree | 0e3f8685d060342a40b238e6a795e737bfb4f7e0 /vcl/unx/gtk/window | |
parent | b29792bfd3e6aae9fdb94d7f072c23ea1629a7ef (diff) |
GLOMenu class is now mostly implemented, but menus are buggy at the moment.
Change-Id: Ib7c657efdd167f66e94717dda71d722196ae1667
Diffstat (limited to 'vcl/unx/gtk/window')
-rw-r--r-- | vcl/unx/gtk/window/gloactiongroup.cxx | 248 | ||||
-rw-r--r-- | vcl/unx/gtk/window/glomenu.cxx | 646 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalmenu.cxx | 574 |
3 files changed, 776 insertions, 692 deletions
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx index a409015c7ac5..39ab45eed577 100644 --- a/vcl/unx/gtk/window/gloactiongroup.cxx +++ b/vcl/unx/gtk/window/gloactiongroup.cxx @@ -1,3 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Antonio Fernández <antonio.fernandez@aentos.es> + */ + #include <unx/gtk/gloactiongroup.h> #include <unx/gtk/gtkinst.hxx> @@ -10,6 +33,92 @@ using namespace std; +/* + * GLOAction + */ + +#define G_TYPE_LO_ACTION (g_lo_action_get_type ()) +#define G_LO_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_LO_ACTION, GLOAction)) +#define G_IS_LO_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_LO_ACTION)) + +struct _GLOAction +{ + GObject parent_instance; + + GtkSalMenuItem* item; // A pointer to the menu item. + 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 + GVariant* state_hint; // A GVariant with state hints. + GVariant* state; // A GVariant with current item state +}; + +typedef GObjectClass GLOActionClass; +typedef struct _GLOAction GLOAction; + +G_DEFINE_TYPE (GLOAction, g_lo_action, G_TYPE_OBJECT); + +GLOAction* +g_lo_action_new (void) +{ + return G_LO_ACTION (g_object_new (G_TYPE_LO_ACTION, NULL)); +} + +static void +g_lo_action_init (GLOAction *action) +{ + action->item = NULL; + action->enabled = FALSE; + action->parameter_type = NULL; + action->state_type = NULL; + action->state_hint = NULL; + action->state = NULL; +} + +static void +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); + action->parameter_type = NULL; + } + + if (action->state_type) { + g_variant_type_free (action->state_type); + action->state_type = NULL; + } + + if (action->state_hint) { + g_variant_unref (action->state_hint); + action->state_hint = NULL; + } + + if (action->state) { + g_variant_unref (action->state); + action->state = NULL; + } + + G_OBJECT_CLASS (g_lo_action_parent_class)->finalize (object); +} + +static void +g_lo_action_class_init (GLOActionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = g_lo_action_finalize; +} + +/* + * GLOActionGroup + */ + struct _GLOActionGroupPrivate { GHashTable *table; /* string -> GtkSalMenuItem* */ @@ -52,35 +161,32 @@ g_lo_action_group_query_action (GActionGroup *group, GVariant **state_hint, GVariant **state) { - GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group); - GtkSalMenuItem* item_info; +// cout << __FUNCTION__ << " - " << action_name << " - enabled: " << enabled << " - parameter_type: " << parameter_type << " - state_type: " << state_type << " - state_hint: " << state_hint << " - state: " << state << endl; + GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group); + GLOAction* action; - item_info = static_cast< GtkSalMenuItem* >( g_hash_table_lookup (loGroup->priv->table, action_name) ); + action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name)); - if (item_info == NULL) + if (action == NULL) return FALSE; - if (enabled) { - sal_Bool bEnabled = item_info->mpVCLMenu->IsItemEnabled( item_info->mnId ); - *enabled = (bEnabled) ? TRUE : FALSE; - } + if (enabled) + *enabled = action->enabled; - if (parameter_type) - *parameter_type = NULL; + if (parameter_type) { + *parameter_type = action->parameter_type; + } - if (state_type) - *state_type = item_info->mpStateType; + if (state_type) { + *state_type = action->state_type; + } - if (state_hint) - *state_hint = NULL; + if (state_hint) { + *state_hint = (action->state_hint) ? g_variant_ref(action->state_hint) : NULL; + } if (state) { - if (item_info->mpState) { - g_variant_ref( item_info->mpState ); - *state = item_info->mpState; - } else { - *state = NULL; - } + *state = (action->state) ? g_variant_ref(action->state) : NULL; } return TRUE; @@ -95,24 +201,23 @@ g_lo_action_group_change_state (GActionGroup *group, return; GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group); - GtkSalMenuItem* item_info; - item_info = static_cast<GtkSalMenuItem*>( g_hash_table_lookup (lo_group->priv->table, action_name) ); + GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name)); - if (!item_info) + if (action == NULL) return; - if (!item_info->mpStateType) { - item_info->mpStateType = g_variant_type_copy(g_variant_get_type(value)); - } + if (action->state_type == NULL) + action->state_type = g_variant_type_copy(g_variant_get_type(value)); - if (g_variant_is_of_type(value, item_info->mpStateType)) { - if (item_info->mpState) - g_variant_unref(item_info->mpState); + g_return_if_fail (g_variant_is_of_type(value, action->state_type) == TRUE); - item_info->mpState = g_variant_new_variant(value); - g_action_group_action_state_changed(group, action_name, value); - } + if (action->state) + g_variant_unref(action->state); + + action->state = g_variant_take_ref(value); + + g_action_group_action_state_changed(group, action_name, value); } static void @@ -120,16 +225,15 @@ g_lo_action_group_activate (GActionGroup *group, const gchar *action_name, GVariant *parameter) { - GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group); - GtkSalMenuItem *pSalMenuItem; + GTK_YIELD_GRAB(); - pSalMenuItem = static_cast< GtkSalMenuItem* >( g_hash_table_lookup (loGroup->priv->table, action_name) ); + 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; if (pSalMenuItem == NULL || pSalMenuItem->mpSubMenu ) return; - GTK_YIELD_GRAB(); - const GtkSalFrame *pFrame = pSalMenuItem->mpParentMenu ? pSalMenuItem->mpParentMenu->GetFrame() : NULL; if ( pFrame && !pFrame->GetParent() ) { @@ -177,18 +281,44 @@ g_lo_action_group_insert (GLOActionGroup *group, const gchar *action_name, gpointer action_info) { - g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); + g_lo_action_group_insert_stateful (group, action_name, action_info, NULL, NULL, NULL, NULL); +} - gpointer old_action; +void +g_lo_action_group_insert_stateful (GLOActionGroup *group, + const gchar *action_name, + gpointer action_info, + const GVariantType *parameter_type, + const GVariantType *state_type, + GVariant *state_hint, + GVariant *state) +{ + g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - old_action = g_hash_table_lookup (group->priv->table, action_name); + GLOAction* old_action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name)); - if (old_action != action_info) + if (old_action == NULL || old_action->item != action_info) { if (old_action != NULL) g_action_group_action_removed (G_ACTION_GROUP (group), action_name); - g_hash_table_insert (group->priv->table, g_strdup (action_name), action_info); + GLOAction* action = g_lo_action_new(); + + g_hash_table_insert (group->priv->table, g_strdup (action_name), action); + + action->item = static_cast< GtkSalMenuItem* >( action_info ); + + if (parameter_type) + action->parameter_type = (GVariantType*) parameter_type; + + if (state_type) + action->state_type = (GVariantType*) state_type; + + if (state_hint) + action->state_hint = g_variant_take_ref (state_hint); + + if (state) + action->state = g_variant_take_ref (state); g_action_group_action_added (G_ACTION_GROUP (group), action_name); } @@ -197,9 +327,9 @@ g_lo_action_group_insert (GLOActionGroup *group, static void g_lo_action_group_finalize (GObject *object) { - GLOActionGroup *loGroup = G_LO_ACTION_GROUP (object); + GLOActionGroup *lo_group = G_LO_ACTION_GROUP (object); - g_hash_table_unref (loGroup->priv->table); + g_hash_table_unref (lo_group->priv->table); G_OBJECT_CLASS (g_lo_action_group_parent_class)->finalize (object); } @@ -211,7 +341,7 @@ g_lo_action_group_init (GLOActionGroup *group) G_TYPE_LO_ACTION_GROUP, GLOActionGroupPrivate); group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL ); + g_free, g_object_unref); } static void @@ -245,11 +375,30 @@ g_lo_action_group_set_action_enabled (GLOActionGroup *group, gboolean enabled) { g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); + g_return_if_fail (action_name != NULL); + + GLOAction* action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name)); + + if (action == NULL) + return; + + 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; } void @@ -270,7 +419,12 @@ g_lo_action_group_clear (GLOActionGroup *group) { g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - g_hash_table_remove_all(group->priv->table); + GList* keys = g_hash_table_get_keys (group->priv->table); + + for (GList* element = g_list_first (keys); element != NULL; element = g_list_next (element)) + { + g_lo_action_group_remove (group, (gchar*) element->data); + } } void @@ -292,3 +446,5 @@ g_lo_action_group_merge (GLOActionGroup *input_group, g_lo_action_group_insert(output_group, (gchar*) key, value); } } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx index 7ada47479f06..989a3b3ed3cd 100644 --- a/vcl/unx/gtk/window/glomenu.cxx +++ b/vcl/unx/gtk/window/glomenu.cxx @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /* * Copyright © 2011 Canonical Ltd. * @@ -16,51 +18,86 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * - * Author: Ryan Lortie <desrt@desrt.ca> + * Author: Antonio Fernández <antonio.fernandez@aentos.es> */ #include <stdio.h> #include <string.h> -#include <unx/gtk/glomenu.h> - - -struct _GLOMenuItem -{ - GObject parent_instance; - - GHashTable *attributes; - GHashTable *links; - gboolean cow; -}; +#include <unx/gtk/gtksalmenu.hxx> -typedef GObjectClass GLOMenuItemClass; +#include <unx/gtk/glomenu.h> struct _GLOMenu { - GMenuModel parent_instance; + GMenuModel parent_instance; - GArray *items; -// gboolean mutable; + GArray *items; }; typedef GMenuModelClass GLOMenuClass; -G_DEFINE_TYPE (GLOMenu, g_lo_menu, G_TYPE_MENU_MODEL) -G_DEFINE_TYPE (GLOMenuItem, g_lo_menu_item, G_TYPE_OBJECT) +G_DEFINE_TYPE (GLOMenu, g_lo_menu, G_TYPE_MENU_MODEL); struct item { - GHashTable *attributes; - GHashTable *links; +// GtkSalMenuItem* menu_item; // Menu item pointer. + GHashTable* attributes; // Item attributes. + GHashTable* links; // Item links. }; + +static void +g_lo_menu_struct_item_init (struct item *menu_item) +{ +// menu_item->menu_item = NULL; + menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +} + +/* We treat attribute names the same as GSettings keys: + * - only lowercase ascii, digits and '-' + * - must start with lowercase + * - must not end with '-' + * - no consecutive '-' + * - not longer than 1024 chars + */ static gboolean -g_lo_menu_is_mutable (GMenuModel *model) +valid_attribute_name (const gchar *name) { -// GMenu *menu = G_MENU (model); + gint i; + + if (!g_ascii_islower (name[0])) + return FALSE; + + for (i = 1; name[i]; i++) + { + if (name[i] != '-' && + !g_ascii_islower (name[i]) && + !g_ascii_isdigit (name[i])) + return FALSE; -// return menu->mutable; + if (name[i] == '-' && name[i + 1] == '-') + return FALSE; + } + + if (name[i - 1] == '-') + return FALSE; + + if (i > 1024) + return FALSE; + + return TRUE; +} + +/* + * GLOMenu + */ + +static gboolean +g_lo_menu_is_mutable (GMenuModel *model) +{ + // Menu is always mutable. return TRUE; } @@ -74,8 +111,8 @@ g_lo_menu_get_n_items (GMenuModel *model) static void g_lo_menu_get_item_attributes (GMenuModel *model, - gint position, - GHashTable **table) + gint position, + GHashTable **table) { GLOMenu *menu = G_LO_MENU (model); @@ -84,8 +121,8 @@ g_lo_menu_get_item_attributes (GMenuModel *model, static void g_lo_menu_get_item_links (GMenuModel *model, - gint position, - GHashTable **table) + gint position, + GHashTable **table) { GLOMenu *menu = G_LO_MENU (model); @@ -93,46 +130,42 @@ g_lo_menu_get_item_links (GMenuModel *model, } void -g_lo_menu_insert_item (GLOMenu *menu, - gint position, - GLOMenuItem *item) +g_lo_menu_insert (GLOMenu *menu, + gint position, + const gchar *label) { - struct item new_item; - +// puts(__FUNCTION__); g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (G_IS_LO_MENU_ITEM (item)); if (position < 0 || position > (gint) menu->items->len) position = menu->items->len; - new_item.attributes = g_hash_table_ref (item->attributes); - new_item.links = g_hash_table_ref (item->links); - item->cow = TRUE; + struct item menu_item; - g_array_insert_val (menu->items, position, new_item); - g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1); -} + g_lo_menu_struct_item_init(&menu_item); -void -g_lo_menu_prepend_item (GLOMenu *menu, - GLOMenuItem *item) -{ - g_lo_menu_insert_item (menu, 0, item); -} + g_array_insert_val (menu->items, position, menu_item); -void -g_lo_menu_append_item (GLOMenu *menu, - GLOMenuItem *item) -{ - g_lo_menu_insert_item (menu, -1, item); + g_lo_menu_set_label (menu, position, label); + + g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1); } void -g_lo_menu_freeze (GLOMenu *menu) +g_lo_menu_insert_in_section (GLOMenu *menu, + gint section, + gint position, + const gchar *label) { g_return_if_fail (G_IS_LO_MENU (menu)); + g_return_if_fail (0 <= section && section < (gint) menu->items->len); -// menu->mutable = FALSE; + GLOMenu *model = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class) + ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION)); + + g_return_if_fail (model != NULL); + + g_lo_menu_insert (model, position, label); } GLOMenu * @@ -142,436 +175,279 @@ g_lo_menu_new (void) } void -g_lo_menu_insert (GLOMenu *menu, - gint position, - const gchar *label, - const gchar *detailed_action) +g_lo_menu_set_attribute_value (GLOMenu *menu, + gint position, + const gchar *attribute, + GVariant *value) { - GLOMenuItem *menu_item; +// puts(__FUNCTION__); + g_return_if_fail (G_IS_LO_MENU (menu)); + g_return_if_fail (attribute != NULL); + g_return_if_fail (valid_attribute_name (attribute)); - menu_item = g_lo_menu_item_new (label, detailed_action); - g_lo_menu_insert_item (menu, position, menu_item); - g_object_unref (menu_item); -} + if (position >= menu->items->len) + return; -void -g_lo_menu_prepend (GLOMenu *menu, - const gchar *label, - const gchar *detailed_action) -{ - g_lo_menu_insert (menu, 0, label, detailed_action); -} + struct item menu_item = g_array_index (menu->items, struct item, position); -void -g_lo_menu_append (GLOMenu *menu, - const gchar *label, - const gchar *detailed_action) -{ - g_lo_menu_insert (menu, -1, label, detailed_action); + if (value != NULL) + g_hash_table_insert (menu_item.attributes, g_strdup (attribute), g_variant_ref_sink (value)); + else + g_hash_table_remove (menu_item.attributes, attribute); } void -g_lo_menu_insert_section (GLOMenu *menu, - gint position, - const gchar *label, - GMenuModel *section) +g_lo_menu_set_label (GLOMenu *menu, + gint position, + const gchar *label) { - GLOMenuItem *menu_item; +// puts(__FUNCTION__); + g_return_if_fail (G_IS_LO_MENU (menu)); - menu_item = g_lo_menu_item_new_section (label, section); - g_lo_menu_insert_item (menu, position, menu_item); - g_object_unref (menu_item); -} + GVariant *value; -void -g_lo_menu_prepend_section (GLOMenu *menu, - const gchar *label, - GMenuModel *section) -{ - g_lo_menu_insert_section (menu, 0, label, section); -} + if (label != NULL) + value = g_variant_new_string (label); + else + value = NULL; -void -g_lo_menu_append_section (GLOMenu *menu, - const gchar *label, - GMenuModel *section) -{ - g_lo_menu_insert_section (menu, -1, label, section); + g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_LABEL, value); } void -g_lo_menu_insert_submenu (GLOMenu *menu, - gint position, - const gchar *label, - GMenuModel *submenu) +g_lo_menu_set_label_in_section (GLOMenu *menu, + gint section, + gint position, + const gchar *label) { - GLOMenuItem *menu_item; +// puts(__FUNCTION__); + g_return_if_fail (G_IS_LO_MENU (menu)); - menu_item = g_lo_menu_item_new_submenu (label, submenu); - g_lo_menu_insert_item (menu, position, menu_item); - g_object_unref (menu_item); -} + struct item menu_item = g_array_index (menu->items, struct item, section); -void -g_lo_menu_prepend_submenu (GLOMenu *menu, - const gchar *label, - GMenuModel *submenu) -{ - g_lo_menu_insert_submenu (menu, 0, label, submenu); -} + GLOMenu *model = G_LO_MENU (g_hash_table_lookup (menu_item.links, G_MENU_LINK_SECTION)); -void -g_lo_menu_append_submenu (GLOMenu *menu, - const gchar *label, - GMenuModel *submenu) -{ - g_lo_menu_insert_submenu (menu, -1, label, submenu); -} + g_return_if_fail (model != NULL); -static void -g_lo_menu_clear_item (struct item *item) -{ - if (item->attributes != NULL) - g_hash_table_unref (item->attributes); - if (item->links != NULL) - g_hash_table_unref (item->links); + g_lo_menu_set_label (model, position, label); } void -g_lo_menu_remove (GLOMenu *menu, - gint position) +g_lo_menu_set_action_and_target_value (GLOMenu *menu, + gint position, + const gchar *action, + GVariant *target_value) { +// puts(__FUNCTION__); g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (0 <= position && position < (gint) menu->items->len); - - g_lo_menu_clear_item (&g_array_index (menu->items, struct item, position)); - g_array_remove_index (menu->items, position); - g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0); -} - -static void -g_lo_menu_finalize (GObject *object) -{ - GLOMenu *menu = G_LO_MENU (object); - struct item *items; - gint n_items; - gint i; - - n_items = menu->items->len; - items = (struct item *) g_array_free (menu->items, FALSE); - for (i = 0; i < n_items; i++) - g_lo_menu_clear_item (&items[i]); - g_free (items); - - G_OBJECT_CLASS (g_lo_menu_parent_class) - ->finalize (object); -} - -static void -g_lo_menu_init (GLOMenu *menu) -{ - menu->items = g_array_new (FALSE, FALSE, sizeof (struct item)); -// menu->mutable = TRUE; -} - -static void -g_lo_menu_class_init (GLOMenuClass *klass) -{ - GMenuModelClass *model_class = G_MENU_MODEL_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = g_lo_menu_finalize; - - model_class->is_mutable = g_lo_menu_is_mutable; - model_class->get_n_items = g_lo_menu_get_n_items; - model_class->get_item_attributes = g_lo_menu_get_item_attributes; - model_class->get_item_links = g_lo_menu_get_item_links; -} + GVariant *action_value; -static void -g_lo_menu_item_clear_cow (GLOMenuItem *menu_item) -{ - if (menu_item->cow) + if (action != NULL) { - GHashTableIter iter; - GHashTable *newHash; - gpointer key; - gpointer val; - - newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); - g_hash_table_iter_init (&iter, menu_item->attributes); - while (g_hash_table_iter_next (&iter, &key, &val)) - g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_variant_ref ((GVariant*) val)); - g_hash_table_unref (menu_item->attributes); - menu_item->attributes = newHash; - - newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); - g_hash_table_iter_init (&iter, menu_item->links); - while (g_hash_table_iter_next (&iter, &key, &val)) - g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_object_ref (val)); - g_hash_table_unref (menu_item->links); - menu_item->links = newHash; - - menu_item->cow = FALSE; + action_value = g_variant_new_string (action); } + else + { + action_value = NULL; + target_value = NULL; + } + + g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_ACTION, action_value); + g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_TARGET, target_value); } -static void -g_lo_menu_item_finalize (GObject *object) +void +g_lo_menu_set_action_and_target_value_to_item_in_section (GLOMenu *menu, + gint section, + gint position, + const gchar *command, + GVariant *target_value) { - GLOMenuItem *menu_item = G_LO_MENU_ITEM (object); + g_return_if_fail (G_IS_LO_MENU (menu)); - g_hash_table_unref (menu_item->attributes); - g_hash_table_unref (menu_item->links); + struct item menu_item = g_array_index (menu->items, struct item, section); - G_OBJECT_CLASS (g_lo_menu_item_parent_class) - ->finalize (object); -} + GLOMenu *model = G_LO_MENU (g_hash_table_lookup (menu_item.links, G_MENU_LINK_SECTION)); -static void -g_lo_menu_item_init (GLOMenuItem *menu_item) -{ - menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); - menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - menu_item->cow = FALSE; -} + g_return_if_fail (model != NULL); -static void -g_lo_menu_item_class_init (GLOMenuItemClass *klass) -{ - klass->finalize = g_lo_menu_item_finalize; + g_lo_menu_set_action_and_target_value (model, position, command, target_value); } -/* We treat attribute names the same as GSettings keys: - * - only lowercase ascii, digits and '-' - * - must start with lowercase - * - must not end with '-' - * - no consecutive '-' - * - not longer than 1024 chars - */ -static gboolean -valid_attribute_name (const gchar *name) +gchar* +g_lo_menu_get_action_value_from_item_in_section (GLOMenu *menu, + gint section, + gint position) { - gint i; + g_return_val_if_fail (G_IS_LO_MENU (menu), NULL); - if (!g_ascii_islower (name[0])) - return FALSE; + GMenuModel *model = G_MENU_MODEL_CLASS (g_lo_menu_parent_class) + ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION); - for (i = 1; name[i]; i++) - { - if (name[i] != '-' && - !g_ascii_islower (name[i]) && - !g_ascii_isdigit (name[i])) - return FALSE; + GVariant *action = g_menu_model_get_item_attribute_value (model, position, G_MENU_ATTRIBUTE_LABEL, NULL); - if (name[i] == '-' && name[i + 1] == '-') - return FALSE; - } + gchar *action_name = NULL; - if (name[i - 1] == '-') - return FALSE; + if (action) + action_name = g_strdup (g_variant_get_string (action, NULL)); - if (i > 1024) - return FALSE; - - return TRUE; + return action_name; } void -g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item, - const gchar *attribute, - GVariant *value) +g_lo_menu_set_link (GLOMenu *menu, + gint position, + const gchar *link, + GMenuModel *model) { - g_return_if_fail (G_IS_LO_MENU_ITEM (menu_item)); - g_return_if_fail (attribute != NULL); - g_return_if_fail (valid_attribute_name (attribute)); +// puts(__FUNCTION__); + g_return_if_fail (G_IS_LO_MENU (menu)); + g_return_if_fail (link != NULL); + g_return_if_fail (valid_attribute_name (link)); - g_lo_menu_item_clear_cow (menu_item); + if (position < 0 || position >= (gint) menu->items->len) + position = menu->items->len - 1; - if (value != NULL) - g_hash_table_insert (menu_item->attributes, g_strdup (attribute), g_variant_ref_sink (value)); + struct item menu_item = g_array_index (menu->items, struct item, position); + + if (model != NULL) + g_hash_table_insert (menu_item.links, g_strdup (link), g_object_ref (model)); else - g_hash_table_remove (menu_item->attributes, attribute); + g_hash_table_remove (menu_item.links, link); } void -g_lo_menu_item_set_attribute (GLOMenuItem *menu_item, - const gchar *attribute, - const gchar *format_string, - ...) +g_lo_menu_insert_section (GLOMenu *menu, + gint position, + const gchar *label) { - GVariant *value; - - if (format_string != NULL) - { - va_list ap; +// puts(__FUNCTION__); + g_return_if_fail (G_IS_LO_MENU (menu)); - va_start (ap, format_string); - value = g_variant_new_va (format_string, NULL, &ap); - va_end (ap); - } - else - value = NULL; + if (position < 0 || position > (gint) menu->items->len) + position = menu->items->len; - g_lo_menu_item_set_attribute_value (menu_item, attribute, value); -} + struct item menu_item; -void -g_lo_menu_item_set_link (GLOMenuItem *menu_item, - const gchar *link, - GMenuModel *model) -{ - g_return_if_fail (G_IS_LO_MENU_ITEM (menu_item)); - g_return_if_fail (link != NULL); - g_return_if_fail (valid_attribute_name (link)); + g_lo_menu_struct_item_init(&menu_item); - g_lo_menu_item_clear_cow (menu_item); + g_array_insert_val (menu->items, position, menu_item); - if (model != NULL) - g_hash_table_insert (menu_item->links, g_strdup (link), g_object_ref (model)); - else - g_hash_table_remove (menu_item->links, link); -} + g_lo_menu_set_label (menu, position, label); -void -g_lo_menu_item_set_label (GLOMenuItem *menu_item, - const gchar *label) -{ - GVariant *value; + GMenuModel *section = G_MENU_MODEL (g_lo_menu_new()); + g_lo_menu_set_link (menu, position, G_MENU_LINK_SECTION, section); - if (label != NULL) - value = g_variant_new_string (label); - else - value = NULL; + g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1); - g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_LABEL, value); +// g_lo_menu_insert (menu, position, label); +// menu_item = g_lo_menu_item_new_section (label, section); +// g_lo_menu_insert_item (menu, position, menu_item); +// g_object_unref (menu_item); } void -g_lo_menu_item_set_submenu (GLOMenuItem *menu_item, - GMenuModel *submenu) +g_lo_menu_set_submenu (GLOMenu *menu, + gint position, + GMenuModel *submenu) { - g_lo_menu_item_set_link (menu_item, G_MENU_LINK_SUBMENU, submenu); +// puts(__FUNCTION__); + g_lo_menu_set_link (menu, position, G_MENU_LINK_SUBMENU, submenu); } void -g_lo_menu_item_set_section (GLOMenuItem *menu_item, - GMenuModel *section) +g_lo_menu_set_submenu_to_item_in_section (GLOMenu *menu, + gint section, + gint position, + GMenuModel *submenu) { - g_lo_menu_item_set_link (menu_item, G_MENU_LINK_SECTION, section); -} +// puts(__FUNCTION__); + g_return_if_fail (G_IS_LO_MENU (menu)); + g_return_if_fail (0 <= section && section < (gint) menu->items->len); -void -g_lo_menu_item_set_action_and_target_value (GLOMenuItem *menu_item, - const gchar *action, - GVariant *target_value) -{ - GVariant *action_value; + GLOMenu *model = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class) + ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION)); - if (action != NULL) - { - action_value = g_variant_new_string (action); - } - else - { - action_value = NULL; - target_value = NULL; - } + g_return_if_fail (model != NULL); - g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ACTION, action_value); - g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_TARGET, target_value); + g_lo_menu_set_submenu (model, position, submenu); } -void -g_lo_menu_item_set_action_and_target (GLOMenuItem *menu_item, - const gchar *action, - const gchar *format_string, - ...) +static void +g_lo_menu_clear_item (struct item *menu_item) { - GVariant *value; - - if (format_string != NULL) - { - va_list ap; - - va_start (ap, format_string); - value = g_variant_new_va (format_string, NULL, &ap); - va_end (ap); - } - else - value = NULL; - - g_lo_menu_item_set_action_and_target_value (menu_item, action, value); + if (menu_item->attributes != NULL) + g_hash_table_unref (menu_item->attributes); + if (menu_item->links != NULL) + g_hash_table_unref (menu_item->links); } void -g_lo_menu_item_set_detailed_action (GLOMenuItem *menu_item, - const gchar *detailed_action) +g_lo_menu_remove (GLOMenu *menu, + gint position) { - const gchar *sep; - - sep = strstr (detailed_action, "::"); - - if (sep != NULL) - { - gchar *action; - - action = g_strndup (detailed_action, sep - detailed_action); - g_lo_menu_item_set_action_and_target (menu_item, action, "s", sep + 2); - g_free (action); - } + printf("%s - %d\n", __FUNCTION__, position); + g_return_if_fail (G_IS_LO_MENU (menu)); + g_return_if_fail (0 <= position && position < (gint) menu->items->len); - else - g_lo_menu_item_set_action_and_target_value (menu_item, detailed_action, NULL); + g_lo_menu_clear_item (&g_array_index (menu->items, struct item, position)); + g_array_remove_index (menu->items, position); + g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0); } -GLOMenuItem * -g_lo_menu_item_new (const gchar *label, - const gchar *detailed_action) +void +g_lo_menu_remove_from_section (GLOMenu *menu, + gint section, + gint position) { - GLOMenuItem *menu_item; - - menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) ); + g_return_if_fail (G_IS_LO_MENU (menu)); + g_return_if_fail (0 <= section && section < (gint) menu->items->len); - if (label != NULL) - g_lo_menu_item_set_label (menu_item, label); + GLOMenu *model = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class) + ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION)); - if (detailed_action != NULL) - g_lo_menu_item_set_detailed_action (menu_item, detailed_action); + g_return_if_fail (model != NULL); - return menu_item; + g_lo_menu_remove (model, position); } -GLOMenuItem * -g_lo_menu_item_new_submenu (const gchar *label, - GMenuModel *submenu) +static void +g_lo_menu_finalize (GObject *object) { - GLOMenuItem *menu_item; - - menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) ); - - if (label != NULL) - g_lo_menu_item_set_label (menu_item, label); + GLOMenu *menu = G_LO_MENU (object); + struct item *items; + gint n_items; + gint i; - g_lo_menu_item_set_submenu (menu_item, submenu); + n_items = menu->items->len; + items = (struct item *) g_array_free (menu->items, FALSE); + for (i = 0; i < n_items; i++) + g_lo_menu_clear_item (&items[i]); + g_free (items); - return menu_item; + G_OBJECT_CLASS (g_lo_menu_parent_class) + ->finalize (object); } -GLOMenuItem * -g_lo_menu_item_new_section (const gchar *label, - GMenuModel *section) +static void +g_lo_menu_init (GLOMenu *menu) { - GLOMenuItem *menu_item; - - menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) ); + menu->items = g_array_new (FALSE, FALSE, sizeof (struct item)); +} - if (label != NULL) - g_lo_menu_item_set_label (menu_item, label); +static void +g_lo_menu_class_init (GLOMenuClass *klass) +{ + GMenuModelClass *model_class = G_MENU_MODEL_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_lo_menu_item_set_section (menu_item, section); + object_class->finalize = g_lo_menu_finalize; - return menu_item; + model_class->is_mutable = g_lo_menu_is_mutable; + model_class->get_n_items = g_lo_menu_get_n_items; + model_class->get_item_attributes = g_lo_menu_get_item_attributes; + model_class->get_item_links = g_lo_menu_get_item_links; } +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 7e0004a68e2e..1eb32c1bb8d0 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -1,3 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Antonio Fernández <antonio.fernandez@aentos.es> + */ #include "unx/gtk/gtksalmenu.hxx" @@ -12,59 +33,60 @@ using namespace std; //Some menus are special, this is the list of them -gboolean -isSpecialSubmenu (OUString command) -{ - const gchar * specialSubmenus[11] = {".uno:CharFontName", - ".uno:FontHeight", - ".uno:ObjectMenue", - ".uno:InsertPageHeader", - ".uno:InsertPageFooter", - ".uno:ChangeControlType", - ".uno:AvailableToolbars", - ".uno:ScriptOrganizer", - ".uno:RecentFileList", - ".uno:AddDirect", - ".uno:AutoPilotMenu"}; - - for (gint i = 0; i < 11; i++) - { - if (command.equals (OUString::createFromAscii (specialSubmenus[i]))) - return TRUE; - } - return FALSE; -} +//gboolean +//isSpecialSubmenu (OUString command) +//{ +// const gchar * specialSubmenus[11] = {".uno:CharFontName", +// ".uno:FontHeight", +// ".uno:ObjectMenue", +// ".uno:InsertPageHeader", +// ".uno:InsertPageFooter", +// ".uno:ChangeControlType", +// ".uno:AvailableToolbars", +// ".uno:ScriptOrganizer", +// ".uno:RecentFileList", +// ".uno:AddDirect", +// ".uno:AutoPilotMenu"}; + +// for (gint i = 0; i < 11; i++) +// { +// if (command.equals (OUString::createFromAscii (specialSubmenus[i]))) +// return TRUE; +// } +// return FALSE; +//} -void updateNativeMenu( GtkSalMenu* pMenu ) { +static void UpdateNativeMenu( GtkSalMenu* pMenu ) { if ( pMenu == NULL ) return; - for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { - GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); + Menu* pVCLMenu = pMenu->GetMenu(); - Menu* pVCLMenu = pSalMenuItem->mpVCLMenu; + for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { + sal_uInt16 nId = pVCLMenu->GetItemId( i ); + GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( i ); - if ( pVCLMenu == NULL ) + if ( pVCLMenu->GetItemType( nId ) == MENUITEM_SEPARATOR ) continue; - sal_uInt16 nId = pSalMenuItem->mnId; - String aText = pVCLMenu->GetItemText( nId ); + String aCommand = pVCLMenu->GetItemCommand( nId ); sal_Bool itemEnabled = pVCLMenu->IsItemEnabled( nId ); + KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId ); + sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId ); // Force updating of native menu labels. pMenu->SetItemText( i, pSalMenuItem, aText ); - + pMenu->SetItemCommand( i, pSalMenuItem, aCommand ); pMenu->EnableItem( i, itemEnabled ); - - // KeyCode nAccelKey = pSubmenu->GetAccelKey( pSalMenuItem->mnId ); - // pMenu->SetAccelerator( i, pSalMenuItem, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) ); +// pMenu->SetAccelerator( i, pSalMenuItem, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) ); +// pMenu->CheckItem( i, itemChecked ); GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; if ( pSubmenu && pSubmenu->GetMenu() ) { pSubmenu->GetMenu()->Activate(); - updateNativeMenu( pSubmenu ); + UpdateNativeMenu( pSubmenu ); pSubmenu->GetMenu()->Deactivate(); } } @@ -73,7 +95,7 @@ void updateNativeMenu( GtkSalMenu* pMenu ) { gboolean GenerateMenu(gpointer user_data) { GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data ); - updateNativeMenu( pSalMenu ); + UpdateNativeMenu( pSalMenu ); return TRUE; } @@ -122,88 +144,100 @@ GActionGroup* GetActionGroupFromMenubar( GtkSalMenu *pMenu ) return ( pSalMenu ) ? pSalMenu->GetActionGroup() : NULL; } -rtl::OUString GetGtkKeyName( rtl::OUString keyName ) -{ - rtl::OUString aGtkKeyName(""); +//rtl::OUString GetGtkKeyName( rtl::OUString keyName ) +//{ +// rtl::OUString aGtkKeyName(""); + +// sal_Int32 nIndex = 0; + +// do +// { +// rtl::OUString token = keyName.getToken( 0, '+', nIndex ); + +// if ( token == "Ctrl" ) { +// aGtkKeyName += "<Control>"; +// } else if ( token == "Alt" ) { +// aGtkKeyName += "<Alt>"; +// } else if ( token == "Shift" ) { +// aGtkKeyName += "<Shift>"; +// } else { +// aGtkKeyName += token; +// } +// } while ( nIndex >= 0 ); + +// return aGtkKeyName; +//} + +//GVariant* GetRadionButtonHints( GtkSalMenuItem *pSalMenuItem ) +//{ +// GVariantBuilder *pBuilder; +// GVariant *pHints; + +// pBuilder = g_variant_builder_new( G_VARIANT_TYPE_STRING ); + +// Menu* pMenu = pSalMenuItem->mpVCLMenu; + +// gboolean bItemIncluded = FALSE; + +// for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) +// { +// sal_uInt16 nId = pMenu->GetItemId( i ); +// MenuItemBits itemBits = pMenu->GetItemBits( nId ); +// MenuItemType itemType = pMenu->GetItemType( nId ); + +// if ( itemBits & MIB_RADIOCHECK ) +// { +// rtl::OString aValue = rtl::OUStringToOString( pMenu->GetItemText( nId ), RTL_TEXTENCODING_UTF8 ); +// g_variant_builder_add( pBuilder, "s", aValue.getStr() ); + +// if ( nId == pSalMenuItem->mnId ) +// bItemIncluded = TRUE; +// } +// else if ( itemType == MENUITEM_SEPARATOR ) +// { +// if ( bItemIncluded == FALSE ) +// { +// g_variant_builder_clear( pBuilder ); +// } +// else +// break; +// } +// } - sal_Int32 nIndex = 0; +// // Build an array of G_VARIANT_TYPE_STRING. +// pHints = g_variant_new ("as", pBuilder); +// g_variant_builder_unref ( pBuilder ); - do - { - rtl::OUString token = keyName.getToken( 0, '+', nIndex ); - - if ( token == "Ctrl" ) { - aGtkKeyName += "<Control>"; - } else if ( token == "Alt" ) { - aGtkKeyName += "<Alt>"; - } else if ( token == "Shift" ) { - aGtkKeyName += "<Shift>"; - } else { - aGtkKeyName += token; - } - } while ( nIndex >= 0 ); - - return aGtkKeyName; -} +// return pHints; +//} /* * GtkSalMenu */ -GtkSalMenuItem* GtkSalMenu::GetSalMenuItem( sal_uInt16 nId ) +void GtkSalMenu::GetInsertionData( unsigned nPos, unsigned *insertSection, unsigned *insertPos ) { - for ( sal_uInt16 i = 0; i < maItems.size(); i++ ) + if ( mpVCLMenu == NULL || nPos >= mpVCLMenu->GetItemCount() ) { - GtkSalMenuItem* pSalMenuItem = maItems[ i ]; - - if ( pSalMenuItem->mnId == nId ) { - return pSalMenuItem; - } - - if ( pSalMenuItem->mpSubMenu ) - { - pSalMenuItem = pSalMenuItem->mpSubMenu->GetSalMenuItem( nId ); - if (pSalMenuItem) { - return pSalMenuItem; - } - } + *insertSection = g_menu_model_get_n_items( mpMenuModel ) - 1; + *insertPos = MENU_APPEND; } - - return NULL; -} - -sal_Int16 GtkSalMenu::GetSectionNumber( GMenuModel* pSection ) -{ - if ( pSection == NULL ) - return -1; - - for ( int i = 0; maSections.size(); i++ ) + else { - if ( maSections[ i ] == pSection ) - return i; - } - - return -1; -} + unsigned nItem; + gint nItemPos; -void GtkSalMenu::GetInsertionData( unsigned nPos, unsigned *insertSection, unsigned *insertPos ) -{ - unsigned nItems; - unsigned nSection; - - for ( nSection = 0, nItems = 0; nSection < maSections.size(); nSection++ ) - { - if ( nPos <= nItems + g_menu_model_get_n_items( maSections[ nSection ] ) ) { - *insertSection = nSection; - *insertPos = nPos - nItems; - return; + for ( nItem = 0, *insertSection = 0, nItemPos = -1; nItem <= nPos; nItem++ ) + { + if ( mpVCLMenu->GetItemType( nItem ) == MENUITEM_SEPARATOR ) { + (*insertSection)++; + nItemPos = -1; + } else + nItemPos++; } - nItems += g_menu_model_get_n_items( maSections[ nSection ] ) + 1; // +1 to count the separator. + *insertPos = nItemPos; } - - *insertSection = maSections.size() - 1; - *insertPos = MENU_APPEND; } GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : @@ -211,44 +245,32 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : mpVCLMenu( NULL ), mpParentSalMenu( NULL ), mpFrame( NULL ), - pSessionBus( NULL ), - mMenubarId( 0 ), - mActionGroupId ( 0 ), mpMenuModel( NULL ), mpActionGroup( NULL ) { - GMenuModel* pSection = G_MENU_MODEL( g_lo_menu_new() ); - maSections.push_back( pSection ); - if (bMenuBar) { mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() ); - - pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - if(!pSessionBus) puts ("Fail bus get"); - } else { - mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); - g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, pSection ); } + + mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); + g_lo_menu_insert_section( G_LO_MENU( mpMenuModel ), 0, NULL); } GtkSalMenu::~GtkSalMenu() { - g_source_remove_by_user_data( this ); + if ( mpActionGroup ) { + g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) ); + } if ( mbMenuBar ) { + g_source_remove_by_user_data( this ); + g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 ); mpMenuModel = NULL; } else { g_object_unref( mpMenuModel ); } - if ( mpActionGroup ) { - g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) ); - } - - pSessionBus = NULL; - - maSections.clear(); maItems.clear(); } @@ -261,51 +283,56 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) { GtkSalMenuItem *pItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); - if ( nPos == MENU_APPEND ) { + if ( nPos == MENU_APPEND ) maItems.push_back( pItem ); - } else { + else maItems.insert( maItems.begin() + nPos, pItem ); - } - - if ( pItem->mpMenuItem ) { - unsigned nSection, nInsertPos; - // Get the section number and position to insert the item. - GetInsertionData( nPos, &nSection, &nInsertPos ); + pItem->mpParentMenu = this; - g_lo_menu_insert_item( G_LO_MENU( maSections[ nSection ] ), nInsertPos, pItem->mpMenuItem ); - } else { - // If no mpMenuItem exists, then item is a separator. - GMenuModel* pSection = G_MENU_MODEL( g_lo_menu_new() ); - maSections.push_back( pSection ); + if ( pItem->mnType != MENUITEM_SEPARATOR ) + { + unsigned nInsertSection, nInsertPos; + GetInsertionData( nPos, &nInsertSection, &nInsertPos ); - if ( mpMenuModel != NULL ) - g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, pSection ); + g_lo_menu_insert_in_section( G_LO_MENU( mpMenuModel ), nInsertSection, nInsertPos, "EMPTY STRING" ); + } + else + { + g_lo_menu_insert_section( G_LO_MENU( mpMenuModel ), MENU_APPEND, NULL ); } - - pItem->mpParentMenu = this; } void GtkSalMenu::RemoveItem( unsigned nPos ) { - GtkSalMenuItem* pItem = maItems[ nPos ]; - - if ( pItem->mpMenuItem != NULL ) { - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); - if ( pActionGroup ) { - g_lo_action_group_remove( pActionGroup, pItem->maCommand ); - } + GLOMenu* pMenu = G_LO_MENU( mpMenuModel ); + // If item is a separator, the last section of the menu is removed. + if ( mpVCLMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) + { unsigned nSection, nItemPos; GetInsertionData( nPos, &nSection, &nItemPos ); - g_lo_menu_remove( G_LO_MENU( maSections[ nSection ] ), nItemPos ); +// gchar *aCommand = g_lo_menu_get_action_value_from_item_in_section( pMenu, nSection, nItemPos ); - // Remove empty sections unless section is the last one. - if ( g_menu_model_get_n_items( maSections[ nSection ] ) == 0 && maSections.size() > 1 ) { - g_lo_menu_remove( G_LO_MENU( mpMenuModel ), nSection ); - maSections.erase( maSections.begin() + nSection ); - } +// if ( aCommand ) { +// GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); + +// if ( pActionGroup != NULL ) +// g_lo_action_group_remove( pActionGroup, aCommand ); + +// g_free( aCommand ); +// } + + cout << __FUNCTION__ << " - " << nSection << " - " << nItemPos << " - " << nPos << " - " << this << endl; + g_lo_menu_remove_from_section( pMenu, nSection, nItemPos ); + } + else + { + gint nSection = g_menu_model_get_n_items( mpMenuModel ) - 1; + cout << __FUNCTION__ << " - " << nSection << endl; + if ( nSection < 0 ) + g_lo_menu_remove( pMenu, nSection ); } maItems.erase( maItems.begin() + nPos ); @@ -313,23 +340,22 @@ void GtkSalMenu::RemoveItem( unsigned nPos ) void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) { + cout << __FUNCTION__ << endl; GtkSalMenuItem *pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem ); GtkSalMenu *pGtkSubMenu = static_cast< GtkSalMenu* >( pSubMenu ); if ( pGtkSubMenu == NULL ) return; + pGtkSubMenu->mpParentSalMenu = this; pItem->mpSubMenu = pGtkSubMenu; - g_lo_menu_item_set_submenu( pItem->mpMenuItem, pGtkSubMenu->mpMenuModel ); // Update item in GMenuModel. unsigned nSection, nItemPos; GetInsertionData( nPos, &nSection, &nItemPos ); - g_lo_menu_remove( G_LO_MENU( maSections[ nSection ] ), nItemPos ); - g_lo_menu_insert_item( G_LO_MENU( maSections[ nSection ] ), nItemPos, pItem->mpMenuItem ); - - pGtkSubMenu->mpParentSalMenu = this; + cout << __FUNCTION__ << " - " << nSection << " - " << nItemPos << " - " << nPos << " - " << this << endl; + g_lo_menu_set_submenu_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, pGtkSubMenu->mpMenuModel ); } void GtkSalMenu::SetFrame( const SalFrame* pFrame ) @@ -345,7 +371,7 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ) ); if ( pMenu && pActionGroup ) { - mpMenuModel = G_MENU_MODEL( pMenu ); +// mpMenuModel = G_MENU_MODEL( pMenu ); // Merge current action group with the exported one g_lo_action_group_clear( pActionGroup ); @@ -355,8 +381,6 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) mpActionGroup = G_ACTION_GROUP( pActionGroup ); } else { - mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); - 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 ); @@ -366,6 +390,10 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) 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) puts ("Failed to get DBus session connection"); + 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 ); @@ -373,24 +401,24 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) // Publish the menu. if ( aDBusMenubarPath ) { - mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, mpMenuModel, NULL); - if(!mMenubarId) puts("Fail export menubar"); + sal_uInt16 menubarId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, mpMenuModel, NULL); + if(!menubarId) puts("Failed to export menubar"); } if ( aDBusPath ) { - mActionGroupId = g_dbus_connection_export_action_group( pSessionBus, aDBusPath, mpActionGroup, NULL); + sal_uInt16 actionGroupId = g_dbus_connection_export_action_group( pSessionBus, aDBusPath, mpActionGroup, NULL); + if(!actionGroupId) puts("Failed to export action group"); } g_free( aDBusPath ); g_free( aDBusWindowPath ); g_free( aDBusMenubarPath ); } +// updateNativeMenu( this ); +// updateNativeMenu( this ); - // Menubar has only one section. - g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, maSections[ 0 ] ); - - // Refresh the menu every second. - // This code is a workaround until required modifications in Gtk+ are available. +// // Refresh the menu every second. +// // This code is a workaround until required modifications in Gtk+ are available. g_timeout_add_seconds( 1, GenerateMenu, this ); } } @@ -405,27 +433,29 @@ const GtkSalFrame* GtkSalMenu::GetFrame() const void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck ) { -// cout << __FUNCTION__ << " - " << nPos << " - " << bCheck << endl; +// GtkSalMenuItem* pItem = maItems[ nPos ]; + +// if ( pItem->maCommand == NULL || g_strcmp0( pItem->maCommand, "" ) == 0 ) +// return; + // GActionGroup* pActionGroup = GetActionGroupFromMenubar( this ); // if ( !pActionGroup ) // return; -// GtkSalMenuItem* pSalMenuItem = maItems[ nPos ]; -// if ( !pSalMenuItem || pSalMenuItem->mpSubMenu ) +// if ( !pItem || pItem->mpSubMenu ) // return; -// MenuItemBits itemBits = pSalMenuItem->mnBits; // GVariant *pCheckValue = NULL; -// if ( itemBits & MIB_CHECKABLE ) { +// if ( pItem->mnBits & MIB_CHECKABLE ) { // gboolean bCheckedValue = ( bCheck == sal_True ) ? TRUE : FALSE; // pCheckValue = g_variant_new_boolean( bCheckedValue ); // } // if ( pCheckValue ) -// g_action_group_change_action_state( pActionGroup, pSalMenuItem->maCommand, pCheckValue ); +// g_action_group_change_action_state( pActionGroup, pItem->maCommand, pCheckValue ); } void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable ) @@ -435,49 +465,57 @@ void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable ) if ( pActionGroup == NULL ) return; - GtkSalMenuItem* pItem = maItems[ nPos ]; - - gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE; + sal_uInt16 nId = mpVCLMenu->GetItemId( nPos ); + rtl::OUString aOUCommand = mpVCLMenu->GetItemCommand( nId ); - if ( pItem->maCommand == NULL || g_strcmp0( pItem->maCommand, "" ) == 0 ) + if ( aOUCommand == NULL || aOUCommand.isEmpty() ) return; - g_lo_action_group_set_action_enabled( pActionGroup, pItem->maCommand, bItemEnabled ); + gchar* aCommand = (gchar*) rtl::OUStringToOString( aOUCommand, RTL_TEXTENCODING_UTF8 ).getStr(); + + gboolean bItemEnabled = (bEnable == sal_True) ? TRUE : FALSE; + + if ( g_action_group_get_action_enabled( G_ACTION_GROUP( pActionGroup ), aCommand ) != bItemEnabled ) + g_lo_action_group_set_action_enabled( pActionGroup, aCommand, bItemEnabled ); } void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText ) { // Replace the "~" character with "_". rtl::OUString aText = rText.replace( '~', '_' ); - rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8); + rtl::OString aConvertedText = OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ); - GtkSalMenuItem *pItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); - GLOMenuItem *pMenuItem = G_LO_MENU_ITEM( pItem->mpMenuItem ); +// GtkSalMenuItem *pItem = static_cast<GtkSalMenuItem*>( pSalMenuItem ); - unsigned nSection, nInsertPos; - GetInsertionData( nPos, &nSection, &nInsertPos ); + unsigned nSection, nItemPos; + GetInsertionData( nPos, &nSection, &nItemPos ); - GLOMenu* pSection = G_LO_MENU( maSections[ nSection ] ); + cout << __FUNCTION__ << " - " << nSection << " - " << nItemPos << " - " << nPos << " - " << this << " - " << aConvertedText.getStr() << endl; - GVariant* aCurrentLabel = NULL; +// GLOMenu* pSection = G_LO_MENU( maSections[ nSection ] ); - if ( g_menu_model_get_n_items( maSections[ nSection ] ) > 0 ) - aCurrentLabel = g_menu_model_get_item_attribute_value( G_MENU_MODEL( pSection ), nInsertPos, G_MENU_ATTRIBUTE_LABEL, G_VARIANT_TYPE_STRING ); +// GVariant* aCurrentLabel = NULL; - sal_Bool bSetLabel = sal_True; +// if ( g_menu_model_get_n_items( maSections[ nSection ] ) > nInsertPos ) +// aCurrentLabel = g_menu_model_get_item_attribute_value( G_MENU_MODEL( pSection ), nInsertPos, G_MENU_ATTRIBUTE_LABEL, G_VARIANT_TYPE_STRING ); - if ( aCurrentLabel != NULL ) { - if ( g_strcmp0( g_variant_get_string( aCurrentLabel, NULL ), aConvertedText.getStr() ) == 0 ) { - bSetLabel = sal_False; - } - } +// sal_Bool bSetLabel = sal_True; - if ( bSetLabel == sal_True ) { - g_lo_menu_item_set_label( pMenuItem, aConvertedText.getStr() ); +// if ( aCurrentLabel != NULL ) { +// if ( g_strcmp0( g_variant_get_string( aCurrentLabel, NULL ), aConvertedText.getStr() ) == 0 ) { +// bSetLabel = sal_False; +// } +// } - g_lo_menu_remove( pSection, nInsertPos ); - g_lo_menu_insert_item( pSection, nInsertPos, pItem->mpMenuItem ); - } +// if ( bSetLabel == sal_True ) { + g_lo_menu_set_label_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aConvertedText.getStr() ); + +//// cout << __FUNCTION__ << " - " << aConvertedText.getStr() << " - Section: " << nSection << " - Position: " << nInsertPos << " - Section size: " << g_menu_model_get_n_items( G_MENU_MODEL( pSection ) ) << endl; +// if ( g_menu_model_get_n_items( G_MENU_MODEL( pSection ) ) > nInsertPos ) +// g_lo_menu_remove( pSection, nInsertPos ); + +// g_lo_menu_insert_item( pSection, nInsertPos, pItem ); +// } } void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage) @@ -486,63 +524,98 @@ void GtkSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const I void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName ) { - // GtkSalMenuItem *pGtkSalMenuItem = static_cast< GtkSalMenuItem* >( pSalMenuItem ); +// GtkSalMenuItem *pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem ); + +// if ( rKeyName.isEmpty() ) +// return; - // if ( rKeyName.isEmpty() ) - // return; +// rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 ); - // rtl::OString aAccelerator = rtl::OUStringToOString( GetGtkKeyName( rKeyName ), RTL_TEXTENCODING_UTF8 ); +// unsigned nSection, nItemPos; +// GetInsertionData( nPos, &nSection, &nItemPos ); - // GVariant* aCurrentAccel = g_menu_model_get_item_attribute_value( pGtkSalMenuItem->mpParentSection, pGtkSalMenuItem->mnPos, "accel", G_VARIANT_TYPE_STRING ); +// GLOMenu* pSection = G_LO_MENU( maSections[ nSection ] ); - // sal_Bool bSetAccel = sal_True; +// GVariant* aCurrentAccel = g_menu_model_get_item_attribute_value( G_MENU_MODEL( pSection ), nItemPos, "accel", G_VARIANT_TYPE_STRING ); - // if ( aCurrentAccel ) { - // if ( g_strcmp0( g_variant_get_string( aCurrentAccel, NULL ), aAccelerator.getStr() ) == 0 ) { - // bSetAccel = sal_False; - // } - // } +// sal_Bool bSetAccel = sal_True; - // if ( bSetAccel == sal_True ) { - // g_lo_menu_item_set_attribute_value( pGtkSalMenuItem->mpMenuItem, "accel", g_variant_new_string( aAccelerator.getStr() ) ); +// if ( aCurrentAccel ) { +// if ( g_strcmp0( g_variant_get_string( aCurrentAccel, NULL ), aAccelerator.getStr() ) == 0 ) { +// bSetAccel = sal_False; +// } +// } - // g_lo_menu_remove( G_LO_MENU( pGtkSalMenuItem->mpParentSection), pGtkSalMenuItem->mnPos ); - // g_lo_menu_insert_item( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem ); - // } +// if ( bSetAccel == sal_True ) { +// g_lo_menu_item_set_attribute_value( pItem->mpMenuItem, "accel", g_variant_new_string( aAccelerator.getStr() ) ); + +// g_lo_menu_remove( pSection, nItemPos ); +// g_lo_menu_insert_item( pSection, nItemPos, pItem ); +// } } void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr ) { GtkSalMenuItem* pItem = static_cast< GtkSalMenuItem* >( pSalMenuItem ); - if ( pItem->mpMenuItem ) { - rtl::OString aOCommandStr = rtl::OUStringToOString( aCommandStr, RTL_TEXTENCODING_UTF8 ); + if ( pItem->mnType == MENUITEM_SEPARATOR || pItem->mpVCLMenu->GetPopupMenu( pItem->mnId ) != NULL ) + return; + + gchar* aCommand = (gchar*) rtl::OUStringToOString( aCommandStr, RTL_TEXTENCODING_UTF8 ).getStr(); - if ( pItem->maCommand ) - g_free( pItem->maCommand ); + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); + if ( pActionGroup == NULL ) + return; - pItem->maCommand = g_strdup( aOCommandStr.getStr() ); +// gboolean bChecked = ( pItem->mpVCLMenu->IsItemChecked( pItem->mnId ) ) ? TRUE : FALSE; - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( GetActionGroupFromMenubar( this ) ); - if ( pActionGroup ) { - g_lo_action_group_insert( pActionGroup, pItem->maCommand, pItem ); - } +// if ( pItem->mnBits & MIB_CHECKABLE ) +// { +//// cout << "Item with command: " << pItem->maCommand << " is checkmark button." << endl; - if ( pItem->mpVCLMenu->GetPopupMenu( pItem->mnId ) == NULL ) { - gchar* aItemCommand = g_strconcat("win.", pItem->maCommand, NULL ); +// // 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_menu_item_set_action_and_target( pItem->mpMenuItem, aItemCommand, NULL ); +// g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, NULL, pStateType, NULL, pState ); +// } +// else if ( pItem->mnBits & MIB_RADIOCHECK ) +// { +//// cout << "Item with command: " << pItem->maCommand << " is a radio button." << endl; - g_free( aItemCommand ); +// // 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* pStateHint = GetRadionButtonHints( pItem ); +//// GVariant* pState = g_variant_new_string( "" ); - unsigned nSection, nInsertPos; - GetInsertionData( nPos, &nSection, &nInsertPos ); +//// g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem, pParameterType, pStateType, NULL, pState ); +// } +// else +// { + // Item is not special, so insert a stateless action. + g_lo_action_group_insert( pActionGroup, aCommand, pItem ); +// } - GLOMenu* pSection = G_LO_MENU( maSections[ nSection ] ); - g_lo_menu_remove( pSection, nInsertPos ); - g_lo_menu_insert_item( pSection, nInsertPos, pItem->mpMenuItem ); - } - } + // Menu item is not updated unless it's necessary. +// if ( ( pItem->maCommand != NULL ) && ( g_strcmp0( pItem->maCommand, aCommand ) == 0 ) ) +// return; + +// if ( pItem->maCommand != NULL ) +// g_free( pItem->maCommand ); + +// pItem->maCommand = g_strdup( aCommand ); + + unsigned nSection, nItemPos; + GetInsertionData( nPos, &nSection, &nItemPos ); + + cout << __FUNCTION__ << " - " << nSection << " - " << nItemPos << " - " << nPos << " - " << this << endl; + + gchar* aItemCommand = g_strconcat("win.", aCommand, NULL ); + + g_lo_menu_set_action_and_target_value_to_item_in_section( G_LO_MENU( mpMenuModel ), nSection, nItemPos, aItemCommand, NULL ); + + g_free( aItemCommand ); } void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) @@ -562,37 +635,16 @@ void GtkSalMenu::Freeze() GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) : mnId( pItemData->nId ), mnBits( pItemData->nBits ), - maCommand( NULL ), + mnType( pItemData->eType ), mpVCLMenu( pItemData->pMenu ), mpParentMenu( NULL ), - mpSubMenu( NULL ), - mpMenuItem( NULL ), - mpStateType( NULL ), - mpState( NULL ) + mpSubMenu( NULL ) { - if ( pItemData->eType != MENUITEM_SEPARATOR ) { - mpMenuItem = g_lo_menu_item_new( "EMPTY STRING", NULL ); - - rtl::OUString aCommand = mpVCLMenu->GetItemCommand( mnId ); - - if ( aCommand == NULL || aCommand.isEmpty() == sal_True ) - return; - - maCommand = g_strdup( rtl::OUStringToOString( aCommand, RTL_TEXTENCODING_UTF8 ).getStr() ); - gchar* aActionCommand = g_strconcat( "win.", maCommand, NULL ); - - g_lo_menu_item_set_action_and_target( mpMenuItem, aActionCommand, NULL ); - - g_free( aActionCommand ); - } } GtkSalMenuItem::~GtkSalMenuItem() { - if ( mpMenuItem ) { - g_object_unref( mpMenuItem ); - - if ( maCommand ) - g_free( maCommand ); - } +// mpVCLMenu = NULL; } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |