source: trunk/third/evolution/shell/e-storage-set.c @ 18142

Revision 18142, 21.8 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18141, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* e-storage-set.c
3 *
4 * Copyright (C) 2000  Ximian, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Ettore Perazzoli
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include "e-storage-set.h"
28
29#include "e-storage-set-view.h"
30#include "e-shell-constants.h"
31
32#include <glib.h>
33#include <gtk/gtkobject.h>
34#include <gtk/gtksignal.h>
35#include <gtk/gtktypeutils.h>
36
37#include <gal/util/e-util.h>
38
39#include <string.h>
40
41
42#define PARENT_TYPE GTK_TYPE_OBJECT
43
44static GtkObjectClass *parent_class = NULL;
45
46/* This is just to make GHashTable happy.  */
47struct _NamedStorage {
48        char *name;
49        EStorage *storage;
50};
51typedef struct _NamedStorage NamedStorage;
52
53struct _EStorageSetPrivate {
54        GList *storages;        /* EStorage */
55        GHashTable *name_to_named_storage;
56
57        EFolderTypeRegistry *folder_type_registry;
58};
59
60enum {
61        NEW_STORAGE,
62        REMOVED_STORAGE,
63        NEW_FOLDER,
64        UPDATED_FOLDER,
65        REMOVED_FOLDER,
66        MOVED_FOLDER,
67        CLOSE_FOLDER,
68        LAST_SIGNAL
69};
70
71static guint signals[LAST_SIGNAL] = { 0 };
72
73
74static NamedStorage *
75named_storage_new (EStorage *storage)
76{
77        NamedStorage *new;
78
79        new = g_new (NamedStorage, 1);
80        new->name    = g_strdup (e_storage_get_name (storage));
81        new->storage = storage;
82
83        return new;
84}
85
86static void
87named_storage_destroy (NamedStorage *named_storage)
88{
89        g_free (named_storage->name);
90        g_free (named_storage);
91}
92
93static gboolean
94name_to_named_storage_foreach_destroy (void *key,
95                                       void *value,
96                                       void *user_data)
97{
98        NamedStorage *named_storage;
99
100        named_storage = (NamedStorage *) value;
101        named_storage_destroy (named_storage);
102
103        return TRUE;
104}
105
106
107/* "Callback converter", from `EStorageResultCallback' to
108   `EStorageSetResultCallback'.  */
109
110enum _StorageOperation {
111        OPERATION_COPY,
112        OPERATION_MOVE,
113        OPERATION_REMOVE,
114        OPERATION_CREATE
115};
116typedef enum _StorageOperation StorageOperation;
117
118struct _StorageCallbackData {
119        EStorageSet *storage_set;
120        EStorageSetResultCallback storage_set_result_callback;
121        char *source_path;
122        char *destination_path;
123        StorageOperation operation;
124        void *data;
125};
126typedef struct _StorageCallbackData StorageCallbackData;
127
128static StorageCallbackData *
129storage_callback_data_new (EStorageSet *storage_set,
130                           EStorageSetResultCallback callback,
131                           const char *source_path,
132                           const char *destination_path,
133                           StorageOperation operation,
134                           void *data)
135{
136        StorageCallbackData *new;
137
138        new = g_new (StorageCallbackData, 1);
139        new->storage_set                 = storage_set;
140        new->storage_set_result_callback = callback;
141        new->source_path                 = g_strdup (source_path);
142        new->destination_path            = g_strdup (destination_path);
143        new->operation                   = operation;
144        new->data                        = data;
145
146        return new;
147}
148
149static void
150storage_callback_data_free (StorageCallbackData *data)
151{
152        g_free (data->source_path);
153        g_free (data->destination_path);
154
155        g_free (data);
156}
157
158static void
159storage_callback (EStorage *storage,
160                  EStorageResult result,
161                  void *data)
162{
163        StorageCallbackData *storage_callback_data;
164
165        storage_callback_data = (StorageCallbackData *) data;
166
167        (* storage_callback_data->storage_set_result_callback) (storage_callback_data->storage_set,
168                                                                result,
169                                                                storage_callback_data->data);
170
171        if (storage_callback_data->operation == OPERATION_MOVE)
172                gtk_signal_emit (GTK_OBJECT (storage_callback_data->storage_set),
173                                 signals[MOVED_FOLDER],
174                                 storage_callback_data->source_path,
175                                 storage_callback_data->destination_path);
176
177        storage_callback_data_free (storage_callback_data);
178}
179
180
181/* Handling for signals coming from the EStorages.  */
182
183static char *
184make_full_path (EStorage *storage,
185                const char *path)
186{
187        const char *storage_name;
188        char *full_path;
189
190        storage_name = e_storage_get_name (storage);
191
192        if (strcmp (path, E_PATH_SEPARATOR_S) == 0)
193                full_path = g_strconcat (E_PATH_SEPARATOR_S, storage_name,
194                                         NULL);
195        else if (! g_path_is_absolute (path))
196                full_path = g_strconcat (E_PATH_SEPARATOR_S, storage_name,
197                                         E_PATH_SEPARATOR_S, path, NULL);
198        else
199                full_path = g_strconcat (E_PATH_SEPARATOR_S, storage_name,
200                                         path, NULL);
201
202        return full_path;
203}
204
205static void
206storage_new_folder_cb (EStorage *storage,
207                       const char *path,
208                       void *data)
209{
210        EStorageSet *storage_set;
211        char *full_path;
212
213        storage_set = E_STORAGE_SET (data);
214
215        full_path = make_full_path (storage, path);
216        gtk_signal_emit (GTK_OBJECT (storage_set), signals[NEW_FOLDER], full_path);
217        g_free (full_path);
218}
219
220static void
221storage_updated_folder_cb (EStorage *storage,
222                           const char *path,
223                           void *data)
224{
225        EStorageSet *storage_set;
226        char *full_path;
227
228        storage_set = E_STORAGE_SET (data);
229
230        full_path = make_full_path (storage, path);
231        gtk_signal_emit (GTK_OBJECT (storage_set), signals[UPDATED_FOLDER], full_path);
232        g_free (full_path);
233}
234
235static void
236storage_removed_folder_cb (EStorage *storage,
237                           const char *path,
238                           void *data)
239{
240        EStorageSet *storage_set;
241        char *full_path;
242
243        storage_set = E_STORAGE_SET (data);
244
245        full_path = make_full_path (storage, path);
246        gtk_signal_emit (GTK_OBJECT (storage_set), signals[REMOVED_FOLDER], full_path);
247        g_free (full_path);
248}
249
250static void
251storage_close_folder_cb (EStorage *storage,
252                         const char *path,
253                         void *data)
254{
255        EStorageSet *storage_set;
256        char *full_path;
257
258        storage_set = E_STORAGE_SET (data);
259
260        full_path = make_full_path (storage, path);
261        gtk_signal_emit (GTK_OBJECT (storage_set), signals[CLOSE_FOLDER], full_path);
262        g_free (full_path);
263}
264
265
266static EStorage *
267get_storage_for_path (EStorageSet *storage_set,
268                      const char *path,
269                      const char **subpath_return)
270{
271        EStorage *storage;
272        char *storage_name;
273        const char *first_separator;
274
275        g_return_val_if_fail (g_path_is_absolute (path), NULL);
276        g_return_val_if_fail (path[1] != E_PATH_SEPARATOR, NULL);
277
278        /* Skip initial separator.  */
279        path++;
280
281        first_separator = strchr (path, E_PATH_SEPARATOR);
282
283        if (first_separator == NULL || first_separator[1] == 0) {
284                storage = e_storage_set_get_storage (storage_set, path);
285                *subpath_return = E_PATH_SEPARATOR_S;
286        } else {
287                storage_name = g_strndup (path, first_separator - path);
288                storage = e_storage_set_get_storage (storage_set, storage_name);
289                g_free (storage_name);
290
291                *subpath_return = first_separator;
292        }
293
294        return storage;
295}
296
297static void
298signal_new_folder_for_all_folders_under_paths (EStorageSet *storage_set,
299                                               EStorage *storage,
300                                               GList *path_list)
301{
302        GList *p;
303
304        for (p = path_list; p != NULL; p = p->next) {
305                GList *sub_path_list;
306                const char *path;
307                char *path_with_storage;
308
309                path = (const char *) p->data;
310
311                path_with_storage = g_strconcat (E_PATH_SEPARATOR_S, e_storage_get_name (storage), path, NULL);
312                gtk_signal_emit (GTK_OBJECT (storage_set), signals[NEW_FOLDER], path_with_storage);
313                g_free (path_with_storage);
314
315                sub_path_list = e_storage_get_subfolder_paths (storage, path);
316
317                signal_new_folder_for_all_folders_under_paths (storage_set, storage, sub_path_list);
318
319                e_free_string_list (sub_path_list);
320        }
321}
322
323static void
324signal_new_folder_for_all_folders_in_storage (EStorageSet *storage_set,
325                                              EStorage *storage)
326{
327        GList *path_list;
328
329        path_list = e_storage_get_subfolder_paths (storage, E_PATH_SEPARATOR_S);
330
331        signal_new_folder_for_all_folders_under_paths (storage_set, storage, path_list);
332
333        e_free_string_list (path_list);
334}
335
336
337/* GtkObject methods.  */
338
339static void
340destroy (GtkObject *object)
341{
342        EStorageSet *storage_set;
343        EStorageSetPrivate *priv;
344
345        storage_set = E_STORAGE_SET (object);
346        priv = storage_set->priv;
347
348        e_free_object_list (priv->storages);
349
350        gtk_object_unref (GTK_OBJECT (priv->folder_type_registry));
351
352        g_hash_table_foreach (priv->name_to_named_storage,
353                              (GHFunc) name_to_named_storage_foreach_destroy, NULL);
354        g_hash_table_destroy (priv->name_to_named_storage);
355
356        g_free (priv);
357
358        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
359}
360
361
362static void
363class_init (EStorageSetClass *klass)
364{
365        GtkObjectClass *object_class;
366
367        parent_class = gtk_type_class (gtk_object_get_type ());
368        object_class = GTK_OBJECT_CLASS (klass);
369
370        object_class->destroy = destroy;
371
372        signals[NEW_STORAGE] =
373                gtk_signal_new ("new_storage",
374                                GTK_RUN_FIRST,
375                                object_class->type,
376                                GTK_SIGNAL_OFFSET (EStorageSetClass, new_storage),
377                                gtk_marshal_NONE__POINTER,
378                                GTK_TYPE_NONE, 1,
379                                GTK_TYPE_POINTER);
380        signals[REMOVED_STORAGE] =
381                gtk_signal_new ("removed_storage",
382                                GTK_RUN_FIRST,
383                                object_class->type,
384                                GTK_SIGNAL_OFFSET (EStorageSetClass, removed_storage),
385                                gtk_marshal_NONE__POINTER,
386                                GTK_TYPE_NONE, 1,
387                                GTK_TYPE_POINTER);
388        signals[NEW_FOLDER] =
389                gtk_signal_new ("new_folder",
390                                GTK_RUN_FIRST,
391                                object_class->type,
392                                GTK_SIGNAL_OFFSET (EStorageSetClass, new_folder),
393                                gtk_marshal_NONE__STRING,
394                                GTK_TYPE_NONE, 1,
395                                GTK_TYPE_STRING);
396        signals[UPDATED_FOLDER] =
397                gtk_signal_new ("updated_folder",
398                                GTK_RUN_FIRST,
399                                object_class->type,
400                                GTK_SIGNAL_OFFSET (EStorageSetClass, updated_folder),
401                                gtk_marshal_NONE__STRING,
402                                GTK_TYPE_NONE, 1,
403                                GTK_TYPE_STRING);
404        signals[REMOVED_FOLDER] =
405                gtk_signal_new ("removed_folder",
406                                GTK_RUN_FIRST,
407                                object_class->type,
408                                GTK_SIGNAL_OFFSET (EStorageSetClass, removed_folder),
409                                gtk_marshal_NONE__STRING,
410                                GTK_TYPE_NONE, 1,
411                                GTK_TYPE_STRING);
412        signals[MOVED_FOLDER] =
413                gtk_signal_new ("moved_folder",
414                                GTK_RUN_FIRST,
415                                object_class->type,
416                                GTK_SIGNAL_OFFSET (EStorageSetClass, moved_folder),
417                                gtk_marshal_NONE__POINTER_POINTER,
418                                GTK_TYPE_NONE, 2,
419                                GTK_TYPE_STRING,
420                                GTK_TYPE_STRING);
421        signals[CLOSE_FOLDER] =
422                gtk_signal_new ("close_folder",
423                                GTK_RUN_FIRST,
424                                object_class->type,
425                                GTK_SIGNAL_OFFSET (EStorageSetClass, close_folder),
426                                gtk_marshal_NONE__STRING,
427                                GTK_TYPE_NONE, 1,
428                                GTK_TYPE_STRING);
429
430        gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
431}
432
433static void
434init (EStorageSet *storage_set)
435{
436        EStorageSetPrivate *priv;
437
438        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
439
440        priv = g_new (EStorageSetPrivate, 1);
441        priv->storages              = NULL;
442        priv->name_to_named_storage = g_hash_table_new (g_str_hash, g_str_equal);
443        priv->folder_type_registry  = NULL;
444
445        storage_set->priv = priv;
446}
447
448
449void
450e_storage_set_construct (EStorageSet *storage_set,
451                         EFolderTypeRegistry *folder_type_registry)
452{
453        g_return_if_fail (storage_set != NULL);
454        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
455
456        GTK_OBJECT_UNSET_FLAGS (storage_set, GTK_FLOATING);
457
458        gtk_object_ref (GTK_OBJECT (folder_type_registry));
459        storage_set->priv->folder_type_registry = folder_type_registry;
460}
461
462EStorageSet *
463e_storage_set_new (EFolderTypeRegistry *folder_type_registry)
464{
465        EStorageSet *new;
466
467        new = gtk_type_new (e_storage_set_get_type ());
468
469        e_storage_set_construct (new, folder_type_registry);
470
471        return new;
472}
473
474
475GList *
476e_storage_set_get_storage_list (EStorageSet *storage_set)
477{
478        EStorageSetPrivate *priv;
479        GList *list;
480        GList *p;
481
482        g_return_val_if_fail (storage_set != NULL, NULL);
483        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
484
485        priv = storage_set->priv;
486
487        list = NULL;
488        for (p = priv->storages; p != NULL; p = p->next) {
489                gtk_object_ref (GTK_OBJECT (p->data));
490                list = g_list_prepend (list, p->data);
491        }
492
493        return g_list_reverse (list); /* Lame.  */
494}
495
496/**
497 * e_storage_set_add_storage:
498 * @storage_set:
499 * @storage:
500 *
501 * Add @storage to @storage_set.  Notice that will ref the storage.
502 **/
503gboolean
504e_storage_set_add_storage (EStorageSet *storage_set,
505                           EStorage *storage)
506{
507        EStorageSetPrivate *priv;
508        const char *storage_name;
509        NamedStorage *named_storage;
510
511        g_return_val_if_fail (storage_set != NULL, FALSE);
512        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), FALSE);
513        g_return_val_if_fail (storage != NULL, FALSE);
514        g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
515
516        priv = storage_set->priv;
517
518        storage_name = e_storage_get_name (storage);
519        if (g_hash_table_lookup (priv->name_to_named_storage, storage_name) != NULL)
520                return FALSE;
521
522        gtk_object_ref (GTK_OBJECT (storage));
523
524        gtk_signal_connect (GTK_OBJECT (storage), "new_folder",
525                            GTK_SIGNAL_FUNC (storage_new_folder_cb), storage_set);
526        gtk_signal_connect (GTK_OBJECT (storage), "updated_folder",
527                            GTK_SIGNAL_FUNC (storage_updated_folder_cb), storage_set);
528        gtk_signal_connect (GTK_OBJECT (storage), "removed_folder",
529                            GTK_SIGNAL_FUNC (storage_removed_folder_cb), storage_set);
530        gtk_signal_connect (GTK_OBJECT (storage), "close_folder",
531                            GTK_SIGNAL_FUNC (storage_close_folder_cb), storage_set);
532
533        priv->storages = g_list_append (priv->storages, storage);
534
535        named_storage = named_storage_new (storage);
536        g_hash_table_insert (priv->name_to_named_storage, named_storage->name, named_storage);
537
538        gtk_signal_emit (GTK_OBJECT (storage_set), signals[NEW_STORAGE], storage);
539
540        signal_new_folder_for_all_folders_in_storage (storage_set, storage);
541
542        return TRUE;
543}
544
545gboolean
546e_storage_set_remove_storage (EStorageSet *storage_set,
547                              EStorage *storage)
548{
549        EStorageSetPrivate *priv;
550        NamedStorage *named_storage;
551
552        g_return_val_if_fail (storage_set != NULL, FALSE);
553        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), FALSE);
554        g_return_val_if_fail (storage != NULL, FALSE);
555        g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
556
557        priv = storage_set->priv;
558
559        named_storage = g_hash_table_lookup (priv->name_to_named_storage,
560                                             e_storage_get_name (storage));
561        if (named_storage == NULL)
562                return FALSE;
563
564        g_hash_table_remove (priv->name_to_named_storage, named_storage->name);
565        named_storage_destroy (named_storage);
566
567        priv->storages = g_list_remove (priv->storages, storage);
568
569        gtk_signal_emit (GTK_OBJECT (storage_set), signals[REMOVED_STORAGE], storage);
570        gtk_object_unref (GTK_OBJECT (storage));
571
572        return TRUE;
573}
574
575void
576e_storage_set_remove_all_storages (EStorageSet *storage_set)
577{
578        EStorageSetPrivate *priv;
579        GList *p;
580
581        g_return_if_fail (storage_set != NULL);
582        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
583
584        priv = storage_set->priv;
585
586        for (p = priv->storages; p != NULL; p = p->next) {
587                EStorage *storage;
588
589                storage = E_STORAGE (p->data);
590
591                gtk_signal_emit (GTK_OBJECT (storage_set), signals[REMOVED_STORAGE], storage);
592                gtk_object_unref (GTK_OBJECT (storage));
593        }
594
595        g_hash_table_foreach_remove (priv->name_to_named_storage,
596                                     name_to_named_storage_foreach_destroy,
597                                     NULL);
598
599        g_list_free (priv->storages);
600        priv->storages = NULL;
601}
602
603
604EStorage *
605e_storage_set_get_storage (EStorageSet *storage_set,
606                           const char *name)
607{
608        EStorageSetPrivate *priv;
609        NamedStorage *named_storage;
610
611        g_return_val_if_fail (storage_set != NULL, NULL);
612        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
613        g_return_val_if_fail (name != NULL, NULL);
614
615        priv = storage_set->priv;
616
617        named_storage = g_hash_table_lookup (priv->name_to_named_storage, name);
618        if (named_storage == NULL)
619                return NULL;
620        else
621                return named_storage->storage;
622}
623
624EFolder *
625e_storage_set_get_folder (EStorageSet *storage_set,
626                          const char *path)
627{
628        EStorage *storage;
629        const char *subpath;
630
631        g_return_val_if_fail (storage_set != NULL, NULL);
632        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
633        g_return_val_if_fail (path != NULL, NULL);
634        g_return_val_if_fail (g_path_is_absolute (path), NULL);
635
636        storage = get_storage_for_path (storage_set, path, &subpath);
637        if (storage == NULL)
638                return NULL;
639
640        return e_storage_get_folder (storage, subpath);
641}
642
643
644static void
645storage_set_view_folder_opened (EStorageSetView *storage_set_view,
646                                const char *path,
647                                EStorageSet *storage_set)
648{
649        EStorage *storage;
650        const char *subpath;
651
652        storage = get_storage_for_path (storage_set, path, &subpath);
653        if (storage == NULL)
654                return;
655
656        e_storage_async_open_folder (storage, subpath);
657}
658
659GtkWidget *
660e_storage_set_create_new_view (EStorageSet *storage_set,
661                               BonoboUIContainer *ui_container)
662{
663        GtkWidget *storage_set_view;
664
665        g_return_val_if_fail (storage_set != NULL, NULL);
666        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
667
668        storage_set_view = e_storage_set_view_new (storage_set, ui_container);
669        gtk_signal_connect (GTK_OBJECT (storage_set_view), "folder_opened",
670                            GTK_SIGNAL_FUNC (storage_set_view_folder_opened),
671                            storage_set);
672
673        return storage_set_view;
674}
675
676
677void
678e_storage_set_async_create_folder  (EStorageSet *storage_set,
679                                    const char *path,
680                                    const char *type,
681                                    const char *description,
682                                    EStorageSetResultCallback callback,
683                                    void *data)
684{
685        EStorage *storage;
686        const char *subpath;
687        StorageCallbackData *storage_callback_data;
688
689        g_return_if_fail (storage_set != NULL);
690        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
691        g_return_if_fail (path != NULL);
692        g_return_if_fail (g_path_is_absolute (path));
693        g_return_if_fail (type != NULL);
694        g_return_if_fail (description != NULL);
695        g_return_if_fail (callback != NULL);
696
697        storage = get_storage_for_path (storage_set, path, &subpath);
698
699        storage_callback_data = storage_callback_data_new (storage_set, callback,
700                                                           path, NULL, OPERATION_CREATE,
701                                                           data);
702
703        e_storage_async_create_folder (storage, subpath, type, description,
704                                       storage_callback, storage_callback_data);
705}
706
707void
708e_storage_set_async_remove_folder  (EStorageSet *storage_set,
709                                    const char *path,
710                                    EStorageSetResultCallback callback,
711                                    void *data)
712{
713        EStorage *storage;
714        const char *subpath;
715        StorageCallbackData *storage_callback_data;
716
717        g_return_if_fail (storage_set != NULL);
718        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
719        g_return_if_fail (path != NULL);
720        g_return_if_fail (g_path_is_absolute (path));
721        g_return_if_fail (callback != NULL);
722
723        storage = get_storage_for_path (storage_set, path, &subpath);
724
725        storage_callback_data = storage_callback_data_new (storage_set, callback,
726                                                           path, NULL, OPERATION_REMOVE,
727                                                           data);
728
729        e_storage_async_remove_folder (storage, subpath,
730                                       storage_callback, storage_callback_data);
731}
732
733void
734e_storage_set_async_xfer_folder (EStorageSet *storage_set,
735                                 const char *source_path,
736                                 const char *destination_path,
737                                 gboolean remove_source,
738                                 EStorageSetResultCallback callback,
739                                 void *data)
740{
741        EStorage *source_storage;
742        EStorage *destination_storage;
743        const char *source_subpath;
744        const char *destination_subpath;
745        StorageCallbackData *storage_callback_data;
746
747        g_return_if_fail (storage_set != NULL);
748        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
749        g_return_if_fail (source_path != NULL);
750        g_return_if_fail (g_path_is_absolute (source_path));
751        g_return_if_fail (destination_path != NULL);
752        g_return_if_fail (g_path_is_absolute (destination_path));
753        g_return_if_fail (callback != NULL);
754
755        source_storage = get_storage_for_path (storage_set, source_path, &source_subpath);
756        destination_storage = get_storage_for_path (storage_set, destination_path, &destination_subpath);
757
758        if (source_storage != destination_storage) {
759                g_warning ("e_storage_set_async_xfer_folder(): "
760                           "Attempt to xfer folders between different storages -- not supported yet.");
761                (* callback) (storage_set, E_STORAGE_UNSUPPORTEDOPERATION, data);
762                return;
763        }
764
765        storage_callback_data = storage_callback_data_new (storage_set,
766                                                           callback,
767                                                           source_path,
768                                                           destination_path,
769                                                           remove_source ? OPERATION_MOVE : OPERATION_COPY,
770                                                           data);
771
772        e_storage_async_xfer_folder (source_storage,
773                                     source_subpath, destination_subpath, remove_source,
774                                     storage_callback, storage_callback_data);
775}
776
777void
778e_storage_set_async_remove_shared_folder (EStorageSet *storage_set,
779                                          const char *path,
780                                          EStorageSetResultCallback callback,
781                                          void *data)
782{
783        EStorage *storage;
784        const char *subpath;
785        StorageCallbackData *storage_callback_data;
786
787        g_return_if_fail (storage_set != NULL);
788        g_return_if_fail (E_IS_STORAGE_SET (storage_set));
789        g_return_if_fail (path != NULL);
790        g_return_if_fail (g_path_is_absolute (path));
791        g_return_if_fail (callback != NULL);
792
793        storage = get_storage_for_path (storage_set, path, &subpath);
794
795        if (!e_storage_supports_shared_folders (storage)) {
796                (* callback) (storage_set, E_STORAGE_NOTIMPLEMENTED, data);
797                return;
798        }
799
800        storage_callback_data = storage_callback_data_new (storage_set, callback,
801                                                           path, NULL, OPERATION_REMOVE,
802                                                           data);
803
804        e_storage_async_remove_shared_folder (storage, subpath,
805                                              storage_callback,
806                                              storage_callback_data);
807}
808
809
810EFolderTypeRegistry *
811e_storage_set_get_folder_type_registry (EStorageSet *storage_set)
812{
813        g_return_val_if_fail (storage_set != NULL, NULL);
814        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
815
816        return storage_set->priv->folder_type_registry;
817}
818
819
820/**
821 * e_storage_set_get_path_for_physical_uri:
822 * @storage_set: A storage set
823 * @physical_uri: A physical URI
824 *
825 * Retrieve the path of the folder whose physical URI matches @physical_uri.
826 *
827 * Return value:
828 **/
829char *
830e_storage_set_get_path_for_physical_uri (EStorageSet *storage_set,
831                                         const char *physical_uri)
832{
833        EStorageSetPrivate *priv;
834        GList *p;
835
836        g_return_val_if_fail (storage_set != NULL, NULL);
837        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
838        g_return_val_if_fail (physical_uri != NULL, NULL);
839
840        priv = storage_set->priv;
841
842        for (p = priv->storages; p != NULL; p = p->next) {
843                EStorage *storage;
844                char *storage_path;
845
846                storage = E_STORAGE (p->data);
847
848                storage_path = e_storage_get_path_for_physical_uri (storage, physical_uri);
849                if (storage_path != NULL) {
850                        char *storage_set_path;
851
852                        storage_set_path = g_strconcat (E_PATH_SEPARATOR_S,
853                                                        e_storage_get_name (storage),
854                                                        storage_path,
855                                                        NULL);
856                        g_free (storage_path);
857
858                        return storage_set_path;
859                }
860        }
861
862        return NULL;
863}
864
865
866E_MAKE_TYPE (e_storage_set, "EStorageSet", EStorageSet, class_init, init, PARENT_TYPE)
Note: See TracBrowser for help on using the repository browser.