1 /* Copyright (c) 2007, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <glib/gi18n.h>
34 #include <modest-tny-local-folders-account.h>
35 #include <modest-tny-outbox-account.h>
36 #include <modest-tny-folder.h>
37 #include <tny-merge-folder.h>
38 #include <tny-simple-list.h>
43 G_DEFINE_TYPE (ModestTnyLocalFoldersAccount,
44 modest_tny_local_folders_account,
45 TNY_TYPE_CAMEL_STORE_ACCOUNT);
47 #define TNY_LOCAL_FOLDERS_ACCOUNT_GET_PRIVATE(o) \
48 (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_TNY_LOCAL_FOLDERS_ACCOUNT, ModestTnyLocalFoldersAccountPrivate))
50 typedef struct _ModestTnyLocalFoldersAccountPrivate ModestTnyLocalFoldersAccountPrivate;
52 struct _ModestTnyLocalFoldersAccountPrivate
54 GSList *list_extra_folders;
58 modest_tny_local_folders_account_dispose (GObject *object)
60 if (G_OBJECT_CLASS (modest_tny_local_folders_account_parent_class)->dispose)
61 G_OBJECT_CLASS (modest_tny_local_folders_account_parent_class)->dispose (object);
66 modest_tny_local_folders_account_remove_all_extra_folders (ModestTnyLocalFoldersAccount *store)
68 ModestTnyLocalFoldersAccountPrivate *priv =
69 TNY_LOCAL_FOLDERS_ACCOUNT_GET_PRIVATE (store);
71 GSList *iter = priv->list_extra_folders;
74 TnyFolder *folder = (TnyFolder*)iter->data;
76 g_object_unref (folder);
80 iter = g_slist_next (iter);
83 g_slist_free (priv->list_extra_folders);
84 priv->list_extra_folders = NULL;
88 modest_tny_local_folders_account_finalize (GObject *object)
90 G_OBJECT_CLASS (modest_tny_local_folders_account_parent_class)->finalize (object);
92 ModestTnyLocalFoldersAccount *self =
93 MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (object);
95 modest_tny_local_folders_account_remove_all_extra_folders (self);
99 get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err);
102 get_folders_async (TnyFolderStore *self, TnyList *list, TnyGetFoldersCallback callback, TnyFolderStoreQuery *query, TnyStatusCallback status_callback, gpointer user_data);
105 modest_tny_local_folders_account_class_init (ModestTnyLocalFoldersAccountClass *klass)
107 GObjectClass *object_class = G_OBJECT_CLASS (klass);
109 g_type_class_add_private (klass, sizeof (ModestTnyLocalFoldersAccountPrivate));
111 object_class->dispose = modest_tny_local_folders_account_dispose;
112 object_class->finalize = modest_tny_local_folders_account_finalize;
114 /* Override virtual functions from the parent class: */
115 TNY_CAMEL_STORE_ACCOUNT_CLASS(klass)->get_folders_func = get_folders;
116 TNY_CAMEL_STORE_ACCOUNT_CLASS(klass)->get_folders_async_func = get_folders_async;
120 modest_tny_local_folders_account_init (ModestTnyLocalFoldersAccount *self)
124 ModestTnyLocalFoldersAccount*
125 modest_tny_local_folders_account_new (void)
127 return g_object_new (MODEST_TYPE_TNY_LOCAL_FOLDERS_ACCOUNT, NULL);
131 modest_tny_local_folders_account_add_extra_folder (ModestTnyLocalFoldersAccount *store,
134 ModestTnyLocalFoldersAccountPrivate *priv =
135 TNY_LOCAL_FOLDERS_ACCOUNT_GET_PRIVATE (store);
137 /* Check that it isn't already in the list: */
138 GSList *exists = g_slist_find (priv->list_extra_folders, folder);
143 /* The reference is released in finalize: */
144 priv->list_extra_folders = g_slist_append (priv->list_extra_folders, folder);
145 g_object_ref (folder);
149 modest_tny_local_folders_account_query_passes (TnyFolderStoreQuery *query, TnyFolder *folder)
151 gboolean retval = FALSE;
153 if (query && (tny_list_get_length (tny_folder_store_query_get_items (query)) > 0))
155 TnyList *items = tny_folder_store_query_get_items (query);
156 TnyIterator *iterator;
157 iterator = tny_list_create_iterator (items);
159 while (!tny_iterator_is_done (iterator))
161 TnyFolderStoreQueryItem *item = (TnyFolderStoreQueryItem*) tny_iterator_get_current (iterator);
162 TnyFolderStoreQueryOption options = tny_folder_store_query_item_get_options (item);
163 regex_t *regex = tny_folder_store_query_item_get_regex (item);
165 if ((options & TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED) &&
166 tny_folder_is_subscribed (folder))
169 if ((options & TNY_FOLDER_STORE_QUERY_OPTION_UNSUBSCRIBED) &&
170 !(tny_folder_is_subscribed (folder)))
173 if (regex && options & TNY_FOLDER_STORE_QUERY_OPTION_MATCH_ON_NAME)
174 if (regexec (regex, tny_folder_get_name (folder), 0, NULL, 0) == 0)
177 if (regex && options & TNY_FOLDER_STORE_QUERY_OPTION_MATCH_ON_ID)
178 if (regexec (regex, tny_folder_get_id (folder), 0, NULL, 0) == 0)
181 g_object_unref (G_OBJECT (item));
182 tny_iterator_next (iterator);
185 g_object_unref (G_OBJECT (iterator));
186 g_object_unref (G_OBJECT (items));
195 get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
197 ModestTnyLocalFoldersAccountPrivate *priv =
198 TNY_LOCAL_FOLDERS_ACCOUNT_GET_PRIVATE (self);
200 /* Call the base class implementation: */
201 TnyCamelStoreAccountClass *parent_class = g_type_class_peek_parent (
202 MODEST_TNY_LOCAL_FOLDERS_ACCOUNT_GET_CLASS (self));
203 parent_class->get_folders_func (self, list, query, err);
205 /* Add our extra folders only if it passes the query */
206 GSList *iter = priv->list_extra_folders;
208 TnyFolder *folder = TNY_FOLDER (iter->data);
210 if (folder && modest_tny_local_folders_account_query_passes (query, folder))
211 tny_list_prepend (list, G_OBJECT (folder));
213 iter = g_slist_next (iter);
218 get_folders_async (TnyFolderStore *self, TnyList *list, TnyGetFoldersCallback callback, TnyFolderStoreQuery *query, TnyStatusCallback status_callback, gpointer user_data)
220 /* Call the base class implementation: */
221 TnyCamelStoreAccountClass *parent_class = g_type_class_peek_parent (
222 MODEST_TNY_LOCAL_FOLDERS_ACCOUNT_GET_CLASS (self));
223 parent_class->get_folders_async_func (self, list, callback, query, status_callback, user_data);
227 add_account_folders_to_merged_folder (TnyAccount *account, TnyMergeFolder* merge_folder)
229 const gchar* account_id = tny_account_get_id (account);
230 const gboolean is_actual_local_folders_account = account_id &&
231 (strcmp (account_id, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0);
233 TnyList *list_outbox_folders = tny_simple_list_new ();
234 tny_folder_store_get_folders (TNY_FOLDER_STORE (account),
235 list_outbox_folders, NULL, NULL);
237 TnyIterator* iter = tny_list_create_iterator (list_outbox_folders);
238 while (!tny_iterator_is_done (iter))
240 TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (iter));
244 /* TODO: Do not add outboxes that are inside local-folders/,
245 * because these are just left-over from earlier Modest versions
246 * that put the outbox there: */
247 if (is_actual_local_folders_account) {
248 const TnyFolderType type = modest_tny_folder_get_local_folder_type (folder);
249 if (type == TNY_FOLDER_TYPE_OUTBOX) {
255 tny_merge_folder_add_folder (merge_folder, folder);
257 g_object_unref (folder);
260 tny_iterator_next (iter);
263 g_object_unref (list_outbox_folders);
266 void modest_tny_local_folders_account_add_merged_outbox_folders (ModestTnyLocalFoldersAccount *self,
269 modest_tny_local_folders_account_remove_all_extra_folders (self);
271 /* All per-account outbox folders are merged into one folders
272 * so that they appear as one outbox to the user: */
273 TnyMergeFolder *merged_outbox = TNY_MERGE_FOLDER (tny_merge_folder_new(_("mcen_me_folder_outbox")));
275 /* Set type to outbox (NB#61580) */
276 tny_merge_folder_set_folder_type (merged_outbox, TNY_FOLDER_TYPE_OUTBOX);
278 GSList *iter = accounts;
281 TnyAccount *account = TNY_ACCOUNT (iter->data);
283 /* Add both outbox account and local-folders account folders
284 * to our one combined account:
286 if (MODEST_IS_TNY_OUTBOX_ACCOUNT (account)) {
287 /* Add the folder to the merged folder.
288 * We will add it later to the virtual local-folders store: */
289 add_account_folders_to_merged_folder (account, merged_outbox);
293 iter = g_slist_next (iter);
296 /* Add the merged outbox folder to the virtual local-folders store: */
297 /* printf ("Debug: %s: adding merged outbox.\n", __FUNCTION__); */
298 modest_tny_local_folders_account_add_extra_folder (self, TNY_FOLDER(merged_outbox));
299 g_object_unref (merged_outbox);
300 merged_outbox = NULL;