From cb3824225bd3a53fb663a45870d52bc88ea40e41 Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Sun, 15 Jan 2006 20:12:49 +0000 Subject: [PATCH] Fixes #324099, Tommi Komulainen. 2006-01-15 Kristian Rietveld Fixes #324099, Tommi Komulainen. * gtk/gtktreestore.[ch] (gtk_tree_store_insert_with_values), (gtk_tree_store_insert_with_valuesv): new functions, analog to those found in GtkListStore. * gtk/gtktreestore.c (gtk_tree_store_real_set_value), (gtk_tree_store_set_valist), (gtk_tree_store_set_valist_internal), (gtk_tree_store_sort_iter_changed): refactored. * gtk/gtk.symbols: updated. * tests/treestoretest.c: added a test for this new functionality. --- ChangeLog | 16 +++ ChangeLog.pre-2-10 | 16 +++ gtk/gtk.symbols | 2 + gtk/gtktreestore.c | 270 +++++++++++++++++++++++++++++++++++++++------ gtk/gtktreestore.h | 12 ++ 5 files changed, 285 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d78ab42ca..17a5d51a17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-01-15 Kristian Rietveld + + Fixes #324099, Tommi Komulainen. + + * gtk/gtktreestore.[ch] (gtk_tree_store_insert_with_values), + (gtk_tree_store_insert_with_valuesv): new functions, analog to + those found in GtkListStore. + + * gtk/gtktreestore.c (gtk_tree_store_real_set_value), + (gtk_tree_store_set_valist), (gtk_tree_store_set_valist_internal), + (gtk_tree_store_sort_iter_changed): refactored. + + * gtk/gtk.symbols: updated. + + * tests/treestoretest.c: added a test for this new functionality. + 2006-01-14 Matthias Clasen * gtk/gtkentry.c (gtk_entry_drag_data_received): Remove diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 7d78ab42ca..17a5d51a17 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,19 @@ +2006-01-15 Kristian Rietveld + + Fixes #324099, Tommi Komulainen. + + * gtk/gtktreestore.[ch] (gtk_tree_store_insert_with_values), + (gtk_tree_store_insert_with_valuesv): new functions, analog to + those found in GtkListStore. + + * gtk/gtktreestore.c (gtk_tree_store_real_set_value), + (gtk_tree_store_set_valist), (gtk_tree_store_set_valist_internal), + (gtk_tree_store_sort_iter_changed): refactored. + + * gtk/gtk.symbols: updated. + + * tests/treestoretest.c: added a test for this new functionality. + 2006-01-14 Matthias Clasen * gtk/gtkentry.c (gtk_entry_drag_data_received): Remove diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 3fcf11f180..9099cfed70 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -3538,6 +3538,8 @@ gtk_tree_store_get_type G_GNUC_CONST gtk_tree_store_insert gtk_tree_store_insert_after gtk_tree_store_insert_before +gtk_tree_store_insert_with_values +gtk_tree_store_insert_with_valuesv gtk_tree_store_is_ancestor gtk_tree_store_iter_depth gtk_tree_store_iter_is_valid diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c index e7dff4328d..f4793774da 100644 --- a/gtk/gtktreestore.c +++ b/gtk/gtktreestore.c @@ -98,7 +98,8 @@ static gboolean gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, static void gtk_tree_store_sort (GtkTreeStore *tree_store); static void gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store, GtkTreeIter *iter, - gint column); + gint column, + gboolean emit_signal); static gboolean gtk_tree_store_get_sort_column_id (GtkTreeSortable *sortable, gint *sort_column_id, GtkSortType *order); @@ -828,7 +829,7 @@ gtk_tree_store_real_set_value (GtkTreeStore *tree_store, if (converted) g_value_unset (&real_value); if (sort && GTK_TREE_STORE_IS_SORTED (tree_store)) - gtk_tree_store_sort_iter_changed (tree_store, iter, old_column); + gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE); return retval; } @@ -866,7 +867,7 @@ gtk_tree_store_real_set_value (GtkTreeStore *tree_store, g_value_unset (&real_value); if (sort && GTK_TREE_STORE_IS_SORTED (tree_store)) - gtk_tree_store_sort_iter_changed (tree_store, iter, old_column); + gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE); return retval; } @@ -904,29 +905,16 @@ gtk_tree_store_set_value (GtkTreeStore *tree_store, } } -/** - * gtk_tree_store_set_valist: - * @tree_store: A #GtkTreeStore - * @iter: A valid #GtkTreeIter for the row being modified - * @var_args: va_list of column/value pairs - * - * See gtk_tree_store_set(); this version takes a va_list for - * use by language bindings. - * - **/ -void -gtk_tree_store_set_valist (GtkTreeStore *tree_store, - GtkTreeIter *iter, - va_list var_args) +static void +gtk_tree_store_set_valist_internal (GtkTreeStore *tree_store, + GtkTreeIter *iter, + gboolean *emit_signal, + gboolean *maybe_need_sort, + va_list var_args) { gint column; - gboolean emit_signal = FALSE; - gboolean maybe_need_sort = FALSE; GtkTreeIterCompareFunc func = NULL; - g_return_if_fail (GTK_IS_TREE_STORE (tree_store)); - g_return_if_fail (VALID_ITER (iter, tree_store)); - column = va_arg (var_args, gint); if (GTK_TREE_STORE_IS_SORTED (tree_store)) @@ -947,7 +935,7 @@ gtk_tree_store_set_valist (GtkTreeStore *tree_store, } if (func != _gtk_tree_data_list_compare_func) - maybe_need_sort = TRUE; + *maybe_need_sort = TRUE; while (column != -1) { @@ -973,23 +961,50 @@ gtk_tree_store_set_valist (GtkTreeStore *tree_store, break; } - emit_signal = gtk_tree_store_real_set_value (tree_store, - iter, - column, - &value, - FALSE) || emit_signal; + *emit_signal = gtk_tree_store_real_set_value (tree_store, + iter, + column, + &value, + FALSE) || *emit_signal; if (func == _gtk_tree_data_list_compare_func && column == tree_store->sort_column_id) - maybe_need_sort = TRUE; + *maybe_need_sort = TRUE; g_value_unset (&value); column = va_arg (var_args, gint); } +} + +/** + * gtk_tree_store_set_valist: + * @tree_store: A #GtkTreeStore + * @iter: A valid #GtkTreeIter for the row being modified + * @var_args: va_list of column/value pairs + * + * See gtk_tree_store_set(); this version takes a va_list for + * use by language bindings. + * + **/ +void +gtk_tree_store_set_valist (GtkTreeStore *tree_store, + GtkTreeIter *iter, + va_list var_args) +{ + gboolean emit_signal = FALSE; + gboolean maybe_need_sort = FALSE; + + g_return_if_fail (GTK_IS_TREE_STORE (tree_store)); + g_return_if_fail (VALID_ITER (iter, tree_store)); + + gtk_tree_store_set_valist_internal (tree_store, iter, + &emit_signal, + &maybe_need_sort, + var_args); if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store)) - gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id); + gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, TRUE); if (emit_signal) { @@ -1315,6 +1330,195 @@ gtk_tree_store_insert_after (GtkTreeStore *tree_store, validate_tree (tree_store); } +/** + * gtk_tree_store_insert_with_values: + * @tree_store: A #GtkTreeStore + * @iter: An unset #GtkTreeIter to set the new row + * @parent: A valid #GtkTreeIter, or %NULL + * @position: position to insert the new row + * @Varargs: pairs of column number and value, terminated with -1 + * + * Creates a new row at @position. @iter will be changed to point to this + * new row. If @position is larger than the number of rows on the list, then + * the new row will be appended to the list. The row will be filled with + * the values given to this function. + * + * Calling + * gtk_tree_store_insert_with_values (tree_store, iter, position, ...) + * has the same effect as calling + * + * gtk_tree_store_insert (tree_store, iter, position); + * gtk_tree_store_set (tree_store, iter, ...); + * + * with the different that the former will only emit a row_inserted signal, + * while the latter will emit row_inserted, row_changed and if the tree store + * is sorted, rows_reordered. Since emitting the rows_reordered signal + * repeatedly can affect the performance of the program, + * gtk_tree_store_insert_with_values() should generally be preferred when + * inserting rows in a sorted tree store. + * + * Since: 2.10 + */ +void +gtk_tree_store_insert_with_values (GtkTreeStore *tree_store, + GtkTreeIter *iter, + GtkTreeIter *parent, + gint position, + ...) +{ + GtkTreePath *path; + GNode *parent_node; + GNode *new_node; + va_list var_args; + gboolean changed = FALSE; + gboolean maybe_need_sort = FALSE; + + g_return_if_fail (GTK_IS_TREE_STORE (tree_store)); + g_return_if_fail (iter != NULL); + if (parent) + g_return_if_fail (VALID_ITER (parent, tree_store)); + + if (parent) + parent_node = parent->user_data; + else + parent_node = tree_store->root; + + tree_store->columns_dirty = TRUE; + + new_node = g_node_new (NULL); + + iter->stamp = tree_store->stamp; + iter->user_data = new_node; + g_node_insert (parent_node, position, new_node); + + va_start (var_args, position); + gtk_tree_store_set_valist_internal (tree_store, iter, + &changed, &maybe_need_sort, + var_args); + va_end (var_args); + + if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store)) + gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, FALSE); + + path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter); + + if (parent_node != tree_store->root) + { + if (new_node->prev == NULL && new_node->next == NULL) + { + gtk_tree_path_up (path); + gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent); + } + } + + gtk_tree_path_free (path); + + validate_tree ((GtkTreeStore *)tree_store); +} + +/** + * gtk_tree_store_insert_with_valuesv: + * @tree_store: A #GtkTreeStore + * @iter: An unset #GtkTreeIter to set the new row + * @parent: A valid #GtkTreeIter, or %NULL + * @position: position to insert the new row + * @columns: an array of column numbers + * @values: an array of GValues + * @n_values: the length of the @columns and @values arrays + * + * A variant of gtk_tree_store_insert_with_values() which takes + * the columns and values as two arrays, instead of varargs. This + * function is mainly intended for language bindings. + * + * Since: 2.10 + */ +void +gtk_tree_store_insert_with_valuesv (GtkTreeStore *tree_store, + GtkTreeIter *iter, + GtkTreeIter *parent, + gint position, + gint *columns, + GValue *values, + gint n_values) +{ + GtkTreePath *path; + GNode *parent_node; + GNode *new_node; + gboolean changed = FALSE; + gboolean maybe_need_sort = FALSE; + GtkTreeIterCompareFunc func = NULL; + gint i; + + g_return_if_fail (GTK_IS_TREE_STORE (tree_store)); + g_return_if_fail (iter != NULL); + if (parent) + g_return_if_fail (VALID_ITER (parent, tree_store)); + + if (parent) + parent_node = parent->user_data; + else + parent_node = tree_store->root; + + tree_store->columns_dirty = TRUE; + + new_node = g_node_new (NULL); + + iter->stamp = tree_store->stamp; + iter->user_data = new_node; + g_node_insert (parent_node, position, new_node); + + if (GTK_TREE_STORE_IS_SORTED (tree_store)) + { + if (tree_store->sort_column_id != -1) + { + GtkTreeDataSortHeader *header; + header = _gtk_tree_data_list_get_header (tree_store->sort_list, + tree_store->sort_column_id); + g_return_if_fail (header != NULL); + g_return_if_fail (header->func != NULL); + func = header->func; + } + else + { + func = tree_store->default_sort_func; + } + } + + if (func != _gtk_tree_data_list_compare_func) + maybe_need_sort = TRUE; + + for (i = 0; i < n_values; i++) + { + changed = gtk_tree_store_real_set_value (tree_store, iter, + columns[i], &values[i], + FALSE) || changed; + + if (func == _gtk_tree_data_list_compare_func && + columns[i] == tree_store->sort_column_id) + maybe_need_sort = TRUE; + } + + if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store)) + gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, FALSE); + + path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter); + + if (parent_node != tree_store->root) + { + if (new_node->prev == NULL && new_node->next == NULL) + { + gtk_tree_path_up (path); + gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent); + } + } + + gtk_tree_path_free (path); + + validate_tree ((GtkTreeStore *)tree_store); +} + /** * gtk_tree_store_prepend: * @tree_store: A #GtkTreeStore @@ -2660,7 +2864,8 @@ gtk_tree_store_sort (GtkTreeStore *tree_store) static void gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store, GtkTreeIter *iter, - gint column) + gint column, + gboolean emit_signal) { GNode *prev = NULL; GNode *next = NULL; @@ -2807,6 +3012,9 @@ gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store, G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data); } + if (!emit_signal) + return; + /* Emit the reordered signal. */ length = g_node_n_children (node->parent); new_order = g_new (int, length); diff --git a/gtk/gtktreestore.h b/gtk/gtktreestore.h index 58e018b74b..59d8e77741 100644 --- a/gtk/gtktreestore.h +++ b/gtk/gtktreestore.h @@ -103,6 +103,18 @@ void gtk_tree_store_insert_after (GtkTreeStore *tree_store, GtkTreeIter *iter, GtkTreeIter *parent, GtkTreeIter *sibling); +void gtk_tree_store_insert_with_values (GtkTreeStore *tree_store, + GtkTreeIter *iter, + GtkTreeIter *parent, + gint position, + ...); +void gtk_tree_store_insert_with_valuesv (GtkTreeStore *tree_store, + GtkTreeIter *iter, + GtkTreeIter *parent, + gint position, + gint *columns, + GValue *values, + gint n_values); void gtk_tree_store_prepend (GtkTreeStore *tree_store, GtkTreeIter *iter, GtkTreeIter *parent);