~ubuntu-branches/ubuntu/karmic/libtinymail/karmic

« back to all changes in this revision

Viewing changes to libtinymail/tny-folder-store.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-10-12 11:21:12 UTC
  • Revision ID: james.westby@ubuntu.com-20071012112112-fod9fs7yrooxjr7i
Tags: upstream-0.0.2
ImportĀ upstreamĀ versionĀ 0.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* libtinymail - The Tiny Mail base library
 
2
 * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org>
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Lesser General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library 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
 * Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public
 
15
 * License along with self library; if not, write to the
 
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
 * Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
#include <config.h>
 
21
 
 
22
#ifdef DBC
 
23
#include <string.h>
 
24
#endif
 
25
 
 
26
#include <tny-folder-store.h>
 
27
#include <tny-folder-store-observer.h>
 
28
#include <tny-list.h>
 
29
 
 
30
 
 
31
/**
 
32
 * tny_folder_store_add_observer:
 
33
 * @self: a #TnyFolder instance
 
34
 * @observer: a #TnyFolderStoreObserver instance
 
35
 *
 
36
 * Add @observer to the list of interested observers for events that could happen
 
37
 * caused by for example folder creates and deletions and other spontaneous 
 
38
 * changes.
 
39
 *
 
40
 * After this, @observer will start receiving notification of changes about @self. 
 
41
 * 
 
42
 * You must use tny_folder_store_remove_observer, in for example the finalization
 
43
 * of your type if you used this method. Adding an observer to @self, changes
 
44
 * reference counting of the objects involved. Removing the observer will undo
 
45
 * those reference counting changes. Therefore if you don't, you will introduce
 
46
 * memory leaks.
 
47
 *
 
48
 **/
 
49
void 
 
50
tny_folder_store_add_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer)
 
51
{
 
52
#ifdef DBC /* require */
 
53
        g_assert (TNY_IS_FOLDER_STORE (self));
 
54
        g_assert (observer);
 
55
        g_assert (TNY_IS_FOLDER_STORE_OBSERVER (observer));
 
56
        g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->add_observer_func != NULL);
 
57
#endif
 
58
 
 
59
        TNY_FOLDER_STORE_GET_IFACE (self)->add_observer_func (self, observer);
 
60
 
 
61
#ifdef DBC /* ensure */
 
62
        /* TNY TODO: Check whether it's really added */
 
63
#endif
 
64
 
 
65
        return;
 
66
}
 
67
 
 
68
 
 
69
/**
 
70
 * tny_folder_store_remove_observer:
 
71
 * @self: a #TnyFolderStore instance
 
72
 * @observer: a #TnyFolderStoreObserver instance
 
73
 *
 
74
 * Remove @observer from the list of interested observers for events that could
 
75
 * happen caused by for example folder creates and deletions and other 
 
76
 * spontaneous changes.
 
77
 *
 
78
 * After this, @observer will no longer receive notification of changes about @self. 
 
79
 * 
 
80
 * You must use this method, in for example the finalization of your type
 
81
 * if you used tny_folder_store_add_observer. Adding an observer to @self, changes
 
82
 * reference counting of the objects involved. Removing the observer will undo
 
83
 * those reference counting changes. Therefore if you don't, you will introduce
 
84
 * memory leaks.
 
85
 *
 
86
 **/
 
87
void 
 
88
tny_folder_store_remove_observer (TnyFolderStore *self, TnyFolderStoreObserver *observer)
 
89
{
 
90
#ifdef DBC /* require */
 
91
        g_assert (TNY_IS_FOLDER_STORE (self));
 
92
        g_assert (observer);
 
93
        g_assert (TNY_IS_FOLDER_STORE_OBSERVER (observer));
 
94
        g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->remove_observer_func != NULL);
 
95
#endif
 
96
 
 
97
        TNY_FOLDER_STORE_GET_IFACE (self)->remove_observer_func (self, observer);
 
98
 
 
99
#ifdef DBC /* ensure */
 
100
        /* TNY TODO: Check whether it's really removed */
 
101
#endif
 
102
 
 
103
        return;
 
104
 
 
105
}
 
106
 
 
107
/**
 
108
 * tny_folder_store_remove_folder:
 
109
 * @self: a #TnyFolderStore object
 
110
 * @folder: The folder to remove
 
111
 * @err: a #GError object or NULL
 
112
 *
 
113
 * Removes a folder represented by @folder from the folder store @self. You are
 
114
 * responsible for unreferencing the @folder instance yourself. This method will
 
115
 * not do this for you, leaving the @folder instance in an unusable state.
 
116
 *
 
117
 * All the #TnyFolderObservers and #TnyFolderStoreObservers of @folder, but of 
 
118
 * course not of @self, will automatically be unsubscribed.
 
119
 * 
 
120
 * This method will always recursively delete all child folders of @self. While
 
121
 * deleting folders, the folders will also always get unsubscribed (for example
 
122
 * in case of IMAP, which means that the folder wont be in LSUB either anymore).
 
123
 *
 
124
 * Observers of @self and of any the child folders of @self will receive delete
 
125
 * observer events in deletion order (childs first, parents after that). Types
 
126
 * like the #TnyGtkFolderStoreListModel know about this and act on folder 
 
127
 * deletions by automatically updating themselves.
 
128
 *
 
129
 * Example:
 
130
 * <informalexample><programlisting>
 
131
 * static void
 
132
 * my_remove_a_folder (TnyFolderStore *store, TnyFolder *remfol, GError **err)
 
133
 * {
 
134
 *     tny_folder_store_remove_folder (store, remfol, err);
 
135
 *     g_object_unref (G_OBJECT (remfol));
 
136
 * }
 
137
 * </programlisting></informalexample>
 
138
 *
 
139
 **/
 
