Commit a2771e40 authored by Jonathan Blandford's avatar Jonathan Blandford

sync to home

parent f8ab34e6
...@@ -46,11 +46,20 @@ struct _SortElt ...@@ -46,11 +46,20 @@ struct _SortElt
gint offset; gint offset;
}; };
typedef struct _SortData SortData;
struct _SortData
{
GtkTreeModel *model;
gint sort_col;
GValueCompareFunc func;
};
static guint tree_model_sort_signals[LAST_SIGNAL] = { 0 }; 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)) #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_init (GtkTreeModelSort *tree_model_sort);
static void gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class); 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_tree_model_init (GtkTreeModelIface *iface);
...@@ -104,13 +113,21 @@ static void gtk_tree_model_sort_unref_iter (GtkTreeModel * ...@@ -104,13 +113,21 @@ static void gtk_tree_model_sort_unref_iter (GtkTreeModel *
GtkTreeIter *iter); GtkTreeIter *iter);
/* Internal functions */ /* Internal functions */
static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, static GtkTreePath *gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort,
SortElt *place); GtkTreePath *child_path,
static void gtk_tree_model_sort_free_level (GArray *array); gboolean build_children);
gint g_value_string_compare_func (const GValue *a, static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
const GValue *b); SortElt *place);
gint g_value_int_compare_func (const GValue *a, static void gtk_tree_model_sort_free_level (GArray *array);
const GValue *b); static GFunc gtk_tree_model_sort_get_func (GtkTreeModelSort *tree_model_sort);
static gint gtk_tree_model_sort_func (gconstpointer a,
gconstpointer b,
gpointer user_data);
static gint g_value_string_compare_func (const GValue *a,
const GValue *b);
static gint g_value_int_compare_func (const GValue *a,
const GValue *b);
GtkType GtkType
...@@ -318,53 +335,11 @@ GtkTreePath * ...@@ -318,53 +335,11 @@ GtkTreePath *
gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort, gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
GtkTreePath *child_path) GtkTreePath *child_path)
{ {
GtkTreePath *retval; g_return_val_if_fail (tree_model_sort != NULL, NULL);
GArray *array; g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
gint *indices; g_return_val_if_fail (child_path != NULL, NULL);
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 (child_path);
do
{
SortElt *elt;
gboolean found = FALSE;
gint j;
if ((array->len < indices[i]) || (array == NULL))
{
gtk_tree_path_free (retval);
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 (retval);
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 (child_path));
return retval; return gtk_tree_model_sort_convert_path_real (tree_model_sort, child_path, TRUE);
} }
static void static void
...@@ -397,7 +372,13 @@ gtk_tree_model_sort_changed (GtkTreeModel *s_model, ...@@ -397,7 +372,13 @@ gtk_tree_model_sort_changed (GtkTreeModel *s_model,
s_path = gtk_tree_model_get_path (s_model, s_iter); s_path = gtk_tree_model_get_path (s_model, s_iter);
} }
path = gtk_tree_model_sort_convert_path (tree_model_sort, s_path); path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE);
if (path == NULL)
{
if (free_s_path)
gtk_tree_path_free (s_path);
return;
}
gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path); gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
gtk_signal_emit_by_name (GTK_OBJECT (data), "changed", path, &iter); gtk_signal_emit_by_name (GTK_OBJECT (data), "changed", path, &iter);
...@@ -406,7 +387,8 @@ gtk_tree_model_sort_changed (GtkTreeModel *s_model, ...@@ -406,7 +387,8 @@ gtk_tree_model_sort_changed (GtkTreeModel *s_model,
gtk_tree_path_free (s_path); gtk_tree_path_free (s_path);
} }
static void /* FALSE if the value was inserted, TRUE otherwise */
static gboolean
gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort, gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
GtkTreePath *s_path, GtkTreePath *s_path,
GtkTreeIter *s_iter) GtkTreeIter *s_iter)
...@@ -417,7 +399,7 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort, ...@@ -417,7 +399,7 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
SortElt elt; SortElt elt;
SortElt *tmp_elt; SortElt *tmp_elt;
gint offset; gint offset;
gint high, low, middle, j; gint middle, j;
GValueCompareFunc func; GValueCompareFunc func;
GValue s_value = {0, }; GValue s_value = {0, };
GValue tmp_value = {0, }; GValue tmp_value = {0, };
...@@ -428,21 +410,28 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort, ...@@ -428,21 +410,28 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
elt.ref = 0; elt.ref = 0;
elt.children = NULL; elt.children = NULL;
elt.offset = offset; elt.offset = offset;
tmp_path = gtk_tree_path_copy (s_path); tmp_path = gtk_tree_path_copy (s_path);
if (gtk_tree_path_up (tmp_path)) if (gtk_tree_path_up (tmp_path))
{ {
GtkTreePath *parent_path; GtkTreePath *parent_path;
parent_path = gtk_tree_model_sort_convert_path (sort, tmp_path); parent_path = gtk_tree_model_sort_convert_path_real (sort, tmp_path, FALSE);
if (parent_path == NULL)
{
gtk_tree_path_free (tmp_path);
return FALSE;
}
gtk_tree_model_get_iter (GTK_TREE_MODEL (sort), &iter, parent_path); gtk_tree_model_get_iter (GTK_TREE_MODEL (sort), &iter, parent_path);
elt.parent = ((SortElt *) iter.tree_node); elt.parent = ((SortElt *) iter.tree_node);
array = ((SortElt *) iter.tree_node)->children; array = ((SortElt *) iter.tree_node)->children;
gtk_tree_path_free (parent_path);
if (array == NULL) if (array == NULL)
{ {
((SortElt *) iter.tree_node)->children = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), 1); gtk_tree_path_free (tmp_path);
array = ((SortElt *) iter.tree_node)->children; return FALSE;
} }
gtk_tree_path_free (parent_path);
} }
else else
{ {
...@@ -453,25 +442,9 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort, ...@@ -453,25 +442,9 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
} }
gtk_tree_path_free (tmp_path); gtk_tree_path_free (tmp_path);
if (sort->func) func = (GValueCompareFunc) gtk_tree_model_sort_get_func (sort);
func = sort->func;
else g_return_val_if_fail (func != NULL, FALSE);
{
switch (gtk_tree_model_get_column_type (sort->child_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 (Type %s)\n",
sort->sort_col,
g_type_name (gtk_tree_model_get_column_type (sort->child_model, sort->sort_col)));
return;
}
}
gtk_tree_model_get_value (sort->child_model, s_iter, sort->sort_col, &s_value); gtk_tree_model_get_value (sort->child_model, s_iter, sort->sort_col, &s_value);
...@@ -535,6 +508,8 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort, ...@@ -535,6 +508,8 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
j != middle) j != middle)
tmp_elt->offset ++; tmp_elt->offset ++;
} }
return TRUE;
} }
static void static void
...@@ -566,12 +541,13 @@ gtk_tree_model_sort_inserted (GtkTreeModel *s_model, ...@@ -566,12 +541,13 @@ gtk_tree_model_sort_inserted (GtkTreeModel *s_model,
else else
real_s_iter = (* s_iter); real_s_iter = (* s_iter);
gtk_tree_model_sort_insert_value (tree_model_sort, s_path, &real_s_iter); if (!gtk_tree_model_sort_insert_value (tree_model_sort, s_path, &real_s_iter))
return;
} }
path = gtk_tree_model_sort_convert_path (tree_model_sort, s_path); path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE);
if (path == NULL)
g_return_if_fail (path != NULL); return;
gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path); gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
gtk_signal_emit_by_name (GTK_OBJECT (data), "inserted", path, &iter); gtk_signal_emit_by_name (GTK_OBJECT (data), "inserted", path, &iter);
...@@ -603,7 +579,9 @@ gtk_tree_model_sort_child_toggled (GtkTreeModel *s_model, ...@@ -603,7 +579,9 @@ gtk_tree_model_sort_child_toggled (GtkTreeModel *s_model,
free_s_path = TRUE; free_s_path = TRUE;
} }
path = gtk_tree_model_sort_convert_path (tree_model_sort, s_path); path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE);
if (path == NULL)
return;
gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path); gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
gtk_signal_emit_by_name (GTK_OBJECT (data), gtk_signal_emit_by_name (GTK_OBJECT (data),
"child_toggled", "child_toggled",
...@@ -805,6 +783,7 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model, ...@@ -805,6 +783,7 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE); g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE); g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
if (parent) if (parent)
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE); g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
...@@ -936,6 +915,81 @@ gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model, ...@@ -936,6 +915,81 @@ gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model,
} }
/* Internal functions */ /* Internal functions */
static GtkTreePath *
gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort,
GtkTreePath *child_path,
gboolean build_children)
{
GtkTreePath *retval;
GArray *array;
gint *indices;
gint i = 0;
if (tree_model_sort->root == NULL)
{
if (build_children)
gtk_tree_model_sort_build_level (tree_model_sort, NULL);
else
return FALSE;
}
retval = gtk_tree_path_new ();
array = (GArray *) tree_model_sort->root;
indices = gtk_tree_path_get_indices (child_path);
do
{
SortElt *elt;
gboolean found = FALSE;
gint j;
if ((array->len < indices[i]) || (array == NULL))
{
gtk_tree_path_free (retval);
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 (retval);
return NULL;
}
gtk_tree_path_prepend_index (retval, j);
i++;
if (i == gtk_tree_path_get_depth (child_path))
break;
if (elt->children == NULL)
{
if (build_children)
{
gtk_tree_path_prepend_index (retval, j);
gtk_tree_model_sort_build_level (tree_model_sort, elt);
}
else
{
gtk_tree_path_free (retval);
return NULL;
}
}
}
while (TRUE);
return retval;
}
static void static void
gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
SortElt *place) SortElt *place)
...@@ -945,6 +999,7 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, ...@@ -945,6 +999,7 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
GtkTreeIter *parent_iter = NULL; GtkTreeIter *parent_iter = NULL;
GtkTreeIter iter; GtkTreeIter iter;
SortElt elt; SortElt elt;
SortData sort_data;
if (place) if (place)
parent_iter = & (place->iter); parent_iter = & (place->iter);
...@@ -979,6 +1034,11 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, ...@@ -979,6 +1034,11 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
} }
while (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter)); while (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter));
sort_data.func = (GValueCompareFunc) gtk_tree_model_sort_get_func (tree_model_sort);
sort_data.model = tree_model_sort->child_model;
sort_data.sort_col = tree_model_sort->sort_col;
g_array_sort_with_data (children, gtk_tree_model_sort_func, &sort_data);
} }
static void static void
...@@ -1001,7 +1061,58 @@ gtk_tree_model_sort_free_level (GArray *array) ...@@ -1001,7 +1061,58 @@ gtk_tree_model_sort_free_level (GArray *array)
g_array_free (array, TRUE); g_array_free (array, TRUE);
} }
gint static GFunc
gtk_tree_model_sort_get_func (GtkTreeModelSort *tree_model_sort)
{
GValueCompareFunc func;
if (tree_model_sort->func)
func = tree_model_sort->func;
else
{
switch (gtk_tree_model_get_column_type (tree_model_sort->child_model,
tree_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 (Type %s)\n",
tree_model_sort->sort_col,
g_type_name (gtk_tree_model_get_column_type (tree_model_sort->child_model,
tree_model_sort->sort_col)));
return NULL;
}
}
return (GFunc) func;
}
static gint
gtk_tree_model_sort_func (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
GValue value_a;
GValue value_b;
SortData *sort_data = user_data;
gint retval;
gtk_tree_model_get_value (sort_data->model, (GtkTreeIter *) a, sort_data->sort_col, &value_a);
gtk_tree_model_get_value (sort_data->model, (GtkTreeIter *) b, sort_data->sort_col, &value_b);
retval = (sort_data->func) (&value_a, &value_b);
g_value_unset (&value_a);
g_value_unset (&value_b);
return retval;
}
static gint
g_value_string_compare_func (const GValue *a, g_value_string_compare_func (const GValue *a,
const GValue *b) const GValue *b)
{ {
...@@ -1016,7 +1127,7 @@ g_value_string_compare_func (const GValue *a, ...@@ -1016,7 +1127,7 @@ g_value_string_compare_func (const GValue *a,
return strcmp (a_str, b_str); return strcmp (a_str, b_str);
} }
gint static gint
g_value_int_compare_func (const GValue *a, g_value_int_compare_func (const GValue *a,
const GValue *b) const GValue *b)
{ {
......
...@@ -117,20 +117,26 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view) ...@@ -117,20 +117,26 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
NULL, NULL,
&selected)) &selected))
{ {
gtk_tree_store_insert_after (model, if (GTK_IS_TREE_STORE (model))
&iter, {
NULL, gtk_tree_store_insert_after (model,
&selected); &iter,
NULL,
&selected);
node_set (&iter);
}
} }
else else
{ {
gtk_tree_store_insert_after (model, if (GTK_IS_TREE_STORE (model))
&iter, {
NULL, gtk_tree_store_insert_after (model,
&selected); &iter,
NULL,
&selected);
node_set (&iter);
}
} }
node_set (&iter);
} }
static void static void
...@@ -219,7 +225,7 @@ make_window (gboolean use_sort) ...@@ -219,7 +225,7 @@ make_window (gboolean use_sort)
GtkTreeModel *sort_model; GtkTreeModel *sort_model;
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model), sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model),
NULL, 0); NULL, 1);
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model)); tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
} }
else else
...@@ -300,6 +306,9 @@ make_window (gboolean use_sort) ...@@ -300,6 +306,9 @@ make_window (gboolean use_sort)
iter_prepend (NULL, GTK_TREE_VIEW (tree_view)); iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view)); iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view)); iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
} }
/* Show it all */ /* Show it all */
gtk_widget_show_all (window); gtk_widget_show_all (window);
......
...@@ -117,20 +117,26 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view) ...@@ -117,20 +117,26 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
NULL, NULL,
&selected)) &selected))
{ {
gtk_tree_store_insert_after (model, if (GTK_IS_TREE_STORE (model))
&iter, {
NULL, gtk_tree_store_insert_after (model,
&selected); &iter,
NULL,
&selected);
node_set (&iter);
}
} }
else else
{ {
gtk_tree_store_insert_after (model, if (GTK_IS_TREE_STORE (model))
&iter, {
NULL, gtk_tree_store_insert_after (model,
&selected); &iter,
NULL,
&selected);
node_set (&iter);
}
} }
node_set (&iter);
} }
static void static void
...@@ -219,7 +225,7 @@ make_window (gboolean use_sort) ...@@ -219,7 +225,7 @@ make_window (gboolean use_sort)
GtkTreeModel *sort_model; GtkTreeModel *sort_model;
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model), sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model),
NULL, 0); NULL, 1);
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model)); tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
} }
else else
...@@ -300,6 +306,9 @@ make_window (gboolean use_sort) ...@@ -300,6 +306,9 @@ make_window (gboolean use_sort)
iter_prepend (NULL, GTK_TREE_VIEW (tree_view)); iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view)); iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view)); iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
} }
/* Show it all */ /* Show it all */
gtk_widget_show_all (window); gtk_widget_show_all (window);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment