X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreemodel.c;h=31d8843509121af396e3b33d9e2efe8dfa6efbce;hb=a89d420270d1a856e072ed87c365b0176f102e6c;hp=b4c342461a2ab02a135e8a8e1bb9d02436538539;hpb=4765f37484b28b99b18b8e7c96bc71754cfe9ebd;p=~andy%2Fgtk diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c index b4c342461..31d884350 100644 --- a/gtk/gtktreemodel.c +++ b/gtk/gtktreemodel.c @@ -12,9 +12,7 @@ * 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. + * License along with this library. If not, see . */ #include "config.h" @@ -170,12 +168,12 @@ * /* Fill the list store with data */ * populate_model (list_store); * - * /* Get the first iter in the list */ - * valid = gtk_tree_model_get_iter_first (list_store, &iter); - * - * while (valid) + * /* Get the first iter in the list, check it is valid and walk + * * through the list, reading each row. */ + * for (valid = gtk_tree_model_get_iter_first (list_store, &iter); + * valid; + * valid = gtk_tree_model_iter_next (list_store, &iter)) * { - * /* Walk through the list, reading each row */ * gchar *str_data; * gint int_data; * @@ -192,11 +190,40 @@ * g_free (str_data); * * row_count++; - * valid = gtk_tree_model_iter_next (list_store, &iter); * } * * * + * The #GtkTreeModel interface contains two methods for reference + * counting: gtk_tree_model_ref_node() and gtk_tree_model_unref_node(). + * These two methods are optional to implement. The reference counting + * is meant as a way for views to let models know when nodes are being + * displayed. #GtkTreeView will take a reference on a node when it is + * visible, which means the node is either in the toplevel or expanded. + * Being displayed does not mean that the node is currently directly + * visible to the user in the viewport. Based on this reference counting + * scheme a caching model, for example, can decide whether or not to cache + * a node based on the reference count. A file-system based model would + * not want to keep the entire file hierarchy in memory, but just the + * folders that are currently expanded in every current view. + * + * When working with reference counting, the following rules must be taken + * into account: + * + * Never take a reference on a node without owning a + * reference on its parent. This means that all parent nodes of a referenced + * node must be referenced as well. + * Outstanding references on a deleted node are not released. + * This is not possible because the node has already been deleted by the + * time the row-deleted signal is received. + * + * Models are not obligated to emit a signal on rows of + * which none of its siblings are referenced. To phrase this differently, + * signals are only required for levels in which nodes are referenced. For + * the root level however, signals must be emitted at all times (however the + * root level is always referenced when any view is attached). + * + * */ #define INITIALIZE_TREE_ITER(Iter) \ @@ -222,7 +249,8 @@ static guint tree_model_signals[LAST_SIGNAL] = { 0 }; struct _GtkTreePath { - gint depth; + gint depth; /* Number of elements */ + gint alloc; /* Number of allocated elements */ gint *indices; }; @@ -559,6 +587,7 @@ gtk_tree_path_new (void) GtkTreePath *retval; retval = g_slice_new (GtkTreePath); retval->depth = 0; + retval->alloc = 0; retval->indices = NULL; return retval; @@ -620,7 +649,7 @@ gtk_tree_path_new_from_string (const gchar *path) /** * gtk_tree_path_new_from_indices: * @first_index: first integer - * @varargs: list of integers terminated by -1 + * @...: list of integers terminated by -1 * * Creates a new path with @first_index and @varargs as indices. * @@ -724,14 +753,23 @@ gtk_tree_path_new_first (void) */ void gtk_tree_path_append_index (GtkTreePath *path, - gint index) + gint index_) { g_return_if_fail (path != NULL); - g_return_if_fail (index >= 0); + g_return_if_fail (index_ >= 0); + + if (path->depth == path->alloc) + { + gint *indices; + path->alloc = MAX (path->alloc * 2, 1); + indices = g_new (gint, path->alloc); + memcpy (indices, path->indices, path->depth * sizeof (gint)); + g_free (path->indices); + path->indices = indices; + } path->depth += 1; - path->indices = g_realloc (path->indices, path->depth * sizeof(gint)); - path->indices[path->depth - 1] = index; + path->indices[path->depth - 1] = index_; } /** @@ -747,20 +785,19 @@ void gtk_tree_path_prepend_index (GtkTreePath *path, gint index) { - gint *new_indices; - - (path->depth)++; - new_indices = g_new (gint, path->depth); - - if (path->indices == NULL) + if (path->depth == path->alloc) { - path->indices = new_indices; - path->indices[0] = index; - return; + gint *indices; + path->alloc = MAX (path->alloc * 2, 1); + indices = g_new (gint, path->alloc); + memcpy (indices + 1, path->indices, path->depth * sizeof (gint)); + g_free (path->indices); + path->indices = indices; } - memcpy (new_indices + 1, path->indices, (path->depth - 1)*sizeof (gint)); - g_free (path->indices); - path->indices = new_indices; + else if (path->depth > 0) + memmove (path->indices + 1, path->indices, path->depth * sizeof (gint)); + + path->depth += 1; path->indices[0] = index; } @@ -789,6 +826,8 @@ gtk_tree_path_get_depth (GtkTreePath *path) * This is an array of integers, each representing a node in a tree. * This value should not be freed. * + * The length of the array can be obtained with gtk_tree_path_get_depth(). + * * Return value: The current indices, or %NULL */ gint * @@ -832,9 +871,9 @@ gtk_tree_path_get_indices_with_depth (GtkTreePath *path, /** * gtk_tree_path_free: - * @path: a #GtkTreePath + * @path: (allow-none): a #GtkTreePath * - * Frees @path. + * Frees @path. If @path is %NULL, it simply returns. */ void gtk_tree_path_free (GtkTreePath *path) @@ -863,7 +902,8 @@ gtk_tree_path_copy (const GtkTreePath *path) retval = g_slice_new (GtkTreePath); retval->depth = path->depth; - retval->indices = g_new (gint, path->depth); + retval->alloc = retval->depth; + retval->indices = g_new (gint, path->alloc); memcpy (retval->indices, path->indices, path->depth * sizeof (gint)); return retval; } @@ -1173,7 +1213,8 @@ gtk_tree_model_get_column_type (GtkTreeModel *tree_model, * @iter: (out): the uninitialized #GtkTreeIter * @path: the #GtkTreePath * - * Sets @iter to a valid iterator pointing to @path. + * Sets @iter to a valid iterator pointing to @path. If @path does + * not exist, @iter is set to an invalid iterator and %FALSE is returned. * * Return value: %TRUE, if @iter was set */ @@ -1601,9 +1642,11 @@ gtk_tree_model_iter_parent (GtkTreeModel *tree_model, * * This function is primarily meant as a way for views to let * caching models know when nodes are being displayed (and hence, - * whether or not to cache that node). For example, a file-system - * based model would not want to keep the entire file-hierarchy in - * memory, just the sections that are currently being displayed by + * whether or not to cache that node). Being displayed means a node + * is in an expanded branch, regardless of whether the node is currently + * visible in the viewport. For example, a file-system based model + * would not want to keep the entire file-hierarchy in memory, + * just the sections that are currently being displayed by * every current view. * * A model should be expected to be able to get an iter independent @@ -1654,7 +1697,7 @@ gtk_tree_model_unref_node (GtkTreeModel *tree_model, * gtk_tree_model_get: * @tree_model: a #GtkTreeModel * @iter: a row in @tree_model - * @Varargs: pairs of column number and value return locations, + * @...: pairs of column number and value return locations, * terminated by -1 * * Gets the value of one or more cells in the row referenced by @iter. @@ -1708,7 +1751,7 @@ gtk_tree_model_get_valist (GtkTreeModel *tree_model, while (column != -1) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; gchar *error = NULL; if (column >= gtk_tree_model_get_n_columns (tree_model)) @@ -1810,6 +1853,9 @@ gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model, * This should be called by models after a row has been removed. * The location pointed to by @path should be the location that * the row previously was at. It may not be a valid location anymore. + * + * Nodes that are deleted are not unreffed, this means that any + * outstanding references on the deleted node should not be released. */ void gtk_tree_model_row_deleted (GtkTreeModel *tree_model, @@ -2161,8 +2207,8 @@ gtk_tree_row_reference_unref_path (GtkTreePath *path, * Creates a row reference based on @path. * * This reference will keep pointing to the node pointed to - * by @path, so long as it exists. It listens to all signals - * emitted by @model, and updates its path appropriately. If + * by @path, so long as it exists. Any changes that occur on @model are + * propagated, and the path is updated appropriately. If * @path isn't a valid path in @model, then %NULL is returned. * * Return value: a newly allocated #GtkTreeRowReference, or %NULL