[Xfce4-commits] <thunar:master> Make the deep count job handle multiple files.

Nick Schermer noreply at xfce.org
Sun Sep 16 20:16:09 CEST 2012


Updating branch refs/heads/master
         to 785499544063df50003f0ea6b4f001e00fc96d44 (commit)
       from fac3514fb550c404fc275dc59330ff9afc490cb1 (commit)

commit 785499544063df50003f0ea6b4f001e00fc96d44
Author: Nick Schermer <nick at xfce.org>
Date:   Thu Sep 13 21:53:16 2012 +0200

    Make the deep count job handle multiple files.
    
    Not the size label...

 thunar/thunar-deep-count-job.c |   85 ++++++-----
 thunar/thunar-deep-count-job.h |    2 +-
 thunar/thunar-size-label.c     |  321 +++++++++++++++++-----------------------
 thunar/thunar-size-label.h     |    1 +
 4 files changed, 185 insertions(+), 224 deletions(-)

diff --git a/thunar/thunar-deep-count-job.c b/thunar/thunar-deep-count-job.c
index d2c9dfb..bd7f15c 100644
--- a/thunar/thunar-deep-count-job.c
+++ b/thunar/thunar-deep-count-job.c
@@ -2,19 +2,19 @@
 /*-
  * Copyright (c) 2009 Jannis Pohlmann <jannis 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 
- * the Free Software Foundation; either version 2 of the License, or (at 
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or (at
  * your option) any later version.
  *
- * This program is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA  02111-1307  USA
  */
 
@@ -65,7 +65,7 @@ struct _ThunarDeepCountJob
 {
   ThunarJob __parent__;
 
-  GFile              *file;
+  GList              *files;
   GFileQueryInfoFlags query_flags;
 
   /* the time of the last "status-update" emission */
@@ -95,7 +95,7 @@ thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass)
   GObjectClass *gobject_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->finalize = thunar_deep_count_job_finalize; 
+  gobject_class->finalize = thunar_deep_count_job_finalize;
 
   job_class = EXO_JOB_CLASS (klass);
   job_class->execute = thunar_deep_count_job_execute;
@@ -108,7 +108,7 @@ thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass)
    * @directory_count            : the number of directories.
    * @unreadable_directory_count : the number of unreadable directories.
    *
-   * Emitted by the @job to inform listeners about the number of files, 
+   * Emitted by the @job to inform listeners about the number of files,
    * directories and bytes counted so far.
    **/
   deep_count_signals[STATUS_UPDATE] =
@@ -130,7 +130,7 @@ thunar_deep_count_job_class_init (ThunarDeepCountJobClass *klass)
 static void
 thunar_deep_count_job_init (ThunarDeepCountJob *job)
 {
-  job->file = NULL;
+  job->files = NULL;
   job->query_flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS;
   job->total_size = 0;
   job->file_count = 0;
@@ -146,8 +146,7 @@ thunar_deep_count_job_finalize (GObject *object)
 {
   ThunarDeepCountJob *job = THUNAR_DEEP_COUNT_JOB (object);
 
-  if (G_LIKELY (job->file != NULL))
-    g_object_unref (job->file);
+  g_list_free_full (job->files, g_object_unref);
 
   (*G_OBJECT_CLASS (thunar_deep_count_job_parent_class)->finalize) (object);
 }
@@ -159,7 +158,7 @@ thunar_deep_count_job_status_update (ThunarDeepCountJob *job)
 {
   _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
 
-  exo_job_emit (EXO_JOB (job), 
+  exo_job_emit (EXO_JOB (job),
                 deep_count_signals[STATUS_UPDATE],
                 0,
                 job->total_size,
@@ -171,9 +170,10 @@ thunar_deep_count_job_status_update (ThunarDeepCountJob *job)
 
 
 static gboolean
-thunar_deep_count_job_process (ExoJob  *job,
-                               GFile   *file,
-                               GError **error)
+thunar_deep_count_job_process (ExoJob    *job,
+                               GFile     *file,
+                               gboolean   toplevel_file,
+                               GError   **error)
 {
   ThunarDeepCountJob *count_job = THUNAR_DEEP_COUNT_JOB (job);
   GFileEnumerator    *enumerator;
@@ -192,7 +192,7 @@ thunar_deep_count_job_process (ExoJob  *job,
     return FALSE;
 
   /* query size and type of the current file */
-  info = g_file_query_info (file, 
+  info = g_file_query_info (file,
                             G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                             G_FILE_ATTRIBUTE_STANDARD_SIZE,
                             count_job->query_flags,
@@ -225,7 +225,7 @@ thunar_deep_count_job_process (ExoJob  *job,
               /* directory was unreadable */
               count_job->unreadable_directory_count += 1;
 
-              if (file == count_job->file)
+              if (toplevel_file)
                 {
                   /* we only bail out if the job file is unreadable */
                   success = FALSE;
@@ -258,7 +258,7 @@ thunar_deep_count_job_process (ExoJob  *job,
 
                   /* recurse unless the job was cancelled before */
                   if (!exo_job_is_cancelled (job))
-                    thunar_deep_count_job_process (job, child, error);
+                    thunar_deep_count_job_process (job, child, FALSE, error);
 
                   /* free resources */
                   g_object_unref (child);
@@ -288,10 +288,6 @@ thunar_deep_count_job_process (ExoJob  *job,
   /* destroy the file info */
   g_object_unref (info);
 
-  /* emit final status update at the very end of the computation */
-  if (file == count_job->file)
-    thunar_deep_count_job_status_update (count_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;
@@ -305,6 +301,8 @@ thunar_deep_count_job_execute (ExoJob  *job,
 {
   gboolean success;
   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);
@@ -313,16 +311,20 @@ thunar_deep_count_job_execute (ExoJob  *job,
   if (exo_job_set_error_if_cancelled (job, error))
     return FALSE;
 
-  /* count files, directories and compute size of the job file */
-  success = thunar_deep_count_job_process (job, 
-                                           THUNAR_DEEP_COUNT_JOB (job)->file, 
-                                           &err);
+  /* count files, directories and compute size of the job files */
+  for (lp = THUNAR_DEEP_COUNT_JOB (job)->files; lp != NULL; lp = lp->next)
+    {
+      gfile = thunar_file_get_file (THUNAR_FILE (lp->data));
+      success = thunar_deep_count_job_process (job, gfile, TRUE, &err);
+      if (G_UNLIKELY (!success))
+        break;
+    }
 
   if (!success)
     {
       g_assert (err != NULL || exo_job_is_cancelled (job));
 
-      /* set error if the job was cancelled. otherwise just propagate 
+      /* 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))
         {
@@ -334,26 +336,31 @@ thunar_deep_count_job_execute (ExoJob  *job,
           if (err != NULL)
             g_propagate_error (error, err);
         }
-      
-      return FALSE;
     }
-  else
-    return TRUE;
+  else if (!exo_job_is_cancelled (job))
+    {
+      /* emit final status update at the very end of the computation */
+      thunar_deep_count_job_status_update (THUNAR_DEEP_COUNT_JOB (job));
+    }
+
+  return success;
 }
 
 
 
 ThunarDeepCountJob *
-thunar_deep_count_job_new (GFile              *file,
-                           GFileQueryInfoFlags flags)
+thunar_deep_count_job_new (GList               *files,
+                           GFileQueryInfoFlags  flags)
 {
   ThunarDeepCountJob *job;
 
-  _thunar_return_val_if_fail (G_IS_FILE (file), NULL);
+  _thunar_return_val_if_fail (files != NULL, NULL);
 
   job = g_object_new (THUNAR_TYPE_DEEP_COUNT_JOB, NULL);
-  job->file = g_object_ref (file);
+  job->files = g_list_copy (files);
   job->query_flags = flags;
 
+  g_list_foreach (job->files, (GFunc) g_object_ref, NULL);
+
   return job;
 }
diff --git a/thunar/thunar-deep-count-job.h b/thunar/thunar-deep-count-job.h
index 4dcefe0..735a121 100644
--- a/thunar/thunar-deep-count-job.h
+++ b/thunar/thunar-deep-count-job.h
@@ -40,7 +40,7 @@ typedef struct _ThunarDeepCountJob        ThunarDeepCountJob;
 
 GType               thunar_deep_count_job_get_type (void) G_GNUC_CONST;
 
-ThunarDeepCountJob *thunar_deep_count_job_new      (GFile              *file,
+ThunarDeepCountJob *thunar_deep_count_job_new      (GList              *files,
                                                     GFileQueryInfoFlags flags) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS;
diff --git a/thunar/thunar-size-label.c b/thunar/thunar-size-label.c
index 27b0396..1e27e05 100644
--- a/thunar/thunar-size-label.c
+++ b/thunar/thunar-size-label.c
@@ -47,10 +47,6 @@ enum
 
 
 
-typedef struct _ThunarSizeLabelFile ThunarSizeLabelFile;
-
-
-
 static void     thunar_size_label_finalize              (GObject              *object);
 static void     thunar_size_label_get_property          (GObject              *object,
                                                          guint                 prop_id,
@@ -63,19 +59,18 @@ static void     thunar_size_label_set_property          (GObject              *o
 static gboolean thunar_size_label_button_press_event    (GtkWidget            *ebox,
                                                          GdkEventButton       *event,
                                                          ThunarSizeLabel      *size_label);
-static void     thunar_size_label_file_changed          (ThunarFile           *changed_file,
-                                                         ThunarSizeLabelFile  *file);
+static void     thunar_size_label_files_changed         (ThunarSizeLabel      *size_label);
 static void     thunar_size_label_error                 (ExoJob               *job,
                                                          const GError         *error,
-                                                         ThunarSizeLabelFile  *file);
+                                                         ThunarSizeLabel      *size_label);
 static void     thunar_size_label_finished              (ExoJob               *job,
-                                                         ThunarSizeLabelFile  *file);
+                                                         ThunarSizeLabel      *size_label);
 static void     thunar_size_label_status_update         (ThunarDeepCountJob   *job,
                                                          guint64               total_size,
                                                          guint                 file_count,
                                                          guint                 directory_count,
                                                          guint                 unreadable_directory_count,
-                                                         ThunarSizeLabelFile  *file);
+                                                         ThunarSizeLabel      *size_label);
 static gboolean thunar_size_label_animate_timer         (gpointer              user_data);
 static void     thunar_size_label_animate_timer_destroy (gpointer              user_data);
 
@@ -90,6 +85,8 @@ struct _ThunarSizeLabel
 {
   GtkHBox             __parent__;
 
+  ThunarDeepCountJob *job;
+
   GList              *files;
 
   GtkWidget          *label;
@@ -99,20 +96,6 @@ struct _ThunarSizeLabel
   guint               animate_timer_id;
 };
 
-struct _ThunarSizeLabelFile
-{
-  ThunarSizeLabel    *size_label;
-
-  ThunarFile         *file;
-  ThunarDeepCountJob *job;
-
-  /* results of the deep-count job */
-  guint64             total_size;
-  guint               file_count;
-  guint               directory_count;
-  guint               unreadable_directory_count;
-};
-
 
 
 G_DEFINE_TYPE (ThunarSizeLabel, thunar_size_label, GTK_TYPE_HBOX)
@@ -202,7 +185,18 @@ thunar_size_label_get_property (GObject    *object,
                                 GValue     *value,
                                 GParamSpec *pspec)
 {
-  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+  ThunarSizeLabel *size_label = THUNAR_SIZE_LABEL (object);
+
+  switch (prop_id)
+    {
+    case PROP_FILES:
+      g_value_set_boxed (value, thunar_size_label_get_files (size_label));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 
@@ -234,9 +228,6 @@ thunar_size_label_button_press_event (GtkWidget       *ebox,
                                       GdkEventButton  *event,
                                       ThunarSizeLabel *size_label)
 {
-  GList               *lp;
-  ThunarSizeLabelFile *file;
-
   _thunar_return_val_if_fail (GTK_IS_EVENT_BOX (ebox), FALSE);
   _thunar_return_val_if_fail (THUNAR_IS_SIZE_LABEL (size_label), FALSE);
 
@@ -247,17 +238,13 @@ thunar_size_label_button_press_event (GtkWidget       *ebox,
       if (G_UNLIKELY (size_label->animate_timer_id != 0))
         g_source_remove (size_label->animate_timer_id);
 
-      /* cancel all pending jobs (if any) */
-      for (lp = size_label->files; lp != NULL; lp = lp->next)
+      /* cancel the pending job (if any) */
+      if (G_UNLIKELY (size_label->job != NULL))
         {
-          file = lp->data;
-          if (G_UNLIKELY (file->job != NULL))
-            {
-              g_signal_handlers_disconnect_matched (file->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, file);
-              exo_job_cancel (EXO_JOB (file->job));
-              g_object_unref (file->job);
-              file->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 throbber */
@@ -277,175 +264,114 @@ thunar_size_label_button_press_event (GtkWidget       *ebox,
 
 
 static void
-thunar_size_label_update (ThunarSizeLabel *size_label)
+thunar_size_label_files_changed (ThunarSizeLabel *size_label)
 {
-  GList               *lp;
-  ThunarSizeLabelFile *file;
-  guint64              total_size = 0;
-  guint                file_count = 0;
-  guint                directory_count = 0;
-  guint                unreadable_directory_count = 0;
-  gchar               *size_string;
-  gchar               *text;
-  guint                n;
-  gchar               *unreable_text;
+  gchar   *size_string;
+  guint64  size;
 
   _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
+  _thunar_return_if_fail (size_label->files != NULL);
+  _thunar_return_if_fail (THUNAR_IS_FILE (size_label->files->data));
 
-  for (lp = size_label->files; lp != NULL; lp = lp->next)
-    {
-      file = lp->data;
-
-      total_size += file->total_size;
-      file_count += file->file_count;
-      directory_count += file->directory_count;
-      unreadable_directory_count += file->unreadable_directory_count;
-    }
-
-  /* check if this is a single file or a directory/multiple files */
-  if (file_count == 1 && directory_count == 0)
-    {
-      size_string = g_format_size_full (total_size, G_FORMAT_SIZE_LONG_FORMAT);
-      gtk_label_set_text (GTK_LABEL (size_label->label), size_string);
-      g_free (size_string);
-    }
-  else
-    {
-      n = file_count + directory_count + unreadable_directory_count;
-
-      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
-           * directories were not accessible */
-          unreable_text = g_strconcat (text, "\n", _("(some contents unreadable)"), NULL);
-          g_free (text);
-          text = unreable_text;
-        }
-
-      gtk_label_set_text (GTK_LABEL (size_label->label), text);
-      g_free (text);
-    }
-}
-
-
-
-static void
-thunar_size_label_file_changed (ThunarFile          *changed_file,
-                                ThunarSizeLabelFile *file)
-{
-  ThunarSizeLabel *size_label = file->size_label;
-
-  _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
-  _thunar_return_if_fail (THUNAR_IS_FILE (changed_file));
-  _thunar_return_if_fail (file->file == changed_file);
+  /* be sure to cancel the animate timer */
+  if (G_UNLIKELY (size_label->animate_timer_id != 0))
+    g_source_remove (size_label->animate_timer_id);
 
   /* cancel the pending job (if any) */
-  if (G_UNLIKELY (file->job != NULL))
+  if (G_UNLIKELY (size_label->job != NULL))
     {
-      g_signal_handlers_disconnect_matched (file->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, file);
-      exo_job_cancel (EXO_JOB (file->job));
-      g_object_unref (file->job);
-      file->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;
     }
 
-  /* reset the size values */
-  file->total_size = 0;
-  file->file_count = 0;
-  file->directory_count = 0;
-  file->unreadable_directory_count = 0;
+  /* be sure to stop and hide the throbber */
+  thunar_throbber_set_animated (THUNAR_THROBBER (size_label->throbber), FALSE);
+  gtk_widget_hide (size_label->throbber);
 
-  /* check if the file is a directory */
-  if (thunar_file_is_directory (changed_file))
+  /* 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) */
-      file->job = thunar_deep_count_job_new (thunar_file_get_file (changed_file), G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS);
-      g_signal_connect (file->job, "error", G_CALLBACK (thunar_size_label_error), file);
-      g_signal_connect (file->job, "finished", G_CALLBACK (thunar_size_label_finished), file);
-      g_signal_connect (file->job, "status-update", G_CALLBACK (thunar_size_label_status_update), file);
+      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);
+      g_signal_connect (size_label->job, "status-update", G_CALLBACK (thunar_size_label_status_update), size_label);
 
       /* launch the job */
-      exo_job_launch (EXO_JOB (file->job));
+      exo_job_launch (EXO_JOB (size_label->job));
     }
   else
     {
-      /* update the data property */
-      file->total_size = thunar_file_get_size (changed_file);
-      file->file_count = 1;
+      /* determine the size of the file */
+      size = thunar_file_get_size (THUNAR_FILE (size_label->files->data));
 
-      /* update the label */
-      thunar_size_label_update (size_label);
+      /* setup the new label */
+      size_string = g_format_size_full (size, G_FORMAT_SIZE_LONG_FORMAT);
+      gtk_label_set_text (GTK_LABEL (size_label->label), size_string);
+      g_free (size_string);
     }
 }
 
 
 
 static void
-thunar_size_label_error (ExoJob              *job,
-                         const GError        *error,
-                         ThunarSizeLabelFile *file)
+thunar_size_label_error (ExoJob          *job,
+                         const GError    *error,
+                         ThunarSizeLabel *size_label)
 {
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (file->size_label));
-  _thunar_return_if_fail (file->job == THUNAR_DEEP_COUNT_JOB (job));
+  _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
+  _thunar_return_if_fail (size_label->job == THUNAR_DEEP_COUNT_JOB (job));
 
   /* setup the error text as label */
-  gtk_label_set_text (GTK_LABEL (file->size_label->label), error->message);
+  gtk_label_set_text (GTK_LABEL (size_label->label), error->message);
 }
 
 
 
 static void
-thunar_size_label_finished (ExoJob              *job,
-                            ThunarSizeLabelFile *file)
+thunar_size_label_finished (ExoJob          *job,
+                            ThunarSizeLabel *size_label)
 {
-  ThunarSizeLabel *size_label = file->size_label;
-  GList           *lp;
-
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
-  _thunar_return_if_fail (file->job == THUNAR_DEEP_COUNT_JOB (job));
+  _thunar_return_if_fail (size_label->job == THUNAR_DEEP_COUNT_JOB (job));
 
-  /* disconnect from the job */
-  g_signal_handlers_disconnect_matched (file->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, file);
-  g_object_unref (file->job);
-  file->job = NULL;
-
-  /* look if there are jobs pending */
-  for (lp = size_label->files; lp != NULL; lp = lp->next)
-    if (((ThunarSizeLabelFile *) lp->data)->job != NULL)
-      break;
+  /* be sure to cancel the animate timer */
+  if (G_UNLIKELY (size_label->animate_timer_id != 0))
+    g_source_remove (size_label->animate_timer_id);
 
-  if (lp == NULL)
-    {
-      /* be sure to cancel the animate timer */
-      if (G_UNLIKELY (size_label->animate_timer_id != 0))
-        g_source_remove (size_label->animate_timer_id);
+  /* stop and hide the throbber */
+  thunar_throbber_set_animated (THUNAR_THROBBER (size_label->throbber), FALSE);
+  gtk_widget_hide (size_label->throbber);
 
-      /* stop and hide the throbber */
-      thunar_throbber_set_animated (THUNAR_THROBBER (size_label->throbber), FALSE);
-      gtk_widget_hide (size_label->throbber);
-    }
+  /* 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;
 }
 
 
 
 static void
-thunar_size_label_status_update (ThunarDeepCountJob  *job,
-                                 guint64              total_size,
-                                 guint                file_count,
-                                 guint                directory_count,
-                                 guint                unreadable_directory_count,
-                                 ThunarSizeLabelFile *file)
+thunar_size_label_status_update (ThunarDeepCountJob *job,
+                                 guint64             total_size,
+                                 guint               file_count,
+                                 guint               directory_count,
+                                 guint               unreadable_directory_count,
+                                 ThunarSizeLabel    *size_label)
 {
-  ThunarSizeLabel *size_label = file->size_label;
+  gchar *size_string;
+  gchar *text;
+  guint  n;
+  gchar *unreable_text;
 
   _thunar_return_if_fail (THUNAR_IS_DEEP_COUNT_JOB (job));
   _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
-  _thunar_return_if_fail (file->job == job);
+  _thunar_return_if_fail (size_label->job == job);
 
   /* check if the animate timer is already running */
   if (G_UNLIKELY (size_label->animate_timer_id == 0))
@@ -455,14 +381,25 @@ thunar_size_label_status_update (ThunarDeepCountJob  *job,
                                                          size_label, thunar_size_label_animate_timer_destroy);
     }
 
-  /* update the structure values */
-  file->total_size = total_size;
-  file->file_count = file_count;
-  file->directory_count = directory_count;
-  file->unreadable_directory_count = unreadable_directory_count;
+  /* determine the total number of items */
+  n = file_count + directory_count + unreadable_directory_count;
 
   /* update the label */
-  thunar_size_label_update (size_label);
+  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
+       * directories were not accessible */
+      unreable_text = g_strconcat (text, "\n", _("(some contents unreadable)"), NULL);
+      g_free (text);
+      text = unreable_text;
+    }
+
+  gtk_label_set_text (GTK_LABEL (size_label->label), text);
+  g_free (text);
 }
 
 
@@ -509,6 +446,21 @@ thunar_size_label_new (void)
 
 
 /**
+ * thunar_size_label_get_files:
+ * @size_label : a #ThunarSizeLabel.
+ *
+ * Get the files displayed by the @size_label.
+ **/
+GList*
+thunar_size_label_get_files (ThunarSizeLabel *size_label)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SIZE_LABEL (size_label), NULL);
+  return size_label->files;
+}
+
+
+
+/**
  * thunar_size_label_set_files:
  * @size_label : a #ThunarSizeLabel.
  * @files      : a list of #ThunarFile's or %NULL.
@@ -519,43 +471,44 @@ void
 thunar_size_label_set_files (ThunarSizeLabel *size_label,
                              GList           *files)
 {
-  GList               *lp;
-  ThunarSizeLabelFile *file;
+  GList *lp;
 
   _thunar_return_if_fail (THUNAR_IS_SIZE_LABEL (size_label));
   _thunar_return_if_fail (files == NULL || THUNAR_IS_FILE (files->data));
 
+  /* stop a running job */
+  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;
+    }
+
   /* disconnect from the previous files */
   for (lp = size_label->files; lp != NULL; lp = lp->next)
     {
-      file = lp->data;
-      _thunar_assert (THUNAR_IS_FILE (file->file));
-
-      g_signal_handlers_disconnect_by_func (G_OBJECT (file->file), thunar_size_label_file_changed, file);
+      _thunar_assert (THUNAR_IS_FILE (lp->data));
 
-      /* cleanup file data */
-      g_object_unref (G_OBJECT (file->file));
-      g_slice_free (ThunarSizeLabelFile, file);
+      g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_size_label_files_changed, size_label);
+      g_object_unref (G_OBJECT (lp->data));
     }
-
   g_list_free (size_label->files);
-  size_label->files = NULL;
+
+  size_label->files = g_list_copy (files);
 
   /* connect to the new file */
-  for (lp = files; lp != NULL; lp = lp->next)
+  for (lp = size_label->files; lp != NULL; lp = lp->next)
     {
       _thunar_assert (THUNAR_IS_FILE (lp->data));
 
-      file = g_slice_new0 (ThunarSizeLabelFile);
-      file->size_label = size_label;
-      file->file = g_object_ref (G_OBJECT (lp->data));
-
-      size_label->files = g_list_prepend (size_label->files, file);
-
-      thunar_size_label_file_changed (file->file, file);
-      g_signal_connect (G_OBJECT (file->file), "changed", G_CALLBACK (thunar_size_label_file_changed), file);
+      g_object_ref (G_OBJECT (lp->data));
+      g_signal_connect_swapped (G_OBJECT (lp->data), "changed", G_CALLBACK (thunar_size_label_files_changed), size_label);
     }
 
+  if (size_label->files != NULL)
+    thunar_size_label_files_changed (size_label);
+
   /* notify listeners */
   g_object_notify (G_OBJECT (size_label), "files");
 }
diff --git a/thunar/thunar-size-label.h b/thunar/thunar-size-label.h
index 76527e1..8fa4774 100644
--- a/thunar/thunar-size-label.h
+++ b/thunar/thunar-size-label.h
@@ -38,6 +38,7 @@ GType       thunar_size_label_get_type  (void) G_GNUC_CONST;
 
 GtkWidget  *thunar_size_label_new       (void) G_GNUC_MALLOC;
 
+GList      *thunar_size_label_get_files (ThunarSizeLabel *size_label);
 void        thunar_size_label_set_files (ThunarSizeLabel *size_label,
                                          GList           *files);
 


More information about the Xfce4-commits mailing list