1
/* vi:set et ai sw=2 sts=2 ts=2: */
3
* Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
* Boston, MA 02110-1301, USA.
27
#include <thunar/thunar-enum-types.h>
28
#include <thunar/thunar-gio-extensions.h>
29
#include <thunar/thunar-io-scan-directory.h>
30
#include <thunar/thunar-io-jobs.h>
31
#include <thunar/thunar-job.h>
32
#include <thunar/thunar-private.h>
33
#include <thunar/thunar-simple-job.h>
34
#include <thunar/thunar-transfer-job.h>
39
_tij_collect_nofollow (ThunarJob *job,
40
GList *base_file_list,
44
GList *child_file_list = NULL;
45
GList *file_list = NULL;
48
/* recursively collect the files */
49
for (lp = base_file_list;
50
err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
53
/* try to scan the directory */
54
child_file_list = thunar_io_scan_directory (job, lp->data,
55
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
58
/* prepend the new files to the existing list */
59
file_list = thunar_g_file_list_prepend (file_list, lp->data);
60
file_list = g_list_concat (child_file_list, file_list);
63
/* check if we failed */
64
if (err != NULL || exo_job_is_cancelled (EXO_JOB (job)))
66
if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
69
g_propagate_error (error, err);
71
/* release the collected files */
72
thunar_g_file_list_free (file_list);
83
_thunar_io_jobs_create (ThunarJob *job,
84
GValueArray *param_values,
87
GFileOutputStream *stream;
88
ThunarJobResponse response = THUNAR_JOB_RESPONSE_CANCEL;
96
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
97
_thunar_return_val_if_fail (param_values != NULL, FALSE);
98
_thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
99
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
101
/* get the file list */
102
file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
104
/* we know the total amount of files to be processed */
105
thunar_job_set_total_files (THUNAR_JOB (job), file_list);
107
/* iterate over all files in the list */
109
err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
112
g_assert (G_IS_FILE (lp->data));
114
/* update progress information */
115
thunar_job_processing_file (THUNAR_JOB (job), lp);
118
/* try to create the file */
119
stream = g_file_create (lp->data,
121
exo_job_get_cancellable (EXO_JOB (job)),
124
/* abort if the job was cancelled */
125
if (exo_job_is_cancelled (EXO_JOB (job)))
128
/* check if creating failed */
131
if (err->code == G_IO_ERROR_EXISTS)
133
g_clear_error (&err);
135
/* the file already exists, query its display name */
136
info = g_file_query_info (lp->data,
137
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
138
G_FILE_QUERY_INFO_NONE,
139
exo_job_get_cancellable (EXO_JOB (job)),
142
/* abort if the job was cancelled */
143
if (exo_job_is_cancelled (EXO_JOB (job)))
146
/* determine the display name, using the basename as a fallback */
149
display_name = g_strdup (g_file_info_get_display_name (info));
150
g_object_unref (info);
154
base_name = g_file_get_basename (lp->data);
155
display_name = g_filename_display_name (base_name);
159
/* ask the user whether he wants to overwrite the existing file */
160
response = thunar_job_ask_overwrite (THUNAR_JOB (job),
161
_("The file \"%s\" already exists"),
164
/* check if we should overwrite */
165
if (response == THUNAR_JOB_RESPONSE_YES)
167
/* try to remove the file. fail if not possible */
168
if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
173
g_free (display_name);
177
/* determine display name of the file */
178
base_name = g_file_get_basename (lp->data);
179
display_name = g_filename_display_basename (base_name);
182
/* ask the user whether to skip/retry this path (cancels the job if not) */
183
response = thunar_job_ask_skip (THUNAR_JOB (job),
184
_("Failed to create empty file \"%s\": %s"),
185
display_name, err->message);
186
g_free (display_name);
188
g_clear_error (&err);
190
/* go back to the beginning if the user wants to retry */
191
if (response == THUNAR_JOB_RESPONSE_RETRY)
196
g_object_unref (stream);
199
/* check if we have failed */
202
g_propagate_error (error, err);
206
/* check if the job was cancelled */
207
if (exo_job_is_cancelled (EXO_JOB (job)))
210
/* emit the "new-files" signal with the given file list */
211
thunar_job_new_files (THUNAR_JOB (job), file_list);
219
thunar_io_jobs_create_files (GList *file_list)
221
return thunar_simple_job_launch (_thunar_io_jobs_create, 1,
222
THUNAR_TYPE_G_FILE_LIST, file_list);
228
_thunar_io_jobs_mkdir (ThunarJob *job,
229
GValueArray *param_values,
232
ThunarJobResponse response;
240
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
241
_thunar_return_val_if_fail (param_values != NULL, FALSE);
242
_thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
243
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
245
file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
247
/* we know the total list of files to process */
248
thunar_job_set_total_files (THUNAR_JOB (job), file_list);
251
err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
254
g_assert (G_IS_FILE (lp->data));
256
/* update progress information */
257
thunar_job_processing_file (THUNAR_JOB (job), lp);
260
/* try to create the directory */
261
if (!g_file_make_directory (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
263
if (err->code == G_IO_ERROR_EXISTS)
268
/* abort if the job was cancelled */
269
if (exo_job_is_cancelled (EXO_JOB (job)))
272
/* the file already exists, query its display name */
273
info = g_file_query_info (lp->data,
274
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
275
G_FILE_QUERY_INFO_NONE,
276
exo_job_get_cancellable (EXO_JOB (job)),
279
/* abort if the job was cancelled */
280
if (exo_job_is_cancelled (EXO_JOB (job)))
283
/* determine the display name, using the basename as a fallback */
286
display_name = g_strdup (g_file_info_get_display_name (info));
287
g_object_unref (info);
291
base_name = g_file_get_basename (lp->data);
292
display_name = g_filename_display_name (base_name);
296
/* ask the user whether he wants to overwrite the existing file */
297
response = thunar_job_ask_overwrite (THUNAR_JOB (job),
298
_("The file \"%s\" already exists"),
301
/* check if we should overwrite it */
302
if (response == THUNAR_JOB_RESPONSE_YES)
304
/* try to remove the file, fail if not possible */
305
if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
310
g_free (display_name);
314
/* determine the display name of the file */
315
base_name = g_file_get_basename (lp->data);
316
display_name = g_filename_display_basename (base_name);
319
/* ask the user whether to skip/retry this path (cancels the job if not) */
320
response = thunar_job_ask_skip (THUNAR_JOB (job),
321
_("Failed to create directory \"%s\": %s"),
322
display_name, err->message);
323
g_free (display_name);
328
/* go back to the beginning if the user wants to retry */
329
if (response == THUNAR_JOB_RESPONSE_RETRY)
335
/* check if we have failed */
338
g_propagate_error (error, err);
342
/* check if the job was cancelled */
343
if (exo_job_is_cancelled (EXO_JOB (job)))
346
/* emit the "new-files" signal with the given file list */
347
thunar_job_new_files (THUNAR_JOB (job), file_list);
355
thunar_io_jobs_make_directories (GList *file_list)
357
return thunar_simple_job_launch (_thunar_io_jobs_mkdir, 1,
358
THUNAR_TYPE_G_FILE_LIST, file_list);
364
_thunar_io_jobs_unlink (ThunarJob *job,
365
GValueArray *param_values,
368
ThunarJobResponse response;
376
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
377
_thunar_return_val_if_fail (param_values != NULL, FALSE);
378
_thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
379
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
381
/* get the file list */
382
file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
384
/* tell the user that we're preparing to unlink the files */
385
exo_job_info_message (EXO_JOB (job), _("Preparing..."));
387
/* recursively collect files for removal, not following any symlinks */
388
file_list = _tij_collect_nofollow (job, file_list, &err);
390
/* free the file list and fail if there was an error or the job was cancelled */
391
if (err != NULL || exo_job_is_cancelled (EXO_JOB (job)))
393
if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
396
g_propagate_error (error, err);
398
thunar_g_file_list_free (file_list);
402
/* we know the total list of files to process */
403
thunar_job_set_total_files (THUNAR_JOB (job), file_list);
405
/* remove all the files */
406
for (lp = file_list; lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); lp = lp->next)
408
g_assert (G_IS_FILE (lp->data));
410
/* skip root folders which cannot be deleted anyway */
411
if (thunar_g_file_is_root (lp->data))
415
/* try to delete the file */
416
if (!g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
418
/* query the file info for the display name */
419
info = g_file_query_info (lp->data,
420
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
421
G_FILE_QUERY_INFO_NONE,
422
exo_job_get_cancellable (EXO_JOB (job)),
425
/* abort if the job was cancelled */
426
if (exo_job_is_cancelled (EXO_JOB (job)))
428
g_clear_error (&err);
432
/* determine the display name, using the basename as a fallback */
435
display_name = g_strdup (g_file_info_get_display_name (info));
436
g_object_unref (info);
440
base_name = g_file_get_basename (lp->data);
441
display_name = g_filename_display_name (base_name);
445
/* ask the user whether he wants to skip this file */
446
response = thunar_job_ask_skip (THUNAR_JOB (job),
447
_("Could not delete file \"%s\": %s"),
448
display_name, err->message);
449
g_free (display_name);
451
/* clear the error */
452
g_clear_error (&err);
454
/* check whether to retry */
455
if (response == THUNAR_JOB_RESPONSE_RETRY)
460
/* release the file list */
461
thunar_g_file_list_free (file_list);
463
if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
472
thunar_io_jobs_unlink_files (GList *file_list)
474
return thunar_simple_job_launch (_thunar_io_jobs_unlink, 1,
475
THUNAR_TYPE_G_FILE_LIST, file_list);
481
thunar_io_jobs_move_files (GList *source_file_list,
482
GList *target_file_list)
486
_thunar_return_val_if_fail (source_file_list != NULL, NULL);
487
_thunar_return_val_if_fail (target_file_list != NULL, NULL);
488
_thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL);
490
job = thunar_transfer_job_new (source_file_list, target_file_list,
491
THUNAR_TRANSFER_JOB_MOVE);
493
return THUNAR_JOB (exo_job_launch (EXO_JOB (job)));
499
thunar_io_jobs_copy_files (GList *source_file_list,
500
GList *target_file_list)
504
_thunar_return_val_if_fail (source_file_list != NULL, NULL);
505
_thunar_return_val_if_fail (target_file_list != NULL, NULL);
506
_thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL);
508
job = thunar_transfer_job_new (source_file_list, target_file_list,
509
THUNAR_TRANSFER_JOB_COPY);
511
return THUNAR_JOB (exo_job_launch (EXO_JOB (job)));
517
_thunar_io_jobs_link (ThunarJob *job,
518
GValueArray *param_values,
521
ThunarJobResponse response;
523
GList *new_files_list = NULL;
524
GList *source_file_list;
526
GList *target_file_list;
532
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
533
_thunar_return_val_if_fail (param_values != NULL, FALSE);
534
_thunar_return_val_if_fail (param_values->n_values == 2, FALSE);
535
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
537
source_file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
538
target_file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 1));
540
/* we know the total list of paths to process */
541
thunar_job_set_total_files (THUNAR_JOB (job), source_file_list);
543
/* process all files */
544
for (sp = source_file_list, tp = target_file_list;
545
err == NULL && sp != NULL && tp != NULL;
546
sp = sp->next, tp = tp->next)
548
_thunar_assert (G_IS_FILE (sp->data));
549
_thunar_assert (G_IS_FILE (tp->data));
551
/* update progress information */
552
thunar_job_processing_file (THUNAR_JOB (job), sp);
555
source_path = g_file_get_path (sp->data);
557
if (G_LIKELY (source_path != NULL))
559
/* try to create the symlink */
560
g_file_make_symbolic_link (tp->data, source_path,
561
exo_job_get_cancellable (EXO_JOB (job)),
564
g_free (source_path);
567
new_files_list = thunar_g_file_list_prepend (new_files_list, sp->data);
570
/* check if we have an error from which we can recover */
571
if (err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
573
/* ask the user whether he wants to overwrite the existing file */
574
response = thunar_job_ask_overwrite (THUNAR_JOB (job), "%s",
577
/* release the error */
578
g_clear_error (&err);
580
/* try to delete the file */
581
if (G_LIKELY (response == THUNAR_JOB_RESPONSE_YES))
583
/* try to remove the target file (fail if not possible) */
584
if (g_file_delete (tp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
592
base_name = g_file_get_basename (sp->data);
593
display_name = g_filename_display_name (base_name);
594
g_set_error (&err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
595
_("Could not create symbolic link to \"%s\" "
596
"because it is not a local file"), display_name);
597
g_free (display_name);
604
thunar_g_file_list_free (new_files_list);
605
g_propagate_error (error, err);
610
thunar_job_new_files (THUNAR_JOB (job), new_files_list);
611
thunar_g_file_list_free (new_files_list);
619
thunar_io_jobs_link_files (GList *source_file_list,
620
GList *target_file_list)
622
_thunar_return_val_if_fail (source_file_list != NULL, NULL);
623
_thunar_return_val_if_fail (target_file_list != NULL, NULL);
624
_thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL);
626
return thunar_simple_job_launch (_thunar_io_jobs_link, 2,
627
THUNAR_TYPE_G_FILE_LIST, source_file_list,
628
THUNAR_TYPE_G_FILE_LIST, target_file_list);
634
_thunar_io_jobs_trash (ThunarJob *job,
635
GValueArray *param_values,
642
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
643
_thunar_return_val_if_fail (param_values != NULL, FALSE);
644
_thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
645
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
647
file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
649
if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
652
for (lp = file_list; err == NULL && lp != NULL; lp = lp->next)
654
_thunar_assert (G_IS_FILE (lp->data));
655
g_file_trash (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err);
660
g_propagate_error (error, err);
672
thunar_io_jobs_trash_files (GList *file_list)
674
_thunar_return_val_if_fail (file_list != NULL, NULL);
676
return thunar_simple_job_launch (_thunar_io_jobs_trash, 1,
677
THUNAR_TYPE_G_FILE_LIST, file_list);
683
thunar_io_jobs_restore_files (GList *source_file_list,
684
GList *target_file_list)
688
_thunar_return_val_if_fail (source_file_list != NULL, NULL);
689
_thunar_return_val_if_fail (target_file_list != NULL, NULL);
690
_thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL);
692
job = thunar_transfer_job_new (source_file_list, target_file_list,
693
THUNAR_TRANSFER_JOB_MOVE);
695
return THUNAR_JOB (exo_job_launch (EXO_JOB (job)));
701
_thunar_io_jobs_chown (ThunarJob *job,
702
GValueArray *param_values,
705
ThunarJobResponse response;
706
const gchar *message;
715
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
716
_thunar_return_val_if_fail (param_values != NULL, FALSE);
717
_thunar_return_val_if_fail (param_values->n_values == 4, FALSE);
718
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
720
file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
721
uid = g_value_get_int (g_value_array_get_nth (param_values, 1));
722
gid = g_value_get_int (g_value_array_get_nth (param_values, 2));
723
recursive = g_value_get_boolean (g_value_array_get_nth (param_values, 3));
725
_thunar_assert ((uid >= 0 || gid >= 0) && !(uid >= 0 && gid >= 0));
727
/* collect the files for the chown operation */
729
file_list = _tij_collect_nofollow (job, file_list, &err);
731
file_list = thunar_g_file_list_copy (file_list);
735
g_propagate_error (error, err);
739
/* we know the total list of files to process */
740
thunar_job_set_total_files (THUNAR_JOB (job), file_list);
742
/* change the ownership of all files */
743
for (lp = file_list; lp != NULL && err == NULL; lp = lp->next)
745
/* update progress information */
746
thunar_job_processing_file (THUNAR_JOB (job), lp);
748
/* try to query information about the file */
749
info = g_file_query_info (lp->data,
750
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
751
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
752
exo_job_get_cancellable (EXO_JOB (job)),
761
/* try to change the owner UID */
762
g_file_set_attribute_uint32 (lp->data,
763
G_FILE_ATTRIBUTE_UNIX_UID, uid,
764
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
765
exo_job_get_cancellable (EXO_JOB (job)),
770
/* try to change the owner GID */
771
g_file_set_attribute_uint32 (lp->data,
772
G_FILE_ATTRIBUTE_UNIX_GID, gid,
773
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
774
exo_job_get_cancellable (EXO_JOB (job)),
778
/* check if there was a recoverable error */
779
if (err != NULL && !exo_job_is_cancelled (EXO_JOB (job)))
781
/* generate a useful error message */
782
message = G_LIKELY (uid >= 0) ? _("Failed to change the owner of \"%s\": %s")
783
: _("Failed to change the group of \"%s\": %s");
785
/* ask the user whether to skip/retry this file */
786
response = thunar_job_ask_skip (THUNAR_JOB (job), message,
787
g_file_info_get_display_name (info),
790
/* clear the error */
791
g_clear_error (&err);
793
/* check whether to retry */
794
if (response == THUNAR_JOB_RESPONSE_RETRY)
798
/* release file information */
799
g_object_unref (info);
802
/* release the file list */
803
thunar_g_file_list_free (file_list);
807
g_propagate_error (error, err);
819
thunar_io_jobs_change_group (GFile *file,
825
_thunar_return_val_if_fail (G_IS_FILE (file), NULL);
827
file_list.data = g_object_ref (file);
828
file_list.next = NULL;
829
file_list.prev = NULL;
831
return thunar_simple_job_launch (_thunar_io_jobs_chown, 4,
832
THUNAR_TYPE_G_FILE_LIST, &file_list,
834
G_TYPE_INT, (gint) gid,
835
G_TYPE_BOOLEAN, recursive);
837
g_object_unref (file_list.data);
843
_thunar_io_jobs_chmod (ThunarJob *job,
844
GValueArray *param_values,
847
ThunarJobResponse response;
853
ThunarFileMode dir_mask;
854
ThunarFileMode dir_mode;
855
ThunarFileMode file_mask;
856
ThunarFileMode file_mode;
859
ThunarFileMode old_mode;
860
ThunarFileMode new_mode;
862
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
863
_thunar_return_val_if_fail (param_values != NULL, FALSE);
864
_thunar_return_val_if_fail (param_values->n_values == 6, FALSE);
865
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
867
file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
868
dir_mask = g_value_get_flags (g_value_array_get_nth (param_values, 1));
869
dir_mode = g_value_get_flags (g_value_array_get_nth (param_values, 2));
870
file_mask = g_value_get_flags (g_value_array_get_nth (param_values, 3));
871
file_mode = g_value_get_flags (g_value_array_get_nth (param_values, 4));
872
recursive = g_value_get_boolean (g_value_array_get_nth (param_values, 5));
874
/* collect the files for the chown operation */
876
file_list = _tij_collect_nofollow (job, file_list, &err);
878
file_list = thunar_g_file_list_copy (file_list);
882
g_propagate_error (error, err);
886
/* we know the total list of files to process */
887
thunar_job_set_total_files (THUNAR_JOB (job), file_list);
889
/* change the ownership of all files */
890
for (lp = file_list; lp != NULL && err == NULL; lp = lp->next)
892
/* update progress information */
893
thunar_job_processing_file (THUNAR_JOB (job), lp);
895
/* try to query information about the file */
896
info = g_file_query_info (lp->data,
897
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
898
G_FILE_ATTRIBUTE_STANDARD_TYPE ","
899
G_FILE_ATTRIBUTE_UNIX_MODE,
900
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
901
exo_job_get_cancellable (EXO_JOB (job)),
908
/* different actions depending on the type of the file */
909
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
920
/* determine the current mode */
921
old_mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);
923
/* generate the new mode, taking the old mode (which contains file type
924
* information) into account */
925
new_mode = ((old_mode & ~mask) | mode) & 07777;
927
/* try to change the file mode */
928
g_file_set_attribute_uint32 (lp->data,
929
G_FILE_ATTRIBUTE_UNIX_MODE, new_mode,
930
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
931
exo_job_get_cancellable (EXO_JOB (job)),
934
/* check if there was a recoverable error */
935
if (err != NULL && !exo_job_is_cancelled (EXO_JOB (job)))
937
/* ask the user whether to skip/retry this file */
938
response = thunar_job_ask_skip (job,
939
_("Failed to change the permissions of \"%s\": %s"),
940
g_file_info_get_display_name (info),
943
/* clear the error */
944
g_clear_error (&err);
946
/* check whether to retry */
947
if (response == THUNAR_JOB_RESPONSE_RETRY)
951
/* release file information */
952
g_object_unref (info);
955
/* release the file list */
956
thunar_g_file_list_free (file_list);
960
g_propagate_error (error, err);
973
thunar_io_jobs_change_mode (GFile *file,
974
ThunarFileMode dir_mask,
975
ThunarFileMode dir_mode,
976
ThunarFileMode file_mask,
977
ThunarFileMode file_mode,
982
_thunar_return_val_if_fail (G_IS_FILE (file), NULL);
984
file_list.data = g_object_ref (file);
985
file_list.next = NULL;
986
file_list.prev = NULL;
988
return thunar_simple_job_launch (_thunar_io_jobs_chmod, 6,
989
THUNAR_TYPE_G_FILE_LIST, &file_list,
990
THUNAR_TYPE_FILE_MODE, dir_mask,
991
THUNAR_TYPE_FILE_MODE, dir_mode,
992
THUNAR_TYPE_FILE_MODE, file_mask,
993
THUNAR_TYPE_FILE_MODE, file_mode,
994
G_TYPE_BOOLEAN, recursive);
996
g_object_unref (file_list.data);
1002
_thunar_io_jobs_ls (ThunarJob *job,
1003
GValueArray *param_values,
1009
GList *file_list = NULL;
1013
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
1014
_thunar_return_val_if_fail (param_values != NULL, FALSE);
1015
_thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
1016
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1018
if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
1021
/* determine the directory to list */
1022
directory = g_value_get_object (g_value_array_get_nth (param_values, 0));
1024
/* make sure the object is valid */
1025
_thunar_assert (G_IS_FILE (directory));
1027
/* collect directory contents (non-recursively) */
1028
path_list = thunar_io_scan_directory (job, directory,
1029
G_FILE_QUERY_INFO_NONE,
1032
/* turn the GFile list into a ThunarFile list */
1033
for (lp = g_list_last (path_list);
1034
err == NULL && !exo_job_is_cancelled (EXO_JOB (job)) && lp != NULL;
1037
file = thunar_file_get (lp->data, &err);
1038
if (G_LIKELY (file != NULL))
1039
file_list = g_list_prepend (file_list, file);
1042
/* free the GFile list */
1043
thunar_g_file_list_free (path_list);
1045
/* abort on errors or cancellation */
1048
g_propagate_error (error, err);
1051
else if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err))
1053
g_propagate_error (error, err);
1057
/* check if we have any files to report */
1058
if (G_LIKELY (file_list != NULL))
1060
/* emit the "files-ready" signal */
1061
if (!thunar_job_files_ready (THUNAR_JOB (job), file_list))
1063
/* none of the handlers took over the file list, so it's up to us
1065
thunar_file_list_free (file_list);
1069
/* there should be no errors here */
1070
_thunar_assert (err == NULL);
1072
/* propagate cancellation error */
1073
if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err))
1075
g_propagate_error (error, err);
1085
thunar_io_jobs_list_directory (GFile *directory)
1087
_thunar_return_val_if_fail (G_IS_FILE (directory), NULL);
1089
return thunar_simple_job_launch (_thunar_io_jobs_ls, 1, G_TYPE_FILE, directory);
1095
_thunar_io_jobs_rename_notify (ThunarFile *file)
1097
_thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
1099
/* tell the associated folder that the file was renamed */
1100
thunarx_file_info_renamed (THUNARX_FILE_INFO (file));
1102
/* emit the file changed signal */
1103
thunar_file_changed (file);
1111
_thunar_io_jobs_rename (ThunarJob *job,
1112
GValueArray *param_values,
1115
const gchar *display_name;
1119
_thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
1120
_thunar_return_val_if_fail (param_values != NULL, FALSE);
1121
_thunar_return_val_if_fail (param_values->n_values == 2, FALSE);
1122
_thunar_return_val_if_fail (G_VALUE_HOLDS (¶m_values->values[0], THUNAR_TYPE_FILE), FALSE);
1123
_thunar_return_val_if_fail (G_VALUE_HOLDS_STRING (¶m_values->values[1]), FALSE);
1124
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1126
if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
1129
/* determine the file and display name */
1130
file = g_value_get_object (g_value_array_get_nth (param_values, 0));
1131
display_name = g_value_get_string (g_value_array_get_nth (param_values, 1));
1133
/* try to rename the file */
1134
if (thunar_file_rename (file, display_name, exo_job_get_cancellable (EXO_JOB (job)), TRUE, &err))
1136
exo_job_send_to_mainloop (EXO_JOB (job),
1137
(GSourceFunc) _thunar_io_jobs_rename_notify,
1138
g_object_ref (file), g_object_unref);
1141
/* abort on errors or cancellation */
1144
g_propagate_error (error, err);
1154
thunar_io_jobs_rename_file (ThunarFile *file,
1155
const gchar *display_name)
1157
_thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
1158
_thunar_return_val_if_fail (g_utf8_validate (display_name, -1, NULL), NULL);
1160
return thunar_simple_job_launch (_thunar_io_jobs_rename, 2,
1161
THUNAR_TYPE_FILE, file,
1162
G_TYPE_STRING, display_name);