1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3
/* Copyright (C) 2002-2004 Novell, Inc.
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of version 2 of the GNU Lesser General Public
7
* License as published by the Free Software Foundation.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this program; if not, write to the
16
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
* Boston, MA 02110-1301, USA.
29
#include <sys/types.h>
31
#include <libxml/parser.h>
32
#include <libxml/tree.h>
33
#include <libxml/xmlmemory.h>
36
#include <glib/gstdio.h>
38
#include "libedataserver/e-source-list.h"
39
#include "libedataserver/e-data-server-util.h"
40
#include "libedataserver/e-xml-utils.h"
42
#include "e-folder-exchange.h"
45
#include "exchange-account.h"
46
#include "exchange-esource.h"
47
#include "exchange-hierarchy.h"
51
struct _EFolderExchangePrivate {
52
ExchangeHierarchy *hier;
53
gchar *internal_uri, *permanent_uri;
54
gchar *outlook_class, *storage_dir;
57
gboolean has_subfolders;
61
#define PARENT_TYPE E_TYPE_FOLDER
62
static EFolderClass *parent_class = NULL;
64
#define EF_CLASS(hier) (E_FOLDER_CLASS (G_OBJECT_GET_CLASS (hier)))
66
static void dispose (GObject *object);
67
static void finalize (GObject *object);
70
class_init (GObjectClass *object_class)
72
parent_class = g_type_class_ref (PARENT_TYPE);
75
object_class->dispose = dispose;
76
object_class->finalize = finalize;
80
init (GObject *object)
82
EFolderExchange *folder = E_FOLDER_EXCHANGE (object);
84
folder->priv = g_new0 (EFolderExchangePrivate, 1);
85
folder->priv->rescan_tree = TRUE;
89
dispose (GObject *object)
91
EFolderExchange *folder = E_FOLDER_EXCHANGE (object);
93
if (folder->priv->hier) {
94
g_object_unref (folder->priv->hier);
95
folder->priv->hier = NULL;
98
G_OBJECT_CLASS (parent_class)->dispose (object);
102
finalize (GObject *object)
104
EFolderExchange *folder = E_FOLDER_EXCHANGE (object);
106
g_free (folder->priv->internal_uri);
107
g_free (folder->priv->permanent_uri);
108
g_free (folder->priv->outlook_class);
109
g_free (folder->priv->storage_dir);
110
g_free (folder->priv->path);
111
g_free (folder->priv);
113
G_OBJECT_CLASS (parent_class)->finalize (object);
116
E2K_MAKE_TYPE (e_folder_exchange, EFolderExchange, class_init, init, PARENT_TYPE)
119
sanitize_path (const gchar *path)
122
gchar *new_path = NULL;
125
return g_strdup(""); /* ??? or NULL? */
127
comps = g_strsplit (path, ";", 2);
129
new_path = g_strdup_printf ("%s%s", comps[0], comps[1]);
131
new_path = g_strdup (comps[0]);
140
* e_folder_exchange_new:
141
* @hier: the #ExchangeHierarchy containing the new folder
142
* @name: the display name of the folder
143
* @type: the Evolution type of the folder (eg, "mail")
144
* @outlook_class: the Outlook IPM class of the folder (eg, "IPM.Note")
145
* @physical_uri: the "exchange:" URI of the folder
146
* @internal_uri: the "http:" URI of the folder
148
* Return value: a new #EFolderExchange
151
e_folder_exchange_new (ExchangeHierarchy *hier, const gchar *name,
152
const gchar *type, const gchar *outlook_class,
153
const gchar *physical_uri, const gchar *internal_uri)
155
EFolderExchange *efe;
157
gchar *sanitized_path;
159
g_return_val_if_fail (EXCHANGE_IS_HIERARCHY (hier), NULL);
160
g_return_val_if_fail (name != NULL, NULL);
161
g_return_val_if_fail (type != NULL, NULL);
162
g_return_val_if_fail (physical_uri != NULL, NULL);
163
g_return_val_if_fail (internal_uri != NULL, NULL);
165
d(g_print ("e_folder_exchange_new: name=[%s], type=[%s], internal_uri=[%s], physical_uri=[%s]\n",
166
name, type, internal_uri, physical_uri));
168
efe = g_object_new (E_TYPE_FOLDER_EXCHANGE, NULL);
171
e_folder_construct (ef, name, type, "");
173
efe->priv->hier = hier;
176
efe->priv->internal_uri = g_strdup (internal_uri);
177
e_folder_set_physical_uri (ef, physical_uri);
179
sanitized_path = sanitize_path (e2k_uri_path (physical_uri));
180
e2k_uri_decode (sanitized_path);
181
efe->priv->path = sanitized_path;
182
d(g_print ("e_folder_exchange_new: sanitized=[%s]\n", sanitized_path));
184
efe->priv->outlook_class = g_strdup (outlook_class);
187
if (hier->type == EXCHANGE_HIERARCHY_PERSONAL ||
188
hier->type == EXCHANGE_HIERARCHY_FAVORITES) {
190
if ((strcmp (type, "calendar") == 0) ||
191
(strcmp (type, "calendar/public") == 0)) {
192
add_folder_esource (hier->account,
193
EXCHANGE_CALENDAR_FOLDER,
197
else if ((strcmp (type, "tasks") == 0) ||
198
(strcmp (type, "tasks/public") == 0)) {
199
add_folder_esource (hier->account,
200
EXCHANGE_TASKS_FOLDER,
204
else if ((strcmp (type, "contacts") == 0) ||
205
(strcmp (type, "contacts/public") == 0)) {
206
add_folder_esource (hier->account,
207
EXCHANGE_CONTACTS_FOLDER,
216
* e_folder_exchange_get_internal_uri:
217
* @folder: an #EFolderExchange
219
* Returns the folder's internal (http/https) URI. The caller
220
* should not cache this value, since it may change if the server
221
* sends a redirect when we try to use it.
223
* Return value: @folder's internal (http/https) URI
226
e_folder_exchange_get_internal_uri (EFolder *folder)
228
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
230
return E_FOLDER_EXCHANGE (folder)->priv->internal_uri;
234
* e_folder_exchange_set_internal_uri:
235
* @folder: an #EFolderExchange
236
* @internal_uri: new internal_uri value
238
* Updates @folder's internal URI to reflect a redirection response
242
e_folder_exchange_set_internal_uri (EFolder *folder, const gchar *internal_uri)
244
EFolderExchange *efe;
246
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
247
g_return_if_fail (internal_uri != NULL);
249
efe = E_FOLDER_EXCHANGE (folder);
250
g_free (efe->priv->internal_uri);
251
efe->priv->internal_uri = g_strdup (internal_uri);
255
* e_folder_exchange_get_path:
256
* @folder: an #EFolderExchange
258
* Return value: @folder's path within its Evolution storage
261
e_folder_exchange_get_path (EFolder *folder)
263
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
265
return E_FOLDER_EXCHANGE (folder)->priv->path;
269
* e_folder_exchange_get_permanent_uri:
270
* @folder: an #EFolderExchange
272
* Returns the folder's permanent URI. See docs/entryids for more
275
* Return value: @folder's permanent URI
278
e_folder_exchange_get_permanent_uri (EFolder *folder)
280
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
282
return E_FOLDER_EXCHANGE (folder)->priv->permanent_uri;
286
* e_folder_exchange_set_permanent_uri:
287
* @folder: an #EFolderExchange
288
* @permanent_uri: permanent_uri value
290
* Sets @folder's permanent URI (which must, for obvious reasons, have
291
* previously been unset).
294
e_folder_exchange_set_permanent_uri (EFolder *folder, const gchar *permanent_uri)
296
EFolderExchange *efe;
298
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
300
efe = E_FOLDER_EXCHANGE (folder);
301
g_return_if_fail (efe->priv->permanent_uri == NULL && permanent_uri != NULL);
303
efe->priv->permanent_uri = g_strdup (permanent_uri);
307
* e_folder_exchange_get_folder_size:
308
* @folder: an #EFolderExchange
310
* Returns the folder's size. See docs/entryids for more
313
* Return value: @folder's size
316
e_folder_exchange_get_folder_size (EFolder *folder)
318
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), -1);
320
return E_FOLDER_EXCHANGE (folder)->priv->folder_size;
324
* e_folder_exchange_set_folder_size:
325
* @folder: an #EFolderExchange
326
* @folder_size: folder size
328
* Sets @folder's folder_size
331
e_folder_exchange_set_folder_size (EFolder *folder, gint64 folder_size)
333
EFolderExchange *efe;
335
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
337
efe = E_FOLDER_EXCHANGE (folder);
339
efe->priv->folder_size = folder_size;
343
* e_folder_exchange_get_has_subfolders:
344
* @folder: an #EFolderExchange
346
* Return value: whether or not @folder has subfolders
349
e_folder_exchange_get_has_subfolders (EFolder *folder)
351
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), FALSE);
353
return E_FOLDER_EXCHANGE (folder)->priv->has_subfolders;
357
* e_folder_exchange_set_has_subfolders
358
* @folder: an #EFolderExchange
359
* @has_subfolders: whether or not @folder has subfolders
361
* Sets @folder's has_subfolders flag.
364
e_folder_exchange_set_has_subfolders (EFolder *folder,
365
gboolean has_subfolders)
367
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
369
E_FOLDER_EXCHANGE (folder)->priv->has_subfolders = has_subfolders;
373
* e_folder_exchange_get_rescan_tree:
374
* @folder: an #EFolderExchange
376
* Return value: whether or not to rescan @folder tree
379
e_folder_exchange_get_rescan_tree (EFolder *folder)
381
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), FALSE);
383
return E_FOLDER_EXCHANGE (folder)->priv->rescan_tree;
387
* e_folder_exchange_set_rescan_tree
388
* @folder: an #EFolderExchange
389
* @rescan_tree: whether or not @folder needs to be rescanned
391
* Sets @folder's has_subfolders flag.
394
e_folder_exchange_set_rescan_tree (EFolder *folder,
395
gboolean rescan_tree)
397
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
399
E_FOLDER_EXCHANGE (folder)->priv->rescan_tree = rescan_tree;
403
* e_folder_exchange_get_outlook_class:
404
* @folder: an #EFolderExchange
406
* Return value: @folder's Outlook IPM class
409
e_folder_exchange_get_outlook_class (EFolder *folder)
411
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
413
return E_FOLDER_EXCHANGE (folder)->priv->outlook_class;
417
* e_folder_exchange_get_hierarchy
418
* @folder: an #EFolderExchange
420
* Return value: @folder's hierarchy
423
e_folder_exchange_get_hierarchy (EFolder *folder)
425
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
427
return E_FOLDER_EXCHANGE (folder)->priv->hier;
431
* e_folder_exchange_get_storage_file:
432
* @folder: an #EFolderExchange
433
* @filename: name of a file
435
* This returns a unique filename ending in @filename in the local
436
* storage space reserved for @folder.
438
* Return value: the full filename, which must be freed.
441
e_folder_exchange_get_storage_file (EFolder *folder, const gchar *filename)
443
EFolderExchange *efe;
446
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
448
efe = (EFolderExchange *)folder;
450
if (!efe->priv->storage_dir) {
451
efe->priv->storage_dir = e_path_to_physical (
452
efe->priv->hier->account->storage_dir,
454
g_mkdir_with_parents (efe->priv->storage_dir, 0755);
457
path = g_build_filename (efe->priv->storage_dir, filename, NULL);
462
* e_folder_exchange_save_to_file:
463
* @folder: the folder
464
* @filename: a filename
466
* Saves all relevant information about @folder to @filename.
468
* Return value: success or failure
471
e_folder_exchange_save_to_file (EFolder *folder, const gchar *filename)
475
const gchar *name, *type, *outlook_class;
476
const gchar *physical_uri, *internal_uri, *permanent_uri;
481
name = e_folder_get_name (folder);
482
type = e_folder_get_type_string (folder);
483
outlook_class = e_folder_exchange_get_outlook_class (folder);
484
physical_uri = e_folder_get_physical_uri (folder);
485
internal_uri = e_folder_exchange_get_internal_uri (folder);
486
permanent_uri = e_folder_exchange_get_permanent_uri (folder);
488
g_return_val_if_fail (name && type && physical_uri && internal_uri,
491
if ((fsize = e_folder_exchange_get_folder_size (folder)) >= 0)
492
folder_size = g_strdup_printf ("%" G_GINT64_FORMAT, fsize);
496
doc = xmlNewDoc ((xmlChar *) "1.0");
497
root = xmlNewDocNode (doc, NULL, (xmlChar *) "connector-folder", NULL);
498
xmlNewProp (root, (xmlChar *) "version", (xmlChar *) "1");
499
xmlDocSetRootElement (doc, root);
503
(xmlChar *) "displayname",
511
(xmlChar *) "outlook_class",
512
(xmlChar *) outlook_class);
515
(xmlChar *) "physical_uri",
516
(xmlChar *) physical_uri);
519
(xmlChar *) "internal_uri",
520
(xmlChar *) internal_uri);
523
(xmlChar *) "folder_size",
524
(xmlChar *) folder_size);
528
(xmlChar *) "permanent_uri",
529
(xmlChar *) permanent_uri);
531
status = e_xml_save_file (filename, doc);
538
g_free (folder_size);
544
* e_folder_exchange_new_from_file:
545
* @hier: the hierarchy to create the folder under
546
* @filename: a filename
548
* Loads information about a folder from a saved file.
550
* Return value: the folder, or %NULL on a failed load.
553
e_folder_exchange_new_from_file (ExchangeHierarchy *hier, const gchar *filename)
555
EFolder *folder = NULL;
557
xmlNode *root, *node;
558
xmlChar *version, *display_name = NULL;
559
xmlChar *type = NULL, *outlook_class = NULL;
560
xmlChar *physical_uri = NULL, *internal_uri = NULL;
561
xmlChar *permanent_uri = NULL;
562
xmlChar *folder_size = NULL;
564
doc = e_xml_parse_file (filename);
569
root = xmlDocGetRootElement (doc);
570
if (root == NULL || strcmp ((gchar *) root->name, "connector-folder") != 0) {
574
version = xmlGetProp (root, (xmlChar *) "version");
579
if (strcmp ((gchar *) version, "1") != 0) {
586
node = e_xml_get_child_by_name (root, (xmlChar *) "displayname");
589
display_name = xmlNodeGetContent (node);
591
node = e_xml_get_child_by_name (root, (xmlChar *) "type");
594
type = xmlNodeGetContent (node);
596
node = e_xml_get_child_by_name (root, (xmlChar *) "outlook_class");
599
outlook_class = xmlNodeGetContent (node);
601
node = e_xml_get_child_by_name (root, (xmlChar *) "physical_uri");
604
physical_uri = xmlNodeGetContent (node);
606
node = e_xml_get_child_by_name (root, (xmlChar *) "internal_uri");
609
internal_uri = xmlNodeGetContent (node);
611
if (!display_name || !type || !physical_uri || !internal_uri)
614
folder = e_folder_exchange_new (
616
(gchar *) display_name,
618
(gchar *) outlook_class,
619
(gchar *) physical_uri,
620
(gchar *) internal_uri);
622
node = e_xml_get_child_by_name (root, (xmlChar *) "permanent_uri");
624
permanent_uri = xmlNodeGetContent (node);
625
e_folder_exchange_set_permanent_uri (folder, (gchar *) permanent_uri);
628
node = e_xml_get_child_by_name (root, (xmlChar *) "folder_size");
630
folder_size = xmlNodeGetContent (node);
631
e_folder_exchange_set_folder_size (folder, atoi ((gchar *) folder_size));
635
xmlFree (display_name);
637
xmlFree (outlook_class);
638
xmlFree (physical_uri);
639
xmlFree (internal_uri);
640
xmlFree (permanent_uri);
641
xmlFree (folder_size);
647
/* E2kContext wrappers */
648
#define E_FOLDER_EXCHANGE_CONTEXT(efe) (exchange_account_get_context (((EFolderExchange *)efe)->priv->hier->account))
649
#define E_FOLDER_EXCHANGE_URI(efe) (((EFolderExchange *)efe)->priv->internal_uri)
652
* e_folder_exchange_propfind:
653
* @folder: the folder
654
* @op: pointer to an #E2kOperation to use for cancellation
655
* @props: array of properties to find
656
* @nprops: length of @props
657
* @results: on return, the results
658
* @nresults: length of @results
660
* Performs a PROPFIND operation on @folder. This is a convenience
661
* wrapper around e2k_context_propfind(), qv.
663
* Return value: the HTTP status
666
e_folder_exchange_propfind (EFolder *folder, E2kOperation *op,
667
const gchar **props, gint nprops,
668
E2kResult **results, gint *nresults)
670
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), E2K_HTTP_MALFORMED);
672
return e2k_context_propfind (
673
E_FOLDER_EXCHANGE_CONTEXT (folder), op,
674
E_FOLDER_EXCHANGE_URI (folder),
675
props, nprops, results, nresults);
679
* e_folder_exchange_bpropfind_start:
680
* @folder: the folder
681
* @op: pointer to an #E2kOperation to use for cancellation
682
* @hrefs: array of URIs, relative to @folder
683
* @nhrefs: length of @hrefs
684
* @props: array of properties to find
685
* @nprops: length of @props
687
* Begins a BPROPFIND (bulk PROPFIND) operation on @folder for @hrefs.
688
* This is a convenience wrapper around e2k_context_bpropfind_start(),
691
* Return value: an iterator for getting the results
694
e_folder_exchange_bpropfind_start (EFolder *folder, E2kOperation *op,
695
const gchar **hrefs, gint nhrefs,
696
const gchar **props, gint nprops)
698
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
700
return e2k_context_bpropfind_start (
701
E_FOLDER_EXCHANGE_CONTEXT (folder), op,
702
E_FOLDER_EXCHANGE_URI (folder),
703
hrefs, nhrefs, props, nprops);
707
* e_folder_exchange_search_start:
708
* @folder: the folder
709
* @op: pointer to an #E2kOperation to use for cancellation
710
* @props: the properties to search for
711
* @nprops: size of @props array
712
* @rn: the search restriction
713
* @orderby: if non-%NULL, the field to sort the search results by
714
* @ascending: %TRUE for an ascending search, %FALSE for descending.
716
* Begins a SEARCH on the contents of @folder. This is a convenience
717
* wrapper around e2k_context_search_start(), qv.
719
* Return value: an iterator for returning the search results
722
e_folder_exchange_search_start (EFolder *folder, E2kOperation *op,
723
const gchar **props, gint nprops,
724
E2kRestriction *rn, const gchar *orderby,
727
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
729
return e2k_context_search_start (
730
E_FOLDER_EXCHANGE_CONTEXT (folder), op,
731
E_FOLDER_EXCHANGE_URI (folder),
732
props, nprops, rn, orderby, ascending);
736
* e_folder_exchange_subscribe:
737
* @folder: the folder to subscribe to notifications on
738
* @type: the type of notification to subscribe to
739
* @min_interval: the minimum interval (in seconds) between
741
* @callback: the callback to call when a notification has been
743
* @user_data: data to pass to @callback.
745
* This subscribes to change notifications of the given @type on
746
* @folder. This is a convenience wrapper around
747
* e2k_context_subscribe(), qv.
750
e_folder_exchange_subscribe (EFolder *folder,
751
E2kContextChangeType type, gint min_interval,
752
E2kContextChangeCallback callback,
755
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
757
e2k_context_subscribe (E_FOLDER_EXCHANGE_CONTEXT (folder),
758
E_FOLDER_EXCHANGE_URI (folder),
759
type, min_interval, callback, user_data);
763
* e_folder_exchange_unsubscribe:
764
* @folder: the folder to unsubscribe from
766
* Unsubscribes to all notifications on @folder. This is a convenience
767
* wrapper around e2k_context_unsubscribe(), qv.
770
e_folder_exchange_unsubscribe (EFolder *folder)
774
g_return_if_fail (E_IS_FOLDER_EXCHANGE (folder));
776
/* FIXME : This is a hack as of now. The free_folder in mail-stub
777
gets called when we are in offline and the context is NULL then. */
778
ctx = E_FOLDER_EXCHANGE_CONTEXT (folder);
780
e2k_context_unsubscribe (E_FOLDER_EXCHANGE_CONTEXT (folder),
781
E_FOLDER_EXCHANGE_URI (folder));
786
* e_folder_exchange_transfer_start:
787
* @source: the source folder
788
* @op: pointer to an #E2kOperation to use for cancellation
789
* @dest: the destination folder
790
* @source_hrefs: an array of hrefs to move, relative to @source_folder
791
* @delete_originals: whether or not to delete the original objects
793
* Starts a BMOVE or BCOPY (depending on @delete_originals) operation
794
* on @source. This is a convenience wrapper around
795
* e2k_context_transfer_start(), qv.
797
* Return value: the iterator for the results
800
e_folder_exchange_transfer_start (EFolder *source, E2kOperation *op,
801
EFolder *dest, GPtrArray *source_hrefs,
802
gboolean delete_originals)
804
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (source), NULL);
806
return e2k_context_transfer_start (E_FOLDER_EXCHANGE_CONTEXT (source), op,
807
E_FOLDER_EXCHANGE_URI (source),
808
E_FOLDER_EXCHANGE_URI (dest),
809
source_hrefs, delete_originals);
813
* e_folder_exchange_put_new:
814
* @folder: the folder to PUT the new item into
815
* @op: pointer to an #E2kOperation to use for cancellation
816
* @object_name: base name of the new object (not URI-encoded)
817
* @test_callback: callback to use to test possible object URIs
818
* @user_data: data for @test_callback
819
* @content_type: MIME Content-Type of the data
821
* @length: length of @body
822
* @location: if not %NULL, will contain the Location of the POSTed
824
* @repl_uid: if not %NULL, will contain the Repl-UID of the POSTed
827
* PUTs data into @folder with a new name based on @object_name. This
828
* is a convenience wrapper around e2k_context_put_new(), qv.
830
* Return value: the HTTP status
833
e_folder_exchange_put_new (EFolder *folder,
835
const gchar *object_name,
836
E2kContextTestCallback test_callback,
838
const gchar *content_type,
839
const gchar *body, gint length,
840
gchar **location, gchar **repl_uid)
842
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), E2K_HTTP_MALFORMED);
844
return e2k_context_put_new (E_FOLDER_EXCHANGE_CONTEXT (folder), op,
845
E_FOLDER_EXCHANGE_URI (folder),
846
object_name, test_callback, user_data,
847
content_type, body, length,
852
* e_folder_exchange_proppatch_new:
853
* @folder: the folder to PROPPATCH a new object in
854
* @op: pointer to an #E2kOperation to use for cancellation
855
* @object_name: base name of the new object (not URI-encoded)
856
* @test_callback: callback to use to test possible object URIs
857
* @user_data: data for @test_callback
858
* @props: the properties to set/remove
859
* @location: if not %NULL, will contain the Location of the
860
* PROPPATCHed object on return
861
* @repl_uid: if not %NULL, will contain the Repl-UID of the
862
* PROPPATCHed object on return
864
* PROPPATCHes data into @folder with a new name based on
865
* @object_name. This is a convenience wrapper around
866
* e2k_context_proppatch_new(), qv.
868
* Return value: the HTTP status
871
e_folder_exchange_proppatch_new (EFolder *folder, E2kOperation *op,
872
const gchar *object_name,
873
E2kContextTestCallback test_callback,
875
E2kProperties *props,
876
gchar **location, gchar **repl_uid)
878
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), E2K_HTTP_MALFORMED);
880
return e2k_context_proppatch_new (E_FOLDER_EXCHANGE_CONTEXT (folder), op,
881
E_FOLDER_EXCHANGE_URI (folder),
883
test_callback, user_data,
889
* e_folder_exchange_bproppatch_start:
890
* @folder: the folder
891
* @op: pointer to an #E2kOperation to use for cancellation
892
* @hrefs: array of URIs, relative to @folder
893
* @nhrefs: length of @hrefs
894
* @props: the properties to set/remove
895
* @create: whether or not to create the objects if they do not exist
897
* Begins BPROPPATCHing @hrefs under @folder. This is a convenience
898
* wrapper around e2k_context_bproppatch_start(), qv.
900
* Return value: an iterator for getting the results of the BPROPPATCH
903
e_folder_exchange_bproppatch_start (EFolder *folder, E2kOperation *op,
904
const gchar **hrefs, gint nhrefs,
905
E2kProperties *props, gboolean create)
907
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
909
return e2k_context_bproppatch_start (E_FOLDER_EXCHANGE_CONTEXT (folder), op,
910
E_FOLDER_EXCHANGE_URI (folder),
911
hrefs, nhrefs, props, create);
915
* e_folder_exchange_bdelete_start:
916
* @folder: the folder
917
* @op: pointer to an #E2kOperation to use for cancellation
918
* @hrefs: array of URIs, relative to @folder, to delete
919
* @nhrefs: length of @hrefs
921
* Begins a BDELETE (bulk DELETE) operation in @folder for @hrefs.
922
* This is a convenience wrapper around e2k_context_bdelete_start(),
925
* Return value: an iterator for returning the results
928
e_folder_exchange_bdelete_start (EFolder *folder, E2kOperation *op,
929
const gchar **hrefs, gint nhrefs)
931
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), NULL);
933
return e2k_context_bdelete_start (E_FOLDER_EXCHANGE_CONTEXT (folder), op,
934
E_FOLDER_EXCHANGE_URI (folder),
939
* e_folder_exchange_mkcol:
940
* @folder: the folder to create
941
* @op: pointer to an #E2kOperation to use for cancellation
942
* @props: properties to set on the new folder, or %NULL
943
* @permanent_url: if not %NULL, will contain the permanent URL of the
944
* new folder on return
946
* Performs a MKCOL operation to create @folder, with optional
947
* additional properties. This is a convenience wrapper around
948
* e2k_context_mkcol(), qv.
950
* Return value: the HTTP status
953
e_folder_exchange_mkcol (EFolder *folder, E2kOperation *op,
954
E2kProperties *props,
955
gchar **permanent_url)
957
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), E2K_HTTP_MALFORMED);
959
return e2k_context_mkcol (E_FOLDER_EXCHANGE_CONTEXT (folder), op,
960
E_FOLDER_EXCHANGE_URI (folder),
961
props, permanent_url);
965
* e_folder_exchange_delete:
966
* @folder: the folder to delete
967
* @op: pointer to an #E2kOperation to use for cancellation
969
* Attempts to DELETE @folder. This is a convenience wrapper around
970
* e2k_context_delete(), qv.
972
* Return value: the HTTP status
975
e_folder_exchange_delete (EFolder *folder, E2kOperation *op)
977
ExchangeHierarchy *hier;
978
const gchar *folder_type, *physical_uri;
980
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (folder), E2K_HTTP_MALFORMED);
981
/* remove ESources */
982
hier = e_folder_exchange_get_hierarchy (folder);
984
if (hier->type == EXCHANGE_HIERARCHY_PERSONAL ||
985
hier->type == EXCHANGE_HIERARCHY_FAVORITES) {
986
folder_type = e_folder_get_type_string (folder);
987
physical_uri = e_folder_get_physical_uri (folder);
989
if ((strcmp (folder_type, "calendar") == 0) ||
990
(strcmp (folder_type, "calendar/public") == 0)) {
991
remove_folder_esource (hier->account,
992
EXCHANGE_CALENDAR_FOLDER,
995
else if ((strcmp (folder_type, "tasks") == 0) ||
996
(strcmp (folder_type, "tasks/public") == 0)) {
997
remove_folder_esource (hier->account,
998
EXCHANGE_TASKS_FOLDER,
1001
else if ((strcmp (folder_type, "contacts") == 0) ||
1002
(strcmp (folder_type, "contacts/public") == 0)) {
1003
remove_folder_esource (hier->account,
1004
EXCHANGE_CONTACTS_FOLDER,
1009
return e2k_context_delete (E_FOLDER_EXCHANGE_CONTEXT (folder), op,
1010
E_FOLDER_EXCHANGE_URI (folder));
1014
* e_folder_exchange_transfer_dir:
1015
* @source: source folder
1016
* @op: pointer to an #E2kOperation to use for cancellation
1017
* @dest: destination folder
1018
* @delete_original: whether or not to delete the original folder
1019
* @permanent_url: if not %NULL, will contain the permanent URL of the
1020
* new folder on return
1022
* Performs a MOVE or COPY (depending on @delete_original) operation
1023
* on @source. This is a convenience wrapper around
1024
* e2k_context_transfer_dir(), qv.
1026
* Return value: the HTTP status
1029
e_folder_exchange_transfer_dir (EFolder *source, E2kOperation *op,
1030
EFolder *dest, gboolean delete_original,
1031
gchar **permanent_url)
1033
g_return_val_if_fail (E_IS_FOLDER_EXCHANGE (source), E2K_HTTP_MALFORMED);
1035
return e2k_context_transfer_dir (E_FOLDER_EXCHANGE_CONTEXT (source), op,
1036
E_FOLDER_EXCHANGE_URI (source),
1037
E_FOLDER_EXCHANGE_URI (dest),
1038
delete_original, permanent_url);