[Xfce4-commits] <thunar:nick/1.8> Port deep count job to a GTask.

Nick Schermer noreply at xfce.org
Sun Aug 4 21:52:13 CEST 2013


Updating branch refs/heads/nick/1.8
         to 1e58702bbdf2b413c5a0f58e342740b2add6e6d9 (commit)
       from 345a6bf65732564df384ae89b71c57f0487a6fe9 (commit)

commit 1e58702bbdf2b413c5a0f58e342740b2add6e6d9
Author: Nick Schermer <nick at xfce.org>
Date:   Sun Aug 4 13:02:10 2013 +0200

    Port deep count job to a GTask.

 thunar/thunar-deep-count-job.c |  271 ++++++++++++++++++++++++----------------
 thunar/thunar-deep-count-job.h |   12 +-
 thunar/thunar-size-label.c     |  117 ++++++++---------
 3 files changed, 233 insertions(+), 167 deletions(-)

diff --git a/thunar/thunar-deep-count-job.c b/thunar/thunar-deep-count-job.c
index d36572e..5b9e512 100644
--- a/thunar/thunar-deep-count-job.c
+++ b/thunar/thunar-deep-count-job.c
@@ -1,7 +1,7 @@
 /* vi:set sw=2 sts=2 ts=2 et ai: */
 /*-
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
- * Copyright (c) 2012 Nick Schermer <nick at xfce.org>
+ * Copyright (c) 2009      Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012-2013 Nick Schermer <nick at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,9 +28,11 @@
 #include <gio/gio.h>
 
 #include <thunar/thunar-deep-count-job.h>
-#include <thunar/thunar-job.h>
 #include <thunar/thunar-marshal.h>
 #include <thunar/thunar-util.h>
+#include <thunar/thunar-gio-extensions.h>
+#include <thunar/thunar-file.h>
+#include <thunar/thunar-tasks.h>
 #include <thunar/thunar-private.h>
 
 
@@ -43,32 +45,35 @@ enum
 };
 
 
+
 #define DEEP_COUNT_FILE_INFO_NAMESPACE \
   G_FILE_ATTRIBUTE_STANDARD_TYPE "," \
   G_FILE_ATTRIBUTE_STANDARD_SIZE "," \
   G_FILE_ATTRIBUTE_ID_FILESYSTEM
 
+
+
 static void     thunar_deep_count_job_finalize   (GObject                 *object);
-static gboolean thunar_deep_count_job_execute    (ExoJob                  *job,
-                                                  GError                 **error);
 
 
 
 struct _ThunarDeepCountJobClass
 {
-  ThunarJobClass __parent__;
+  GObjectClass __parent__;
 
   /* signals */
