diff --git a/ChangeLog b/ChangeLog index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 2b7bf88347..1d5c0b3666 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,17 @@ +2001-02-16 Alexander Larsson + + * gtk/gtktreemodelmapping.[ch]: + New files. Implement GtkTreeModelMapping. + + * gtk/Makefile.am: + Add gtktreemodelmapping.[ch]. + + * gtk/gtk.h: + Add gtktreemodelmapping.h + + * gtk/treestoretest.c: + Test the GtkTreeModelMapping + Tue Feb 13 13:16:09 2001 Jonathan Blandford * demos/gtk-demo/panes.c (create_pane_options): If we're going to diff --git a/gtk/Makefile.am b/gtk/Makefile.am index b709878fa7..89a91809f0 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -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 \ diff --git a/gtk/gtk.h b/gtk/gtk.h index 7eedaa1c8e..1a7d36fe65 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -144,6 +144,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtktreemodelmapping.c b/gtk/gtktreemodelmapping.c new file mode 100644 index 0000000000..886295340f --- /dev/null +++ b/gtk/gtktreemodelmapping.c @@ -0,0 +1,571 @@ +/* gtktreemodelmapping.c + * Copyright (C) 2000 Red Hat, Inc., Alexander Larsson + * + * 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); +} diff --git a/gtk/gtktreemodelmapping.h b/gtk/gtktreemodelmapping.h new file mode 100644 index 0000000000..20de3daa0e --- /dev/null +++ b/gtk/gtktreemodelmapping.h @@ -0,0 +1,102 @@ +/* gtktreemodelmapping.h + * Copyright (C) 2000 Red Hat, Inc., Alexander Larsson + * + * 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 + +#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__ */ diff --git a/gtk/treestoretest.c b/gtk/treestoretest.c index 2202a92fcb..8079137a3c 100644 --- a/gtk/treestoretest.c +++ b/gtk/treestoretest.c @@ -201,7 +201,20 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view) } 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; @@ -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) - { - 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 + switch (view_type) { + 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; } + diff --git a/tests/treestoretest.c b/tests/treestoretest.c index 2202a92fcb..8079137a3c 100644 --- a/tests/treestoretest.c +++ b/tests/treestoretest.c @@ -201,7 +201,20 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view) } 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; @@ -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) - { - 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 + switch (view_type) { + 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; } +