1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * GThumb
5 *
6 * Copyright (C) 2008-2009 Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23 #include <string.h>
24 #include <glib/gi18n.h>
25 #include <glib.h>
26 #include <gtk/gtk.h>
27 #include "gth-file-data.h"
28 #include "glib-utils.h"
29 #include "gth-file-source.h"
30 #include "gth-main.h"
31
32
33 struct _GthFileSourcePrivate {
34 GList *schemes;
35 gboolean active;
36 GList *queue;
37 GCancellable *cancellable;
38 };
39
40
41 G_DEFINE_TYPE_WITH_CODE (GthFileSource,
42 gth_file_source,
43 G_TYPE_OBJECT,
44 G_ADD_PRIVATE (GthFileSource))
45
46
47 /* -- queue -- */
48
49
50 typedef enum {
51 FILE_SOURCE_OP_WRITE_METADATA,
52 FILE_SOURCE_OP_READ_METADATA,
53 FILE_SOURCE_OP_LIST,
54 FILE_SOURCE_OP_FOR_EACH_CHILD,
55 FILE_SOURCE_OP_READ_ATTRIBUTES,
56 FILE_SOURCE_OP_RENAME,
57 FILE_SOURCE_OP_COPY,
58 FILE_SOURCE_OP_REORDER,
59 FILE_SOURCE_OP_REMOVE,
60 FILE_SOURCE_OP_DELETED_FROM_DISK,
61 FILE_SOURCE_OP_GET_FREE_SPACE
62 } FileSourceOp;
63
64
65 typedef struct {
66 GFile *folder;
67 const char *attributes;
68 ListReady func;
69 gpointer data;
70 } ListData;
71
72
73 typedef struct {
74 GList *files;
75 const char *attributes;
76 ListReady func;
77 gpointer data;
78 } ReadAttributesData;
79
80
81 typedef struct {
82 GFile *file;
83 char *edit_name;
84 ReadyCallback callback;
85 gpointer data;
86 } RenameData;
87
88
89 typedef struct {
90 GthFileData *destination;
91 GList *file_list;
92 gboolean move;
93 int destination_position;
94 ProgressCallback progress_callback;
95 DialogCallback dialog_callback;
96 ReadyCallback ready_callback;
97 gpointer data;
98 } CopyData;
99
100
101 typedef struct {
102 GthFileData *destination;
103 GList *visible_files;
104 GList *files_to_move;
105 int dest_pos;
106 ReadyCallback ready_callback;
107 gpointer data;
108 } ReorderData;
109
110
111 typedef struct {
112 GthFileData *file_data;
113 char *attributes;
114 ReadyCallback ready_callback;
115 gpointer data;
116 } WriteMetadataData;
117
118
119 typedef struct {
120 GthFileData *file_data;
121 char *attributes;
122 ReadyCallback ready_callback;
123 gpointer data;
124 } ReadMetadataData;
125
126
127 typedef struct {
128 GFile *parent;
129 gboolean recursive;
130 const char *attributes;
131 StartDirCallback dir_func;
132 ForEachChildCallback child_func;
133 ReadyCallback ready_func;
134 gpointer data;
135 } ForEachChildData;
136
137
138 typedef struct {
139 GthFileData *location;
140 GList *file_list;
141 gboolean permanently;
142 GtkWindow *parent;
143 } RemoveData;
144
145
146 typedef struct {
147 GthFileData *location;
148 GList *file_list;
149 } DeletedFromDiskData;
150
151
152 typedef struct {
153 GFile *location;
154 SpaceReadyCallback callback;
155 gpointer data;
156 } GetFreeSpaceData;
157
158
159 typedef struct {
160 GthFileSource *file_source;
161 FileSourceOp op;
162 union {
163 ListData list;
164 ForEachChildData fec;
165 ReadAttributesData read_attributes;
166 RenameData rename;
167 CopyData copy;
168 ReorderData reorder;
169 WriteMetadataData write_metadata;
170 ReadMetadataData read_metadata;
171 RemoveData remove;
172 DeletedFromDiskData deleted_from_disk;
173 GetFreeSpaceData get_free_space;
174 } data;
175 } FileSourceAsyncOp;
176
177
178 static void
file_source_async_op_free(FileSourceAsyncOp * async_op)179 file_source_async_op_free (FileSourceAsyncOp *async_op)
180 {
181 switch (async_op->op) {
182 case FILE_SOURCE_OP_WRITE_METADATA:
183 g_free (async_op->data.write_metadata.attributes);
184 g_object_unref (async_op->data.write_metadata.file_data);
185 break;
186 case FILE_SOURCE_OP_READ_METADATA:
187 g_free (async_op->data.write_metadata.attributes);
188 g_object_unref (async_op->data.read_metadata.file_data);
189 break;
190 case FILE_SOURCE_OP_LIST:
191 g_object_unref (async_op->data.list.folder);
192 break;
193 case FILE_SOURCE_OP_FOR_EACH_CHILD:
194 g_object_unref (async_op->data.fec.parent);
195 break;
196 case FILE_SOURCE_OP_READ_ATTRIBUTES:
197 _g_object_list_unref (async_op->data.read_attributes.files);
198 break;
199 case FILE_SOURCE_OP_RENAME:
200 g_object_unref (async_op->data.rename.file);
201 g_free (async_op->data.rename.edit_name);
202 break;
203 case FILE_SOURCE_OP_COPY:
204 g_object_unref (async_op->data.copy.destination);
205 _g_object_list_unref (async_op->data.copy.file_list);
206 break;
207 case FILE_SOURCE_OP_REORDER:
208 g_object_unref (async_op->data.copy.destination);
209 _g_object_list_unref (async_op->data.copy.file_list);
210 break;
211 case FILE_SOURCE_OP_REMOVE:
212 _g_object_unref (async_op->data.remove.location);
213 _g_object_list_unref (async_op->data.remove.file_list);
214 break;
215 case FILE_SOURCE_OP_DELETED_FROM_DISK:
216 _g_object_unref (async_op->data.deleted_from_disk.location);
217 _g_object_list_unref (async_op->data.deleted_from_disk.file_list);
218 break;
219 case FILE_SOURCE_OP_GET_FREE_SPACE:
220 _g_object_unref (async_op->data.get_free_space.location);
221 break;
222 }
223
224 g_free (async_op);
225 }
226
227
228 static void
gth_file_source_queue_write_metadata(GthFileSource * file_source,GthFileData * file_data,const char * attributes,ReadyCallback callback,gpointer data)229 gth_file_source_queue_write_metadata (GthFileSource *file_source,
230 GthFileData *file_data,
231 const char *attributes,
232 ReadyCallback callback,
233 gpointer data)
234 {
235 FileSourceAsyncOp *async_op;
236
237 async_op = g_new0 (FileSourceAsyncOp, 1);
238 async_op->file_source = file_source;
239 async_op->op = FILE_SOURCE_OP_WRITE_METADATA;
240 async_op->data.write_metadata.file_data = g_object_ref (file_data);
241 async_op->data.write_metadata.attributes = g_strdup (attributes);
242 async_op->data.write_metadata.ready_callback = callback;
243 async_op->data.write_metadata.data = data;
244
245 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
246 }
247
248
249 static void
gth_file_source_queue_read_metadata(GthFileSource * file_source,GthFileData * file_data,const char * attributes,ReadyCallback callback,gpointer data)250 gth_file_source_queue_read_metadata (GthFileSource *file_source,
251 GthFileData *file_data,
252 const char *attributes,
253 ReadyCallback callback,
254 gpointer data)
255 {
256 FileSourceAsyncOp *async_op;
257
258 async_op = g_new0 (FileSourceAsyncOp, 1);
259 async_op->file_source = file_source;
260 async_op->op = FILE_SOURCE_OP_READ_METADATA;
261 async_op->data.read_metadata.file_data = g_object_ref (file_data);
262 async_op->data.write_metadata.attributes = g_strdup (attributes);
263 async_op->data.read_metadata.ready_callback = callback;
264 async_op->data.read_metadata.data = data;
265
266 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
267 }
268
269
270 static void
gth_file_source_queue_list(GthFileSource * file_source,GFile * folder,const char * attributes,ListReady func,gpointer data)271 gth_file_source_queue_list (GthFileSource *file_source,
272 GFile *folder,
273 const char *attributes,
274 ListReady func,
275 gpointer data)
276 {
277 FileSourceAsyncOp *async_op;
278
279 async_op = g_new0 (FileSourceAsyncOp, 1);
280 async_op->file_source = file_source;
281 async_op->op = FILE_SOURCE_OP_LIST;
282 async_op->data.list.folder = g_file_dup (folder);
283 async_op->data.list.attributes = attributes;
284 async_op->data.list.func = func;
285 async_op->data.list.data = data;
286
287 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
288 }
289
290
291 static void
gth_file_source_queue_for_each_child(GthFileSource * file_source,GFile * parent,gboolean recursive,const char * attributes,StartDirCallback dir_func,ForEachChildCallback child_func,ReadyCallback ready_func,gpointer data)292 gth_file_source_queue_for_each_child (GthFileSource *file_source,
293 GFile *parent,
294 gboolean recursive,
295 const char *attributes,
296 StartDirCallback dir_func,
297 ForEachChildCallback child_func,
298 ReadyCallback ready_func,
299 gpointer data)
300 {
301 FileSourceAsyncOp *async_op;
302
303 async_op = g_new0 (FileSourceAsyncOp, 1);
304 async_op->file_source = file_source;
305 async_op->op = FILE_SOURCE_OP_FOR_EACH_CHILD;
306 async_op->data.fec.parent = g_file_dup (parent);
307 async_op->data.fec.recursive = recursive;
308 async_op->data.fec.attributes = attributes;
309 async_op->data.fec.dir_func = dir_func;
310 async_op->data.fec.child_func = child_func;
311 async_op->data.fec.ready_func = ready_func;
312 async_op->data.fec.data = data;
313
314 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
315 }
316
317
318 static void
gth_file_source_queue_read_attributes(GthFileSource * file_source,GList * files,const char * attributes,ListReady func,gpointer data)319 gth_file_source_queue_read_attributes (GthFileSource *file_source,
320 GList *files,
321 const char *attributes,
322 ListReady func,
323 gpointer data)
324 {
325 FileSourceAsyncOp *async_op;
326
327 async_op = g_new0 (FileSourceAsyncOp, 1);
328 async_op->file_source = file_source;
329 async_op->op = FILE_SOURCE_OP_READ_ATTRIBUTES;
330 async_op->data.read_attributes.files = _g_object_list_ref (files);
331 async_op->data.read_attributes.attributes = attributes;
332 async_op->data.read_attributes.func = func;
333 async_op->data.read_attributes.data = data;
334
335 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
336 }
337
338
339 static void
gth_file_source_queue_rename(GthFileSource * file_source,GFile * file,const char * edit_name,ReadyCallback callback,gpointer data)340 gth_file_source_queue_rename (GthFileSource *file_source,
341 GFile *file,
342 const char *edit_name,
343 ReadyCallback callback,
344 gpointer data)
345 {
346 FileSourceAsyncOp *async_op;
347
348 async_op = g_new0 (FileSourceAsyncOp, 1);
349 async_op->file_source = file_source;
350 async_op->op = FILE_SOURCE_OP_RENAME;
351 async_op->data.rename.file = g_file_dup (file);
352 async_op->data.rename.edit_name = g_strdup (edit_name);
353 async_op->data.rename.callback = callback;
354 async_op->data.rename.data = data;
355
356 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
357 }
358
359
360 static void
gth_file_source_queue_copy(GthFileSource * file_source,GthFileData * destination,GList * file_list,gboolean move,int destination_position,ProgressCallback progress_callback,DialogCallback dialog_callback,ReadyCallback ready_callback,gpointer data)361 gth_file_source_queue_copy (GthFileSource *file_source,
362 GthFileData *destination,
363 GList *file_list,
364 gboolean move,
365 int destination_position,
366 ProgressCallback progress_callback,
367 DialogCallback dialog_callback,
368 ReadyCallback ready_callback,
369 gpointer data)
370 {
371 FileSourceAsyncOp *async_op;
372
373 async_op = g_new0 (FileSourceAsyncOp, 1);
374 async_op->file_source = file_source;
375 async_op->op = FILE_SOURCE_OP_COPY;
376 async_op->data.copy.destination = gth_file_data_dup (destination);
377 async_op->data.copy.file_list = _g_file_list_dup (file_list);
378 async_op->data.copy.move = move;
379 async_op->data.copy.destination_position = destination_position;
380 async_op->data.copy.progress_callback = progress_callback;
381 async_op->data.copy.dialog_callback = dialog_callback;
382 async_op->data.copy.ready_callback = ready_callback;
383 async_op->data.copy.data = data;
384
385 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
386 }
387
388
389 static void
gth_file_source_queue_reorder(GthFileSource * file_source,GthFileData * destination,GList * visible_files,GList * files_to_move,int dest_pos,ReadyCallback ready_callback,gpointer data)390 gth_file_source_queue_reorder (GthFileSource *file_source,
391 GthFileData *destination,
392 GList *visible_files, /* GFile list */
393 GList *files_to_move, /* GFile list */
394 int dest_pos,
395 ReadyCallback ready_callback,
396 gpointer data)
397 {
398 FileSourceAsyncOp *async_op;
399
400 async_op = g_new0 (FileSourceAsyncOp, 1);
401 async_op->file_source = file_source;
402 async_op->op = FILE_SOURCE_OP_REORDER;
403 async_op->data.reorder.destination = gth_file_data_dup (destination);
404 async_op->data.reorder.visible_files = _g_file_list_dup (visible_files);
405 async_op->data.reorder.files_to_move = _g_file_list_dup (files_to_move);
406 async_op->data.reorder.dest_pos = dest_pos;
407 async_op->data.reorder.ready_callback = ready_callback;
408 async_op->data.reorder.data = data;
409
410 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
411 }
412
413
414 static void
gth_file_source_queue_remove(GthFileSource * file_source,GthFileData * location,GList * file_list,gboolean permanently,GtkWindow * parent)415 gth_file_source_queue_remove (GthFileSource *file_source,
416 GthFileData *location,
417 GList *file_list,
418 gboolean permanently,
419 GtkWindow *parent)
420 {
421 FileSourceAsyncOp *async_op;
422
423 async_op = g_new0 (FileSourceAsyncOp, 1);
424 async_op->file_source = file_source;
425 async_op->op = FILE_SOURCE_OP_REMOVE;
426 async_op->data.remove.location = gth_file_data_dup (location);
427 async_op->data.remove.file_list = gth_file_data_list_dup (file_list);
428 async_op->data.remove.permanently = permanently;
429 async_op->data.remove.parent = parent;
430
431 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
432 }
433
434
435 static void
gth_file_source_queue_deleted_from_disk(GthFileSource * file_source,GthFileData * location,GList * file_list)436 gth_file_source_queue_deleted_from_disk (GthFileSource *file_source,
437 GthFileData *location,
438 GList *file_list)
439 {
440 FileSourceAsyncOp *async_op;
441
442 async_op = g_new0 (FileSourceAsyncOp, 1);
443 async_op->file_source = file_source;
444 async_op->op = FILE_SOURCE_OP_DELETED_FROM_DISK;
445 async_op->data.deleted_from_disk.location = gth_file_data_dup (location);
446 async_op->data.deleted_from_disk.file_list = _g_file_list_dup (file_list);
447
448 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
449 }
450
451
452 static void
gth_file_source_queue_get_free_space(GthFileSource * file_source,GFile * location,SpaceReadyCallback callback,gpointer data)453 gth_file_source_queue_get_free_space (GthFileSource *file_source,
454 GFile *location,
455 SpaceReadyCallback callback,
456 gpointer data)
457 {
458 FileSourceAsyncOp *async_op;
459
460 async_op = g_new0 (FileSourceAsyncOp, 1);
461 async_op->file_source = file_source;
462 async_op->op = FILE_SOURCE_OP_GET_FREE_SPACE;
463 async_op->data.get_free_space.location = g_file_dup (location);
464 async_op->data.get_free_space.callback = callback;
465 async_op->data.get_free_space.data = data;
466
467 file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
468 }
469
470
471 static void
gth_file_source_exec_next_in_queue(GthFileSource * file_source)472 gth_file_source_exec_next_in_queue (GthFileSource *file_source)
473 {
474 GList *head;
475 FileSourceAsyncOp *async_op;
476
477 if (file_source->priv->queue == NULL)
478 return;
479
480 g_cancellable_reset (file_source->priv->cancellable);
481
482 head = file_source->priv->queue;
483 file_source->priv->queue = g_list_remove_link (file_source->priv->queue, head);
484
485 async_op = head->data;
486 switch (async_op->op) {
487 case FILE_SOURCE_OP_WRITE_METADATA:
488 gth_file_source_write_metadata (file_source,
489 async_op->data.write_metadata.file_data,
490 async_op->data.write_metadata.attributes,
491 async_op->data.write_metadata.ready_callback,
492 async_op->data.write_metadata.data);
493 break;
494 case FILE_SOURCE_OP_READ_METADATA:
495 gth_file_source_read_metadata (file_source,
496 async_op->data.read_metadata.file_data,
497 async_op->data.write_metadata.attributes,
498 async_op->data.read_metadata.ready_callback,
499 async_op->data.read_metadata.data);
500 break;
501 case FILE_SOURCE_OP_LIST:
502 gth_file_source_list (file_source,
503 async_op->data.list.folder,
504 async_op->data.list.attributes,
505 async_op->data.list.func,
506 async_op->data.list.data);
507 break;
508 case FILE_SOURCE_OP_FOR_EACH_CHILD:
509 gth_file_source_for_each_child (file_source,
510 async_op->data.fec.parent,
511 async_op->data.fec.recursive,
512 async_op->data.fec.attributes,
513 async_op->data.fec.dir_func,
514 async_op->data.fec.child_func,
515 async_op->data.fec.ready_func,
516 async_op->data.fec.data);
517 break;
518 case FILE_SOURCE_OP_READ_ATTRIBUTES:
519 gth_file_source_read_attributes (file_source,
520 async_op->data.read_attributes.files,
521 async_op->data.read_attributes.attributes,
522 async_op->data.read_attributes.func,
523 async_op->data.read_attributes.data);
524 break;
525 case FILE_SOURCE_OP_RENAME:
526 gth_file_source_rename (file_source,
527 async_op->data.rename.file,
528 async_op->data.rename.edit_name,
529 async_op->data.rename.callback,
530 async_op->data.rename.data);
531 break;
532 case FILE_SOURCE_OP_COPY:
533 gth_file_source_copy (file_source,
534 async_op->data.copy.destination,
535 async_op->data.copy.file_list,
536 async_op->data.copy.move,
537 async_op->data.copy.destination_position,
538 async_op->data.copy.progress_callback,
539 async_op->data.copy.dialog_callback,
540 async_op->data.copy.ready_callback,
541 async_op->data.copy.data);
542 break;
543 case FILE_SOURCE_OP_REORDER:
544 gth_file_source_reorder (file_source,
545 async_op->data.reorder.destination,
546 async_op->data.reorder.visible_files,
547 async_op->data.reorder.files_to_move,
548 async_op->data.reorder.dest_pos,
549 async_op->data.reorder.ready_callback,
550 async_op->data.reorder.data);
551 break;
552 case FILE_SOURCE_OP_REMOVE:
553 gth_file_source_remove (file_source,
554 async_op->data.remove.location,
555 async_op->data.remove.file_list,
556 async_op->data.remove.permanently,
557 async_op->data.remove.parent);
558 break;
559
560 case FILE_SOURCE_OP_DELETED_FROM_DISK:
561 gth_file_source_queue_deleted_from_disk (file_source,
562 async_op->data.deleted_from_disk.location,
563 async_op->data.deleted_from_disk.file_list);
564 break;
565
566 case FILE_SOURCE_OP_GET_FREE_SPACE:
567 gth_file_source_get_free_space (file_source,
568 async_op->data.get_free_space.location,
569 async_op->data.get_free_space.callback,
570 async_op->data.get_free_space.data);
571 break;
572 }
573
574 file_source_async_op_free (async_op);
575 g_list_free (head);
576 }
577
578
579 static void
gth_file_source_clear_queue(GthFileSource * file_source)580 gth_file_source_clear_queue (GthFileSource *file_source)
581 {
582 g_list_foreach (file_source->priv->queue, (GFunc) file_source_async_op_free, NULL);
583 g_list_free (file_source->priv->queue);
584 file_source->priv->queue = NULL;
585 }
586
587
588 /* -- */
589
590
591 static GList *
base_get_entry_points(GthFileSource * file_source)592 base_get_entry_points (GthFileSource *file_source)
593 {
594 return NULL;
595 }
596
597
598 static GList *
base_get_current_list(GthFileSource * file_source,GFile * file)599 base_get_current_list (GthFileSource *file_source,
600 GFile *file)
601 {
602 GList *list = NULL;
603 GFile *parent;
604
605 if (file == NULL)
606 return NULL;
607
608 parent = g_file_dup (file);
609 while (parent != NULL) {
610 GFile *tmp;
611
612 list = g_list_prepend (list, g_object_ref (parent));
613 tmp = g_file_get_parent (parent);
614 g_object_unref (parent);
615 parent = tmp;
616 }
617
618 return g_list_reverse (list);
619 }
620
621
622 static GFile *
base_to_gio_file(GthFileSource * file_source,GFile * file)623 base_to_gio_file (GthFileSource *file_source,
624 GFile *file)
625 {
626 return g_file_dup (file);
627 }
628
629
630 static GFileInfo *
base_get_file_info(GthFileSource * file_source,GFile * file,const char * attributes)631 base_get_file_info (GthFileSource *file_source,
632 GFile *file,
633 const char *attributes)
634 {
635 return NULL;
636 }
637
638
639 static GthFileData *
base_get_file_data(GthFileSource * file_source,GFile * file,GFileInfo * info)640 base_get_file_data (GthFileSource *file_source,
641 GFile *file,
642 GFileInfo *info)
643 {
644 return gth_file_data_new (file, info);
645 }
646
647
648 static void
base_write_metadata(GthFileSource * file_source,GthFileData * file_data,const char * attributes,ReadyCallback callback,gpointer data)649 base_write_metadata (GthFileSource *file_source,
650 GthFileData *file_data,
651 const char *attributes,
652 ReadyCallback callback,
653 gpointer data)
654 {
655 object_ready_with_error (file_source, callback, data, NULL);
656 }
657
658
659 typedef struct {
660 GFile *location;
661 GthFileSource *file_source;
662 SpaceReadyCallback callback;
663 gpointer data;
664 } BaseFreeSpaceData;
665
666
667 static void
get_free_space_ready_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)668 get_free_space_ready_cb (GObject *source_object,
669 GAsyncResult *res,
670 gpointer user_data)
671 {
672 BaseFreeSpaceData *free_space_data = user_data;
673 GFileInfo *info;
674 GError *error = NULL;
675 guint64 total_size = 0;
676 guint64 free_space = 0;
677
678 info = g_file_query_filesystem_info_finish (free_space_data->location, res, &error);
679 if (info != NULL) {
680 total_size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
681 free_space = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
682 g_object_unref (info);
683 }
684
685 free_space_data->callback (free_space_data->file_source,
686 total_size,
687 free_space,
688 error,
689 free_space_data->data);
690
691 if (error != NULL)
692 g_error_free (error);
693 g_object_unref (free_space_data->location);
694 g_free (free_space_data);
695 }
696
697
698 static void
base_get_free_space(GthFileSource * file_source,GFile * location,SpaceReadyCallback callback,gpointer data)699 base_get_free_space (GthFileSource *file_source,
700 GFile *location,
701 SpaceReadyCallback callback,
702 gpointer data)
703 {
704 BaseFreeSpaceData *free_space_data;
705
706 free_space_data = g_new0 (BaseFreeSpaceData, 1);
707 free_space_data->location = g_object_ref (location);
708 free_space_data->file_source = file_source;
709 free_space_data->callback = callback;
710 free_space_data->data = data;
711 g_file_query_filesystem_info_async (location,
712 G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," G_FILE_ATTRIBUTE_FILESYSTEM_FREE,
713 G_PRIORITY_DEFAULT,
714 file_source->priv->cancellable,
715 get_free_space_ready_cb,
716 free_space_data);
717 }
718
719
720 /* -- base_read_metadata -- */
721
722
723 typedef struct {
724 GthFileSource *file_source;
725 GthFileData *file_data;
726 ReadyCallback callback;
727 gpointer data;
728 } ReadMetadataOpData;
729
730
731 static void
read_metadata_free(ReadMetadataOpData * read_metadata)732 read_metadata_free (ReadMetadataOpData *read_metadata)
733 {
734 g_object_unref (read_metadata->file_source);
735 g_object_unref (read_metadata->file_data);
736 g_free (read_metadata);
737 }
738
739
740 static void
read_metadata_info_ready_cb(GList * files,GError * error,gpointer user_data)741 read_metadata_info_ready_cb (GList *files,
742 GError *error,
743 gpointer user_data)
744 {
745 ReadMetadataOpData *read_metadata = user_data;
746 GthFileData *result;
747
748 if (error != NULL) {
749 read_metadata->callback (G_OBJECT (read_metadata->file_source), error, read_metadata->data);
750 read_metadata_free (read_metadata);
751 return;
752 }
753
754 result = files->data;
755 g_file_info_copy_into (result->info, read_metadata->file_data->info);
756 read_metadata->callback (G_OBJECT (read_metadata->file_source), NULL, read_metadata->data);
757
758 read_metadata_free (read_metadata);
759 }
760
761
762 static void
base_read_metadata(GthFileSource * file_source,GthFileData * file_data,const char * attributes,ReadyCallback callback,gpointer data)763 base_read_metadata (GthFileSource *file_source,
764 GthFileData *file_data,
765 const char *attributes,
766 ReadyCallback callback,
767 gpointer data)
768 {
769 ReadMetadataOpData *read_metadata;
770 GList *files;
771
772 read_metadata = g_new0 (ReadMetadataOpData, 1);
773 read_metadata->file_source = g_object_ref (file_source);
774 read_metadata->file_data = g_object_ref (file_data);
775 read_metadata->callback = callback;
776 read_metadata->data = data;
777
778 files = g_list_prepend (NULL, file_data->file);
779 _g_query_all_metadata_async (files,
780 GTH_LIST_DEFAULT,
781 attributes,
782 file_source->priv->cancellable,
783 read_metadata_info_ready_cb,
784 read_metadata);
785
786 g_list_free (files);
787 }
788
789
790 static void
base_rename(GthFileSource * file_source,GFile * file,const char * edit_name,ReadyCallback callback,gpointer data)791 base_rename (GthFileSource *file_source,
792 GFile *file,
793 const char *edit_name,
794 ReadyCallback callback,
795 gpointer data)
796 {
797 GFile *parent;
798 GFile *new_file;
799 GFile *source;
800 GFile *destination;
801 GError *error = NULL;
802
803 parent = g_file_get_parent (file);
804 new_file = g_file_get_child_for_display_name (parent, edit_name, &error);
805 if (new_file == NULL) {
806 object_ready_with_error (file_source, callback, data, error);
807 return;
808 }
809
810 source = gth_file_source_to_gio_file (file_source, file);
811 destination = gth_file_source_to_gio_file (file_source, new_file);
812
813 if (g_file_move (source,
814 destination,
815 0,
816 gth_file_source_get_cancellable (file_source),
817 NULL,
818 NULL,
819 &error))
820 {
821 GthMonitor *monitor;
822
823 monitor = gth_main_get_default_monitor ();
824 gth_monitor_file_renamed (monitor, file, new_file);
825 }
826 object_ready_with_error (file_source, callback, data, error);
827
828 g_object_unref (destination);
829 g_object_unref (source);
830 }
831
832
833 static gboolean
base_can_cut(GthFileSource * file_source)834 base_can_cut (GthFileSource *file_source)
835 {
836 return FALSE;
837 }
838
839
840 static void
base_monitor_entry_points(GthFileSource * file_source)841 base_monitor_entry_points (GthFileSource *file_source)
842 {
843 /* void */
844 }
845
846
847 static void
base_monitor_directory(GthFileSource * file_source,GFile * file,gboolean activate)848 base_monitor_directory (GthFileSource *file_source,
849 GFile *file,
850 gboolean activate)
851 {
852 /* void */
853 }
854
855
856 static gboolean
base_is_reorderable(GthFileSource * file_source)857 base_is_reorderable (GthFileSource *file_source)
858 {
859 return FALSE;
860 }
861
862
863 static void
base_reorder(GthFileSource * file_source,GthFileData * destination,GList * visible_files,GList * files_to_move,int dest_pos,ReadyCallback callback,gpointer data)864 base_reorder (GthFileSource *file_source,
865 GthFileData *destination,
866 GList *visible_files, /* GFile list */
867 GList *files_to_move, /* GFile list */
868 int dest_pos,
869 ReadyCallback callback,
870 gpointer data)
871 {
872 /* void */
873 }
874
875
876 static void
base_remove(GthFileSource * file_source,GthFileData * location,GList * file_list,gboolean permanently,GtkWindow * parent)877 base_remove (GthFileSource *file_source,
878 GthFileData *location,
879 GList *file_list, /* GFile list */
880 gboolean permanently,
881 GtkWindow *parent)
882 {
883 /* void */
884 }
885
886
887 static void
base_deleted_from_disk(GthFileSource * file_source,GthFileData * location,GList * file_list)888 base_deleted_from_disk (GthFileSource *file_source,
889 GthFileData *location,
890 GList *file_list /* GFile list */)
891 {
892 /* void */
893 }
894
895
896 static gboolean
base_shows_extra_widget(GthFileSource * file_source)897 base_shows_extra_widget (GthFileSource *file_source)
898 {
899 return FALSE;
900 }
901
902
903 static GdkDragAction
base_get_drop_actions(GthFileSource * file_source,GFile * destination,GFile * file)904 base_get_drop_actions (GthFileSource *file_source,
905 GFile *destination,
906 GFile *file)
907 {
908 return 0; /* no action supported by default. */
909 }
910
911
912 static void
gth_file_source_finalize(GObject * object)913 gth_file_source_finalize (GObject *object)
914 {
915 GthFileSource *file_source = GTH_FILE_SOURCE (object);
916
917 gth_file_source_clear_queue (file_source);
918 _g_string_list_free (file_source->priv->schemes);
919 _g_object_unref (file_source->priv->cancellable);
920
921 G_OBJECT_CLASS (gth_file_source_parent_class)->finalize (object);
922 }
923
924
925 static void
gth_file_source_class_init(GthFileSourceClass * class)926 gth_file_source_class_init (GthFileSourceClass *class)
927 {
928 GObjectClass *object_class;
929
930 object_class = (GObjectClass*) class;
931 object_class->finalize = gth_file_source_finalize;
932
933 class->get_entry_points = base_get_entry_points;
934 class->get_current_list = base_get_current_list;
935 class->to_gio_file = base_to_gio_file;
936 class->get_file_info = base_get_file_info;
937 class->get_file_data = base_get_file_data;
938 class->write_metadata = base_write_metadata;
939 class->read_metadata = base_read_metadata;
940 class->rename = base_rename;
941 class->can_cut = base_can_cut;
942 class->monitor_entry_points = base_monitor_entry_points;
943 class->monitor_directory = base_monitor_directory;
944 class->is_reorderable = base_is_reorderable;
945 class->reorder = base_reorder;
946 class->remove = base_remove;
947 class->deleted_from_disk = base_deleted_from_disk;
948 class->get_free_space = base_get_free_space;
949 class->shows_extra_widget = base_shows_extra_widget;
950 class->get_drop_actions = base_get_drop_actions;
951 }
952
953
954 static void
gth_file_source_init(GthFileSource * file_source)955 gth_file_source_init (GthFileSource *file_source)
956 {
957 file_source->priv = gth_file_source_get_instance_private (file_source);
958 file_source->priv->schemes = NULL;
959 file_source->priv->active = FALSE;
960 file_source->priv->queue = NULL;
961 file_source->priv->cancellable = g_cancellable_new ();
962 }
963
964
965 void
gth_file_source_add_scheme(GthFileSource * file_source,const char * scheme)966 gth_file_source_add_scheme (GthFileSource *file_source,
967 const char *scheme)
968 {
969 file_source->priv->schemes = g_list_prepend (file_source->priv->schemes, g_strdup (scheme));
970 }
971
972
973 gboolean
gth_file_source_supports_scheme(GthFileSource * file_source,const char * uri)974 gth_file_source_supports_scheme (GthFileSource *file_source,
975 const char *uri)
976 {
977 GList *scan;
978
979 for (scan = file_source->priv->schemes; scan; scan = scan->next) {
980 const char *scheme = scan->data;
981
982 if (g_str_has_prefix (uri, scheme))
983 return TRUE;
984 }
985
986 return FALSE;
987 }
988
989
990 void
gth_file_source_set_active(GthFileSource * file_source,gboolean active)991 gth_file_source_set_active (GthFileSource *file_source,
992 gboolean active)
993 {
994 file_source->priv->active = active;
995 if (! active)
996 gth_file_source_exec_next_in_queue (file_source);
997 }
998
999
1000 void
gth_file_source_set_cancellable(GthFileSource * file_source,GCancellable * cancellable)1001 gth_file_source_set_cancellable (GthFileSource *file_source,
1002 GCancellable *cancellable)
1003 {
1004 _g_object_unref (file_source->priv->cancellable);
1005 file_source->priv->cancellable = NULL;
1006 if (cancellable != NULL)
1007 file_source->priv->cancellable = g_object_ref (cancellable);
1008 }
1009
1010
1011 GList *
gth_file_source_get_entry_points(GthFileSource * file_source)1012 gth_file_source_get_entry_points (GthFileSource *file_source)
1013 {
1014 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_entry_points (file_source);
1015 }
1016
1017
1018 GList *
gth_file_source_get_current_list(GthFileSource * file_source,GFile * file)1019 gth_file_source_get_current_list (GthFileSource *file_source,
1020 GFile *file)
1021 {
1022 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_current_list (file_source, file);
1023 }
1024
1025
1026 GFile *
gth_file_source_to_gio_file(GthFileSource * file_source,GFile * file)1027 gth_file_source_to_gio_file (GthFileSource *file_source,
1028 GFile *file)
1029 {
1030 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->to_gio_file (file_source, file);
1031 }
1032
1033
1034 GList *
gth_file_source_to_gio_file_list(GthFileSource * file_source,GList * files)1035 gth_file_source_to_gio_file_list (GthFileSource *file_source,
1036 GList *files)
1037 {
1038 GList *gio_files = NULL;
1039 GList *scan;
1040
1041 for (scan = files; scan; scan = scan->next)
1042 gio_files = g_list_prepend (gio_files, gth_file_source_to_gio_file (file_source, (GFile *) scan->data));
1043
1044 return g_list_reverse (gio_files);
1045 }
1046
1047
1048 GFileInfo *
gth_file_source_get_file_info(GthFileSource * file_source,GFile * file,const char * attributes)1049 gth_file_source_get_file_info (GthFileSource *file_source,
1050 GFile *file,
1051 const char *attributes)
1052 {
1053 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_file_info (file_source, file, attributes);
1054 }
1055
1056
1057 GthFileData *
gth_file_source_get_file_data(GthFileSource * file_source,GFile * file,GFileInfo * info)1058 gth_file_source_get_file_data (GthFileSource *file_source,
1059 GFile *file,
1060 GFileInfo *info)
1061 {
1062 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_file_data (file_source, file, info);
1063 }
1064
1065
1066 gboolean
gth_file_source_is_active(GthFileSource * file_source)1067 gth_file_source_is_active (GthFileSource *file_source)
1068 {
1069 return file_source->priv->active;
1070 }
1071
1072
1073 GCancellable *
gth_file_source_get_cancellable(GthFileSource * file_source)1074 gth_file_source_get_cancellable (GthFileSource *file_source)
1075 {
1076 return file_source->priv->cancellable;
1077 }
1078
1079
1080 void
gth_file_source_cancel(GthFileSource * file_source)1081 gth_file_source_cancel (GthFileSource *file_source)
1082 {
1083 gth_file_source_clear_queue (file_source);
1084 g_cancellable_cancel (file_source->priv->cancellable);
1085 }
1086
1087
1088 void
gth_file_source_write_metadata(GthFileSource * file_source,GthFileData * file_data,const char * attributes,ReadyCallback callback,gpointer data)1089 gth_file_source_write_metadata (GthFileSource *file_source,
1090 GthFileData *file_data,
1091 const char *attributes,
1092 ReadyCallback callback,
1093 gpointer data)
1094 {
1095 if (gth_file_source_is_active (file_source)) {
1096 gth_file_source_queue_write_metadata (file_source, file_data, attributes, callback, data);
1097 return;
1098 }
1099 g_cancellable_reset (file_source->priv->cancellable);
1100 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->write_metadata (file_source, file_data, attributes, callback, data);
1101 }
1102
1103
1104 void
gth_file_source_read_metadata(GthFileSource * file_source,GthFileData * file_data,const char * attributes,ReadyCallback callback,gpointer data)1105 gth_file_source_read_metadata (GthFileSource *file_source,
1106 GthFileData *file_data,
1107 const char *attributes,
1108 ReadyCallback callback,
1109 gpointer data)
1110 {
1111 if (gth_file_source_is_active (file_source)) {
1112 gth_file_source_queue_read_metadata (file_source, file_data, attributes, callback, data);
1113 return;
1114 }
1115 g_cancellable_reset (file_source->priv->cancellable);
1116 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->read_metadata (file_source, file_data, attributes, callback, data);
1117 }
1118
1119
1120 /* -- gth_file_source_list -- */
1121
1122
1123 typedef struct {
1124 GthFileSource *file_source;
1125 ListReady ready_func;
1126 gpointer user_data;
1127 GList *files;
1128 } ListOpData;
1129
1130
1131 static void
list__done_func(GObject * source,GError * error,gpointer user_data)1132 list__done_func (GObject *source,
1133 GError *error,
1134 gpointer user_data)
1135 {
1136 ListOpData *data = user_data;
1137
1138 data->files = g_list_reverse (data->files);
1139 data->ready_func (data->file_source, data->files, error, data->user_data);
1140
1141 _g_object_list_unref (data->files);
1142 g_object_unref (data->file_source);
1143 g_free (data);
1144 }
1145
1146
1147 static void
list__for_each_file_func(GFile * file,GFileInfo * info,gpointer user_data)1148 list__for_each_file_func (GFile *file,
1149 GFileInfo *info,
1150 gpointer user_data)
1151 {
1152 ListOpData *data = user_data;
1153
1154 switch (g_file_info_get_file_type (info)) {
1155 case G_FILE_TYPE_REGULAR:
1156 case G_FILE_TYPE_DIRECTORY:
1157 data->files = g_list_prepend (data->files, gth_file_data_new (file, info));
1158 break;
1159 default:
1160 break;
1161 }
1162 }
1163
1164
1165 static DirOp
list__start_dir_func(GFile * directory,GFileInfo * info,GError ** error,gpointer user_data)1166 list__start_dir_func (GFile *directory,
1167 GFileInfo *info,
1168 GError **error,
1169 gpointer user_data)
1170 {
1171 return DIR_OP_CONTINUE;
1172 }
1173
1174
1175 void
gth_file_source_list(GthFileSource * file_source,GFile * folder,const char * attributes,ListReady func,gpointer user_data)1176 gth_file_source_list (GthFileSource *file_source,
1177 GFile *folder,
1178 const char *attributes,
1179 ListReady func,
1180 gpointer user_data)
1181 {
1182 ListOpData *data;
1183
1184 if (gth_file_source_is_active (file_source)) {
1185 gth_file_source_queue_list (file_source, folder, attributes, func, user_data);
1186 return;
1187 }
1188
1189 g_cancellable_reset (file_source->priv->cancellable);
1190
1191 data = g_new0 (ListOpData, 1);
1192 data->file_source = g_object_ref (file_source);
1193 data->ready_func = func;
1194 data->user_data = user_data;
1195
1196 gth_file_source_for_each_child (file_source,
1197 folder,
1198 FALSE,
1199 attributes,
1200 list__start_dir_func,
1201 list__for_each_file_func,
1202 list__done_func,
1203 data);
1204 }
1205
1206
1207 void
gth_file_source_for_each_child(GthFileSource * file_source,GFile * parent,gboolean recursive,const char * attributes,StartDirCallback dir_func,ForEachChildCallback child_func,ReadyCallback ready_func,gpointer data)1208 gth_file_source_for_each_child (GthFileSource *file_source,
1209 GFile *parent,
1210 gboolean recursive,
1211 const char *attributes,
1212 StartDirCallback dir_func,
1213 ForEachChildCallback child_func,
1214 ReadyCallback ready_func,
1215 gpointer data)
1216 {
1217 if (gth_file_source_is_active (file_source)) {
1218 gth_file_source_queue_for_each_child (file_source, parent, recursive, attributes, dir_func, child_func, ready_func, data);
1219 return;
1220 }
1221 g_cancellable_reset (file_source->priv->cancellable);
1222 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->for_each_child (file_source, parent, recursive, attributes, dir_func, child_func, ready_func, data);
1223 }
1224
1225
1226 /* -- gth_file_source_read_attributes -- */
1227
1228
1229 typedef struct {
1230 GthFileSource *file_source;
1231 ListReady ready_func;
1232 gpointer ready_data;
1233 } ReadAttributesOpData;
1234
1235
1236
1237 static void
read_attributes_op_data_free(ReadAttributesOpData * data)1238 read_attributes_op_data_free (ReadAttributesOpData *data)
1239 {
1240 g_object_unref (data->file_source);
1241 g_free (data);
1242 }
1243
1244
1245 static void
metadata_ready_cb(GList * files,GError * error,gpointer user_data)1246 metadata_ready_cb (GList *files,
1247 GError *error,
1248 gpointer user_data)
1249 {
1250 ReadAttributesOpData *data = user_data;
1251 GList *scan;
1252 GList *result_files;
1253
1254 gth_file_source_set_active (data->file_source, FALSE);
1255
1256 result_files = NULL;
1257 for (scan = files; scan; scan = scan->next) {
1258 GthFileData *file_data = scan->data;
1259 result_files = g_list_prepend (result_files, gth_file_source_get_file_data (data->file_source, file_data->file, file_data->info));
1260 }
1261 result_files = g_list_reverse (result_files);
1262
1263 data->ready_func (data->file_source,
1264 result_files,
1265 error,
1266 data->ready_data);
1267
1268 _g_object_list_unref (result_files);
1269 read_attributes_op_data_free (data);
1270 }
1271
1272
1273 void
gth_file_source_read_attributes(GthFileSource * file_source,GList * files,const char * attributes,ListReady func,gpointer user_data)1274 gth_file_source_read_attributes (GthFileSource *file_source,
1275 GList *files,
1276 const char *attributes,
1277 ListReady func,
1278 gpointer user_data)
1279 {
1280 ReadAttributesOpData *data;
1281 GList *gio_files;
1282
1283 if (gth_file_source_is_active (file_source)) {
1284 gth_file_source_queue_read_attributes (file_source, files, attributes, func, user_data);
1285 return;
1286 }
1287
1288 g_cancellable_reset (file_source->priv->cancellable);
1289
1290 data = g_new0 (ReadAttributesOpData, 1);
1291 data->file_source = g_object_ref (file_source);
1292 data->ready_func = func;
1293 data->ready_data = user_data;
1294
1295 gio_files = gth_file_source_to_gio_file_list (file_source, files);
1296 _g_query_all_metadata_async (gio_files,
1297 GTH_LIST_DEFAULT,
1298 attributes,
1299 file_source->priv->cancellable,
1300 metadata_ready_cb,
1301 data);
1302
1303 _g_object_list_unref (gio_files);
1304 }
1305
1306
1307 void
gth_file_source_rename(GthFileSource * file_source,GFile * file,const char * edit_name,ReadyCallback ready_callback,gpointer data)1308 gth_file_source_rename (GthFileSource *file_source,
1309 GFile *file,
1310 const char *edit_name,
1311 ReadyCallback ready_callback,
1312 gpointer data)
1313 {
1314 if (gth_file_source_is_active (file_source)) {
1315 gth_file_source_queue_rename (file_source, file, edit_name, ready_callback, data);
1316 return;
1317 }
1318 g_cancellable_reset (file_source->priv->cancellable);
1319 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->rename (file_source, file, edit_name, ready_callback, data);
1320 }
1321
1322
1323 void
gth_file_source_copy(GthFileSource * file_source,GthFileData * destination,GList * file_list,gboolean move,int destination_position,ProgressCallback progress_callback,DialogCallback dialog_callback,ReadyCallback ready_callback,gpointer data)1324 gth_file_source_copy (GthFileSource *file_source,
1325 GthFileData *destination,
1326 GList *file_list, /* GFile * list */
1327 gboolean move,
1328 int destination_position,
1329 ProgressCallback progress_callback,
1330 DialogCallback dialog_callback,
1331 ReadyCallback ready_callback,
1332 gpointer data)
1333 {
1334 if (gth_file_source_is_active (file_source)) {
1335 gth_file_source_queue_copy (file_source, destination, file_list, move, destination_position, progress_callback, dialog_callback, ready_callback, data);
1336 return;
1337 }
1338 g_cancellable_reset (file_source->priv->cancellable);
1339 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->copy (file_source, destination, file_list, move, destination_position, progress_callback, dialog_callback, ready_callback, data);
1340 }
1341
1342
1343 gboolean
gth_file_source_can_cut(GthFileSource * file_source)1344 gth_file_source_can_cut (GthFileSource *file_source)
1345 {
1346 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->can_cut (file_source);
1347 }
1348
1349
1350 void
gth_file_source_monitor_entry_points(GthFileSource * file_source)1351 gth_file_source_monitor_entry_points (GthFileSource *file_source)
1352 {
1353 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->monitor_entry_points (file_source);
1354 }
1355
1356
1357 void
gth_file_source_monitor_directory(GthFileSource * file_source,GFile * file,gboolean activate)1358 gth_file_source_monitor_directory (GthFileSource *file_source,
1359 GFile *file,
1360 gboolean activate)
1361 {
1362 g_return_if_fail (file != NULL);
1363
1364 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->monitor_directory (file_source, file, activate);
1365 }
1366
1367
1368 gboolean
gth_file_source_is_reorderable(GthFileSource * file_source)1369 gth_file_source_is_reorderable (GthFileSource *file_source)
1370 {
1371 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->is_reorderable (file_source);
1372 }
1373
1374
1375 void
gth_file_source_reorder(GthFileSource * file_source,GthFileData * destination,GList * visible_files,GList * files_to_move,int dest_pos,ReadyCallback callback,gpointer data)1376 gth_file_source_reorder (GthFileSource *file_source,
1377 GthFileData *destination,
1378 GList *visible_files, /* GFile list */
1379 GList *files_to_move, /* GFile list */
1380 int dest_pos,
1381 ReadyCallback callback,
1382 gpointer data)
1383 {
1384 if (gth_file_source_is_active (file_source)) {
1385 gth_file_source_queue_reorder (file_source, destination, visible_files, files_to_move, dest_pos, callback, data);
1386 return;
1387 }
1388 g_cancellable_reset (file_source->priv->cancellable);
1389 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->reorder (file_source, destination, visible_files, files_to_move, dest_pos, callback, data);
1390 }
1391
1392
1393 void
gth_file_source_remove(GthFileSource * file_source,GthFileData * location,GList * file_list,gboolean permanently,GtkWindow * parent)1394 gth_file_source_remove (GthFileSource *file_source,
1395 GthFileData *location,
1396 GList *file_list, /* GthFileData list */
1397 gboolean permanently,
1398 GtkWindow *parent)
1399 {
1400 if (gth_file_source_is_active (file_source)) {
1401 gth_file_source_queue_remove (file_source, location, file_list, permanently, parent);
1402 return;
1403 }
1404 g_cancellable_reset (file_source->priv->cancellable);
1405 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->remove (file_source, location, file_list, permanently, parent);
1406 }
1407
1408
1409 void
gth_file_source_deleted_from_disk(GthFileSource * file_source,GthFileData * location,GList * file_list)1410 gth_file_source_deleted_from_disk (GthFileSource *file_source,
1411 GthFileData *location,
1412 GList *file_list /* GFile list */)
1413 {
1414 if (gth_file_source_is_active (file_source)) {
1415 gth_file_source_queue_deleted_from_disk (file_source, location, file_list);
1416 return;
1417 }
1418 g_cancellable_reset (file_source->priv->cancellable);
1419 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->deleted_from_disk (file_source, location, file_list);
1420 }
1421
1422
1423 void
gth_file_source_get_free_space(GthFileSource * file_source,GFile * location,SpaceReadyCallback callback,gpointer data)1424 gth_file_source_get_free_space (GthFileSource *file_source,
1425 GFile *location,
1426 SpaceReadyCallback callback,
1427 gpointer data)
1428 {
1429 g_return_if_fail (location != NULL);
1430 g_return_if_fail (callback != NULL);
1431
1432 if (gth_file_source_is_active (file_source)) {
1433 gth_file_source_queue_get_free_space (file_source, location, callback, data);
1434 return;
1435 }
1436 g_cancellable_reset (file_source->priv->cancellable);
1437 GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_free_space (file_source, location, callback, data);
1438 }
1439
1440
1441 gboolean
gth_file_source_shows_extra_widget(GthFileSource * file_source)1442 gth_file_source_shows_extra_widget (GthFileSource *file_source)
1443 {
1444 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->shows_extra_widget (file_source);
1445 }
1446
1447
1448 GdkDragAction
gth_file_source_get_drop_actions(GthFileSource * file_source,GFile * destination,GFile * file)1449 gth_file_source_get_drop_actions (GthFileSource *file_source,
1450 GFile *destination,
1451 GFile *file)
1452 {
1453 return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_drop_actions (file_source, destination, file);
1454 }
1455