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.
20 /* ExchangeHierarchyFavorites: class for the "Favorites" Public Folders
21 * hierarchy (and favorites-handling code).
28 #include "exchange-hierarchy-favorites.h"
29 #include "exchange-account.h"
30 #include "e-folder-exchange.h"
31 #include "e2k-propnames.h"
33 #include "e2k-utils.h"
34 #include "exchange-esource.h"
36 #include <libedataserver/e-source-list.h>
42 struct _ExchangeHierarchyFavoritesPrivate {
43 char *public_uri, *shortcuts_uri;
44 GHashTable *shortcuts;
47 #define PARENT_TYPE EXCHANGE_TYPE_HIERARCHY_SOMEDAV
48 static ExchangeHierarchySomeDAVClass *parent_class = NULL;
50 static GPtrArray *get_hrefs (ExchangeHierarchySomeDAV *hsd);
51 static ExchangeAccountFolderResult remove_folder (ExchangeHierarchy *hier,
53 static void finalize (GObject *object);
56 class_init (GObjectClass *object_class)
58 ExchangeHierarchySomeDAVClass *somedav_class =
59 EXCHANGE_HIERARCHY_SOMEDAV_CLASS (object_class);
60 ExchangeHierarchyClass *hier_class =
61 EXCHANGE_HIERARCHY_CLASS (object_class);
63 parent_class = g_type_class_ref (PARENT_TYPE);
65 /* virtual method override */
66 object_class->finalize = finalize;
67 hier_class->remove_folder = remove_folder;
68 somedav_class->get_hrefs = get_hrefs;
72 init (GObject *object)
74 ExchangeHierarchyFavorites *hfav = EXCHANGE_HIERARCHY_FAVORITES (object);
76 hfav->priv = g_new0 (ExchangeHierarchyFavoritesPrivate, 1);
77 hfav->priv->shortcuts = g_hash_table_new_full (g_str_hash, g_str_equal,
82 finalize (GObject *object)
84 ExchangeHierarchyFavorites *hfav = EXCHANGE_HIERARCHY_FAVORITES (object);
86 g_hash_table_destroy (hfav->priv->shortcuts);
87 g_free (hfav->priv->public_uri);
88 g_free (hfav->priv->shortcuts_uri);
91 G_OBJECT_CLASS (parent_class)->finalize (object);
94 E2K_MAKE_TYPE (exchange_hierarchy_favorites, ExchangeHierarchyFavorites, class_init, init, PARENT_TYPE)
97 add_hrefs (ExchangeHierarchy *hier, EFolder *folder, gpointer hrefs)
99 g_ptr_array_add (hrefs, (char *)e2k_uri_path (e_folder_exchange_get_internal_uri (folder)));
102 static const char *shortcuts_props[] = {
103 PR_FAV_DISPLAY_NAME, /* PR_DISPLAY_NAME of referent */
104 PR_FAV_DISPLAY_ALIAS, /* if set, user-chosen display name */
105 PR_FAV_PUBLIC_SOURCE_KEY, /* PR_SOURCE_KEY of referent */
106 PR_FAV_PARENT_SOURCE_KEY, /* PR_FAV_PUBLIC_SOURCE_KEY of parent */
107 PR_FAV_LEVEL_MASK /* depth in hierarchy (first level is 1) */
109 static const int n_shortcuts_props = G_N_ELEMENTS (shortcuts_props);
112 get_hrefs (ExchangeHierarchySomeDAV *hsd)
114 ExchangeHierarchy *hier = EXCHANGE_HIERARCHY (hsd);
115 ExchangeHierarchyFavorites *hfav = EXCHANGE_HIERARCHY_FAVORITES (hsd);
116 E2kContext *ctx = exchange_account_get_context (hier->account);
119 E2kResult *result, *results;
120 E2kHTTPStatus status;
121 GByteArray *source_key;
122 const char *prop = E2K_PR_DAV_HREF, *shortcut_uri;
123 char *perm_url, *folder_uri;
124 int i, nresults = 0, mode;
126 hrefs = g_ptr_array_new ();
128 exchange_account_is_offline (hier->account, &mode);
129 if (mode != ONLINE_MODE) {
130 exchange_hierarchy_webdav_offline_scan_subtree (EXCHANGE_HIERARCHY (hfav), add_hrefs, hrefs);
133 /* Scan the shortcut links and use PROPFIND to resolve the
134 * permanent_urls. Unfortunately it doesn't seem to be possible
135 * to BPROPFIND a group of permanent_urls.
137 iter = e2k_context_search_start (ctx, NULL, hfav->priv->shortcuts_uri,
138 shortcuts_props, n_shortcuts_props,
140 while ((result = e2k_result_iter_next (iter))) {
141 shortcut_uri = result->href;
142 source_key = e2k_properties_get_prop (result->props, PR_FAV_PUBLIC_SOURCE_KEY);
146 perm_url = e2k_entryid_to_permanenturl (source_key, hfav->priv->public_uri);
148 status = e2k_context_propfind (ctx, NULL, perm_url,
149 &prop, 1, &results, &nresults);
150 if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status) && nresults) {
151 folder_uri = g_strdup (results[0].href);
152 g_ptr_array_add (hrefs, folder_uri);
153 g_hash_table_insert (hfav->priv->shortcuts,
154 g_strdup (folder_uri),
155 g_strdup (shortcut_uri));
156 e2k_results_free (results, nresults);
162 status = e2k_result_iter_free (iter);
163 if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
164 /* FIXME: need to be able to return an error */
165 for (i = 0; i < hrefs->len; i++)
166 g_free (hrefs->pdata[i]);
167 g_ptr_array_free (hrefs, TRUE);
174 * exchange_hierarchy_favorites_is_added:
175 * @hier: the hierarchy
176 * @folder: the Public Folder to check in the favorites tree
178 * Checks if @folder is present in the favorites hierarchy
180 * Return value: TRUE if @folder is already added as a favorite.
184 exchange_hierarchy_favorites_is_added (ExchangeHierarchy *hier, EFolder *folder)
186 ExchangeHierarchyFavorites *hfav =
187 EXCHANGE_HIERARCHY_FAVORITES (hier);
188 const char *folder_uri, *shortcut_uri;
190 folder_uri = e_folder_exchange_get_internal_uri (folder);
191 shortcut_uri = g_hash_table_lookup (hfav->priv->shortcuts, folder_uri);
193 return shortcut_uri ? TRUE : FALSE;
196 static ExchangeAccountFolderResult
197 remove_folder (ExchangeHierarchy *hier, EFolder *folder)
199 ExchangeHierarchyFavorites *hfav =
200 EXCHANGE_HIERARCHY_FAVORITES (hier);
201 const char *folder_uri, *shortcut_uri;
202 E2kHTTPStatus status;
203 const char *folder_type, *physical_uri;
205 folder_uri = e_folder_exchange_get_internal_uri (folder);
206 shortcut_uri = g_hash_table_lookup (hfav->priv->shortcuts, folder_uri);
208 return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
210 status = e2k_context_delete (
211 exchange_account_get_context (hier->account), NULL,
214 if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
215 g_hash_table_remove (hfav->priv->shortcuts, folder_uri);
216 exchange_hierarchy_removed_folder (hier, folder);
218 /* Temp Fix for remove fav folders. see #59168 */
219 /* remove ESources */
220 folder_type = e_folder_get_type_string (folder);
221 physical_uri = e_folder_get_physical_uri (folder);
223 if (strcmp (folder_type, "calendar") == 0) {
224 remove_folder_esource (hier->account,
225 EXCHANGE_CALENDAR_FOLDER,
228 else if (strcmp (folder_type, "tasks") == 0) {
229 remove_folder_esource (hier->account,
230 EXCHANGE_TASKS_FOLDER,
233 else if (strcmp (folder_type, "contacts") == 0) {
234 remove_folder_esource (hier->account,
235 EXCHANGE_CONTACTS_FOLDER,
240 return exchange_hierarchy_webdav_status_to_folder_result (status);
244 * exchange_hierarchy_favorites_add_folder:
245 * @hier: the hierarchy
246 * @folder: the Public Folder to add to the favorites tree
248 * Adds a new folder to @hier.
250 * Return value: the folder result.
252 ExchangeAccountFolderResult
253 exchange_hierarchy_favorites_add_folder (ExchangeHierarchy *hier,
256 ExchangeHierarchyFavorites *hfav;
257 E2kProperties *props;
258 E2kHTTPStatus status;
259 const char *folder_uri, *permanent_uri;
262 g_return_val_if_fail (EXCHANGE_IS_HIERARCHY (hier), EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR);
263 g_return_val_if_fail (E_IS_FOLDER (folder), EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR);
264 g_return_val_if_fail (e_folder_exchange_get_hierarchy (folder)->type == EXCHANGE_HIERARCHY_PUBLIC, EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR);
266 hfav = EXCHANGE_HIERARCHY_FAVORITES (hier);
267 permanent_uri = e_folder_exchange_get_permanent_uri (folder);
269 props = e2k_properties_new ();
270 e2k_properties_set_string (props, PR_FAV_DISPLAY_NAME,
271 g_strdup (e_folder_get_name (folder)));
273 e2k_properties_set_binary (props, PR_FAV_PUBLIC_SOURCE_KEY,
274 e2k_permanenturl_to_entryid (permanent_uri));
275 e2k_properties_set_int (props, PR_FAV_LEVEL_MASK, 1);
277 status = e2k_context_proppatch_new (
278 exchange_account_get_context (hier->account), NULL,
279 hfav->priv->shortcuts_uri,
280 e_folder_get_name (folder), NULL, NULL,
281 props, &shortcut_uri, NULL);
282 e2k_properties_free (props);
284 if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
285 folder_uri = e_folder_exchange_get_internal_uri (folder);
287 g_hash_table_insert (hfav->priv->shortcuts,
288 g_strdup (folder_uri), shortcut_uri);
289 return exchange_hierarchy_somedav_add_folder (EXCHANGE_HIERARCHY_SOMEDAV (hier),
292 return exchange_hierarchy_webdav_status_to_folder_result (status);
296 * exchange_hierarchy_favorites_new:
297 * @account: an #ExchangeAccount
298 * @hierarchy_name: the name of the hierarchy
299 * @physical_uri_prefix: prefix for physical URIs in this hierarchy
300 * @home_uri: the home URI of the owner's mailbox
301 * @public_uri: the URI of the public folder tree
302 * @owner_name: display name of the owner of the hierarchy
303 * @owner_email: email address of the owner of the hierarchy
304 * @source_uri: account source URI for folders in this hierarchy
306 * Creates a new Favorites hierarchy
308 * Return value: the new hierarchy.
311 exchange_hierarchy_favorites_new (ExchangeAccount *account,
312 const char *hierarchy_name,
313 const char *physical_uri_prefix,
314 const char *home_uri,
315 const char *public_uri,
316 const char *owner_name,
317 const char *owner_email,
318 const char *source_uri)
320 ExchangeHierarchy *hier;
321 ExchangeHierarchyFavorites *hfav;
323 g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
325 hier = g_object_new (EXCHANGE_TYPE_HIERARCHY_FAVORITES, NULL);
327 hfav = (ExchangeHierarchyFavorites *)hier;
328 hfav->priv->public_uri = g_strdup (public_uri);
329 hfav->priv->shortcuts_uri = e2k_uri_concat (home_uri, "NON_IPM_SUBTREE/Shortcuts");
331 exchange_hierarchy_webdav_construct (EXCHANGE_HIERARCHY_WEBDAV (hier),
333 EXCHANGE_HIERARCHY_FAVORITES,
337 owner_name, owner_email,