-  void (*status_update) (ThunarJob *job,
-                         guint64    total_size,
-                         guint      file_count,
-                         guint      directory_count,
-                         guint      unreadable_directory_count);
+  void (*status_update) (ThunarDeepCountJob *job,
+                         guint64             total_size,
+                         guint               file_count,
+                         guint               directory_count,
+                         guint               unreadable_directory_count);
 };
 
 struct _ThunarDeepCountJob
 {
-  ThunarJob __parent__;
+  GObject __parent__;
+
+  GTask              *task;
 
   GList              *files;
   GFileQueryInfoFlags query_flags;
@@ -89,22 +94,18 @@ static guint deep_count_signals[LAST_SIGNAL];
 
 
 
-G_DEFINE_TYPE (ThunarDeepCountJob, thunar_deep_count_job, THUNAR_TYPE_JOB)
+G_DEFINE_TYPE (ThunarDeepCountJob, thunar_deep_count_job, G_TYPE_OBJECT)
 
 
 
 static void
 thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass)
 {
-  ExoJobClass  *job_class;
   GObjectClass *gobject_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunar_deep_count_job_finalize;
 
-  job_class = EXO_JOB_CLASS (klass);
-  job_class->execute = thunar_deep_count_job_execute;
-
   /**
    * ThunarDeepCountJob::status-update:
    * @job                        : a #ThunarJob.
@@ -117,7 +118,7 @@ thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass)
    * directories and bytes counted so far.
    **/
   deep_count_signals[STATUS_UPDATE] =
-    g_signal_new ("status-update",
+    g_signal_new (I_("status-update"),
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_NO_HOOKS,
                   G_STRUCT_OFFSET (ThunarDeepCountJobClass, status_update),
@@ -145,53 +146,79 @@ thunar_deep_count_job_finalize (GObject *object)
 {
   ThunarDeepCountJob *job = THUNAR_DEEP_COUNT_JOB (object);
 
-  g_list_free_full (job->files, g_object_unref);
+  thunar_g_file_list_free (job->files);
+
+  g_object_unref (job->task);
 
   (*G_OBJECT_CLASS (thunar_deep_count_job_parent_class)->finalize) (object);
 }
 
 
 
+static gboolean
+thunar_deep_count_job_status_update_main (gpointer user_data)
+{
+  ThunarDeepCountJob *job = user_data;
+
+  _thunar_return_val_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job), FALSE);
+
+  if (!g_task_had_error (job->task))
+    {
+      g_signal_emit (job,
+                     deep_count_signals[STATUS_UPDATE],
+                     0,
+                     job->total_size,
+                     job->file_count,
+                     job->directory_count,
+                     job->unreadable_directory_count);
+    }
+
+  return FALSE;
+}
+
+
+
 static void
 thunar_deep_count_job_status_update (ThunarDeepCountJob *job)
 {
-  _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
-
-  exo_job_emit (EXO_JOB (job),
-                deep_count_signals[STATUS_UPDATE],
-                0,
-                job->total_size,
-                job->file_count,
-                job->directory_count,
-                job->unreadable_directory_count);
+  /* emit in the mainloop */
+  if (THUNAR_IS_DEEP_COUNT_JOB (job)
+      && !g_task_had_error (job->task))
+    {
+      g_main_context_invoke_full (NULL, G_PRIORITY_DEFAULT,
+                                  thunar_deep_count_job_status_update_main,
+                                  g_object_ref (job), g_object_unref);
+    }
 }
 
 
 
 static gboolean
-thunar_deep_count_job_process (ExoJob       *job,
-                               GFile        *file,
-                               GFileInfo    *file_info,
-                               const gchar  *toplevel_fs_id,
-                               GError      **error)
+thunar_deep_count_job_process (ThunarDeepCountJob  *job,
+                               GFile               *file,
+                               GFileInfo           *file_info,
+                               const gchar         *toplevel_fs_id,
+                               GError             **error)
 {
-  ThunarDeepCountJob *count_job = THUNAR_DEEP_COUNT_JOB (job);
-  GFileEnumerator    *enumerator;
-  GFileInfo          *child_info;
-  GFileInfo          *info;
-  gboolean            success = TRUE;
-  GFile              *child;
-  gint64              real_time;
-  const gchar        *fs_id;
-  gboolean            toplevel_file = (toplevel_fs_id == NULL);
+  GFileEnumerator *enumerator;
+  GFileInfo       *child_info;
+  GFileInfo       *info;
+  gboolean         success = TRUE;
+  GFile           *child;
+  gint64           real_time;
+  const gchar     *fs_id;
+  gboolean         toplevel_file = (toplevel_fs_id == NULL);
+  GCancellable    *cancellable;
 
-  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (G_IS_FILE (file), FALSE);
+  _thunar_return_val_if_fail (G_IS_TASK (job->task), FALSE);
   _thunar_return_val_if_fail (file_info == NULL || G_IS_FILE_INFO (file_info), FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
+  cancellable = g_task_get_cancellable (job->task);
+
   /* abort if job was already cancelled */
-  if (exo_job_is_cancelled (job))
+  if (g_cancellable_is_cancelled (cancellable))
     return FALSE;
 
   if (file_info != NULL)
@@ -204,8 +231,8 @@ thunar_deep_count_job_process (ExoJob       *job,
       /* query size and type of the current file */
       info = g_file_query_info (file,
                                 DEEP_COUNT_FILE_INFO_NAMESPACE,
-                                count_job->query_flags,
-                                exo_job_get_cancellable (job),
+                                job->query_flags,
+                                cancellable,
                                 error);
     }
 
@@ -214,7 +241,7 @@ thunar_deep_count_job_process (ExoJob       *job,
     return FALSE;
 
   /* abort on cancellation */
-  if (exo_job_is_cancelled (job))
+  if (g_cancellable_is_cancelled (cancellable))
     {
       g_object_unref (info);
       return FALSE;
@@ -247,19 +274,19 @@ thunar_deep_count_job_process (ExoJob       *job,
       enumerator = g_file_enumerate_children (file,
                                               DEEP_COUNT_FILE_INFO_NAMESPACE ","
                                               G_FILE_ATTRIBUTE_STANDARD_NAME,
-                                              count_job->query_flags,
-                                              exo_job_get_cancellable (job),
+                                              job->query_flags,
+                                              cancellable,
                                               error);
 
-      if (!exo_job_is_cancelled (job))
+      if (!g_cancellable_is_cancelled (cancellable))
         {
           if (enumerator == NULL)
             {
               /* directory was unreadable */
-              count_job->unreadable_directory_count++;
+              job->unreadable_directory_count++;
 
               if (toplevel_file
-                  && g_list_length (count_job->files) < 2)
+                  && g_list_length (job->files) < 2)
                 {
                   /* we only bail out if the job file is unreadable */
                   success = FALSE;
@@ -273,31 +300,27 @@ thunar_deep_count_job_process (ExoJob       *job,
           else
             {
               /* directory was readable */
-              count_job->directory_count++;
+              job->directory_count++;
 
-              while (!exo_job_is_cancelled (job))
+              while (!g_cancellable_is_cancelled (cancellable))
                 {
                   /* query next child info */
                   child_info = g_file_enumerator_next_file (enumerator,
-                                                            exo_job_get_cancellable (job),
+                                                            cancellable,
                                                             error);
 
                   /* abort on invalid child info (iteration ends) or cancellation */
                   if (child_info == NULL)
                     break;
 
-                  if (!exo_job_is_cancelled (job))
-                    {
-                      /* generate a GFile for the child */
-                      child = g_file_resolve_relative_path (file, g_file_info_get_name (child_info));
-
-                      /* recurse unless the job was cancelled before */
-                      thunar_deep_count_job_process (job, child, child_info, toplevel_fs_id, error);
+                  /* generate a GFile for the child */
+                  child = g_file_resolve_relative_path (file, g_file_info_get_name (child_info));
 
-                      /* free resources */
-                      g_object_unref (child);
-                    }
+                  /* recurse unless the job was cancelled before */
+                  thunar_deep_count_job_process (job, child, child_info, toplevel_fs_id, error);
 
+                  /* free resources */
+                  g_object_unref (child);
                   g_object_unref (child_info);
                 }
             }
@@ -307,23 +330,26 @@ thunar_deep_count_job_process (ExoJob       *job,
       if (enumerator != NULL)
         g_object_unref (enumerator);
 
-      /* emit status update whenever we've finished a directory,
-       * but not more than four times per second */
-      real_time = g_get_real_time ();
-      if (real_time >= count_job->last_time)
+      if (!g_cancellable_is_cancelled (cancellable))
         {
-          if (count_job->last_time != 0)
-            thunar_deep_count_job_status_update (count_job);
-          count_job->last_time = real_time + (G_USEC_PER_SEC / 4);
+          /* emit status update whenever we've finished a directory,
+           * but not more than four times per second */
+          real_time = g_get_real_time ();
+          if (real_time >= job->last_time)
+            {
+              if (job->last_time != 0)
+                thunar_deep_count_job_status_update (job);
+              job->last_time = real_time + (G_USEC_PER_SEC / 4);
+            }
         }
     }
   else
     {
       /* we have a regular file or at least not a directory */
-      count_job->file_count++;
+      job->file_count++;
 
       /* add size of the file to the total size */
-      count_job->total_size += g_file_info_get_size (info);
+      job->total_size += g_file_info_get_size (info);
     }
 
   /* destroy the file info */
@@ -331,37 +357,41 @@ thunar_deep_count_job_process (ExoJob       *job,
 
   /* we've succeeded if there was no error when loading information
    * about the job file itself and the job was not cancelled */
-  return !exo_job_is_cancelled (job) && success;
+  return !g_cancellable_is_cancelled (cancellable) && success;
 }
 
 
 
-static gboolean
-thunar_deep_count_job_execute (ExoJob  *job,
-                               GError **error)
+static void
+thunar_deep_count_job_thread (GTask        *task,
+                              gpointer      source_object,
+                              gpointer      task_data,
+                              GCancellable *cancellable)
 {
-  ThunarDeepCountJob *count_job = THUNAR_DEEP_COUNT_JOB (job);
+  ThunarDeepCountJob *job = THUNAR_DEEP_COUNT_JOB (task_data);
   gboolean            success = TRUE;
   GError             *err = NULL;
   GList              *lp;
   GFile              *gfile;
 
-  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
-  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _thunar_return_if_fail (G_IS_TASK (task));
+  _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
+  _thunar_return_if_fail (job->task == task);
+  _thunar_return_if_fail (g_task_get_cancellable (job->task) == cancellable);
 
   /* don't start the job if it was already cancelled */
-  if (exo_job_set_error_if_cancelled (job, error))
-    return FALSE;
+  if (g_task_return_error_if_cancelled (task))
+    return;
 
   /* reset counters */
-  count_job->total_size = 0;
-  count_job->file_count = 0;
-  count_job->directory_count = 0;
-  count_job->unreadable_directory_count = 0;
-  count_job->last_time = 0;
+  job->total_size = 0;
+  job->file_count = 0;
+  job->directory_count = 0;
+  job->unreadable_directory_count = 0;
+  job->last_time = 0;
 
   /* count files, directories and compute size of the job files */
-  for (lp = count_job->files; lp != NULL; lp = lp->next)
+  for (lp = job->files; lp != NULL; lp = lp->next)
     {
       gfile = thunar_file_get_file (THUNAR_FILE (lp->data));
       success = thunar_deep_count_job_process (job, gfile, NULL, NULL, &err);
@@ -371,45 +401,72 @@ thunar_deep_count_job_execute (ExoJob  *job,
 
   if (!success)
     {
-      g_assert (err != NULL || exo_job_is_cancelled (job));
+      g_assert (err != NULL || g_cancellable_is_cancelled (cancellable));
 
-      /* set error if the job was cancelled. otherwise just propagate
-       * the results of the processing function */
-      if (exo_job_set_error_if_cancelled (job, error))
+      /* set error if the job was cancelled */
+      if (!g_task_return_error_if_cancelled (task))
         {
-          if (err != NULL)
-            g_error_free (err);
-        }
-      else
-        {
-          if (err != NULL)
-            g_propagate_error (error, err);
+          /* return the error from the process */
+          g_task_return_error (task, err);
         }
+
+      return;
     }
-  else if (!exo_job_is_cancelled (job))
+  else if (!g_cancellable_is_cancelled (cancellable))
     {
       /* emit final status update at the very end of the computation */
-      thunar_deep_count_job_status_update (count_job);
+      thunar_deep_count_job_status_update (job);
     }
 
-  return success;
+  /* done */
+  g_task_return_pointer (task, NULL, NULL);
 }
 
 
 
 ThunarDeepCountJob *
-thunar_deep_count_job_new (GList               *files,
-                           GFileQueryInfoFlags  flags)
+thunar_deep_count_job_new (gpointer             source_object,
+                           GList               *files,
+                           GFileQueryInfoFlags  flags,
+                           GAsyncReadyCallback  callback)
 {
   ThunarDeepCountJob *job;
 
+  _thunar_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
   _thunar_return_val_if_fail (files != NULL, NULL);
 
   job = g_object_new (THUNAR_TYPE_DEEP_COUNT_JOB, NULL);
-  job->files = g_list_copy (files);
+  job->task = thunar_tasks_new (source_object, callback, job);
+  job->files = thunar_g_file_list_copy (files);
   job->query_flags = flags;
 
-  g_list_foreach (job->files, (GFunc) g_object_ref, NULL);
+  /* but lower than folder tasks */
+  g_task_set_priority (job->task, G_PRIORITY_DEFAULT_IDLE);
 
   return job;
 }
+
+
+
+void
+thunar_deep_count_job_run (ThunarDeepCountJob *job)
+{
+  _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
+  _thunar_return_if_fail (G_IS_TASK (job->task));
+
+  g_task_set_task_data (job->task, job, NULL);
+  g_task_run_in_thread (job->task, thunar_deep_count_job_thread);
+}
+
+
+
+void
+thunar_deep_count_job_cancel (ThunarDeepCountJob *job)
+{
+  GCancellable *cancellable;
+
+  _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
+
+  cancellable = g_task_get_cancellable (job->task);
+  g_cancellable_cancel (cancellable);
+}
diff --git a/thunar/thunar-deep-count-job.h b/thunar/thunar-deep-count-job.h
index 735a121..ecad182 100644
--- a/thunar/thunar-deep-count-job.h
+++ b/thunar/thunar-deep-count-job.h
@@ -23,8 +23,6 @@
 
 #include <gio/gio.h>
 
-#include <thunar/thunar-job.h>
-
 G_BEGIN_DECLS;
 
 typedef struct _ThunarDeepCountJobPrivate ThunarDeepCountJobPrivate;
@@ -40,8 +38,14 @@ typedef struct _ThunarDeepCountJob        ThunarDeepCountJob;
 
 GType               thunar_deep_count_job_get_type (void) G_GNUC_CONST;
 
-ThunarDeepCountJob *thunar_deep_count_job_new      (GList              *files,
-                                                    GFileQueryInfoFlags flags) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+ThunarDeepCountJob *thunar_deep_count_job_new      (gpointer            source_object,
+                                                    GList              *files,
+                                                    GFileQueryInfoFlags flags,
+                                                    GAsyncReadyCallback callback) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+void                thunar_deep_count_job_run      (ThunarDeepCountJob *job);
+
+void                thunar_deep_count_job_cancel   (ThunarDeepCountJob *job);
 
 G_END_DECLS;
 
diff --git a/thunar/thunar-size-label.c b/thunar/thunar-size-label.c
index eff53e7..dbd5bc7 100644
--- a/thunar/thunar-size-label.c
+++ b/thunar/thunar-size-label.c
@@ -46,6 +46,7 @@ enum
 
 
 
+static void     thunar_size_label_dispose               (GObject              *object);
 static void     thunar_size_label_finalize              (GObject              *object);
 static void     thunar_size_label_get_property          (GObject              *object,
                                                          guint                 prop_id,
@@ -59,11 +60,10 @@ static gboolean thunar_size_label_button_press_event    (GtkWidget            *e
                                                          GdkEventButton       *event,
                                                          ThunarSizeLabel      *size_label);
 static void     thunar_size_label_files_changed         (ThunarSizeLabel      *size_label);
-static void     thunar_size_label_error                 (ExoJob               *job,
-                                                         const GError         *error,
-                                                         ThunarSizeLabel      *size_label);
-static void     thunar_size_label_finished              (ExoJob               *job,
-                                                         ThunarSizeLabel      *size_label);
+static void     thunar_size_label_stop_count            (ThunarSizeLabel      *size_label);
+static void     thunar_size_label_finished              (GObject              *source_object,
+                                                         GAsyncResult         *result,
+                                                         gpointer              user_data);
 static void     thunar_size_label_status_update         (ThunarDeepCountJob   *job,
                                                          guint64               total_size,
                                                          guint                 file_count,
@@ -106,6 +106,7 @@ thunar_size_label_class_init (ThunarSizeLabelClass *klass)
 
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunar_size_label_finalize;
+  gobject_class->dispose = thunar_size_label_dispose;
   gobject_class->get_property = thunar_size_label_get_property;
   gobject_class->set_property = thunar_size_label_set_property;
 
@@ -161,17 +162,22 @@ thunar_size_label_init (ThunarSizeLabel *size_label)
 
 
 static void
-thunar_size_label_finalize (GObject *object)
+thunar_size_label_dispose (GObject *object)
 {
   ThunarSizeLabel *size_label = THUNAR_SIZE_LABEL (object);
 
   /* cancel the pending job (if any) */
-  if (G_UNLIKELY (size_label->job != NULL))
-    {
-      g_signal_handlers_disconnect_matched (G_OBJECT (size_label->job), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label);
-      exo_job_cancel (EXO_JOB (size_label->job));
-      g_object_unref (size_label->job);
-    }
+  thunar_size_label_stop_count (size_label);
+
+  (*G_OBJECT_CLASS (thunar_size_label_parent_class)->dispose) (object);
+}
+
+
+
+static void
+thunar_size_label_finalize (GObject *object)
+{
+  ThunarSizeLabel *size_label = THUNAR_SIZE_LABEL (object);
 
   /* reset the file property */
   thunar_size_label_set_files (size_label, NULL);
@@ -237,18 +243,8 @@ thunar_size_label_button_press_event (GtkWidget       *ebox,
   if (G_LIKELY (event->button == 1))
     {
       /* cancel the pending job (if any) */
-      if (G_UNLIKELY (size_label->job != NULL))
-        {
-          g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label);
-          exo_job_cancel (EXO_JOB (size_label->job));
-          g_object_unref (size_label->job);
-          size_label->job = NULL;
-        }
-
-      /* be sure to stop and hide the spinner */
-      gtk_spinner_stop (GTK_SPINNER (size_label->spinner));
-      gtk_widget_hide (size_label->spinner);
-
+      thunar_size_label_stop_count (size_label);
+g_message ("aborted");
       /* tell the user that the operation was canceled */
       gtk_label_set_text (GTK_LABEL (size_label->label), _("Calculation aborted"));
 
@@ -272,22 +268,14 @@ thunar_size_label_files_changed (ThunarSizeLabel *size_label)
   _thunar_return_if_fail (THUNAR_IS_FILE (size_label->files->data));
 
   /* cancel the pending job (if any) */
-  if (G_UNLIKELY (size_label->job != NULL))
-    {
-      g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label);
-      exo_job_cancel (EXO_JOB (size_label->job));
-      g_object_unref (size_label->job);
-      size_label->job = NULL;
-    }
+  thunar_size_label_stop_count (size_label);
 
   /* check if there are multiple files or the single file is a directory */
   if (size_label->files->next != NULL
       || thunar_file_is_directory (THUNAR_FILE (size_label->files->data)))
     {
       /* schedule a new job to determine the total size of the directory (not following symlinks) */
-      size_label->job = thunar_deep_count_job_new (size_label->files, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS);
-      g_signal_connect (size_label->job, "error", G_CALLBACK (thunar_size_label_error), size_label);
-      g_signal_connect (size_label->job, "finished", G_CALLBACK (thunar_size_label_finished), size_label);
+      size_label->job = thunar_deep_count_job_new (size_label, size_label->files, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, thunar_size_label_finished);
       g_signal_connect (size_label->job, "status-update", G_CALLBACK (thunar_size_label_status_update), size_label);
 
       /* tell the user that we started calculation */
@@ -296,7 +284,7 @@ thunar_size_label_files_changed (ThunarSizeLabel *size_label)
       gtk_widget_show (size_label->spinner);
 
       /* launch the job */
-      exo_job_launch (EXO_JOB (size_label->job));
+      thunar_deep_count_job_run (size_label->job);
     }
   else
     {
@@ -317,36 +305,53 @@ thunar_size_label_files_changed (ThunarSizeLabel *size_label)
 
 
 static void
-thunar_size_label_error (ExoJob          *job,
-                         const GError    *error,
-                         ThunarSizeLabel *size_label)
+thunar_size_label_stop_count (ThunarSizeLabel *size_label)
 {
-  _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
-  _thunar_return_if_fail (size_label->job == THUNAR_DEEP_COUNT_JOB (job));
+  /* disconnect from the job */
+  if (size_label->job != NULL)
+    {
+      g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label);
+      thunar_deep_count_job_cancel (size_label->job);
+      size_label->job = NULL;
 
-  /* setup the error text as label */
-  gtk_label_set_text (GTK_LABEL (size_label->label), error->message);
+      /* stop and hide the spinner */
+      gtk_spinner_stop (GTK_SPINNER (size_label->spinner));
+      gtk_widget_hide (size_label->spinner);
+    }
 }
 
 
 
 static void
-thunar_size_label_finished (ExoJob          *job,
-                            ThunarSizeLabel *size_label)
+thunar_size_label_finished (GObject      *source_object,
+                            GAsyncResult *result,
+                            gpointer      job)
 {
-  _thunar_return_if_fail (THUNAR_IS_JOB (job));
+  ThunarSizeLabel *size_label = THUNAR_SIZE_LABEL (source_object);
+  GError          *error = NULL;
+
   _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
-  _thunar_return_if_fail (size_label->job == THUNAR_DEEP_COUNT_JOB (job));
+  _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
+  _thunar_return_if_fail (G_IS_TASK (result));
+  _thunar_return_if_fail (THUNAR_DEEP_COUNT_JOB (job));
+
+  /* check if this is still our active job */
+  if (size_label->job == THUNAR_DEEP_COUNT_JOB (job))
+    {
+      g_task_propagate_pointer (G_TASK (result), &error);
+      if (error != NULL)
+        {
+          /* setup the error text as label */
+          gtk_label_set_text (GTK_LABEL (size_label->label), error->message);
+          g_error_free (error);
+        }
+    }
 
-  /* stop and hide the spinner */
-  gtk_spinner_stop (GTK_SPINNER (size_label->spinner));
-  gtk_widget_hide (size_label->spinner);
+  /* stop everything */
+  thunar_size_label_stop_count (size_label);
 
-  /* disconnect from the job */
-  g_signal_handlers_disconnect_matched (size_label->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, size_label);
-  g_object_unref (size_label->job);
-  size_label->job = NULL;
+  /* release the job */
+  g_object_unref (G_OBJECT (job));
 }
 
 
@@ -377,7 +382,7 @@ thunar_size_label_status_update (ThunarDeepCountJob *job,
       size_string = g_format_size (total_size);
       text = g_strdup_printf (ngettext ("%u item, totalling %s", "%u items, totalling %s", n), n, size_string);
       g_free (size_string);
-      
+
       if (unreadable_directory_count > 0)
         {
           /* TRANSLATORS: this is shows if during the deep count size
@@ -386,7 +391,7 @@ thunar_size_label_status_update (ThunarDeepCountJob *job,
           g_free (text);
           text = unreable_text;
         }
-      
+
       gtk_label_set_text (GTK_LABEL (size_label->label), text);
       g_free (text);
     }


More information about the Xfce4-commits mailing list