GtkTreeModelMapping



I was gonna put some abstract types in a GtkTreeView to view them, only
i didn't want to copy strings from it and place in a GtkListStore, so I
wrote a TreeModel that takes another model and generates a new one where
the columns can be specified as transformations of the data in the
original model.

For each column in the model a (src_column, col_type, map_func, user_data)
tupel is used to map the value, where the map_func is of the type:

typedef void (* GValueMapFunc) (const GValue *a,
				GValue *b,
				gpointer user_data);


I think this is of general interest. Comments?

/ Alex

Index: gtk/Makefile.am
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/Makefile.am,v
retrieving revision 1.152
diff -u -p -r1.152 Makefile.am
--- gtk/Makefile.am	2001/02/13 05:44:46	1.152
+++ gtk/Makefile.am	2001/02/14 16:14:20
@@ -175,6 +175,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
 	gtktreemodel.h		\
 	gtktreemodelsimple.h	\
 	gtktreemodelsort.h	\
+	gtktreemodelmapping.h	\
 	gtktreeselection.h	\
 	gtktreesortable.h	\
 	gtktreestore.h		\
@@ -342,6 +343,7 @@ gtk_c_sources = @STRIP_BEGIN@   \
 	gtktreemodel.c		\
 	gtktreemodelsimple.c	\
 	gtktreemodelsort.c	\
+	gtktreemodelmapping.c	\
 	gtktreeselection.c	\
 	gtktreestore.c		\
 	gtktreeview.c		\
Index: gtk/gtk.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtk.h,v
retrieving revision 1.43
diff -u -p -r1.43 gtk.h
--- gtk/gtk.h	2001/02/13 05:44:47	1.43
+++ gtk/gtk.h	2001/02/14 16:14:20
@@ -144,6 +144,7 @@
 #include <gtk/gtktreemodel.h>
 #include <gtk/gtktreemodelsimple.h>
 #include <gtk/gtktreemodelsort.h>
+#include <gtk/gtktreemodelmapping.h>
 #include <gtk/gtktreeselection.h>
 #include <gtk/gtktreestore.h>
 #include <gtk/gtktreeview.h>
Index: gtk/treestoretest.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/treestoretest.c,v
retrieving revision 1.11
diff -u -p -r1.11 treestoretest.c
--- gtk/treestoretest.c	2001/01/04 21:33:24	1.11
+++ gtk/treestoretest.c	2001/02/14 16:14:20
@@ -201,8 +201,21 @@ iter_append (GtkWidget *button, GtkTreeV
 }

 static void
-make_window (gboolean use_sort)
+uppercase_value (const GValue *src, GValue *dest, gpointer data)
 {
+  gchar *str;
+
+  g_value_init (dest, G_TYPE_STRING);
+  str = g_strdup (g_value_get_string (src));
+  if (str)
+    g_strup (str);
+  g_value_set_string (dest, str);
+  g_free (str);
+}
+
+static void
+make_window (gint view_type)
+{
   GtkWidget *window;
   GtkWidget *vbox;
   GtkWidget *hbox, *entry;
@@ -215,26 +228,61 @@ make_window (gboolean use_sort)

   /* Make the Widgets/Objects */
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  if (use_sort)
-    gtk_window_set_title (GTK_WINDOW (window), "Sorted list");
-  else
-    gtk_window_set_title (GTK_WINDOW (window), "Unsorted list");
+  switch (view_type)
+    {
+    case 0:
+      gtk_window_set_title (GTK_WINDOW (window), "Unsorted list");
+      break;
+    case 1:
+      gtk_window_set_title (GTK_WINDOW (window), "Sorted list");
+      break;
+    case 2:
+      gtk_window_set_title (GTK_WINDOW (window), "Uppercase flipped list");
+      break;
+    }

   vbox = gtk_vbox_new (FALSE, 8);
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
   gtk_window_set_default_size (GTK_WINDOW (window), 300, 350);
   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-  if (use_sort)
+  switch (view_type)
     {
-      GtkTreeModel *sort_model;
-
-      sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model),
-						       NULL, 1);
-      tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
-    }
-  else
-    {
+    case 0:
       tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (base_model));
