[gtk+] filechooserentry: Use a GtkFileSystemModel



commit a1e0c1e042e2fa41212f44ecafb81e7d0bc33e18
Author: Benjamin Otte <otte redhat com>
Date:   Thu Nov 3 18:27:36 2011 +0100

    filechooserentry: Use a GtkFileSystemModel
    
    Replace the usage of a list store and a GtkFolder with a
    GtkFileSystemModel. This improves performance and reduces code size.

 gtk/gtkfilechooserentry.c |  201 +++++++++++++++------------------------------
 1 files changed, 65 insertions(+), 136 deletions(-)
---
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c
index 1a51713..901d3e6 100644
--- a/gtk/gtkfilechooserentry.c
+++ b/gtk/gtkfilechooserentry.c
@@ -27,6 +27,7 @@
 #include "gtkcelllayout.h"
 #include "gtkcellrenderertext.h"
 #include "gtkentry.h"
+#include "gtkfilesystemmodel.h"
 #include "gtklabel.h"
 #include "gtkmain.h"
 #include "gtksizerequest.h"
@@ -72,10 +73,6 @@ struct _GtkFileChooserEntry
   gchar *file_part;
   gint file_part_pos;
 
-  /* Folder being loaded or already loaded */
-  GtkFolder *current_folder;
-  GCancellable *load_folder_cancellable;
-
   LoadCompleteAction load_complete_action;
 
   GtkTreeModel *completion_store;
@@ -154,8 +151,9 @@ typedef enum {
 
 static RefreshStatus refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry,
 						  RefreshMode refresh_mode);
-static void finished_loading_cb (GtkFolder *folder,
-				 gpointer   data);
+static void finished_loading_cb (GtkFileSystemModel  *model,
+                                 GError              *error,
+		                 GtkFileChooserEntry *chooser_entry);
 static void autocomplete (GtkFileChooserEntry *chooser_entry);
 static void install_start_autocompletion_idle (GtkFileChooserEntry *chooser_entry);
 static void remove_completion_feedback (GtkFileChooserEntry *chooser_entry);
@@ -244,9 +242,6 @@ gtk_file_chooser_entry_finalize (GObject *object)
   if (chooser_entry->base_folder)
     g_object_unref (chooser_entry->base_folder);
 
-  if (chooser_entry->current_folder)
-    g_object_unref (chooser_entry->current_folder);
-
   if (chooser_entry->current_folder_file)
     g_object_unref (chooser_entry->current_folder_file);
 
