diff options
author | Kristian Rietveld <kris@gtk.org> | 2006-01-15 20:12:49 +0000 |
---|---|---|
committer | Kristian Rietveld <kristian@src.gnome.org> | 2006-01-15 20:12:49 +0000 |
commit | cb3824225bd3a53fb663a45870d52bc88ea40e41 (patch) | |
tree | cdb4eec5c30b3b34929b8a7212702f2c7b4fc408 /gtk/gtktreestore.c | |
parent | ea6731b779b26d44be5f0582f8eed09d136fe376 (diff) | |
download | gtk+-cb3824225bd3a53fb663a45870d52bc88ea40e41.tar.gz |
Fixes #324099, Tommi Komulainen.
2006-01-15 Kristian Rietveld <kris@gtk.org>
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.
Diffstat (limited to 'gtk/gtktreestore.c')
-rw-r--r-- | gtk/gtktreestore.c | 270 |
1 files changed, 239 insertions, 31 deletions
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: <type>va_list</type> of column/value pairs - * - * See gtk_tree_store_set(); this version takes a <type>va_list</type> 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: <type>va_list</type> of column/value pairs + * + * See gtk_tree_store_set(); this version takes a <type>va_list</type> 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) { @@ -1316,6 +1331,195 @@ gtk_tree_store_insert_after (GtkTreeStore *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 + * <literal>gtk_tree_store_insert_with_values (tree_store, iter, position, ...)</literal> + * has the same effect as calling + * <informalexample><programlisting> + * gtk_tree_store_insert (tree_store, iter, position); + * gtk_tree_store_set (tree_store, iter, ...); + * </programlisting></informalexample> + * 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 * @iter: An unset #GtkTreeIter to set to the prepended row @@ -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); |