+      break;
+    case 1:
+      {
+	GtkTreeModel *sort_model;
+
+	sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model),
+							 NULL, 1);
+	tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
+      }
+      break;
+    case 2:
+      {
+	GtkTreeModel *map_model;
+
+	map_model = gtk_tree_model_mapping_new_with_model (GTK_TREE_MODEL (base_model));
+
+	gtk_tree_model_mapping_set_n_columns (GTK_TREE_MODEL_MAPPING (map_model), 2);
+	gtk_tree_model_mapping_set_column_mapping (GTK_TREE_MODEL_MAPPING (map_model),
+						   0,
+						   1,
+						   G_TYPE_STRING,
+						   uppercase_value,
+						   NULL);
+	gtk_tree_model_mapping_set_column_mapping (GTK_TREE_MODEL_MAPPING (map_model),
+						   1,
+						   0,
+						   G_TYPE_STRING,
+						   uppercase_value,
+						   NULL);
+
+	tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (map_model));
+
+      }
+      break;
     }

   selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)));
@@ -305,7 +353,7 @@ make_window (gboolean use_sort)
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);

   /* A few to start */
-  if (!use_sort)
+  if (view_type == 0)
     {
       iter_append (NULL, GTK_TREE_VIEW (tree_view));
       iter_append (NULL, GTK_TREE_VIEW (tree_view));
@@ -326,10 +374,12 @@ main (int argc, char *argv[])
   base_model = gtk_tree_store_new_with_types (2, G_TYPE_STRING, G_TYPE_STRING);

   /* FIXME: reverse this */
-  make_window (FALSE);
-  make_window (TRUE);
+  make_window (0);
+  make_window (1);
+  make_window (2);

   gtk_main ();

   return 0;
 }
