[Xfce4-commits] <ristretto:master> Add the directory-contents asynchronously.

Stephan Arts noreply at xfce.org
Sun Apr 15 22:26:01 CEST 2012


Updating branch refs/heads/master
         to 1ce6812ab6a0ab6708b534f087e5f57e3c9dbf75 (commit)
       from 6daa6261fd9c15092e950d88618e345284a84b94 (commit)

commit 1ce6812ab6a0ab6708b534f087e5f57e3c9dbf75
Author: Stephan Arts <stephan at xfce.org>
Date:   Sun Apr 15 22:23:34 2012 +0200

    Add the directory-contents asynchronously.
    
    Do not freeze the gui when we are dealing with a lot of files.

 src/image_list.c  |  113 +++++++++++++++++++++++++++++++++++++++++++----------
 src/main_window.c |   34 ++++++++++++++++
 2 files changed, 126 insertions(+), 21 deletions(-)

diff --git a/src/image_list.c b/src/image_list.c
index d0b5934..8a2cdb0 100644
--- a/src/image_list.c
+++ b/src/image_list.c
@@ -221,6 +221,21 @@ struct _RsttoImageListPriv
     gboolean      wrap_images;
 };
 
+typedef struct _RsttoFileLoader RsttoFileLoader;
+
+struct _RsttoFileLoader
+{
+    GFile           *dir;
+    RsttoImageList  *image_list;
+    GFileEnumerator *file_enum;
+
+    guint            n_files;
+    RsttoFile      **files;
+};
+
+static gboolean
+cb_rstto_read_file ( gpointer user_data );
+
 static gint rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_COUNT];
 static gint rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_COUNT];
 
@@ -621,11 +636,7 @@ rstto_image_list_set_directory (
 {
     /* Declare variables */
     GFileEnumerator *file_enumerator = NULL;
-    GFileInfo *file_info;
-    const gchar *filename;
-    const gchar *content_type;
-    GFile *child_file;
-    RsttoFile *r_file;
+    RsttoFileLoader *loader = NULL;
 
     /* Source code block */
     rstto_image_list_remove_all (image_list);
@@ -637,28 +648,88 @@ rstto_image_list_set_directory (
 
         if (NULL != file_enumerator)
         {
-            for(file_info = g_file_enumerator_next_file (file_enumerator, NULL, NULL);
-                NULL != file_info;
-                file_info = g_file_enumerator_next_file (file_enumerator, NULL, NULL))
+            g_object_ref (dir);
+
+            loader = g_new0 (RsttoFileLoader, 1);
+            loader->dir = dir;
+            loader->file_enum = file_enumerator;
+            loader->image_list = image_list;
+
+            g_idle_add ( (GSourceFunc) cb_rstto_read_file, loader );
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean
+cb_rstto_read_file ( gpointer user_data )
+{
+    RsttoFileLoader *loader = user_data;
+    GFileInfo       *file_info;
+    const gchar     *content_type;
+    const gchar     *filename;
+    RsttoFile      **files;
+    GFile           *child_file;
+    guint            i;
+    GSList          *iter;
+
+    /* Check the inputs */
+    g_return_val_if_fail ( NULL != loader, FALSE );
+    g_return_val_if_fail ( NULL != loader->file_enum, FALSE );
+
+    file_info = g_file_enumerator_next_file (
+            loader->file_enum,
+            NULL,
+            NULL );
+    if ( NULL != file_info )
+    {
+        content_type  = g_file_info_get_content_type (file_info);
+        if (strncmp (content_type, "image/", 6) == 0)
+        {
+            filename = g_file_info_get_name (file_info);
+            child_file = g_file_get_child (loader->dir, filename);
+            files = g_new0 ( RsttoFile *, loader->n_files+1);
+            files[0] = rstto_file_new (child_file);
+
+            for (i = 0; i < loader->n_files; ++i)
             {
-                filename = g_file_info_get_name (file_info);
-                content_type  = g_file_info_get_content_type (file_info);
-                child_file = g_file_get_child (dir, filename);
-                r_file = rstto_file_new (child_file);
-                if (strncmp (content_type, "image/", 6) == 0)
-                {
-                    rstto_image_list_add_file (image_list, r_file, NULL);
-                }
-                g_object_unref (r_file);
-                r_file = NULL;
+                files[i+1] = loader->files[i];
+            }
+
+            if ( NULL != loader->files )
+            {
+                g_free (loader->files);
             }
-            g_object_unref (file_enumerator);
-            file_enumerator = NULL;
+            loader->files = files;
+            loader->n_files++;
         }
     }
+    else
+    {
+        for (i = 0; i < loader->n_files; ++i)
+        {
+            rstto_image_list_add_file (
+                    loader->image_list,
+                    loader->files[i],
+                    NULL);
 
-    rstto_image_list_monitor_dir ( image_list, dir );
+            g_object_unref (loader->files[i]);
+        }
+
+        rstto_image_list_monitor_dir ( 
+                loader->image_list,
+                loader->dir );
 
+        iter = loader->image_list->priv->iterators;
+        while (iter)
+        {
+            g_signal_emit (G_OBJECT (iter->data), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
+            iter = g_slist_next (iter);
+        }
+
+        return FALSE;
+    }
     return TRUE;
 }
 
diff --git a/src/main_window.c b/src/main_window.c
index 1dfd363..6717775 100644
--- a/src/main_window.c
+++ b/src/main_window.c
@@ -2708,14 +2708,31 @@ cb_rstto_main_window_open_image (GtkWidget *widget, RsttoMainWindow *window)
                     r_file = rstto_file_new (files->data);
 
                     p_file = g_file_get_parent (files->data);
+
+                    /* This call adds the contents of the
+                     * directory asynchronously.
+                     */
                     rstto_image_list_set_directory (
                             window->priv->image_list,
                             p_file,
                             NULL );
+
+                    /* Make sure the file we are looking
+                     * for is already in the list.
+                     */
+                    rstto_image_list_add_file (
+                            window->priv->image_list,
+                            r_file,
+                            NULL);
+
+                    /* Point the main iterator to the
+                     * correct file
+                     */
                     rstto_image_list_iter_find_file (
                             window->priv->iter,
                             r_file );
 
+                    /* Cleanup the reference */
                     g_object_unref (r_file);
                 }
             }
@@ -2760,14 +2777,31 @@ cb_rstto_main_window_open_recent(GtkRecentChooser *chooser, RsttoMainWindow *win
         if ( NULL != r_file )
         {
             p_file = g_file_get_parent (file);
+
+            /* This call adds the contents of the
+             * directory asynchronously.
+             */
             rstto_image_list_set_directory (
                     window->priv->image_list,
                     p_file,
                     NULL);
+
+            /* Make sure the file we are looking
+             * for is already in the list.
+             */
+            rstto_image_list_add_file (
+                    window->priv->image_list,
+                    r_file,
+                    NULL );
+
+            /* Point the main iterator to the
+             * correct file
+             */
             rstto_image_list_iter_find_file (
                     window->priv->iter,
                     r_file );
 
+            /* Cleanup the reference */
             g_object_unref (G_OBJECT (r_file));
             r_file = NULL;
         }


More information about the Xfce4-commits mailing list