diff --git a/ChangeLog b/ChangeLog index 89e9a9ec31..6024a1e921 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-12-09 Matthias Clasen + + * gtk/gtkliststore.h: + * gtk/gtkliststore.c (gtk_list_store_insert_with_values): + (gtk_list_store_insert_with_valuesv): Add functions which allow + faster insertion of rows in sorted list stores. (#160063) + 2004-12-08 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 89e9a9ec31..6024a1e921 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,10 @@ +2004-12-09 Matthias Clasen + + * gtk/gtkliststore.h: + * gtk/gtkliststore.c (gtk_list_store_insert_with_values): + (gtk_list_store_insert_with_valuesv): Add functions which allow + faster insertion of rows in sorted list stores. (#160063) + 2004-12-08 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 89e9a9ec31..6024a1e921 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,10 @@ +2004-12-09 Matthias Clasen + + * gtk/gtkliststore.h: + * gtk/gtkliststore.c (gtk_list_store_insert_with_values): + (gtk_list_store_insert_with_valuesv): Add functions which allow + faster insertion of rows in sorted list stores. (#160063) + 2004-12-08 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 89e9a9ec31..6024a1e921 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,10 @@ +2004-12-09 Matthias Clasen + + * gtk/gtkliststore.h: + * gtk/gtkliststore.c (gtk_list_store_insert_with_values): + (gtk_list_store_insert_with_valuesv): Add functions which allow + faster insertion of rows in sorted list stores. (#160063) + 2004-12-08 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 10b2d10df3..6753a66810 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2004-12-09 Matthias Clasen + + * gtk/gtk-sections.txt: Add new list store methods. + 2004-12-08 Matthias Clasen * gtk/gtk-sections.txt: Add gtk_text_view_get_iter_at_position. diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index d0efc4cd5d..ec00deba4f 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -4268,6 +4268,8 @@ gtk_list_store_remove gtk_list_store_insert gtk_list_store_insert_before gtk_list_store_insert_after +gtk_list_store_insert_with_values +gtk_list_store_insert_with_valuesv gtk_list_store_prepend gtk_list_store_append gtk_list_store_clear diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c index 9f175cf266..29ed16ea92 100644 --- a/gtk/gtkliststore.c +++ b/gtk/gtkliststore.c @@ -778,29 +778,16 @@ gtk_list_store_set_value (GtkListStore *list_store, } } -/** - * gtk_list_store_set_valist: - * @list_store: A #GtkListStore - * @iter: A valid #GtkTreeIter for the row being modified - * @var_args: va_list of column/value pairs - * - * See gtk_list_store_set(); this version takes a va_list for use by language - * bindings. - * - **/ -void -gtk_list_store_set_valist (GtkListStore *list_store, - GtkTreeIter *iter, - va_list var_args) +static void +gtk_list_store_set_valist_internal (GtkListStore *list_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_LIST_STORE (list_store)); - g_return_if_fail (VALID_ITER (iter, list_store)); - column = va_arg (var_args, gint); if (GTK_LIST_STORE_IS_SORTED (list_store)) @@ -821,7 +808,7 @@ gtk_list_store_set_valist (GtkListStore *list_store, } if (func != _gtk_tree_data_list_compare_func) - maybe_need_sort = TRUE; + *maybe_need_sort = TRUE; while (column != -1) { @@ -848,20 +835,47 @@ gtk_list_store_set_valist (GtkListStore *list_store, } /* FIXME: instead of calling this n times, refactor with above */ - emit_signal = gtk_list_store_real_set_value (list_store, - iter, - column, - &value, - FALSE) || emit_signal; - + *emit_signal = gtk_list_store_real_set_value (list_store, + iter, + column, + &value, + FALSE) || *emit_signal; + if (func == _gtk_tree_data_list_compare_func && column == list_store->sort_column_id) - maybe_need_sort = TRUE; + *maybe_need_sort = TRUE; g_value_unset (&value); column = va_arg (var_args, gint); } +} + +/** + * gtk_list_store_set_valist: + * @list_store: A #GtkListStore + * @iter: A valid #GtkTreeIter for the row being modified + * @var_args: va_list of column/value pairs + * + * See gtk_list_store_set(); this version takes a va_list for use by language + * bindings. + * + **/ +void +gtk_list_store_set_valist (GtkListStore *list_store, + GtkTreeIter *iter, + va_list var_args) +{ + gboolean emit_signal = FALSE; + gboolean maybe_need_sort = FALSE; + + g_return_if_fail (GTK_IS_LIST_STORE (list_store)); + g_return_if_fail (VALID_ITER (iter, list_store)); + + gtk_list_store_set_valist_internal (list_store, iter, + &emit_signal, + &maybe_need_sort, + var_args); if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store)) gtk_list_store_sort_iter_changed (list_store, iter, list_store->sort_column_id); @@ -960,9 +974,9 @@ gtk_list_store_remove (GtkListStore *list_store, * * 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 empty before this - * function is called. To fill in values, you need to call gtk_list_store_set() - * or gtk_list_store_set_value(). + * new row will be appended to the list. The row will be empty after this + * function is called. To fill in values, you need to call + * gtk_list_store_set() or gtk_list_store_set_value(). * **/ void @@ -1009,10 +1023,10 @@ gtk_list_store_insert (GtkListStore *list_store, * @iter: An unset #GtkTreeIter to set to the new row * @sibling: A valid #GtkTreeIter, or %NULL * - * Inserts a new row before @sibling. If @sibling is %NULL, then the row will be - * appended to the end of the list. @iter will be changed to point to this new - * row. The row will be empty before this function is called. To fill in values, - * you need to call gtk_list_store_set() or gtk_list_store_set_value(). + * Inserts a new row before @sibling. If @sibling is %NULL, then the row will + * be appended to the end of the list. @iter will be changed to point to this + * new row. The row will be empty after this function is called. To fill in + * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). * **/ void @@ -1133,8 +1147,8 @@ gtk_list_store_clear (GtkListStore *list_store) * @list_store: A #GtkListStore. * @iter: A #GtkTreeIter. * - * WARNING: This function is slow. Only use it for debugging and/or testing - * purposes. + * This function is slow. Only use it for debugging and/or testing + * purposes. * * Checks if the given iter is a valid iter for this #GtkListStore. * @@ -1870,3 +1884,189 @@ gtk_list_store_has_default_sort_func (GtkTreeSortable *sortable) return (list_store->default_sort_func != NULL); } + + +/** + * gtk_list_store_insert_with_values: + * @list_store: A #GtkListStore + * @iter: An unset #GtkTreeIter to set to the new row + * @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_list_store_insert_with_values(list_store, iter, position...) + * has the same effect as calling + * + * gtk_list_store_insert (list_store, iter, position); + * gtk_list_store_set (list_store_iter, ...); + * + * with the difference that the former will only emit a row_inserted signal, + * while the latter will emit row_inserted, row_changed and, if the list store + * is sorted, rows_reordered. Since emitting the rows_reordered signal + * repeatedly can affect the performance of the program, + * gtk_list_store_insert_with_values() should generally be preferred when + * inserting rows in a sorted list store. + * + * Since: 2.6 + */ +void +gtk_list_store_insert_with_values (GtkListStore *list_store, + GtkTreeIter *iter, + gint position, + ...) +{ + GtkTreePath *path; + GtkSequence *seq; + GtkSequencePtr ptr; + gint length; + gboolean changed = FALSE; + gboolean maybe_need_sort = FALSE; + va_list var_args; + + /* FIXME: refactor to reduce overlap with gtk_list_store_set() */ + g_return_if_fail (GTK_IS_LIST_STORE (list_store)); + g_return_if_fail (iter != NULL); + + list_store->columns_dirty = TRUE; + + seq = list_store->seq; + + length = _gtk_sequence_get_length (seq); + if (position > length) + position = length; + + ptr = _gtk_sequence_get_ptr_at_pos (seq, position); + ptr = _gtk_sequence_insert (ptr, NULL); + + iter->stamp = list_store->stamp; + iter->user_data = ptr; + + g_assert (VALID_ITER (iter, list_store)); + + list_store->length++; + + va_start (var_args, position); + gtk_list_store_set_valist_internal (list_store, iter, + &changed, &maybe_need_sort, + var_args); + va_end (var_args); + + /* Don't emit rows_reordered here */ + if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store)) + _gtk_sequence_sort_changed (iter->user_data, + gtk_list_store_compare_func, + list_store); + + /* Just emit row_inserted */ + path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter); + gtk_tree_path_free (path); +} + + +/** + * gtk_list_store_insert_with_valuesv: + * @list_store: A #GtkListStore + * @iter: An unset #GtkTreeIter to set to the new row + * @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_list_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.6 + */ +void +gtk_list_store_insert_with_valuesv (GtkListStore *list_store, + GtkTreeIter *iter, + gint position, + gint *columns, + GValue *values, + gint n_values) +{ + GtkTreePath *path; + GtkSequence *seq; + GtkSequencePtr ptr; + gint length; + gboolean changed = FALSE; + gboolean maybe_need_sort = FALSE; + GtkTreeIterCompareFunc func = NULL; + gint i; + + /* FIXME refactor to reduce overlap with + * gtk_list_store_insert_with_values() + */ + g_return_if_fail (GTK_IS_LIST_STORE (list_store)); + g_return_if_fail (iter != NULL); + + list_store->columns_dirty = TRUE; + + seq = list_store->seq; + + length = _gtk_sequence_get_length (seq); + if (position > length) + position = length; + + ptr = _gtk_sequence_get_ptr_at_pos (seq, position); + ptr = _gtk_sequence_insert (ptr, NULL); + + iter->stamp = list_store->stamp; + iter->user_data = ptr; + + g_assert (VALID_ITER (iter, list_store)); + + list_store->length++; + + if (GTK_LIST_STORE_IS_SORTED (list_store)) + { + if (list_store->sort_column_id != -1) + { + GtkTreeDataSortHeader *header; + header = _gtk_tree_data_list_get_header (list_store->sort_list, + list_store->sort_column_id); + g_return_if_fail (header != NULL); + g_return_if_fail (header->func != NULL); + func = header->func; + } + else + { + func = list_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_list_store_real_set_value (list_store, + iter, + columns[i], + &values[i], + FALSE) || changed; + + if (func == _gtk_tree_data_list_compare_func && + columns[i] == list_store->sort_column_id) + maybe_need_sort = TRUE; + } + + /* Don't emit rows_reordered here */ + if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store)) + _gtk_sequence_sort_changed (iter->user_data, + gtk_list_store_compare_func, + list_store); + + /* Just emit row_inserted */ + path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter); + gtk_tree_path_free (path); +} diff --git a/gtk/gtkliststore.h b/gtk/gtkliststore.h index d653acf223..20b5acb1b7 100644 --- a/gtk/gtkliststore.h +++ b/gtk/gtkliststore.h @@ -101,6 +101,16 @@ void gtk_list_store_insert_before (GtkListStore *list_store, void gtk_list_store_insert_after (GtkListStore *list_store, GtkTreeIter *iter, GtkTreeIter *sibling); +void gtk_list_store_insert_with_values (GtkListStore *list_store, + GtkTreeIter *iter, + gint position, + ...); +void gtk_list_store_insert_with_valuesv (GtkListStore *list_store, + GtkTreeIter *iter, + gint position, + gint *columns, + GValue *values, + gint n_values); void gtk_list_store_prepend (GtkListStore *list_store, GtkTreeIter *iter); void gtk_list_store_append (GtkListStore *list_store,