+
--- /dev/null	Thu Aug 24 11:00:32 2000
+++ gtk/gtktreemodelmapping.h	Wed Feb 14 16:34:15 2001
@@ -0,0 +1,102 @@
+/* gtktreemodelmapping.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Alexander Larsson <alexl redhat com>
+ *
+ * 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
+ * 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
+ * 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.
+ */
+
+#ifndef __GTK_TREE_MODEL_MAPPING_H__
+#define __GTK_TREE_MODEL_MAPPING_H__
+
+#include <gtk/gtktreemodel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GTK_TYPE_TREE_MODEL_MAPPING		(gtk_tree_model_mapping_get_type ())
+#define GTK_TREE_MODEL_MAPPING(obj)		(GTK_CHECK_CAST ((obj), GTK_TYPE_TREE_MODEL_MAPPING, GtkTreeModelMapping))
+#define GTK_TREE_MODEL_MAPPING_CLASS(klass)	(GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_MODEL_MAPPING, GtkTreeModelMappingClass))
+#define GTK_IS_TREE_MODEL_MAPPING(obj)		(GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE_MODEL_MAPPING))
+#define GTK_IS_TREE_MODEL_MAPPING_CLASS(klass)	(GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TREE_MODEL_MAPPING))
+
+typedef struct _GtkTreeModelMapping       GtkTreeModelMapping;
+typedef struct _GtkTreeModelMappingClass  GtkTreeModelMappingClass;
+typedef struct _GtkTreeModelMappingMap    GtkTreeModelMappingMap;
+
+typedef void (* GValueMapFunc) (const GValue *a,
+				GValue *b,
+				gpointer user_data);
+
+
+struct _GtkTreeModelMappingMap
+{
+  gint src_column;
+  GType col_type;
+  GValueMapFunc map_func;
+  gpointer user_data;
+};
+
+struct _GtkTreeModelMapping
+{
+  GtkObject parent;
+
+  /* < private > */
+  GtkTreeModel *child_model;
+  gint n_columns;
+  GtkTreeModelMappingMap *column_maps;
+};
+
+struct _GtkTreeModelMappingClass
+{
+  GtkObjectClass parent_class;
+
+  /* signals */
+  /* Will be moved into the GtkTreeModelIface eventually */
+  void (* changed)       (GtkTreeModel *tree_model,
+			  GtkTreePath  *path,
+			  GtkTreeIter  *iter);
+  void (* inserted)      (GtkTreeModel *tree_model,
+			  GtkTreePath  *path,
+			  GtkTreeIter  *iter);
+  void (* child_toggled) (GtkTreeModel *tree_model,
+			  GtkTreePath  *path,
+			  GtkTreeIter  *iter);
+  void (* deleted)       (GtkTreeModel *tree_model,
+			  GtkTreePath  *path);
+};
+
+
+GtkType       gtk_tree_model_mapping_get_type           (void);
+GtkTreeModel *gtk_tree_model_mapping_new                (void);
+GtkTreeModel *gtk_tree_model_mapping_new_with_model     (GtkTreeModel        *child_model);
+void          gtk_tree_model_mapping_set_n_columns      (GtkTreeModelMapping *tree_model_mapping,
+							 gint                 n_columns);
+void          gtk_tree_model_mapping_set_column_mapping (GtkTreeModelMapping *tree_model_mapping,
+							 gint                 column,
+							 gint                 src_column,
+							 GType                col_type,
+							 GValueMapFunc        map_func,
+							 gpointer             user_data);
+void          gtk_tree_model_mapping_set_model          (GtkTreeModelMapping *tree_model_mapping,
+							 GtkTreeModel        *child_model);
+GtkTreeModel *gtk_tree_model_mapping_get_model          (GtkTreeModelMapping *tree_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TREE_MODEL_MAPPING_H__ */
--- /dev/null	Thu Aug 24 11:00:32 2000
+++ gtk/gtktreemodelmapping.c	Wed Feb 14 17:08:30 2001
@@ -0,0 +1,571 @@
+/* gtktreemodelmapping.c
+ * Copyright (C) 2000  Red Hat, Inc.,  Alexander Larsson <alexl redhat com>
+ *
+ * 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
+ * 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
+ * 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.
+ */
+
+#include "gtktreemodelmapping.h"
+#include "gtksignal.h"
+
+enum {
+  CHANGED,
+  INSERTED,
+  CHILD_TOGGLED,
+  DELETED,
+  LAST_SIGNAL
+};
+
+static guint tree_model_mapping_signals[LAST_SIGNAL] = { 0 };
+
+static void         gtk_tree_model_mapping_init            (GtkTreeModelMapping      *tree_model_mapping);
+static void         gtk_tree_model_mapping_class_init      (GtkTreeModelMappingClass *tree_model_mapping_class);
+static void         gtk_tree_model_mapping_tree_model_init (GtkTreeModelIface        *iface);
+static void         gtk_tree_model_mapping_finalize        (GObject                  *object);
+/* signals */
+static void         gtk_tree_model_mapping_changed         (GtkTreeModel             *model,
+							    GtkTreePath              *path,
+							    GtkTreeIter              *iter,
+							    gpointer                  data);
+static void         gtk_tree_model_mapping_inserted        (GtkTreeModel             *model,
+							    GtkTreePath              *path,
+							    GtkTreeIter              *iter,
+							    gpointer                  data);
+static void         gtk_tree_model_mapping_child_toggled   (GtkTreeModel             *model,
+							    GtkTreePath              *path,
+							    GtkTreeIter              *iter,
+							    gpointer                  data);
+static void         gtk_tree_model_mapping_deleted         (GtkTreeModel             *model,
+							    GtkTreePath              *path,
+							    gpointer                  data);
+static void         gtk_tree_model_mapping_reordered       (GtkTreeModel             *model,
+							    GtkTreePath              *path,
+							    gint                     *new_order);
+/* vtable */
+static GtkTreeModelFlags gtk_tree_model_mapping_get_flags  (GtkTreeModel             *tree_model);
+static gint         gtk_tree_model_mapping_get_n_columns   (GtkTreeModel             *tree_model);
+static GType        gtk_tree_model_mapping_get_column_type (GtkTreeModel             *tree_model,
+							    gint                      index);
+static gboolean     gtk_tree_model_mapping_get_iter        (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter,
+							    GtkTreePath              *path);
+static GtkTreePath *gtk_tree_model_mapping_get_path        (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter);
+static void         gtk_tree_model_mapping_get_value       (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter,
+							    gint                      column,
+							    GValue                   *value);
+static gboolean     gtk_tree_model_mapping_iter_next       (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter);
+static gboolean     gtk_tree_model_mapping_iter_children   (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter,
+							    GtkTreeIter              *parent);
+static gboolean     gtk_tree_model_mapping_iter_has_child  (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter);
+static gint         gtk_tree_model_mapping_iter_n_children (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter);
+static gboolean     gtk_tree_model_mapping_iter_nth_child  (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter,
+							    GtkTreeIter              *parent,
+							    gint                      n);
+static gboolean     gtk_tree_model_mapping_iter_parent     (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter,
+							    GtkTreeIter              *child);
+static void         gtk_tree_model_mapping_ref_iter        (GtkTreeModel             *tree_model,
+							    GtkTreeIter              *iter);
+static void         gtk_tree_model_mapping_unref_iter      (GtkTreeModel          *tree_model,
+							    GtkTreeIter              *iter);
+
+
+GtkType
+gtk_tree_model_mapping_get_type (void)
+{
+  static GtkType tree_model_mapping_type = 0;
+
+  if (!tree_model_mapping_type)
+    {
+      static const GTypeInfo tree_model_mapping_info =
+      {
+        sizeof (GtkTreeModelMappingClass),
+	NULL,		/* base_init */
+	NULL,		/* base_finalize */
+        (GClassInitFunc) gtk_tree_model_mapping_class_init,
+	NULL,		/* class_finalize */
+	NULL,		/* class_data */
+        sizeof (GtkTreeModelMapping),
+	0,              /* n_preallocs */
+        (GInstanceInitFunc) gtk_tree_model_mapping_init
+      };
+
+      static const GInterfaceInfo tree_model_info =
+      {
+	(GInterfaceInitFunc) gtk_tree_model_mapping_tree_model_init,
+	NULL,
+	NULL
+      };
+
+      tree_model_mapping_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeModelMapping", &tree_model_mapping_info, 0);
+      g_type_add_interface_static (tree_model_mapping_type,
+				   GTK_TYPE_TREE_MODEL,
+				   &tree_model_info);
+    }
+
+  return tree_model_mapping_type;
+}
+
+static void
+gtk_tree_model_mapping_class_init (GtkTreeModelMappingClass *tree_model_mapping_class)
+{
+  GObjectClass *object_class;
+
+  object_class = (GObjectClass *) tree_model_mapping_class;
+
+  object_class->finalize = gtk_tree_model_mapping_finalize;
+
+  tree_model_mapping_signals[CHANGED] =
+    gtk_signal_new ("changed",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelMappingClass, changed),
+                    gtk_marshal_VOID__POINTER_POINTER,
+                    GTK_TYPE_NONE, 2,
+		    GTK_TYPE_POINTER,
+		    GTK_TYPE_POINTER);
+  tree_model_mapping_signals[INSERTED] =
+    gtk_signal_new ("inserted",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelMappingClass, inserted),
+                    gtk_marshal_VOID__POINTER_POINTER,
+                    GTK_TYPE_NONE, 2,
+		    GTK_TYPE_POINTER,
+		    GTK_TYPE_POINTER);
+  tree_model_mapping_signals[CHILD_TOGGLED] =
+    gtk_signal_new ("child_toggled",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelMappingClass, child_toggled),
+                    gtk_marshal_VOID__POINTER_POINTER,
+                    GTK_TYPE_NONE, 2,
+		    GTK_TYPE_POINTER,
+		    GTK_TYPE_POINTER);
+  tree_model_mapping_signals[DELETED] =
+    gtk_signal_new ("deleted",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelMappingClass, deleted),
+                    gtk_marshal_VOID__POINTER,
+                    GTK_TYPE_NONE, 1,
+		    GTK_TYPE_POINTER);
+}
+
+static void
+gtk_tree_model_mapping_tree_model_init (GtkTreeModelIface *iface)
+{
+  iface->get_flags = gtk_tree_model_mapping_get_flags;
+  iface->get_n_columns = gtk_tree_model_mapping_get_n_columns;
+  iface->get_column_type = gtk_tree_model_mapping_get_column_type;
+  iface->get_iter = gtk_tree_model_mapping_get_iter;
+  iface->get_path = gtk_tree_model_mapping_get_path;
+  iface->get_value = gtk_tree_model_mapping_get_value;
+  iface->iter_next = gtk_tree_model_mapping_iter_next;
+  iface->iter_children = gtk_tree_model_mapping_iter_children;
+  iface->iter_has_child = gtk_tree_model_mapping_iter_has_child;
+  iface->iter_n_children = gtk_tree_model_mapping_iter_n_children;
+  iface->iter_nth_child = gtk_tree_model_mapping_iter_nth_child;
+  iface->iter_parent = gtk_tree_model_mapping_iter_parent;
+  iface->ref_iter = gtk_tree_model_mapping_ref_iter;
+  iface->unref_iter = gtk_tree_model_mapping_unref_iter;
+}
+
+static void
+gtk_tree_model_mapping_init (GtkTreeModelMapping *tree_model_mapping)
+{
+}
+
+GtkTreeModel *
+gtk_tree_model_mapping_new (void)
+{
+  return GTK_TREE_MODEL (gtk_type_new (gtk_tree_model_mapping_get_type ()));
+}
+
+GtkTreeModel *
+gtk_tree_model_mapping_new_with_model (GtkTreeModel      *child_model)
+{
+  GtkTreeModel *retval;
+
+  retval = gtk_tree_model_mapping_new ();
+  gtk_tree_model_mapping_set_model (GTK_TREE_MODEL_MAPPING (retval), child_model);
+  return retval;
+}
+
+void
+gtk_tree_model_mapping_set_n_columns (GtkTreeModelMapping *tree_model_mapping,
+				      gint                 n_columns)
+{
+  g_return_if_fail (tree_model_mapping != NULL);
+  g_return_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model_mapping));
+
+  tree_model_mapping->n_columns = n_columns;
+  tree_model_mapping->column_maps = g_realloc (tree_model_mapping->column_maps, sizeof (GtkTreeModelMapping)*n_columns);
+}
+
+void
+gtk_tree_model_mapping_set_column_mapping (GtkTreeModelMapping *tree_model_mapping,
+					   gint                 column,
+					   gint                 src_column,
+					   GType                col_type,
+					   GValueMapFunc        map_func,
+					   gpointer             user_data)
+{
+  GtkTreeModelMappingMap *map;
+
+  g_return_if_fail (tree_model_mapping != NULL);
+  g_return_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model_mapping));
+  g_return_if_fail (column < tree_model_mapping->n_columns);
+
+  map = &tree_model_mapping->column_maps[column];
+  map->src_column = src_column;
+  map->col_type = col_type;
+  map->map_func = map_func;
+  map->user_data = user_data;
+}
+
+/**
+ * gtk_tree_model_mapping_set_model:
+ * @tree_model_mapping: The #GtkTreeModelMapping.
+ * @child_model: A #GtkTreeModel, or NULL.
+ *
+ * Sets the model of @tree_model_mapping to be @model.  If @model is NULL, then the
+ * old model is unset.
+ **/
+void
+gtk_tree_model_mapping_set_model (GtkTreeModelMapping *tree_model_mapping,
+				  GtkTreeModel     *child_model)
+{
+  g_return_if_fail (tree_model_mapping != NULL);
+  g_return_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model_mapping));
+
+  if (child_model)
+    g_object_ref (G_OBJECT (child_model));
+
+  if (tree_model_mapping->child_model)
+    {
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_mapping->child_model),
+				     gtk_tree_model_mapping_changed,
+				     tree_model_mapping);
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_mapping->child_model),
+				     gtk_tree_model_mapping_inserted,
+				     tree_model_mapping);
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_mapping->child_model),
+				     gtk_tree_model_mapping_child_toggled,
+				     tree_model_mapping);
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_mapping->child_model),
+				     gtk_tree_model_mapping_deleted,
+				     tree_model_mapping);
+
+      g_object_unref (G_OBJECT (tree_model_mapping->child_model));
+    }
+
+  tree_model_mapping->child_model = child_model;
+
+  if (child_model)
+    {
+      gtk_signal_connect (GTK_OBJECT (child_model),
+			  "changed",
+			  gtk_tree_model_mapping_changed,
+			  tree_model_mapping);
+      gtk_signal_connect (GTK_OBJECT (child_model),
+			  "inserted",
+			  gtk_tree_model_mapping_inserted,
+			  tree_model_mapping);
+      gtk_signal_connect (GTK_OBJECT (child_model),
+			  "child_toggled",
+			  gtk_tree_model_mapping_child_toggled,
+			  tree_model_mapping);
+      gtk_signal_connect (GTK_OBJECT (child_model),
+			  "deleted",
+			  gtk_tree_model_mapping_deleted,
+			  tree_model_mapping);
+    }
+}
+
+/**
+ * gtk_tree_model_mapping_get_model:
+ * @tree_model: a #GtkTreeModelMapping
+ *
+ * Returns the model the #GtkTreeModelMapping is mappinging.
+ *
+ * Return value: the "child model" being mappinged
+ **/
+GtkTreeModel*
+gtk_tree_model_mapping_get_model (GtkTreeModelMapping  *tree_model)
+{
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), NULL);
+
+  return tree_model->child_model;
+}
+
+static void
+gtk_tree_model_mapping_finalize (GObject *object)
+{
+  GtkTreeModelMapping *tree_model_mapping = (GtkTreeModelMapping *) object;
+
+  g_free (tree_model_mapping->column_maps);
+  tree_model_mapping->column_maps = NULL;
+
+  if (tree_model_mapping->child_model)
+    {
+      g_object_unref (G_OBJECT (tree_model_mapping->child_model));
+      tree_model_mapping->child_model = NULL;
+    }
+}
+
+static void
+gtk_tree_model_mapping_changed (GtkTreeModel             *model,
+				GtkTreePath              *path,
+				GtkTreeIter              *iter,
+				gpointer                  data)
+{
+  gtk_signal_emit_by_name (GTK_OBJECT (data), "changed", path, iter);
+}
+
+static void
+gtk_tree_model_mapping_inserted (GtkTreeModel             *model,
+				 GtkTreePath              *path,
+				 GtkTreeIter              *iter,
+				 gpointer                  data)
+{
+  gtk_signal_emit_by_name (GTK_OBJECT (data), "inserted", path, iter);
+}
+
+static void
+gtk_tree_model_mapping_child_toggled (GtkTreeModel             *model,
+				      GtkTreePath              *path,
+				      GtkTreeIter              *iter,
+				      gpointer                  data)
+{
+  gtk_signal_emit_by_name (GTK_OBJECT (data), "child_toggled", path, iter);
+}
+
+static void
+gtk_tree_model_mapping_deleted (GtkTreeModel             *model,
+				GtkTreePath              *path,
+				gpointer                  data)
+{
+  gtk_signal_emit_by_name (GTK_OBJECT (data), "deleted", path);
+}
+
+
+static GtkTreeModelFlags
+gtk_tree_model_mapping_get_flags (GtkTreeModel *tree_model)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+
+  return gtk_tree_model_get_flags (child_model);
+}
+
+static gint
+gtk_tree_model_mapping_get_n_columns (GtkTreeModel *tree_model)
+{
+  GtkTreeModelMapping *tree_model_mapping;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+
+  tree_model_mapping = GTK_TREE_MODEL_MAPPING (tree_model);
+
+  return tree_model_mapping->n_columns;
+}
+
+static GType
+gtk_tree_model_mapping_get_column_type (GtkTreeModel  *tree_model,
+					gint           index)
+{
+  GtkTreeModelMapping *tree_model_mapping;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+
+  tree_model_mapping = GTK_TREE_MODEL_MAPPING (tree_model);
+
+  return tree_model_mapping->column_maps[index].col_type;
+}
+
+static gboolean
+gtk_tree_model_mapping_get_iter (GtkTreeModel *tree_model,
+				 GtkTreeIter  *iter,
+				 GtkTreePath  *path)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+
+  return gtk_tree_model_get_iter (child_model, iter, path);
+}
+
+static GtkTreePath *
+gtk_tree_model_mapping_get_path (GtkTreeModel *tree_model,
+				 GtkTreeIter  *iter)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+
+  return gtk_tree_model_get_path (child_model, iter);
+}
+
+static void
+gtk_tree_model_mapping_get_value (GtkTreeModel  *tree_model,
+				  GtkTreeIter   *iter,
+				  gint           column,
+				  GValue        *value)
+{
+  GValue src_val = { 0, };
+  GtkTreeModel *child_model;
+  GtkTreeModelMapping *tree_model_mapping;
+  GtkTreeModelMappingMap *map;
+
+  g_return_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model));
+  g_return_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL);
+
+  tree_model_mapping = GTK_TREE_MODEL_MAPPING (tree_model);
+  child_model = tree_model_mapping->child_model;
+
+  map = &tree_model_mapping->column_maps[column];
+
+  gtk_tree_model_get_value (child_model, iter, map->src_column, &src_val);
+  (* map->map_func) (&src_val, value, map->user_data);
+  g_value_unset (&src_val);
+}
+
+static gboolean
+gtk_tree_model_mapping_iter_next (GtkTreeModel *tree_model,
+				  GtkTreeIter  *iter)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+
+  return gtk_tree_model_iter_next (child_model, iter);
+}
+
+static gboolean
+gtk_tree_model_mapping_iter_children (GtkTreeModel *tree_model,
+				      GtkTreeIter  *iter,
+				      GtkTreeIter  *parent)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  return gtk_tree_model_iter_children (child_model, iter, parent);
+}
+
+static gboolean
+gtk_tree_model_mapping_iter_has_child (GtkTreeModel *tree_model,
+				       GtkTreeIter  *iter)
+
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  return gtk_tree_model_iter_has_child (child_model, iter);
+}
+
+static gint
+gtk_tree_model_mapping_iter_n_children (GtkTreeModel *tree_model,
+					GtkTreeIter  *iter)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  return gtk_tree_model_iter_n_children (child_model, iter);
+}
+
+static gboolean
+gtk_tree_model_mapping_iter_nth_child (GtkTreeModel *tree_model,
+				       GtkTreeIter  *iter,
+				       GtkTreeIter  *parent,
+				       gint         n)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  return gtk_tree_model_iter_nth_child (child_model, iter, parent, n);
+}
+
+static gboolean
+gtk_tree_model_mapping_iter_parent (GtkTreeModel             *tree_model,
+				    GtkTreeIter              *iter,
+				    GtkTreeIter              *child)
+{
+  GtkTreeModel *child_model;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL, 0);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  return gtk_tree_model_iter_parent (child_model, iter, child);
+}
+
+static void
+gtk_tree_model_mapping_ref_iter (GtkTreeModel *tree_model,
+				 GtkTreeIter  *iter)
+{
+  GtkTreeModel *child_model;
+
+  g_return_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model));
+  g_return_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  gtk_tree_model_ref_iter (child_model, iter);
+}
+
+static void
+gtk_tree_model_mapping_unref_iter (GtkTreeModel *tree_model,
+				   GtkTreeIter  *iter)
+{
+  GtkTreeModel *child_model;
+
+  g_return_if_fail (GTK_IS_TREE_MODEL_MAPPING (tree_model));
+  g_return_if_fail (GTK_TREE_MODEL_MAPPING (tree_model)->child_model != NULL);
+
+  child_model = GTK_TREE_MODEL_MAPPING (tree_model)->child_model;
+  gtk_tree_model_unref_iter (child_model, iter);
+}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]