1 /*
2 * RAL -- Rubrica Addressbook Library
3 * file: groups.c
4 *
5 * Copyright (C) Nicola Fragale <nicolafragale@libero.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include <time.h>
22 #include <glib.h>
23 #include <glib-object.h>
24
25 #include "group_box.h"
26 #include "group.h"
27
28 enum {
29 GROUP_ADDED,
30 GROUP_REMOVED,
31 GROUP_MODIFYED,
32
33 LAST_SIGNAL
34 };
35
36 static guint r_group_box_signals[LAST_SIGNAL] = {0};
37
38
39 struct _RGroupBoxPrivate {
40 GList* lst;
41 GList* iter;
42 GList* find;
43
44 gboolean dispose_has_run;
45 };
46
47
48 static void r_group_box_class_init (RGroupBoxClass* klass);
49 static void r_group_box_init (RGroupBox* obj);
50
51 static void r_group_box_dispose (RGroupBox* obj);
52 static void r_group_box_finalize (RGroupBox* obj);
53
54 /* Private
55 */
56 static gboolean delete_group(RGroupBox* box, gchar* name);
57
58
59 GType
r_group_box_get_type()60 r_group_box_get_type()
61 {
62 static GType group_box_type = 0;
63
64 if (!group_box_type)
65 {
66 static const GTypeInfo group_box_info =
67 {
68 sizeof(RGroupBoxClass),
69 NULL,
70 NULL,
71 (GClassInitFunc) r_group_box_class_init,
72 NULL,
73 NULL,
74 sizeof(RGroupBox),
75 0,
76 (GInstanceInitFunc) r_group_box_init
77 };
78
79 group_box_type = g_type_register_static (G_TYPE_OBJECT,
80 "RGroupBox",
81 &group_box_info, 0);
82 }
83
84 return group_box_type;
85 }
86
87
88 static void
r_group_box_class_init(RGroupBoxClass * klass)89 r_group_box_class_init(RGroupBoxClass* klass)
90 {
91 GObjectClass *class;
92
93 class = G_OBJECT_CLASS (klass);
94 class->dispose = (GObjectFinalizeFunc) r_group_box_dispose;
95 class->finalize = (GObjectFinalizeFunc) r_group_box_finalize;
96
97
98 /* class signals */
99 /**
100 * RGroupBox::group-added
101 * @box: the #RGroupBox that receives the signal
102 * @group: the group added to the box
103 *
104 * signal emitted when a new group is added to the group's box.
105 */
106 r_group_box_signals[GROUP_ADDED] =
107 g_signal_new("group_added",
108 R_GROUP_BOX_TYPE,
109 G_SIGNAL_RUN_LAST,
110 G_STRUCT_OFFSET(RGroupBoxClass, group_added),
111 NULL,
112 NULL,
113 g_cclosure_marshal_VOID__INT,
114 G_TYPE_NONE, /* return type */
115 1, /* params */
116 G_TYPE_POINTER); /* params type */
117
118 /**
119 * RGroupbox::group-removed
120 * @set: the #RGroupBox that receives the signal
121 * @group: the group removed from the set
122 *
123 * signal emitted when a group is removed from the group's set.
124 */
125 r_group_box_signals[GROUP_REMOVED] =
126 g_signal_new("group_removed",
127 R_GROUP_BOX_TYPE,
128 G_SIGNAL_RUN_LAST,
129 G_STRUCT_OFFSET(RGroupBoxClass, group_removed),
130 NULL,
131 NULL,
132 g_cclosure_marshal_VOID__INT,
133 G_TYPE_NONE, /* return type */
134 1, /* params */
135 G_TYPE_INT); /* params type */
136
137 /**
138 * RGroupbox::group-remamed
139 * @set: the #RGroupBox that receives the signal
140 * @group: the group remamed from the set
141 *
142 * signal emitted when a group is removed from the group's set.
143 */
144 r_group_box_signals[GROUP_MODIFYED] =
145 g_signal_new("group_modifyed",
146 R_GROUP_BOX_TYPE,
147 G_SIGNAL_RUN_LAST,
148 G_STRUCT_OFFSET(RGroupBoxClass, group_removed),
149 NULL,
150 NULL,
151 g_cclosure_marshal_VOID__INT,
152 G_TYPE_NONE, /* return type */
153 1, /* params */
154 G_TYPE_POINTER); /* params type */
155 }
156
157
158 static void
r_group_box_init(RGroupBox * self)159 r_group_box_init(RGroupBox* self)
160 {
161 self->priv = g_new(RGroupBoxPrivate, 1);
162
163 self->priv->lst = NULL;
164 self->priv->iter = NULL;
165 self->priv->dispose_has_run = FALSE;
166 }
167
168
169
170 static void
r_group_box_dispose(RGroupBox * self)171 r_group_box_dispose (RGroupBox* self)
172 {
173 GList* list;
174
175 g_return_if_fail(IS_R_GROUP_BOX(self));
176
177 if (self->priv->dispose_has_run)
178 return;
179
180 for (list = self->priv->lst; list; list = g_list_next(list))
181 r_group_free(R_GROUP(list->data));
182
183 g_list_free(self->priv->lst);
184
185 self->priv->dispose_has_run = TRUE;
186 }
187
188
189 static void
r_group_box_finalize(RGroupBox * self)190 r_group_box_finalize (RGroupBox* self)
191 {
192 g_return_if_fail(IS_R_GROUP_BOX(self));
193
194 g_free(self->priv);
195 self->priv = NULL;
196 }
197
198
199 static gboolean
delete_group(RGroupBox * box,gchar * name)200 delete_group(RGroupBox* box, gchar* name)
201 {
202 gint id;
203
204 box->priv->iter = box->priv->lst;
205 for (; box->priv->iter; box->priv->iter = box->priv->iter->next)
206 {
207 RGroup* group = box->priv->iter->data;
208
209 if (r_group_has_name(R_GROUP(group), name))
210 {
211 g_object_get(group, "id", &id, NULL);
212
213 box->priv->lst = g_list_remove_link(box->priv->lst, box->priv->iter);
214
215 r_group_free(R_GROUP(box->priv->iter->data));
216
217 g_list_free_1(box->priv->iter);
218 box->priv->iter = NULL;
219
220 g_signal_emit_by_name(box, "group_removed", id, G_TYPE_INT);
221
222 return TRUE;
223 }
224 }
225
226 return FALSE;
227 }
228
229
230 /* Public
231 */
232
233 /**
234 * r_group_box_
235 * @box: a #RGroupBox
236 *
237 * create a new #RGroupBox
238 *
239 * returns: a new allocated #RGroupBox*
240 */
241 RGroupBox*
r_group_box_new(void)242 r_group_box_new(void)
243 {
244 RGroupBox* box;
245
246 box = g_object_new(r_group_box_get_type(), NULL);
247
248 return box;
249 }
250
251
252 /**
253 * r_group_box_free
254 * @box: a #RGroupBox
255 *
256 * free memory owned by a #RGroupBox
257 */
258 void
r_group_box_free(RGroupBox * box)259 r_group_box_free(RGroupBox* box)
260 {
261 g_return_if_fail(IS_R_GROUP_BOX(box));
262
263 g_object_unref(box);
264 }
265
266
267 /**
268 * r_group_box_is_empty
269 * @box: a #RGroupBox
270 *
271 * Test if the given group_box is empty
272 *
273 * Returns: %TRUE if the box is empty, %FALSE otherwise
274 */
275 gboolean
r_group_box_is_empty(RGroupBox * box)276 r_group_box_is_empty (RGroupBox* box)
277 {
278 g_return_val_if_fail(IS_R_GROUP_BOX(box), TRUE);
279
280 return (box->priv->lst == NULL);
281 }
282
283
284 /**
285 * r_group_box_find
286 * @box: a #RGroupBox
287 * @group_name: a #RGroup's name
288 *
289 * find a group by name
290 *
291 * returns: a gpointer to the group with the given name, or %NULL if
292 * box haven't the group.
293 */
294 gpointer
r_group_box_find(RGroupBox * box,const gchar * group_name)295 r_group_box_find (RGroupBox* box, const gchar* group_name)
296 {
297 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
298 g_return_val_if_fail(group_name != NULL, NULL);
299
300 box->priv->find = box->priv->lst;
301 for (; box->priv->find; box->priv->find = box->priv->find->next)
302 {
303 RGroup* grp = box->priv->find->data;
304
305 if (r_group_has_name(R_GROUP(grp), group_name))
306 return (gpointer) grp;
307 }
308
309 return NULL;
310 }
311
312
313 /**
314 * r_group_box_find_groups_owned_by
315 * @box: a #RGroupBox
316 * @owner: a gchar*
317 *
318 * search for all groups owned by the given "owner"
319 *
320 * Returns: a #GList of #RGroup or NULL
321 */
322 GList*
r_group_box_find_groups_owned_by(RGroupBox * box,const gchar * owner)323 r_group_box_find_groups_owned_by (RGroupBox* box, const gchar* owner)
324 {
325 GList* ret = NULL;
326
327 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
328 g_return_val_if_fail(owner != NULL, NULL);
329
330 box->priv->find = box->priv->lst;
331 for (; box->priv->find; box->priv->find = box->priv->find->next)
332 {
333 RGroup* grp = box->priv->find->data;
334
335 if (r_group_has_owner(R_GROUP(grp), owner))
336 ret = g_list_append(ret, grp);
337 }
338
339 return ret;
340 }
341
342
343 /**
344 * r_group_box_owns_group
345 * @box: a #RGroupBox
346 * @group_name: a #RGroup's name
347 *
348 * test if box owns the given group
349 *
350 * returns: a gboolean, %TRUE if box owns group, %FALSE otherwise
351 */
352 gboolean
r_group_box_owns_group(RGroupBox * box,const gchar * group_name)353 r_group_box_owns_group (RGroupBox* box, const gchar* group_name)
354 {
355 g_return_val_if_fail(IS_R_GROUP_BOX(box), FALSE);
356 g_return_val_if_fail(group_name != NULL, FALSE);
357
358 if (r_group_box_find(box, group_name))
359 return TRUE;
360
361 return FALSE;
362 }
363
364
365 /**
366 * r_group_box_add_group
367 * @box: a #RGroupBox
368 * @group: a #RGroup
369 *
370 * add the group to te box
371 *
372 * returns: a gboolean. %TRUE if group if added successfully, %FALSE otherwise
373 */
374 gboolean
r_group_box_add_group(RGroupBox * box,RGroup * group)375 r_group_box_add_group (RGroupBox* box, RGroup* group)
376 {
377 gchar* name;
378
379 g_return_val_if_fail(IS_R_GROUP_BOX(box), FALSE);
380 g_return_val_if_fail(IS_R_GROUP(group), FALSE);
381
382 /* test if group is already known
383 */
384 g_object_get(group, "group-name", &name, NULL);
385 if (r_group_box_owns_group(box, name))
386 return TRUE;
387
388 /* else add to the box
389 */
390 box->priv->lst = g_list_append(box->priv->lst, group);
391
392 /* init group iterator */
393 if (!box->priv->iter)
394 box->priv->iter = box->priv->lst;
395
396 g_signal_emit_by_name(box, "group_added", group, G_TYPE_POINTER);
397
398 return TRUE;
399 }
400
401
402 /**
403 * r_group_box_delete_group_by_name
404 * @box: a #RGroupBox
405 * @name: group's name
406 *
407 * delete a group from box
408 *
409 * returns: a gboolean. %TRUE if group is deleted, %FALSE otherwise
410 */
411 gboolean
r_group_box_delete_group_by_name(RGroupBox * box,gchar * name)412 r_group_box_delete_group_by_name (RGroupBox* box, gchar* name)
413 {
414 g_return_val_if_fail(IS_R_GROUP_BOX(box), FALSE);
415 g_return_val_if_fail(name != NULL, FALSE);
416
417 return delete_group(box, name);
418 }
419
420
421 /**
422 * r_group_box_delete_group
423 * @box: a #RGroupBox
424 * @group: a #RGroup
425 *
426 * delete a group from box
427 *
428 * returns: a gboolean. %TRUE if group is deleted, %FALSE otherwise
429 */
430 gboolean
r_group_box_delete_group(RGroupBox * box,RGroup * group)431 r_group_box_delete_group (RGroupBox* box, RGroup* group)
432 {
433 gchar* name;
434
435 g_return_val_if_fail(IS_R_GROUP_BOX(box), FALSE);
436 g_return_val_if_fail(IS_R_GROUP(group), FALSE);
437
438 g_object_get(group, "group-name", &name, NULL);
439
440 return r_group_box_delete_group_by_name(box, name);
441 }
442
443
444 /**
445 * r_group_box_modify_group_name
446 * @box: a #RGroupBox
447 * @oldname:
448 * @newname:
449 *
450 * rename a group in the box
451 *
452 * returns: a gboolean. %TRUE if group is modifyed, %FALSE otherwise
453 * If group is modifyed, the "group_modifyed" signal is emitted
454 */
455 gboolean
r_group_box_modify_group_name(RGroupBox * box,gchar * oldname,gchar * newname)456 r_group_box_modify_group_name (RGroupBox* box, gchar* oldname, gchar* newname)
457 {
458 RGroup* group;
459 // gint id;
460
461 g_return_val_if_fail(IS_R_GROUP_BOX(box), FALSE);
462 g_return_val_if_fail(oldname != NULL, FALSE);
463 g_return_val_if_fail(newname != NULL, FALSE);
464
465 group = r_group_box_find(box, oldname);
466 if (r_group_rename(group, newname))
467 {
468 g_object_set(group, "group-label", newname, NULL);
469 // g_object_get(group, "id", &id, NULL);
470
471 g_signal_emit_by_name(box, "group_modifyed", group, G_TYPE_POINTER);
472
473 return TRUE;
474 }
475
476 return FALSE;
477 }
478
479 /**
480 * r_group_box_modify_group_pixmap
481 * @box: a #RGroupBox
482 * @group_name:
483 * @newpixmap:
484 *
485 * modify the group's pixmap
486 *
487 * returns: a gboolean. %TRUE if group is modifyed, %FALSE otherwise.
488 * If group is modifyed, the "group_modifyed" signal is emitted
489 */
490 gboolean
r_group_box_modify_group_pixmap(RGroupBox * box,gchar * group_name,gchar * newpixmap)491 r_group_box_modify_group_pixmap (RGroupBox* box, gchar* group_name,
492 gchar* newpixmap)
493 {
494 RGroup* group;
495
496 g_return_val_if_fail(IS_R_GROUP_BOX(box), FALSE);
497 g_return_val_if_fail(group_name != NULL, FALSE);
498 g_return_val_if_fail(newpixmap != NULL, FALSE);
499
500 group = r_group_box_find(box, group_name);
501 if (r_group_change_pixmap (group, newpixmap))
502 {
503 g_signal_emit_by_name(box, "group_modifyed", group, G_TYPE_POINTER);
504
505 return TRUE;
506 }
507
508 return FALSE;
509 }
510
511
512 /**
513 * r_group_box_disable_all
514 * @box: a #RGroupBox
515 *
516 * disable all groups in box
517 */
518 void
r_group_box_disable_all(RGroupBox * box)519 r_group_box_disable_all (RGroupBox* box)
520 {
521 RGroup* group;
522
523 g_return_if_fail(IS_R_GROUP_BOX(box));
524
525 r_group_box_reset(box);
526 group = r_group_box_get_group(box);
527 for(; group; group = r_group_box_get_next_group(box))
528 g_object_set(group, "enabled", FALSE, NULL);
529 }
530
531
532 /**
533 * r_group_box_enable_group
534 * @box: a #RGroupBox
535 * @group: a #RGroup
536 *
537 * enable the given group
538 */
539 void
r_group_box_enable_group(RGroupBox * box,RGroup * grp)540 r_group_box_enable_group (RGroupBox* box, RGroup* grp)
541 {
542 gchar* name;
543 RGroup* group = NULL;
544
545 g_return_if_fail(IS_R_GROUP_BOX(box));
546 g_return_if_fail(IS_R_GROUP(grp));
547
548 g_object_get(grp, "group-name", &name, NULL);
549 group = r_group_box_find(box, name);
550
551 if (group)
552 g_object_set(group, "enabled", TRUE, NULL);
553 }
554
555
556 /**
557 * r_group_box_disable_group
558 * @box: a #RGroupBox
559 * @group: a #RGroup
560 *
561 * disable the given group
562 */
563 void
r_group_box_disable_group(RGroupBox * box,RGroup * grp)564 r_group_box_disable_group (RGroupBox* box, RGroup* grp)
565 {
566 gchar* name;
567 RGroup* group = NULL;
568
569 g_return_if_fail(IS_R_GROUP_BOX(box));
570 g_return_if_fail(IS_R_GROUP(grp));
571
572 g_object_get(grp, "group-name", &name, NULL);
573 group = r_group_box_find(box, name);
574 if (group)
575 g_object_set(group, "enabled", FALSE, NULL);
576 }
577
578
579
580
581 /**
582 * r_group_box_merge_boxes
583 * @box: a #RGroupBox
584 * @second: a #RGroupBox
585 *
586 * merges the #RGroupBoxs
587 *
588 *returns: a RGroupBox*
589 */
590 RGroupBox*
r_group_box_merge_boxes(RGroupBox * box,RGroupBox * second)591 r_group_box_merge_boxes (RGroupBox* box, RGroupBox* second)
592 {
593 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
594 g_return_val_if_fail(IS_R_GROUP_BOX(second), box);
595
596 box->priv->lst = g_list_concat(box->priv->lst, second->priv->lst);
597
598 return box;
599 }
600
601
602 /**
603 * r_group_box_reset
604 * @box: a #RGroupBox
605 *
606 * reset the private #RGroupBox iterator to the head of group's list.
607 */
608 void
r_group_box_reset(RGroupBox * box)609 r_group_box_reset(RGroupBox* box)
610 {
611 g_return_if_fail(IS_R_GROUP_BOX(box));
612
613 box->priv->iter = box->priv->lst;
614 }
615
616
617 /**
618 * r_group_box_get_group
619 * @box: a #RGroupBox
620 *
621 * get the first group in box
622 *
623 * returns: a gpointer or NULL if box is void
624 */
625 RGroup*
r_group_box_get_group(RGroupBox * box)626 r_group_box_get_group (RGroupBox* box)
627 {
628 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
629
630 if (box->priv->iter)
631 return (RGroup*) box->priv->iter->data;
632
633 return NULL;
634 }
635
636
637 /**
638 * r_group_box_get_next_group
639 * @box: a #RGroupBox
640 *
641 * get the next group in box.
642 *
643 * returns: a gpointer or NULL if the groups's end list is reached.
644 */
645 RGroup*
r_group_box_get_next_group(RGroupBox * box)646 r_group_box_get_next_group (RGroupBox* box)
647 {
648 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
649
650 box->priv->iter = g_list_next(box->priv->iter);
651 if (box->priv->iter)
652 return (RGroup*) box->priv->iter->data;
653 else
654 box->priv->iter = box->priv->lst;
655
656 return NULL;
657 }
658
659
660 /**
661 * r_group_box_get_prev_group
662 * @box: a #RGroupBox
663 *
664 * get the previous group in box.
665 *
666 * returns: a gpointer or NULL if the groups's head list is reached.
667 */
668 RGroup*
r_group_box_get_prev_group(RGroupBox * box)669 r_group_box_get_prev_group (RGroupBox* box)
670 {
671 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
672
673 g_return_val_if_fail(IS_R_GROUP_BOX(box), NULL);
674
675 box->priv->iter = g_list_previous(box->priv->iter);
676 if (box->priv->iter)
677 return (RGroup*) box->priv->iter->data;
678 else
679 box->priv->iter = box->priv->lst;
680
681 return NULL;
682 }
683
684
685
686
687
688
689
690