[Xfce4-commits] r29904 - in thunar/branches/migration-to-gio: . thunar

Jannis Pohlmann jannis at xfce.org
Fri Apr 24 20:48:54 CEST 2009


Author: jannis
Date: 2009-04-24 18:48:54 +0000 (Fri, 24 Apr 2009)
New Revision: 29904

Modified:
   thunar/branches/migration-to-gio/ChangeLog
   thunar/branches/migration-to-gio/thunar/thunar-file.c
   thunar/branches/migration-to-gio/thunar/thunar-folder.c
   thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c
   thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h
   thunar/branches/migration-to-gio/thunar/thunar-job.c
   thunar/branches/migration-to-gio/thunar/thunar-job.h
Log:
	* thunar/thunar-file.c: Implement thunar_file_get_group(),
	  thunar_file_get_user() and thunar_file_get_emblem_names() based on
	  GFile/GFileInfo.
	* thunar/thunar-folder.c, thunar/thunar-io-jobs.{c,h},
	  thunar/thunar-job.{c,h}: Add new "files-ready" signal to ThunarJob
	  which is emitted when a list of ThunarFiles is ready. Also add a new
	  function called thunar_job_files_ready() which emits the signal.
	  Implement a new job thunar_io_jobs_list_directory() as an equivalent
	  to thunar_vfs_listdir(), using the new "files-ready" signal. Update
	  ThunarJob to use "files-ready" instead of "infos-ready". For the
	  first time in a while you can open the trash again without crashing
	  Thunar.

Modified: thunar/branches/migration-to-gio/ChangeLog
===================================================================
--- thunar/branches/migration-to-gio/ChangeLog	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/ChangeLog	2009-04-24 18:48:54 UTC (rev 29904)
@@ -1,5 +1,20 @@
 2009-04-24	Jannis Pohlmann <jannis at xfce.org>
 
+	* thunar/thunar-file.c: Implement thunar_file_get_group(),
+	  thunar_file_get_user() and thunar_file_get_emblem_names() based on
+	  GFile/GFileInfo.
+	* thunar/thunar-folder.c, thunar/thunar-io-jobs.{c,h},
+	  thunar/thunar-job.{c,h}: Add new "files-ready" signal to ThunarJob
+	  which is emitted when a list of ThunarFiles is ready. Also add a new
+	  function called thunar_job_files_ready() which emits the signal.
+	  Implement a new job thunar_io_jobs_list_directory() as an equivalent
+	  to thunar_vfs_listdir(), using the new "files-ready" signal. Update
+	  ThunarJob to use "files-ready" instead of "infos-ready". For the
+	  first time in a while you can open the trash again without crashing
+	  Thunar.
+
+2009-04-24	Jannis Pohlmann <jannis at xfce.org>
+
 	* thunar/thunar-folder.c: Add "corresponding-file" property for the
 	  ThunarFile member of ThunarFolder. Monitor folders using
 	  GFileMonitor instead of ThunarVfsMonitor.

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-04-24 18:48:54 UTC (rev 29904)
@@ -123,10 +123,10 @@
 
 
 static ThunarUserManager *user_manager;
-static guint32            effective_user_id;
 static ThunarMetafile    *metafile;
 static GObjectClass      *thunar_file_parent_class;
-static GHashTable        *file_cache;
+static GHashTable        *file_cache; /* TODO Make the cache thread safe! */
+static guint32            effective_user_id;
 static GQuark             thunar_file_thumb_path_quark;
 static GQuark             thunar_file_watch_count_quark;
 static GQuark             thunar_file_emblem_names_quark;
@@ -1427,8 +1427,15 @@
 ThunarGroup*
 thunar_file_get_group (const ThunarFile *file)
 {
+  guint32 gid;
+
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  return thunar_user_manager_get_group_by_id (user_manager, file->info->gid);
+
+  /* TODO what are we going to do on non-UNIX systems? */
+  gid = g_file_info_get_attribute_uint32 (file->ginfo,
+                                          G_FILE_ATTRIBUTE_UNIX_GID);
+
+  return thunar_user_manager_get_group_by_id (user_manager, gid);
 }
 
 
@@ -1449,8 +1456,14 @@
 ThunarUser*
 thunar_file_get_user (const ThunarFile *file)
 {
+  guint32 uid;
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  return thunar_user_manager_get_user_by_id (user_manager, file->info->uid);
+
+  /* TODO what are we going to do on non-UNIX systems? */
+  uid = g_file_info_get_attribute_uint32 (file->ginfo,
+                                          G_FILE_ATTRIBUTE_UNIX_UID);
+
+  return thunar_user_manager_get_user_by_id (user_manager, uid);
 }
 
 
