X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkfilesystemmodel.c;h=132902b31788851b2fecc1b75ac822a8f26b2085;hb=f5217289ca6feee9d482763d9c1fcf412d2dd610;hp=e10babcb0c8526091979063ed4408b25ee19bcc3;hpb=fb1a72fcb005a14b004eaae6912abd5232713a80;p=~andy%2Fgtk diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c index e10babcb0..132902b31 100644 --- a/gtk/gtkfilesystemmodel.c +++ b/gtk/gtkfilesystemmodel.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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" @@ -31,7 +29,6 @@ #include "gtktreedatalist.h" #include "gtktreednd.h" #include "gtktreemodel.h" -#include "gtkalias.h" /*** Structure: how GtkFileSystemModel works * @@ -45,6 +42,9 @@ * the special kind of usage for "search" and "recent-files", where the file chooser gives the model the * files to be displayed. * + * Internal data structure + * ----------------------- + * * Each file is kept in a FileModelNode structure. Each FileModelNode holds a GFile* and other data. All the * node structures have the same size, determined at runtime, depending on the number of columns that were passed * to _gtk_file_system_model_new() or _gtk_file_system_model_new_for_directory() (that is, the size of a node is @@ -69,7 +69,14 @@ * * Each FileModelNode has a node->visible field, which indicates whether the node is visible in the GtkTreeView. * A node may be invisible if, for example, it corresponds to a hidden file and the file chooser is not showing - * hidden files. + * hidden files. Also, a file filter may be explicitly set onto the model, for example, to only show files that + * match "*.jpg". In this case, node->filtered_out says whether the node failed the filter. The ultimate + * decision on whether a node is visible or not in the treeview is distilled into the node->visible field. + * The reason for having a separate node->filtered_out field is so that the file chooser can query whether + * a (filtered-out) folder should be made sensitive in the GUI. + * + * Visible rows vs. possibly-invisible nodes + * ----------------------------------------- * * Since not all nodes in the model->files array may be visible, we need a way to map visible row indexes from * the treeview to array indexes in our array of files. And thus we introduce a bit of terminology: @@ -98,6 +105,16 @@ * * You never access a node->row directly. Instead, call node_get_tree_row(). That function will validate the nodes * up to the sought one if the node is not valid yet, and it will return a proper 0-based row. + * + * Sorting + * ------- + * + * The model implements the GtkTreeSortable interface. To avoid re-sorting + * every time a node gets added (which would lead to O(n^2) performance during + * the initial population of the model), the model can freeze itself (with + * freeze_updates()) during the intial population process. When the model is + * frozen, sorting will not happen. The model will sort itself when the freeze + * count goes back to zero, via corresponding calls to thaw_updates(). */ /*** DEFINES ***/ @@ -123,6 +140,7 @@ struct _FileModelNode */ guint visible :1; /* if the file is currently visible */ + guint filtered_out :1;/* if the file is currently filtered out (i.e. it didn't pass the filters) */ guint frozen_add :1; /* true if the model was frozen and the entry has not been added yet */ GValue values[1]; /* actually n_columns values */ @@ -139,7 +157,7 @@ struct _GtkFileSystemModel GCancellable * cancellable; /* cancellable in use for all operations - cancelled on dispose */ GArray * files; /* array of FileModelNode containing all our files */ - GSize node_size; /* Size of a FileModelNode structure once its ->values field has n_columns */ + gsize node_size; /* Size of a FileModelNode structure once its ->values field has n_columns */ guint n_nodes_valid; /* count of valid nodes (i.e. those whose node->row is accurate) */ GHashTable * file_lookup; /* mapping of GFile => array index in model->files * This hash table doesn't always have the same number of entries as the files array; @@ -170,6 +188,7 @@ struct _GtkFileSystemModel guint show_hidden :1; /* whether to show hidden files */ guint show_folders :1;/* whether to show folders */ guint show_files :1; /* whether to show files */ + guint filter_folders :1;/* whether filter applies to folders */ }; #define GTK_FILE_SYSTEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModelClass)) @@ -185,6 +204,12 @@ struct _GtkFileSystemModelClass void (*finished_loading) (GtkFileSystemModel *model, GError *error); }; +static void freeze_updates (GtkFileSystemModel *model); +static void thaw_updates (GtkFileSystemModel *model); + +static guint node_get_for_file (GtkFileSystemModel *model, + GFile *file); + static void add_file (GtkFileSystemModel *model, GFile *file, GFileInfo *info); @@ -264,13 +289,13 @@ node_invalidate_index (GtkFileSystemModel *model, guint id) } static GtkTreePath * -gtk_tree_path_new_from_node (GtkFileSystemModel *model, guint id) +tree_path_new_from_node (GtkFileSystemModel *model, guint id) { - guint i = node_get_tree_row (model, id); + guint r = node_get_tree_row (model, id); - g_assert (i < model->files->len); + g_assert (r < model->files->len); - return gtk_tree_path_new_from_indices (i, -1); + return gtk_tree_path_new_from_indices (r, -1); } static void @@ -279,7 +304,7 @@ emit_row_inserted_for_node (GtkFileSystemModel *model, guint id) GtkTreePath *path; GtkTreeIter iter; - path = gtk_tree_path_new_from_node (model, id); + path = tree_path_new_from_node (model, id); ITER_INIT_FROM_INDEX (model, &iter, id); gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); gtk_tree_path_free (path); @@ -291,7 +316,7 @@ emit_row_changed_for_node (GtkFileSystemModel *model, guint id) GtkTreePath *path; GtkTreeIter iter; - path = gtk_tree_path_new_from_node (model, id); + path = tree_path_new_from_node (model, id); ITER_INIT_FROM_INDEX (model, &iter, id); gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); gtk_tree_path_free (path); @@ -308,10 +333,21 @@ emit_row_deleted_for_row (GtkFileSystemModel *model, guint row) } static void -node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible) +node_set_visible_and_filtered_out (GtkFileSystemModel *model, guint id, gboolean visible, gboolean filtered_out) { FileModelNode *node = get_node (model, id); + /* Filteredness */ + + if (node->filtered_out != filtered_out) + { + node->filtered_out = filtered_out; + if (node->visible && visible) + emit_row_changed_for_node (model, id); + } + + /* Visibility */ + if (node->visible == visible || node->frozen_add) return; @@ -336,35 +372,21 @@ node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible) } static gboolean -node_should_be_visible (GtkFileSystemModel *model, guint id) +node_should_be_filtered_out (GtkFileSystemModel *model, guint id) { FileModelNode *node = get_node (model, id); GtkFileFilterInfo filter_info = { 0, }; GtkFileFilterFlags required; - gboolean is_folder, result; + gboolean result; char *mime_type = NULL; char *filename = NULL; char *uri = NULL; if (node->info == NULL) - return FALSE; - - if (!model->show_hidden && - (g_file_info_get_is_hidden (node->info) || g_file_info_get_is_backup (node->info))) - return FALSE; - - is_folder = _gtk_file_info_consider_as_directory (node->info); - - /* wtf? */ - if (model->show_folders != model->show_files && - model->show_folders != is_folder) - return FALSE; - - if (is_folder) return TRUE; if (model->filter == NULL) - return TRUE; + return FALSE; /* fill info */ required = gtk_file_filter_get_needed (model->filter); @@ -406,7 +428,7 @@ node_should_be_visible (GtkFileSystemModel *model, guint id) } } - result = gtk_file_filter_filter (model->filter, &filter_info); + result = !gtk_file_filter_filter (model->filter, &filter_info); g_free (mime_type); g_free (filename); @@ -415,6 +437,50 @@ node_should_be_visible (GtkFileSystemModel *model, guint id) return result; } +static gboolean +node_should_be_visible (GtkFileSystemModel *model, guint id, gboolean filtered_out) +{ + FileModelNode *node = get_node (model, id); + gboolean result; + + if (node->info == NULL) + return FALSE; + + if (!model->show_hidden && + (g_file_info_get_is_hidden (node->info) || g_file_info_get_is_backup (node->info))) + return FALSE; + + if (_gtk_file_info_consider_as_directory (node->info)) + { + if (!model->show_folders) + return FALSE; + + if (!model->filter_folders) + return TRUE; + } + else + { + if (!model->show_files) + return FALSE; + } + + result = !filtered_out; + + return result; +} + +static void +node_compute_visibility_and_filters (GtkFileSystemModel *model, guint id) +{ + gboolean filtered_out; + gboolean visible; + + filtered_out = node_should_be_filtered_out (model, id); + visible = node_should_be_visible (model, id, filtered_out); + + node_set_visible_and_filtered_out (model, id, visible, filtered_out); +} + /*** GtkTreeModel ***/ static GtkTreeModelFlags @@ -513,6 +579,9 @@ gtk_file_system_model_get_iter (GtkTreeModel *tree_model, { g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); + if (gtk_tree_path_get_depth (path) > 1) + return FALSE; + return gtk_file_system_model_iter_nth_child (tree_model, iter, NULL, @@ -527,7 +596,7 @@ gtk_file_system_model_get_path (GtkTreeModel *tree_model, g_return_val_if_fail (ITER_IS_VALID (model, iter), NULL); - return gtk_tree_path_new_from_node (model, ITER_INDEX (iter)); + return tree_path_new_from_node (model, ITER_INDEX (iter)); } static void @@ -739,7 +808,7 @@ gtk_file_system_model_sort (GtkFileSystemModel *model) continue; } - new_order[r] = node->row; + new_order[r] = node->row - 1; r++; node->row = r; } @@ -984,8 +1053,8 @@ gtk_file_system_model_finalize (GObject *object) if (node->info) g_object_unref (node->info); - for (v = 0; v < model->column_types; v++) - if (G_VALUE_TYPE (node->values[v]) != G_TYPE_INVALID) + for (v = 0; v < model->n_columns; v++) + if (G_VALUE_TYPE (&node->values[v]) != G_TYPE_INVALID) g_value_unset (&node->values[v]); } g_array_free (model->files, TRUE); @@ -1000,7 +1069,7 @@ gtk_file_system_model_finalize (GObject *object) if (model->filter) g_object_unref (model->filter); - g_slice_free1 (sizeof (GType) * n_columns, model->column_types); + g_slice_free1 (sizeof (GType) * model->n_columns, model->column_types); _gtk_tree_data_list_header_free (model->sort_list); if (model->default_sort_destroy) @@ -1033,6 +1102,7 @@ _gtk_file_system_model_init (GtkFileSystemModel *model) model->show_files = TRUE; model->show_folders = TRUE; model->show_hidden = FALSE; + model->filter_folders = FALSE; model->sort_column_id = GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID; @@ -1053,7 +1123,7 @@ thaw_func (gpointer data) { GtkFileSystemModel *model = data; - _gtk_file_system_model_thaw_updates (model); + thaw_updates (model); model->dir_thaw_source = 0; return FALSE; @@ -1075,7 +1145,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da { if (model->dir_thaw_source == 0) { - _gtk_file_system_model_freeze_updates (model); + freeze_updates (model); model->dir_thaw_source = gdk_threads_add_timeout_full (IO_PRIORITY + 1, 50, thaw_func, @@ -1113,24 +1183,25 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da } else { - g_file_enumerator_close_async (enumerator, - IO_PRIORITY, - model->cancellable, - gtk_file_system_model_closed_enumerator, - model); - if (model->dir_thaw_source != 0) + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_source_remove (model->dir_thaw_source); - model->dir_thaw_source = 0; - _gtk_file_system_model_thaw_updates (model); - } + g_file_enumerator_close_async (enumerator, + IO_PRIORITY, + model->cancellable, + gtk_file_system_model_closed_enumerator, + NULL); + if (model->dir_thaw_source != 0) + { + g_source_remove (model->dir_thaw_source); + model->dir_thaw_source = 0; + thaw_updates (model); + } - g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, error); + g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, error); + } if (error) g_error_free (error); - - g_object_unref (model); } gdk_threads_leave (); @@ -1144,12 +1215,20 @@ gtk_file_system_model_query_done (GObject * object, GtkFileSystemModel *model = data; /* only a valid pointer if not cancelled */ GFile *file = G_FILE (object); GFileInfo *info; + guint id; info = g_file_query_info_finish (file, res, NULL); if (info == NULL) return; - _gtk_file_system_model_update_file (model, file, info, TRUE); + gdk_threads_enter (); + + _gtk_file_system_model_update_file (model, file, info); + + id = node_get_for_file (model, file); + gtk_file_system_model_sort_node (model, id); + + gdk_threads_leave (); } static void @@ -1174,7 +1253,9 @@ gtk_file_system_model_monitor_change (GFileMonitor * monitor, model); break; case G_FILE_MONITOR_EVENT_DELETED: + gdk_threads_enter (); remove_file (model, file); + gdk_threads_leave (); break; case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: /* FIXME: use freeze/thaw with this somehow? */ @@ -1198,9 +1279,11 @@ gtk_file_system_model_got_enumerator (GObject *dir, GAsyncResult *res, gpointer enumerator = g_file_enumerate_children_finish (G_FILE (dir), res, &error); if (enumerator == NULL) { - g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, error); - g_object_unref (model); - g_error_free (error); + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, error); + g_error_free (error); + } } else { @@ -1270,7 +1353,6 @@ gtk_file_system_model_set_directory (GtkFileSystemModel *model, model->dir = g_object_ref (dir); model->attributes = g_strdup (attributes); - g_object_ref (model); g_file_enumerate_children_async (model->dir, attributes, G_FILE_QUERY_INFO_NONE, @@ -1333,7 +1415,7 @@ _gtk_file_system_model_new (GtkFileSystemModelGetValue get_func, /** * _gtk_file_system_model_new_for_directory: * @directory: the directory to show. - * @attributes: attributes to immediately load or %NULL for all + * @attributes: (allow-none): attributes to immediately load or %NULL for all * @get_func: function that the model should call to query data about a file * @get_data: user data to pass to the @get_func * @n_columns: number of columns @@ -1383,16 +1465,14 @@ gtk_file_system_model_refilter_all (GtkFileSystemModel *model) return; } - _gtk_file_system_model_freeze_updates (model); + freeze_updates (model); /* start at index 1, don't change the editable */ for (i = 1; i < model->files->len; i++) - { - node_set_visible (model, i, node_should_be_visible (model, i)); - } + node_compute_visibility_and_filters (model, i); model->filter_on_thaw = FALSE; - _gtk_file_system_model_thaw_updates (model); + thaw_updates (model); } /** @@ -1465,6 +1545,30 @@ _gtk_file_system_model_set_show_files (GtkFileSystemModel *model, } } +/** + * _gtk_file_system_model_set_filter_folders: + * @model: a #GtkFileSystemModel + * @filter_folders: whether the filter applies to folders + * + * Sets whether the filter set by _gtk_file_system_model_set_filter() + * applies to folders. By default, it does not and folders are always + * visible. + **/ +void +_gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model, + gboolean filter_folders) +{ + g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); + + filter_folders = filter_folders != FALSE; + + if (filter_folders != model->filter_folders) + { + model->filter_folders = filter_folders; + gtk_file_system_model_refilter_all (model); + } +} + /** * _gtk_file_system_model_get_cancellable: * @model: the model @@ -1492,7 +1596,7 @@ _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model) * Checks if the iterator is visible. A visible iterator references * a row that is currently exposed using the #GtkTreeModel API. If * the iterator is invisible, it references a file that is not shown - * for some reason, such as being filtered by the current filter or + * for some reason, such as being filtered out by the current filter or * being a hidden file. * * Returns: %TRUE if the iterator is visible @@ -1510,6 +1614,32 @@ _gtk_file_system_model_iter_is_visible (GtkFileSystemModel *model, return node->visible; } +/** + * _gtk_file_system_model_iter_is_filtered_out: + * @model: the model + * @iter: a valid iterator + * + * Checks if the iterator is filtered out. This is only useful for rows + * that refer to folders, as those are always visible regardless + * of what the current filter says. This function lets you see + * the results of the filter. + * + * Returns: %TRUE if the iterator passed the current filter; %FALSE if the + * filter would not have let the row pass. + **/ +gboolean +_gtk_file_system_model_iter_is_filtered_out (GtkFileSystemModel *model, + GtkTreeIter *iter) +{ + FileModelNode *node; + + g_return_val_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + + node = get_node (model, ITER_INDEX (iter)); + return node->filtered_out; +} + /** * _gtk_file_system_model_get_info: * @model: a #GtkFileSystemModel @@ -1677,6 +1807,33 @@ _gtk_file_system_model_get_iter_for_file (GtkFileSystemModel *model, return TRUE; } +/* When an element is added or removed to the model->files array, we need to + * update the model->file_lookup mappings of (node, index), as the indexes + * change. This function adds the specified increment to the index in that pair + * if the index is equal or after the specified id. We use this to slide the + * mappings up or down when a node is added or removed, respectively. + */ +static void +adjust_file_lookup (GtkFileSystemModel *model, guint id, int increment) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init (&iter, model->file_lookup); + + while (g_hash_table_iter_next (&iter, &key, &value)) + { + guint index = GPOINTER_TO_UINT (value); + + if (index >= id) + { + index += increment; + g_hash_table_iter_replace (&iter, GUINT_TO_POINTER (index)); + } + } +} + /** * add_file: * @model: the model @@ -1707,8 +1864,8 @@ add_file (GtkFileSystemModel *model, g_slice_free1 (model->node_size, node); if (!model->frozen) - node_set_visible (model, model->files->len -1, - node_should_be_visible (model, model->files->len - 1)); + node_compute_visibility_and_filters (model, model->files->len -1); + gtk_file_system_model_sort_node (model, model->files->len -1); } @@ -1727,6 +1884,7 @@ remove_file (GtkFileSystemModel *model, { FileModelNode *node; guint id; + guint row; g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); g_return_if_fail (G_IS_FILE (file)); @@ -1736,16 +1894,22 @@ remove_file (GtkFileSystemModel *model, return; node = get_node (model, id); - node_set_visible (model, id, FALSE); + row = node_get_tree_row (model, id); + + node_invalidate_index (model, id); g_hash_table_remove (model->file_lookup, file); g_object_unref (node->file); + adjust_file_lookup (model, id, -1); if (node->info) g_object_unref (node->info); g_array_remove_index (model->files, id); - /* We don't need to resort, as removing a row doesn't change the sorting order */ + + /* We don't need to resort, as removing a row doesn't change the sorting order of the other rows */ + + emit_row_deleted_for_row (model, row); } /** @@ -1753,7 +1917,6 @@ remove_file (GtkFileSystemModel *model, * @model: the model * @file: the file * @info: the new file info - * @requires_resort: FIXME: get rid of this argument * * Tells the file system model that the file changed and that the * new @info should be used for it now. If the file is not part of @@ -1762,8 +1925,7 @@ remove_file (GtkFileSystemModel *model, void _gtk_file_system_model_update_file (GtkFileSystemModel *model, GFile *file, - GFileInfo *info, - gboolean requires_resort) + GFileInfo *info) { FileModelNode *node; guint i, id; @@ -1775,7 +1937,10 @@ _gtk_file_system_model_update_file (GtkFileSystemModel *model, id = node_get_for_file (model, file); if (id == 0) - add_file (model, file, info); + { + add_file (model, file, info); + id = node_get_for_file (model, file); + } node = get_node (model, id); @@ -1792,32 +1957,35 @@ _gtk_file_system_model_update_file (GtkFileSystemModel *model, if (node->visible) emit_row_changed_for_node (model, id); - - if (requires_resort) - gtk_file_system_model_sort_node (model, id); } /** * _gtk_file_system_model_set_filter: * @mode: a #GtkFileSystemModel - * @filter: %NULL or filter to use + * @filter: (allow-none): %NULL or filter to use * * Sets a filter to be used for deciding if a row should be visible or not. - * Directories are always visible. + * Whether this filter applies to directories can be toggled with + * _gtk_file_system_model_set_filter_folders(). **/ void _gtk_file_system_model_set_filter (GtkFileSystemModel *model, GtkFileFilter * filter) { + GtkFileFilter *old_filter; + g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); g_return_if_fail (filter == NULL || GTK_IS_FILE_FILTER (filter)); if (filter) g_object_ref (filter); - if (model->filter) - g_object_unref (model->filter); + + old_filter = model->filter; model->filter = filter; + if (old_filter) + g_object_unref (old_filter); + gtk_file_system_model_refilter_all (model); } @@ -1837,7 +2005,7 @@ _gtk_file_system_model_add_editable (GtkFileSystemModel *model, GtkTreeIter *ite g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); g_return_if_fail (!get_node (model, 0)->visible); - node_set_visible (model, 0, TRUE); + node_set_visible_and_filtered_out (model, 0, TRUE, FALSE); ITER_INIT_FROM_INDEX (model, iter, 0); } @@ -1855,21 +2023,20 @@ _gtk_file_system_model_remove_editable (GtkFileSystemModel *model) g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); g_return_if_fail (get_node (model, 0)->visible); - node_set_visible (model, 0, FALSE); + node_set_visible_and_filtered_out (model, 0, FALSE, FALSE); } /** - * _gtk_file_system_model_freeze_updates: + * freeze_updates: * @model: a #GtkFileSystemModel * - * Freezes most updates on the model, so that performing multiple - * operations on the files in the model do not cause any events. - * Use _gtk_file_system_model_thaw_updates() to resume proper - * operations. It is fine to call this function multiple times as - * long as freeze and thaw calls are balanced. + * Freezes most updates on the model, so that performing multiple operations on + * the files in the model do not cause any events. Use thaw_updates() to resume + * proper operations. It is fine to call this function multiple times as long as + * freeze and thaw calls are balanced. **/ -void -_gtk_file_system_model_freeze_updates (GtkFileSystemModel *model) +static void +freeze_updates (GtkFileSystemModel *model) { g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); @@ -1877,14 +2044,13 @@ _gtk_file_system_model_freeze_updates (GtkFileSystemModel *model) } /** - * _gtk_file_system_model_thaw_updates: + * thaw_updates: * @model: a #GtkFileSystemModel * - * Undoes the effect of a previous call to - * _gtk_file_system_model_freeze_updates() + * Undoes the effect of a previous call to freeze_updates() **/ -void -_gtk_file_system_model_thaw_updates (GtkFileSystemModel *model) +static void +thaw_updates (GtkFileSystemModel *model) { gboolean stuff_added; @@ -1912,7 +2078,7 @@ _gtk_file_system_model_thaw_updates (GtkFileSystemModel *model) if (!node->frozen_add) continue; node->frozen_add = FALSE; - node_set_visible (model, i, node_should_be_visible (model, i)); + node_compute_visibility_and_filters (model, i); } } }