Author: jannis Date: 2009-04-22 00:49:04 +0000 (Wed, 22 Apr 2009) New Revision: 29883
Added: thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.c thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.h Modified: thunar/branches/migration-to-gio/ChangeLog thunar/branches/migration-to-gio/thunar/Makefile.am thunar/branches/migration-to-gio/thunar/thunar-application.c thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h 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-simple-job.c Log: * thunar/Makefile.am, thunar/thunar-io-scan-directory.{c,h}: Port _thunar_vfs_info_scan_directory() to GIO and rename it to thunar_io_scan_directory(). * thunar/thunar-application.c, thunar/thunar-io-jobs.{c,h}: Implement thunar_io_jobs_unlink_files() as an equivalent to thunar_vfs_jobs_unlink_files(). Use it in unlink_stub() and modify thunar_application_unlink_files() and hunar_application_empty_trash() to use thunar_application_job_launch() and GFile lists. * thunar/thunar-gio-extensions.{c,h}: Add g_file_list_prepend(). * thunar/thunar-job.c: Don't treat cancellation as an error for now. * thunar/thunar-simple-job.c: Use g_clear_error() instead of g_error_free() in thunar_simple_job_execute(). Modified: thunar/branches/migration-to-gio/ChangeLog =================================================================== --- thunar/branches/migration-to-gio/ChangeLog 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/ChangeLog 2009-04-22 00:49:04 UTC (rev 29883) @@ -1,3 +1,19 @@ +2009-04-22 Jannis Pohlmann <jan...@xfce.org> + + * thunar/Makefile.am, thunar/thunar-io-scan-directory.{c,h}: Port + _thunar_vfs_info_scan_directory() to GIO and rename it to + thunar_io_scan_directory(). + * thunar/thunar-application.c, thunar/thunar-io-jobs.{c,h}: Implement + thunar_io_jobs_unlink_files() as an equivalent to + thunar_vfs_jobs_unlink_files(). Use it in unlink_stub() and modify + thunar_application_unlink_files() and + hunar_application_empty_trash() to use + thunar_application_job_launch() and GFile lists. + * thunar/thunar-gio-extensions.{c,h}: Add g_file_list_prepend(). + * thunar/thunar-job.c: Don't treat cancellation as an error for now. + * thunar/thunar-simple-job.c: Use g_clear_error() instead of + g_error_free() in thunar_simple_job_execute(). + 2009-04-21 Jannis Pohlmann <jan...@xfce.org> * thunar/thunar-application.c, thunar/thunar-io-jobs.{c,h}, Modified: thunar/branches/migration-to-gio/thunar/Makefile.am =================================================================== --- thunar/branches/migration-to-gio/thunar/Makefile.am 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/Makefile.am 2009-04-22 00:49:04 UTC (rev 29883) @@ -98,6 +98,8 @@ thunar-icon-view.h \ thunar-io-jobs.c \ thunar-io-jobs.h \ + thunar-io-scan-directory.c \ + thunar-io-scan-directory.h \ thunar-job.c \ thunar-job.h \ thunar-launcher.c \ Modified: thunar/branches/migration-to-gio/thunar/thunar-application.c =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-application.c 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-application.c 2009-04-22 00:49:04 UTC (rev 29883) @@ -1365,12 +1365,11 @@ -static ThunarVfsJob* -unlink_stub (GList *source_path_list, - GList *target_path_list, - GError **error) +static ThunarJob* +unlink_stub (GList *source_path_list, + GList *target_path_list) { - return thunar_vfs_unlink_files (source_path_list, error); + return thunar_io_jobs_unlink_files (source_path_list); } @@ -1414,11 +1413,7 @@ for (lp = g_list_last (file_list); lp != NULL; lp = lp->prev, ++n_path_list) { /* prepend the path to the path list */ - path_list = thunar_vfs_path_list_prepend (path_list, thunar_file_get_path (lp->data)); - - /* check if the file is not a local file */ - if (!thunar_file_is_local (lp->data)) - permanently = TRUE; + path_list = g_file_list_prepend (path_list, thunar_file_get_file (lp->data)); } /* nothing to do if we don't have any paths */ @@ -1447,8 +1442,7 @@ /* ask the user to confirm the delete operation */ dialog = gtk_message_dialog_new (window, - GTK_DIALOG_MODAL - | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", message); @@ -1459,7 +1453,8 @@ GTK_STOCK_DELETE, GTK_RESPONSE_YES, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("If you delete a file, it is permanently lost.")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("If you delete a file, it is permanently lost.")); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_free (message); @@ -1468,9 +1463,9 @@ if (G_LIKELY (response == GTK_RESPONSE_YES)) { /* launch the "Delete" operation */ - thunar_application_launch (application, parent, "stock_delete", - _("Deleting files..."), unlink_stub, - path_list, path_list, NULL); + thunar_application_launch_job (application, parent, "stock_delete", + _("Deleting files..."), unlink_stub, + path_list, path_list, NULL); } } else @@ -1482,7 +1477,7 @@ } /* release the path list */ - thunar_vfs_path_list_free (path_list); + g_file_list_free (path_list); } @@ -1617,17 +1612,17 @@ /* fake a path list with only the trash root (the root * folder itself will never be unlinked, so this is safe) */ - path_list.data = thunar_vfs_path_get_for_trash (); + path_list.data = g_file_new_for_trash (); path_list.next = NULL; path_list.prev = NULL; /* launch the operation */ - thunar_application_launch (application, parent, "gnome-fs-trash-empty", - _("Emptying the Trash..."), - unlink_stub, &path_list, NULL, NULL); + thunar_application_launch_job (application, parent, "gnome-fs-trash-empty", + _("Emptying the Trash..."), + unlink_stub, &path_list, NULL, NULL); /* cleanup */ - thunar_vfs_path_unref (path_list.data); + g_object_unref (path_list.data); } } Modified: thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c 2009-04-22 00:49:04 UTC (rev 29883) @@ -183,6 +183,15 @@ +GList * +g_file_list_prepend (GList *list, + GFile *file) +{ + return g_list_prepend (list, g_object_ref (file)); +} + + + /** * g_file_list_copy: * @list : a list of #GFile<!---->s. Modified: thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h 2009-04-22 00:49:04 UTC (rev 29883) @@ -37,6 +37,8 @@ gchar *g_file_list_to_string (GList *list); GList *g_file_list_append (GList *list, GFile *file); +GList *g_file_list_prepend (GList *list, + GFile *file); GList *g_file_list_copy (GList *list); void g_file_list_free (GList *list); Modified: thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c 2009-04-22 00:49:04 UTC (rev 29883) @@ -25,16 +25,61 @@ #include <gio/gio.h> #include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-io-scan-directory.h> #include <thunar/thunar-job.h> #include <thunar/thunar-private.h> #include <thunar/thunar-simple-job.h> +static GList * +_tij_collect_nofollow (ThunarJob *job, + GList *base_file_list, + GError **error) +{ + GError *err = NULL; + GList *child_file_list = NULL; + GList *file_list = NULL; + GList *lp; + + /* recursively collect the files */ + for (lp = base_file_list; + err == NULL && lp != NULL && !thunar_job_is_cancelled (job); + lp = lp->next) + { + /* try to scan the directory */ + child_file_list = thunar_io_scan_directory (job, lp->data, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + TRUE, &err); + + /* prepend the new files to the existing list */ + file_list = g_file_list_prepend (file_list, lp->data); + file_list = g_list_concat (child_file_list, file_list); + } + + /* check if we failed */ + if (G_UNLIKELY (err != NULL || thunar_job_is_cancelled (job))) + { + if (thunar_job_set_error_if_cancelled (job, error)) + g_error_free (err); + else + g_propagate_error (error, err); + + /* release the collected files */ + g_file_list_free (file_list); + + return NULL; + } + + return file_list; +} + + + static gboolean _thunar_io_jobs_create (ThunarJob *job, - GValueArray *param_values, - GError **error) + GValueArray *param_values, + GError **error) { GFileOutputStream *stream; ThunarJobResponse response = THUNAR_JOB_RESPONSE_CANCEL; @@ -82,8 +127,7 @@ { if (err->code == G_IO_ERROR_EXISTS) { - g_error_free (err); - err = NULL; + g_clear_error (&err); /* the file already exists, query its display name */ info = g_file_query_info (lp->data, @@ -136,8 +180,7 @@ display_name, err->message); g_free (display_name); - g_error_free (err); - err = NULL; + g_clear_error (&err); /* go back to the beginning if the user wants to retry */ if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_RETRY)) @@ -309,3 +352,119 @@ return thunar_simple_job_launch (_thunar_io_jobs_mkdir, 1, G_TYPE_FILE_LIST, file_list); } + + + +static gboolean +_thunar_io_jobs_unlink (ThunarJob *job, + GValueArray *param_values, + GError **error) +{ + ThunarJobResponse response; + GFileInfo *info; + GError *err = NULL; + GList *file_list; + GList *lp; + gchar *basename; + gchar *display_name; + + _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 > 0, FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* get the file list */ + file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0)); + + /* tell the user that we're preparing to unlink the files */ + thunar_job_info_message (job, _("Preparing...")); + + /* recursively collect files for removal, not following any symlinks */ + file_list = _tij_collect_nofollow (job, file_list, &err); + + /* free the file list and fail if there was an error or the job was cancelled */ + if (err != NULL || thunar_job_is_cancelled (job)) + { + if (thunar_job_set_error_if_cancelled (job, error)) + g_error_free (err); + else + g_propagate_error (error, err); + + g_file_list_free (file_list); + return FALSE; + } + + /* we know the total list of files to process */ + thunar_job_set_total_files (job, file_list); + + /* remove all the files */ + for (lp = file_list; lp != NULL && !thunar_job_is_cancelled (job); lp = lp->next) + { + g_assert (G_IS_FILE (lp->data)); + + /* skip root folders which cannot be deleted anyway */ + if (G_UNLIKELY (g_file_is_root (lp->data))) + continue; + +again: + /* try to delete the file */ + if (G_UNLIKELY (!g_file_delete (lp->data, thunar_job_get_cancellable (job), &err))) + { + /* query the file info for the display name */ + info = g_file_query_info (lp->data, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NONE, + thunar_job_get_cancellable (job), + NULL); + + /* abort if the job was cancelled */ + if (thunar_job_is_cancelled (job)) + { + g_clear_error (&err); + break; + } + + /* determine the display name, using the basename as a fallback */ + if (info != NULL) + { + display_name = g_strdup (g_file_info_get_display_name (info)); + g_object_unref (info); + } + else + { + basename = g_file_get_basename (lp->data); + display_name = g_filename_display_name (basename); + g_free (basename); + } + + /* ask the user whether he wants to skip this file */ + response = thunar_job_ask_skip (job, _("Could not delete file \"%s\": %s"), + display_name, err->message); + g_free (display_name); + + /* clear the error */ + g_clear_error (&err); + + /* check whether to retry */ + if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_RETRY)) + goto again; + } + } + + /* release the file list */ + g_file_list_free (file_list); + + if (thunar_job_set_error_if_cancelled (job, error)) + return FALSE; + else + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_unlink_files (GList *file_list) +{ + return thunar_simple_job_launch (_thunar_io_jobs_unlink, 1, + G_TYPE_FILE_LIST, file_list); +} Modified: thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h 2009-04-22 00:49:04 UTC (rev 29883) @@ -27,6 +27,7 @@ ThunarJob *thunar_io_jobs_create_files (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; ThunarJob *thunar_io_jobs_make_directories (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_unlink_files (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; G_END_DECLS Added: thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.c =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.c (rev 0) +++ thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.c 2009-04-22 00:49:04 UTC (rev 29883) @@ -0,0 +1,119 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jan...@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 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 + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> + +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> + + + +GList * +thunar_io_scan_directory (ThunarJob *job, + GFile *file, + GFileQueryInfoFlags flags, + gboolean recursively, + GError **error) +{ + GFileEnumerator *enumerator; + GFileInfo *info; + GFileType type; + GError *err = NULL; + GFile *child_file; + GList *child_files = NULL; + GList *files = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_JOB (job), NULL); + _thunar_return_val_if_fail (G_IS_FILE (file), NULL); + _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); + + /* abort if the job was cancelled */ + if (thunar_job_set_error_if_cancelled (job, error)) + return NULL; + + /* query the file type */ + type = g_file_query_file_type (file, flags, thunar_job_get_cancellable (job)); + + /* ignore non-directory nodes */ + if (type != G_FILE_TYPE_DIRECTORY) + return NULL; + + /* abort if the job was cancelled */ + if (thunar_job_set_error_if_cancelled (job, error)) + return NULL; + + /* try to read from the direectory */ + enumerator = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_NAME, + flags, thunar_job_get_cancellable (job), + &err); + + /* abort if there was an error or the job was cancelled */ + if (err != NULL) + { + g_propagate_error (error, err); + return NULL; + } + + /* query info of the first child */ + info = g_file_enumerator_next_file (enumerator, thunar_job_get_cancellable (job), &err); + + /* iterate over children one by one as long as there's no error */ + while (info != NULL && err == NULL && !thunar_job_is_cancelled (job)) + { + /* create GFile for the child and prepend it to the file list */ + child_file = g_file_get_child (file, g_file_info_get_name (info)); + files = g_file_list_prepend (files, child_file); + + /* if the child is a directory and we need to recurse ... just do so */ + if (recursively && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + child_files = thunar_io_scan_directory (job, child_file, flags, recursively, &err); + + /* prepend children to the file list to make sure they're + * processed first (required for unlinking) */ + files = g_list_concat (child_files, files); + } + + g_object_unref (child_file); + g_object_unref (info); + + info = g_file_enumerator_next_file (enumerator, thunar_job_get_cancellable (job), &err); + } + + if (err != NULL || thunar_job_is_cancelled (job)) + { + if (thunar_job_set_error_if_cancelled (job, error)) + g_error_free (err); + else + g_propagate_error (error, err); + + g_object_unref (enumerator); + g_file_list_free (files); + return NULL; + } + + return files; +} Copied: thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.h (from rev 29878, thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h) =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.h (rev 0) +++ thunar/branches/migration-to-gio/thunar/thunar-io-scan-directory.h 2009-04-22 00:49:04 UTC (rev 29883) @@ -0,0 +1,37 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2009 Jannis Pohlmann <jan...@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 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 + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __THUNAR_IO_SCAN_DIRECTORY_H__ +#define __THUNAR_IO_SCAN_DIRECTORY_H__ + +#include <thunar/thunar-job.h> +#include <thunar/thunar-private.h> + +G_BEGIN_DECLS + +GList *thunar_io_scan_directory (ThunarJob *job, + GFile *file, + GFileQueryInfoFlags flags, + gboolean recursively, + GError **error); + +G_END_DECLS + +#endif /* !__THUNAR_IO_SCAN_DIRECTORY_H__ */ Modified: thunar/branches/migration-to-gio/thunar/thunar-job.c =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-job.c 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-job.c 2009-04-22 00:49:04 UTC (rev 29883) @@ -296,7 +296,11 @@ if (!_thunar_job_finish (job, G_SIMPLE_ASYNC_RESULT (result), &error)) { g_assert (error != NULL); - _thunar_job_error (job, error); + + /* don't treat cancellation as an error for now */ + if (error->code != G_IO_ERROR_CANCELLED) + _thunar_job_error (job, error); + g_error_free (error); } Modified: thunar/branches/migration-to-gio/thunar/thunar-simple-job.c =================================================================== --- thunar/branches/migration-to-gio/thunar/thunar-simple-job.c 2009-04-21 21:43:11 UTC (rev 29882) +++ thunar/branches/migration-to-gio/thunar/thunar-simple-job.c 2009-04-22 00:49:04 UTC (rev 29883) @@ -140,8 +140,7 @@ * the results of the processing function */ if (thunar_job_set_error_if_cancelled (job, error)) { - if (err != NULL) - g_error_free (err); + g_clear_error (&err); } else { _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits