X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreemenu.c;h=8fef02e6f97af0807ea9c798e7afbf845d2ab28b;hb=6f1476edd3fbe31259e59ca3f03a01bf0f8ff67b;hp=bbb83f4658638206b7ff0c087bc1285483428062;hpb=613545f821b4eb226cca5d53d816e51550043f19;p=~andy%2Fgtk diff --git a/gtk/gtktreemenu.c b/gtk/gtktreemenu.c index bbb83f465..8fef02e6f 100644 --- a/gtk/gtktreemenu.c +++ b/gtk/gtktreemenu.c @@ -5,6 +5,8 @@ * Authors: * Tristan Van Berkom * + * Based on some GtkComboBox menu code by Kristian Rietveld + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -16,17 +18,15 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library 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. + * License along with this library. If not, see . */ -/** +/* * SECTION:gtktreemenu * @Short_Description: A GtkMenu automatically created from a #GtkTreeModel * @Title: GtkTreeMenu * - * The #GtkTreeMenu is used to display a drop-down menu allowing selection + * The #GtkTreeMenu is used to display a drop-down menu allowing selection * of every row in the model and is used by the #GtkComboBox for its drop-down * menu. */ @@ -36,37 +36,43 @@ #include "gtktreemenu.h" #include "gtkmarshalers.h" #include "gtkmenuitem.h" -#include "gtktearoffmenuitem.h" #include "gtkseparatormenuitem.h" #include "gtkcellareabox.h" #include "gtkcellareacontext.h" #include "gtkcelllayout.h" #include "gtkcellview.h" +#include "gtkmenushellprivate.h" #include "gtkprivate.h" +#undef GDK_DEPRECATED +#undef GDK_DEPRECATED_FOR +#define GDK_DEPRECATED +#define GDK_DEPRECATED_FOR(f) + +#include "deprecated/gtktearoffmenuitem.h" /* GObjectClass */ static GObject *gtk_tree_menu_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); + guint n_construct_properties, + GObjectConstructParam *construct_properties); static void gtk_tree_menu_dispose (GObject *object); static void gtk_tree_menu_finalize (GObject *object); static void gtk_tree_menu_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void gtk_tree_menu_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); + guint prop_id, + GValue *value, + GParamSpec *pspec); /* GtkWidgetClass */ static void gtk_tree_menu_get_preferred_width (GtkWidget *widget, - gint *minimum_size, - gint *natural_size); + gint *minimum_size, + gint *natural_size); static void gtk_tree_menu_get_preferred_height (GtkWidget *widget, - gint *minimum_size, - gint *natural_size); + gint *minimum_size, + gint *natural_size); /* GtkCellLayoutIface */ static void gtk_tree_menu_cell_layout_init (GtkCellLayoutIface *iface); @@ -76,60 +82,60 @@ static GtkCellArea *gtk_tree_menu_cell_layout_get_area (GtkCellLayout /* TreeModel/DrawingArea callbacks and building menus/submenus */ static inline void rebuild_menu (GtkTreeMenu *menu); static gboolean menu_occupied (GtkTreeMenu *menu, - guint left_attach, - guint right_attach, - guint top_attach, - guint bottom_attach); + guint left_attach, + guint right_attach, + guint top_attach, + guint bottom_attach); static void relayout_item (GtkTreeMenu *menu, - GtkWidget *item, - GtkTreeIter *iter, - GtkWidget *prev); + GtkWidget *item, + GtkTreeIter *iter, + GtkWidget *prev); static void gtk_tree_menu_populate (GtkTreeMenu *menu); static GtkWidget *gtk_tree_menu_create_item (GtkTreeMenu *menu, - GtkTreeIter *iter, - gboolean header_item); + GtkTreeIter *iter, + gboolean header_item); static void gtk_tree_menu_create_submenu (GtkTreeMenu *menu, - GtkWidget *item, - GtkTreePath *path); + GtkWidget *item, + GtkTreePath *path); static void gtk_tree_menu_set_area (GtkTreeMenu *menu, - GtkCellArea *area); + GtkCellArea *area); static GtkWidget *gtk_tree_menu_get_path_item (GtkTreeMenu *menu, - GtkTreePath *path); + GtkTreePath *path); static gboolean gtk_tree_menu_path_in_menu (GtkTreeMenu *menu, - GtkTreePath *path, - gboolean *header_item); + GtkTreePath *path, + gboolean *header_item); static void row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - GtkTreeMenu *menu); + GtkTreePath *path, + GtkTreeIter *iter, + GtkTreeMenu *menu); static void row_deleted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeMenu *menu); + GtkTreePath *path, + GtkTreeMenu *menu); static void row_reordered_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gint *new_order, - GtkTreeMenu *menu); + GtkTreePath *path, + GtkTreeIter *iter, + gint *new_order, + GtkTreeMenu *menu); static void row_changed_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - GtkTreeMenu *menu); + GtkTreePath *path, + GtkTreeIter *iter, + GtkTreeMenu *menu); static void context_size_changed_cb (GtkCellAreaContext *context, - GParamSpec *pspec, - GtkWidget *menu); + GParamSpec *pspec, + GtkWidget *menu); static void area_apply_attributes_cb (GtkCellArea *area, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gboolean is_expander, - gboolean is_expanded, - GtkTreeMenu *menu); + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gboolean is_expander, + gboolean is_expanded, + GtkTreeMenu *menu); static void item_activated_cb (GtkMenuItem *item, - GtkTreeMenu *menu); + GtkTreeMenu *menu); static void submenu_activated_cb (GtkTreeMenu *submenu, - const gchar *path, - GtkTreeMenu *menu); + const gchar *path, + GtkTreeMenu *menu); static void gtk_tree_menu_set_model_internal (GtkTreeMenu *menu, - GtkTreeModel *model); + GtkTreeModel *model); @@ -142,7 +148,7 @@ struct _GtkTreeMenuPrivate /* CellArea and context for this menu */ GtkCellArea *area; GtkCellAreaContext *context; - + /* Signals */ gulong size_changed_id; gulong apply_attributes_id; @@ -190,18 +196,18 @@ enum { static guint tree_menu_signals[N_SIGNALS] = { 0 }; static GQuark tree_menu_path_quark = 0; -G_DEFINE_TYPE_WITH_CODE (GtkTreeMenu, gtk_tree_menu, GTK_TYPE_MENU, - G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT, - gtk_tree_menu_cell_layout_init)); +G_DEFINE_TYPE_WITH_CODE (GtkTreeMenu, _gtk_tree_menu, GTK_TYPE_MENU, + G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT, + gtk_tree_menu_cell_layout_init)); static void -gtk_tree_menu_init (GtkTreeMenu *menu) +_gtk_tree_menu_init (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; menu->priv = G_TYPE_INSTANCE_GET_PRIVATE (menu, - GTK_TYPE_TREE_MENU, - GtkTreeMenuPrivate); + GTK_TYPE_TREE_MENU, + GtkTreeMenuPrivate); priv = menu->priv; priv->model = NULL; @@ -233,8 +239,8 @@ gtk_tree_menu_init (GtkTreeMenu *menu) gtk_menu_set_reserve_toggle_size (GTK_MENU (menu), FALSE); } -static void -gtk_tree_menu_class_init (GtkTreeMenuClass *class) +static void +_gtk_tree_menu_class_init (GtkTreeMenuClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); @@ -250,7 +256,7 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) widget_class->get_preferred_width = gtk_tree_menu_get_preferred_width; widget_class->get_preferred_height = gtk_tree_menu_get_preferred_height; - /** + /* * GtkTreeMenu::menu-activate: * @menu: a #GtkTreeMenu * @path: the #GtkTreePath string for the item which was activated @@ -264,18 +270,18 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) */ tree_menu_signals[SIGNAL_MENU_ACTIVATE] = g_signal_new (I_("menu-activate"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, /* No class closure here */ - NULL, NULL, - _gtk_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - /** + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, /* No class closure here */ + NULL, NULL, + _gtk_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + /* * GtkTreeMenu:model: * * The #GtkTreeModel from which the menu is constructed. - * + * * Since: 3.0 */ g_object_class_install_property (object_class, @@ -286,7 +292,7 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) GTK_TYPE_TREE_MODEL, GTK_PARAM_READWRITE)); - /** + /* * GtkTreeMenu:root: * * The #GtkTreePath that is the root for this menu, or %NULL. @@ -297,20 +303,20 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) * * If you dont provide a root for the #GtkTreeMenu then the whole * model will be added to the menu. Specifying a root allows you - * to build a menu for a given #GtkTreePath and it's children. + * to build a menu for a given #GtkTreePath and its children. * * Since: 3.0 */ g_object_class_install_property (object_class, PROP_ROOT, g_param_spec_boxed ("root", - P_("TreeMenu root row"), - P_("The TreeMenu will display children of the " - "specified root"), - GTK_TYPE_TREE_PATH, - GTK_PARAM_READWRITE)); + P_("TreeMenu root row"), + P_("The TreeMenu will display children of the " + "specified root"), + GTK_TYPE_TREE_PATH, + GTK_PARAM_READWRITE)); - /** + /* * GtkTreeMenu:cell-area: * * The #GtkCellArea used to render cells in the menu items. @@ -321,14 +327,14 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) * Since: 3.0 */ g_object_class_install_property (object_class, - PROP_CELL_AREA, - g_param_spec_object ("cell-area", - P_("Cell Area"), - P_("The GtkCellArea used to layout cells"), - GTK_TYPE_CELL_AREA, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** + PROP_CELL_AREA, + g_param_spec_object ("cell-area", + P_("Cell Area"), + P_("The GtkCellArea used to layout cells"), + GTK_TYPE_CELL_AREA, + GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /* * GtkTreeMenu:tearoff: * * Specifies whether this menu comes with a leading tearoff menu item @@ -336,14 +342,14 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) * Since: 3.0 */ g_object_class_install_property (object_class, - PROP_TEAROFF, - g_param_spec_boolean ("tearoff", - P_("Tearoff"), - P_("Whether the menu has a tearoff item"), - FALSE, - GTK_PARAM_READWRITE)); - - /** + PROP_TEAROFF, + g_param_spec_boolean ("tearoff", + P_("Tearoff"), + P_("Whether the menu has a tearoff item"), + FALSE, + GTK_PARAM_READWRITE)); + + /* * GtkTreeMenu:wrap-width: * * If wrap-width is set to a positive value, the list will be @@ -353,57 +359,57 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) * Since: 3.0 */ g_object_class_install_property (object_class, - PROP_WRAP_WIDTH, - g_param_spec_int ("wrap-width", - P_("Wrap Width"), - P_("Wrap width for laying out items in a grid"), - 0, - G_MAXINT, - 0, - GTK_PARAM_READWRITE)); - - /** + PROP_WRAP_WIDTH, + g_param_spec_int ("wrap-width", + P_("Wrap Width"), + P_("Wrap width for laying out items in a grid"), + 0, + G_MAXINT, + 0, + GTK_PARAM_READWRITE)); + + /* * GtkTreeMenu:row-span-column: * - * If this is set to a non-negative value, it must be the index of a column - * of type %G_TYPE_INT in the model. + * If this is set to a non-negative value, it must be the index of a column + * of type %G_TYPE_INT in the model. * - * The values of that column are used to determine how many rows a value in - * the list will span. Therefore, the values in the model column pointed to + * The values of that column are used to determine how many rows a value in + * the list will span. Therefore, the values in the model column pointed to * by this property must be greater than zero and not larger than wrap-width. * * Since: 3.0 */ g_object_class_install_property (object_class, - PROP_ROW_SPAN_COL, - g_param_spec_int ("row-span-column", - P_("Row span column"), - P_("TreeModel column containing the row span values"), - -1, - G_MAXINT, - -1, - GTK_PARAM_READWRITE)); - - /** + PROP_ROW_SPAN_COL, + g_param_spec_int ("row-span-column", + P_("Row span column"), + P_("TreeModel column containing the row span values"), + -1, + G_MAXINT, + -1, + GTK_PARAM_READWRITE)); + + /* * GtkTreeMenu:column-span-column: * - * If this is set to a non-negative value, it must be the index of a column - * of type %G_TYPE_INT in the model. + * If this is set to a non-negative value, it must be the index of a column + * of type %G_TYPE_INT in the model. * - * The values of that column are used to determine how many columns a value - * in the list will span. + * The values of that column are used to determine how many columns a value + * in the list will span. * * Since: 3.0 */ g_object_class_install_property (object_class, - PROP_COL_SPAN_COL, - g_param_spec_int ("column-span-column", - P_("Column span column"), - P_("TreeModel column containing the column span values"), - -1, - G_MAXINT, - -1, - GTK_PARAM_READWRITE)); + PROP_COL_SPAN_COL, + g_param_spec_int ("column-span-column", + P_("Column span column"), + P_("TreeModel column containing the column span values"), + -1, + G_MAXINT, + -1, + GTK_PARAM_READWRITE)); g_type_class_add_private (object_class, sizeof (GtkTreeMenuPrivate)); } @@ -413,14 +419,14 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class) ****************************************************************/ static GObject * gtk_tree_menu_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) + guint n_construct_properties, + GObjectConstructParam *construct_properties) { GObject *object; GtkTreeMenu *menu; GtkTreeMenuPrivate *priv; - object = G_OBJECT_CLASS (gtk_tree_menu_parent_class)->constructor + object = G_OBJECT_CLASS (_gtk_tree_menu_parent_class)->constructor (type, n_construct_properties, construct_properties); menu = GTK_TREE_MENU (object); @@ -435,9 +441,9 @@ gtk_tree_menu_constructor (GType type, priv->context = gtk_cell_area_create_context (priv->area); - priv->size_changed_id = + priv->size_changed_id = g_signal_connect (priv->context, "notify", - G_CALLBACK (context_size_changed_cb), menu); + G_CALLBACK (context_size_changed_cb), menu); return object; } @@ -451,7 +457,7 @@ gtk_tree_menu_dispose (GObject *object) menu = GTK_TREE_MENU (object); priv = menu->priv; - gtk_tree_menu_set_model (menu, NULL); + _gtk_tree_menu_set_model (menu, NULL); gtk_tree_menu_set_area (menu, NULL); if (priv->context) @@ -464,7 +470,7 @@ gtk_tree_menu_dispose (GObject *object) priv->size_changed_id = 0; } - G_OBJECT_CLASS (gtk_tree_menu_parent_class)->dispose (object); + G_OBJECT_CLASS (_gtk_tree_menu_parent_class)->dispose (object); } static void @@ -476,31 +482,31 @@ gtk_tree_menu_finalize (GObject *object) menu = GTK_TREE_MENU (object); priv = menu->priv; - gtk_tree_menu_set_row_separator_func (menu, NULL, NULL, NULL); - gtk_tree_menu_set_header_func (menu, NULL, NULL, NULL); + _gtk_tree_menu_set_row_separator_func (menu, NULL, NULL, NULL); + _gtk_tree_menu_set_header_func (menu, NULL, NULL, NULL); - if (priv->root) + if (priv->root) gtk_tree_row_reference_free (priv->root); - G_OBJECT_CLASS (gtk_tree_menu_parent_class)->finalize (object); + G_OBJECT_CLASS (_gtk_tree_menu_parent_class)->finalize (object); } static void gtk_tree_menu_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GtkTreeMenu *menu = GTK_TREE_MENU (object); switch (prop_id) { case PROP_MODEL: - gtk_tree_menu_set_model (menu, g_value_get_object (value)); + _gtk_tree_menu_set_model (menu, g_value_get_object (value)); break; case PROP_ROOT: - gtk_tree_menu_set_root (menu, g_value_get_boxed (value)); + _gtk_tree_menu_set_root (menu, g_value_get_boxed (value)); break; case PROP_CELL_AREA: @@ -509,19 +515,19 @@ gtk_tree_menu_set_property (GObject *object, break; case PROP_TEAROFF: - gtk_tree_menu_set_tearoff (menu, g_value_get_boolean (value)); + _gtk_tree_menu_set_tearoff (menu, g_value_get_boolean (value)); break; case PROP_WRAP_WIDTH: - gtk_tree_menu_set_wrap_width (menu, g_value_get_int (value)); + _gtk_tree_menu_set_wrap_width (menu, g_value_get_int (value)); break; case PROP_ROW_SPAN_COL: - gtk_tree_menu_set_row_span_column (menu, g_value_get_int (value)); + _gtk_tree_menu_set_row_span_column (menu, g_value_get_int (value)); break; case PROP_COL_SPAN_COL: - gtk_tree_menu_set_column_span_column (menu, g_value_get_int (value)); + _gtk_tree_menu_set_column_span_column (menu, g_value_get_int (value)); break; default: @@ -532,9 +538,9 @@ gtk_tree_menu_set_property (GObject *object, static void gtk_tree_menu_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { GtkTreeMenu *menu = GTK_TREE_MENU (object); GtkTreeMenuPrivate *priv = menu->priv; @@ -544,11 +550,11 @@ gtk_tree_menu_get_property (GObject *object, case PROP_MODEL: g_value_set_object (value, priv->model); break; - + case PROP_ROOT: g_value_set_boxed (value, priv->root); break; - + case PROP_CELL_AREA: g_value_set_object (value, priv->area); break; @@ -584,10 +590,10 @@ sync_reserve_submenu_size (GtkTreeMenu *menu) GtkMenuItem *item = l->data; if (gtk_menu_item_get_submenu (item) != NULL) - { - has_submenu = TRUE; - break; - } + { + has_submenu = TRUE; + break; + } } for (l = children; l; l = l->next) @@ -602,8 +608,8 @@ sync_reserve_submenu_size (GtkTreeMenu *menu) static void gtk_tree_menu_get_preferred_width (GtkWidget *widget, - gint *minimum_size, - gint *natural_size) + gint *minimum_size, + gint *natural_size) { GtkTreeMenu *menu = GTK_TREE_MENU (widget); GtkTreeMenuPrivate *priv = menu->priv; @@ -619,15 +625,15 @@ gtk_tree_menu_get_preferred_width (GtkWidget *widget, sync_reserve_submenu_size (menu); - GTK_WIDGET_CLASS (gtk_tree_menu_parent_class)->get_preferred_width (widget, minimum_size, natural_size); + GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->get_preferred_width (widget, minimum_size, natural_size); g_signal_handler_unblock (priv->context, priv->size_changed_id); } static void gtk_tree_menu_get_preferred_height (GtkWidget *widget, - gint *minimum_size, - gint *natural_size) + gint *minimum_size, + gint *natural_size) { GtkTreeMenu *menu = GTK_TREE_MENU (widget); GtkTreeMenuPrivate *priv = menu->priv; @@ -636,7 +642,7 @@ gtk_tree_menu_get_preferred_height (GtkWidget *widget, sync_reserve_submenu_size (menu); - GTK_WIDGET_CLASS (gtk_tree_menu_parent_class)->get_preferred_height (widget, minimum_size, natural_size); + GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->get_preferred_height (widget, minimum_size, natural_size); g_signal_handler_unblock (priv->context, priv->size_changed_id); } @@ -665,7 +671,7 @@ gtk_tree_menu_cell_layout_get_area (GtkCellLayout *layout) ****************************************************************/ static GtkWidget * gtk_tree_menu_get_path_item (GtkTreeMenu *menu, - GtkTreePath *search) + GtkTreePath *search) { GtkWidget *item = NULL; GList *children, *l; @@ -678,45 +684,45 @@ gtk_tree_menu_get_path_item (GtkTreeMenu *menu, GtkTreePath *path = NULL; if (GTK_IS_SEPARATOR_MENU_ITEM (child)) - { - GtkTreeRowReference *row = - g_object_get_qdata (G_OBJECT (child), tree_menu_path_quark); - - if (row) - { - path = gtk_tree_row_reference_get_path (row); - - if (!path) - /* Return any first child where it's row-reference became invalid, - * this is because row-references get null paths before we recieve - * the "row-deleted" signal. - */ - item = child; - } - } + { + GtkTreeRowReference *row = + g_object_get_qdata (G_OBJECT (child), tree_menu_path_quark); + + if (row) + { + path = gtk_tree_row_reference_get_path (row); + + if (!path) + /* Return any first child where its row-reference became invalid, + * this is because row-references get null paths before we recieve + * the "row-deleted" signal. + */ + item = child; + } + } else if (!GTK_IS_TEAROFF_MENU_ITEM (child)) - { - GtkWidget *view = gtk_bin_get_child (GTK_BIN (child)); + { + GtkWidget *view = gtk_bin_get_child (GTK_BIN (child)); - /* It's always a cellview */ - if (GTK_IS_CELL_VIEW (view)) - path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (view)); + /* It's always a cellview */ + if (GTK_IS_CELL_VIEW (view)) + path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (view)); - if (!path) - /* Return any first child where it's row-reference became invalid, - * this is because row-references get null paths before we recieve - * the "row-deleted" signal. - */ - item = child; - } + if (!path) + /* Return any first child where its row-reference became invalid, + * this is because row-references get null paths before we recieve + * the "row-deleted" signal. + */ + item = child; + } if (path) - { - if (gtk_tree_path_compare (search, path) == 0) - item = child; + { + if (gtk_tree_path_compare (search, path) == 0) + item = child; - gtk_tree_path_free (path); - } + gtk_tree_path_free (path); + } } g_list_free (children); @@ -726,41 +732,40 @@ gtk_tree_menu_get_path_item (GtkTreeMenu *menu, static gboolean gtk_tree_menu_path_in_menu (GtkTreeMenu *menu, - GtkTreePath *path, - gboolean *header_item) + GtkTreePath *path, + gboolean *header_item) { GtkTreeMenuPrivate *priv = menu->priv; gboolean in_menu = FALSE; gboolean is_header = FALSE; /* Check if the is in root of the model */ - if (gtk_tree_path_get_depth (path) == 1) - { - if (!priv->root) - in_menu = TRUE; - } + if (gtk_tree_path_get_depth (path) == 1 && !priv->root) + in_menu = TRUE; /* If we are a submenu, compare the parent path */ - else if (priv->root && gtk_tree_path_get_depth (path) > 1) + else if (priv->root) { GtkTreePath *root_path = gtk_tree_row_reference_get_path (priv->root); - GtkTreePath *parent_path = gtk_tree_path_copy (path); - - gtk_tree_path_up (parent_path); + GtkTreePath *search_path = gtk_tree_path_copy (path); if (root_path) - { - if (gtk_tree_path_compare (root_path, parent_path) == 0) - in_menu = TRUE; - - if (!in_menu && priv->menu_with_header && - gtk_tree_path_compare (root_path, path) == 0) - { - in_menu = TRUE; - is_header = TRUE; - } - } + { + if (priv->menu_with_header && + gtk_tree_path_compare (root_path, search_path) == 0) + { + in_menu = TRUE; + is_header = TRUE; + } + else if (gtk_tree_path_get_depth (search_path) > 1) + { + gtk_tree_path_up (search_path); + + if (gtk_tree_path_compare (root_path, search_path) == 0) + in_menu = TRUE; + } + } gtk_tree_path_free (root_path); - gtk_tree_path_free (parent_path); + gtk_tree_path_free (search_path); } if (header_item) @@ -770,8 +775,8 @@ gtk_tree_menu_path_in_menu (GtkTreeMenu *menu, } static GtkWidget * -gtk_tree_menu_path_needs_submenu (GtkTreeMenu *menu, - GtkTreePath *search) +gtk_tree_menu_path_needs_submenu (GtkTreeMenu *menu, + GtkTreePath *search) { GtkWidget *item = NULL; GList *children, *l; @@ -792,23 +797,23 @@ gtk_tree_menu_path_needs_submenu (GtkTreeMenu *menu, /* Separators dont get submenus, if it already has a submenu then let * the submenu handle inserted rows */ - if (!GTK_IS_SEPARATOR_MENU_ITEM (child) && - !gtk_menu_item_get_submenu (GTK_MENU_ITEM (child))) - { - GtkWidget *view = gtk_bin_get_child (GTK_BIN (child)); + if (!GTK_IS_SEPARATOR_MENU_ITEM (child) && + !gtk_menu_item_get_submenu (GTK_MENU_ITEM (child))) + { + GtkWidget *view = gtk_bin_get_child (GTK_BIN (child)); - /* It's always a cellview */ - if (GTK_IS_CELL_VIEW (view)) - path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (view)); - } + /* It's always a cellview */ + if (GTK_IS_CELL_VIEW (view)) + path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (view)); + } if (path) - { - if (gtk_tree_path_compare (parent_path, path) == 0) - item = child; + { + if (gtk_tree_path_compare (parent_path, path) == 0) + item = child; - gtk_tree_path_free (path); - } + gtk_tree_path_free (path); + } } g_list_free (children); @@ -835,22 +840,22 @@ find_empty_submenu (GtkTreeMenu *menu) /* Separators dont get submenus, if it already has a submenu then let * the submenu handle inserted rows */ if (!GTK_IS_SEPARATOR_MENU_ITEM (child) && !GTK_IS_TEAROFF_MENU_ITEM (child)) - { - GtkWidget *view = gtk_bin_get_child (GTK_BIN (child)); + { + GtkWidget *view = gtk_bin_get_child (GTK_BIN (child)); - /* It's always a cellview */ - if (GTK_IS_CELL_VIEW (view)) - path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (view)); - } + /* It's always a cellview */ + if (GTK_IS_CELL_VIEW (view)) + path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (view)); + } if (path) - { - if (gtk_tree_model_get_iter (priv->model, &iter, path) && - !gtk_tree_model_iter_has_child (priv->model, &iter)) - submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (child)); + { + if (gtk_tree_model_get_iter (priv->model, &iter, path) && + !gtk_tree_model_iter_has_child (priv->model, &iter)) + submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (child)); - gtk_tree_path_free (path); - } + gtk_tree_path_free (path); + } } g_list_free (children); @@ -860,9 +865,9 @@ find_empty_submenu (GtkTreeMenu *menu) static void row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - GtkTreeMenu *menu) + GtkTreePath *path, + GtkTreeIter *iter, + GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv = menu->priv; gint *indices, index, depth; @@ -872,56 +877,56 @@ row_inserted_cb (GtkTreeModel *model, if (gtk_tree_menu_path_in_menu (menu, path, NULL)) { if (priv->wrap_width > 0) - rebuild_menu (menu); + rebuild_menu (menu); else - { - /* Get the index of the path for this depth */ - indices = gtk_tree_path_get_indices (path); - depth = gtk_tree_path_get_depth (path); - index = indices[depth -1]; - - /* Menus with a header include a menuitem for it's root node - * and a separator menu item */ - if (priv->menu_with_header) - index += 2; - - /* Index after the tearoff item for the root menu if - * there is a tearoff item - */ - if (priv->root == NULL && priv->tearoff) - index += 1; - - item = gtk_tree_menu_create_item (menu, iter, FALSE); - gtk_menu_shell_insert (GTK_MENU_SHELL (menu), item, index); - - /* Resize everything */ - gtk_cell_area_context_reset (menu->priv->context); - } + { + /* Get the index of the path for this depth */ + indices = gtk_tree_path_get_indices (path); + depth = gtk_tree_path_get_depth (path); + index = indices[depth -1]; + + /* Menus with a header include a menuitem for its root node + * and a separator menu item */ + if (priv->menu_with_header) + index += 2; + + /* Index after the tearoff item for the root menu if + * there is a tearoff item + */ + if (priv->root == NULL && priv->tearoff) + index += 1; + + item = gtk_tree_menu_create_item (menu, iter, FALSE); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), item, index); + + /* Resize everything */ + gtk_cell_area_context_reset (menu->priv->context); + } } else { /* Create submenus for iters if we need to */ item = gtk_tree_menu_path_needs_submenu (menu, path); if (item) - { - GtkTreePath *item_path = gtk_tree_path_copy (path); + { + GtkTreePath *item_path = gtk_tree_path_copy (path); - gtk_tree_path_up (item_path); - gtk_tree_menu_create_submenu (menu, item, item_path); - gtk_tree_path_free (item_path); - } + gtk_tree_path_up (item_path); + gtk_tree_menu_create_submenu (menu, item, item_path); + gtk_tree_path_free (item_path); + } } } static void row_deleted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeMenu *menu) + GtkTreePath *path, + GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv = menu->priv; GtkWidget *item; - /* If it's the header item we leave it to the parent menu + /* If it's the header item we leave it to the parent menu * to remove us from its menu */ item = gtk_tree_menu_get_path_item (menu, path); @@ -929,45 +934,45 @@ row_deleted_cb (GtkTreeModel *model, if (item) { if (priv->wrap_width > 0) - rebuild_menu (menu); + rebuild_menu (menu); else - { - /* Get rid of the deleted item */ - gtk_widget_destroy (item); - - /* Resize everything */ - gtk_cell_area_context_reset (menu->priv->context); - } + { + /* Get rid of the deleted item */ + gtk_widget_destroy (item); + + /* Resize everything */ + gtk_cell_area_context_reset (menu->priv->context); + } } - else + else { /* It's up to the parent menu to destroy a child menu that becomes empty * since the topmost menu belongs to the user and is allowed to have no contents */ GtkWidget *submenu = find_empty_submenu (menu); if (submenu) - gtk_widget_destroy (submenu); + gtk_widget_destroy (submenu); } } static void row_reordered_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gint *new_order, - GtkTreeMenu *menu) + GtkTreePath *path, + GtkTreeIter *iter, + gint *new_order, + GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv = menu->priv; gboolean this_menu = FALSE; - if (path == NULL && priv->root == NULL) + if (gtk_tree_path_get_depth (path) == 0 && !priv->root) this_menu = TRUE; else if (priv->root) { GtkTreePath *root_path = - gtk_tree_row_reference_get_path (priv->root); + gtk_tree_row_reference_get_path (priv->root); if (gtk_tree_path_compare (root_path, path) == 0) - this_menu = TRUE; + this_menu = TRUE; gtk_tree_path_free (root_path); } @@ -976,9 +981,9 @@ row_reordered_cb (GtkTreeModel *model, rebuild_menu (menu); } -static gint +static gint menu_item_position (GtkTreeMenu *menu, - GtkWidget *item) + GtkWidget *item) { GList *children, *l; gint position; @@ -989,7 +994,7 @@ menu_item_position (GtkTreeMenu *menu, GtkWidget *iitem = l->data; if (item == iitem) - break; + break; } g_list_free (children); @@ -999,9 +1004,9 @@ menu_item_position (GtkTreeMenu *menu, static void row_changed_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - GtkTreeMenu *menu) + GtkTreePath *path, + GtkTreeIter *iter, + GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv = menu->priv; gboolean is_separator = FALSE; @@ -1013,69 +1018,69 @@ row_changed_cb (GtkTreeModel *model, if (priv->root) { GtkTreePath *root_path = - gtk_tree_row_reference_get_path (priv->root); - + gtk_tree_row_reference_get_path (priv->root); + if (root_path && gtk_tree_path_compare (root_path, path) == 0) - { - if (priv->header_func) - has_header = - priv->header_func (priv->model, iter, priv->header_data); - - if (has_header && !item) - { - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item); - - item = gtk_tree_menu_create_item (menu, iter, TRUE); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item); - - priv->menu_with_header = TRUE; - } - else if (!has_header && item) - { - /* Destroy the header item and then the following separator */ - gtk_widget_destroy (item); - gtk_widget_destroy (GTK_MENU_SHELL (menu)->children->data); - - priv->menu_with_header = FALSE; - } - - gtk_tree_path_free (root_path); - } + { + if (priv->header_func) + has_header = + priv->header_func (priv->model, iter, priv->header_data); + + if (has_header && !item) + { + item = gtk_separator_menu_item_new (); + gtk_widget_show (item); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item); + + item = gtk_tree_menu_create_item (menu, iter, TRUE); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item); + + priv->menu_with_header = TRUE; + } + else if (!has_header && item) + { + /* Destroy the header item and then the following separator */ + gtk_widget_destroy (item); + gtk_widget_destroy (GTK_MENU_SHELL (menu)->priv->children->data); + + priv->menu_with_header = FALSE; + } + + gtk_tree_path_free (root_path); + } } - + if (item) { if (priv->wrap_width > 0) - /* Ugly, we need to rebuild the menu here if - * the row-span/row-column values change - */ - rebuild_menu (menu); + /* Ugly, we need to rebuild the menu here if + * the row-span/row-column values change + */ + rebuild_menu (menu); else - { - if (priv->row_separator_func) - is_separator = - priv->row_separator_func (model, iter, - priv->row_separator_data); - - - if (is_separator != GTK_IS_SEPARATOR_MENU_ITEM (item)) - { - gint position = menu_item_position (menu, item); - - gtk_widget_destroy (item); - item = gtk_tree_menu_create_item (menu, iter, FALSE); - gtk_menu_shell_insert (GTK_MENU_SHELL (menu), item, position); - } - } + { + if (priv->row_separator_func) + is_separator = + priv->row_separator_func (model, iter, + priv->row_separator_data); + + + if (is_separator != GTK_IS_SEPARATOR_MENU_ITEM (item)) + { + gint position = menu_item_position (menu, item); + + gtk_widget_destroy (item); + item = gtk_tree_menu_create_item (menu, iter, FALSE); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), item, position); + } + } } } static void context_size_changed_cb (GtkCellAreaContext *context, - GParamSpec *pspec, - GtkWidget *menu) + GParamSpec *pspec, + GtkWidget *menu) { if (!strcmp (pspec->name, "minimum-width") || !strcmp (pspec->name, "natural-width") || @@ -1089,15 +1094,15 @@ area_is_sensitive (GtkCellArea *area) { GList *cells, *list; gboolean sensitive = FALSE; - + cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area)); for (list = cells; list; list = list->next) { g_object_get (list->data, "sensitive", &sensitive, NULL); - + if (sensitive) - break; + break; } g_list_free (cells); @@ -1106,11 +1111,11 @@ area_is_sensitive (GtkCellArea *area) static void area_apply_attributes_cb (GtkCellArea *area, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gboolean is_expander, - gboolean is_expanded, - GtkTreeMenu *menu) + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gboolean is_expander, + gboolean is_expanded, + GtkTreeMenu *menu) { /* If the menu for this iter has a submenu */ GtkTreeMenuPrivate *priv = menu->priv; @@ -1128,26 +1133,26 @@ area_apply_attributes_cb (GtkCellArea *area, /* If there is no submenu, go ahead and update item sensitivity, * items with submenus are always sensitive */ if (item && !gtk_menu_item_get_submenu (GTK_MENU_ITEM (item))) - { - sensitive = area_is_sensitive (priv->area); - - gtk_widget_set_sensitive (item, sensitive); - - if (is_header) - { - /* For header items we need to set the sensitivity - * of the following separator item - */ - if (GTK_MENU_SHELL (menu)->children && - GTK_MENU_SHELL (menu)->children->next) - { - GtkWidget *separator = - GTK_MENU_SHELL (menu)->children->next->data; - - gtk_widget_set_sensitive (separator, sensitive); - } - } - } + { + sensitive = area_is_sensitive (priv->area); + + gtk_widget_set_sensitive (item, sensitive); + + if (is_header) + { + /* For header items we need to set the sensitivity + * of the following separator item + */ + if (GTK_MENU_SHELL (menu)->priv->children && + GTK_MENU_SHELL (menu)->priv->children->next) + { + GtkWidget *separator = + GTK_MENU_SHELL (menu)->priv->children->next->data; + + gtk_widget_set_sensitive (separator, sensitive); + } + } + } } gtk_tree_path_free (path); @@ -1155,14 +1160,14 @@ area_apply_attributes_cb (GtkCellArea *area, static void gtk_tree_menu_set_area (GtkTreeMenu *menu, - GtkCellArea *area) + GtkCellArea *area) { GtkTreeMenuPrivate *priv = menu->priv; if (priv->area) { g_signal_handler_disconnect (priv->area, - priv->apply_attributes_id); + priv->apply_attributes_id); priv->apply_attributes_id = 0; g_object_unref (priv->area); @@ -1175,8 +1180,8 @@ gtk_tree_menu_set_area (GtkTreeMenu *menu, g_object_ref_sink (priv->area); priv->apply_attributes_id = - g_signal_connect (priv->area, "apply-attributes", - G_CALLBACK (area_apply_attributes_cb), menu); + g_signal_connect (priv->area, "apply-attributes", + G_CALLBACK (area_apply_attributes_cb), menu); } } @@ -1189,12 +1194,12 @@ menu_occupied (GtkTreeMenu *menu, { GList *i; - for (i = GTK_MENU_SHELL (menu)->children; i; i = i->next) + for (i = GTK_MENU_SHELL (menu)->priv->children; i; i = i->next) { guint l, r, b, t; - gtk_container_child_get (GTK_CONTAINER (menu), - i->data, + gtk_container_child_get (GTK_CONTAINER (menu), + i->data, "left-attach", &l, "right-attach", &r, "bottom-attach", &b, @@ -1203,7 +1208,7 @@ menu_occupied (GtkTreeMenu *menu, /* look if this item intersects with the given coordinates */ if (right_attach > l && left_attach < r && bottom_attach > t && top_attach < b) - return TRUE; + return TRUE; } return FALSE; @@ -1211,54 +1216,54 @@ menu_occupied (GtkTreeMenu *menu, static void relayout_item (GtkTreeMenu *menu, - GtkWidget *item, - GtkTreeIter *iter, - GtkWidget *prev) + GtkWidget *item, + GtkTreeIter *iter, + GtkWidget *prev) { GtkTreeMenuPrivate *priv = menu->priv; gint current_col = 0, current_row = 0; gint rows = 1, cols = 1; - + if (priv->col_span_col == -1 && priv->row_span_col == -1 && prev) { gtk_container_child_get (GTK_CONTAINER (menu), prev, - "right-attach", ¤t_col, - "top-attach", ¤t_row, - NULL); + "right-attach", ¤t_col, + "top-attach", ¤t_row, + NULL); if (current_col + cols > priv->wrap_width) - { - current_col = 0; - current_row++; - } + { + current_col = 0; + current_row++; + } } else { if (priv->col_span_col != -1) - gtk_tree_model_get (priv->model, iter, - priv->col_span_col, &cols, - -1); + gtk_tree_model_get (priv->model, iter, + priv->col_span_col, &cols, + -1); if (priv->row_span_col != -1) - gtk_tree_model_get (priv->model, iter, - priv->row_span_col, &rows, - -1); + gtk_tree_model_get (priv->model, iter, + priv->row_span_col, &rows, + -1); while (1) - { - if (current_col + cols > priv->wrap_width) - { - current_col = 0; - current_row++; - } - - if (!menu_occupied (menu, - current_col, current_col + cols, - current_row, current_row + rows)) - break; - - current_col++; - } + { + if (current_col + cols > priv->wrap_width) + { + current_col = 0; + current_row++; + } + + if (!menu_occupied (menu, + current_col, current_col + cols, + current_row, current_row + rows)) + break; + + current_col++; + } } /* set attach props */ @@ -1269,8 +1274,8 @@ relayout_item (GtkTreeMenu *menu, static void gtk_tree_menu_create_submenu (GtkTreeMenu *menu, - GtkWidget *item, - GtkTreePath *path) + GtkWidget *item, + GtkTreePath *path) { GtkTreeMenuPrivate *priv = menu->priv; GtkWidget *view; @@ -1279,33 +1284,33 @@ gtk_tree_menu_create_submenu (GtkTreeMenu *menu, view = gtk_bin_get_child (GTK_BIN (item)); gtk_cell_view_set_draw_sensitive (GTK_CELL_VIEW (view), TRUE); - submenu = gtk_tree_menu_new_with_area (priv->area); - - gtk_tree_menu_set_row_separator_func (GTK_TREE_MENU (submenu), - priv->row_separator_func, - priv->row_separator_data, - priv->row_separator_destroy); - gtk_tree_menu_set_header_func (GTK_TREE_MENU (submenu), - priv->header_func, - priv->header_data, - priv->header_destroy); - - gtk_tree_menu_set_wrap_width (GTK_TREE_MENU (submenu), priv->wrap_width); - gtk_tree_menu_set_row_span_column (GTK_TREE_MENU (submenu), priv->row_span_col); - gtk_tree_menu_set_column_span_column (GTK_TREE_MENU (submenu), priv->col_span_col); - + submenu = _gtk_tree_menu_new_with_area (priv->area); + + _gtk_tree_menu_set_row_separator_func (GTK_TREE_MENU (submenu), + priv->row_separator_func, + priv->row_separator_data, + priv->row_separator_destroy); + _gtk_tree_menu_set_header_func (GTK_TREE_MENU (submenu), + priv->header_func, + priv->header_data, + priv->header_destroy); + + _gtk_tree_menu_set_wrap_width (GTK_TREE_MENU (submenu), priv->wrap_width); + _gtk_tree_menu_set_row_span_column (GTK_TREE_MENU (submenu), priv->row_span_col); + _gtk_tree_menu_set_column_span_column (GTK_TREE_MENU (submenu), priv->col_span_col); + gtk_tree_menu_set_model_internal (GTK_TREE_MENU (submenu), priv->model); - gtk_tree_menu_set_root (GTK_TREE_MENU (submenu), path); + _gtk_tree_menu_set_root (GTK_TREE_MENU (submenu), path); gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - - g_signal_connect (submenu, "menu-activate", - G_CALLBACK (submenu_activated_cb), menu); + + g_signal_connect (submenu, "menu-activate", + G_CALLBACK (submenu_activated_cb), menu); } static GtkWidget * gtk_tree_menu_create_item (GtkTreeMenu *menu, - GtkTreeIter *iter, - gboolean header_item) + GtkTreeIter *iter, + gboolean header_item) { GtkTreeMenuPrivate *priv = menu->priv; GtkWidget *item, *view; @@ -1315,9 +1320,9 @@ gtk_tree_menu_create_item (GtkTreeMenu *menu, path = gtk_tree_model_get_path (priv->model, iter); if (priv->row_separator_func) - is_separator = + is_separator = priv->row_separator_func (priv->model, iter, - priv->row_separator_data); + priv->row_separator_data); if (is_separator) { @@ -1325,9 +1330,9 @@ gtk_tree_menu_create_item (GtkTreeMenu *menu, gtk_widget_show (item); g_object_set_qdata_full (G_OBJECT (item), - tree_menu_path_quark, - gtk_tree_row_reference_new (priv->model, path), - (GDestroyNotify)gtk_tree_row_reference_free); + tree_menu_path_quark, + gtk_tree_row_reference_new (priv->model, path), + (GDestroyNotify)gtk_tree_row_reference_free); } else { @@ -1335,19 +1340,19 @@ gtk_tree_menu_create_item (GtkTreeMenu *menu, item = gtk_menu_item_new (); gtk_widget_show (view); gtk_widget_show (item); - + gtk_cell_view_set_model (GTK_CELL_VIEW (view), priv->model); gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (view), path); - + gtk_widget_show (view); gtk_container_add (GTK_CONTAINER (item), view); - + g_signal_connect (item, "activate", G_CALLBACK (item_activated_cb), menu); /* Add a GtkTreeMenu submenu to render the children of this row */ if (header_item == FALSE && - gtk_tree_model_iter_has_child (priv->model, iter)) - gtk_tree_menu_create_submenu (menu, item, path); + gtk_tree_model_iter_has_child (priv->model, iter)) + gtk_tree_menu_create_submenu (menu, item, path); } gtk_tree_path_free (path); @@ -1355,15 +1360,15 @@ gtk_tree_menu_create_item (GtkTreeMenu *menu, return item; } -static inline void +static inline void rebuild_menu (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv = menu->priv; /* Destroy all the menu items */ - gtk_container_foreach (GTK_CONTAINER (menu), - (GtkCallback) gtk_widget_destroy, NULL); - + gtk_container_foreach (GTK_CONTAINER (menu), + (GtkCallback) gtk_widget_destroy, NULL); + /* Populate */ if (priv->model) gtk_tree_menu_populate (menu); @@ -1389,43 +1394,43 @@ gtk_tree_menu_populate (GtkTreeMenu *menu) if (path) { if (gtk_tree_model_get_iter (priv->model, &parent, path)) - { - valid = gtk_tree_model_iter_children (priv->model, &iter, &parent); - - if (priv->header_func && - priv->header_func (priv->model, &parent, priv->header_data)) - { - /* Add a submenu header for rows which desire one, used for - * combo boxes to allow all rows to be activatable/selectable - */ - menu_item = gtk_tree_menu_create_item (menu, &parent, TRUE); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - - menu_item = gtk_separator_menu_item_new (); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - - prev = menu_item; - priv->menu_with_header = TRUE; - } - } + { + valid = gtk_tree_model_iter_children (priv->model, &iter, &parent); + + if (priv->header_func && + priv->header_func (priv->model, &parent, priv->header_data)) + { + /* Add a submenu header for rows which desire one, used for + * combo boxes to allow all rows to be activatable/selectable + */ + menu_item = gtk_tree_menu_create_item (menu, &parent, TRUE); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + + menu_item = gtk_separator_menu_item_new (); + gtk_widget_show (menu_item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + + prev = menu_item; + priv->menu_with_header = TRUE; + } + } gtk_tree_path_free (path); } else { /* Tearoff menu items only go in the root menu */ if (priv->tearoff) - { - menu_item = gtk_tearoff_menu_item_new (); - gtk_widget_show (menu_item); + { + menu_item = gtk_tearoff_menu_item_new (); + gtk_widget_show (menu_item); - if (priv->wrap_width > 0) - gtk_menu_attach (GTK_MENU (menu), menu_item, 0, priv->wrap_width, 0, 1); - else - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + if (priv->wrap_width > 0) + gtk_menu_attach (GTK_MENU (menu), menu_item, 0, priv->wrap_width, 0, 1); + else + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - prev = menu_item; - } + prev = menu_item; + } valid = gtk_tree_model_iter_children (priv->model, &iter, NULL); } @@ -1439,7 +1444,7 @@ gtk_tree_menu_populate (GtkTreeMenu *menu) gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); if (priv->wrap_width > 0) - relayout_item (menu, menu_item, &iter, prev); + relayout_item (menu, menu_item, &iter, prev); prev = menu_item; valid = gtk_tree_model_iter_next (priv->model, &iter); @@ -1448,7 +1453,7 @@ gtk_tree_menu_populate (GtkTreeMenu *menu) static void item_activated_cb (GtkMenuItem *item, - GtkTreeMenu *menu) + GtkTreeMenu *menu) { GtkCellView *view; GtkTreePath *path; @@ -1460,9 +1465,9 @@ item_activated_cb (GtkMenuItem *item, view = GTK_CELL_VIEW (gtk_bin_get_child (GTK_BIN (item))); path = gtk_cell_view_get_displayed_row (view); path_str = gtk_tree_path_to_string (path); - + g_signal_emit (menu, tree_menu_signals[SIGNAL_MENU_ACTIVATE], 0, path_str); - + g_free (path_str); gtk_tree_path_free (path); } @@ -1470,8 +1475,8 @@ item_activated_cb (GtkMenuItem *item, static void submenu_activated_cb (GtkTreeMenu *submenu, - const gchar *path, - GtkTreeMenu *menu) + const gchar *path, + GtkTreeMenu *menu) { g_signal_emit (menu, tree_menu_signals[SIGNAL_MENU_ACTIVATE], 0, path); } @@ -1481,7 +1486,7 @@ submenu_activated_cb (GtkTreeMenu *submenu, * until the root is set and then build the menu) */ static void gtk_tree_menu_set_model_internal (GtkTreeMenu *menu, - GtkTreeModel *model) + GtkTreeModel *model) { GtkTreeMenuPrivate *priv; @@ -1490,40 +1495,40 @@ gtk_tree_menu_set_model_internal (GtkTreeMenu *menu, if (priv->model != model) { if (priv->model) - { - /* Disconnect signals */ - g_signal_handler_disconnect (priv->model, - priv->row_inserted_id); - g_signal_handler_disconnect (priv->model, - priv->row_deleted_id); - g_signal_handler_disconnect (priv->model, - priv->row_reordered_id); - g_signal_handler_disconnect (priv->model, - priv->row_changed_id); - priv->row_inserted_id = 0; - priv->row_deleted_id = 0; - priv->row_reordered_id = 0; - priv->row_changed_id = 0; - - g_object_unref (priv->model); - } + { + /* Disconnect signals */ + g_signal_handler_disconnect (priv->model, + priv->row_inserted_id); + g_signal_handler_disconnect (priv->model, + priv->row_deleted_id); + g_signal_handler_disconnect (priv->model, + priv->row_reordered_id); + g_signal_handler_disconnect (priv->model, + priv->row_changed_id); + priv->row_inserted_id = 0; + priv->row_deleted_id = 0; + priv->row_reordered_id = 0; + priv->row_changed_id = 0; + + g_object_unref (priv->model); + } priv->model = model; if (priv->model) - { - g_object_ref (priv->model); - - /* Connect signals */ - priv->row_inserted_id = g_signal_connect (priv->model, "row-inserted", - G_CALLBACK (row_inserted_cb), menu); - priv->row_deleted_id = g_signal_connect (priv->model, "row-deleted", - G_CALLBACK (row_deleted_cb), menu); - priv->row_reordered_id = g_signal_connect (priv->model, "rows-reordered", - G_CALLBACK (row_reordered_cb), menu); - priv->row_changed_id = g_signal_connect (priv->model, "row-changed", - G_CALLBACK (row_changed_cb), menu); - } + { + g_object_ref (priv->model); + + /* Connect signals */ + priv->row_inserted_id = g_signal_connect (priv->model, "row-inserted", + G_CALLBACK (row_inserted_cb), menu); + priv->row_deleted_id = g_signal_connect (priv->model, "row-deleted", + G_CALLBACK (row_deleted_cb), menu); + priv->row_reordered_id = g_signal_connect (priv->model, "rows-reordered", + G_CALLBACK (row_reordered_cb), menu); + priv->row_changed_id = g_signal_connect (priv->model, "row-changed", + G_CALLBACK (row_changed_cb), menu); + } } } @@ -1532,7 +1537,7 @@ gtk_tree_menu_set_model_internal (GtkTreeMenu *menu, ****************************************************************/ /** - * gtk_tree_menu_new: + * _gtk_tree_menu_new: * * Creates a new #GtkTreeMenu. * @@ -1541,55 +1546,55 @@ gtk_tree_menu_set_model_internal (GtkTreeMenu *menu, * Since: 3.0 */ GtkWidget * -gtk_tree_menu_new (void) +_gtk_tree_menu_new (void) { return (GtkWidget *)g_object_new (GTK_TYPE_TREE_MENU, NULL); } -/** - * gtk_tree_menu_new_with_area: +/* + * _gtk_tree_menu_new_with_area: * @area: the #GtkCellArea to use to render cells in the menu * - * Creates a new #GtkTreeMenu using @area to render it's cells. + * Creates a new #GtkTreeMenu using @area to render its cells. * * Return value: A newly created #GtkTreeMenu with no model or root. * * Since: 3.0 */ GtkWidget * -gtk_tree_menu_new_with_area (GtkCellArea *area) +_gtk_tree_menu_new_with_area (GtkCellArea *area) { - return (GtkWidget *)g_object_new (GTK_TYPE_TREE_MENU, - "cell-area", area, - NULL); + return (GtkWidget *)g_object_new (GTK_TYPE_TREE_MENU, + "cell-area", area, + NULL); } -/** - * gtk_tree_menu_new_full: +/* + * _gtk_tree_menu_new_full: * @area: (allow-none): the #GtkCellArea to use to render cells in the menu, or %NULL. * @model: (allow-none): the #GtkTreeModel to build the menu heirarchy from, or %NULL. * @root: (allow-none): the #GtkTreePath indicating the root row for this menu, or %NULL. * - * Creates a new #GtkTreeMenu hierarchy from the provided @model and @root using @area to render it's cells. + * Creates a new #GtkTreeMenu hierarchy from the provided @model and @root using @area to render its cells. * * Return value: A newly created #GtkTreeMenu. * * Since: 3.0 */ GtkWidget * -gtk_tree_menu_new_full (GtkCellArea *area, - GtkTreeModel *model, - GtkTreePath *root) +_gtk_tree_menu_new_full (GtkCellArea *area, + GtkTreeModel *model, + GtkTreePath *root) { - return (GtkWidget *)g_object_new (GTK_TYPE_TREE_MENU, - "cell-area", area, - "model", model, - "root", root, - NULL); + return (GtkWidget *)g_object_new (GTK_TYPE_TREE_MENU, + "cell-area", area, + "model", model, + "root", root, + NULL); } -/** - * gtk_tree_menu_set_model: +/* + * _gtk_tree_menu_set_model: * @menu: a #GtkTreeMenu * @model: (allow-none): the #GtkTreeModel to build the menu hierarchy from, or %NULL. * @@ -1598,8 +1603,8 @@ gtk_tree_menu_new_full (GtkCellArea *area, * Since: 3.0 */ void -gtk_tree_menu_set_model (GtkTreeMenu *menu, - GtkTreeModel *model) +_gtk_tree_menu_set_model (GtkTreeMenu *menu, + GtkTreeModel *model) { g_return_if_fail (GTK_IS_TREE_MENU (menu)); g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model)); @@ -1609,8 +1614,8 @@ gtk_tree_menu_set_model (GtkTreeMenu *menu, rebuild_menu (menu); } -/** - * gtk_tree_menu_get_model: +/* + * _gtk_tree_menu_get_model: * @menu: a #GtkTreeMenu * * Gets the @model currently used for the menu heirarhcy. @@ -1621,7 +1626,7 @@ gtk_tree_menu_set_model (GtkTreeMenu *menu, * Since: 3.0 */ GtkTreeModel * -gtk_tree_menu_get_model (GtkTreeMenu *menu) +_gtk_tree_menu_get_model (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1632,8 +1637,8 @@ gtk_tree_menu_get_model (GtkTreeMenu *menu) return priv->model; } -/** - * gtk_tree_menu_set_root: +/* + * _gtk_tree_menu_set_root: * @menu: a #GtkTreeMenu * @path: (allow-none): the #GtkTreePath which is the root of @menu, or %NULL. * @@ -1643,8 +1648,8 @@ gtk_tree_menu_get_model (GtkTreeMenu *menu) * Since: 3.0 */ void -gtk_tree_menu_set_root (GtkTreeMenu *menu, - GtkTreePath *path) +_gtk_tree_menu_set_root (GtkTreeMenu *menu, + GtkTreePath *path) { GtkTreeMenuPrivate *priv; @@ -1653,7 +1658,7 @@ gtk_tree_menu_set_root (GtkTreeMenu *menu, priv = menu->priv; - if (priv->root) + if (priv->root) gtk_tree_row_reference_free (priv->root); if (path) @@ -1664,8 +1669,8 @@ gtk_tree_menu_set_root (GtkTreeMenu *menu, rebuild_menu (menu); } -/** - * gtk_tree_menu_get_root: +/* + * _gtk_tree_menu_get_root: * @menu: a #GtkTreeMenu * * Gets the @root path for @menu's hierarchy, or returns %NULL if @menu @@ -1677,7 +1682,7 @@ gtk_tree_menu_set_root (GtkTreeMenu *menu, * Since: 3.0 */ GtkTreePath * -gtk_tree_menu_get_root (GtkTreeMenu *menu) +_gtk_tree_menu_get_root (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1691,8 +1696,8 @@ gtk_tree_menu_get_root (GtkTreeMenu *menu) return NULL; } -/** - * gtk_tree_menu_get_tearoff: +/* + * _gtk_tree_menu_get_tearoff: * @menu: a #GtkTreeMenu * * Gets whether this menu is build with a leading tearoff menu item. @@ -1702,7 +1707,7 @@ gtk_tree_menu_get_root (GtkTreeMenu *menu) * Since: 3.0 */ gboolean -gtk_tree_menu_get_tearoff (GtkTreeMenu *menu) +_gtk_tree_menu_get_tearoff (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1713,8 +1718,8 @@ gtk_tree_menu_get_tearoff (GtkTreeMenu *menu) return priv->tearoff; } -/** - * gtk_tree_menu_set_tearoff: +/* + * _gtk_tree_menu_set_tearoff: * @menu: a #GtkTreeMenu * @tearoff: whether the menu should have a leading tearoff menu item. * @@ -1723,8 +1728,8 @@ gtk_tree_menu_get_tearoff (GtkTreeMenu *menu) * Since: 3.0 */ void -gtk_tree_menu_set_tearoff (GtkTreeMenu *menu, - gboolean tearoff) +_gtk_tree_menu_set_tearoff (GtkTreeMenu *menu, + gboolean tearoff) { GtkTreeMenuPrivate *priv; @@ -1742,11 +1747,11 @@ gtk_tree_menu_set_tearoff (GtkTreeMenu *menu, } } -/** - * gtk_tree_menu_get_wrap_width: +/* + * _gtk_tree_menu_get_wrap_width: * @menu: a #GtkTreeMenu * - * Gets the wrap width which is used to determine the number of columns + * Gets the wrap width which is used to determine the number of columns * for @menu. If the wrap width is larger than 1, @menu is in table mode. * * Return value: the wrap width. @@ -1754,7 +1759,7 @@ gtk_tree_menu_set_tearoff (GtkTreeMenu *menu, * Since: 3.0 */ gint -gtk_tree_menu_get_wrap_width (GtkTreeMenu *menu) +_gtk_tree_menu_get_wrap_width (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1765,19 +1770,19 @@ gtk_tree_menu_get_wrap_width (GtkTreeMenu *menu) return priv->wrap_width; } -/** - * gtk_tree_menu_set_wrap_width: +/* + * _gtk_tree_menu_set_wrap_width: * @menu: a #GtkTreeMenu * @width: the wrap width * - * Sets the wrap width which is used to determine the number of columns + * Sets the wrap width which is used to determine the number of columns * for @menu. If the wrap width is larger than 1, @menu is in table mode. * * Since: 3.0 */ void -gtk_tree_menu_set_wrap_width (GtkTreeMenu *menu, - gint width) +_gtk_tree_menu_set_wrap_width (GtkTreeMenu *menu, + gint width) { GtkTreeMenuPrivate *priv; @@ -1796,8 +1801,8 @@ gtk_tree_menu_set_wrap_width (GtkTreeMenu *menu, } } -/** - * gtk_tree_menu_get_row_span_column: +/* + * _gtk_tree_menu_get_row_span_column: * @menu: a #GtkTreeMenu * * Gets the column with row span information for @menu. @@ -1809,7 +1814,7 @@ gtk_tree_menu_set_wrap_width (GtkTreeMenu *menu, * Since: 3.0 */ gint -gtk_tree_menu_get_row_span_column (GtkTreeMenu *menu) +_gtk_tree_menu_get_row_span_column (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1820,8 +1825,8 @@ gtk_tree_menu_get_row_span_column (GtkTreeMenu *menu) return priv->row_span_col; } -/** - * gtk_tree_menu_set_row_span_column: +/* + * _gtk_tree_menu_set_row_span_column: * @menu: a #GtkTreeMenu * @row_span: the column in the model to fetch the row span for a given menu item. * @@ -1832,8 +1837,8 @@ gtk_tree_menu_get_row_span_column (GtkTreeMenu *menu) * Since: 3.0 */ void -gtk_tree_menu_set_row_span_column (GtkTreeMenu *menu, - gint row_span) +_gtk_tree_menu_set_row_span_column (GtkTreeMenu *menu, + gint row_span) { GtkTreeMenuPrivate *priv; @@ -1846,14 +1851,14 @@ gtk_tree_menu_set_row_span_column (GtkTreeMenu *menu, priv->row_span_col = row_span; if (priv->wrap_width > 0) - rebuild_menu (menu); + rebuild_menu (menu); g_object_notify (G_OBJECT (menu), "row-span-column"); } } -/** - * gtk_tree_menu_get_column_span_column: +/* + * _gtk_tree_menu_get_column_span_column: * @menu: a #GtkTreeMenu * * Gets the column with column span information for @menu. @@ -1865,7 +1870,7 @@ gtk_tree_menu_set_row_span_column (GtkTreeMenu *menu, * Since: 3.0 */ gint -gtk_tree_menu_get_column_span_column (GtkTreeMenu *menu) +_gtk_tree_menu_get_column_span_column (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1876,8 +1881,8 @@ gtk_tree_menu_get_column_span_column (GtkTreeMenu *menu) return priv->col_span_col; } -/** - * gtk_tree_menu_set_column_span_column: +/* + * _gtk_tree_menu_set_column_span_column: * @menu: a #GtkTreeMenu * @column_span: the column in the model to fetch the column span for a given menu item. * @@ -1888,8 +1893,8 @@ gtk_tree_menu_get_column_span_column (GtkTreeMenu *menu) * Since: 3.0 */ void -gtk_tree_menu_set_column_span_column (GtkTreeMenu *menu, - gint column_span) +_gtk_tree_menu_set_column_span_column (GtkTreeMenu *menu, + gint column_span) { GtkTreeMenuPrivate *priv; @@ -1902,24 +1907,24 @@ gtk_tree_menu_set_column_span_column (GtkTreeMenu *menu, priv->col_span_col = column_span; if (priv->wrap_width > 0) - rebuild_menu (menu); + rebuild_menu (menu); g_object_notify (G_OBJECT (menu), "column-span-column"); } } -/** - * gtk_tree_menu_get_row_separator_func: +/* + * _gtk_tree_menu_get_row_separator_func: * @menu: a #GtkTreeMenu - * + * * Gets the current #GtkTreeViewRowSeparatorFunc separator function. - * + * * Return value: the current row separator function. * * Since: 3.0 */ GtkTreeViewRowSeparatorFunc -gtk_tree_menu_get_row_separator_func (GtkTreeMenu *menu) +_gtk_tree_menu_get_row_separator_func (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1930,13 +1935,13 @@ gtk_tree_menu_get_row_separator_func (GtkTreeMenu *menu) return priv->row_separator_func; } -/** - * gtk_tree_menu_set_row_separator_func: +/* + * _gtk_tree_menu_set_row_separator_func: * @menu: a #GtkTreeMenu * @func: (allow-none): a #GtkTreeViewRowSeparatorFunc, or %NULL to unset the separator function. * @data: (allow-none): user data to pass to @func, or %NULL * @destroy: (allow-none): destroy notifier for @data, or %NULL - * + * * Sets the row separator function, which is used to determine * whether a row should be drawn as a separator. If the row separator * function is %NULL, no separators are drawn. This is the default value. @@ -1944,10 +1949,10 @@ gtk_tree_menu_get_row_separator_func (GtkTreeMenu *menu) * Since: 3.0 */ void -gtk_tree_menu_set_row_separator_func (GtkTreeMenu *menu, - GtkTreeViewRowSeparatorFunc func, - gpointer data, - GDestroyNotify destroy) +_gtk_tree_menu_set_row_separator_func (GtkTreeMenu *menu, + GtkTreeViewRowSeparatorFunc func, + gpointer data, + GDestroyNotify destroy) { GtkTreeMenuPrivate *priv; @@ -1965,18 +1970,18 @@ gtk_tree_menu_set_row_separator_func (GtkTreeMenu *menu, rebuild_menu (menu); } -/** - * gtk_tree_menu_get_header_func: +/* + * _gtk_tree_menu_get_header_func: * @menu: a #GtkTreeMenu - * + * * Gets the current #GtkTreeMenuHeaderFunc header function. - * + * * Return value: the current header function. * * Since: 3.0 */ GtkTreeMenuHeaderFunc -gtk_tree_menu_get_header_func (GtkTreeMenu *menu) +_gtk_tree_menu_get_header_func (GtkTreeMenu *menu) { GtkTreeMenuPrivate *priv; @@ -1987,27 +1992,27 @@ gtk_tree_menu_get_header_func (GtkTreeMenu *menu) return priv->header_func; } -/** - * gtk_tree_menu_set_header_func: +/* + * _gtk_tree_menu_set_header_func: * @menu: a #GtkTreeMenu * @func: (allow-none): a #GtkTreeMenuHeaderFunc, or %NULL to unset the header function. * @data: (allow-none): user data to pass to @func, or %NULL * @destroy: (allow-none): destroy notifier for @data, or %NULL - * + * * Sets the header function, which is used to determine * whether a row width children should contain a leading header * menu item to allow that row to be selectable as an independant * menu item. If the header function is %NULL, no rows with children - * have menu items which can be activated as leafs. + * have menu items which can be activated as leafs. * This is the default value. * * Since: 3.0 */ void -gtk_tree_menu_set_header_func (GtkTreeMenu *menu, - GtkTreeMenuHeaderFunc func, - gpointer data, - GDestroyNotify destroy) +_gtk_tree_menu_set_header_func (GtkTreeMenu *menu, + GtkTreeMenuHeaderFunc func, + gpointer data, + GDestroyNotify destroy) { GtkTreeMenuPrivate *priv;