root/trunk/libtinymailui-gtk/tny-gtk-account-list-model.c

Revision 3666 (checked in by jdapena, 7 months ago)

* Use GOnce registering all types in tinymail to make

registering thread-safe.

Line 
1 /* libtinymailui-gtk - The Tiny Mail UI library for Gtk+
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., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * TnyGtkAccountListModel:
22  *
23  * A #GtkTreeModel for #TnyAccount instances
24  *
25  * Note that a #TnyGtkAccountListModel is a #TnyList too. You can use the
26  * #TnyList API on instances of this type too.
27  *
28  * Note that you must make sure that you unreference #TnyAccount instances that
29  * you get out of the instance column of this type using the #GtkTreeModel API
30  * gtk_tree_model_get().
31  *
32  * free-function: g_object_unref
33  **/
34
35 #include <config.h>
36
37 #include <glib.h>
38 #include <gtk/gtk.h>
39
40 #ifdef GNOME
41 #include <libgnomeui/libgnomeui.h>
42 #endif
43
44 #include <tny-gtk-account-list-model.h>
45 #include <tny-mime-part.h>
46 #include <tny-iterator.h>
47 #include <tny-mime-part.h>
48 #include <tny-folder.h>
49
50 #include "tny-gtk-account-list-model-iterator-priv.h"
51
52
53 static GObjectClass *parent_class = NULL;
54
55
56 #define TNY_GTK_ACCOUNT_LIST_MODEL_GET_PRIVATE(o)       \
57         (G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_GTK_ACCOUNT_LIST_MODEL, TnyGtkAccountListModelPriv))
58
59
60 /**
61  * tny_gtk_account_list_model_new:
62  *
63  * Create a new #GtkTreeModel suitable for showing a list of accounts. Note
64  * that when using gtk_combo_box_set_model() or gtk_tree_view_set_model(),
65  * the view will add its reference to your model instance. If you want the
66  * view to become the owner, you must get rid of your initial reference.
67  *
68  * Example:
69  * <informalexample><programlisting>
70  * GtkTreeModel *model = tny_gtk_account_list_model_new ();
71  * GtkTreeView *view = ...;
72  * tny_account_store_get_accounts (accstore, TNY_LIST (model), ...);
73  * gtk_tree_view_set_model (view, model);
74  * g_object_unref (model);
75  * </programlisting></informalexample>
76  *
77  * returns: (caller-owns): a new #GtkTreeModel for accounts
78  * since: 1.0
79  * audience: application-developer
80  **/
81 GtkTreeModel*
82 tny_gtk_account_list_model_new (void)
83 {
84         TnyGtkAccountListModel *self = g_object_new (TNY_TYPE_GTK_ACCOUNT_LIST_MODEL, NULL);
85
86         return GTK_TREE_MODEL (self);
87 }
88
89
90 static void
91 tny_gtk_account_list_model_finalize (GObject *object)
92 {
93         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*) object;
94
95         g_mutex_lock (me->iterator_lock);
96         if (me->first) {
97                 if (me->first_needs_unref)
98                         g_list_foreach (me->first, (GFunc)g_object_unref, NULL);
99                 me->first_needs_unref = FALSE;
100                 g_list_free (me->first);
101         }
102         me->first = NULL;
103         g_mutex_unlock (me->iterator_lock);
104
105         g_mutex_free (me->iterator_lock);
106
107         (*parent_class->finalize) (object);
108 }
109
110 static void
111 tny_gtk_account_list_model_class_init (TnyGtkAccountListModelClass *class)
112 {
113         GObjectClass *object_class;
114
115         parent_class = g_type_class_peek_parent (class);
116         object_class = (GObjectClass*) class;
117
118         object_class->finalize = tny_gtk_account_list_model_finalize;
119
120         return;
121 }
122
123 static void
124 tny_gtk_account_list_model_instance_init (GTypeInstance *instance, gpointer g_class)
125 {
126         GtkListStore *store = (GtkListStore*) instance;
127         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*) instance;
128         static GType types[] = { G_TYPE_STRING, G_TYPE_OBJECT };
129
130         me->iterator_lock = g_mutex_new ();
131         me->first = NULL;
132         me->first_needs_unref = FALSE;
133
134         gtk_list_store_set_column_types (store,
135                 TNY_GTK_ACCOUNT_LIST_MODEL_N_COLUMNS, types);
136
137         return;
138 }
139
140 static TnyIterator*
141 tny_gtk_account_list_model_create_iterator (TnyList *self)
142 {
143         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
144
145         /* Return a new iterator */
146
147         return TNY_ITERATOR (_tny_gtk_account_list_model_iterator_new (me));
148 }
149
150
151
152 static void
153 tny_gtk_account_list_model_prepend (TnyList *self, GObject* item)
154 {
155         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
156         GtkListStore *store = GTK_LIST_STORE (me);
157         GtkTreeIter iter;
158         TnyAccount *account = TNY_ACCOUNT (item);
159
160         g_mutex_lock (me->iterator_lock);
161         gtk_list_store_prepend (store, &iter);
162         gtk_list_store_set (store, &iter,
163                 TNY_GTK_ACCOUNT_LIST_MODEL_NAME_COLUMN, tny_account_get_name (account),
164                 TNY_GTK_ACCOUNT_LIST_MODEL_INSTANCE_COLUMN, account, -1);
165         me->first = g_list_prepend (me->first, item);   
166         g_mutex_unlock (me->iterator_lock);
167 }
168
169 static void
170 tny_gtk_account_list_model_append (TnyList *self, GObject* item)
171 {
172         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
173         GtkListStore *store = GTK_LIST_STORE (me);
174         GtkTreeIter iter;
175         TnyAccount *account = TNY_ACCOUNT (item);
176
177         g_mutex_lock (me->iterator_lock);
178         gtk_list_store_append (store, &iter);
179         gtk_list_store_set (store, &iter,
180                 TNY_GTK_ACCOUNT_LIST_MODEL_NAME_COLUMN, tny_account_get_name (account),
181                 TNY_GTK_ACCOUNT_LIST_MODEL_INSTANCE_COLUMN, account, -1);   
182         me->first = g_list_append (me->first, item);   
183         g_mutex_unlock (me->iterator_lock);
184 }
185
186 static guint
187 tny_gtk_account_list_model_get_length (TnyList *self)
188 {
189         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
190         guint retval = 0;
191
192         g_mutex_lock (me->iterator_lock);
193         retval = me->first?g_list_length (me->first):0;
194         g_mutex_unlock (me->iterator_lock);
195
196         return retval;
197 }
198
199 static void
200 tny_gtk_account_list_model_remove (TnyList *self, GObject* item)
201 {
202         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
203         GtkTreeModel *model = GTK_TREE_MODEL (me);
204         GtkTreeIter iter;
205
206         g_return_if_fail (G_IS_OBJECT (item));
207         g_return_if_fail (G_IS_OBJECT (me));
208
209         /* Remove something from the list */
210
211         g_mutex_lock (me->iterator_lock);
212
213         me->first = g_list_remove (me->first, (gconstpointer)item);
214
215         if (gtk_tree_model_get_iter_first (model, &iter))
216           do
217           {
218
219                 GObject *citem;
220
221                 gtk_tree_model_get (model, &iter,
222                         TNY_GTK_ACCOUNT_LIST_MODEL_INSTANCE_COLUMN,
223                         &citem, -1);
224
225                 if (citem == item)
226                 {
227                         gtk_list_store_remove (GTK_LIST_STORE (me), &iter);
228                         g_object_unref (citem);
229                         break;
230                 }
231                 g_object_unref (citem);
232           } while (gtk_tree_model_iter_next (model, &iter));
233
234         g_mutex_unlock (me->iterator_lock);
235 }
236
237 static void
238 tny_gtk_account_list_model_foreach_in_the_list (TnyList *self, GFunc func, gpointer user_data)
239 {
240         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
241
242         /* Foreach item in the list (without using a slower iterator) */
243
244         g_mutex_lock (me->iterator_lock);
245         g_list_foreach (me->first, func, user_data);
246         g_mutex_unlock (me->iterator_lock);
247
248         return;
249 }
250
251
252 static TnyList*
253 tny_gtk_account_list_model_copy_the_list (TnyList *self)
254 {
255         TnyGtkAccountListModel *me = (TnyGtkAccountListModel*)self;
256         TnyGtkAccountListModel *copy = g_object_new (TNY_TYPE_GTK_ACCOUNT_LIST_MODEL, NULL);
257         GList *list_copy = NULL;
258
259         g_mutex_lock (me->iterator_lock);
260         list_copy = g_list_copy (me->first);
261         g_list_foreach (list_copy, (GFunc)g_object_ref, NULL);
262         copy->first_needs_unref = TRUE;
263         copy->first = list_copy;
264         g_mutex_unlock (me->iterator_lock);   
265
266         return TNY_LIST (copy);
267 }
268
269 static void
270 tny_list_init (TnyListIface *klass)
271 {
272         klass->get_length= tny_gtk_account_list_model_get_length;
273         klass->prepend= tny_gtk_account_list_model_prepend;
274         klass->append= tny_gtk_account_list_model_append;
275         klass->remove= tny_gtk_account_list_model_remove;
276         klass->create_iterator= tny_gtk_account_list_model_create_iterator;
277         klass->copy= tny_gtk_account_list_model_copy_the_list;
278         klass->foreach= tny_gtk_account_list_model_foreach_in_the_list;
279
280         return;
281 }
282
283 static gpointer
284 tny_gtk_account_list_model_register_type (gpointer notused)
285 {
286         GType type = 0;
287
288         static const GTypeInfo info =
289                 {
290                   sizeof (TnyGtkAccountListModelClass),
291                   NULL,   /* base_init */
292                   NULL,   /* base_finalize */
293                   (GClassInitFunc) tny_gtk_account_list_model_class_init,   /* class_init */
294                   NULL,   /* class_finalize */
295                   NULL,   /* class_data */
296                   sizeof (TnyGtkAccountListModel),
297                   0,      /* n_preallocs */
298                   tny_gtk_account_list_model_instance_init,    /* instance_init */
299                   NULL
300                 };
301
302         static const GInterfaceInfo tny_list_info = {
303                 (GInterfaceInitFunc) tny_list_init,
304                 NULL,
305                 NULL
306         };
307
308         type = g_type_register_static (GTK_TYPE_LIST_STORE, "TnyGtkAccountListModel",
309                                        &info, 0);
310
311         g_type_add_interface_static (type, TNY_TYPE_LIST,
312                                      &tny_list_info);
313
314         return GUINT_TO_POINTER (type);
315 }
316
317 /**
318  * tny_gtk_account_list_model_get_type:
319  *
320  * GType system helper function
321  *
322  * returns: a #GType
323  **/
324 GType
325 tny_gtk_account_list_model_get_type (void)
326 {
327         static GOnce once = G_ONCE_INIT;
328         g_once (&once, tny_gtk_account_list_model_register_type, NULL);
329         return GPOINTER_TO_UINT (once.retval);
330 }
331
332 static gpointer
333 tny_gtk_account_list_model_column_register_type (gpointer notused)
334 {
335   GType etype = 0;
336   static const GEnumValue values[] = {
337       { TNY_GTK_ACCOUNT_LIST_MODEL_NAME_COLUMN, "TNY_GTK_ACCOUNT_LIST_MODEL_NAME_COLUMN", "name" },
338       { TNY_GTK_ACCOUNT_LIST_MODEL_INSTANCE_COLUMN, "TNY_GTK_ACCOUNT_LIST_MODEL_INSTANCE_COLUMN", "instance" },
339       { TNY_GTK_ACCOUNT_LIST_MODEL_N_COLUMNS, "TNY_GTK_ACCOUNT_LIST_MODEL_N_COLUMNS", "n" },
340       { 0, NULL, NULL }
341   };
342   etype = g_enum_register_static ("TnyGtkAccountListModelColumn", values);
343   return GUINT_TO_POINTER (etype);
344 }
345
346 /**
347  * tny_gtk_account_list_model_column_get_type:
348  *
349  * GType system helper function
350  *
351  * returns: a #GType
352  **/
353 GType
354 tny_gtk_account_list_model_column_get_type (void)
355 {
356         static GOnce once = G_ONCE_INIT;
357         g_once (&once, tny_gtk_account_list_model_column_register_type, NULL);
358         return GPOINTER_TO_UINT (once.retval);
359 }
Note: See TracBrowser for help on using the browser.