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