diff options
author | Denis Washington <denisw@online.de> | 2011-08-30 08:38:03 +0200 |
---|---|---|
committer | Denis Washington <denisw@online.de> | 2011-08-30 08:38:03 +0200 |
commit | cea54613538ffaa0a2cf2326de1822f740de1361 (patch) | |
tree | c18de79055af8c6466ab882ac1f257c93c316311 /gtk/tests/treemodel.c | |
parent | c2107aebe708d44e04a34f9549c110a82cce5153 (diff) | |
parent | 143f943905fc75cb5888011b641e447ee5c75037 (diff) | |
download | gtk+-gtkbuilder-gbinding-transform.tar.gz |
Merge branch 'gtkbuilder-gbinding' into gtkbuilder-gbinding-transformgtkbuilder-gbinding-transform
Diffstat (limited to 'gtk/tests/treemodel.c')
-rw-r--r-- | gtk/tests/treemodel.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/gtk/tests/treemodel.c b/gtk/tests/treemodel.c new file mode 100644 index 0000000000..97bbc14b27 --- /dev/null +++ b/gtk/tests/treemodel.c @@ -0,0 +1,347 @@ +/* Main wrapper for TreeModel test suite. + * Copyright (C) 2011 Kristian Rietveld <kris@gtk.org> + * + * 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 License, 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. + */ + +#include <gtk/gtk.h> + +#include "treemodel.h" + +int +main (int argc, + char **argv) +{ + gtk_test_init (&argc, &argv, NULL); + + g_test_bug_base ("http://bugzilla.gnome.org/"); + + register_list_store_tests (); + register_tree_store_tests (); + register_model_ref_count_tests (); + register_sort_model_tests (); + register_filter_model_tests (); + + return g_test_run (); +} + +/* + * Signal monitor + */ + +static const char * +signal_name_to_string (SignalName signal) +{ + switch (signal) + { + case ROW_INSERTED: + return "row-inserted"; + + case ROW_DELETED: + return "row-deleted"; + + case ROW_CHANGED: + return "row-changed"; + + case ROW_HAS_CHILD_TOGGLED: + return "row-has-child-toggled"; + + case ROWS_REORDERED: + return "rows-reordered"; + + default: + /* Fall through */ + break; + } + + return "(unknown)"; +} + +typedef struct +{ + SignalName signal; + GtkTreePath *path; + + /* For rows-reordered */ + int *new_order; + int len; +} +Signal; + + +static Signal * +signal_new (SignalName signal, GtkTreePath *path) +{ + Signal *s; + + s = g_new0 (Signal, 1); + s->signal = signal; + s->path = gtk_tree_path_copy (path); + s->new_order = NULL; + + return s; +} + +static Signal * +signal_new_with_order (SignalName signal, GtkTreePath *path, + int *new_order, int len) +{ + Signal *s = signal_new (signal, path); + + s->new_order = new_order; + s->len = len; + + return s; +} + +static void +signal_free (Signal *s) +{ + if (s->path) + gtk_tree_path_free (s->path); + + g_free (s); +} + + +struct _SignalMonitor +{ + GQueue *queue; + GtkTreeModel *client; + gulong signal_ids[LAST_SIGNAL]; +}; + + +static void +signal_monitor_generic_handler (SignalMonitor *m, + SignalName signal, + GtkTreeModel *model, + GtkTreeIter *iter, + GtkTreePath *path, + int *new_order) +{ + Signal *s; + + if (g_queue_is_empty (m->queue)) + { + gchar *path_str; + + path_str = gtk_tree_path_to_string (path); + g_error ("Signal queue empty, got signal %s path %s\n", + signal_name_to_string (signal), path_str); + g_free (path_str); + + g_assert_not_reached (); + } + + if (m->client != model) + { + g_error ("Model mismatch; expected %p, got %p\n", + m->client, model); + g_assert_not_reached (); + } + + s = g_queue_peek_tail (m->queue); + +#if 0 + /* For debugging: output signals that are coming in. Leaks memory. */ + g_print ("signal=%s path=%s\n", signal_name_to_string (signal), + gtk_tree_path_to_string (path)); +#endif + + if (s->signal != signal || + (gtk_tree_path_get_depth (s->path) == 0 && + gtk_tree_path_get_depth (path) != 0) || + (gtk_tree_path_get_depth (s->path) != 0 && + gtk_tree_path_compare (s->path, path) != 0)) + { + gchar *path_str, *s_path_str; + + s_path_str = gtk_tree_path_to_string (s->path); + path_str = gtk_tree_path_to_string (path); + + g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n", + signal_name_to_string (s->signal), s_path_str, + signal_name_to_string (signal), path_str); + + g_free (s_path_str); + g_free (path_str); + + g_assert_not_reached (); + } + + if (signal == ROWS_REORDERED && s->new_order != NULL) + { + int i, len; + + g_assert (new_order != NULL); + + len = gtk_tree_model_iter_n_children (model, iter); + g_assert (s->len == len); + + for (i = 0; i < len; i++) + g_assert (s->new_order[i] == new_order[i]); + } + + s = g_queue_pop_tail (m->queue); + + signal_free (s); +} + +static void +signal_monitor_row_inserted (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_INSERTED, + model, iter, path, NULL); +} + +static void +signal_monitor_row_deleted (GtkTreeModel *model, + GtkTreePath *path, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_DELETED, + model, NULL, path, NULL); +} + +static void +signal_monitor_row_changed (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_CHANGED, + model, iter, path, NULL); +} + +static void +signal_monitor_row_has_child_toggled (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED, + model, iter, path, NULL); +} + +static void +signal_monitor_rows_reordered (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gint *new_order, + gpointer data) +{ + signal_monitor_generic_handler (data, ROWS_REORDERED, + model, iter, path, new_order); +} + +SignalMonitor * +signal_monitor_new (GtkTreeModel *client) +{ + SignalMonitor *m; + + m = g_new0 (SignalMonitor, 1); + m->client = g_object_ref (client); + m->queue = g_queue_new (); + + m->signal_ids[ROW_INSERTED] = g_signal_connect (client, + "row-inserted", + G_CALLBACK (signal_monitor_row_inserted), + m); + m->signal_ids[ROW_DELETED] = g_signal_connect (client, + "row-deleted", + G_CALLBACK (signal_monitor_row_deleted), + m); + m->signal_ids[ROW_CHANGED] = g_signal_connect (client, + "row-changed", + G_CALLBACK (signal_monitor_row_changed), + m); + m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client, + "row-has-child-toggled", + G_CALLBACK (signal_monitor_row_has_child_toggled), + m); + m->signal_ids[ROWS_REORDERED] = g_signal_connect (client, + "rows-reordered", + G_CALLBACK (signal_monitor_rows_reordered), + m); + + return m; +} + +void +signal_monitor_free (SignalMonitor *m) +{ + int i; + + for (i = 0; i < LAST_SIGNAL; i++) + g_signal_handler_disconnect (m->client, m->signal_ids[i]); + + g_object_unref (m->client); + + if (m->queue) + g_queue_free (m->queue); + + g_free (m); +} + +void +signal_monitor_assert_is_empty (SignalMonitor *m) +{ + g_assert (g_queue_is_empty (m->queue)); +} + +void +signal_monitor_append_signal_path (SignalMonitor *m, + SignalName signal, + GtkTreePath *path) +{ + Signal *s; + + s = signal_new (signal, path); + g_queue_push_head (m->queue, s); +} + +void +signal_monitor_append_signal_reordered (SignalMonitor *m, + SignalName signal, + GtkTreePath *path, + int *new_order, + int len) +{ + Signal *s; + + s = signal_new_with_order (signal, path, new_order, len); + g_queue_push_head (m->queue, s); +} + +void +signal_monitor_append_signal (SignalMonitor *m, + SignalName signal, + const gchar *path_string) +{ + Signal *s; + GtkTreePath *path; + + path = gtk_tree_path_new_from_string (path_string); + + s = signal_new (signal, path); + g_queue_push_head (m->queue, s); + + gtk_tree_path_free (path); +} |