[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Add thunar_file_get_async(). Prepare lazy loading of file shortcuts.

Jannis Pohlmann noreply at xfce.org
Wed Jun 8 04:42:01 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 8d83c5c0e8db0167ccc47e08aa20d2a250d86382 (commit)
       from 7b04c9538da8ab1984e8d9ae4b0f3bfc1b4211fe (commit)

commit 8d83c5c0e8db0167ccc47e08aa20d2a250d86382
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Wed Jun 8 04:40:33 2011 +0200

    Add thunar_file_get_async(). Prepare lazy loading of file shortcuts.

 thunar/thunar-file.c         |  188 ++++++++++++++++++++++++++++++++++--------
 thunar/thunar-file.h         |   13 +++
 thunar/thunar-shortcut-row.c |    2 +
 thunar/thunar-shortcut.c     |   93 ++++++++++++++++-----
 4 files changed, 239 insertions(+), 57 deletions(-)

diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c
index fece42f..de2cb1f 100644
--- a/thunar/thunar-file.c
+++ b/thunar/thunar-file.c
@@ -117,6 +117,13 @@ static void               thunar_file_monitor                  (GFileMonitor
                                                                 GFile                  *other_path,
                                                                 GFileMonitorEvent       event_type,
                                                                 gpointer                user_data);
+static void               thunar_file_get_async_finish         (GObject                *object,
+                                                                GAsyncResult           *result,
+                                                                gpointer                user_data);
+static void               thunar_file_prepare_reload           (ThunarFile             *file);
+static void               thunar_file_finish_reload            (ThunarFile             *file,
+                                                                GCancellable           *cancellable,
+                                                                GError                **error);
 
 
 
@@ -683,39 +690,92 @@ thunar_file_get_for_uri (const gchar *uri,
 
 
 
+static void
+thunar_file_get_async_finish (GObject      *object,
+                              GAsyncResult *result,
+                              gpointer      user_data)
+{
+  ThunarFileGetAsyncFunc func = user_data;
+  ThunarFile            *file;
+  GFileInfo             *file_info;
+  GError                *error = NULL;
+  GFile                 *location = G_FILE (object);
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
+
+  /* finish querying the file information */
+  file_info = g_file_query_info_finish (location, result, &error);
+
+  /* allocate a new file object */
+  file = g_object_new (THUNAR_TYPE_FILE, NULL);
+  file->gfile = g_object_ref (location);
+
+  /* reset the file */
+  thunar_file_prepare_reload (file);
+
+  /* set the file information */
+  file->info = file_info;
+
+  /* update the file from the information */
+  /* how can we get a cancellable from the async result here */
+  thunar_file_finish_reload (file, NULL, &error);
+
+  /* insert the file into the cache */
+  G_LOCK (file_cache_mutex);
+  g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
+  G_UNLOCK (file_cache_mutex);
+
+  /* pass the loaded file and possible errors to the return function */
+  (func) (location, file, error);
+
+  /* free the error, if there is any */
+  if (error != NULL)
+    g_error_free (error);
+
+  /* release the file */
+  g_object_unref (file);
+}
+
+
+
 /**
- * thunar_file_load:
- * @file        : a #ThunarFile.
- * @cancellable : a #GCancellable.
- * @error       : return location for errors or %NULL.
- *
- * Loads all information about the file. As this is a possibly
- * blocking call, it can be cancelled using @cancellable. 
- *
- * If loading the file fails or the operation is cancelled,
- * @error will be set.
- *
- * Return value: %TRUE on success, %FALSE on error or interruption.
+ * thunar_file_get_async:
  **/
-gboolean
-thunar_file_load (ThunarFile   *file,
-                  GCancellable *cancellable,
-                  GError      **error)
+void
+thunar_file_get_async (GFile                 *location,
+                       GCancellable          *cancellable,
+                       ThunarFileGetAsyncFunc func)
 {
-  const gchar *target_uri;
-  GKeyFile    *key_file;
-  GError      *err = NULL;
-  GFile       *thumbnail_dir;
-  gchar       *base_name;
-  gchar       *md5_hash;
-  gchar       *p;
-  gchar       *thumbnail_dir_path;
-  gchar       *uri = NULL;
+  ThunarFile *file;
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+
+  /* check if we already have a cached version of that file */
+  file = thunar_file_cache_lookup (location);
+  if (G_UNLIKELY (file != NULL))
+    {
+      /* call the return function with the file from the cache */
+      (func) (location, file, NULL);
+    }
+  else
+    {
+      /* load the file information asynchronously */
+      g_file_query_info_async (location,
+                               THUNARX_FILE_INFO_NAMESPACE,
+                               G_FILE_QUERY_INFO_NONE,
+                               0,
+                               cancellable,
+                               thunar_file_get_async_finish,
+                               func);
+    }
+}
 
-  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-  _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
 
+
+static void
+thunar_file_prepare_reload (ThunarFile *file)
+{
   /* release the current file info */
   if (file->info != NULL)
     {
@@ -740,14 +800,29 @@ thunar_file_load (ThunarFile   *file,
 
   /* assume the file is mounted by default */
   file->is_mounted = TRUE;
+}
+
 
-  /* query a new file info */
-  file->info = g_file_query_info (file->gfile,
-                                  THUNARX_FILE_INFO_NAMESPACE,
-                                  G_FILE_QUERY_INFO_NONE,
-                                  cancellable, &err);
 
-  if (err == NULL)
+static void
+thunar_file_finish_reload (ThunarFile   *file,
+                           GCancellable *cancellable,
+                           GError      **error)
+{
+  const gchar *target_uri;
+  GKeyFile    *key_file;
+  GFile       *thumbnail_dir;
+  gchar       *base_name;
+  gchar       *md5_hash;
+  gchar       *p;
+  gchar       *thumbnail_dir_path;
+  gchar       *uri = NULL;
+
+  _thunar_return_if_fail (THUNAR_IS_FILE (file));
+  _thunar_return_if_fail (error != NULL);
+
+  /* check the mounted state of the file */
+  if (*error == NULL)
     {
       if (g_file_info_get_file_type (file->info) == G_FILE_TYPE_MOUNTABLE)
         {
@@ -759,10 +834,10 @@ thunar_file_load (ThunarFile   *file,
     }
   else
     {
-      if (err->domain == G_IO_ERROR && err->code == G_IO_ERROR_NOT_MOUNTED)
+      if ((*error)->domain == G_IO_ERROR && (*error)->code == G_IO_ERROR_NOT_MOUNTED)
         {
           file->is_mounted = FALSE;
-          g_clear_error (&err);
+          g_clear_error (error);
         }
     }
 
@@ -901,7 +976,48 @@ thunar_file_load (ThunarFile   *file,
   g_free (uri);
 
   /* TODO monitor the thumbnail file for changes */
+}
+
+
+
+/**
+ * thunar_file_load:
+ * @file        : a #ThunarFile.
+ * @cancellable : a #GCancellable.
+ * @error       : return location for errors or %NULL.
+ *
+ * Loads all information about the file. As this is a possibly
+ * blocking call, it can be cancelled using @cancellable. 
+ *
+ * If loading the file fails or the operation is cancelled,
+ * @error will be set.
+ *
+ * Return value: %TRUE on success, %FALSE on error or interruption.
+ **/
+gboolean
+thunar_file_load (ThunarFile   *file,
+                  GCancellable *cancellable,
+                  GError      **error)
+{
+  GError *err = NULL;
+
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+
+  /* reset the file */
+  thunar_file_prepare_reload (file);
+
+  /* query a new file info */
+  file->info = g_file_query_info (file->gfile,
+                                  THUNARX_FILE_INFO_NAMESPACE,
+                                  G_FILE_QUERY_INFO_NONE,
+                                  cancellable, &err);
+
+  /* update from file information */
+  thunar_file_finish_reload (file, cancellable, &err);
 
+  /* propagate the error */
   if (err != NULL)
     {
       g_propagate_error (error, err);
diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h
index d1a5704..34b970e 100644
--- a/thunar/thunar-file.h
+++ b/thunar/thunar-file.h
@@ -99,6 +99,15 @@ typedef enum /*< flags >*/
 #define THUNAR_FILE_EMBLEM_NAME_CANT_WRITE "emblem-nowrite"
 #define THUNAR_FILE_EMBLEM_NAME_DESKTOP "emblem-desktop"
 
+/**
+ * ThunarFileGetAsyncFunc:
+ *
+ * Callback type for loading #ThunarFile<!---->s asynchronously.
+ **/
+typedef void (*ThunarFileGetAsyncFunc) (GFile      *location,
+                                        ThunarFile *file,
+                                        GError     *error);
+
 struct _ThunarFileClass
 {
   GObjectClass __parent__;
@@ -131,6 +140,10 @@ ThunarFile       *thunar_file_get                  (GFile                  *file
 ThunarFile       *thunar_file_get_for_uri          (const gchar            *uri,
                                                     GError                **error);
 
+void              thunar_file_get_async            (GFile                 *location,
+                                                    GCancellable          *cancellable,
+                                                    ThunarFileGetAsyncFunc func);
+
 gboolean          thunar_file_load                 (ThunarFile             *file,
                                                     GCancellable           *cancellable,
                                                     GError                **error);
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index fb4fe23..de93e6e 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -849,6 +849,8 @@ thunar_shortcut_row_button_clicked (ThunarShortcutRow *row,
         }
       else if (g_mount_can_eject (row->mount))
         {
+          g_debug ("need to eject the mount");
+
           /* start spinning */
           thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_EJECTING);
 
diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c
index 6b3178c..96170c7 100644
--- a/thunar/thunar-shortcut.c
+++ b/thunar/thunar-shortcut.c
@@ -60,16 +60,17 @@ enum
 
 
 
-static void thunar_shortcut_constructed  (GObject      *object);
-static void thunar_shortcut_finalize     (GObject      *object);
-static void thunar_shortcut_get_property (GObject      *object,
-                                          guint         prop_id,
-                                          GValue       *value,
-                                          GParamSpec   *pspec);
-static void thunar_shortcut_set_property (GObject      *object,
-                                          guint         prop_id,
-                                          const GValue *value,
-                                          GParamSpec   *pspec);
+static void thunar_shortcut_constructed  (GObject        *object);
+static void thunar_shortcut_finalize     (GObject        *object);
+static void thunar_shortcut_get_property (GObject        *object,
+                                          guint           prop_id,
+                                          GValue         *value,
+                                          GParamSpec     *pspec);
+static void thunar_shortcut_set_property (GObject        *object,
+                                          guint           prop_id,
+                                          const GValue   *value,
+                                          GParamSpec     *pspec);
+static void thunar_shortcut_load_file    (ThunarShortcut *shortcut);
 
 
 
@@ -131,7 +132,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         "location",
                                                         "location",
                                                         G_TYPE_FILE,
-                                                        EXO_PARAM_READWRITE));
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_FILE,
@@ -147,7 +149,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         "volume",
                                                         "volume",
                                                         G_TYPE_VOLUME,
-                                                        EXO_PARAM_READWRITE));
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_MOUNT,
@@ -155,7 +158,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         "mount",
                                                         "mount",
                                                         G_TYPE_MOUNT,
-                                                        EXO_PARAM_READWRITE));
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_ICON,
@@ -163,7 +167,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         "icon",
                                                         "icon",
                                                         G_TYPE_ICON,
-                                                        EXO_PARAM_READWRITE));
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_EJECT_ICON,
@@ -179,7 +184,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         "name",
                                                         "name",
                                                         NULL,
-                                                        EXO_PARAM_READWRITE));
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_SHORTCUT_TYPE,
@@ -188,7 +194,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                       "shortcut-type",
                                                       THUNAR_TYPE_SHORTCUT_TYPE,
                                                       THUNAR_SHORTCUT_REGULAR_FILE,
-                                                      EXO_PARAM_READWRITE));
+                                                      EXO_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_HIDDEN,
@@ -196,7 +203,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                          "hidden",
                                                          "hidden",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         EXO_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_MUTABLE,
