mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-19 00:20:09 +00:00
Move SignalMonitor to treemodel.[ch] so it can be used by other tests
This commit is contained in:
parent
97b1f34868
commit
9ef07cb0f3
@ -88,326 +88,6 @@ create_tree_store (int depth,
|
||||
return store;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal monitor
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ROW_INSERTED,
|
||||
ROW_DELETED,
|
||||
ROW_CHANGED,
|
||||
ROW_HAS_CHILD_TOGGLED,
|
||||
ROWS_REORDERED,
|
||||
LAST_SIGNAL
|
||||
}
|
||||
SignalName;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GQueue *queue;
|
||||
GtkTreeModel *client;
|
||||
gulong signal_ids[LAST_SIGNAL];
|
||||
}
|
||||
SignalMonitor;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_monitor_assert_is_empty (SignalMonitor *m)
|
||||
{
|
||||
g_assert (g_queue_is_empty (m->queue));
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixture
|
||||
*/
|
||||
|
@ -37,3 +37,311 @@ main (int argc,
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -17,8 +17,44 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
void register_list_store_tests ();
|
||||
void register_tree_store_tests ();
|
||||
void register_sort_model_tests ();
|
||||
void register_filter_model_tests ();
|
||||
void register_model_ref_count_tests ();
|
||||
|
||||
/*
|
||||
* Signal monitor
|
||||
*/
|
||||
typedef struct _SignalMonitor SignalMonitor;
|
||||
typedef enum _SignalName SignalName;
|
||||
|
||||
enum _SignalName
|
||||
{
|
||||
ROW_INSERTED,
|
||||
ROW_DELETED,
|
||||
ROW_CHANGED,
|
||||
ROW_HAS_CHILD_TOGGLED,
|
||||
ROWS_REORDERED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
SignalMonitor *signal_monitor_new (GtkTreeModel *client);
|
||||
void signal_monitor_free (SignalMonitor *m);
|
||||
|
||||
void signal_monitor_assert_is_empty (SignalMonitor *m);
|
||||
|
||||
void signal_monitor_append_signal_reordered (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreePath *path,
|
||||
int *new_order,
|
||||
int len);
|
||||
void signal_monitor_append_signal_path (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreePath *path);
|
||||
void signal_monitor_append_signal (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
const gchar *path_string);
|
||||
|
Loading…
Reference in New Issue
Block a user