@@ -258,19 +253,6 @@ gtk_file_chooser_entry_finalize (GObject *object)
 static void
 discard_loading_and_current_folder_file (GtkFileChooserEntry *chooser_entry)
 {
-  if (chooser_entry->current_folder)
-    {
-      g_signal_handlers_disconnect_by_func (chooser_entry->current_folder,
-					    G_CALLBACK (finished_loading_cb), chooser_entry);
-      g_object_unref (chooser_entry->current_folder);
-      chooser_entry->current_folder = NULL;
-    }
-  if (chooser_entry->load_folder_cancellable)
-    {
-      g_cancellable_cancel (chooser_entry->load_folder_cancellable);
-      chooser_entry->load_folder_cancellable = NULL;
-    }
-
   if (chooser_entry->current_folder_file)
     {
       g_object_unref (chooser_entry->current_folder_file);
@@ -478,7 +460,6 @@ find_common_prefix (GtkFileChooserEntry *chooser_entry,
     return FALSE;
 
   g_assert (parsed_folder_file != NULL
-	    && chooser_entry->current_folder != NULL
 	    && g_file_equal (parsed_folder_file, chooser_entry->current_folder_file));
 
   g_object_unref (parsed_folder_file);
@@ -980,7 +961,6 @@ explicitly_complete (GtkFileChooserEntry *chooser_entry)
 {
   CommonPrefixResult result;
 
-  g_assert (chooser_entry->current_folder != NULL);
   g_assert (chooser_entry->current_folder_loaded);
 
   /* FIXME: see what Emacs does in case there is no common prefix, or there is more than one match:
@@ -1054,7 +1034,7 @@ start_explicit_completion (GtkFileChooserEntry *chooser_entry)
     case REFRESH_OK:
       g_assert (chooser_entry->current_folder_file != NULL);
 
-      if (chooser_entry->current_folder && chooser_entry->current_folder_loaded)
+      if (chooser_entry->current_folder_loaded)
 	explicitly_complete (chooser_entry);
       else
 	{
@@ -1212,53 +1192,49 @@ discard_completion_store (GtkFileChooserEntry *chooser_entry)
   chooser_entry->completion_store = NULL;
 }
 
+static gboolean
+completion_store_set (GtkFileSystemModel  *model,
+                      GFile               *file,
+                      GFileInfo           *info,
+                      int                  column,
+                      GValue              *value,
+                      gpointer             data)
+{
+  switch (column)
+    {
+    case FILE_COLUMN:
+      g_value_set_object (value, file);
+      break;
+    case DISPLAY_NAME_COLUMN:
+      if (_gtk_file_info_consider_as_directory (info))
+        g_value_take_string (value, g_strconcat (g_file_info_get_display_name (info), G_DIR_SEPARATOR_S, NULL));
+      else
+        g_value_set_string (value, g_file_info_get_display_name (info));
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  return TRUE;
+}
+
 /* Fills the completion store from the contents of the current folder */
 static void
 populate_completion_store (GtkFileChooserEntry *chooser_entry)
 {
-  GSList *files;
-  GSList *tmp_list;
-
   discard_completion_store (chooser_entry);
 
-  files = _gtk_folder_list_children (chooser_entry->current_folder);
-
-  chooser_entry->completion_store = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS,
-                                                                        G_TYPE_STRING,
-                                                                        G_TYPE_FILE));
-
-  for (tmp_list = files; tmp_list; tmp_list = tmp_list->next)
-    {
-      GFileInfo *info;
-      GFile *file;
-
-      file = tmp_list->data;
-
-      info = _gtk_folder_get_info (chooser_entry->current_folder, file);
-
-      if (info)
-	{
-	  gchar *display_name = g_strdup (g_file_info_get_display_name (info));
-	  GtkTreeIter iter;
-
-          if (_gtk_file_info_consider_as_directory (info))
-            display_name = g_strconcat (g_file_info_get_display_name (info), G_DIR_SEPARATOR_S, NULL);
-          else
-            display_name = g_strdup (g_file_info_get_display_name (info));
-
-	  gtk_list_store_append (GTK_LIST_STORE (chooser_entry->completion_store), &iter);
-	  gtk_list_store_set (GTK_LIST_STORE (chooser_entry->completion_store), &iter,
-			      DISPLAY_NAME_COLUMN, display_name,
-			      FILE_COLUMN, file,
-			      -1);
-
-	  g_object_unref (info);
-          g_free (display_name);
-	}
-    }
-
-  g_slist_foreach (files, (GFunc) g_object_unref, NULL);
-  g_slist_free (files);
+  chooser_entry->completion_store = GTK_TREE_MODEL (
+      _gtk_file_system_model_new_for_directory (chooser_entry->current_folder_file,
+                                                "standard::name,standard::display-name,standard::type",
+                                                completion_store_set,
+                                                chooser_entry,
+                                                N_COLUMNS,
+                                                G_TYPE_STRING,
+                                                G_TYPE_FILE));
+  g_signal_connect (chooser_entry->completion_store, "finished-loading",
+		    G_CALLBACK (finished_loading_cb), chooser_entry);
 
   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (chooser_entry->completion_store),
 					DISPLAY_NAME_COLUMN, GTK_SORT_ASCENDING);
@@ -1296,7 +1272,6 @@ perform_load_complete_action (GtkFileChooserEntry *chooser_entry)
 static void
 finish_folder_load (GtkFileChooserEntry *chooser_entry)
 {
-  populate_completion_store (chooser_entry);
   perform_load_complete_action (chooser_entry);
 
   gtk_widget_set_tooltip_text (GTK_WIDGET (chooser_entry), NULL);
@@ -1304,29 +1279,11 @@ finish_folder_load (GtkFileChooserEntry *chooser_entry)
 
 /* Callback when the current folder finishes loading */
 static void
-finished_loading_cb (GtkFolder *folder,
-		     gpointer   data)
+finished_loading_cb (GtkFileSystemModel  *model,
+                     GError              *error,
+		     GtkFileChooserEntry *chooser_entry)
 {
-  GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (data);
-
   chooser_entry->current_folder_loaded = TRUE;
-  finish_folder_load (chooser_entry);
-}
-
-/* Callback when the current folder's handle gets obtained (not necessarily loaded completely) */
-static void
-load_directory_get_folder_callback (GCancellable  *cancellable,
-				    GtkFolder     *folder,
-				    const GError  *error,
-				    gpointer       data)
-{
-  gboolean cancelled = g_cancellable_is_cancelled (cancellable);
-  GtkFileChooserEntry *chooser_entry = data;
-
-  if (cancellable != chooser_entry->load_folder_cancellable)
-    goto out;
-
-  chooser_entry->load_folder_cancellable = NULL;
 
   if (error)
     {
@@ -1344,26 +1301,11 @@ load_directory_get_folder_callback (GCancellable  *cancellable,
 	  beep (chooser_entry);
 	  pop_up_completion_feedback (chooser_entry, error->message);
 	}
-    }
 
-  if (cancelled || error)
-    goto out;
-
-  g_assert (folder != NULL);
-  chooser_entry->current_folder = g_object_ref (folder);
-
-  discard_completion_store (chooser_entry);
-
-  chooser_entry->current_folder_loaded = _gtk_folder_is_finished_loading (chooser_entry->current_folder);
-  if (chooser_entry->current_folder_loaded)
-    finish_folder_load (chooser_entry);
-  else
-    g_signal_connect (chooser_entry->current_folder, "finished-loading",
-		      G_CALLBACK (finished_loading_cb), chooser_entry);
+      return;
+    }
 
-out:
-  g_object_unref (chooser_entry);
-  g_object_unref (cancellable);
+  finish_folder_load (chooser_entry);
 }
 
 static RefreshStatus
@@ -1373,8 +1315,7 @@ reload_current_folder (GtkFileChooserEntry *chooser_entry,
   g_assert (folder_file != NULL);
 
   if (chooser_entry->current_folder_file
-      && g_file_equal (folder_file, chooser_entry->current_folder_file)
-      && chooser_entry->load_folder_cancellable)
+      && g_file_equal (folder_file, chooser_entry->current_folder_file))
     return REFRESH_OK;
 
   if (chooser_entry->current_folder_file)
@@ -1387,13 +1328,9 @@ reload_current_folder (GtkFileChooserEntry *chooser_entry,
     return REFRESH_NOT_LOCAL;
 
   chooser_entry->current_folder_file = g_object_ref (folder_file);
+  chooser_entry->current_folder_loaded = FALSE;
 
-  chooser_entry->load_folder_cancellable =
-    _gtk_file_system_get_folder (chooser_entry->file_system,
-			         chooser_entry->current_folder_file,
-			 	 "standard::name,standard::display-name,standard::type",
-			         load_directory_get_folder_callback,
-			         g_object_ref (chooser_entry));
+  populate_completion_store (chooser_entry);
 
   return REFRESH_OK;
 }
@@ -1492,14 +1429,10 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry,
 
   g_assert (/* we are OK and we have a current folder file and (loading process or folder handle)... */
 	    ((result == REFRESH_OK)
-	     && (chooser_entry->current_folder_file != NULL)
-	     && (((chooser_entry->load_folder_cancellable != NULL) && (chooser_entry->current_folder == NULL))
-		 || ((chooser_entry->load_folder_cancellable == NULL) && (chooser_entry->current_folder != NULL))))
+	     && (chooser_entry->current_folder_file != NULL))
 	    /* ... OR we have an error, and we don't have a current folder file nor a loading process nor a folder handle */
 	    || ((result != REFRESH_OK)
-		&& (chooser_entry->current_folder_file == NULL)
-		&& (chooser_entry->load_folder_cancellable == NULL)
-		&& (chooser_entry->current_folder == NULL)));
+		&& (chooser_entry->current_folder_file == NULL)));
 
   return result;
 }
