Compare commits

...

6 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
2748c251cd gtkfilesystemmodel: Use g_clear_* helpers
Saves some code.
2022-12-20 01:05:33 -05:00
Georges Basile Stavracas Neto
4b5cf44695 filesystemmodel: Use G_DECLARE_FINAL_TYPE()
Clean up boilerplate. It's a private object anyway.
2022-12-20 01:05:33 -05:00
Georges Basile Stavracas Neto
64b8abe4d0 filesystemmodel: Cosmetics
Adjust code style, and shuffle some functions around. Remove
unhelpful doc comments.
2022-12-20 01:05:33 -05:00
Georges Basile Stavracas Neto
896a7bebda filesystemmodel: Remove GtkTreeModel cruft
Back when GtkFileSystemModel was a GtkTreeModel implementation, it
had an empty first item that was used for renaming files. Of course,
after we moved away from GtkTreeModel, this empty item became an
obsolete detail.

Remove it.
2022-12-20 01:05:33 -05:00
Georges Basile Stavracas Neto
4f4aa404a5 filesystemmodel: Make function private to gtkfilesystemmodel.c
The _gtk_file_system_model_update_file() function is not used outside
GtkFileSystemModel, so no need to expose it in the header.

Shuffle it around in code, and remove it from the header.
2022-12-20 01:05:33 -05:00
Georges Basile Stavracas Neto
d59a906505 filesystemmodel: Cleanup unused defines
They were made unused with the removal of GtkTreeModel interface
implementation.
2022-12-20 01:05:33 -05:00
2 changed files with 302 additions and 404 deletions

View File

