summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorJonathan Blandford <jrb@redhat.com>2000-11-09 16:52:17 +0000
committerJonathan Blandford <jrb@src.gnome.org>2000-11-09 16:52:17 +0000
commitc97d57ebb8ceae99ed77fc6d953470e01d74310a (patch)
tree78786db0c79bbf6692d68833d469e5d5b601a0cb /gtk
parent8898529c12e0d2d4a5dd4e3b9917a6a1272f4882 (diff)
downloadgdk-pixbuf-c97d57ebb8ceae99ed77fc6d953470e01d74310a.tar.gz
added more fields to allow more interesting iterators. Also, made the
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to allow more interesting iterators. Also, made the lifecycle of iterators more explicit. * gtk/gtktreemodelsort.[ch]: New model for sorting. * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed types.
Diffstat (limited to 'gtk')
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/gtk-boxed.defs9
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkliststore.c15
-rw-r--r--gtk/gtktreemodel.c144
-rw-r--r--gtk/gtktreemodel.h26
-rw-r--r--gtk/gtktreemodelsort.c897
-rw-r--r--gtk/gtktreemodelsort.h94
-rw-r--r--gtk/gtktreeselection.c13
-rw-r--r--gtk/gtktreeselection.h1
-rw-r--r--gtk/gtktreestore.c33
-rw-r--r--gtk/gtktreeview.c4
-rw-r--r--gtk/gtktreeviewcolumn.c17
-rw-r--r--gtk/gtktreeviewcolumn.h84
-rw-r--r--gtk/treestoretest.c20
15 files changed, 1280 insertions, 80 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index f4eaa8925..e05b165c0 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -171,6 +171,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtktree.h \
gtktreeitem.h \
gtktreemodel.h \
+ gtktreemodelsort.h \
gtktreeselection.h \
gtktreestore.h \
gtktreeview.h \
@@ -329,6 +330,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtktreeitem.c \
gtktreedatalist.c \
gtktreemodel.c \
+ gtktreemodelsort.c \
gtktreeselection.c \
gtktreestore.c \
gtktreeview.c \
diff --git a/gtk/gtk-boxed.defs b/gtk/gtk-boxed.defs
index 27a3e8733..b21c10498 100644
--- a/gtk/gtk-boxed.defs
+++ b/gtk/gtk-boxed.defs
@@ -1286,6 +1286,15 @@
gtk_text_iter_copy
gtk_text_iter_free)
+;; TreeView
+(define-boxed GtkTreeIter
+ gtk_tree_iter_copy
+ gtk_tree_iter_free)
+
+(define-boxed GtkTreePath
+ gtk_tree_path_copy
+ gtk_tree_path_free)
+
;; Alignment
(define-object GtkAlignment (GtkBin))
diff --git a/gtk/gtk.h b/gtk/gtk.h
index ff27fb08c..a7b3e8818 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -141,6 +141,7 @@
#include <gtk/gtktree.h>
#include <gtk/gtktreeitem.h>
#include <gtk/gtktreemodel.h>
+#include <gtk/gtktreemodelsort.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtktreestore.h>
#include <gtk/gtktreeview.h>
diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c
index 032241cf3..c50974b4e 100644
--- a/gtk/gtkliststore.c
+++ b/gtk/gtkliststore.c
@@ -38,6 +38,7 @@ static guint list_store_signals[LAST_SIGNAL] = { 0 };
static void gtk_list_store_init (GtkListStore *list_store);
static void gtk_list_store_class_init (GtkListStoreClass *class);
static void gtk_list_store_tree_model_init (GtkTreeModelIface *iface);
+static guint gtk_list_store_get_flags (GtkTreeModel *tree_model);
static gint gtk_list_store_get_n_columns (GtkTreeModel *tree_model);
static gboolean gtk_list_store_get_iter (GtkTreeModel *tree_model,
GtkTreeIter *iter,
@@ -152,6 +153,7 @@ gtk_list_store_class_init (GtkListStoreClass *class)
static void
gtk_list_store_tree_model_init (GtkTreeModelIface *iface)
{
+ iface->get_flags = gtk_list_store_get_flags;
iface->get_n_columns = gtk_list_store_get_n_columns;
iface->get_iter = gtk_list_store_get_iter;
iface->get_path = gtk_list_store_get_path;
@@ -168,7 +170,7 @@ static void
gtk_list_store_init (GtkListStore *list_store)
{
list_store->root = NULL;
- list_store->stamp = 1;
+ list_store->stamp = g_random_int ();
}
GtkListStore *
@@ -242,6 +244,14 @@ gtk_list_store_set_column_type (GtkListStore *list_store,
}
/* Fulfill the GtkTreeModel requirements */
+static guint
+gtk_list_store_get_flags (GtkTreeModel *tree_model)
+{
+ g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), 0);
+
+ return GTK_TREE_MODEL_ITERS_PERSIST;
+}
+
static gint
gtk_list_store_get_n_columns (GtkTreeModel *tree_model)
{
@@ -350,6 +360,9 @@ static gint
gtk_list_store_iter_n_children (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
+ if (iter == NULL)
+ return g_slist_length (G_SLIST (GTK_LIST_STORE (tree_model)->root));
+
return 0;
}
diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c
index af752dfd6..ef3f05c65 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -260,7 +260,7 @@ gtk_tree_path_free (GtkTreePath *path)
* gtk_tree_path_copy:
* @path: A #GtkTreePath.
*
- * Creates a new #GtkTreePath based upon @path.
+ * Creates a new #GtkTreePath as a copy of @path.
*
* Return value: A new #GtkTreePath.
**/
@@ -381,6 +381,69 @@ gtk_tree_path_down (GtkTreePath *path)
gtk_tree_path_append_index (path, 0);
}
+
+/**
+ * gtk_tree_iter_copy:
+ * @iter: A #GtkTreeIter.
+ *
+ * Creates a dynamically allocated tree iterator as a copy of @iter. This
+ * function is not intended for use in applications, because you can just copy
+ * the structs by value (<literal>GtkTreeIter new_iter = iter;</literal>). You
+ * must free this iter with gtk_tree_iter_free ().
+ *
+ * Return value: a newly allocated copy of @iter.
+ **/
+GtkTreeIter *
+gtk_tree_iter_copy (GtkTreeIter *iter)
+{
+ GtkTreeIter *retval;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ retval = g_new (GtkTreeIter, 1);
+ *retval = *iter;
+
+ return retval;
+}
+
+/**
+ * gtk_tree_iter_free:
+ * @iter: A dynamically allocated tree iterator.
+ *
+ * Free an iterator that has been allocated on the heap. This function is
+ * mainly used for language bindings.
+ **/
+void
+gtk_tree_iter_free (GtkTreeIter *iter)
+{
+ g_return_if_fail (iter != NULL);
+
+ g_free (iter);
+
+}
+
+/**
+ * gtk_tree_model_get_flags:
+ * @tree_model: A #GtkTreeModel.
+ *
+ * Returns a list of flags supported by this interface. The flags are a bitwise
+ * combination of #GtkTreeModelFlags. It is expected that the flags supported
+ * do not change for an interface.
+ *
+ * Return value: The flags supported by this interface.
+ **/
+guint
+gtk_tree_model_get_flags (GtkTreeModel *tree_model)
+{
+ g_return_val_if_fail (tree_model != NULL, 0);
+ g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
+
+ if (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags)
+ return (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags) (tree_model);
+
+ return 0;
+}
+
/**
* gtk_tree_model_get_n_columns:
* @tree_model: A #GtkTreeModel.
@@ -400,6 +463,27 @@ gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
}
/**
+ * gtk_tree_model_get_column_type:
+ * @tree_model: A #GtkTreeModel.
+ * @index: The column index.
+ *
+ * Returns the type of the column.
+ *
+ * Return value: The type of the column.
+ **/
+GType
+gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
+ gint index)
+{
+ g_return_val_if_fail (tree_model != NULL, G_TYPE_INVALID);
+ g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
+ g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type != NULL, G_TYPE_INVALID);
+ g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
+
+ return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type) (tree_model, index);
+}
+
+/**
* gtk_tree_model_get_iter:
* @tree_model: A #GtkTreeModel.
* @iter: The uninitialized #GtkTreeIter.
@@ -564,9 +648,10 @@ gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
/**
* gtk_tree_model_iter_n_children:
* @tree_model: A #GtkTreeModel.
- * @iter: The #GtkTreeIter.
+ * @iter: The #GtkTreeIter, or NULL.
*
- * Returns the number of children that @iter has.
+ * Returns the number of children that @iter has. If @iter is NULL, then the
+ * number of toplevel nodes is returned.
*
* Return value: The number of children of @iter.
**/
@@ -576,7 +661,6 @@ gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
{
g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
- g_return_val_if_fail (iter != NULL, 0);
g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children != NULL, 0);
return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children) (tree_model, iter);
@@ -589,10 +673,11 @@ gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
* @parent: The #GtkTreeIter to get the child from, or NULL.
* @n: Then index of the desired child.
*
- * Sets @iter to be the child of @parent, using the given index. The first index
- * is 0. If the index is too big, or @parent has no children, @iter is set to an
- * invalid iterator and FALSE is returned. @parent will remain a valid node after
- * this function has been called. If @parent is NULL, then the root node is assumed.
+ * Sets @iter to be the child of @parent, using the given index. The first
+ * index is 0. If the index is too big, or @parent has no children, @iter is
+ * set to an invalid iterator and FALSE is returned. @parent will remain a
+ * valid node after this function has been called. If @parent is NULL, then the
+ * root node is assumed.
*
* Return value: TRUE, if @parent has an nth child.
**/
@@ -629,8 +714,51 @@ gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *child)
{
+ g_return_val_if_fail (tree_model != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (child != NULL, FALSE);
g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent != NULL, FALSE);
return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent) (tree_model, iter, child);
}
+/**
+ * gtk_tree_model_ref_iter:
+ * @tree_model: A #GtkTreeModel.
+ * @iter: The #GtkTreeIter.
+ *
+ * Ref's the iter. This is an optional method for models to implement. To be
+ * more specific, models may ignore this call as it exists primarily for
+ * performance reasons.
+ **/
+void
+gtk_tree_model_ref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ g_return_if_fail (tree_model != NULL);
+ g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
+
+ if (GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter)
+ (* GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter) (tree_model, iter);
+}
+
+/**
+ * gtk_tree_model_unref_iter:
+ * @tree_model: A #GtkTreeModel.
+ * @iter: The #GtkTreeIter.
+ *
+ * Unref's the iter. This is an optional method for models to implement. To be
+ * more specific, models may ignore this call as it exists primarily for
+ * performance reasons.
+ **/
+void
+gtk_tree_model_unref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ g_return_if_fail (tree_model != NULL);
+ g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
+
+ if (GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter)
+ (* GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter) (tree_model, iter);
+}
diff --git a/gtk/gtktreemodel.h b/gtk/gtktreemodel.h
index fce77d607..ec5ba2b28 100644
--- a/gtk/gtktreemodel.h
+++ b/gtk/gtktreemodel.h
@@ -37,10 +37,18 @@ typedef struct _GtkTreePath GtkTreePath;
typedef struct _GtkTreeModel GtkTreeModel; /* Dummy typedef */
typedef struct _GtkTreeModelIface GtkTreeModelIface;
+
+typedef enum
+{
+ GTK_TREE_MODEL_ITERS_PERSIST = 1 << 0
+} GtkTreeModelFlags;
+
struct _GtkTreeIter
{
gint stamp;
gpointer tree_node;
+ gpointer tree_node2;
+ gpointer tree_node3;
};
struct _GtkTreeModelIface
@@ -65,6 +73,7 @@ struct _GtkTreeModelIface
GtkTreePath *path);
/* VTable - not signals */
+ guint (* get_flags) (GtkTreeModel *tree_model);
gint (* get_n_columns) (GtkTreeModel *tree_model);
GType (* get_column_type) (GtkTreeModel *tree_model,
gint index);
@@ -93,10 +102,14 @@ struct _GtkTreeModelIface
gboolean (* iter_parent) (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *child);
+ void (* ref_iter) (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+ void (* unref_iter) (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
};
-/* Path operations */
+/* GtkTreePath operations */
GtkTreePath *gtk_tree_path_new (void);
GtkTreePath *gtk_tree_path_new_from_string (gchar *path);
gchar *gtk_tree_path_to_string (GtkTreePath *path);
@@ -117,9 +130,13 @@ gint gtk_tree_path_up (GtkTreePath *path);
void gtk_tree_path_down (GtkTreePath *path);
+/* GtkTreeIter operations */
+GtkTreeIter *gtk_tree_iter_copy (GtkTreeIter *iter);
+void gtk_tree_iter_free (GtkTreeIter *iter);
+
/* GtkTreeModel stuff */
GtkType gtk_tree_model_get_type (void) G_GNUC_CONST;
-
+guint gtk_tree_model_get_flags (GtkTreeModel *tree_model);
/* Column information */
gint gtk_tree_model_get_n_columns (GtkTreeModel *tree_model);
@@ -153,7 +170,10 @@ gboolean gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
gboolean gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *child);
-
+void gtk_tree_model_ref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+void gtk_tree_model_unref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
#ifdef __cplusplus
}
diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c
new file mode 100644
index 000000000..608aeb84f
--- /dev/null
+++ b/gtk/gtktreemodelsort.c
@@ -0,0 +1,897 @@
+/* gtktreemodelsort.c
+ * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@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 "gtktreemodelsort.h"
+#include "gtksignal.h"
+
+enum {
+ CHANGED,
+ INSERTED,
+ CHILD_TOGGLED,
+ DELETED,
+ LAST_SIGNAL
+};
+
+typedef struct _SortElt SortElt;
+struct _SortElt
+{
+ GtkTreeIter iter;
+ SortElt *parent;
+ GArray *children;
+ gint ref;
+ gint offset;
+};
+
+static guint tree_model_sort_signals[LAST_SIGNAL] = { 0 };
+
+
+#define get_array(e,t) ((GArray *)((e)->parent?(e)->parent->children:GTK_TREE_MODEL_SORT(t)->root))
+
+static void gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort);
+static void gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class);
+static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
+static void gtk_tree_model_sort_finalize (GObject *object);
+static void gtk_tree_model_sort_changed (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data);
+static void gtk_tree_model_sort_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data);
+static void gtk_tree_model_sort_child_toggled (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data);
+static void gtk_tree_model_sort_deleted (GtkTreeModel *model,
+ GtkTreePath *path,
+ gpointer data);
+static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
+static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
+ gint index);
+static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path);
+static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gint column,
+ GValue *value);
+static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent);
+static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n);
+static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child);
+static void gtk_tree_model_sort_ref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static void gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+
+/* Internal functions */
+static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
+ SortElt *place);
+static void gtk_tree_model_sort_free_level (GArray *array);
+gint g_value_string_compare_func (const GValue *a,
+ const GValue *b);
+gint g_value_int_compare_func (const GValue *a,
+ const GValue *b);
+
+
+GtkType
+gtk_tree_model_sort_get_type (void)
+{
+ static GtkType tree_model_sort_type = 0;
+
+ if (!tree_model_sort_type)
+ {
+ static const GTypeInfo tree_model_sort_info =
+ {
+ sizeof (GtkTreeModelSortClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_tree_model_sort_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkTreeModelSort),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_tree_model_sort_init
+ };
+
+ static const GInterfaceInfo tree_model_info =
+ {
+ (GInterfaceInitFunc) gtk_tree_model_sort_tree_model_init,
+ NULL,
+ NULL
+ };
+
+ tree_model_sort_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeModelSort", &tree_model_sort_info, 0);
+ g_type_add_interface_static (tree_model_sort_type,
+ GTK_TYPE_TREE_MODEL,
+ &tree_model_info);
+ }
+
+ return tree_model_sort_type;
+}
+
+static void
+gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) tree_model_sort_class;
+
+ tree_model_sort_signals[CHANGED] =
+ gtk_signal_new ("changed",
+ GTK_RUN_FIRST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, changed),
+ gtk_marshal_VOID__POINTER_POINTER,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_POINTER);
+ tree_model_sort_signals[INSERTED] =
+ gtk_signal_new ("inserted",
+ GTK_RUN_FIRST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, inserted),
+ gtk_marshal_VOID__POINTER_POINTER,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_POINTER);
+ tree_model_sort_signals[CHILD_TOGGLED] =
+ gtk_signal_new ("child_toggled",
+ GTK_RUN_FIRST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, child_toggled),
+ gtk_marshal_VOID__POINTER_POINTER,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_POINTER);
+ tree_model_sort_signals[DELETED] =
+ gtk_signal_new ("deleted",
+ GTK_RUN_FIRST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, deleted),
+ gtk_marshal_VOID__POINTER,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_POINTER);
+
+ object_class->finalize = gtk_tree_model_sort_finalize;
+
+ gtk_object_class_add_signals (GTK_OBJECT_CLASS (object_class), tree_model_sort_signals, LAST_SIGNAL);
+}
+
+static void
+gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
+ iface->get_column_type = gtk_tree_model_sort_get_column_type;
+ iface->get_iter = gtk_tree_model_sort_get_iter;
+ iface->get_path = gtk_tree_model_sort_get_path;
+ iface->get_value = gtk_tree_model_sort_get_value;
+ iface->iter_next = gtk_tree_model_sort_iter_next;
+ iface->iter_children = gtk_tree_model_sort_iter_children;
+ iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
+ iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
+ iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
+ iface->iter_parent = gtk_tree_model_sort_iter_parent;
+ iface->ref_iter = gtk_tree_model_sort_ref_iter;
+ iface->unref_iter = gtk_tree_model_sort_unref_iter;
+}
+
+static void
+gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
+{
+ tree_model_sort->stamp = g_random_int ();
+}
+
+GtkTreeModel *
+gtk_tree_model_sort_new (void)
+{
+ return GTK_TREE_MODEL (gtk_type_new (gtk_tree_model_sort_get_type ()));
+}
+
+GtkTreeModel *
+gtk_tree_model_sort_new_with_model (GtkTreeModel *model,
+ GValueCompareFunc *func,
+ gint sort_col)
+{
+ GtkTreeModel *retval;
+
+ retval = gtk_tree_model_sort_new ();
+ gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), model);
+
+ GTK_TREE_MODEL_SORT (retval)->func = func;
+ GTK_TREE_MODEL_SORT (retval)->sort_col = sort_col;
+ return retval;
+}
+
+/**
+ * gtk_tree_model_sort_set_model:
+ * @tree_model_sort: The #GtkTreeModelSort.
+ * @model: A #GtkTreeModel, or NULL.
+ *
+ * Sets the model of @tree_model_sort to be @model. If @model is NULL, then the
+ * old model is unset.
+ **/
+void
+gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
+ GtkTreeModel *model)
+{
+ g_return_if_fail (tree_model_sort != NULL);
+ g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
+
+ if (model)
+ g_object_ref (G_OBJECT (model));
+
+ if (tree_model_sort->model)
+ {
+ gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+ gtk_tree_model_sort_changed,
+ tree_model_sort);
+ gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+ gtk_tree_model_sort_inserted,
+ tree_model_sort);
+ gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+ gtk_tree_model_sort_child_toggled,
+ tree_model_sort);
+ gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+ gtk_tree_model_sort_deleted,
+ tree_model_sort);
+
+ g_object_unref (G_OBJECT (tree_model_sort->model));
+ }
+
+ tree_model_sort->model = model;
+
+ if (model)
+ {
+ gtk_signal_connect (GTK_OBJECT (model),
+ "changed",
+ gtk_tree_model_sort_changed,
+ tree_model_sort);
+ gtk_signal_connect (GTK_OBJECT (model),
+ "inserted",
+ gtk_tree_model_sort_inserted,
+ tree_model_sort);
+ gtk_signal_connect (GTK_OBJECT (model),
+ "child_toggled",
+ gtk_tree_model_sort_child_toggled,
+ tree_model_sort);
+ gtk_signal_connect (GTK_OBJECT (model),
+ "deleted",
+ gtk_tree_model_sort_deleted,
+ tree_model_sort);
+
+ tree_model_sort->flags = gtk_tree_model_get_flags (model);
+ }
+}
+
+/**
+ * gtk_tree_model_sort_convert_path:
+ * @tree_model_sort: The #GtkTreeModelSort.
+ * @path: A #GtkTreePath, relative to the @tree_model_sort 's model.
+ *
+ * Converts the @path to a new path, relative to the sorted position. In other
+ * words, the value found in the @tree_model_sort ->model at the @path, is
+ * identical to that found in the @tree_model_sort and the return value.
+ *
+ * Return value: A new path, or NULL if @path does not exist in @tree_model_sort
+ * ->model.
+ **/
+GtkTreePath *
+gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
+ GtkTreePath *path)
+{
+ GtkTreePath *retval;
+ GArray *array;
+ gint *indices;
+ gint i = 0;
+
+ if (tree_model_sort->root == NULL)
+ gtk_tree_model_sort_build_level (tree_model_sort, NULL);
+
+ retval = gtk_tree_path_new ();
+ array = (GArray *) tree_model_sort->root;
+ indices = gtk_tree_path_get_indices (path);
+
+ do
+ {
+ SortElt *elt;
+ gboolean found = FALSE;
+ gint j;
+
+ if ((array->len < indices[i]) || (array == NULL))
+ {
+ gtk_tree_path_free (path);
+ return NULL;
+ }
+
+ elt = (SortElt *) array->data;
+ for (j = 0; j < array->len; j++, elt++)
+ {
+ if (elt->offset == indices[i])
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (! found)
+ {
+ gtk_tree_path_free (path);
+ return NULL;
+ }
+
+ gtk_tree_path_prepend_index (retval, j);
+ if (elt->children == NULL)
+ gtk_tree_model_sort_build_level (tree_model_sort, elt);
+ i++;
+ }
+ while (i < gtk_tree_path_get_depth (path));
+
+ return retval;
+}
+
+static void
+gtk_tree_model_sort_finalize (GObject *object)
+{
+ GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
+
+ if (tree_model_sort->root)
+ gtk_tree_model_sort_free_level (tree_model_sort->root);
+
+ g_object_unref (G_OBJECT (tree_model_sort->model));
+}
+
+static void
+gtk_tree_model_sort_changed (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+ GtkTreePath *local_path;
+ GtkTreeIter local_iter;
+
+ g_return_if_fail (path != NULL || iter != NULL);
+
+ if (path == NULL)
+ path = gtk_tree_model_get_path (model, iter);
+
+ local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
+ gtk_signal_emit_by_name (GTK_OBJECT (data),
+ "changed",
+ local_path,
+ &local_iter);
+ gtk_tree_path_free (local_path);
+}
+
+#if 0
+static void
+gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
+ GtkTreeIter *old_iter,
+ GtkTreePath *path)
+{
+ GtkTreePath *parent_path;
+ GArray *array;
+ GtkTreeIter iter;
+ SortElt new_elt;
+ SortElt *tmp_elt;
+ gint high, low, middle;
+ GValueCompareFunc *func;
+ GValue tmp_value = {0, };
+ GValue old_value = {0, };
+
+ parent_path = gtk_tree_path_copy (path);
+ gtk_tree_path_up (parent_path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (sort),
+ &iter,
+ parent_path);
+ gtk_tree_path_free (parent_path);
+ array = ((SortElt *) iter.tree_node)->children;
+
+ if (sort->func)
+ func = sort->func;
+ else
+ {
+ switch (gtk_tree_model_get_column_type (sort->model, sort->sort_col))
+ {
+ case G_TYPE_STRING:
+ func = &g_value_string_compare_func;
+ break;
+ case G_TYPE_INT:
+ func = &g_value_int_compare_func;
+ break;
+ default:
+ g_warning ("No comparison function for row %d\n", sort->sort_col);
+ return;
+ }
+ }
+
+ new_elt.iter = iter;
+ new_elt.ref = 0;
+ new_elt.parent = ((SortElt *) iter.tree_node);
+ new_elt.children = NULL;
+
+ last = 0;
+ j = array->len/2;
+ while (1)
+ {
+ gint cmp;
+ tmp_elt = &(g_array_index (array, SortElt, j));
+ gtk_tree_model_get_value (sort->model, tmp_elt, sort->sort_col, &tmp_value);
+
+ cmp = ((func) (&tmp_value, value));
+ if (retval < 0)
+ ;
+ else if (retval == 0)
+ g_array_insert_vals
+ ;
+ else if (retval > 0)
+ ;
+ }
+}
+#endif
+
+static void
+gtk_tree_model_sort_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+ GtkTreePath *local_path;
+ GtkTreeIter local_iter;
+ GValue value;
+
+ g_return_if_fail (path != NULL || iter != NULL);
+
+ if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
+ (tree_model_sort->root != NULL))
+ {
+ gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
+ tree_model_sort->root = NULL;
+ }
+
+ if (path == NULL)
+ path = gtk_tree_model_get_path (model, iter);
+
+ local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
+ gtk_signal_emit_by_name (GTK_OBJECT (data),
+ "inserted",
+ local_path,
+ &local_iter);
+ gtk_tree_path_free (local_path);
+}
+
+static void
+gtk_tree_model_sort_child_toggled (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+ GtkTreePath *local_path;
+ GtkTreeIter local_iter;
+
+ g_return_if_fail (path != NULL || iter != NULL);
+
+ if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
+ (tree_model_sort->root != NULL))
+ {
+ gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
+ tree_model_sort->root = NULL;
+ }
+
+ if (path == NULL)
+ path = gtk_tree_model_get_path (model, iter);
+
+ local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
+ gtk_signal_emit_by_name (GTK_OBJECT (data),
+ "child_toggled",
+ local_path,
+ &local_iter);
+ gtk_tree_path_free (local_path);
+}
+
+static void
+gtk_tree_model_sort_deleted (GtkTreeModel *model,
+ GtkTreePath *path,
+ gpointer data)
+{
+ GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+ GtkTreePath *local_path;
+
+ g_return_if_fail (path != NULL);
+
+ if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
+ (tree_model_sort->root != NULL))
+ {
+ gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
+ tree_model_sort->root = NULL;
+ }
+ local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+ tree_model_sort->stamp++;
+ gtk_signal_emit_by_name (GTK_OBJECT (data),
+ "deleted",
+ local_path);
+
+ gtk_tree_path_free (local_path);
+}
+
+static gint
+gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
+{
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, 0);
+
+ return gtk_tree_model_get_n_columns (GTK_TREE_MODEL_SORT (tree_model)->model);
+}
+
+static GType
+gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
+ gint index)
+{
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), G_TYPE_INVALID);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, G_TYPE_INVALID);
+
+ return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->model, index);
+}
+
+static gboolean
+gtk_tree_model_sort_get_iter_helper (GtkTreeModelSort *tree_model_sort,
+ GArray *array,
+ GtkTreeIter *iter,
+ gint depth,
+ GtkTreePath *path)
+{
+ SortElt *elt;
+
+ if (array == NULL)
+ return FALSE;
+
+ if (gtk_tree_path_get_indices (path)[depth] > array->len)
+ return FALSE;
+
+ elt = & (g_array_index (array, SortElt, gtk_tree_path_get_indices (path)[depth]));
+
+ if (depth == gtk_tree_path_get_depth (path) - 1)
+ {
+ iter->stamp = tree_model_sort->stamp;
+ iter->tree_node = elt;
+ return TRUE;
+ }
+
+ if (elt->children != NULL)
+ return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
+ elt->children,
+ iter,
+ depth + 1,
+ path);
+
+ if (gtk_tree_model_iter_has_child (tree_model_sort->model,
+ &(elt->iter)))
+
+ gtk_tree_model_sort_build_level (tree_model_sort, elt);
+
+ return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
+ elt->children,
+ iter,
+ depth + 1,
+ path);
+}
+
+static gboolean
+gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+
+ if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
+ gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
+
+ return gtk_tree_model_sort_get_iter_helper (GTK_TREE_MODEL_SORT (tree_model),
+ GTK_TREE_MODEL_SORT (tree_model)->root,
+ iter, 0, path);
+}
+
+static GtkTreePath *
+gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, NULL);
+
+ return gtk_tree_model_get_path (GTK_TREE_MODEL_SORT (tree_model)->model, iter);
+}
+
+static void
+gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gint column,
+ GValue *value)
+{
+ SortElt *elt;
+
+ g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
+ g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL);
+ g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
+
+ elt = iter->tree_node;
+
+ gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt, column, value);
+}
+
+static gboolean
+gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ GArray *array;
+ SortElt *elt;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
+
+ elt = iter->tree_node;
+ array = get_array (elt, tree_model);
+
+ if (elt - ((SortElt*) array->data) >= array->len - 1)
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
+ iter->tree_node = elt+1;
+ return TRUE;
+}
+
+static gboolean
+gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ SortElt *elt;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+ if (parent)
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
+
+ if (parent)
+ elt = parent->tree_node;
+ else
+ elt = (SortElt *) ((GArray *)GTK_TREE_MODEL_SORT (tree_model)->root)->data;
+
+ if (elt == NULL)
+ return FALSE;
+
+ if (elt->children == NULL &&
+ gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt))
+ gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
+
+ if (elt->children == NULL)
+ return FALSE;
+
+ iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+ iter->tree_node = elt->children->data;
+
+ return TRUE;
+}
+
+static gboolean
+gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ SortElt *elt;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
+
+ elt = iter->tree_node;
+ if (elt->children)
+ return TRUE;
+
+ return gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *) elt);
+}
+
+static gint
+gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ SortElt *elt;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, 0);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);
+
+ elt = iter->tree_node;
+ if (elt->children)
+ return elt->children->len;
+
+ return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *) elt);
+}
+
+
+static gboolean
+gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n)
+{
+ SortElt *elt;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+ if (parent)
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
+
+ elt = iter->tree_node;
+
+
+ if (elt->children == NULL)
+ {
+ if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt))
+ gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
+ else
+ return FALSE;
+ }
+
+ if (elt->children == NULL)
+ return FALSE;
+
+ if (n >= elt->children->len)
+ return FALSE;
+
+ iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+ iter->tree_node = &g_array_index (elt->children, SortElt, n);
+
+ return TRUE;
+}
+
+static gboolean
+gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child)
+{
+ SortElt *elt;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+ g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);
+
+ elt = iter->tree_node;
+ if (elt->parent)
+ {
+ iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+ iter->tree_node = elt->parent;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+gtk_tree_model_sort_ref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+}
+
+static void
+gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+
+}
+
+/* Internal functions */
+static void
+gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
+ SortElt *place)
+{
+ gint n, i;
+ GArray *children;
+ GtkTreeIter *parent_iter = NULL;
+ GtkTreeIter iter;
+ SortElt elt;
+
+ if (place)
+ parent_iter = & (place->iter);
+
+
+ n = gtk_tree_model_iter_n_children (tree_model_sort->model, parent_iter);
+
+ if (n == 0)
+ return;
+
+ children = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), n);
+
+ if (place)
+ place->children = children;
+ else
+ tree_model_sort->root = children;
+
+ gtk_tree_model_iter_children (tree_model_sort->model,
+ &iter,
+ parent_iter);
+
+ i = 0;
+ do
+ {
+ elt.iter = iter;
+ elt.parent = place;
+ elt.children = NULL;
+ elt.ref = 0;
+ elt.offset = i;
+
+ g_array_append_vals (children, &elt, 1);
+ i++;
+ }
+ while (gtk_tree_model_iter_next (tree_model_sort->model, &iter));
+
+}
+
+static void
+gtk_tree_model_sort_free_level (GArray *array)
+{
+ gint i;
+
+ for (i = 0; i < array->len; i++)
+ {
+ SortElt *elt;
+
+ elt = &g_array_index (array, SortElt, i);
+ if (elt->children)
+ gtk_tree_model_sort_free_level (array);
+ }
+
+ g_array_free (array, TRUE);
+}
+
+gint
+g_value_string_compare_func (const GValue *a,
+ const GValue *b)
+{
+ return strcmp (g_value_get_string (a),
+ g_value_get_string (b));
+}
+
+gint
+g_value_int_compare_func (const GValue *a,
+ const GValue *b)
+{
+ return g_value_get_int (a) < g_value_get_int (b);
+}
diff --git a/gtk/gtktreemodelsort.h b/gtk/gtktreemodelsort.h
new file mode 100644
index 000000000..01366e6cb
--- /dev/null
+++ b/gtk/gtktreemodelsort.h
@@ -0,0 +1,94 @@
+/* gtktreemodelsort.h
+ * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@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_SORT_H__
+#define __GTK_TREE_MODEL_SORT_H__
+
+#include <gtk/gtktreemodel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GTK_TYPE_TREE_MODEL_SORT (gtk_tree_model_sort_get_type ())
+#define GTK_TREE_MODEL_SORT(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TREE_MODEL_SORT, GtkTreeModelSort))
+#define GTK_TREE_MODEL_SORT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_MODEL_SORT, GtkTreeModelSortClass))
+#define GTK_IS_TREE_MODEL_SORT(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE_MODEL_SORT))
+#define GTK_IS_TREE_MODEL_SORT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TREE_MODEL_SORT))
+
+typedef struct _GtkTreeModelSort GtkTreeModelSort;
+typedef struct _GtkTreeModelSortClass GtkTreeModelSortClass;
+
+typedef gint (* GValueCompareFunc) (const GValue *a,
+ const GValue *b);
+
+struct _GtkTreeModelSort
+{
+ GtkObject parent;
+
+ /* < private > */
+ gpointer root;
+ gint stamp;
+ guint flags;
+ GtkTreeModel *model;
+ gint sort_col;
+ GValueCompareFunc *func;
+};
+
+struct _GtkTreeModelSortClass
+{
+ 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_sort_get_type (void);
+GtkTreeModel *gtk_tree_model_sort_new (void);
+GtkTreeModel *gtk_tree_model_sort_new_with_model (GtkTreeModel *model,
+ GValueCompareFunc *func,
+ gint sort_col);
+void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
+ GtkTreeModel *model);
+void gtk_tree_model_sort_set_sort_col (GtkTreeModelSort *tree_model_sort,
+ gint sort_col);
+void gtk_tree_model_sort_set_compare (GtkTreeModelSort *tree_model_sort,
+ GValueCompareFunc *func);
+void gtk_tree_model_sort_resort (GtkTreeModelSort *tree_model_sort);
+GtkTreePath *gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
+ GtkTreePath *path);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TREE_MODEL_SORT_H__ */
diff --git a/gtk/gtktreeselection.c b/gtk/gtktreeselection.c
index 414eae2bf..706549ee3 100644
--- a/gtk/gtktreeselection.c
+++ b/gtk/gtktreeselection.c
@@ -241,17 +241,20 @@ gtk_tree_selection_get_user_data (GtkTreeSelection *selection)
/**
* gtk_tree_selection_get_selected:
* @selection: A #GtkTreeSelection.
+ * @model: A pointer set to the #GtkTreeModel, or NULL.
* @iter: The #GtkTreeIter, or NULL.
*
* Sets @iter to the currently selected node if @selection is set to
* #GTK_TREE_SELECTION_SINGLE. Otherwise, it uses the anchor. @iter may be
- * NULL if you just want to test if @selection has any selected nodes.
+ * NULL if you just want to test if @selection has any selected nodes. @model
+ * is filled with the current model as a convenience.
*
* Return value: TRUE, if there is a selected node.
**/
gboolean
-gtk_tree_selection_get_selected (GtkTreeSelection *selection,
- GtkTreeIter *iter)
+gtk_tree_selection_get_selected (GtkTreeSelection *selection,
+ GtkTreeModel **model,
+ GtkTreeIter *iter)
{
GtkRBTree *tree;
GtkRBNode *node;
@@ -274,9 +277,11 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection,
! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
/* We don't want to return the anchor if it isn't actually selected.
*/
-
return FALSE;
+ if (model)
+ *model = selection->tree_view->priv->model;
+
return gtk_tree_model_get_iter (selection->tree_view->priv->model,
iter,
selection->tree_view->priv->anchor);
diff --git a/gtk/gtktreeselection.h b/gtk/gtktreeselection.h
index cafedf7dd..3f7201ec3 100644
--- a/gtk/gtktreeselection.h
+++ b/gtk/gtktreeselection.h
@@ -79,6 +79,7 @@ gpointer gtk_tree_selection_get_user_data (GtkTreeSelection
/* Only meaningful if GTK_TREE_SELECTION_SINGLE is set */
/* Use selected_foreach for GTK_TREE_SELECTION_MULTI */
gboolean gtk_tree_selection_get_selected (GtkTreeSelection *selection,
+ GtkTreeModel **model,
GtkTreeIter *iter);
/* FIXME: Get a more convenient get_selection function???? one returning GSList?? */
diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c
index 3454202ad..44befc800 100644
--- a/gtk/gtktreestore.c
+++ b/gtk/gtktreestore.c
@@ -40,6 +40,7 @@ static guint tree_store_signals[LAST_SIGNAL] = { 0 };
static void gtk_tree_store_init (GtkTreeStore *tree_store);
static void gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class);
static void gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
+static guint gtk_tree_store_get_flags (GtkTreeModel *tree_model);
static gint gtk_tree_store_get_n_columns (GtkTreeModel *tree_model);
static GtkTreePath *gtk_tree_store_get_path (GtkTreeModel *tree_model,
GtkTreeIter *iter);
@@ -58,11 +59,11 @@ static gint gtk_tree_store_iter_n_children (GtkTreeModel *tree_mode
GtkTreeIter *iter);
static gboolean gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
GtkTreeIter *iter,
- GtkTreeIter *child,
+ GtkTreeIter *parent,
gint n);
static gboolean gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
GtkTreeIter *iter,
- GtkTreeIter *parent);
+ GtkTreeIter *child);
GtkType
@@ -150,6 +151,7 @@ gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
static void
gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
{
+ iface->get_flags = gtk_tree_store_get_flags;
iface->get_n_columns = gtk_tree_store_get_n_columns;
iface->get_path = gtk_tree_store_get_path;
iface->get_value = gtk_tree_store_get_value;
@@ -165,7 +167,7 @@ static void
gtk_tree_store_init (GtkTreeStore *tree_store)
{
tree_store->root = g_node_new (NULL);
- tree_store->stamp = 1;
+ tree_store->stamp = g_random_int ();
}
GtkTreeStore *
@@ -242,10 +244,19 @@ gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
* it is not visible to the tree or to the user., and the path "1" refers to the
* first child of GtkTreeStore::root.
*/
+
+
+static guint
+gtk_tree_store_get_flags (GtkTreeModel *tree_model)
+{
+ g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
+
+ return GTK_TREE_MODEL_ITERS_PERSIST;
+}
+
static gint
gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
{
- g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
return GTK_TREE_STORE (tree_model)->n_columns;
@@ -362,7 +373,10 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model,
GtkTreeIter *parent)
{
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
- iter->tree_node = G_NODE (parent->tree_node)->children;
+ if (parent)
+ iter->tree_node = G_NODE (parent->tree_node)->children;
+ else
+ iter->tree_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
return iter->tree_node != NULL;
}
@@ -388,10 +402,13 @@ gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
- g_return_val_if_fail (iter != NULL, 0);
- g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
+ if (iter)
+ g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
- node = G_NODE (iter->tree_node)->children;
+ if (iter == NULL)
+ node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
+ else
+ node = G_NODE (iter->tree_node)->children;
while (node)
{
i++;
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 837948610..de3d50472 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -2037,6 +2037,8 @@ gtk_tree_view_inserted (GtkTreeModel *model,
}
}
+ /* ref the node */
+ gtk_tree_model_ref_iter (tree_view->priv->model, iter);
max_height = gtk_tree_view_insert_iter_height (tree_view,
tree,
iter,
@@ -2245,6 +2247,8 @@ gtk_tree_view_build_tree (GtkTreeView *tree_view,
tree,
iter,
depth);
+
+ gtk_tree_model_ref_iter (tree_view->priv->model, iter);
temp = _gtk_rbtree_insert_after (tree, temp, max_height);
if (recurse)
{
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index 6c51f4355..2ecefdb5b 100644
--- a/gtk/gtktreeviewcolumn.c
+++ b/gtk/gtktreeviewcolumn.c
@@ -145,12 +145,12 @@ gtk_real_tree_column_clicked (GtkTreeViewColumn *tree_column)
*
* Return value: A newly created #GtkTreeViewColumn.
**/
-GtkObject *
+GtkTreeViewColumn *
gtk_tree_view_column_new (void)
{
- GtkObject *retval;
+ GtkTreeViewColumn *retval;
- retval = GTK_OBJECT (gtk_type_new (GTK_TYPE_TREE_COLUMN));
+ retval = GTK_TREE_VIEW_COLUMN (gtk_type_new (GTK_TYPE_TREE_COLUMN));
return retval;
}
@@ -168,22 +168,21 @@ gtk_tree_view_column_new (void)
*
* Return value: A newly created #GtkTreeViewColumn.
**/
-GtkObject *
+GtkTreeViewColumn *
gtk_tree_view_column_new_with_attributes (gchar *title,
GtkCellRenderer *cell,
...)
{
- GtkObject *retval;
+ GtkTreeViewColumn *retval;
va_list args;
retval = gtk_tree_view_column_new ();
- gtk_tree_view_column_set_title (GTK_TREE_VIEW_COLUMN (retval), title);
- gtk_tree_view_column_set_cell_renderer (GTK_TREE_VIEW_COLUMN (retval), cell);
+ gtk_tree_view_column_set_title (retval, title);
+ gtk_tree_view_column_set_cell_renderer (retval, cell);
va_start (args, cell);
- gtk_tree_view_column_set_attributesv (GTK_TREE_VIEW_COLUMN (retval),
- args);
+ gtk_tree_view_column_set_attributesv (retval, args);
va_end (args);
return retval;
diff --git a/gtk/gtktreeviewcolumn.h b/gtk/gtktreeviewcolumn.h
index 091ff0715..148c488ac 100644
--- a/gtk/gtktreeviewcolumn.h
+++ b/gtk/gtktreeviewcolumn.h
@@ -82,51 +82,53 @@ struct _GtkTreeViewColumnClass
};
-GtkType gtk_tree_view_column_get_type (void);
-GtkObject *gtk_tree_view_column_new (void);
-GtkObject *gtk_tree_view_column_new_with_attributes (gchar *title,
- GtkCellRenderer *cell,
- ...);
-void gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
- GtkCellRenderer *cell);
-void gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
- gchar *attribute,
- gint column);
-void gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
- ...);
-void gtk_tree_view_column_set_cell_data (GtkTreeViewColumn *tree_column,
- GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-void gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
- gboolean visible);
-gboolean gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column);
-void gtk_tree_view_column_set_col_type (GtkTreeViewColumn *tree_column,
- GtkTreeViewColumnType type);
-gint gtk_tree_view_column_get_col_type (GtkTreeViewColumn *tree_column);
-gint gtk_tree_view_column_get_size (GtkTreeViewColumn *tree_column);
-void gtk_tree_view_column_set_size (GtkTreeViewColumn *tree_column,
- gint size);
-void gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
- gint min_width);
-gint gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column);
-void gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
- gint max_width);
-gint gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column);
+GtkType gtk_tree_view_column_get_type (void);
+GtkTreeViewColumn *gtk_tree_view_column_new (void);
+GtkTreeViewColumn *gtk_tree_view_column_new_with_attributes (gchar *title,
+ GtkCellRenderer *cell,
+ ...);
+void gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell);
+void gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
+ gchar *attribute,
+ gint column);
+void gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
+ ...);
+void gtk_tree_view_column_set_cell_data (GtkTreeViewColumn *tree_column,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+void gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
+ gboolean visible);
+gboolean gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column);
+void gtk_tree_view_column_set_col_type (GtkTreeViewColumn *tree_column,
+ GtkTreeViewColumnType type);
+gint gtk_tree_view_column_get_col_type (GtkTreeViewColumn *tree_column);
+gint gtk_tree_view_column_get_size (GtkTreeViewColumn *tree_column);
+void gtk_tree_view_column_set_size (GtkTreeViewColumn *tree_column,
+ gint size);
+void gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
+ gint min_width);
+gint gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column);
+void gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
+ gint max_width);
+gint gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column);
+
/* Options for manipulating the column headers
*/
-void gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
- gchar *title);
-gchar *gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column);
-void gtk_tree_view_column_set_header_active (GtkTreeViewColumn *tree_column,
- gboolean active);
-void gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
- GtkWidget *widget);
-GtkWidget *gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column);
-void gtk_tree_view_column_set_justification (GtkTreeViewColumn *tree_column,
- GtkJustification justification);
-GtkJustification gtk_tree_view_column_get_justification (GtkTreeViewColumn *tree_column);
+void gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
+ gchar *title);
+gchar *gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column);
+void gtk_tree_view_column_set_header_active (GtkTreeViewColumn *tree_column,
+ gboolean active);
+void gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
+ GtkWidget *widget);
+GtkWidget *gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column);
+void gtk_tree_view_column_set_justification (GtkTreeViewColumn *tree_column,
+ GtkJustification justification);
+GtkJustification gtk_tree_view_column_get_justification (GtkTreeViewColumn *tree_column);
+
#ifdef __cplusplus
diff --git a/gtk/treestoretest.c b/gtk/treestoretest.c
index d1c311c83..3835d9d17 100644
--- a/gtk/treestoretest.c
+++ b/gtk/treestoretest.c
@@ -7,8 +7,7 @@ static void
selection_changed (GtkTreeSelection *selection,
GtkWidget *button)
{
- if (gtk_tree_selection_get_selected (selection,
- NULL))
+ if (gtk_tree_selection_get_selected (selection, NULL, NULL))
gtk_widget_set_sensitive (button, TRUE);
else
gtk_widget_set_sensitive (button, FALSE);
@@ -31,6 +30,7 @@ iter_remove (GtkWidget *button, GtkTreeView *tree_view)
{
GtkTreeIter selected;
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+ NULL,
&selected))
{
gtk_tree_store_remove (model, &selected);
@@ -46,6 +46,7 @@ iter_insert (GtkWidget *button, GtkTreeView *tree_view)
entry = gtk_object_get_user_data (GTK_OBJECT (button));
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+ NULL,
&selected))
{
gtk_tree_store_insert (model,
@@ -71,6 +72,7 @@ iter_insert_before (GtkWidget *button, GtkTreeView *tree_view)
GtkTreeIter selected;
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+ NULL,
&selected))
{
gtk_tree_store_insert_before (model,
@@ -96,6 +98,7 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
GtkTreeIter selected;
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+ NULL,
&selected))
{
gtk_tree_store_insert_after (model,
@@ -121,6 +124,7 @@ iter_prepend (GtkWidget *button, GtkTreeView *tree_view)
GtkTreeIter selected;
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+ NULL,
&selected))
{
gtk_tree_store_prepend (model,
@@ -144,6 +148,7 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
GtkTreeIter selected;
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+ NULL,
&selected))
{
gtk_tree_store_append (model, &iter, &selected);
@@ -159,13 +164,14 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
static void
make_window ()
{
+ GtkTreeModel *sort_model;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *hbox, *entry;
GtkWidget *button;
GtkWidget *scrolled_window;
GtkWidget *tree_view;
- GtkObject *column;
+ GtkTreeViewColumn *column;
GtkCellRenderer *cell;
GtkObject *selection;
@@ -175,7 +181,9 @@ make_window ()
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);
- tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+ sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model),
+ NULL, 0);
+ tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)));
gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection), GTK_TREE_SELECTION_SINGLE);
@@ -237,7 +245,7 @@ make_window ()
/* The selected column */
cell = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("nodes", cell, "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
/* A few to start */
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
@@ -254,7 +262,7 @@ main (int argc, char *argv[])
gtk_init (&argc, &argv);
model = gtk_tree_store_new_with_values (2, G_TYPE_STRING, G_TYPE_STRING);
-
+
make_window ();
make_window ();