* src/codeconv.c
[claws.git] / src / addritem.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2002 Match Grun
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * General primitive address item objects.
22  */
23
24 #include <stdio.h>
25 #include <glib.h>
26
27 #include "addritem.h"
28 #include "mgutils.h"
29
30 /*
31 * Create new email address item.
32 */
33 ItemEMail *addritem_create_item_email( void ) {
34         ItemEMail *item;
35         item = g_new0( ItemEMail, 1 );
36         ADDRITEM_TYPE(item) = ITEMTYPE_EMAIL;
37         ADDRITEM_ID(item) = NULL;
38         ADDRITEM_NAME(item) = NULL;
39         ADDRITEM_PARENT(item) = NULL;
40         ADDRITEM_SUBTYPE(item) = 0;
41         item->address = NULL;
42         item->remarks = NULL;
43         return item;
44 }
45
46 /*
47 * Create a shallow copy of specified email address item.
48 * Enter: item E-Mail to copy.
49 */
50 ItemEMail *addritem_copy_item_email( ItemEMail *item ) {
51         ItemEMail *itemNew = NULL;
52         if( item ) {
53                 itemNew = addritem_create_item_email();
54                 ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) );
55                 itemNew->address = g_strdup( item->address );
56                 itemNew->remarks = g_strdup( item->remarks );
57         }
58         return itemNew;
59 }
60
61 /*
62 * Create a full copy of specified email address item.
63 * Enter: item E-Mail to copy.
64 */
65 ItemEMail *addritem_copyfull_item_email( ItemEMail *item ) {
66         ItemEMail *itemNew = NULL;
67         if( item ) {
68                 itemNew = addritem_create_item_email();
69                 ADDRITEM_ID(itemNew) = g_strdup( ADDRITEM_ID(item) );
70                 ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) );
71                 ADDRITEM_PARENT(itemNew) = ADDRITEM_PARENT(item);
72                 itemNew->address = g_strdup( item->address );
73                 itemNew->remarks = g_strdup( item->remarks );
74         }
75         return itemNew;
76 }
77
78 void addritem_email_set_id( ItemEMail *email, const gchar *value ) {
79         ADDRITEM_ID(email) = mgu_replace_string( ADDRITEM_ID(email), value );
80 }
81 void addritem_email_set_alias( ItemEMail *email, const gchar *value ) {
82         ADDRITEM_NAME(email) = mgu_replace_string( ADDRITEM_NAME(email), value );
83 }
84 void addritem_email_set_address( ItemEMail *email, const gchar *value ) {
85         email->address = mgu_replace_string( email->address, value );
86 }
87 void addritem_email_set_remarks( ItemEMail *email, const gchar *value ) {
88         email->remarks = mgu_replace_string( email->remarks, value );
89 }
90
91 /*
92 * Free address item email.
93 */
94 void addritem_free_item_email( ItemEMail *item ) {
95         g_return_if_fail( item != NULL );
96
97         /* Free internal stuff */
98         g_free( ADDRITEM_ID(item) );
99         g_free( ADDRITEM_NAME(item) );
100         g_free( item->address );
101         g_free( item->remarks );
102
103         ADDRITEM_OBJECT(item)->type = ITEMTYPE_NONE;
104         ADDRITEM_ID(item) = NULL;
105         ADDRITEM_NAME(item) = NULL;
106         ADDRITEM_PARENT(item) = NULL;
107         ADDRITEM_SUBTYPE(item) = 0;
108         item->address = NULL;
109         item->remarks = NULL;
110         g_free( item );
111 }
112
113 /*
114 * Create new attribute.
115 */
116 UserAttribute *addritem_create_attribute( void ) {
117         UserAttribute *item;
118         item = g_new0( UserAttribute, 1 );
119         item->uid = NULL;
120         item->name = NULL;
121         item->value = NULL;
122         return item;
123 }
124
125 /*
126 * Create copy of specified attribute.
127 */
128 UserAttribute *addritem_copy_attribute( UserAttribute *item ) {
129         UserAttribute *itemNew = NULL;
130         if( item ) {
131                 itemNew = addritem_create_attribute();
132                 itemNew->uid = g_strdup( item->uid );
133                 itemNew->name = g_strdup( item->name );
134                 itemNew->value = g_strdup( item->value );
135         }
136         return itemNew;
137 }
138
139 void addritem_attrib_set_id( UserAttribute *item, const gchar *value ) {
140         g_return_if_fail( item != NULL );
141         item->uid = mgu_replace_string( item->uid, value );
142 }
143 void addritem_attrib_set_name( UserAttribute *item, const gchar *value ) {
144         g_return_if_fail( item != NULL );
145         item->name = mgu_replace_string( item->name, value );
146 }
147 void addritem_attrib_set_value( UserAttribute *item, const gchar *value ) {
148         g_return_if_fail( item != NULL );
149         item->value = mgu_replace_string( item->value, value );
150 }
151
152 /*
153 * Free user attribute.
154 */
155 void addritem_free_attribute( UserAttribute *item ) {
156         g_return_if_fail( item != NULL );
157         g_free( item->uid );
158         g_free( item->name );
159         g_free( item->value );
160         item->uid = NULL;
161         item->name = NULL;
162         item->value = NULL;
163         g_free( item );
164 }
165
166 /*
167 * Create new address book person.
168 */
169 ItemPerson *addritem_create_item_person( void ) {
170         ItemPerson *person;
171         person = g_new0( ItemPerson, 1 );
172         ADDRITEM_TYPE(person) = ITEMTYPE_PERSON;
173         ADDRITEM_ID(person) = NULL;
174         ADDRITEM_NAME(person) = NULL;
175         ADDRITEM_PARENT(person) = NULL;
176         ADDRITEM_SUBTYPE(person) = 0;
177         person->firstName = NULL;
178         person->lastName = NULL;
179         person->nickName = NULL;
180         person->listEMail = NULL;
181         person->listAttrib = NULL;
182         person->externalID = NULL;
183         person->isOpened = FALSE;
184         return person;
185 }
186
187 /*
188 * Create a shallow copy of address book person.
189 * Enter: item Person to copy.
190 */
191 ItemPerson *addritem_copy_item_person( ItemPerson *item ) {
192         ItemPerson *itemNew;
193
194         itemNew = NULL;
195         if( item ) {
196                 itemNew = addritem_create_item_person();
197                 ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) );
198                 itemNew->firstName = g_strdup( item->firstName );
199                 itemNew->lastName = g_strdup( item->lastName );
200                 itemNew->nickName = g_strdup( item->nickName );
201                 itemNew->externalID = g_strdup( item->externalID );
202         }
203         return itemNew;
204 }
205
206 void addritem_person_set_id( ItemPerson *person, const gchar *value ) {
207         ADDRITEM_ID(person) = mgu_replace_string( ADDRITEM_ID(person), value );
208 }
209 void addritem_person_set_first_name( ItemPerson *person, const gchar *value ) {
210         person->firstName = mgu_replace_string( person->firstName, value );
211 }
212 void addritem_person_set_last_name( ItemPerson *person, const gchar *value ) {
213         person->lastName = mgu_replace_string( person->lastName, value );
214 }
215 void addritem_person_set_nick_name( ItemPerson *person, const gchar *value ) {
216         person->nickName = mgu_replace_string( person->nickName, value );
217 }
218 void addritem_person_set_common_name( ItemPerson *person, const gchar *value ) {
219         ADDRITEM_NAME(person) = mgu_replace_string( ADDRITEM_NAME(person), value );
220 }
221 void addritem_person_set_external_id( ItemPerson *person, const gchar *value ) {
222         person->externalID = mgu_replace_string( person->externalID, value );
223 }
224 void addritem_person_set_opened( ItemPerson *person, const gboolean value ) {
225         person->isOpened = value;
226 }
227
228 /*
229 * Free linked list of item addresses.
230 */
231 void addritem_free_list_email( GList *list ) {
232         GList *node = list;
233         while( node ) {
234                 addritem_free_item_email( node->data );
235                 node->data = NULL;
236                 node = g_list_next( node );
237         }
238         g_list_free( list );
239 }
240
241 /*
242 * Free linked list of attributes.
243 */
244 void addritem_free_list_attribute( GList *list ) {
245         GList *node = list;
246         while( node ) {
247                 addritem_free_attribute( node->data );
248                 node->data = NULL;
249                 node = g_list_next( node );
250         }
251         g_list_free( list );
252 }
253
254 /*
255 * Free address person.
256 */
257 void addritem_free_item_person( ItemPerson *person ) {
258         g_return_if_fail( person != NULL );
259
260         /* Free internal stuff */
261         g_free( ADDRITEM_ID(person) );
262         g_free( ADDRITEM_NAME(person) );
263         g_free( person->firstName );
264         g_free( person->lastName );
265         g_free( person->nickName );
266         g_free( person->externalID );
267         addritem_free_list_email( person->listEMail );
268         addritem_free_list_attribute( person->listAttrib );
269
270         ADDRITEM_OBJECT(person)->type = ITEMTYPE_NONE;
271         ADDRITEM_ID(person) = NULL;
272         ADDRITEM_NAME(person) = NULL;
273         ADDRITEM_PARENT(person) = NULL;
274         ADDRITEM_SUBTYPE(person) = 0;
275         person->firstName = NULL;
276         person->lastName = NULL;
277         person->nickName = NULL;
278         person->externalID = NULL;
279         person->listEMail = NULL;
280         person->listAttrib = NULL;
281
282         g_free( person );
283 }
284
285 /*
286 * Print address item.
287 */
288 void addritem_print_item_email( ItemEMail *item, FILE *stream ) {
289         g_return_if_fail( item != NULL );
290         fprintf( stream, "\t\tt/id: %d : '%s'\n", ADDRITEM_TYPE(item), ADDRITEM_ID(item) );
291         fprintf( stream, "\t\tsubty: %d\n", ADDRITEM_SUBTYPE(item) );
292         fprintf( stream, "\t\talis: '%s'\n", ADDRITEM_NAME(item) );
293         fprintf( stream, "\t\taddr: '%s'\n", item->address );
294         fprintf( stream, "\t\trems: '%s'\n", item->remarks );
295         fprintf( stream, "\t\t---\n" );
296 }
297
298 /*
299 * Print user attribute.
300 */
301 void addritem_print_attribute( UserAttribute *item, FILE *stream ) {
302         g_return_if_fail( item != NULL );
303         fprintf( stream, "\t\tuid  : '%s'\n", item->uid );
304         fprintf( stream, "\t\tname : '%s'\n", item->name );
305         fprintf( stream, "\t\tvalue: '%s'\n", item->value );
306         fprintf( stream, "\t\t---\n" );
307 }
308
309 /*
310 * Print person item.
311 */
312 void addritem_print_item_person( ItemPerson *person, FILE *stream ) {
313         GList *node;
314         g_return_if_fail( person != NULL );
315         fprintf( stream, "Person:\n" );
316         fprintf( stream, "\tt/uid: %d : '%s'\n", ADDRITEM_TYPE(person), ADDRITEM_ID(person) );
317         fprintf( stream, "\tsubty: %d\n", ADDRITEM_SUBTYPE(person) );
318         fprintf( stream, "\tcommn: '%s'\n", ADDRITEM_NAME(person) );
319         fprintf( stream, "\tfirst: '%s'\n", person->firstName );
320         fprintf( stream, "\tlast : '%s'\n", person->lastName );
321         fprintf( stream, "\tnick : '%s'\n", person->nickName );
322         fprintf( stream, "\textID: '%s'\n", person->externalID );
323         fprintf( stream, "\teMail:\n" );
324         fprintf( stream, "\t---\n" );
325         node = person->listEMail;
326         while( node ) {
327                 addritem_print_item_email( node->data, stream );
328                 node = g_list_next( node );
329         }
330         fprintf( stream, "\tuAttr:\n" );
331         fprintf( stream, "\t---\n" );
332         node = person->listAttrib;
333         while( node ) {
334                 addritem_print_attribute( node->data, stream );
335                 node = g_list_next( node );
336         }
337         fprintf( stream, "\t===\n" );
338 }
339
340 /*
341 * Add EMail address to person.
342 * return: TRUE if item added.
343 */
344 gboolean addritem_person_add_email( ItemPerson *person, ItemEMail *email ) {
345         GList *node;
346
347         g_return_val_if_fail( person != NULL, FALSE );
348         g_return_val_if_fail( email != NULL, FALSE );
349
350         node = person->listEMail;
351         while( node ) {
352                 if( node->data == email ) return FALSE;
353                 node = g_list_next( node );
354         }
355         person->listEMail = g_list_append( person->listEMail, email );
356         ADDRITEM_PARENT(email) = ADDRITEM_OBJECT(person);
357         return TRUE;
358 }
359
360 /*
361 * Return email object with specified ID.
362 * param: person Person object.
363 *        eid    EMail ID.
364 * return: EMail object, or NULL if not found.
365 */
366 ItemEMail *addritem_person_get_email( ItemPerson *person, const gchar *eid ) {
367         ItemEMail *email = NULL;
368         GList *node;
369
370         g_return_val_if_fail( person != NULL, NULL );
371         if( eid == NULL || *eid == '\0' ) return NULL;
372
373         /* Look for email */
374         node = person->listEMail;
375         while( node ) {
376                 AddrItemObject *objE = node->data;
377                 gchar *ide = ADDRITEM_ID(objE);
378                 if( ide ) {
379                         if( strcmp( ide, eid ) == 0 ) {
380                                 email = ( ItemEMail * ) objE;
381                         }
382                 }
383                 node = g_list_next( node );
384         }
385         return email;
386 }
387
388 /*
389 * Remove email address for specified person.
390 * param: person Person object.
391 *        eid    EMail ID.
392 * return: EMail object, or NULL if not found. Note that object should still be freed.
393 */
394 ItemEMail *addritem_person_remove_email_id( ItemPerson *person, const gchar *eid ) {
395         ItemEMail *email = NULL;
396         GList *node;
397
398         g_return_val_if_fail( person != NULL, NULL );
399         if( eid == NULL || *eid == '\0' ) return NULL;
400
401         /* Look for email */
402         node = person->listEMail;
403         while( node ) {
404                 AddrItemObject *objE = node->data;
405                 gchar *ide = ADDRITEM_ID(objE);
406                 if( ide ) {
407                         if( strcmp( ide, eid ) == 0 ) {
408                                 email = ( ItemEMail * ) objE;
409                         }
410                 }
411                 node = g_list_next( node );
412         }
413
414         if( email ) {
415                 /* Remove email from person's address list */
416                 if( person->listEMail ) {
417                         person->listEMail = g_list_remove( person->listEMail, email );
418                 }
419                 /* Unlink reference to person. */
420                 ADDRITEM_PARENT(email) = NULL;
421         }
422         return email;
423 }
424
425 /*
426 * Remove email address for specified.
427 * param: person Person.
428 *        email  EMail to remove.
429 * return: EMail object, or NULL if not found. Note that object should still be freed.
430 */
431 ItemEMail *addritem_person_remove_email( ItemPerson *person, ItemEMail *email ) {
432         gboolean found = FALSE;
433         GList *node;
434
435         g_return_val_if_fail( person != NULL, NULL );
436         if( email == NULL ) return NULL;
437
438         /* Look for email */
439         node = person->listEMail;
440         while( node ) {
441                 if( node-> data == email ) {
442                         found = TRUE;
443                         break;
444                 }
445                 node = g_list_next( node );
446         }
447
448         if( found ) {
449                 /* Remove email from person's address list */
450                 if( person->listEMail ) {
451                         person->listEMail = g_list_remove( person->listEMail, email );
452                 }
453                 /* Unlink reference to person. */
454                 ADDRITEM_PARENT(email) = NULL;
455                 return email;
456         }
457         return NULL;
458 }
459
460 /*
461 * Add user attribute to person.
462 * return: TRUE if item added.
463 */
464 void addritem_person_add_attribute( ItemPerson *person, UserAttribute *attrib ) {
465         g_return_if_fail( person != NULL );
466         person->listAttrib = g_list_append( person->listAttrib, attrib );
467 }
468
469 /*
470 * Return attribute with specified ID.
471 * param: person Person object.
472 *        aid    Attribute ID.
473 * return: UserAttribute object, or NULL if not found. Note that object should still be freed.
474 */
475 UserAttribute *addritem_person_get_attribute( ItemPerson *person, const gchar *aid ) {
476         UserAttribute *attrib = NULL;
477         GList *node;
478
479         g_return_val_if_fail( person != NULL, NULL );
480         if( aid == NULL || *aid == '\0' ) return NULL;
481
482         /* Look for attribute */
483         node = person->listAttrib;
484         while( node ) {
485                 UserAttribute *attr = node->data;
486                 gchar *ida = attr->uid;
487                 if( ida ) {
488                         if( strcmp( ida, aid ) == 0 ) {
489                                 attrib = attr;
490                         }
491                 }
492                 node = g_list_next( node );
493         }
494         return attrib;
495 }
496
497 /*
498 * Remove attribute from person.
499 * param: person Person object.
500 *        aid    Attribute ID.
501 * return: UserAttribute object, or NULL if not found. Note that object should still be freed.
502 */
503 UserAttribute *addritem_person_remove_attrib_id( ItemPerson *person, const gchar *aid ) {
504         UserAttribute *attrib = NULL;
505         GList *node;
506
507         g_return_val_if_fail( person != NULL, NULL );
508         if( aid == NULL || *aid == '\0' ) return NULL;
509
510         /* Look for attribute */
511         node = person->listAttrib;
512         while( node ) {
513                 UserAttribute *attr = node->data;
514                 gchar *ida = attr->uid;
515                 if( ida ) {
516                         if( strcmp( ida, aid ) == 0 ) {
517                                 attrib = attr;
518                         }
519                 }
520                 node = g_list_next( node );
521         }
522
523         /* Remove email from person's address list */
524         if( person->listAttrib ) {
525                 person->listAttrib = g_list_remove( person->listAttrib, attrib );
526         }
527         return attrib;
528 }
529
530 /*
531 * Remove attribute from person.
532 * param: person Person.
533 *        attrib Attribute to remove.
534 * return: UserAttribute object. Note that object should still be freed.
535 */
536 UserAttribute *addritem_person_remove_attribute( ItemPerson *person, UserAttribute *attrib ) {
537         gboolean found = FALSE;
538         GList *node;
539
540         g_return_val_if_fail( person != NULL, NULL );
541         if( attrib == NULL ) return NULL;
542
543         /* Look for attribute */
544         node = person->listAttrib;
545         while( node ) {
546                 if( node-> data == attrib ) {
547                         found = TRUE;
548                         break;
549                 }
550                 node = g_list_next( node );
551         }
552
553         if( found ) {
554                 /* Remove attribute */
555                 if( person->listAttrib ) {
556                         person->listAttrib = g_list_remove( person->listAttrib, attrib );
557                 }
558         }
559         return attrib;
560 }
561
562 /*
563 * Create new address book group.
564 */
565 ItemGroup *addritem_create_item_group( void ) {
566         ItemGroup *group;
567
568         group = g_new0( ItemGroup, 1 );
569         ADDRITEM_TYPE(group) = ITEMTYPE_GROUP;
570         ADDRITEM_ID(group) = NULL;
571         ADDRITEM_NAME(group) = NULL;
572         ADDRITEM_PARENT(group) = NULL;
573         ADDRITEM_SUBTYPE(group) = 0;
574         group->remarks = NULL;
575         group->listEMail = NULL;
576         return group;
577 }
578
579 /*
580 * Copy address book group.
581 * Enter:  item Group to copy.
582 * Return: A copy of the group. 
583 */
584 ItemGroup *addritem_copy_item_group( ItemGroup *item ) {
585         ItemGroup *itemNew;
586
587         itemNew = g_new0( ItemGroup, 1 );
588         if( item ) {
589                 itemNew = addritem_create_item_group();
590                 ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) );
591                 itemNew->remarks = g_strdup( item->remarks );
592         }
593         return itemNew;
594 }
595
596 /*
597 * Specify name to be used.
598 */
599 void addritem_group_set_id( ItemGroup *group, const gchar *value ) {
600         ADDRITEM_ID(group) = mgu_replace_string( ADDRITEM_ID(group), value );
601 }
602 void addritem_group_set_name( ItemGroup *group, const gchar *value ) {
603         ADDRITEM_NAME(group) = mgu_replace_string( ADDRITEM_NAME(group), value );
604 }
605 void addritem_group_set_remarks( ItemGroup *group, const gchar *value ) {
606         group->remarks = mgu_replace_string( group->remarks, value );
607 }
608
609 /*
610 * Free address group.
611 */
612 void addritem_free_item_group( ItemGroup *group ) {
613         g_return_if_fail( group != NULL );
614
615         /* Free internal stuff */
616         g_free( ADDRITEM_ID(group) );
617         g_free( ADDRITEM_NAME(group) );
618         g_free( group->remarks );
619         mgu_clear_list( group->listEMail );
620         g_list_free( group->listEMail );
621
622         ADDRITEM_TYPE(group) = ITEMTYPE_NONE;
623         ADDRITEM_ID(group) = NULL;
624         ADDRITEM_NAME(group) = NULL;
625         ADDRITEM_PARENT(group) = NULL;
626         ADDRITEM_SUBTYPE(group) = 0;
627         group->remarks = NULL;
628         group->listEMail = NULL;
629
630         g_free( group );
631 }
632
633 /*
634 * Add EMail address to group.
635 * return: TRUE if item added.
636 */
637 gboolean addritem_group_add_email( ItemGroup *group, ItemEMail *email ) {
638         GList *node;
639
640         g_return_val_if_fail( group != NULL, FALSE );
641         g_return_val_if_fail( email != NULL, FALSE );
642
643         node = group->listEMail;
644         while( node ) {
645                 if( node->data == email ) return FALSE;
646                 node = g_list_next( node );
647         }
648         group->listEMail = g_list_append( group->listEMail, email );
649         return TRUE;
650 }
651
652 /*
653 * Remove email address for specified group.
654 * param: group  Group from which to remove address.
655 *        email  EMail to remove
656 * return: EMail object, or NULL if email not found in group. Note that this object is
657 * referenced (linked) to a group and should *NOT* be freed. This object should only be
658 * freed after removing from a person.
659 */
660 ItemEMail *addritem_group_remove_email( ItemGroup *group, ItemEMail *email ) {
661         if( group && email ) {
662                 GList *node = group->listEMail;
663                 while( node ) {
664                         if( node->data == email ) {
665                                 group->listEMail = g_list_remove( group->listEMail, email );
666                                 return email;
667                         }
668                         node = g_list_next( node );
669                 }
670         }
671         return NULL;
672 }
673
674 /*
675 * Remove email address for specified group and ID.
676 * param: group  Group from which to remove address.
677 *        eid    EMail ID.
678 * return: EMail object, or NULL if email not found in group. Note that this object is
679 * referenced (linked) to a group and should *NOT* be freed. This object should only be
680 * freed after removing from a person.
681 */
682 ItemEMail *addritem_group_remove_email_id( ItemGroup *group, const gchar *eid ) {
683         if( group ) {
684                 GList *node = group->listEMail;
685                 while( node ) {
686                         ItemEMail *email = ( ItemEMail * ) node->data;
687                         if( strcmp( ADDRITEM_ID( email ), eid ) == 0 ) {
688                                 group->listEMail = g_list_remove( group->listEMail, email );
689                                 return email;
690                         }
691                         node = g_list_next( node );
692                 }
693         }
694         return NULL;
695 }
696
697 /*
698 * Print address group item.
699 */
700 void addritem_print_item_group( ItemGroup *group, FILE *stream ) {
701         GList *node;
702         ItemPerson *person;
703         ItemEMail *item;
704         g_return_if_fail( group != NULL );
705         fprintf( stream, "Group:\n" );
706         fprintf( stream, "\tt/u: %d : '%s'\n", ADDRITEM_TYPE(group), ADDRITEM_ID(group) );
707         fprintf( stream, "\tsub: %d\n", ADDRITEM_SUBTYPE(group) );
708         fprintf( stream, "\tgrp: '%s'\n", ADDRITEM_NAME(group) );
709         fprintf( stream, "\trem: '%s'\n", group->remarks );
710         fprintf( stream, "\t---\n" );
711         node = group->listEMail;
712         while( node ) {
713                 item = node->data;
714                 person = ( ItemPerson * ) ADDRITEM_PARENT(item);
715                 if( person ) {
716                         fprintf( stream, "\t\tpid : '%s'\n", ADDRITEM_ID(person) );
717                         fprintf( stream, "\t\tcomn: '%s'\n", ADDRITEM_NAME(person) );
718                 }
719                 else {
720                         fprintf( stream, "\t\tpid : ???\n" );
721                         fprintf( stream, "\t\tcomn: ???\n" );
722                 }
723                 addritem_print_item_email( item, stream );
724                 node = g_list_next( node );
725         }
726         fprintf( stream, "\t***\n" );
727 }
728
729 /*
730 * Create new address folder.
731 */
732 ItemFolder *addritem_create_item_folder( void ) {
733         ItemFolder *folder;
734         folder = g_new0( ItemFolder, 1 );
735         ADDRITEM_TYPE(folder) = ITEMTYPE_FOLDER;
736         ADDRITEM_ID(folder) = NULL;
737         ADDRITEM_NAME(folder) = NULL;
738         ADDRITEM_PARENT(folder) = NULL;
739         ADDRITEM_SUBTYPE(folder) = 0;
740         folder->remarks = NULL;
741         folder->isRoot = FALSE;
742         folder->listItems = NULL;
743         folder->listFolder = NULL;
744         folder->listPerson = NULL;
745         folder->listGroup = NULL;
746         return folder;
747 }
748
749 /*
750 * Copy address book folder.
751 * Enter:  item Folder to copy.
752 * Return: A copy of the folder. 
753 */
754 ItemFolder *addritem_copy_item_folder( ItemFolder *item ) {
755         ItemFolder *itemNew;
756
757         itemNew = g_new0( ItemFolder, 1 );
758         if( item ) {
759                 itemNew = addritem_create_item_folder();
760                 ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) );
761         }
762         return itemNew;
763 }
764
765 /*
766 * Specify name to be used.
767 */
768 void addritem_folder_set_id( ItemFolder *folder, const gchar *value ) {
769         ADDRITEM_ID(folder) = mgu_replace_string( ADDRITEM_ID(folder), value );
770 }
771 void addritem_folder_set_name( ItemFolder *folder, const gchar *value ) {
772         ADDRITEM_NAME(folder) = mgu_replace_string( ADDRITEM_NAME(folder), value );
773 }
774 void addritem_folder_set_remarks( ItemFolder *folder, const gchar *value ) {
775         folder->remarks = mgu_replace_string( folder->remarks, value );
776 }
777
778 /*
779 * Free address folder. Note: this does not free up the lists of children
780 * (folders, groups and person). This should be done prior to calling this
781 * function.
782 */
783 void addritem_free_item_folder( ItemFolder *folder ) {
784         g_return_if_fail( folder != NULL );
785
786         /* Free internal stuff */
787         g_free( ADDRITEM_ID(folder) );
788         g_free( ADDRITEM_NAME(folder) );
789         g_free( folder->remarks );
790         mgu_clear_list( folder->listItems );
791         g_list_free( folder->listItems );
792
793         ADDRITEM_TYPE(folder) = ITEMTYPE_NONE;
794         ADDRITEM_ID(folder) = NULL;
795         ADDRITEM_NAME(folder) = NULL;
796         ADDRITEM_PARENT(folder) = NULL;
797         ADDRITEM_SUBTYPE(folder) = 0;
798         folder->isRoot = FALSE;
799         folder->remarks = NULL;
800         folder->listItems = NULL;
801         folder->listFolder = NULL;
802         folder->listGroup = NULL;
803         folder->listPerson = NULL;
804
805         g_free( folder );
806 }
807
808 /*
809 * Free up folders recursively. Note: this does not free up the lists of children
810 * (folders, groups and person). This should be done prior to calling this
811 * function.
812 */
813 void addritem_free_item_folder_recurse( ItemFolder *parent ) {
814         GList *node = parent->listFolder;
815
816         while( node ) {
817                 ItemFolder *folder = node->data;
818                 addritem_free_item_folder_recurse( folder );
819                 node = g_list_next( node );
820         }
821         g_list_free( parent->listPerson );
822         g_list_free( parent->listGroup );
823         g_list_free( parent->listFolder );
824         parent->listPerson = NULL;
825         parent->listGroup = NULL;
826         parent->listFolder = NULL;
827 }
828
829 /*
830 * Free up list of person in specified folder.
831 */
832 void addritem_folder_free_person( ItemFolder *folder ) {
833         GList *node;
834
835         g_return_if_fail( folder != NULL );
836         
837         /* Free up folder of persons. */
838         node = folder->listPerson;
839         while( node ) {
840                 ItemPerson *person = node->data;
841                 addritem_free_item_person( person );
842                 person = NULL;
843                 node = g_list_next( node );
844         }
845 }
846
847 /*
848 * Add person into folder.
849 * return: TRUE if person added.
850 */
851 gboolean addritem_folder_add_person( ItemFolder *folder, ItemPerson *item ) {
852         g_return_val_if_fail( folder != NULL, FALSE );
853         g_return_val_if_fail( item != NULL, FALSE );
854
855         folder->listPerson = g_list_append( folder->listPerson, item );
856         ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder);
857         return TRUE;
858 }
859
860 /*
861 * Add folder into folder.
862 * return: TRUE if folder added.
863 */
864 gboolean addritem_folder_add_folder( ItemFolder *folder, ItemFolder *item ) {
865         g_return_val_if_fail( folder != NULL, FALSE );
866         g_return_val_if_fail( item != NULL, FALSE );
867
868         folder->listFolder = g_list_append( folder->listFolder, item );
869         ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder);
870         return TRUE;
871 }
872
873 /*
874 * Add group into folder.
875 * return: TRUE if folder added.
876 */
877 gboolean addritem_folder_add_group( ItemFolder *folder, ItemGroup *item ) {
878         g_return_val_if_fail( folder != NULL, FALSE );
879         g_return_val_if_fail( item != NULL, FALSE );
880
881         folder->listGroup = g_list_append( folder->listGroup, item );
882         ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder);
883         return TRUE;
884 }
885
886 /*
887 * Print address folder item.
888 */
889 void addritem_print_item_folder( ItemFolder *folder, FILE *stream ) {
890         GList *node;
891         /* ItemPerson *person; */
892         ItemFolder *parent;
893
894         g_return_if_fail( folder != NULL );
895
896         fprintf( stream, "Folder:\n" );
897         fprintf( stream, "\tt/u: %d : '%s'\n", ADDRITEM_TYPE(folder), ADDRITEM_ID(folder) );
898         fprintf( stream, "\tsub: %d\n", ADDRITEM_SUBTYPE(folder) );
899         fprintf( stream, "\tnam: '%s'\n", ADDRITEM_NAME(folder) );
900         fprintf( stream, "\trem: '%s'\n", folder->remarks );
901         fprintf( stream, "\t---\n" );
902         parent = ( ItemFolder * ) ADDRITEM_PARENT(folder);
903         if( parent ) {
904                 fprintf( stream, "\tpar: %s : %s\n", ADDRITEM_ID(parent), ADDRITEM_NAME(parent) );
905         }
906         else {
907                 fprintf( stream, "\tpar: NULL\n" );
908         }
909         node = folder->listFolder;
910         while( node ) {
911                 AddrItemObject *aio = node->data;
912                 if( aio ) {
913                         if( aio->type == ITEMTYPE_FOLDER ) {
914                                 ItemFolder *item = ( ItemFolder * ) aio;
915                                 addritem_print_item_folder( item, stream );
916                         }
917                 }
918                 else {
919                         fprintf( stream, "\t\tpid : ???\n" );
920                 }
921
922                 node = g_list_next( node );
923         }
924
925         node = folder->listPerson;
926         while( node ) {
927                 AddrItemObject *aio = node->data;
928                 if( aio ) {
929                         if( aio->type == ITEMTYPE_PERSON ) {
930                                 ItemPerson *item = ( ItemPerson * ) aio;
931                                 addritem_print_item_person( item, stream );
932                         }
933                 }
934                 else {
935                         fprintf( stream, "\t\tpid : ???\n" );
936                 }
937
938                 node = g_list_next( node );
939         }
940
941         node = folder->listGroup;
942         while( node ) {
943                 AddrItemObject *aio = node->data;
944                 if( aio ) {
945                         if( aio->type == ITEMTYPE_GROUP ) {
946                                 ItemGroup *item = ( ItemGroup * ) aio;
947                                 addritem_print_item_group( item, stream );
948                         }
949                 }
950                 else {
951                         fprintf( stream, "\t\tpid : ???\n" );
952                 }
953                 node = g_list_next( node );
954         }
955         fprintf( stream, "\t###\n" );
956 }
957
958 /*
959 * Print address item.
960 */
961 void addritem_print_item( AddrItemObject *aio, FILE *stream ) {
962         g_return_if_fail( aio != NULL );
963
964         if( aio->type == ITEMTYPE_PERSON ) {
965                 ItemPerson *item = ( ItemPerson * ) aio;
966                 addritem_print_item_person( item, stream );
967         }
968         else if( aio->type == ITEMTYPE_EMAIL ) {
969                 ItemEMail *item = ( ItemEMail * ) aio;
970                 addritem_print_item_email( item, stream );
971         }
972         else if( aio->type == ITEMTYPE_GROUP ) {
973                 ItemGroup *item = ( ItemGroup * ) aio;
974                 addritem_print_item_group( item, stream );
975         }
976         else if( aio->type == ITEMTYPE_FOLDER ) {
977                 ItemFolder *item = ( ItemFolder * ) aio;
978                 addritem_print_item_folder( item, stream );
979         }
980 }
981
982 /*
983 * Return link list of persons for specified folder. Note that the list contains
984 * references to items and should be g_free() when done. Do *NOT* attempt to use the
985 * addritem_free_xxx() functions... this will destroy the addressbook data!
986 * Return: List of items, or NULL if none.
987 */
988 GList *addritem_folder_get_person_list( ItemFolder *folder ) {
989         GList *list = NULL;
990         GList *node = NULL;
991
992         g_return_val_if_fail( folder != NULL, NULL );
993
994         node = folder->listPerson;
995         while( node ) {
996                 ItemPerson *person = node->data;
997                 list = g_list_append( list, person );
998                 node = g_list_next( node );
999         }
1000         return list;
1001 }
1002
1003 /*
1004 * Return link list of groups for specified folder. Note that the list contains
1005 * references to items and should be g_free() when done. Do *NOT* attempt to use the
1006 * addritem_free_xxx() functions... this will destroy the addressbook data!
1007 * Return: List of items, or NULL if none.
1008 */
1009 GList *addritem_folder_get_group_list( ItemFolder *folder ) {
1010         GList *list = NULL;
1011         GList *node = NULL;
1012
1013         g_return_val_if_fail( folder != NULL, NULL );
1014
1015         node = folder->listGroup;
1016         while( node ) {
1017                 ItemGroup *group = node->data;
1018                 list = g_list_append( list, group );
1019                 node = g_list_next( node );
1020         }
1021         return list;
1022 }
1023
1024 /*
1025 * Move person's email item.
1026 * param: person     Person.
1027 *        itemMove   Item to move.
1028 *        itemTarget Target item before which to move item.
1029 */
1030
1031 ItemEMail *addritem_move_email_before( ItemPerson *person, ItemEMail *itemMove, ItemEMail *itemTarget ) {
1032         gint posT, posM;
1033
1034         g_return_val_if_fail( person != NULL, NULL );
1035
1036         if( itemTarget == NULL ) return NULL;
1037         if( itemMove == NULL ) return NULL;
1038         if( itemMove == itemTarget ) return itemMove;
1039
1040         posT = g_list_index( person->listEMail, itemTarget );
1041         if( posT < 0 ) return NULL;
1042         posM = g_list_index( person->listEMail, itemMove );
1043         if( posM < 0 ) return NULL;
1044         person->listEMail = g_list_remove( person->listEMail, itemMove );
1045         person->listEMail = g_list_insert( person->listEMail, itemMove, posT );
1046         return itemMove;
1047 }
1048
1049 /*
1050 * Move person's email item.
1051 * param: person     Person.
1052 *        itemMove   Item to move.
1053 *        itemTarget Target item after which to move item.
1054 */
1055 ItemEMail *addritem_move_email_after( ItemPerson *person, ItemEMail *itemMove, ItemEMail *itemTarget ) {
1056         gint posT, posM;
1057
1058         g_return_val_if_fail( person != NULL, NULL );
1059
1060         if( itemTarget == NULL ) return NULL;
1061         if( itemMove == NULL ) return NULL;
1062         if( itemMove == itemTarget ) return itemMove;
1063
1064         posT = g_list_index( person->listEMail, itemTarget );
1065         if( posT < 0 ) return NULL;
1066         posM = g_list_index( person->listEMail, itemMove );
1067         if( posM < 0 ) return NULL;
1068         person->listEMail = g_list_remove( person->listEMail, itemMove );
1069         person->listEMail = g_list_insert( person->listEMail, itemMove, 1+posT );
1070         return itemMove;
1071 }
1072
1073 /*
1074 * End of Source.
1075 */