@@ -2036,10 +2049,10 @@
 GList*
 thunar_file_get_emblem_names (ThunarFile *file)
 {
-  const ThunarVfsInfo *info = file->info;
-  const gchar         *emblem_string;
-  gchar              **emblem_names;
-  GList               *emblems = NULL;
+  const gchar *emblem_string;
+  guint32      uid;
+  gchar      **emblem_names;
+  GList       *emblems = NULL;
 
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
 
@@ -2064,9 +2077,13 @@
         emblems = g_list_append (emblems, *emblem_names);
     }
 
-  if ((info->flags & THUNAR_VFS_FILE_FLAGS_SYMLINK) != 0)
+  if (g_file_info_get_is_symlink (file->ginfo))
     emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_SYMBOLIC_LINK);
 
+  /* determine the user ID of the file owner */
+  /* TODO what are we going to do here on non-UNIX systems? */
+  uid = g_file_info_get_attribute_uint32 (file->ginfo, G_FILE_ATTRIBUTE_UNIX_UID);
+
   /* we add "cant-read" if either (a) the file is not readable or (b) a directory, that lacks the
    * x-bit, see http://bugzilla.xfce.org/show_bug.cgi?id=1408 for the details about this change.
    */
@@ -2078,7 +2095,7 @@
     {
       emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_CANT_READ);
     }
