[gtk+/filesystemmodel] make using the code to select files not enumerate the whole dir
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/filesystemmodel] make using the code to select files not enumerate the whole dir
- Date: Thu, 25 Jun 2009 13:52:18 +0000 (UTC)
commit 1e493ea36b71742273cd380f83dd55fcc41e24b9
Author: Benjamin Otte <otte gnome org>
Date: Thu Jun 25 15:43:59 2009 +0200
make using the code to select files not enumerate the whole dir
It now uses the files in the list view it's going to select in anyway.
gtk/gtkfilechooserdefault.c | 229 ++++++++-----------------------------------
gtk/gtkfilechooserprivate.h | 1 -
gtk/gtkfilesystemmodel.c | 62 +++++++++++-
gtk/gtkfilesystemmodel.h | 2 +
4 files changed, 100 insertions(+), 194 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 7d8da72..0da6879 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -5533,12 +5533,6 @@ gtk_file_chooser_default_dispose (GObject *object)
impl->update_current_folder_cancellable = NULL;
}
- if (impl->show_and_select_files_cancellable)
- {
- g_cancellable_cancel (impl->show_and_select_files_cancellable);
- impl->show_and_select_files_cancellable = NULL;
- }
-
if (impl->should_respond_get_info_cancellable)
{
g_cancellable_cancel (impl->should_respond_get_info_cancellable);
@@ -5758,57 +5752,6 @@ gtk_file_chooser_default_size_allocate (GtkWidget *widget,
GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation);
}
-static gboolean
-get_is_file_filtered (GtkFileChooserDefault *impl,
- GFile *file,
- GFileInfo *file_info)
-{
- GtkFileFilterInfo filter_info;
- GtkFileFilterFlags needed;
- gboolean result;
- const char *s;
-
- if (!impl->current_filter)
- return FALSE;
-
- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
-
- needed = gtk_file_filter_get_needed (impl->current_filter);
-
- filter_info.display_name = g_file_info_get_display_name (file_info);
- s = g_file_info_get_content_type (file_info);
- if (s)
- filter_info.mime_type = g_content_type_get_mime_type (s);
- else
- filter_info.mime_type = NULL;
-
- if (needed & GTK_FILE_FILTER_FILENAME)
- {
- filter_info.filename = g_file_get_path (file);
- if (filter_info.filename)
- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
- }
- else
- filter_info.filename = NULL;
-
- if (needed & GTK_FILE_FILTER_URI)
- {
- filter_info.uri = g_file_get_uri (file);
- if (filter_info.uri)
- filter_info.contains |= GTK_FILE_FILTER_URI;
- }
- else
- filter_info.uri = NULL;
-
- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
-
- g_free ((gchar *)filter_info.filename);
- g_free ((gchar *)filter_info.uri);
- g_free ((gchar *)filter_info.mime_type);
-
- return !result;
-}
-
static void
set_sort_column (GtkFileChooserDefault *impl)
{
@@ -6254,148 +6197,58 @@ browse_files_center_selected_row (GtkFileChooserDefault *impl)
gtk_tree_selection_selected_foreach (selection, center_selected_row_foreach_cb, &closure);
}
-struct ShowAndSelectPathsData
-{
- GtkFileChooserDefault *impl;
- GSList *files;
-};
-
-static void
-show_and_select_files_finished_loading (GtkFolder *folder,
- gpointer user_data)
+static gboolean
+show_and_select_files (GtkFileChooserDefault *impl,
+ GSList *files)
{
- gboolean have_hidden;
- gboolean have_filtered;
- GSList *l;
- struct ShowAndSelectPathsData *data = user_data;
-
- have_hidden = FALSE;
- have_filtered = FALSE;
-
- for (l = data->files; l; l = l->next)
- {
- GFile *file;
- GFileInfo *info;
-
- file = l->data;
-
- info = _gtk_folder_get_info (folder, file);
- if (info)
- {
- if (!have_hidden)
- have_hidden = g_file_info_get_is_hidden (info)
- || g_file_info_get_is_backup (info);
-
- if (!have_filtered)
- have_filtered = (! _gtk_file_info_consider_as_directory (info)) &&
- get_is_file_filtered (data->impl, file, info);
-
- g_object_unref (info);
-
- if (have_hidden && have_filtered)
- break; /* we now have all the information we need */
- }
- }
-
- g_signal_handlers_disconnect_by_func (folder,
- show_and_select_files_finished_loading,
- user_data);
-
- if (have_hidden)
- g_object_set (data->impl, "show-hidden", TRUE, NULL);
+ GtkTreeSelection *selection;
+ GtkFileSystemModel *fsmodel;
+ gboolean can_have_hidden, can_have_filtered, selected_a_file;
+ GSList *walk;
- if (have_filtered)
- set_current_filter (data->impl, NULL);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
+ fsmodel = GTK_FILE_SYSTEM_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view)));
+ can_have_hidden = !impl->show_hidden;
+ can_have_filtered = impl->current_filter != NULL;
+ selected_a_file = FALSE;
- for (l = data->files; l; l = l->next)
+ for (walk = files; walk && (can_have_hidden || can_have_filtered); walk = walk->next)
{
- GtkTreeSelection *selection;
+ GFile *file = walk->data;
GtkTreeIter iter;
- if (!_gtk_file_system_model_get_iter_for_file (data->impl->browse_files_model,
- &iter,
- l->data))
+ if (!_gtk_file_system_model_get_iter_for_file (fsmodel, &iter, file))
continue;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->impl->browse_files_tree_view));
- gtk_tree_selection_select_iter (selection, &iter);
- }
-
- browse_files_center_selected_row (data->impl);
-
- g_object_unref (data->impl);
- g_slist_foreach (data->files, (GFunc) g_object_unref, NULL);
- g_slist_free (data->files);
- g_free (data);
-}
-
-static void
-show_and_select_files_get_folder_cb (GCancellable *cancellable,
- GtkFolder *folder,
- const GError *error,
- gpointer user_data)
-{
- gboolean cancelled = g_cancellable_is_cancelled (cancellable);
- struct ShowAndSelectPathsData *data = user_data;
-
- if (data->impl->show_and_select_files_cancellable != cancellable)
- goto out;
-
- data->impl->show_and_select_files_cancellable = NULL;
-
- if (cancelled || error)
- goto out;
-
- g_object_unref (cancellable);
-
- if (_gtk_folder_is_finished_loading (folder))
- show_and_select_files_finished_loading (folder, user_data);
- else
- g_signal_connect (folder, "finished-loading",
- G_CALLBACK (show_and_select_files_finished_loading),
- user_data);
-
- return;
-
-out:
- g_object_unref (data->impl);
- g_slist_foreach (data->files, (GFunc) g_object_unref, NULL);
- g_slist_free (data->files);
- g_free (data);
-
- g_object_unref (cancellable);
-}
-
-static gboolean
-show_and_select_files (GtkFileChooserDefault *impl,
- GFile *parent_file,
- GSList *files)
-{
- struct ShowAndSelectPathsData *info;
+ if (!_gtk_file_system_model_get_is_visible (fsmodel, &iter))
+ {
+ GFileInfo *info = _gtk_file_system_model_get_info (fsmodel, &iter);
- profile_start ("start", NULL);
+ if (can_have_hidden &&
+ (g_file_info_get_is_hidden (info) ||
+ g_file_info_get_is_backup (info)))
+ {
+ g_object_set (impl, "show-hidden", TRUE, NULL);
+ can_have_hidden = FALSE;
+ }
- if (!files)
- {
- profile_end ("end", NULL);
- return TRUE;
+ if (can_have_filtered)
+ {
+ set_current_filter (impl, NULL);
+ can_have_filtered = FALSE;
+ }
+ }
+
+ if (_gtk_file_system_model_get_is_visible (fsmodel, &iter))
+ {
+ gtk_tree_selection_select_iter (selection, &iter);
+ selected_a_file = TRUE;
+ }
}
- info = g_new (struct ShowAndSelectPathsData, 1);
- info->impl = g_object_ref (impl);
- info->files = g_slist_copy (files);
- g_slist_foreach (info->files, (GFunc) g_object_ref, NULL);
-
- if (impl->show_and_select_files_cancellable)
- g_cancellable_cancel (impl->show_and_select_files_cancellable);
+ browse_files_center_selected_row (impl);
- impl->show_and_select_files_cancellable =
- _gtk_file_system_get_folder (impl->file_system, parent_file,
- "standard::is-hidden,standard::is-backup,standard::type,standard::name,standard::content-type",
- show_and_select_files_get_folder_cb, info);
-
- profile_end ("end", NULL);
- return TRUE;
+ return selected_a_file;
}
/* Processes the pending operation when a folder is finished loading */
@@ -6407,7 +6260,7 @@ pending_select_files_process (GtkFileChooserDefault *impl)
if (impl->pending_select_files)
{
- show_and_select_files (impl, impl->current_folder, impl->pending_select_files);
+ show_and_select_files (impl, impl->pending_select_files);
pending_select_files_free (impl);
browse_files_center_selected_row (impl);
}
@@ -7313,7 +7166,7 @@ gtk_file_chooser_default_select_file (GtkFileChooser *chooser,
files.data = (gpointer) file;
files.next = NULL;
- result = show_and_select_files (impl, parent_file, &files);
+ result = show_and_select_files (impl, &files);
g_object_unref (parent_file);
return result;
}
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index cfb0c70..4e90024 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -233,7 +233,6 @@ struct _GtkFileChooserDefault
GSList *reload_icon_cancellables;
GCancellable *file_list_drag_data_received_cancellable;
GCancellable *update_current_folder_cancellable;
- GCancellable *show_and_select_files_cancellable;
GCancellable *should_respond_get_info_cancellable;
GCancellable *file_exists_get_info_cancellable;
GCancellable *update_from_entry_cancellable;
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index 300addf..e2a7c4e 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -968,11 +968,6 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
model->cancellable,
gtk_file_system_model_closed_enumerator,
NULL);
- if (error)
- g_error_free (error);
- else
- g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, NULL);
-
if (model->dir_thaw_source != 0)
{
g_source_remove (model->dir_thaw_source);
@@ -980,6 +975,11 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
_gtk_file_system_model_thaw_updates (model);
}
+ if (error)
+ g_error_free (error);
+ else
+ g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, NULL);
+
g_object_unref (model);
}
else
@@ -1315,6 +1315,17 @@ _gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
}
}
+/**
+ * _gtk_file_system_model_get_cancellable:
+ * @model: the model
+ *
+ * Gets the cancellable used by the @model. This is the cancellable used
+ * internally by the @model that will be cancelled when @model is
+ * disposed. So you can use it for operations that should be cancelled
+ * when the model goes away.
+ *
+ * Returns: The cancellable used by @model
+ **/
GCancellable *
_gtk_file_system_model_get_cancellable (GtkFileSystemModel *model)
{
@@ -1324,6 +1335,32 @@ _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model)
}
/**
+ * _gtk_file_system_model_get_is_visible:
+ * @model: the model
+ * @iter: a valid iterator
+ *
+ * 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
+ * being a hidden file.
+ *
+ * Returns: %TRUE if the iterator is visible
+ **/
+gboolean
+_gtk_file_system_model_get_is_visible (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->visible;
+}
+
+/**
* _gtk_file_system_model_get_info:
* @model: a #GtkFileSystemModel
* @iter: a #GtkTreeIter pointing to a row of @model
@@ -1347,6 +1384,7 @@ _gtk_file_system_model_get_info (GtkFileSystemModel *model,
FileModelNode *node;
g_return_val_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
node = get_node (model, ITER_INDEX (iter));
g_assert (node->info == NULL || G_IS_FILE_INFO (node->info));
@@ -1447,6 +1485,20 @@ node_get_for_file (GtkFileSystemModel *model,
return 0;
}
+/**
+ * _gtk_file_system_model_get_iter_for_file:
+ * @model: the model
+ * @iter: the iterator to be initialized
+ * @file: the file to look up
+ *
+ * Initializes @iter to point to the row used for @file, if @file is part
+ * of the model. Note that upon successful return, @iter may point to an
+ * invisible row in the @model. Use
+ * _gtk_file_system_model_get_is_visible() to make sure it is visible to
+ * the tree view.
+ *
+ * Returns: %TRUE if file is part of the model and @iter was initialized
+ **/
gboolean
_gtk_file_system_model_get_iter_for_file (GtkFileSystemModel *model,
GtkTreeIter *iter,
diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h
index 11e1d7c..f96b5b1 100644
--- a/gtk/gtkfilesystemmodel.h
+++ b/gtk/gtkfilesystemmodel.h
@@ -53,6 +53,8 @@ GtkFileSystemModel *_gtk_file_system_model_new_for_directory(GFile *
guint n_columns,
...);
GCancellable * _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model);
+gboolean _gtk_file_system_model_get_is_visible (GtkFileSystemModel *model,
+ GtkTreeIter *iter);
GFileInfo * _gtk_file_system_model_get_info (GtkFileSystemModel *model,
GtkTreeIter *iter);
gboolean _gtk_file_system_model_get_iter_for_file(GtkFileSystemModel *model,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]