@@ -38,7 +38,6 @@
#define FILES_PER_QUERY 100
typedef struct _FileModelNode FileModelNode;
typedef struct _GtkFileSystemModelClass GtkFileSystemModelClass;
struct _FileModelNode
{
@@ -84,46 +83,9 @@ struct _GtkFileSystemModel
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))
#define GTK_IS_FILE_SYSTEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SYSTEM_MODEL))
#define GTK_FILE_SYSTEM_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModelClass))
struct _GtkFileSystemModelClass
{
GObjectClass parent_class;
/* Signals */
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);
static void remove_file (GtkFileSystemModel *model,
GFile *file);
/* iter setup:
* @user_data: the model
* @user_data2: GUINT_TO_POINTER of array index of current entry
*
* All other fields are unused. Note that the array index does not correspond
* 1:1 with the path index as entries might not be visible.
*/
#define ITER_INDEX(iter) GPOINTER_TO_UINT((iter)->user_data2)
#define ITER_IS_VALID(model, iter) ((model) == (iter)->user_data)
#define ITER_INIT_FROM_INDEX(model, _iter, _index) G_STMT_START {\
g_assert (_index < (model)->files->len); \
(_iter)->user_data = (model); \
(_iter)->user_data2 = GUINT_TO_POINTER (_index); \
}G_STMT_END
/*** FileModelNode ***/
/* Get a FileModelNode structure given an index in the model->files array of nodes */
@@ -140,7 +102,9 @@ static void remove_file (GtkFileSystemModel *model,
* G_MAXUINT for both arguments for “validate everything”.
*/
static void
node_validate_rows (GtkFileSystemModel *model, guint up_to_index, guint up_to_row)
node_validate_rows (GtkFileSystemModel *model,
guint up_to_index,
guint up_to_row)
{
guint i, row;
@@ -167,7 +131,8 @@ node_validate_rows (GtkFileSystemModel *model, guint up_to_index, guint up_to_ro
}
static guint G_GNUC_UNUSED
node_get_tree_row (GtkFileSystemModel *model, guint index)
node_get_tree_row (GtkFileSystemModel *model,
guint index)
{
if (model->n_nodes_valid <= index)
node_validate_rows (model, index, G_MAXUINT);
@@ -176,13 +141,17 @@ node_get_tree_row (GtkFileSystemModel *model, guint index)
}
static void
node_invalidate_index (GtkFileSystemModel *model, guint id)
node_invalidate_index (GtkFileSystemModel *model,
guint id)
{
model->n_nodes_valid = MIN (model->n_nodes_valid, id);
}
static void
node_set_visible_and_filtered_out (GtkFileSystemModel *model, guint id, gboolean visible, gboolean filtered_out)
node_set_visible_and_filtered_out (GtkFileSystemModel *model,
guint id,
gboolean visible,
gboolean filtered_out)
{
FileModelNode *node = get_node (model, id);
@@ -218,7 +187,8 @@ node_set_visible_and_filtered_out (GtkFileSystemModel *model, guint id, gboolean
}
static gboolean
node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
node_should_be_filtered_out (GtkFileSystemModel *model,
guint id)
{
FileModelNode *node = get_node (model, id);
@@ -234,7 +204,9 @@ node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
}
static gboolean
node_should_be_visible (GtkFileSystemModel *model, guint id, gboolean filtered_out)
node_should_be_visible (GtkFileSystemModel *model,
guint id,
gboolean filtered_out)
{
FileModelNode *node = get_node (model, id);
gboolean result;
@@ -266,7 +238,8 @@ node_should_be_visible (GtkFileSystemModel *model, guint id, gboolean filtered_o
}
static void
node_compute_visibility_and_filters (GtkFileSystemModel *model, guint id)
node_compute_visibility_and_filters (GtkFileSystemModel *model,
guint id)
{
gboolean filtered_out;
gboolean visible;
@@ -277,6 +250,20 @@ node_compute_visibility_and_filters (GtkFileSystemModel *model, guint id)
node_set_visible_and_filtered_out (model, id, visible, filtered_out);
}
static guint
node_get_for_file (GtkFileSystemModel *model,
GFile *file)
{
gpointer position;
if (!g_hash_table_lookup_extended (model->file_lookup,
file, NULL,
&position))
return GTK_INVALID_LIST_POSITION;
return GPOINTER_TO_UINT (position);
}
/*** GListModel ***/
static GType
@@ -290,7 +277,7 @@ list_model_get_n_items (GListModel *list_model)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (list_model);
return model->files->len - 1;
return model->files->len;
}
static gpointer
@@ -300,12 +287,10 @@ list_model_get_item (GListModel *list_model,
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (list_model);
FileModelNode *node;
/* The first items of GtkFileSystemModel is not really a file,
* so ignore it. */
if (position + 1 >= model->files->len)
if (position >= model->files->len)
return NULL;
node = get_node (model, position + 1);
node = get_node (model, position);
return g_object_ref (node->info);
}
@@ -327,89 +312,164 @@ enum {
static guint file_system_model_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_CODE (GtkFileSystemModel, _gtk_file_system_model, G_TYPE_OBJECT,
G_DEFINE_TYPE_WITH_CODE (GtkFileSystemModel, gtk_file_system_model, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
g_list_model_iface_init))
static void
gtk_file_system_model_dispose (GObject *object)
gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (object);
if (model->dir_thaw_source)
{
g_source_remove (model->dir_thaw_source);
model->dir_thaw_source = 0;
}
g_cancellable_cancel (model->cancellable);
if (model->dir_monitor)
g_file_monitor_cancel (model->dir_monitor);
G_OBJECT_CLASS (_gtk_file_system_model_parent_class)->dispose (object);
}
static void
gtk_file_system_model_finalize (GObject *object)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (object);
guint i;
for (i = 0; i < model->files->len; i++)
if (model->frozen)
{
FileModelNode *node = get_node (model, i);
g_clear_object (&node->file);
g_clear_object (&node->info);
model->filter_on_thaw = TRUE;
return;
}
g_array_free (model->files, TRUE);
g_clear_object (&model->cancellable);
g_clear_pointer (&model->attributes, g_free);
g_clear_object (&model->dir);
g_clear_object (&model->dir_monitor);
g_clear_pointer (&model->file_lookup, g_hash_table_destroy);
g_clear_object (&model->filter);
freeze_updates (model);
G_OBJECT_CLASS (_gtk_file_system_model_parent_class)->finalize (object);
for (i = 0; i < model->files->len; i++)
node_compute_visibility_and_filters (model, i);
model->filter_on_thaw = FALSE;
thaw_updates (model);
}
static void
_gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
freeze_updates (GtkFileSystemModel *model)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
gobject_class->finalize = gtk_file_system_model_finalize;
gobject_class->dispose = gtk_file_system_model_dispose;
file_system_model_signals[FINISHED_LOADING] =
g_signal_new (I_("finished-loading"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileSystemModelClass, finished_loading),
NULL, NULL,
NULL,
G_TYPE_NONE, 1, G_TYPE_ERROR);
model->frozen++;
}
static void
_gtk_file_system_model_init (GtkFileSystemModel *model)
thaw_updates (GtkFileSystemModel *model)
{
model->show_files = TRUE;
model->show_folders = TRUE;
model->show_hidden = FALSE;
model->filter_folders = FALSE;
gboolean stuff_added = FALSE;
model->file_lookup = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
model->cancellable = g_cancellable_new ();
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (model->frozen > 0);
model->frozen--;
if (model->frozen > 0)
return;
if (model->files->len > 0)
stuff_added = get_node (model, model->files->len - 1)->frozen_add;
if (model->filter_on_thaw)
gtk_file_system_model_refilter_all (model);
if (stuff_added)
{
guint i;
for (i = 0; i < model->files->len; i++)
{
FileModelNode *node = get_node (model, i);
if (!node->frozen_add)
continue;
node->frozen_add = FALSE;
node_compute_visibility_and_filters (model, i);
}
}
}
/*** API ***/
/* 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));
}
}
}
static void
gtk_file_system_model_closed_enumerator (GObject *object, GAsyncResult *res, gpointer data)
add_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info)
{
FileModelNode *node;
guint position;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (G_IS_FILE_INFO (info));
node = g_slice_alloc0 (sizeof (FileModelNode));
node->file = g_object_ref (file);
if (info)
{
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
node->info = g_object_ref (info);
}
node->frozen_add = model->frozen ? TRUE : FALSE;
g_array_append_vals (model->files, node, 1);
g_slice_free1 (sizeof (FileModelNode), node);
position = model->files->len - 1;
if (!model->frozen)
node_compute_visibility_and_filters (model, position);
g_list_model_items_changed (G_LIST_MODEL (model), position, 0, 1);
}
static void
remove_file (GtkFileSystemModel *model,
GFile *file)
{
FileModelNode *node;
guint id;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
id = node_get_for_file (model, file);
if (id == GTK_INVALID_LIST_POSITION)
return;
node = get_node (model, id);
node_invalidate_index (model, id);
g_hash_table_remove (model->file_lookup, file);
g_clear_object (&node->file);
adjust_file_lookup (model, id, -1);
g_clear_object (&node->info);
g_array_remove_index (model->files, id);
g_list_model_items_changed (G_LIST_MODEL (model), id, 1, 0);
}
static void
gtk_file_system_model_closed_enumerator (GObject *object,
GAsyncResult *res,
gpointer data)
{
g_file_enumerator_close_finish (G_FILE_ENUMERATOR (object), res, NULL);
}
@@ -426,7 +486,9 @@ thaw_func (gpointer data)
}
static void
gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer data)
gtk_file_system_model_got_files (GObject *object,
GAsyncResult *res,
gpointer data)
{
GFileEnumerator *enumerator = G_FILE_ENUMERATOR (object);
GtkFileSystemModel *model = data;
@@ -486,8 +548,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
NULL);
if (model->dir_thaw_source != 0)
{
g_source_remove (model->dir_thaw_source);
model->dir_thaw_source = 0;
g_clear_handle_id (&model->dir_thaw_source, g_source_remove);
thaw_updates (model);
}
@@ -499,10 +560,36 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
}
}
static void
_gtk_file_system_model_update_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info)
{
FileModelNode *node;
guint id;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (G_IS_FILE_INFO (info));
id = node_get_for_file (model, file);
if (id == GTK_INVALID_LIST_POSITION)
{
add_file (model, file, info);
id = node_get_for_file (model, file);
}
node = get_node (model, id);
g_set_object (&node->info, info);
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
}
/* Helper for gtk_file_system_model_query_done and
* gtk_file_system_model_one_query_done */
static void
query_done_helper (GObject * object,
query_done_helper (GObject *object,
GAsyncResult *res,
gpointer data,
gboolean do_thaw_updates)
@@ -523,7 +610,7 @@ query_done_helper (GObject * object,
}
static void
gtk_file_system_model_query_done (GObject * object,
gtk_file_system_model_query_done (GObject *object,
GAsyncResult *res,
gpointer data)
{
@@ -531,9 +618,9 @@ gtk_file_system_model_query_done (GObject * object,
}
static void
gtk_file_system_model_monitor_change (GFileMonitor * monitor,
GFile * file,
GFile * other_file,
gtk_file_system_model_monitor_change (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent type,
GtkFileSystemModel *model)
{
@@ -569,7 +656,9 @@ gtk_file_system_model_monitor_change (GFileMonitor * monitor,
}
static void
gtk_file_system_model_got_enumerator (GObject *dir, GAsyncResult *res, gpointer data)
gtk_file_system_model_got_enumerator (GObject *dir,
GAsyncResult *res,
gpointer data)
{
GtkFileSystemModel *model = data;
GFileEnumerator *enumerator;
@@ -607,8 +696,8 @@ gtk_file_system_model_got_enumerator (GObject *dir, GAsyncResult *res, gpointer
static void
gtk_file_system_model_set_directory (GtkFileSystemModel *model,
GFile * dir,
const char * attributes)
GFile *dir,
const char *attributes)
{
g_assert (G_IS_FILE (dir));
@@ -625,6 +714,85 @@ gtk_file_system_model_set_directory (GtkFileSystemModel *model,
}
static void
gtk_file_system_model_one_query_done (GObject *object,
GAsyncResult *res,
gpointer data)
{
query_done_helper (object, res, data, TRUE);
}
/* GObject overrides */
static void
gtk_file_system_model_dispose (GObject *object)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (object);
g_clear_handle_id (&model->dir_thaw_source, g_source_remove);
g_cancellable_cancel (model->cancellable);
if (model->dir_monitor)
g_file_monitor_cancel (model->dir_monitor);
G_OBJECT_CLASS (gtk_file_system_model_parent_class)->dispose (object);
}
static void
gtk_file_system_model_finalize (GObject *object)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (object);
guint i;
for (i = 0; i < model->files->len; i++)
{
FileModelNode *node = get_node (model, i);
g_clear_object (&node->file);
g_clear_object (&node->info);
}
g_array_free (model->files, TRUE);
g_clear_object (&model->cancellable);
g_clear_pointer (&model->attributes, g_free);
g_clear_object (&model->dir);
g_clear_object (&model->dir_monitor);
g_clear_pointer (&model->file_lookup, g_hash_table_destroy);
g_clear_object (&model->filter);
G_OBJECT_CLASS (gtk_file_system_model_parent_class)->finalize (object);
}
static void
gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = gtk_file_system_model_finalize;
gobject_class->dispose = gtk_file_system_model_dispose;
file_system_model_signals[FINISHED_LOADING] =
g_signal_new (I_("finished-loading"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
NULL,
G_TYPE_NONE, 1, G_TYPE_ERROR);
}
static void
gtk_file_system_model_init (GtkFileSystemModel *model)
{
model->show_files = TRUE;
model->show_folders = TRUE;
model->show_hidden = FALSE;
model->filter_folders = FALSE;
model->file_lookup = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
model->cancellable = g_cancellable_new ();
}
/*** API ***/
/**
* _gtk_file_system_model_new:
*
@@ -640,11 +808,7 @@ _gtk_file_system_model_new (void)
GtkFileSystemModel *model;
model = g_object_new (GTK_TYPE_FILE_SYSTEM_MODEL, NULL);
model->files = g_array_sized_new (FALSE, FALSE, sizeof (FileModelNode), FILES_PER_QUERY);
/* add editable node at start */
g_array_set_size (model->files, 1);
memset (get_node (model, 0), 0, sizeof (FileModelNode));
return model;
}
@@ -678,27 +842,6 @@ _gtk_file_system_model_new_for_directory (GFile *dir,
return model;
}
static void
gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
{
guint i;
if (model->frozen)
{
model->filter_on_thaw = TRUE;
return;
}
freeze_updates (model);
/* start at index 1, don't change the editable */
for (i = 1; i < model->files->len; i++)
node_compute_visibility_and_filters (model, i);
model->filter_on_thaw = FALSE;
thaw_updates (model);
}
/**
* _gtk_file_system_model_set_show_hidden:
* @model: a `GtkFileSystemModel`
@@ -779,7 +922,7 @@ _gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
*/
void
_gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model,
gboolean filter_folders)
gboolean filter_folders)
{
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
@@ -811,36 +954,6 @@ _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model)
return model->cancellable;
}
static guint
node_get_for_file (GtkFileSystemModel *model,
GFile * file)
{
guint i;
i = GPOINTER_TO_UINT (g_hash_table_lookup (model->file_lookup, file));
if (i != 0)
return i;
/* Node 0 is the editable row and has no associated file or entry in the table, so we start counting from 1.
*
* The invariant here is that the files in model->files[n] for n < g_hash_table_size (model->file_lookup)
* are already added to the hash table. this loop merely rebuilds our (file -> index) mapping on demand.
*
* If we exit the loop, the next pending batch of mappings will be resolved when this function gets called again
* with another file that is not yet in the mapping.
*/
for (i = g_hash_table_size (model->file_lookup) + 1; i < model->files->len; i++)
{
FileModelNode *node = get_node (model, i);
g_hash_table_insert (model->file_lookup, node->file, GUINT_TO_POINTER (i));
if (g_file_equal (node->file, file))
return i;
}
return 0;
}
GFileInfo *
_gtk_file_system_model_get_info_for_file (GtkFileSystemModel *model,
GFile *file)
@@ -853,157 +966,23 @@ _gtk_file_system_model_get_info_for_file (GtkFileSystemModel *model,
i = node_get_for_file (model, file);
if (i == 0)
if (i == GTK_INVALID_LIST_POSITION)
return NULL;
node = get_node (model, i);
return node->info;
}
/* 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:
* _gtk_file_system_model_update_files:
* @model: the model
* @file: the file to add
* @info: the information to associate with the file
* @files: the files
* @infos: the new file infos
*
* Adds the given @file with its associated @info to the @model.
* If the model is frozen, the file will only show up after it is thawn.
* Tells the file system model that the files changed and that the
* new @infos should be used for it now. If these files are not
* part of @model, it will get added automatically.
**/
static void
add_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info)
{
FileModelNode *node;
guint position;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (G_IS_FILE_INFO (info));
node = g_slice_alloc0 (sizeof (FileModelNode));
node->file = g_object_ref (file);
if (info)
{
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
node->info = g_object_ref (info);
}
node->frozen_add = model->frozen ? TRUE : FALSE;
g_array_append_vals (model->files, node, 1);
g_slice_free1 (sizeof (FileModelNode), node);
position = model->files->len - 1;
if (!model->frozen)
node_compute_visibility_and_filters (model, model->files->len -1);
/* Ignore the first item */
g_list_model_items_changed (G_LIST_MODEL (model), position - 1, 0, 1);
}
/**
* remove_file:
* @model: the model
* @file: file to remove from the model. The file must have been
* added to the model previously
*
* Removes the given file from the model. If the file is not part of
* @model, this function does nothing.
**/
static void
remove_file (GtkFileSystemModel *model,
GFile *file)
{
FileModelNode *node;
guint id;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
id = node_get_for_file (model, file);
if (id == 0)
return;
node = get_node (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);
g_list_model_items_changed (G_LIST_MODEL (model), id - 1, 1, 0);
}
/**
* _gtk_file_system_model_update_file:
* @model: the model
* @file: the file
* @info: the new file info
*
* 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
* @model, it will get added automatically.
**/
void
_gtk_file_system_model_update_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info)
{
FileModelNode *node;
guint id;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (G_IS_FILE_INFO (info));
id = node_get_for_file (model, file);
if (id == 0)
{
add_file (model, file, info);
id = node_get_for_file (model, file);
}
node = get_node (model, id);
g_set_object (&node->info, info);
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
}
void
_gtk_file_system_model_update_files (GtkFileSystemModel *model,
GList *files,
@@ -1031,81 +1010,16 @@ _gtk_file_system_model_update_files (GtkFileSystemModel *model,
* _gtk_file_system_model_set_filter_folders().
**/
void
_gtk_file_system_model_set_filter (GtkFileSystemModel *model,
GtkFileFilter * filter)
_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);
old_filter = model->filter;
model->filter = filter;
if (old_filter)
g_object_unref (old_filter);
g_set_object (&model->filter, filter);
gtk_file_system_model_refilter_all (model);
}
/**
* 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 thaw_updates() to resume
* proper operations. It is fine to call this function multiple times as long as
* freeze and thaw calls are balanced.
**/
static void
freeze_updates (GtkFileSystemModel *model)
{
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
model->frozen++;
}
/**
* thaw_updates:
* @model: a `GtkFileSystemModel`
*
* Undoes the effect of a previous call to freeze_updates()
**/
static void
thaw_updates (GtkFileSystemModel *model)
{
gboolean stuff_added;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (model->frozen > 0);
model->frozen--;
if (model->frozen > 0)
return;
stuff_added = get_node (model, model->files->len - 1)->frozen_add;
if (model->filter_on_thaw)
gtk_file_system_model_refilter_all (model);
if (stuff_added)
{
guint i;
for (i = 0; i < model->files->len; i++)
{
FileModelNode *node = get_node (model, i);
if (!node->frozen_add)
continue;
node->frozen_add = FALSE;
node_compute_visibility_and_filters (model, i);
}
}
}
/**
* _gtk_file_system_model_add_and_query_file:
* @model: a `GtkFileSystemModel`
@@ -1118,8 +1032,8 @@ thaw_updates (GtkFileSystemModel *model)
**/
void
_gtk_file_system_model_add_and_query_file (GtkFileSystemModel *model,
GFile * file,
const char * attributes)
GFile *file,
const char *attributes)
{
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
@@ -1134,14 +1048,6 @@ _gtk_file_system_model_add_and_query_file (GtkFileSystemModel *model,
model);
}
static void
gtk_file_system_model_one_query_done (GObject * object,
GAsyncResult *res,
gpointer data)
{
query_done_helper (object, res, data, TRUE);
}
void
_gtk_file_system_model_add_and_query_files (GtkFileSystemModel *model,
GList *list,

View File

@@ -24,13 +24,8 @@
G_BEGIN_DECLS
#define GTK_TYPE_FILE_SYSTEM_MODEL (_gtk_file_system_model_get_type ())
#define GTK_FILE_SYSTEM_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModel))
#define GTK_IS_FILE_SYSTEM_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_SYSTEM_MODEL))
typedef struct _GtkFileSystemModel GtkFileSystemModel;
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
#define GTK_TYPE_FILE_SYSTEM_MODEL (gtk_file_system_model_get_type ())
G_DECLARE_FINAL_TYPE (GtkFileSystemModel, gtk_file_system_model, GTK, FILE_SYSTEM_MODEL, GObject)
GtkFileSystemModel *_gtk_file_system_model_new (void);
GtkFileSystemModel *_gtk_file_system_model_new_for_directory(GFile *dir,
@@ -46,9 +41,6 @@ void _gtk_file_system_model_add_and_query_file (GtkFileSystemMod
void _gtk_file_system_model_add_and_query_files (GtkFileSystemModel *model,
GList *files,
const char *attributes);
void _gtk_file_system_model_update_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info);
void _gtk_file_system_model_update_files (GtkFileSystemModel *model,
GList *files,
GList *infos);