@@ -1507,8 +1440,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry,
 static void
 autocomplete (GtkFileChooserEntry *chooser_entry)
 {
-  if (!(chooser_entry->current_folder != NULL
-	&& chooser_entry->current_folder_loaded
+  if (!(chooser_entry->current_folder_loaded
 	&& gtk_editable_get_position (GTK_EDITABLE (chooser_entry)) == gtk_entry_get_text_length (GTK_ENTRY (chooser_entry))))
     return;
 
@@ -1527,7 +1459,7 @@ start_autocompletion (GtkFileChooserEntry *chooser_entry)
     case REFRESH_OK:
       g_assert (chooser_entry->current_folder_file != NULL);
 
-      if (chooser_entry->current_folder && chooser_entry->current_folder_loaded)
+      if (chooser_entry->current_folder_loaded)
 	autocomplete (chooser_entry);
       else
 	chooser_entry->load_complete_action = LOAD_COMPLETE_AUTOCOMPLETE;
@@ -1803,22 +1735,19 @@ gboolean
 _gtk_file_chooser_entry_get_is_folder (GtkFileChooserEntry *chooser_entry,
 				       GFile               *file)
 {
-  gboolean retval = FALSE;
-
-  if (chooser_entry->current_folder)
-    {
-      GFileInfo *file_info;
+  GtkTreeIter iter;
+  GFileInfo *info;
 
-      file_info = _gtk_folder_get_info (chooser_entry->current_folder, file);
+  if (chooser_entry->completion_store == NULL ||
+      !_gtk_file_system_model_get_iter_for_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
+                                                 &iter,
+                                                 file))
+    return FALSE;
 
-      if (file_info)
-        {
-	  retval = _gtk_file_info_consider_as_directory (file_info);
-	  g_object_unref (file_info);
-	}
-    }
+  info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
+                                          &iter);
 
-  return retval;
+  return _gtk_file_info_consider_as_directory (info);
 }
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]