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