@@ -204,7 +212,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                          "mutable",
                                                          "mutable",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         EXO_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
                                    PROP_PERSISTENT,
@@ -212,7 +221,8 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                          "persistent",
                                                          "persistent",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         EXO_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
 
   shortcut_signals[SIGNAL_CHANGED] = g_signal_new ("changed",
                                                    G_TYPE_FROM_CLASS (klass),
@@ -233,9 +243,13 @@ thunar_shortcut_init (ThunarShortcut *shortcut)
 static void
 thunar_shortcut_constructed (GObject *object)
 {
-#if 0
   ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
-#endif
+
+  if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
+      || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
+    {
+      thunar_shortcut_load_file (shortcut);
+    }
 }
 
 
@@ -394,6 +408,43 @@ thunar_shortcut_set_property (GObject      *object,
 
 
 
+#if 0
+static void
+thunar_shortcut_load_file_finish (GFile      *location,
+                                  ThunarFile *file,
+                                  GError     *error)
+{
+  if (error != NULL)
+    {
+      g_debug ("error: %s", error->message);
+    }
+  else
+    {
+      g_debug ("file loaded: %s", thunar_file_get_display_name (file));
+    }
+}
+#endif
+
+
+
+static void
+thunar_shortcut_load_file (ThunarShortcut *shortcut)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  
+  if (shortcut->file != NULL)
+    return;
+
+#if 0
+  /* load the ThunarFile asynchronously */
+  /* TODO pass a cancellable here */
+  thunar_file_get_async (shortcut->location, NULL,
+                         thunar_shortcut_load_file_finish);
+#endif
+}
+
+
+
 GFile *
 thunar_shortcut_get_location (ThunarShortcut *shortcut)
 {



More information about the Xfce4-commits mailing list