140
void 
 
141
tny_folder_store_remove_folder (TnyFolderStore *self, TnyFolder *folder, GError **err)
 
142
{
 
143
#ifdef DBC /* require */
 
144
        g_assert (TNY_IS_FOLDER_STORE (self));
 
145
        g_assert (folder);
 
146
        g_assert (TNY_IS_FOLDER (folder));
 
147
        g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->remove_folder_func != NULL);
 
148
#endif
 
149
 
 
150
        TNY_FOLDER_STORE_GET_IFACE (self)->remove_folder_func (self, folder, err);
 
151
 
 
152
#ifdef DBC /* ensure */
 
153
        /* Checking this is something for a unit test */
 
154
#endif
 
155
 
 
156
        return;
 
157
}
 
158
 
 
159
/**
 
160
 * tny_folder_store_create_folder:
 
161
 * @self: a #TnyFolderStore object
 
162
 * @name: The folder name to create
 
163
 * @err: a #GError object or NULL
 
164
 *
 
165
 * Creates a new folder in @self. If not NULL, the value returned is the newly 
 
166
 * created folder instance and must be unreferenced after use.
 
167
 *
 
168
 * Example:
 
169
 * <informalexample><programlisting>
 
170
 * TnyFolderStore *store = ...
 
171
 * TnyFolder *createfol;
 
172
 * createfol = tny_folder_store_create_folder (store, "Test", NULL);
 
173
 * if (createfol) g_object_unref (G_OBJECT (createfol));
 
174
 * </programlisting></informalexample>
 
175
 * 
 
176
 * Return value: A new folder instance representing the folder that was created 
 
177
 * or NULL in case of failure
 
178
 *
 
179
 **/
 
180
TnyFolder*
 
181
tny_folder_store_create_folder (TnyFolderStore *self, const gchar *name, GError **err)
 
182
{
 
183
        TnyFolder *retval;
 
184
 
 
185
#ifdef DBC /* require */
 
186
        g_assert (TNY_IS_FOLDER_STORE (self));
 
187
        g_assert (name);
 
188
        g_assert (strlen (name) > 0);
 
189
        g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->create_folder_func != NULL);
 
190
#endif
 
191
 
 
192
        retval = TNY_FOLDER_STORE_GET_IFACE (self)->create_folder_func (self, name, err);
 
193
 
 
194
#ifdef DBC /* ensure */
 
195
        if (retval)
 
196
                g_assert (TNY_IS_FOLDER (retval));
 
197
#endif
 
198
 
 
199
        return retval;
 
200
}
 
201
 
 
202
/**
 
203
 * tny_folder_store_get_folders:
 
204
 * @self: a #TnyFolderStore object
 
205
 * @list: A #TnyList to fillup
 
206
 * @query: A #TnyFolderStoreQuery object or NULL
 
207
 * @err: a #GError object or NULL
 
208
 *
 
209
 * Get a list of child folders from @self. You can use @query to limit the list 
 
210
 * of folders with only folders that match a query or NULL if you don't want
 
211
 * to limit the list at all.
 
212
 * 
 
213
 * Example:
 
214
 * <informalexample><programlisting>
 
215
 * TnyFolderStore *store = ...
 
216
 * TnyIterator *iter; TnyFolderStoreQuery *query = ...
 
217
 * TnyList *folders = tny_simple_list_new ();
 
218
 * tny_folder_store_get_folders (store, folders, query, NULL);
 
219
 * iter = tny_list_create_iterator (folders);
 
220
 * while (!tny_iterator_is_done (iter))
 
221
 * {
 
222
 *     TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (iter));
 
223
 *     g_print ("%s\n", tny_folder_get_name (folder));
 
224
 *     g_object_unref (G_OBJECT (folder));
 
225
 *     tny_iterator_next (iter);
 
226
 * }
 
227
 * g_object_unref (G_OBJECT (iter));
 
228
 * g_object_unref (G_OBJECT (folders)); 
 
229
 * </programlisting></informalexample>
 
230
 **/
 
231
void 
 
232
tny_folder_store_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err)
 
233
{
 
234
#ifdef DBC /* require */
 
235
        g_assert (TNY_IS_FOLDER_STORE (self));
 
236
        g_assert (list);
 
237
        g_assert (TNY_IS_LIST (list));
 
238
        if (query)
 
239
                g_assert (TNY_IS_FOLDER_STORE_QUERY (query));
 
240
        g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_func != NULL);
 
241
#endif
 
242
 
 
243
        TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_func (self, list, query, err);
 
244
 
 
245
#ifdef DBC /* ensure */
 
246
#endif
 
247
 
 
248
        return;
 
249
}
 
250
 
 
251
/**
 
252
 * tny_folder_store_get_folders_async:
 
253
 * @self: a #TnyFolderStore object
 
254
 * @list: A #TnyList to fillup
 
255
 * @callback: The callback handler
 
256
 * @query: A #TnyFolderStoreQuery object
 
257
 * @user_data: user data for the callback
 
258
 *
 
259
 * Get a list of child folders from the folder store @self and call back when 
 
260
 * finished. You can use @query to limit the list of folders with only folders 
 
261
 * that match a query or NULL if you don't want to limit the list at all.
 
262
 *
 
263
 * Example:
 
264
 * <informalexample><programlisting>
 
265
 * static void 
 
266
 * callback (TnyFolderStore *self, TnyList *list, GError **err, gpointer user_data)
 
267
 * {
 
268
 *     TnyIterator *iter = tny_list_create_iterator (list);
 
269
 *     while (!tny_iterator_is_done (iter))
 
270
 *     {
 
271
 *         TnyFolderStore *folder = tny_iterator_get_current (iter);
 
272
 *         TnyList *folders = tny_simple_list_new ();
 
273
 *         g_print ("%s\n", tny_folder_get_name (TNY_FOLDER (folder)));
 
274
 *         tny_folder_store_get_folders_async (folder,
 
275
 *             folders, callback, NULL, NULL);
 
276
 *         g_object_unref (G_OBJECT (folder));
 
277
 *         tny_iterator_next (iter);
 
278
 *     }
 
279
 *     g_object_unref (G_OBJECT (iter));
 
280
 *     g_object_unref (G_OBJECT (list));
 
281
 * } 
 
282
 * static void
 
283
 * get_all_folders (TnyStoreAccount *account)
 
284
 * {
 
285
 *     TnyList *folders;
 
286
 *     folders = tny_simple_list_new ();
 
287
 *     tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account),
 
288
 *         folders, callback, NULL, NULL);
 
289
 * }
 
290
 * </programlisting></informalexample>
 
291
 *
 
292
 * If you want to use this functionality, you are advised to let your application 
 
293
 * use a #GMainLoop. All Gtk+ applications have this once gtk_main () is called.
 
294
 * 
 
295
 * When using a #GMainLoop, this method will callback using g_idle_add_full.
 
296
 * Without a #GMainLoop, which the libtinymail-camel implementations detect
 
297
 * using (g_main_depth > 0), the callbacks will happen in a worker thread at an 
 
298
 * unknown moment in time (check your locking).
 
299
 *
 
300
 * When using Gtk+ the callback doesn't need gdk_threads_enter and 
 
301
 * gdk_threads_leave in Gtk+.
 
302
 *
 
303
 **/
 
304
void 
 
305
tny_folder_store_get_folders_async (TnyFolderStore *self, TnyList *list, TnyGetFoldersCallback callback, TnyFolderStoreQuery *query, TnyStatusCallback status_callback, gpointer user_data)
 
306
{
 
307
#ifdef DBC /* require */
 
308
        g_assert (TNY_IS_FOLDER_STORE (self));
 
309
        g_assert (list);
 
310
        g_assert (callback);
 
311
        g_assert (TNY_IS_LIST (list));
 
312
        if (query)
 
313
                g_assert (TNY_IS_FOLDER_STORE_QUERY (query));
 
314
        g_assert (TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_async_func != NULL);
 
315
#endif
 
316
 
 
317
        TNY_FOLDER_STORE_GET_IFACE (self)->get_folders_async_func (self, list, callback, query, status_callback, user_data);
 
318
 
 
319
#ifdef DBC /* ensure */
 
320
#endif
 
321
 
 
322
        return;
 
323
}
 
324
 
 
325
 
 
326
 
 
327
static void
 
328
tny_folder_store_base_init (gpointer g_class)
 
329
{
 
330
        static gboolean initialized = FALSE;
 
331
 
 
332
        if (!initialized) {
 
333
                /* create interface signals here. */
 
334
                initialized = TRUE;
 
335
        }
 
336
}
 
337
 
 
338
GType
 
339
tny_folder_store_get_type (void)
 
340
{
 
341
        static GType type = 0;
 
342
        
 
343
        if (G_UNLIKELY(type == 0))
 
344
        {
 
345
                static const GTypeInfo info = 
 
346
                {
 
347
                  sizeof (TnyFolderStoreIface),
 
348
                  tny_folder_store_base_init,   /* base_init */
 
349
                  NULL,   /* base_finalize */
 
350
                  NULL,   /* class_init */
 
351
                  NULL,   /* class_finalize */
 
352
                  NULL,   /* class_data */
 
353
                  0,
 
354
                  0,      /* n_preallocs */
 
355
                  NULL,    /* instance_init */
 
356
                  NULL
 
357
                };
 
358
                type = g_type_register_static (G_TYPE_INTERFACE, 
 
359
                        "TnyFolderStore", &info, 0);
 
360
        }
 
361
 
 
362
        return type;
 
363
}
 
364
 
 
365