1 /*
2 *  RAL -- Rubrica Addressbook Library
3 *  file: card.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 <string.h>
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include "card.h"
27 #include "group_box.h"
28 #include "group.h"
29 #include "utils.h"
30 #include "ref.h"
31 
32 glong id = 0;
33 
34 
35 
36 /*  property enumeration
37 */
38 enum {
39   CARD_NAME = 1,
40   CARD_ID,
41   CARD_TYPE,
42   CARD_RATE,
43   CARD_LOCKED,
44   CARD_DELETED,
45   CARD_DESTROYED,
46   CARD_MARKED,
47   CARD_PRINTABLE,
48   CARD_CREATED,
49   CARD_CHANGED
50 };
51 
52 
53 struct _RCardPrivate {
54   glong      id;           /* card's unique id                 */
55 
56   gchar*     name;         /* card's name                      */
57   gchar*     type;         /* card's type                      */
58   RRate      rate;         /* card's rate                      */
59 
60   gboolean   locked;       /* true if card is locked           */
61   gboolean   deleted;      /* is card marked as deleted?       */
62   gboolean   destroyed;    /* is card marked as destroyed?     */
63   gboolean   marked;       /* true if card is marked           */
64   gboolean   printable;    /* card marked as to print          */
65 
66   RGroupBox* box;          /* card's groups set                */
67 
68   GList*     addresses;
69   GList*     nets;         /* web, email and irc uries         */
70   GList*     phones;
71 
72   GList*     refs;         /* references to other cards        */
73   GList*     linked;       /* cards that have a reference to this one */
74 
75   time_t     created;      /* card's creation time             */
76   time_t     changed;      /* card's last change time          */
77 
78   GList*     grp_iter;     /* groups, addresses, telephones,   */
79   GList*     addr_iter;    /* nets and refs iterators          */
80   GList*     net_iter;
81   GList*     phone_iter;
82   GList*     refs_iter;
83 
84   gboolean   dispose_has_run;
85 };
86 
87 
88 static void r_card_class_init   (RCardClass* klass);
89 static void r_card_init         (RCard* self);
90 
91 static void r_card_dispose      (RCard* self);
92 static void r_card_finalize     (RCard* self);
93 
94 static void r_card_set_property (GObject* obj, guint property_id,
95 				 const GValue* value, GParamSpec* spec);
96 static void r_card_get_property (GObject* obj, guint property_id,
97 				 GValue* value, GParamSpec* spec);
98 
99 
100 static void   r_card_copy_commons           (RCard* new,  RCard* old);
101 static void   r_card_copy_paste_group       (RCard* card, gpointer data);
102 static void   r_card_copy_paste_ref         (RCard* card, gpointer data);
103 static void   r_card_copy_paste_address     (RCard* card, gpointer data);
104 static void   r_card_copy_paste_net_address (RCard* card, gpointer data);
105 static void   r_card_copy_paste_telephone   (RCard* card, gpointer data);
106 
107 
108 /*  Private functions
109 */
110 GType
r_card_get_type()111 r_card_get_type()
112 {
113   static GType r_card_type = 0;
114 
115   if (!r_card_type)
116     {
117       static const GTypeInfo r_card_info =
118 	{
119 	  sizeof(RCardClass),
120 	  NULL,
121 	  NULL,
122 	  (GClassInitFunc) r_card_class_init,
123 	  NULL,
124 	  NULL,
125 	  sizeof(RCard),
126 	  0,
127 	  (GInstanceInitFunc) r_card_init
128 	};
129 
130       r_card_type = g_type_register_static (G_TYPE_OBJECT, "RCard",
131 					    &r_card_info, 0);
132     }
133 
134   return r_card_type;
135 }
136 
137 
138 static void
r_card_class_init(RCardClass * klass)139 r_card_class_init(RCardClass* klass)
140 {
141   GObjectClass *class;
142   GParamSpec* pspec;
143 
144   klass->free            = NULL;      /* free method, child will set */
145 
146   klass->copy            = NULL;      /* copy a card */
147   klass->search          = NULL;      /* search a string into the card */
148 
149   klass->get_infos       = NULL;      /* return infos on card record   */
150   klass->print_card      = NULL;      /* unused */
151 
152 
153   class = G_OBJECT_CLASS (klass);
154   class->dispose  = (GObjectFinalizeFunc) r_card_dispose;
155   class->finalize = (GObjectFinalizeFunc) r_card_finalize;
156 
157   class->set_property = r_card_set_property;
158   class->get_property = r_card_get_property;
159 
160   /**
161    * RCard:card-id:
162    *
163    * card's id
164    */
165   pspec = g_param_spec_long("card-id",
166 			    "card's id",
167 			    "the id of the card",
168 			    G_MINLONG,
169 			    G_MAXLONG,
170 			    0,
171 			    G_PARAM_READWRITE);
172   g_object_class_install_property(class, CARD_ID, pspec);
173 
174 
175   /**
176    * RCard:card-name:
177    *
178    * card's name
179    */
180   pspec = g_param_spec_string("card-name",
181 			      "card's name",
182 			      "the name of the card",
183 			      NULL,
184 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
185   g_object_class_install_property(class, CARD_NAME, pspec);
186 
187 
188   /**
189    * RCard:card-type:
190    *
191    * card's type
192    */
193   pspec = g_param_spec_string("card-type",
194 			      "card's type",
195 			      "card's type, must be \"personal\""
196 			      "or \"company\"",
197 			      NULL,
198 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
199   g_object_class_install_property(class, CARD_TYPE, pspec);
200 
201   /**
202    * RCard:rate:
203    *
204    * card's rate
205    */
206   pspec = g_param_spec_int("card-rate",
207 			   "card's rate",
208 			   "the rate user wants for the card",
209 			   R_RATE_NONE,
210 			   R_RATE_VERY_HIGH,
211 			   R_RATE_NORMAL,
212 			   G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
213   g_object_class_install_property(class, CARD_RATE, pspec);
214 
215   /**
216    * RCard:locked:
217    *
218    * is the card locked?
219    */
220   pspec = g_param_spec_boolean("card-locked",
221 			       "locked",
222 			       "is the card locked",
223 			       TRUE,
224 			       G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
225   g_object_class_install_property(class, CARD_LOCKED, pspec);
226 
227   /**
228    * RCard:deleted:
229    *
230    * is the card deleted?
231    */
232   pspec = g_param_spec_boolean("card-deleted",
233 			       "deleted",
234 			       "is the card deleted",
235 			       FALSE,
236 			       G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
237   g_object_class_install_property(class, CARD_DELETED, pspec);
238 
239   /**
240    * RCard:destroyed:
241    *
242    * is the card destroyed?
243    */
244   pspec = g_param_spec_boolean("card-destroyed",
245 			       "destroyed",
246 			       "is the card destroyed",
247 			       FALSE,
248 			       G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
249   g_object_class_install_property(class, CARD_DESTROYED, pspec);
250 
251 
252   /**
253    * RCard:marked:
254    *
255    * is the card marked?
256    */
257   pspec = g_param_spec_boolean("card-marked",
258 			       "marked",
259 			       "is the card marked",
260 			       FALSE,
261 			       G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
262   g_object_class_install_property(class, CARD_MARKED, pspec);
263 
264   /**
265    * RCard:printable:
266    *
267    * is the card set to be printed?
268    */
269   pspec = g_param_spec_boolean("card-printable",
270 			       "printable",
271 			       "is the card marked to be printed",
272 			       FALSE,
273 			       G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
274   g_object_class_install_property(class, CARD_PRINTABLE, pspec);
275 
276   /**
277    * RCard:creation:
278    *
279    * card's creation time
280    */
281   pspec = g_param_spec_int("card-created",
282 			   "card's creation time",
283 			   "the card's creation time",
284 			   G_MININT,
285 			   G_MAXINT,
286 			   -1,
287 			   G_PARAM_READWRITE);
288   g_object_class_install_property(class, CARD_CREATED, pspec);
289 
290   /**
291    * RCard:modification:
292    *
293    * card's modification time
294    */
295   pspec = g_param_spec_int("card-changed",
296 			   "card's modification time",
297 			   "last time that card was modified",
298 			   G_MININT,
299 			   G_MAXINT,
300 			   -1,
301 			   G_PARAM_READWRITE);
302   g_object_class_install_property(class, CARD_CHANGED, pspec);
303 }
304 
305 
306 static void
r_card_init(RCard * self)307 r_card_init(RCard* self)
308 {
309   self->priv = g_new(RCardPrivate, 1);
310 
311   self->priv->id         = ++id;
312 
313   self->priv->name       = NULL;
314   self->priv->type       = NULL;
315   self->priv->rate       = R_RATE_NORMAL;
316 
317   self->priv->box        = r_group_box_new();
318 
319   self->priv->locked     = FALSE;
320   self->priv->deleted    = FALSE;
321   self->priv->destroyed  = FALSE;
322   self->priv->marked     = FALSE;
323   self->priv->printable  = FALSE;
324 
325   self->priv->linked     = NULL;
326 
327   self->priv->addresses  = NULL;
328   self->priv->nets       = NULL;
329   self->priv->phones     = NULL;
330 
331   self->priv->refs       = NULL;
332 
333   self->priv->created    = time(NULL);
334   self->priv->changed    = time(NULL);
335 
336   self->priv->grp_iter   = NULL;
337   self->priv->addr_iter  = NULL;
338   self->priv->net_iter   = NULL;
339   self->priv->phone_iter = NULL;
340   self->priv->refs_iter  = NULL;
341 
342   self->priv->dispose_has_run = FALSE;
343 }
344 
345 
346 
347 static void
r_card_dispose(RCard * self)348 r_card_dispose (RCard* self)
349 {
350   GList* del;
351 
352   g_return_if_fail(IS_R_CARD(self));
353 
354   if (self->priv->dispose_has_run)
355     return;
356 
357   self->priv->dispose_has_run = TRUE;
358 
359   /* free card's children
360   */
361   R_CARD_CLASS(R_CARD_GET_CLASS(self))->free(self);
362 
363   /* free card's data
364    */
365   r_utils_free_string(self->priv->name);
366   r_utils_free_string(self->priv->type);
367   self->priv->name = NULL;
368   self->priv->type = NULL;
369 
370   /* groups */
371   r_group_box_free(R_GROUP_BOX(self->priv->box));
372 
373   /* addresses */
374   del = self->priv->addresses;
375   for (; del; del = del->next)
376     {
377       RAddress* address = del->data;;
378 
379       if(address)
380 	r_address_free(R_ADDRESS(address));
381     }
382   self->priv->addresses = NULL;
383 
384   /* net addresses */
385   del = self->priv->nets;
386   for (; del; del = del->next)
387     {
388       RNetAddress* net = del->data;;
389 
390       if(net)
391 	r_net_address_free(R_NET_ADDRESS(net));
392     }
393   self->priv->nets = NULL;
394 
395   /* telephone numbers */
396   del = self->priv->phones;
397   for (; del; del = del->next)
398     {
399       RTelephone* tel = del->data;;
400 
401       if(tel)
402 	r_telephone_free(R_TELEPHONE(tel));
403     }
404   self->priv->phones = NULL;
405 
406   /*  delete cards's references
407    */
408   for(; self->priv->refs_iter;
409       self->priv->refs_iter = self->priv->refs_iter->next)
410     if(self->priv->refs_iter->data)
411       {
412 	r_ref_free(R_REF(self->priv->refs_iter->data));
413 	// cancellare card del contatto ?
414       }
415 
416   g_list_free(self->priv->refs);
417   g_list_free(self->priv->refs_iter);
418   self->priv->refs = self->priv->refs_iter = NULL;
419 
420   self->priv->grp_iter   = NULL;
421   self->priv->addr_iter  = NULL;
422   self->priv->net_iter   = NULL;
423   self->priv->phone_iter = NULL;
424 }
425 
426 
427 static void
r_card_finalize(RCard * self)428 r_card_finalize (RCard* self)
429 {
430   g_return_if_fail(IS_R_CARD(self));
431 
432   g_free(self->priv);
433   self->priv = NULL;
434 }
435 
436 
437 static void
r_card_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * spec)438 r_card_set_property (GObject* obj, guint property_id,
439 		     const GValue* value, GParamSpec* spec)
440 {
441   RCard* self = (RCard*) obj;
442 
443   switch(property_id)
444     {
445     case CARD_ID:
446       self->priv->id = g_value_get_long(value);
447       break;
448 
449     case CARD_TYPE:
450       g_free(self->priv->type);
451       self->priv->type = g_value_dup_string(value);
452       break;
453 
454     case CARD_NAME:
455       g_free(self->priv->name);
456       self->priv->name = g_value_dup_string(value);
457       break;
458 
459     case CARD_RATE:
460       self->priv->rate = g_value_get_int(value);
461       break;
462 
463     case CARD_LOCKED:
464       self->priv->locked = g_value_get_boolean(value);
465       break;
466 
467     case CARD_DELETED:
468       self->priv->deleted = g_value_get_boolean(value);
469       break;
470 
471     case CARD_DESTROYED:
472       self->priv->destroyed = g_value_get_boolean(value);
473       break;
474 
475     case CARD_MARKED:
476       self->priv->marked = g_value_get_boolean(value);
477       break;
478 
479     case CARD_PRINTABLE:
480       self->priv->printable = g_value_get_boolean(value);
481       break;
482 
483      case CARD_CREATED:
484       self->priv->created = g_value_get_int(value);
485       break;
486 
487     case CARD_CHANGED:
488       self->priv->changed = g_value_get_int(value);
489       break;
490 
491     default:
492       break;
493     }
494 }
495 
496 static void
r_card_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)497 r_card_get_property (GObject* obj, guint property_id,
498 		     GValue* value, GParamSpec* spec)
499 {
500   RCard* self = (RCard*) obj;
501 
502   switch(property_id)
503     {
504     case CARD_ID:
505       g_value_set_long(value, self->priv->id);
506       break;
507 
508     case CARD_NAME:
509       g_value_set_string(value, self->priv->name);
510       break;
511 
512     case CARD_TYPE:
513       g_value_set_string(value, self->priv->type);
514       break;
515 
516     case CARD_RATE:
517       g_value_set_int(value, self->priv->rate);
518       break;
519 
520     case CARD_LOCKED:
521       g_value_set_boolean(value, self->priv->locked);
522       break;
523 
524     case CARD_DELETED:
525       g_value_set_boolean(value, self->priv->deleted);
526       break;
527 
528     case CARD_DESTROYED:
529       g_value_set_boolean(value, self->priv->destroyed);
530       break;
531 
532     case CARD_MARKED:
533       g_value_set_boolean(value, self->priv->marked);
534       break;
535 
536     case CARD_PRINTABLE:
537       g_value_set_boolean(value, self->priv->printable);
538       break;
539 
540     case CARD_CREATED:
541       g_value_set_int(value, self->priv->created);
542       break;
543 
544     case CARD_CHANGED:
545       g_value_set_int(value, self->priv->changed);
546       break;
547 
548     default:
549       break;
550     }
551 }
552 
553 
554 
555 static void
r_card_copy_paste_group(RCard * card,gpointer data)556 r_card_copy_paste_group(RCard* card, gpointer data)
557 {
558   RGroup* grp;
559 
560   grp = r_group_copy(R_GROUP(data));
561   if (grp)
562     r_card_add_group(R_CARD(card), grp);
563 }
564 
565 
566 static void
r_card_copy_paste_ref(RCard * card,gpointer data)567 r_card_copy_paste_ref (RCard* card, gpointer data)
568 {
569   RRef* ref;
570 
571   ref = r_ref_copy(R_REF(data));
572   if (ref)
573     r_card_add_ref(card, ref);
574 }
575 
576 
577 static void
r_card_copy_paste_address(RCard * card,gpointer data)578 r_card_copy_paste_address (RCard* card, gpointer data)
579 {
580   RAddress* add;
581 
582   add = r_address_copy(R_ADDRESS(data));
583   if (add)
584     r_card_add_address(R_CARD(card), add);
585 }
586 
587 
588 static void
r_card_copy_paste_net_address(RCard * card,gpointer data)589 r_card_copy_paste_net_address (RCard* card, gpointer data)
590 {
591   RNetAddress* net;
592 
593   net = r_net_address_copy(R_NET_ADDRESS(data));
594   if (net)
595     r_card_add_net_address(R_CARD(card), net);
596 }
597 
598 
599 static void
r_card_copy_paste_telephone(RCard * card,gpointer data)600 r_card_copy_paste_telephone (RCard* card, gpointer data)
601 {
602   RTelephone* tel;
603 
604   tel = r_telephone_copy(R_TELEPHONE(data));
605   if (tel)
606     r_card_add_telephone(R_CARD(card), tel);
607 }
608 
609 
610 /*
611  * r_card_copy_commons
612  * private method. Copy from the old card to the new one the
613  * RPersonalCard and RCompanycard common values, it est:
614  * card infos, groups, addresses, net addresses, telephone numbers
615  */
616 static void
r_card_copy_commons(RCard * new,RCard * old)617 r_card_copy_commons (RCard* new, RCard* old)
618 {
619   gchar *name;
620   gint rate;
621   gboolean locked, deleted, marked, printable;
622   time_t created, changed;
623 
624   g_return_if_fail(IS_R_CARD(new));
625   g_return_if_fail(IS_R_CARD(old));
626 
627   g_object_get(G_OBJECT(old),
628 	       "card-name", &name, "card-rate", &rate,
629 	       "card-locked", &locked, "card-deleted", &deleted,
630 	       "card-marked", &marked, "card-printable", &printable,
631 	       "card-created", &created, "card-changed", &changed, NULL);
632 
633   g_object_set(G_OBJECT(new),
634 	       "card-name", name, "card-rate", rate,
635 	       "card-locked", locked, "card-deleted", deleted,
636 	       "card-marked", marked, "card-printable", printable,
637 	       "card-created", created, "card-changed", changed, NULL);
638 
639   r_card_foreach_group       (old, (RFunc) r_card_copy_paste_group,       new);
640   r_card_foreach_address     (old, (RFunc) r_card_copy_paste_address,     new);
641   r_card_foreach_net_address (old, (RFunc) r_card_copy_paste_net_address, new);
642   r_card_foreach_telephone   (old, (RFunc) r_card_copy_paste_telephone,   new);
643   r_card_foreach_ref         (old, (RFunc) r_card_copy_paste_ref,         new);
644 }
645 
646 
647 
648 /* ************************************  Public Functions
649  */
650 
651 /**
652  * r_card_new
653  *
654  * create a new #RCard
655  *
656  * Returns: a new allocated #RCard*
657  */
658 RCard*
r_card_new(void)659 r_card_new(void)
660 {
661   RCard* card;
662 
663   card = g_object_new(r_card_get_type(), NULL);
664 
665   return card;
666 }
667 
668 
669 /*
670   Returns: #R_CARD_UNDELETED if an error occurred,
671   #R_CARD_HAS_REFS if the given card has got references to
672   other cards (you must delete the referenced card before), or
673   #R_CARD_DELETED if card was successfully deleted
674 */
675 
676 
677 /**
678  * r_card_free
679  * @card: a #RCard
680  *
681  * free the #RCard*
682  */
683 void
r_card_free(RCard * card)684 r_card_free(RCard* card)
685 {
686   g_return_if_fail(IS_R_CARD(card));
687 
688   g_object_unref(G_OBJECT(card));
689 }
690 
691 /**
692  * r_card_id_align
693  * @card:
694  * @id:
695  *
696  * align the card's id. User shouldn't use this function.
697  */
698 void
r_card_reassign_id(RCard * self,glong card_id)699 r_card_reassign_id (RCard* self, glong card_id)
700 {
701   g_return_if_fail(IS_R_CARD(self));
702   g_return_if_fail(card_id > 0L);
703 
704   if (card_id > id)
705     {
706       g_object_set(self, "card-id", card_id, NULL);
707       id = card_id;
708     }
709 }
710 
711 
712 gboolean
r_card_is_personal(RCard * card)713 r_card_is_personal (RCard* card)
714 {
715   g_return_val_if_fail(IS_R_CARD(card), FALSE);
716 
717   if (g_ascii_strcasecmp(card->priv->type, "personal") == 0)
718     return TRUE;
719 
720   return FALSE;
721 }
722 
723 
724 gboolean
r_card_is_deleted(RCard * card)725 r_card_is_deleted (RCard* card)
726 {
727   g_return_val_if_fail(IS_R_CARD(card), FALSE);
728 
729   return card->priv->deleted;
730 }
731 
732 
733 
734 /**
735  * r_card_search
736  * @card: a #RCard
737  * @str: the string that user is looking for
738  *
739  * search the given string in the card
740  *
741  * returns: %TRUE if string has been found, %FALSE otherwise.
742  * If str is %NULL, %FALSE is returned
743  */
744 gboolean
r_card_search(RCard * card,const gchar * str)745 r_card_search (RCard* card, const gchar* str)
746 {
747   RCardClass* klass;
748 
749   g_return_val_if_fail(IS_R_CARD(card), FALSE);
750   g_return_val_if_fail(str != NULL, FALSE);
751 
752   klass = R_CARD_GET_CLASS(card);
753   if (R_CARD_CLASS(klass)->search)
754     return R_CARD_CLASS(klass)->search(card, str);
755 
756   return FALSE;
757 }
758 
759 
760 
761 /**
762  * r_card_copy
763  * @card: a #RCard
764  *
765  * copy the given #RCard*
766  *
767  * Returns: a new allocated copy of the card
768  */
769 RCard*
r_card_copy(RCard * card)770 r_card_copy (RCard* card)
771 {
772   RCardClass* klass;
773   RCard* new;
774 
775   g_return_val_if_fail(IS_R_CARD(card), NULL);
776 
777   klass = R_CARD_GET_CLASS(card);
778 
779   if (R_CARD_CLASS(klass)->copy)
780     {
781       new = R_CARD_CLASS(klass)->copy(R_CARD(card));
782       r_card_copy_commons(R_CARD(new), R_CARD(card));
783 
784       return new;
785     }
786 
787   return NULL;
788 }
789 
790 
791 
792 /**
793  * r_card_get_infos
794  * @card: a #RCard
795  *
796  * get infos about card.
797  *
798  * returns: a #RInfos. caller must free the #RInfos, calling
799  * the #r_card_free_infos
800  */
801 RInfos*
r_card_get_infos(RCard * card)802 r_card_get_infos (RCard* card)
803 {
804   RCardClass* klass;
805   RInfos* infos;
806   gpointer address, tel;
807 
808   g_return_val_if_fail(IS_R_CARD(card), NULL);
809 
810   klass = R_CARD_GET_CLASS(card);
811 
812   if (R_CARD_CLASS(klass)->get_infos)
813     {
814       infos = R_CARD_CLASS(klass)->get_infos(R_CARD(card));
815 
816       g_object_get(R_CARD(card),
817 		   "card-id", &infos->id,
818 		   "card-name", &infos->label, NULL);
819 
820       infos->web   = g_strdup(r_card_get_home_page(R_CARD(card)));
821       infos->email = g_strdup(r_card_get_email(R_CARD(card)));
822       infos->irc   = g_strdup(r_card_get_irc(R_CARD(card)));
823 
824       address = r_card_get_address(R_CARD(card));
825       tel     = r_card_get_telephone(R_CARD(card));
826 
827       if (address)
828 	g_object_get(R_ADDRESS(address),
829 		     "city", &infos->city,
830 		     "country", &infos->country, NULL);
831       else
832 	infos->city = infos->country = g_strdup(NULL);
833 
834 
835       if (tel)
836 	g_object_get(R_TELEPHONE(tel),
837 		     "telephone-number", &infos->telephone, NULL);
838       else
839 	infos->telephone = g_strdup(NULL);
840 
841       return infos;
842    }
843 
844   return NULL;
845 }
846 
847 
848 /**
849  * r_card_free_infos
850  * @infos: a #RInfos
851  *
852  * free the RInfos object
853  */
854 void
r_card_free_infos(RInfos * infos)855 r_card_free_infos (RInfos *infos)
856 {
857   g_return_if_fail(infos != NULL);
858 
859   g_free(infos->label);
860   g_free(infos->first);
861   g_free(infos->last);
862   g_free(infos->prof);
863   g_free(infos->city);
864   g_free(infos->country);
865   g_free(infos->assignment);
866   g_free(infos->web);
867   g_free(infos->email);
868   g_free(infos->irc);
869   g_free(infos->telephone);
870 
871   g_free(infos);
872   infos = NULL;
873 }
874 
875 
876 /**
877  * r_card_add_group
878  * @card: a #RCard
879  * @group: a #RGroup
880  *
881  * add a group to card (card belongs to added group)
882  */
883 void
r_card_add_group(RCard * card,RGroup * group)884 r_card_add_group (RCard* card, RGroup* group)
885 {
886   g_return_if_fail(IS_R_CARD(card));
887   g_return_if_fail(IS_R_GROUP(group));
888 
889   r_group_box_add_group(card->priv->box, group);
890 }
891 
892 
893 /**
894  * r_card_delete_group
895  * @card: a #RCard
896  * @name: group's name
897  *
898  * delete a group from card's groups list (i.e. remove a card from a group)
899  *
900  * Returns: TRUE if group was successfully deleted, FALSE otherwise
901  */
902 gboolean
r_card_delete_group(RCard * card,gchar * name)903 r_card_delete_group (RCard* card, gchar* name)
904 {
905   g_return_val_if_fail(IS_R_CARD(card), FALSE);
906   g_return_val_if_fail(name != NULL, FALSE);
907 
908   return r_group_box_delete_group_by_name(card->priv->box, name);
909 }
910 
911 
912 
913 /**
914  * r_card_rename_group
915  * @card: a #RCard
916  * @oldname: old group's name
917  * @newname: new group's name
918  *
919  * rename the old name group with the new name group
920  *
921  * Returns: TRUE if replaced, FALSE otherwise
922  */
923 gboolean
r_card_rename_group(RCard * card,gchar * oldname,gchar * newname)924 r_card_rename_group (RCard* card, gchar* oldname, gchar* newname)
925 {
926   g_return_val_if_fail(IS_R_CARD(card), FALSE);
927   g_return_val_if_fail(oldname != NULL, FALSE);
928   g_return_val_if_fail(newname != NULL, FALSE);
929 
930   return r_group_box_modify_group_name(card->priv->box, oldname, newname);
931 }
932 
933 gboolean
r_card_change_pixmap(RCard * card,gchar * group_name,gchar * new_uri)934 r_card_change_pixmap (RCard* card, gchar* group_name, gchar* new_uri)
935 {
936   g_return_val_if_fail(IS_R_CARD(card), FALSE);
937   g_return_val_if_fail(new_uri != NULL, FALSE);
938 
939   return r_group_box_modify_group_name(card->priv->box, group_name, new_uri);
940 }
941 
942 
943 gboolean
r_card_has_groups(RCard * card)944 r_card_has_groups (RCard* card)
945 {
946   g_return_val_if_fail(IS_R_CARD(card), FALSE);
947 
948   return !r_group_box_is_empty(card->priv->box);
949 }
950 
951 
952 
953 /**
954  * r_card_find_group
955  * @card: a #RCard
956  * @name: group's name
957  *
958  * find a card's group by name. User must cast returned value
959  * to a #RGroup.
960  *
961  * Returns: a gpointer to the group if group has been found, NULL otherwise.
962  */
963 gpointer
r_card_find_group(RCard * card,gchar * name)964 r_card_find_group (RCard* card, gchar* name)
965 {
966   g_return_val_if_fail(IS_R_CARD(card), NULL);
967   g_return_val_if_fail(name != NULL, NULL);
968 
969   return r_group_box_find(card->priv->box, name);
970 }
971 
972 
973 /**
974  * r_card_belong_to_group
975  * @card: a #RCard
976  * @group_name: group's name
977  *
978  * check if the card belongs to the group
979  *
980  * Returns: %TRUE if card belongs to the given group, %FALSE otherwise
981  */
982 gboolean
r_card_belong_to_group(RCard * card,const gchar * group_name)983 r_card_belong_to_group (RCard* card, const gchar* group_name)
984 {
985   g_return_val_if_fail(IS_R_CARD(card), FALSE);
986   g_return_val_if_fail(group_name != NULL, FALSE);
987 
988   return r_group_box_owns_group(card->priv->box, group_name);
989 }
990 
991 
992 /**
993  * r_card_get_groups_owned_by
994  * @card: a #RCard
995  * @owner: the owner of the groups
996  *
997  * look for all groups that belongs to owner
998  *
999  * Returns: A list of #RGroup, or %NULL
1000  */
1001 GList*
r_card_get_groups_owned_by(RCard * card,const gchar * owner)1002 r_card_get_groups_owned_by (RCard* card, const gchar* owner)
1003 {
1004   g_return_val_if_fail(IS_R_CARD(card), NULL);
1005   g_return_val_if_fail(owner != NULL, NULL);
1006 
1007   return r_group_box_find_groups_owned_by(card->priv->box, owner);
1008 }
1009 
1010 
1011 /**
1012  * r_card_get_group
1013  * @card: a #RCard
1014  *
1015  * get the first of card's groups. User must cast returned value
1016  * to a #RGroup.
1017  *
1018  * Returns: a gpointer.
1019  */
1020 RGroup*
r_card_get_group(RCard * card)1021 r_card_get_group (RCard* card)
1022 {
1023   g_return_val_if_fail(IS_R_CARD(card), NULL);
1024 
1025   return r_group_box_get_group(card->priv->box);
1026 }
1027 
1028 
1029 /**
1030  * r_card_get_next_group
1031  * @card: a #RCard
1032  *
1033  * get the next in card's group. User must cast returned value
1034  * to a #RGroup.
1035  *
1036  * Returns: a gpointer
1037  */
1038 RGroup*
r_card_get_next_group(RCard * card)1039 r_card_get_next_group (RCard* card)
1040 {
1041   g_return_val_if_fail(IS_R_CARD(card),NULL);
1042 
1043   return r_group_box_get_next_group(card->priv->box);
1044 }
1045 
1046 
1047 /**
1048  * r_card_get_prev_group
1049  * @card: a #RCard
1050  *
1051  * get the previous in card's group. User must cast returned value
1052  * to a #RGroup.
1053  *
1054  * Returns: a gpointer
1055  */
1056 RGroup*
r_card_get_prev_group(RCard * card)1057 r_card_get_prev_group (RCard* card)
1058 {
1059   g_return_val_if_fail(IS_R_CARD(card), NULL);
1060 
1061   return r_group_box_get_prev_group(card->priv->box);
1062 }
1063 
1064 
1065 
1066 /**
1067  * r_card_reset_group
1068  * @card: a #RCard
1069  *
1070  * set the private group iterartor to the first one
1071  */
1072 void
r_card_reset_group(RCard * card)1073 r_card_reset_group (RCard* card)
1074 {
1075   g_return_if_fail(IS_R_CARD(card));
1076 
1077   r_group_box_reset(card->priv->box);
1078 }
1079 
1080 
1081 /**
1082  * r_card_foreach_group
1083  * @card: a #RCard
1084  * @func: the #RFunc that will be called on each group in the card
1085  * @user_data: user's data to pass to func
1086  *
1087  * User's function func, will be called foreach group in card.
1088  * func must have two parameter: the group (automatically passed) and
1089  * the user_data
1090  */
1091 void
r_card_foreach_group(RCard * card,RFunc func,gpointer user_data)1092 r_card_foreach_group (RCard* card, RFunc func, gpointer user_data)
1093 {
1094   gpointer grp;
1095 
1096   r_card_reset_group(card);
1097   grp = r_card_get_group(card);
1098   for(; grp; grp = r_card_get_next_group(card))
1099     func(user_data, grp);
1100 }
1101 
1102 
1103 /**
1104  * r_card_add_address
1105  * @card: a #RCard
1106  * @address: a #RAddress
1107  *
1108  * add an address to card
1109  */
1110 void
r_card_add_address(RCard * card,RAddress * address)1111 r_card_add_address (RCard* card, RAddress* address)
1112 {
1113   g_return_if_fail(IS_R_CARD(card));
1114   g_return_if_fail(IS_R_ADDRESS(address));
1115 
1116   card->priv->addresses = g_list_append(card->priv->addresses, address);
1117 
1118   /* init address iterator */
1119   if (!card->priv->addr_iter)
1120     card->priv->addr_iter = card->priv->addresses;
1121 }
1122 
1123 
1124 
1125 /**
1126  * r_card_delete_address
1127  * @card: a #RCard
1128  * @address: a #RAddress
1129  *
1130  * delete the address from card
1131  *
1132  * returns: %TRUE if address has been successfully deleted, %FALSE otherwihe.
1133  */
1134 gboolean
r_card_delete_address(RCard * card,RAddress * address)1135 r_card_delete_address (RCard* card, RAddress* address)
1136 {
1137   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1138   g_return_val_if_fail(IS_R_ADDRESS(address), FALSE);
1139 
1140   card->priv->addr_iter = card->priv->addresses;
1141   for (; card->priv->addr_iter;
1142        card->priv->addr_iter = card->priv->addr_iter->next)
1143     {
1144       if (card->priv->addr_iter && (card->priv->addr_iter->data == address))
1145 	card->priv->addresses = g_list_remove_link(card->priv->addresses,
1146 						   card->priv->addr_iter);
1147 
1148       r_address_free(address);
1149       g_list_free_1(card->priv->addr_iter);
1150       card->priv->addr_iter = NULL;
1151 
1152       return TRUE;
1153     }
1154 
1155   return FALSE;
1156 }
1157 
1158 
1159 /**
1160  * r_card_replace_address
1161  * @card: a #RCard
1162  * @old: a #RAddress
1163  * @new: a #RAddress
1164  *
1165  * replace the old address with new one. On success, old address is deleted.
1166  *
1167  * returns: %TRUE if address has been successfully replaced, %FALSE otherwihe.
1168  */
1169 gboolean
r_card_replace_address(RCard * card,RAddress * old,RAddress * new)1170 r_card_replace_address (RCard* card, RAddress* old, RAddress* new)
1171 {
1172   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1173   g_return_val_if_fail(IS_R_ADDRESS(old), FALSE);
1174   g_return_val_if_fail(IS_R_ADDRESS(new), FALSE);
1175 
1176   card->priv->addr_iter = card->priv->addresses;
1177   for (; card->priv->addr_iter;
1178        card->priv->addr_iter = card->priv->addr_iter->next)
1179     {
1180       if (card->priv->addr_iter && (card->priv->addr_iter->data == old))
1181 	{
1182 	  card->priv->addr_iter->data = new;
1183 	  r_address_free(old);
1184 	  card->priv->addr_iter = NULL;
1185 
1186 	  return TRUE;
1187 	}
1188     }
1189 
1190   return FALSE;
1191 }
1192 
1193 
1194 
1195 /**
1196  * r_card_get_address
1197  * @card: a #RCard
1198  *
1199  * get the first item of card's addresses list. User must cast to
1200  * a #RAddress.
1201  *
1202  * Returns: a gpointer
1203  */
1204 gpointer
r_card_get_address(RCard * card)1205 r_card_get_address (RCard* card)
1206 {
1207   RAddress* ret = NULL;
1208 
1209   g_return_val_if_fail(IS_R_CARD(card), NULL);
1210 
1211   if (card->priv->addr_iter)
1212     ret = card->priv->addr_iter->data;
1213   if (IS_R_ADDRESS(ret))
1214     return ret;
1215 
1216   return NULL;
1217 }
1218 
1219 
1220 /**
1221  * r_card_get_next_address
1222  * @card: a #RCard
1223  *
1224  * get the next item in card's addresses list. User must cast to
1225  * a #RAddress.
1226  *
1227  * Returns: a gpointer
1228  */
1229 gpointer
r_card_get_next_address(RCard * card)1230 r_card_get_next_address (RCard* card)
1231 {
1232   g_return_val_if_fail(IS_R_CARD(card), NULL);
1233 
1234   card->priv->addr_iter = g_list_next(card->priv->addr_iter);
1235   if(card->priv->addr_iter)
1236     return card->priv->addr_iter->data;
1237   else  /* iterator is NULL, reset iterator */
1238     card->priv->addr_iter = card->priv->addresses;
1239 
1240   return NULL;
1241 }
1242 
1243 
1244 /**
1245  * r_card_get_prev_address
1246  * @card: a #RCard
1247  *
1248  * get the previous item in card's addresses list. User must cast to
1249  * a #RAddress.
1250  *
1251  * Returns: a gpointer
1252  */
1253 gpointer
r_card_get_prev_address(RCard * card)1254 r_card_get_prev_address (RCard* card)
1255 {
1256   g_return_val_if_fail(IS_R_CARD(card), NULL);
1257 
1258   card->priv->addr_iter = g_list_previous(card->priv->addr_iter);
1259   if (card->priv->addr_iter)
1260     return card->priv->addr_iter->data;
1261   else  /* iterator is NULL, reset iterator */
1262     card->priv->addr_iter = card->priv->addresses;
1263 
1264   return NULL;
1265 }
1266 
1267 
1268 /**
1269  * r_card_reset_address
1270  * @card: a #RCard
1271  *
1272  * set the private address iterartor to the first one
1273  */
1274 void
r_card_reset_address(RCard * card)1275 r_card_reset_address (RCard* card)
1276 {
1277   g_return_if_fail(IS_R_CARD(card));
1278 
1279   card->priv->addr_iter = card->priv->addresses;
1280 }
1281 
1282 
1283 /**
1284  * r_card_foreach_address
1285  * @card: a #RCard
1286  * @func: the #RFunc that will be called on each group in the card
1287  * @user_data: user's data to pass to func
1288  *
1289  * User's function func, will be called foreach address in card.
1290  * func must have two parameter: the address (automatically passed) and
1291  * the user_data
1292  */
1293 void
r_card_foreach_address(RCard * card,RFunc func,gpointer user_data)1294 r_card_foreach_address (RCard* card, RFunc func, gpointer user_data)
1295 {
1296   gpointer address;
1297 
1298   r_card_reset_address(card);
1299   address = r_card_get_address(card);
1300   for(; address; address = r_card_get_next_address(card))
1301     func(user_data, address);
1302 }
1303 
1304 
1305 /**
1306  * r_card_add_net_address
1307  * @card: a #RCard
1308  * @net: a #RNetAddress
1309  *
1310  * add a net address to card
1311  */
1312 void
r_card_add_net_address(RCard * card,RNetAddress * net)1313 r_card_add_net_address (RCard* card, RNetAddress* net)
1314 {
1315   g_return_if_fail(IS_R_CARD(card));
1316   g_return_if_fail(IS_R_NET_ADDRESS(net));
1317 
1318   card->priv->nets = g_list_append(card->priv->nets, net);
1319 
1320   /* init card iterator */
1321   if (!card->priv->net_iter)
1322     card->priv->net_iter = card->priv->nets;
1323 }
1324 
1325 
1326 /**
1327  * r_card_delete_net_address
1328  * @card: a #RCard
1329  * @address: a #RNetAddress
1330  *
1331  * delete a net address from card
1332  *
1333  * returns: %TRUE if address has been successfully deleted, %FALSE otherwihe.
1334  */
1335 gboolean
r_card_delete_net_address(RCard * card,RNetAddress * address)1336 r_card_delete_net_address  (RCard* card, RNetAddress* address)
1337 {
1338   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1339   g_return_val_if_fail(IS_R_NET_ADDRESS(address), FALSE);
1340 
1341   card->priv->net_iter = card->priv->nets;
1342   for (; card->priv->net_iter;
1343        card->priv->net_iter = card->priv->net_iter->next)
1344     {
1345       if (card->priv->net_iter && (card->priv->net_iter->data == address))
1346 	card->priv->nets = g_list_remove_link(card->priv->nets,
1347 					      card->priv->net_iter);
1348 
1349       r_net_address_free(address);
1350       g_list_free_1(card->priv->net_iter);
1351       card->priv->net_iter = NULL;
1352 
1353       return TRUE;
1354     }
1355 
1356   return FALSE;
1357 }
1358 
1359 
1360 /**
1361  * r_card_replace_net_address
1362  * @card: a #RCard
1363  * @old: the old #RNetAddress
1364  * @new: the new #RNetAddress
1365  *
1366  * replace the old net address with new one.
1367  * On success, old address is deleted.
1368  *
1369  * returns: %TRUE if address has been successfully replaced, %FALSE otherwihe.
1370  */
1371 gboolean
r_card_replace_net_address(RCard * card,RNetAddress * old,RNetAddress * new)1372 r_card_replace_net_address (RCard* card, RNetAddress* old, RNetAddress* new)
1373 {
1374   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1375   g_return_val_if_fail(IS_R_NET_ADDRESS(old), FALSE);
1376   g_return_val_if_fail(IS_R_NET_ADDRESS(new), FALSE);
1377 
1378   card->priv->net_iter = card->priv->nets;
1379   for (; card->priv->net_iter;
1380        card->priv->net_iter = card->priv->net_iter->next)
1381     {
1382       if (card->priv->net_iter && (card->priv->net_iter->data == old))
1383 	{
1384 	  card->priv->net_iter->data = new;
1385 	  r_net_address_free(old);
1386 	  card->priv->net_iter = NULL;
1387 
1388 	  return TRUE;
1389 	}
1390     }
1391 
1392   return FALSE;
1393 }
1394 
1395 
1396 
1397 /**
1398  * r_card_get_net_address
1399  * @card: a #RCard
1400  *
1401  * get the first item of card's net addresses list. User must cast to
1402  * a #RNetAddress.
1403  *
1404  * Returns: a gpointer
1405  */
1406 gpointer
r_card_get_net_address(RCard * card)1407 r_card_get_net_address (RCard* card)
1408 {
1409   RNetAddress* ret = NULL;
1410 
1411   g_return_val_if_fail(IS_R_CARD(card), NULL);
1412 
1413   if (card->priv->net_iter)
1414     ret = card->priv->net_iter->data;
1415   if (IS_R_NET_ADDRESS(ret))
1416     return ret;
1417 
1418   return NULL;
1419 }
1420 
1421 
1422 /**
1423  * r_card_get_next_net_address
1424  * @card: a #RCard
1425  *
1426  * get the next item in card's net addresses list. User must cast to
1427  * a #RNetAddress.
1428  *
1429  * Returns: a gpointer
1430  */
1431 gpointer
r_card_get_next_net_address(RCard * card)1432 r_card_get_next_net_address (RCard* card)
1433 {
1434   g_return_val_if_fail(IS_R_CARD(card), NULL);
1435 
1436   card->priv->net_iter = g_list_next(card->priv->net_iter);
1437   if (card->priv->net_iter)
1438     return card->priv->net_iter->data;
1439   else  /* iterator is NULL, reset iterator */
1440     card->priv->net_iter = card->priv->nets;
1441 
1442   return NULL;
1443 }
1444 
1445 
1446 /**
1447  * r_card_get_prev_net_address
1448  * @card: a #RCard
1449  *
1450  * get the previous item in card's net addresses list. User must cast to
1451  * a #RNetAddress.
1452  *
1453  * Returns: a gpointer
1454  */
1455 gpointer
r_card_get_prev_net_address(RCard * card)1456 r_card_get_prev_net_address (RCard* card)
1457 {
1458   g_return_val_if_fail(IS_R_CARD(card), NULL);
1459 
1460   card->priv->net_iter = g_list_previous(card->priv->net_iter);
1461   if (card->priv->net_iter)
1462     return card->priv->net_iter->data;
1463   else
1464     card->priv->net_iter = card->priv->nets;
1465 
1466   return NULL;
1467 }
1468 
1469 
1470 /**
1471  * r_card_reset_net_address
1472  * @card: a #RCard
1473  *
1474  * set the private net addresses iterartor to the first one.
1475  */
1476 void
r_card_reset_net_address(RCard * card)1477 r_card_reset_net_address (RCard* card)
1478 {
1479   g_return_if_fail(IS_R_CARD(card));
1480 
1481   card->priv->net_iter = card->priv->nets;
1482 }
1483 
1484 
1485 /**
1486  * r_card_foreach_net_address:
1487  * @card: a #RCard
1488  * @func: the #RFunc that will be called on each group in the card
1489  * @user_data: user's data to pass to func
1490  *
1491  * User's function func, will be called foreach net address in card.
1492  * func must have two parameter: the net address (automatically passed) and
1493  * the user_data
1494  */
1495 void
r_card_foreach_net_address(RCard * card,RFunc func,gpointer user_data)1496 r_card_foreach_net_address (RCard* card, RFunc func, gpointer user_data)
1497 {
1498   gpointer net;
1499 
1500   r_card_reset_net_address(card);
1501   net = r_card_get_net_address(card);
1502   for(; net; net = r_card_get_next_net_address(card))
1503     func(user_data, net);
1504 }
1505 
1506 
1507 /**
1508  * r_card_add_telephone
1509  * @card: a #RCard
1510  * @tel: a #RTelephone
1511  *
1512  * add a telephone number to card
1513  */
1514 void
r_card_add_telephone(RCard * card,RTelephone * tel)1515 r_card_add_telephone (RCard* card, RTelephone* tel)
1516 {
1517   g_return_if_fail(IS_R_CARD(card));
1518   g_return_if_fail(IS_R_TELEPHONE(tel));
1519 
1520   card->priv->phones = g_list_append(card->priv->phones, tel);
1521 
1522   /* init telephone iterator */
1523   if (!card->priv->phone_iter)
1524     card->priv->phone_iter = card->priv->phones;
1525 }
1526 
1527 
1528 
1529 /**
1530  * r_card_delete_telephone
1531  * @card: a #RCard
1532  * @phone: a #RTelephone
1533  *
1534  * delete a telephone number from card
1535  *
1536  * returns: %TRUE if telephone has been successfully, %FALSE otherwise.
1537  */
1538 gboolean
r_card_delete_telephone(RCard * card,RTelephone * phone)1539 r_card_delete_telephone (RCard* card, RTelephone* phone)
1540 {
1541   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1542   g_return_val_if_fail(IS_R_TELEPHONE(phone), FALSE);
1543 
1544   card->priv->phone_iter = card->priv->phones;
1545   for (; card->priv->phone_iter;
1546        card->priv->phone_iter = card->priv->phone_iter->next)
1547     {
1548       if (card->priv->phone_iter &&
1549 	  (card->priv->phone_iter->data == phone))
1550 	{
1551 	  card->priv->phones = g_list_remove_link(card->priv->phones,
1552 						  card->priv->phone_iter);
1553 
1554 	  r_telephone_free(phone);
1555 	  g_list_free_1(card->priv->phone_iter);
1556 	  card->priv->phone_iter = NULL;
1557 
1558 	  return TRUE;
1559 	}
1560     }
1561 
1562   return FALSE;
1563 }
1564 
1565 
1566 /**
1567  * r_card_replace_telephone
1568  * @card: a #RCard
1569  * @old: a #RTelephone
1570  * @new: a #RTelephone
1571  *
1572  * replace the old telephone with new one.
1573  * On success, old telephone is deleted.
1574  *
1575  * returns: %TRUE if telephone has been successfully replaced ,
1576  * %FALSE otherwihe.
1577  */
1578 gboolean
r_card_replace_telephone(RCard * card,RTelephone * old,RTelephone * new)1579 r_card_replace_telephone (RCard* card, RTelephone* old,	RTelephone* new)
1580 {
1581   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1582   g_return_val_if_fail(IS_R_TELEPHONE(old), FALSE);
1583   g_return_val_if_fail(IS_R_TELEPHONE(new), FALSE);
1584 
1585   card->priv->phone_iter = card->priv->phones;
1586   for (; card->priv->phone_iter;
1587        card->priv->phone_iter = card->priv->phone_iter->next)
1588     {
1589       if (card->priv->phone_iter &&
1590 	  (card->priv->phone_iter->data == old))
1591 	{
1592 	  card->priv->phone_iter->data = new;
1593 	  r_telephone_free(old);
1594 	  card->priv->phone_iter = NULL;
1595 
1596 	  return TRUE;
1597 	}
1598     }
1599 
1600   return FALSE;
1601 }
1602 
1603 
1604 
1605 /**
1606  * r_card_get_telephone
1607  * @card: a #RCard
1608  *
1609  * get the first item of card's telephones list. User must cast to
1610  * a #RTelephone.
1611  *
1612  * Returns: a gpointer
1613  */
1614 gpointer
r_card_get_telephone(RCard * card)1615 r_card_get_telephone (RCard* card)
1616 {
1617   RTelephone* ret = NULL;
1618 
1619   g_return_val_if_fail(IS_R_CARD(card), NULL);
1620 
1621   if (card->priv->phone_iter)
1622     ret = card->priv->phone_iter->data;
1623   if (IS_R_TELEPHONE(ret))
1624     return ret;
1625 
1626   return NULL;
1627 }
1628 
1629 
1630 
1631 /**
1632  * r_card_get_next_telephone
1633  * @card: a #RCard
1634  *
1635  * get the next item in card's telephones list. User must cast to
1636  * a #RTelephone.
1637  *
1638  * Returns: a gpointer
1639  */
1640 gpointer
r_card_get_next_telephone(RCard * card)1641 r_card_get_next_telephone (RCard* card)
1642 {
1643   g_return_val_if_fail(IS_R_CARD(card), NULL);
1644 
1645   card->priv->phone_iter = g_list_next(card->priv->phone_iter);
1646   if (card->priv->phone_iter)
1647     return card->priv->phone_iter->data;
1648   else  /* iterator is NULL, reset iterator */
1649     card->priv->phone_iter = card->priv->phones;
1650 
1651   return NULL;
1652 }
1653 
1654 
1655 /**
1656  * r_card_get_prev_telephone
1657  * @card: a #RCard
1658  *
1659  * get the previous item in card's telephones list. User must cast to
1660  * a #RTelephone.
1661  *
1662  * Returns: a gpointer
1663  */
1664 gpointer
r_card_get_prev_telephone(RCard * card)1665 r_card_get_prev_telephone (RCard* card)
1666 {
1667   g_return_val_if_fail(IS_R_CARD(card), NULL);
1668 
1669   card->priv->phone_iter= g_list_previous(card->priv->phone_iter);
1670   if (card->priv->phone_iter)
1671     return card->priv->phone_iter->data;
1672   else
1673     card->priv->phone_iter = card->priv->phones;
1674 
1675   return NULL;
1676 }
1677 
1678 
1679 
1680 /**
1681  * r_card_reset_telephone
1682  * @card: a #RCard
1683  *
1684  * set the private telephones iterartor to the first one
1685  */
1686 void
r_card_reset_telephone(RCard * card)1687 r_card_reset_telephone (RCard* card)
1688 {
1689   g_return_if_fail(IS_R_CARD(card));
1690 
1691   card->priv->phone_iter = card->priv->phones;
1692 }
1693 
1694 
1695 /**
1696  * r_card_foreach_telephone
1697  * @card: a #RCard
1698  * @func: the #RFunc that will be called on each group in the card
1699  * @user_data: user's data to pass to func
1700  *
1701  * User's function func, will be called foreach telephone in card.
1702  * func must have two parameter: the telephone (automatically passed) and
1703  * the user_data
1704  */
1705 void
r_card_foreach_telephone(RCard * card,RFunc func,gpointer user_data)1706 r_card_foreach_telephone (RCard* card, RFunc func, gpointer user_data)
1707 {
1708   gpointer phone;
1709 
1710   r_card_reset_telephone(card);
1711   phone = r_card_get_telephone(card);
1712   for(; phone; phone = r_card_get_next_telephone(card))
1713     func(user_data, phone);
1714 }
1715 
1716 /**
1717  * r_card_add_ref
1718  * @card: a #RCard
1719  * @ref: a #RRef
1720  *
1721  * add a #RRef to the given #RCard card
1722  */
1723 void
r_card_add_ref(RCard * card,RRef * ref)1724 r_card_add_ref (RCard* card, RRef* ref)
1725 {
1726   g_return_if_fail(IS_R_CARD(card));
1727   g_return_if_fail(IS_R_REF(ref));
1728 
1729   card->priv->refs = g_list_append(card->priv->refs, ref);
1730   if (!card->priv->refs_iter)
1731     card->priv->refs_iter = card->priv->refs;
1732 }
1733 
1734 
1735 /**
1736  * r_card_del_ref
1737  * @card: a #RCard
1738  * @ref: a #RRef
1739  *
1740  * remove a #RRef from card
1741  * returns: %TRUE if reference is successfully deleted, %FALSE otherwise
1742  */
1743 gboolean
r_card_del_ref(RCard * card,RRef * ref)1744 r_card_del_ref (RCard* card, RRef* ref)
1745 {
1746   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1747   g_return_val_if_fail(IS_R_REF(ref), FALSE);
1748 
1749   card->priv->refs_iter = card->priv->refs;
1750   for (; card->priv->refs_iter;
1751        card->priv->refs_iter = card->priv->refs_iter->next)
1752     {
1753       if (card->priv->refs_iter->data == ref)
1754 	{
1755 	  card->priv->refs = g_list_remove_link(card->priv->refs,
1756 						card->priv->refs_iter);
1757 
1758 	  r_ref_free(ref);
1759 	  g_list_free_1(card->priv->refs_iter);
1760 	  card->priv->refs_iter = NULL;
1761 
1762 	  return TRUE;
1763 	}
1764     }
1765 
1766   return FALSE;
1767 }
1768 
1769 
1770 
1771 /**
1772  * r_card_has_refs
1773  * @card: a #RCard
1774  *
1775  * Check if card has references to other cards
1776  *
1777  * returns: %TRUE if has references, %FALSE otherwise
1778  */
1779 gboolean
r_card_has_refs(RCard * card)1780 r_card_has_refs (RCard* card)
1781 {
1782   g_return_val_if_fail(IS_R_CARD(card), FALSE);
1783 
1784   return (card->priv->refs != NULL);
1785 }
1786 
1787 /**
1788  * r_card_get_ref
1789  * @card: a #RCard
1790  *
1791  * get the first #RRef
1792  *
1793  * returns: a gpointer or NULL if card hasn't refs
1794  */
1795 gpointer
r_card_get_ref(RCard * card)1796 r_card_get_ref (RCard* card)
1797 {
1798   g_return_val_if_fail(IS_R_CARD(card), NULL);
1799 
1800   if (card->priv->refs_iter)
1801     return card->priv->refs_iter->data;
1802 
1803   return NULL;
1804 }
1805 
1806 
1807 /**
1808  * r_card_get_next_ref
1809  * @card: a #RCard
1810  *
1811  * get the next ref
1812  *
1813  * returns: a gpointer or NULL
1814  */
1815 gpointer
r_card_get_next_ref(RCard * card)1816 r_card_get_next_ref (RCard* card)
1817 {
1818   g_return_val_if_fail(IS_R_CARD(card), NULL);
1819 
1820   card->priv->refs_iter = g_list_next(card->priv->refs_iter);
1821   if (card->priv->refs_iter)
1822     return card->priv->refs_iter->data;
1823   else
1824     card->priv->refs_iter = card->priv->refs;
1825 
1826   return NULL;
1827 }
1828 
1829 
1830 /**
1831  * r_card_get_prev_ref
1832  * @card: a #RCard
1833  *
1834  * get the previous ref
1835  *
1836  * returns: a gpointer or NULL
1837  */
1838 gpointer
r_card_get_prev_ref(RCard * card)1839 r_card_get_prev_ref (RCard* card)
1840 {
1841   g_return_val_if_fail(IS_R_CARD(card), NULL);
1842 
1843   card->priv->refs_iter = g_list_previous(card->priv->refs_iter);
1844   if (card->priv->refs_iter)
1845     return card->priv->refs_iter->data;
1846   else
1847     card->priv->refs_iter = card->priv->refs;
1848 
1849   return NULL;
1850 }
1851 
1852 
1853 /**
1854  * r_card_reset_ref
1855  * @card: a #RCard
1856  *
1857  * reset the private refs's iterator to ref head's list
1858  */
1859 void
r_card_reset_ref(RCard * card)1860 r_card_reset_ref (RCard* card)
1861 {
1862   g_return_if_fail(IS_R_CARD(card));
1863 
1864   card->priv->refs_iter = card->priv->refs;
1865 }
1866 
1867 
1868 /**
1869  * r_card_foreach_ref
1870  * @card: a #RCard
1871  * @func: the #RFunc that will be called on each group in the card
1872  * @user_data: user's data to pass to func
1873  *
1874  * User's function func, will be called foreach ref in card.
1875  * func must have two parameter: the ref (automatically passed) and
1876  * the user_data
1877  */
1878 void
r_card_foreach_ref(RCard * card,RFunc func,gpointer user_data)1879 r_card_foreach_ref (RCard* card, RFunc func, gpointer user_data)
1880 {
1881   gpointer ref;
1882 
1883   r_card_reset_ref(card);
1884   ref = r_card_get_ref(card);
1885   for(; ref; ref = r_card_get_next_ref(card))
1886     func(user_data, ref);
1887 }
1888 
1889 
1890 /**
1891  * r_card_get_group_owner
1892  * @card: a #RCard
1893  * @group: a #RGroup
1894  *
1895  * get the owner of the given group. Caller does not free the returned value
1896  *
1897  * Returns: a gchar*, "r" if given group if a default group,
1898  * "user" if given group was build by user
1899  */
1900 gchar*
r_card_get_group_owner(RCard * card,RGroup * group)1901 r_card_get_group_owner (RCard* card, RGroup* group)
1902 {
1903   gchar* owner;
1904 
1905   g_return_val_if_fail(IS_R_CARD(card), NULL);
1906   g_return_val_if_fail(IS_R_GROUP(card), NULL);
1907 
1908   g_object_get(G_OBJECT(group), "group-owner", &owner, NULL);
1909 
1910   return owner;
1911 }
1912 
1913 
1914 
1915 /**
1916  * r_card_get_home_page
1917  * @card: a #RCard
1918  *
1919  * get the first web url in net addresses list.
1920  * Caller does not free the returned value
1921  *
1922  * Returns: a gchar*
1923  */
1924 gchar*
r_card_get_home_page(RCard * card)1925 r_card_get_home_page (RCard* card)
1926 {
1927   gpointer net;
1928 
1929   g_return_val_if_fail(IS_R_CARD(card), "");
1930 
1931   net = r_card_get_net_address(card);
1932   for (; net; net = r_card_get_next_net_address(card))
1933     {
1934       RNetAddressType type = R_NET_ADDRESS_UNKNOWN;
1935       gchar* url;
1936 
1937       g_object_get(R_NET_ADDRESS(net), "url", &url, "url-type", &type, NULL);
1938       if (type == R_NET_ADDRESS_WEB)
1939 	{
1940 	  r_card_reset_net_address(card);
1941 
1942 	  return url;
1943 	}
1944     }
1945 
1946   return "";
1947 }
1948 
1949 
1950 /**
1951  * r_card_get_email
1952  * @card: a #RCard
1953  *
1954  * get the first email in net addresses list.
1955  * Caller does not free the returned value
1956  *
1957  * Returns: a gchar*
1958  */
r_card_get_email(RCard * card)1959 gchar* r_card_get_email (RCard* card)
1960 {
1961   gpointer net;
1962 
1963   g_return_val_if_fail(IS_R_CARD(card), "");
1964 
1965   net = r_card_get_net_address(card);
1966   for (; net; net = r_card_get_next_net_address(card))
1967     {
1968       RNetAddressType type = R_NET_ADDRESS_UNKNOWN;
1969       gchar* url;
1970 
1971       g_object_get(R_NET_ADDRESS(net), "url", &url, "url-type", &type, NULL);
1972       if (type == R_NET_ADDRESS_EMAIL)
1973 	{
1974 	  r_card_reset_net_address(card);
1975 
1976 	  return url;
1977 	}
1978     }
1979 
1980   return "";
1981 }
1982 
1983 
1984 /**
1985  * r_card_get_irc
1986  * @card: a #RCard
1987  *
1988  * get the first irc in net addresses list.
1989  * Caller does not free the returned value
1990  *
1991  * Returns: a gchar*
1992  */
1993 gchar*
r_card_get_irc(RCard * card)1994 r_card_get_irc (RCard* card)
1995 {
1996   gpointer net;
1997 
1998   g_return_val_if_fail(IS_R_CARD(card), "");
1999 
2000   net = r_card_get_net_address(card);
2001   for (; net; net = r_card_get_next_net_address(card))
2002     {
2003       RNetAddressType type = R_NET_ADDRESS_UNKNOWN;
2004       gchar* url;
2005 
2006       g_object_get(net, "url", &url, "url-type", &type, NULL);
2007       if ((type >= R_NET_ADDRESS_IRC) &&
2008 	  (type <= R_NET_ADDRESS_IRC_MSN))
2009 	{
2010 	  r_card_reset_net_address(card);
2011 
2012 	  return url;
2013 	}
2014     }
2015 
2016   return "";
2017 }
2018 
2019 
2020 gpointer
r_card_find_address(RCard * card,RAddressType type)2021 r_card_find_address (RCard* card, RAddressType type)
2022 {
2023   gpointer address;
2024 
2025   g_return_val_if_fail(IS_R_CARD(card), NULL);
2026 
2027   address = r_card_get_address(card);
2028   for (; address; address = r_card_get_next_address(card))
2029     {
2030       RAddressType adstype;
2031 
2032       g_object_get(R_ADDRESS(address), "address-type", &adstype, NULL);
2033       if (adstype == type)
2034 	return address;
2035     }
2036 
2037   return NULL;
2038 }
2039 
2040 
2041 gpointer
r_card_find_net_address(RCard * card,RNetAddressType type)2042 r_card_find_net_address (RCard* card, RNetAddressType type)
2043 {
2044   gpointer net;
2045 
2046   g_return_val_if_fail(IS_R_CARD(card), NULL);
2047 
2048   net = r_card_get_net_address(card);
2049   for (; net; net = r_card_get_next_net_address(card))
2050     {
2051       RNetAddressType nettype;
2052 
2053       g_object_get(R_NET_ADDRESS(net), "url-type", &nettype, NULL);
2054       if (nettype == type)
2055 	return net;
2056     }
2057 
2058   return NULL;
2059 }
2060 
2061 gpointer
r_card_find_telephone(RCard * card,RTelephoneType type)2062 r_card_find_telephone (RCard* card, RTelephoneType type)
2063 {
2064   gpointer telephone;
2065 
2066   g_return_val_if_fail(IS_R_CARD(card), NULL);
2067 
2068   telephone = r_card_get_telephone(card);
2069   for (; telephone; telephone = r_card_get_next_telephone(card))
2070     {
2071       RTelephoneType teltype;
2072 
2073       g_object_get(R_TELEPHONE(telephone), "telephone-type", &teltype, NULL);
2074       if (teltype == type)
2075 	return telephone;
2076     }
2077 
2078   return NULL;
2079 }
2080 
2081 
2082 
2083 /**
2084  * r_card_check
2085  * @card: a #RCard
2086  * @property: an #RCard's property
2087  * @value: the property's value (if set)
2088  *
2089  * check if the given property is set.
2090  *
2091  * returns: %FALSE if the property is %NULL, otherwise it return %TRUE and
2092  * the content of the property is copied into value
2093  **/
2094 gboolean
r_card_check(RCard * card,const gchar * property,gchar ** value)2095 r_card_check (RCard* card, const gchar* property, gchar** value)
2096 {
2097   gchar* tmp;
2098 
2099   g_return_val_if_fail(IS_R_CARD(card), FALSE);
2100 
2101   g_object_get(card, property, &tmp, NULL);
2102 
2103   if (tmp)
2104     {
2105       if (value)
2106 	*value = tmp;
2107 
2108       return TRUE;
2109     }
2110 
2111   return FALSE;
2112 }
2113 
2114 /* eof */
2115