-  else if (G_UNLIKELY (file->info->uid == effective_user_id && !thunar_file_is_writable (file)))
+  else if (G_UNLIKELY (uid == effective_user_id && !thunar_file_is_writable (file)))
     {
       /* we own the file, but we cannot write to it, that's why we mark it as "cant-write", so
        * users won't be surprised when opening the file in a text editor, but are unable to save.
@@ -2564,8 +2581,8 @@
 #endif
 
   /* we compare only the display names (UTF-8!) */
-  ap = file_a->info->display_name;
-  bp = file_b->info->display_name;
+  ap = thunar_file_get_display_name (file_a);
+  bp = thunar_file_get_display_name (file_b);
 
   /* check if we should ignore case */
   if (G_LIKELY (case_sensitive))
@@ -2635,7 +2652,8 @@
       /* a second case is '20 file' and '2file', where comparison by number
        * makes sense, if the previous char for both strings is a digit.
        */
-      if (ap > file_a->info->display_name && bp > file_b->info->display_name
+      if (ap > thunar_file_get_display_name (file_a) 
+          && bp > thunar_file_get_display_name (file_b)
           && g_ascii_isdigit (*(ap - 1)) && g_ascii_isdigit (*(bp - 1)))
         {
           return compare_by_name_using_number (ap - 1, bp - 1);

Modified: thunar/branches/migration-to-gio/thunar/thunar-folder.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-folder.c	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/thunar/thunar-folder.c	2009-04-24 18:48:54 UTC (rev 29904)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * 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
@@ -24,6 +25,8 @@
 #include <thunar/thunar-file-monitor.h>
 #include <thunar/thunar-folder.h>
 #include <thunar/thunar-gobject-extensions.h>
+#include <thunar/thunar-io-jobs.h>
+#include <thunar/thunar-job.h>
 #include <thunar/thunar-private.h>
 
 
@@ -58,13 +61,13 @@
                                                            guint                   prop_uid,
                                                            const GValue           *value,
                                                            GParamSpec             *pspec);
-static void     thunar_folder_error                       (ThunarVfsJob           *job,
+static void     thunar_folder_error                       (ThunarJob              *job,
                                                            GError                 *error,
                                                            ThunarFolder           *folder);
-static gboolean thunar_folder_infos_ready                 (ThunarVfsJob           *job,
-                                                           GList                  *infos,
+static gboolean thunar_folder_files_ready                 (ThunarJob              *job,
+                                                           GList                  *files,
                                                            ThunarFolder           *folder);
-static void     thunar_folder_finished                    (ThunarVfsJob           *job,
+static void     thunar_folder_finished                    (ThunarJob              *job,
                                                            ThunarFolder           *folder);
 static void     thunar_folder_file_changed                (ThunarFileMonitor      *file_monitor,
                                                            ThunarFile             *file,
@@ -97,15 +100,15 @@
 {
   GtkObject __parent__;
 
-  ThunarVfsJob           *job;
+  ThunarJob         *job;
 
-  ThunarFile             *corresponding_file;
-  GList                  *new_files;
-  GList                  *files;
+  ThunarFile        *corresponding_file;
+  GList             *new_files;
+  GList             *files;
 
-  ThunarFileMonitor      *file_monitor;
+  ThunarFileMonitor *file_monitor;
 
-  GFileMonitor           *monitor;
+  GFileMonitor      *monitor;
 };
 
 
@@ -272,7 +275,7 @@
   if (G_UNLIKELY (folder->job != NULL))
     {
       g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-      thunar_vfs_job_cancel (folder->job);
+      thunar_job_cancel (folder->job);
       g_object_unref (G_OBJECT (folder->job));
     }
 
@@ -348,12 +351,12 @@
 
 
 static void
-thunar_folder_error (ThunarVfsJob *job,
+thunar_folder_error (ThunarJob    *job,
                      GError       *error,
                      ThunarFolder *folder)
 {
   _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
-  _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job));
+  _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (folder->job == job);
 
   /* tell the consumer about the problem */
@@ -363,42 +366,26 @@
 
 
 static gboolean
-thunar_folder_infos_ready (ThunarVfsJob *job,
-                           GList        *infos,
+thunar_folder_files_ready (ThunarJob    *job,
+                           GList        *files,
                            ThunarFolder *folder)
 {
-  ThunarFile *file;
-  GList      *lp;
-
   _thunar_return_val_if_fail (THUNAR_IS_FOLDER (folder), FALSE);
-  _thunar_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE);
+  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (folder->monitor == NULL, FALSE);
   _thunar_return_val_if_fail (folder->job == job, FALSE);
 
-  /* turn the info list into a file list */
-  for (lp = infos; lp != NULL; lp = lp->next)
-    {
-      /* get the file corresponding to the info... */
-      file = thunar_file_get_for_info (lp->data);
-
-      /* ...release the info at the list position... */
-      thunar_vfs_info_unref (lp->data);
-
-      /* ...and replace it with the file */
-      lp->data = file;
-    }
-
   /* merge the list with the existing list of new files */
-  folder->new_files = g_list_concat (folder->new_files, infos);
+  folder->new_files = g_list_concat (folder->new_files, files);
 
-  /* TRUE to indicate that we took over ownership of the infos list */
+  /* indicate that we took over ownership of the file list */
   return TRUE;
 }
 
 
 
 static void
-thunar_folder_finished (ThunarVfsJob *job,
+thunar_folder_finished (ThunarJob    *job,
                         ThunarFolder *folder)
 {
   ThunarFile *file;
@@ -406,7 +393,7 @@
   GList      *lp;
 
   _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
-  _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job));
+  _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (THUNAR_IS_FILE (folder->corresponding_file));
   _thunar_return_if_fail (folder->monitor == NULL);
   _thunar_return_if_fail (folder->job == job);
@@ -742,7 +729,7 @@
     {
       /* disconnect from the job */
       g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-      thunar_vfs_job_cancel (THUNAR_VFS_JOB (folder->job));
+      thunar_job_cancel (THUNAR_JOB (folder->job));
       g_object_unref (G_OBJECT (folder->job));
     }
 
@@ -759,10 +746,10 @@
   folder->new_files = NULL;
 
   /* start a new job */
-  folder->job = thunar_vfs_listdir (thunar_file_get_path (folder->corresponding_file), NULL);
+  folder->job = thunar_io_jobs_list_directory (thunar_file_get_file (folder->corresponding_file));
   g_signal_connect (folder->job, "error", G_CALLBACK (thunar_folder_error), folder);
   g_signal_connect (folder->job, "finished", G_CALLBACK (thunar_folder_finished), folder);
-  g_signal_connect (folder->job, "infos-ready", G_CALLBACK (thunar_folder_infos_ready), folder);
+  g_signal_connect (folder->job, "files-ready", G_CALLBACK (thunar_folder_files_ready), folder);
 
   /* tell all consumers that we're loading */
   g_object_notify (G_OBJECT (folder), "loading");

Modified: thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c	2009-04-24 18:48:54 UTC (rev 29904)
@@ -980,3 +980,86 @@
   g_object_unref (file_list.data);
 }
 
+
+
+static gboolean
+_thunar_io_jobs_ls (ThunarJob   *job,
+                    GValueArray *param_values,
+                    GError     **error)
+{
+  ThunarFile *file;
+  GError     *err = NULL;
+  GFile      *directory;
+  GList      *file_list = NULL;
+  GList      *lp;
+  GList      *path_list;
+
+  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
+  _thunar_return_val_if_fail (param_values != NULL, FALSE);
+  _thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* determine the directory to list */
+  directory = g_value_get_object (g_value_array_get_nth (param_values, 0));
+
+  /* make sure the object is valid */
+  _thunar_assert (G_IS_FILE (directory));
+
+  /* collect directory contents (non-recursively) */
+  path_list = thunar_io_scan_directory (job, directory, 
+                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, 
+                                        FALSE, &err);
+
+  /* turn the GFile list into a ThunarFile list */
+  for (lp = g_list_last (path_list); 
+       err == NULL && !thunar_job_is_cancelled (job) && lp != NULL; 
+       lp = lp->prev)
+    {
+      file = thunar_file_get (lp->data, &err);
+      if (G_LIKELY (file != NULL))
+        file_list = g_list_prepend (file_list, file);
+    }
+
+  /* free the GFile list */
+  g_file_list_free (path_list);
+
+  /* abort on errors or cancellation */
+  thunar_job_set_error_if_cancelled (job, &err);
+  if (G_UNLIKELY (err != NULL))
+    {
+      g_propagate_error (error, err);
+      return FALSE;
+    }
+
+  /* check if we have any files to report */
+  if (G_LIKELY (file_list != NULL))
+    {
+      /* emit the "files-ready" signal */
+      if (!thunar_job_files_ready (job, file_list))
+        {
+          /* none of the handlers took over the file list, so it's up to us
+           * to destroy it */
+          g_list_foreach (file_list, (GFunc) g_object_unref, NULL);
+          g_list_free (file_list);
+        }
+    }
+  
+  /* check if there were any errors */
+  if (err != NULL)
+    {
+      g_propagate_error (error, err);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+ThunarJob *
+thunar_io_jobs_list_directory (GFile *directory)
+{
+  _thunar_return_val_if_fail (G_IS_FILE (directory), NULL);
+  
+  return thunar_simple_job_launch (_thunar_io_jobs_ls, 1, G_TYPE_FILE, directory);
+}

Modified: thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h	2009-04-24 18:48:54 UTC (rev 29904)
@@ -47,6 +47,7 @@
                                             ThunarFileMode file_mask,
                                             ThunarFileMode file_mode,
                                             gboolean       recursive) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+ThunarJob *thunar_io_jobs_list_directory   (GFile         *directory) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-job.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-job.c	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/thunar/thunar-job.c	2009-04-24 18:48:54 UTC (rev 29904)
@@ -48,7 +48,7 @@
   ERROR,
   FINISHED,
   INFO_MESSAGE,
-  INFOS_READY,
+  FILES_READY,
   NEW_FILES,
   PERCENT,
   LAST_SIGNAL,
@@ -218,6 +218,41 @@
                   G_TYPE_NONE, 1, G_TYPE_POINTER);
 
   /**
+   * ThunarJob::files-ready:
+   * @job       : a #ThunarJob.
+   * @file_list : a list of #ThunarFile<!---->s.
+   *
+   * This signal is used by #ThunarJob<!---->s returned by
+   * the thunar_io_jobs_list_directory() function whenever 
+   * there's a bunch of #ThunarFile<!---->s ready. This signal 
+   * is garantied to be never emitted with an @file_list 
+   * parameter of %NULL.
+   *
+   * To allow some further optimizations on the handler-side,
+   * the handler is allowed to take over ownership of the
+   * @file_list, i.e. it can reuse the @infos list and just replace
+   * the data elements with it's own objects based on the
+   * #ThunarFile<!---->s contained within the @file_list (and
+   * of course properly unreffing the previously contained infos).
+   * If a handler takes over ownership of @file_list it must return
+   * %TRUE here, and no further handlers will be run. Else, if
+   * the handler doesn't want to take over ownership of @infos,
+   * it must return %FALSE, and other handlers will be run. Use
+   * this feature with care, and only if you can be sure that
+   * you are the only handler connected to this signal for a
+   * given job!
+   *
+   * Return value: %TRUE if the handler took over ownership of
+   *               @file_list, else %FALSE.
+   **/
+  job_signals[FILES_READY] =
+    g_signal_new (I_("files-ready"),
+                  G_TYPE_FROM_CLASS (klass), G_SIGNAL_NO_HOOKS,
+                  0, g_signal_accumulator_true_handled, NULL,
+                  _thunar_marshal_BOOLEAN__POINTER,
+                  G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
+
+  /**
    * ThunarJob::finished:
    * @job : a #ThunarJob.
    *
@@ -838,6 +873,19 @@
 
 
 
+gboolean
+thunar_job_files_ready (ThunarJob *job,
+                        GList     *file_list)
+{
+  gboolean handled = FALSE;
+
+  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
+  thunar_job_emit (job, job_signals[FILES_READY], 0, file_list, &handled);
+  return handled;
+}
+
+
+
 void
 thunar_job_info_message (ThunarJob   *job,
                          const gchar *message)

Modified: thunar/branches/migration-to-gio/thunar/thunar-job.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-job.h	2009-04-24 16:36:08 UTC (rev 29903)
+++ thunar/branches/migration-to-gio/thunar/thunar-job.h	2009-04-24 18:48:54 UTC (rev 29904)
@@ -98,6 +98,8 @@
 ThunarJobResponse thunar_job_ask_skip               (ThunarJob       *job,
                                                      const gchar     *format,
                                                      ...);
+gboolean          thunar_job_files_ready            (ThunarJob       *job,
+                                                     GList           *file_list);
 void              thunar_job_info_message           (ThunarJob       *job,
                                                      const gchar     *message);
 void              thunar_job_new_files              (ThunarJob       *job,




More information about the Xfce4-commits mailing list