Add table menu tests.

2003-09-11  Matthias Clasen  <maclas@gmx.de>

	* tests/testgtk.c: Add table menu tests.

	* gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the
	GtkMenuPrivate struct itself. Pointed out by valgrind.

	* gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up
	properly.  (#121998)
This commit is contained in:
Matthias Clasen
2003-09-11 21:02:24 +00:00
committed by Matthias Clasen
parent fdb5605164
commit 6f81c10a54
8 changed files with 311 additions and 31 deletions

View File

@ -1,3 +1,13 @@
2003-09-11 Matthias Clasen <maclas@gmx.de>
* tests/testgtk.c: Add table menu tests.
* gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the
GtkMenuPrivate struct itself. Pointed out by valgrind.
* gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up
properly. (#121998)
Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org> Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org>
The table menu patch! Turns GtkMenu into a table, so you can attach The table menu patch! Turns GtkMenu into a table, so you can attach

View File

@ -1,3 +1,13 @@
2003-09-11 Matthias Clasen <maclas@gmx.de>
* tests/testgtk.c: Add table menu tests.
* gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the
GtkMenuPrivate struct itself. Pointed out by valgrind.
* gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up
properly. (#121998)
Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org> Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org>
The table menu patch! Turns GtkMenu into a table, so you can attach The table menu patch! Turns GtkMenu into a table, so you can attach

View File

@ -1,3 +1,13 @@
2003-09-11 Matthias Clasen <maclas@gmx.de>
* tests/testgtk.c: Add table menu tests.
* gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the
GtkMenuPrivate struct itself. Pointed out by valgrind.
* gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up
properly. (#121998)
Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org> Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org>
The table menu patch! Turns GtkMenu into a table, so you can attach The table menu patch! Turns GtkMenu into a table, so you can attach

View File

@ -1,3 +1,13 @@
2003-09-11 Matthias Clasen <maclas@gmx.de>
* tests/testgtk.c: Add table menu tests.
* gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the
GtkMenuPrivate struct itself. Pointed out by valgrind.
* gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up
properly. (#121998)
Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org> Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org>
The table menu patch! Turns GtkMenu into a table, so you can attach The table menu patch! Turns GtkMenu into a table, so you can attach

View File

@ -1,3 +1,13 @@
2003-09-11 Matthias Clasen <maclas@gmx.de>
* tests/testgtk.c: Add table menu tests.
* gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the
GtkMenuPrivate struct itself. Pointed out by valgrind.
* gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up
properly. (#121998)
Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org> Wed Sep 10 22:25:04 2003 Kristian Rietveld <kris@gtk.org>
The table menu patch! Turns GtkMenu into a table, so you can attach The table menu patch! Turns GtkMenu into a table, so you can attach

View File

@ -28,6 +28,7 @@
#include <string.h> /* memset */ #include <string.h> /* memset */
#include "gdk/gdkkeysyms.h" #include "gdk/gdkkeysyms.h"
#include "gtkaccellabel.h"
#include "gtkaccelmap.h" #include "gtkaccelmap.h"
#include "gtkbindings.h" #include "gtkbindings.h"
#include "gtklabel.h" #include "gtklabel.h"
@ -226,6 +227,8 @@ gtk_menu_free_private (gpointer data)
GtkMenuPrivate *priv = (GtkMenuPrivate *)data; GtkMenuPrivate *priv = (GtkMenuPrivate *)data;
g_free (priv->heights); g_free (priv->heights);
g_free (priv);
} }
GtkMenuPrivate * GtkMenuPrivate *
@ -2303,6 +2306,41 @@ gtk_menu_button_release (GtkWidget *widget,
return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event); return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
} }
static const gchar *
get_accel_path (GtkWidget *menu_item,
gboolean *locked)
{
const gchar *path;
GtkWidget *label;
GClosure *accel_closure;
GtkAccelGroup *accel_group;
path = _gtk_widget_get_accel_path (menu_item, locked);
if (!path)
{
path = GTK_MENU_ITEM (menu_item)->accel_path;
if (locked)
{
*locked = TRUE;
label = GTK_BIN (menu_item)->child;
if (GTK_IS_ACCEL_LABEL (label))
{
g_object_get (label,
"accel_closure", &accel_closure,
NULL);
accel_group = gtk_accel_group_from_accel_closure (accel_closure);
*locked = accel_group->lock_count > 0;
}
}
}
return path;
}
static gboolean static gboolean
gtk_menu_key_press (GtkWidget *widget, gtk_menu_key_press (GtkWidget *widget,
GdkEventKey *event) GdkEventKey *event)
@ -2397,7 +2435,7 @@ gtk_menu_key_press (GtkWidget *widget,
gboolean locked, replace_accels = TRUE; gboolean locked, replace_accels = TRUE;
const gchar *path; const gchar *path;
path = _gtk_widget_get_accel_path (menu_item, &locked); path = get_accel_path (menu_item, &locked);
if (!path || locked) if (!path || locked)
{ {
/* can't change accelerators on menu_items without paths /* can't change accelerators on menu_items without paths

View File

@ -64,7 +64,7 @@ typedef struct _Node Node;
struct _Node { struct _Node {
NodeType type; NodeType type;
const gchar *name; gchar *name;
GQuark action_name; GQuark action_name;
GtkAction *action; GtkAction *action;
@ -126,6 +126,7 @@ static GNode *get_node (GtkUIManager *self,
const gchar *path, const gchar *path,
NodeType node_type, NodeType node_type,
gboolean create); gboolean create);
static gboolean free_node (GNode *node);
static void node_prepend_ui_reference (Node *node, static void node_prepend_ui_reference (Node *node,
guint merge_id, guint merge_id,
@ -269,10 +270,9 @@ gtk_ui_manager_init (GtkUIManager *self)
self->private_data->last_merge_id = 0; self->private_data->last_merge_id = 0;
self->private_data->add_tearoffs = FALSE; self->private_data->add_tearoffs = FALSE;
merge_id = gtk_ui_manager_new_merge_id (self); merge_id = gtk_ui_manager_new_merge_id (self);
node = get_child_node (self, NULL, "ui", 4, node = get_child_node (self, NULL, "ui", 2,
NODE_TYPE_ROOT, TRUE, FALSE); NODE_TYPE_ROOT, TRUE, FALSE);
node_prepend_ui_reference (NODE_INFO (node), merge_id, 0); node_prepend_ui_reference (NODE_INFO (node), merge_id, 0);
} }
@ -286,6 +286,20 @@ gtk_ui_manager_finalize (GObject *object)
g_source_remove (self->private_data->update_tag); g_source_remove (self->private_data->update_tag);
self->private_data->update_tag = 0; self->private_data->update_tag = 0;
} }
g_node_traverse (self->private_data->root_node,
G_POST_ORDER, G_TRAVERSE_ALL, -1,
(GNodeTraverseFunc)free_node, 0);
g_node_destroy (self->private_data->root_node);
self->private_data->root_node = NULL;
g_list_foreach (self->private_data->action_groups,
(GFunc) g_object_unref, NULL);
g_list_free (self->private_data->action_groups);
self->private_data->action_groups = NULL;
g_object_unref (self->private_data->accel_group);
self->private_data->accel_group = NULL;
} }
static void static void
@ -462,7 +476,7 @@ gtk_ui_manager_remove_action_group (GtkUIManager *self,
* Since: 2.4 * Since: 2.4
**/ **/
GList * GList *
gtk_ui_manager_get_action_groups (GtkUIManager *self) gtk_ui_manager_get_action_groups (GtkUIManager *self)
{ {
g_return_val_if_fail (GTK_IS_UI_MANAGER (self), NULL); g_return_val_if_fail (GTK_IS_UI_MANAGER (self), NULL);
@ -480,7 +494,7 @@ gtk_ui_manager_get_action_groups (GtkUIManager *self)
* Since: 2.4 * Since: 2.4
**/ **/
GtkAccelGroup * GtkAccelGroup *
gtk_ui_manager_get_accel_group (GtkUIManager *self) gtk_ui_manager_get_accel_group (GtkUIManager *self)
{ {
g_return_val_if_fail (GTK_IS_UI_MANAGER (self), NULL); g_return_val_if_fail (GTK_IS_UI_MANAGER (self), NULL);
@ -538,8 +552,8 @@ gtk_ui_manager_get_widget (GtkUIManager *self,
* Since: 2.4 * Since: 2.4
**/ **/
GtkAction * GtkAction *
gtk_ui_manager_get_action (GtkUIManager *self, gtk_ui_manager_get_action (GtkUIManager *self,
const gchar *path) const gchar *path)
{ {
GNode *node; GNode *node;
@ -559,13 +573,13 @@ gtk_ui_manager_get_action (GtkUIManager *self,
} }
static GNode * static GNode *
get_child_node (GtkUIManager *self, get_child_node (GtkUIManager *self,
GNode *parent, GNode *parent,
const gchar *childname, const gchar *childname,
gint childname_length, gint childname_length,
NodeType node_type, NodeType node_type,
gboolean create, gboolean create,
gboolean top) gboolean top)
{ {
GNode *child = NULL; GNode *child = NULL;
@ -644,10 +658,10 @@ get_child_node (GtkUIManager *self,
} }
static GNode * static GNode *
get_node (GtkUIManager *self, get_node (GtkUIManager *self,
const gchar *path, const gchar *path,
NodeType node_type, NodeType node_type,
gboolean create) gboolean create)
{ {
const gchar *pos, *end; const gchar *pos, *end;
GNode *parent, *node; GNode *parent, *node;
@ -677,9 +691,26 @@ get_node (GtkUIManager *self,
if (node != NULL && NODE_INFO (node)->type == NODE_TYPE_UNDECIDED) if (node != NULL && NODE_INFO (node)->type == NODE_TYPE_UNDECIDED)
NODE_INFO (node)->type = node_type; NODE_INFO (node)->type = node_type;
return node; return node;
} }
static gboolean
free_node (GNode *node)
{
Node *info = NODE_INFO (node);
g_list_foreach (info->uifiles, (GFunc) g_free, NULL);
g_list_free (info->uifiles);
if (info->action)
g_object_unref (info->action);
g_free (info->name);
g_chunk_free (info, merge_node_chunk);
return FALSE;
}
/** /**
* gtk_ui_manager_new_merge_id: * gtk_ui_manager_new_merge_id:
* @self: a #GtkUIManager * @self: a #GtkUIManager
@ -700,9 +731,9 @@ gtk_ui_manager_new_merge_id (GtkUIManager *self)
} }
static void static void
node_prepend_ui_reference (Node *node, node_prepend_ui_reference (Node *node,
guint merge_id, guint merge_id,
GQuark action_quark) GQuark action_quark)
{ {
NodeUIReference *reference; NodeUIReference *reference;
@ -717,8 +748,8 @@ node_prepend_ui_reference (Node *node,
} }
static void static void
node_remove_ui_reference (Node *node, node_remove_ui_reference (Node *node,
guint merge_id) guint merge_id)
{ {
GList *p; GList *p;
@ -1900,11 +1931,9 @@ update_node (GtkUIManager *self,
{ {
if (info->proxy) if (info->proxy)
gtk_widget_destroy (info->proxy); gtk_widget_destroy (info->proxy);
if ((info->type == NODE_TYPE_MENU_PLACEHOLDER || if (info->extra)
info->type == NODE_TYPE_TOOLBAR_PLACEHOLDER) &&
info->extra)
gtk_widget_destroy (info->extra); gtk_widget_destroy (info->extra);
g_chunk_free (info, merge_node_chunk); free_node (node);
g_node_destroy (node); g_node_destroy (node);
} }
} }
@ -2056,8 +2085,8 @@ print_node (GtkUIManager *self,
* *
* Since: 2.4 * Since: 2.4
**/ **/
gchar* gchar *
gtk_ui_manager_get_ui (GtkUIManager *self) gtk_ui_manager_get_ui (GtkUIManager *self)
{ {
GString *buffer; GString *buffer;

View File

@ -3465,6 +3465,162 @@ create_menu (GdkScreen *screen, gint depth, gint length, gboolean tearoff)
return menu; return menu;
} }
static GtkWidget*
create_table_menu (GdkScreen *screen, gint cols, gint rows, gboolean tearoff)
{
GtkWidget *menu;
GtkWidget *menuitem;
GtkWidget *submenu;
GtkWidget *image;
char buf[32];
int i, j;
menu = gtk_menu_new ();
gtk_menu_set_screen (GTK_MENU (menu), screen);
j = 0;
if (tearoff)
{
menuitem = gtk_tearoff_menu_item_new ();
gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
gtk_widget_show (menuitem);
j++;
}
menuitem = gtk_menu_item_new_with_label ("items");
gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
submenu = gtk_menu_new ();
gtk_menu_set_screen (GTK_MENU (submenu), screen);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
gtk_widget_show (menuitem);
j++;
/* now fill the items submenu */
image = gtk_image_new_from_stock (GTK_STOCK_HELP,
GTK_ICON_SIZE_MENU);
gtk_widget_show (image);
menuitem = gtk_image_menu_item_new_with_label ("Image");
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("x");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 0, 1);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("x");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 2);
gtk_widget_show (menuitem);
image = gtk_image_new_from_stock (GTK_STOCK_HELP,
GTK_ICON_SIZE_MENU);
gtk_widget_show (image);
menuitem = gtk_image_menu_item_new_with_label ("Image");
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
gtk_widget_show (menuitem);
menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 2, 3);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("x");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 2, 3);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("x");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 3, 4);
gtk_widget_show (menuitem);
menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 3, 4);
gtk_widget_show (menuitem);
menuitem = gtk_check_menu_item_new_with_label ("Check");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 4, 5);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("x");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 4, 5);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("x");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 5, 6);
gtk_widget_show (menuitem);
menuitem = gtk_check_menu_item_new_with_label ("Check");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 5, 6);
gtk_widget_show (menuitem);
/* end of items submenu */
menuitem = gtk_menu_item_new_with_label ("spanning");
gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
submenu = gtk_menu_new ();
gtk_menu_set_screen (GTK_MENU (submenu), screen);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
gtk_widget_show (menuitem);
j++;
/* now fill the spanning submenu */
menuitem = gtk_menu_item_new_with_label ("a");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 2, 0, 1);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("b");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 2, 3, 0, 2);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("c");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 3);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("d");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("e");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 3, 2, 3);
gtk_widget_show (menuitem);
/* end of spanning submenu */
menuitem = gtk_menu_item_new_with_label ("left");
gtk_menu_attach (GTK_MENU (menu), menuitem, 0, 1, j, j + 1);
submenu = gtk_menu_new ();
gtk_menu_set_screen (GTK_MENU (submenu), screen);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("Empty");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("right");
gtk_menu_attach (GTK_MENU (menu), menuitem, 1, 2, j, j + 1);
submenu = gtk_menu_new ();
gtk_menu_set_screen (GTK_MENU (submenu), screen);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("Empty");
gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
gtk_widget_show (menuitem);
j++;
for (; j < rows; j++)
for (i = 0; i < cols; i++)
{
sprintf (buf, "(%d %d)", i, j);
menuitem = gtk_menu_item_new_with_label (buf);
gtk_menu_attach (GTK_MENU (menu), menuitem, i, i + 1, j, j + 1);
gtk_widget_show (menuitem);
}
return menu;
}
static void static void
create_menus (GtkWidget *widget) create_menus (GtkWidget *widget)
{ {
@ -3516,6 +3672,13 @@ create_menus (GtkWidget *widget)
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
gtk_widget_show (menuitem); gtk_widget_show (menuitem);
menu = create_table_menu (screen, 2, 50, TRUE);
menuitem = gtk_menu_item_new_with_label ("table");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
gtk_widget_show (menuitem);
menuitem = gtk_menu_item_new_with_label ("foo"); menuitem = gtk_menu_item_new_with_label ("foo");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE)); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE));