Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / servers / exchange / storage / e-folder.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* e-folder.c
3  *
4  * Copyright (C) 2000, 2001, 2002  Ximian, Inc.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU Lesser General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  * Author: Ettore Perazzoli
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "e-folder.h"
28
29 #include <string.h>
30 #include <glib.h>
31 #include <libedataserver/e-data-server-util.h>
32
33 #define PARENT_TYPE G_TYPE_OBJECT
34 static GObjectClass *parent_class = NULL;
35
36 struct EFolderPrivate {
37         char *name;
38         char *type;
39         char *description;
40         char *physical_uri;
41
42         int child_highlight;
43         int unread_count;
44
45         /* Folders have a default sorting priority of zero; when deciding the
46            sort order in the Evolution folder tree, folders with the same
47            priority value are compared by name, while folders with a higher
48            priority number always come after the folders with a lower priority
49            number.  */
50         int sorting_priority;
51
52         unsigned int self_highlight : 1;
53         unsigned int is_stock : 1;
54         unsigned int can_sync_offline : 1;
55         unsigned int has_subfolders : 1;
56
57         /* Custom icon for this folder; if NULL the folder will just use the
58            icon for its type.  */
59         char *custom_icon_name;
60 };
61
62 enum {
63         CHANGED,
64         NAME_CHANGED,
65         LAST_SIGNAL
66 };
67
68 static guint signals[LAST_SIGNAL] = { 0 };
69
70 /* EFolder methods.   */
71
72 static gboolean
73 accept_drop (EFolder *folder, GdkDragContext *context,
74              const char *target_type,
75              GtkSelectionData *selection_data)
76 {
77         return FALSE;
78 }
79
80
81 /* GObject methods.  */
82
83 static void
84 impl_finalize (GObject *object)
85 {
86         EFolder *folder;
87         EFolderPrivate *priv;
88
89         folder = E_FOLDER (object);
90         priv = folder->priv;
91
92         g_free (priv->name);
93         g_free (priv->type);
94         g_free (priv->description);
95         g_free (priv->physical_uri);
96
97         g_free (priv->custom_icon_name);
98
99         g_free (priv);
100
101         (* G_OBJECT_CLASS (parent_class)->finalize) (object);
102 }
103
104 static void
105 e_folder_class_init (EFolderClass *klass)
106 {
107         GObjectClass *object_class;
108
109         parent_class = g_type_class_ref (PARENT_TYPE);
110
111         object_class = G_OBJECT_CLASS (klass);
112         object_class->finalize = impl_finalize;
113
114         klass->accept_drop = accept_drop;
115         signals[CHANGED] = g_signal_new ("changed",
116                                          G_OBJECT_CLASS_TYPE (object_class),
117                                          G_SIGNAL_RUN_FIRST,
118                                          G_STRUCT_OFFSET (EFolderClass, changed),
119                                          NULL, NULL,
120                                          g_cclosure_marshal_VOID__VOID,
121                                          G_TYPE_NONE, 0);
122
123         signals[NAME_CHANGED] = g_signal_new ("name_changed",
124                                               G_OBJECT_CLASS_TYPE (object_class),
125                                               G_SIGNAL_RUN_FIRST,
126                                               G_STRUCT_OFFSET (EFolderClass, name_changed),
127                                               NULL, NULL,
128                                               g_cclosure_marshal_VOID__VOID,
129                                               G_TYPE_NONE, 0);
130 }
131
132 static void
133 e_folder_init (EFolder *folder)
134 {
135         EFolderPrivate *priv;
136
137         priv = g_new0 (EFolderPrivate, 1);
138         folder->priv = priv;
139 }
140
141 void
142 e_folder_construct (EFolder *folder,
143                     const char *name,
144                     const char *type,
145                     const char *description)
146 {
147         EFolderPrivate *priv;
148
149         g_return_if_fail (E_IS_FOLDER (folder));
150         g_return_if_fail (name != NULL);
151         g_return_if_fail (type != NULL);
152
153         priv = folder->priv;
154
155         priv->name        = g_strdup (name);
156         priv->type        = g_strdup (type);
157         priv->description = g_strdup (description);
158 }
159
160 EFolder *
161 e_folder_new (const char *name,
162               const char *type,
163               const char *description)
164 {
165         EFolder *folder;
166
167         g_return_val_if_fail (name != NULL, NULL);
168         g_return_val_if_fail (type != NULL, NULL);
169         g_return_val_if_fail (description != NULL, NULL);
170
171         folder = g_object_new (E_TYPE_FOLDER, NULL);
172
173         e_folder_construct (folder, name, type, description);
174
175         return folder;
176 }
177
178 const char *
179 e_folder_get_name (EFolder *folder)
180 {
181         g_return_val_if_fail (E_IS_FOLDER (folder), NULL);
182
183         return folder->priv->name;
184 }
185
186 const char *
187 e_folder_get_type_string (EFolder *folder)
188 {
189         g_return_val_if_fail (E_IS_FOLDER (folder), NULL);
190
191         return folder->priv->type;
192 }
193
194 const char *
195 e_folder_get_description (EFolder *folder)
196 {
197         g_return_val_if_fail (E_IS_FOLDER (folder), NULL);
198
199         return folder->priv->description;
200 }
201
202 const char *
203 e_folder_get_physical_uri (EFolder *folder)
204 {
205         g_return_val_if_fail (E_IS_FOLDER (folder), NULL);
206
207         return folder->priv->physical_uri;
208 }
209
210 int
211 e_folder_get_unread_count (EFolder *folder)
212 {
213         g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
214
215         return folder->priv->unread_count;
216 }
217
218 gboolean
219 e_folder_get_highlighted (EFolder *folder)
220 {
221         g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
222
223         return folder->priv->child_highlight || folder->priv->unread_count;
224 }
225
226 gboolean
227 e_folder_get_is_stock (EFolder *folder)
228 {
229         g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
230
231         return folder->priv->is_stock;
232 }
233
234 gboolean
235 e_folder_get_can_sync_offline (EFolder *folder)
236 {
237         g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
238
239         return folder->priv->can_sync_offline;
240 }
241
242 gboolean
243 e_folder_get_has_subfolders (EFolder *folder)
244 {
245         g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
246
247         return folder->priv->has_subfolders;
248 }
249
250 /**
251  * e_folder_get_custom_icon:
252  * @folder: An EFolder
253  * 
254  * Get the name of the custom icon for @folder, or NULL if no custom icon is
255  * associated with it.
256  **/
257 const char *
258 e_folder_get_custom_icon_name (EFolder *folder)
259 {
260         g_return_val_if_fail (E_IS_FOLDER (folder), NULL);
261
262         return folder->priv->custom_icon_name;
263 }
264
265 /**
266  * e_folder_get_sorting_priority:
267  * @folder: An EFolder
268  * 
269  * Get the sorting priority for @folder.
270  * 
271  * Return value: Sorting priority value for @folder.
272  **/
273 int
274 e_folder_get_sorting_priority (EFolder *folder)
275 {
276         g_return_val_if_fail (E_IS_FOLDER (folder), 0);
277
278         return folder->priv->sorting_priority;
279 }
280
281 void
282 e_folder_set_name (EFolder *folder,
283                    const char *name)
284 {
285         g_return_if_fail (E_IS_FOLDER (folder));
286         g_return_if_fail (name != NULL);
287
288         if (folder->priv->name == name)
289                 return;
290
291         g_free (folder->priv->name);
292         folder->priv->name = g_strdup (name);
293
294         g_signal_emit (folder, signals[NAME_CHANGED], 0);
295         g_signal_emit (folder, signals[CHANGED], 0);
296 }
297
298 void
299 e_folder_set_type_string (EFolder *folder,
300                           const char *type)
301 {
302         g_return_if_fail (E_IS_FOLDER (folder));
303         g_return_if_fail (type != NULL);
304
305         g_free (folder->priv->type);
306         folder->priv->type = g_strdup (type);
307
308         g_signal_emit (folder, signals[CHANGED], 0);
309 }
310
311 void
312 e_folder_set_description (EFolder *folder,
313                           const char *description)
314 {
315         g_return_if_fail (E_IS_FOLDER (folder));
316         g_return_if_fail (description != NULL);
317
318         g_free (folder->priv->description);
319         folder->priv->description = g_strdup (description);
320
321         g_signal_emit (folder, signals[CHANGED], 0);
322 }
323
324 void
325 e_folder_set_physical_uri (EFolder *folder,
326                            const char *physical_uri)
327 {
328         g_return_if_fail (E_IS_FOLDER (folder));
329         g_return_if_fail (physical_uri != NULL);
330
331         if (folder->priv->physical_uri == physical_uri)
332                 return;
333
334         g_free (folder->priv->physical_uri);
335         folder->priv->physical_uri = g_strdup (physical_uri);
336
337         g_signal_emit (folder, signals[CHANGED], 0);
338 }
339
340 void
341 e_folder_set_unread_count (EFolder *folder,
342                            gint unread_count)
343 {
344         g_return_if_fail (E_IS_FOLDER (folder));
345
346         folder->priv->unread_count = unread_count;
347
348         g_signal_emit (folder, signals[CHANGED], 0);
349 }
350
351 void
352 e_folder_set_child_highlight (EFolder *folder,
353                               gboolean highlighted)
354 {
355         g_return_if_fail (E_IS_FOLDER (folder));
356
357         if (highlighted)
358                 folder->priv->child_highlight++;
359         else
360                 folder->priv->child_highlight--;
361
362         g_signal_emit (folder, signals[CHANGED], 0);
363 }
364
365 void
366 e_folder_set_is_stock (EFolder *folder,
367                        gboolean is_stock)
368 {
369         g_return_if_fail (E_IS_FOLDER (folder));
370
371         folder->priv->is_stock = !! is_stock;
372
373         g_signal_emit (folder, signals[CHANGED], 0);
374 }
375
376 void
377 e_folder_set_can_sync_offline (EFolder *folder,
378                                gboolean can_sync_offline)
379 {
380         g_return_if_fail (E_IS_FOLDER (folder));
381
382         folder->priv->can_sync_offline = !! can_sync_offline;
383
384         g_signal_emit (folder, signals[CHANGED], 0);
385 }
386
387 void
388 e_folder_set_has_subfolders (EFolder *folder,
389                              gboolean has_subfolders)
390 {
391         g_return_if_fail (E_IS_FOLDER (folder));
392
393         folder->priv->has_subfolders = !! has_subfolders;
394
395         g_signal_emit (folder, signals[CHANGED], 0);
396 }
397
398 /**
399  * e_folder_set_custom_icon_name:
400  * @folder: An EFolder
401  * @icon_name: Name of the icon to be set (to be found in the standard
402  * Evolution icon dir)
403  * 
404  * Set a custom icon for @folder (thus overriding the default icon, which is
405  * the one associated to the type of the folder).
406  **/
407 void
408 e_folder_set_custom_icon (EFolder *folder,
409                           const char *icon_name)
410 {
411         g_return_if_fail (E_IS_FOLDER (folder));
412
413         if (icon_name == folder->priv->custom_icon_name)
414                 return;
415
416         if (folder->priv->custom_icon_name == NULL
417             || (icon_name != NULL && strcmp (icon_name, folder->priv->custom_icon_name) != 0)) {
418                 g_free (folder->priv->custom_icon_name);
419                 folder->priv->custom_icon_name = g_strdup (icon_name);
420
421                 g_signal_emit (folder, signals[CHANGED], 0);
422         }
423 }
424
425 /**
426  * e_folder_set_sorting_priority:
427  * @folder: An EFolder
428  * @sorting_priority: A sorting priority number
429  * 
430  * Set the sorting priority for @folder.  Folders have a default sorting
431  * priority of zero; when deciding the sort order in the Evolution folder tree,
432  * folders with the same priority value are compared by name, while folders
433  * with a higher priority number always come after the folders with a lower
434  * priority number.
435  **/
436 void
437 e_folder_set_sorting_priority (EFolder *folder,
438                                int sorting_priority)
439 {
440         g_return_if_fail (E_IS_FOLDER (folder));
441
442         if (folder->priv->sorting_priority == sorting_priority)
443                 return;
444
445         folder->priv->sorting_priority = sorting_priority;
446
447         g_signal_emit (folder, signals[CHANGED], 0);
448 }
449
450 gboolean
451 e_folder_accept_drop (EFolder *folder, GdkDragContext *context,
452                       const char *target_type,
453                       GtkSelectionData *selection_data)
454 {
455         g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
456         g_return_val_if_fail (context != NULL, FALSE);
457
458         return E_FOLDER_GET_CLASS (folder)->accept_drop (folder, context,
459                                                          target_type,
460                                                          selection_data);
461 }
462
463 G_DEFINE_TYPE (EFolder, e_folder, G_TYPE_OBJECT)