Rename camel_service_get_settings().
[platform/upstream/evolution-data-server.git] / camel / camel-offline-store.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  *  Authors: Jeffrey Stedfast <fejj@novell.com>
4  *
5  *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU Lesser General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <glib/gi18n-lib.h>
28
29 #include "camel-folder.h"
30 #include "camel-offline-folder.h"
31 #include "camel-offline-settings.h"
32 #include "camel-offline-store.h"
33 #include "camel-session.h"
34
35 #define CAMEL_OFFLINE_STORE_GET_PRIVATE(obj) \
36         (G_TYPE_INSTANCE_GET_PRIVATE \
37         ((obj), CAMEL_TYPE_OFFLINE_STORE, CamelOfflineStorePrivate))
38
39 struct _CamelOfflineStorePrivate {
40         gboolean online;
41 };
42
43 G_DEFINE_TYPE (CamelOfflineStore, camel_offline_store, CAMEL_TYPE_STORE)
44
45 static void
46 offline_store_constructed (GObject *object)
47 {
48         CamelOfflineStorePrivate *priv;
49         CamelSession *session;
50
51         priv = CAMEL_OFFLINE_STORE_GET_PRIVATE (object);
52
53         /* Chain up to parent's constructed() method. */
54         G_OBJECT_CLASS (camel_offline_store_parent_class)->
55                 constructed (object);
56
57         session = camel_service_get_session (CAMEL_SERVICE (object));
58         priv->online = camel_session_get_online (session);
59 }
60
61 static void
62 camel_offline_store_class_init (CamelOfflineStoreClass *class)
63 {
64         GObjectClass *object_class;
65         CamelServiceClass *service_class;
66
67         g_type_class_add_private (class, sizeof (CamelOfflineStorePrivate));
68
69         object_class = G_OBJECT_CLASS (class);
70         object_class->constructed = offline_store_constructed;
71
72         service_class = CAMEL_SERVICE_CLASS (class);
73         service_class->settings_type = CAMEL_TYPE_OFFLINE_SETTINGS;
74 }
75
76 static void
77 camel_offline_store_init (CamelOfflineStore *store)
78 {
79         store->priv = CAMEL_OFFLINE_STORE_GET_PRIVATE (store);
80 }
81
82 /**
83  * camel_offline_store_get_online:
84  * @store: a #CamelOfflineStore
85  *
86  * Returns %TRUE if @store is online.
87  *
88  * Since: 2.24
89  **/
90 gboolean
91 camel_offline_store_get_online (CamelOfflineStore *store)
92 {
93         g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), 0);
94
95         return store->priv->online;
96 }
97
98 /**
99  * camel_offline_store_set_online_sync:
100  * @store: a #CamelOfflineStore
101  * @online: %TRUE for online, %FALSE for offline
102  * @cancellable: optional #GCancellable object, or %NULL
103  * @error: return location for a #GError, or %NULL
104  *
105  * Sets the online/offline state of @store according to @online.
106  **/
107 gboolean
108 camel_offline_store_set_online_sync (CamelOfflineStore *store,
109                                      gboolean online,
110                                      GCancellable *cancellable,
111                                      GError **error)
112 {
113         CamelService *service;
114         CamelSession *session;
115         CamelSettings *settings;
116         gboolean network_available;
117         gboolean store_is_online;
118         gboolean sync_store;
119         gboolean success;
120
121         g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), FALSE);
122
123         if (store->priv->online == online)
124                 return TRUE;
125
126         service = CAMEL_SERVICE (store);
127         session = camel_service_get_session (service);
128
129         network_available = camel_session_get_network_available (session);
130         store_is_online = camel_offline_store_get_online (store);
131
132         settings = camel_service_ref_settings (service);
133
134         sync_store = camel_offline_settings_get_stay_synchronized (
135                 CAMEL_OFFLINE_SETTINGS (settings));
136
137         g_object_unref (settings);
138
139         /* Returning to online mode is the simpler case. */
140         if (!store_is_online) {
141                 store->priv->online = online;
142                 return camel_service_connect_sync (
143                         service, cancellable, error);
144         }
145
146         /* network available -> network unavailable */
147         if (network_available) {
148                 GPtrArray *folders;
149                 guint ii;
150
151                 folders = camel_object_bag_list (
152                         CAMEL_STORE (store)->folders);
153
154                 for (ii = 0; ii < folders->len; ii++) {
155                         CamelFolder *folder = folders->pdata[ii];
156                         gboolean sync_folder;
157
158                         if (!CAMEL_IS_OFFLINE_FOLDER (folder))
159                                 continue;
160
161                         sync_folder =
162                                 camel_offline_folder_get_offline_sync (
163                                 CAMEL_OFFLINE_FOLDER (folder));
164
165                         if (sync_store || sync_folder)
166                                 camel_offline_folder_downsync_sync (
167                                         CAMEL_OFFLINE_FOLDER (folder),
168                                         NULL, cancellable, NULL);
169                 }
170
171                 g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
172                 g_ptr_array_free (folders, TRUE);
173
174                 camel_store_synchronize_sync (
175                         CAMEL_STORE (store), FALSE, cancellable, NULL);
176         }
177
178         success = camel_service_disconnect_sync (
179                 service, network_available, cancellable, error);
180
181         store->priv->online = online;
182
183         return success;
184 }
185
186 /**
187  * camel_offline_store_prepare_for_offline_sync:
188  *
189  * Since: 2.22
190  **/
191 gboolean
192 camel_offline_store_prepare_for_offline_sync (CamelOfflineStore *store,
193                                               GCancellable *cancellable,
194                                               GError **error)
195 {
196         CamelService *service;
197         CamelSession *session;
198         CamelSettings *settings;
199         gboolean network_available;
200         gboolean store_is_online;
201         gboolean sync_store;
202
203         g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), FALSE);
204
205         service = CAMEL_SERVICE (store);
206         session = camel_service_get_session (service);
207
208         network_available = camel_session_get_network_available (session);
209         store_is_online = camel_offline_store_get_online (store);
210
211         settings = camel_service_ref_settings (service);
212
213         sync_store = camel_offline_settings_get_stay_synchronized (
214                 CAMEL_OFFLINE_SETTINGS (settings));
215
216         g_object_unref (settings);
217
218         if (network_available && store_is_online) {
219                 GPtrArray *folders;
220                 guint ii;
221
222                 folders = camel_object_bag_list (
223                         CAMEL_STORE (store)->folders);
224
225                 for (ii = 0; ii < folders->len; ii++) {
226                         CamelFolder *folder = folders->pdata[ii];
227                         gboolean sync_folder;
228
229                         if (!CAMEL_IS_OFFLINE_FOLDER (folder))
230                                 continue;
231
232                         sync_folder =
233                                 camel_offline_folder_get_offline_sync (
234                                 CAMEL_OFFLINE_FOLDER (folder));
235
236                         if (sync_store || sync_folder) {
237                                 camel_offline_folder_downsync_sync (
238                                         CAMEL_OFFLINE_FOLDER (folder),
239                                         NULL, cancellable, NULL);
240                         }
241                 }
242
243                 g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
244                 g_ptr_array_free (folders, TRUE);
245         }
246
247         if (network_available)
248                 camel_store_synchronize_sync (
249                         CAMEL_STORE (store), FALSE, cancellable, NULL);
250
251         return TRUE;
252 }