/** * Create a full copy (deep copy) of specified email address item. * \param item E-Mail to copy. * \return Copy of email. */ ItemEMail *addritem_copyfull_item_email( ItemEMail *item ) { ItemEMail *itemNew = NULL; if( item ) { itemNew = addritem_create_item_email(); ADDRITEM_ID(itemNew) = g_strdup( ADDRITEM_ID(item) ); ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) ); ADDRITEM_PARENT(itemNew) = ADDRITEM_PARENT(item); itemNew->address = g_strdup( item->address ); itemNew->remarks = g_strdup( item->remarks ); } return itemNew; }
/* * Remove folder from cache. Children are deleted. * param: folder Folder to remove. * return: Folder, or NULL if not found. Note that object should still be freed. */ ItemFolder *addrcache_remove_folder_delete( AddressCache *cache, ItemFolder *folder ) { AddrItemObject *obj = NULL; cm_return_val_if_fail( cache != NULL, NULL ); if( folder ) { gchar *uid = ADDRITEM_ID(folder); if( uid == NULL || *uid == '\0' ) return NULL; obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); if( obj ) { ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(folder); if( ! parent ) parent = cache->rootFolder; /* Remove groups */ while( folder->listGroup ) { ItemGroup *item = ( ItemGroup * ) folder->listGroup->data; item = addrcache_remove_group( cache, item ); if( item ) { addritem_free_item_group( item ); item = NULL; } } while( folder->listPerson ) { ItemPerson *item = ( ItemPerson * ) folder->listPerson->data; item = addrcache_remove_person( cache, item ); if( item ) { addritem_free_item_person( item ); item = NULL; } } /* Recursive deletion of folder */ while( folder->listFolder ) { ItemFolder *item = ( ItemFolder * ) folder->listFolder->data; item = addrcache_remove_folder_delete( cache, item ); if( item ) { addritem_free_item_folder( item ); item = NULL; } } /* Remove folder from parent's list and hash table */ parent->listFolder = g_list_remove( parent->listFolder, folder ); ADDRITEM_PARENT(folder) = NULL; g_hash_table_remove( cache->itemHash, uid ); cache->dirtyFlag = TRUE; return folder; } } return NULL; }
/* * Move folder to destination folder. * Enter: cache Cache. * folder Folder to move. * target Target folder. */ void addrcache_folder_move_folder( AddressCache *cache, ItemFolder *folder, ItemFolder *target ) { ItemFolder *parent; cm_return_if_fail( cache != NULL ); cm_return_if_fail( folder != NULL ); parent = ( ItemFolder * ) ADDRITEM_PARENT(folder); if( ! parent ) parent = cache->rootFolder; parent->listFolder = g_list_remove( parent->listFolder, folder ); target->listFolder = g_list_append( target->listFolder, folder ); ADDRITEM_PARENT(folder) = ADDRITEM_OBJECT(target); cache->dirtyFlag = TRUE; }
/* * Move person to destination folder. * Enter: cache Cache. * person Person to move. * target Target folder. */ void addrcache_folder_move_person( AddressCache *cache, ItemPerson *person, ItemFolder *target ) { ItemFolder *parent; cm_return_if_fail( cache != NULL ); cm_return_if_fail( person != NULL ); parent = ( ItemFolder * ) ADDRITEM_PARENT(person); if( ! parent ) parent = cache->rootFolder; parent->listPerson = g_list_remove( parent->listPerson, person ); target->listPerson = g_list_append( target->listPerson, person ); ADDRITEM_PARENT(person) = ADDRITEM_OBJECT(target); cache->dirtyFlag = TRUE; }
/* * Remove folder from cache. Children are re-parented to parent folder. * param: folder Folder to remove. * return: Folder, or NULL if not found. Note that object should still be freed. */ ItemFolder *addrcache_remove_folder( AddressCache *cache, ItemFolder *folder ) { AddrItemObject *obj = NULL; cm_return_val_if_fail( cache != NULL, NULL ); if( folder ) { gchar *uid = ADDRITEM_ID(folder); if( uid == NULL || *uid == '\0' ) return NULL; obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); if( obj ) { ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(folder); GList *node; AddrItemObject *aio; if( ! parent ) parent = cache->rootFolder; /* Re-parent children in folder */ node = folder->listFolder; while( node ) { aio = ( AddrItemObject * ) node->data; parent->listFolder = g_list_append( parent->listFolder, aio ); aio->parent = ADDRITEM_OBJECT(parent); node = g_list_next( node ); } node = folder->listPerson; while( node ) { aio = ( AddrItemObject * ) node->data; parent->listPerson = g_list_append( parent->listPerson, aio ); aio->parent = ADDRITEM_OBJECT(parent); node = g_list_next( node ); } node = folder->listGroup; while( node ) { aio = ( AddrItemObject * ) node->data; parent->listGroup = g_list_append( parent->listGroup, aio ); aio->parent = ADDRITEM_OBJECT(parent); node = g_list_next( node ); } /* Remove folder from parent's list and hash table */ parent->listFolder = g_list_remove( parent->listFolder, folder ); ADDRITEM_PARENT(folder) = NULL; g_hash_table_remove( cache->itemHash, uid ); cache->dirtyFlag = TRUE; return folder; } } return NULL; }
/** * Free address folder. Note: this does not free up the lists of children * (folders, groups and person). This should be done prior to calling this * function. * \param folder Folder to free. */ void addritem_free_item_folder( ItemFolder *folder ) { g_return_if_fail( folder != NULL ); /* Free internal stuff */ g_free( ADDRITEM_ID(folder) ); g_free( ADDRITEM_NAME(folder) ); g_free( folder->remarks ); mgu_clear_list( folder->listItems ); g_list_free( folder->listItems ); ADDRITEM_TYPE(folder) = ITEMTYPE_NONE; ADDRITEM_ID(folder) = NULL; ADDRITEM_NAME(folder) = NULL; ADDRITEM_PARENT(folder) = NULL; ADDRITEM_SUBTYPE(folder) = 0; folder->isRoot = FALSE; folder->remarks = NULL; folder->listItems = NULL; folder->listFolder = NULL; folder->listGroup = NULL; folder->listPerson = NULL; folder->folderType = ADDRFOLDER_NONE; folder->folderData = NULL; folder->isHidden = FALSE; g_free( folder ); }
/** * Free address person object. * \param person Person object to free. */ void addritem_free_item_person( ItemPerson *person ) { g_return_if_fail( person != NULL ); /* Free internal stuff */ g_free( ADDRITEM_ID(person) ); g_free( ADDRITEM_NAME(person) ); g_free( person->firstName ); g_free( person->lastName ); g_free( person->nickName ); g_free( person->externalID ); g_list_free( person->listEMail ); addritem_free_list_attribute( person->listAttrib ); ADDRITEM_OBJECT(person)->type = ITEMTYPE_NONE; ADDRITEM_ID(person) = NULL; ADDRITEM_NAME(person) = NULL; ADDRITEM_PARENT(person) = NULL; ADDRITEM_SUBTYPE(person) = 0; person->firstName = NULL; person->lastName = NULL; person->nickName = NULL; person->externalID = NULL; person->listEMail = NULL; person->listAttrib = NULL; g_free( person ); }
/** * Remove email address with specified ID for specified person. * \param person Person object. * \param eid EMail ID. * \return EMail object, or <i>NULL</i> if not found. Note that object should * still be freed after calling this function. */ ItemEMail *addritem_person_remove_email_id( ItemPerson *person, const gchar *eid ) { ItemEMail *email = NULL; GList *node; g_return_val_if_fail( person != NULL, NULL ); if( eid == NULL || *eid == '\0' ) return NULL; /* Look for email */ node = person->listEMail; while( node ) { AddrItemObject *objE = node->data; gchar *ide = ADDRITEM_ID(objE); if( ide ) { if( strcmp( ide, eid ) == 0 ) { email = ( ItemEMail * ) objE; } } node = g_list_next( node ); } if( email ) { /* Remove email from person's address list */ if( person->listEMail ) { person->listEMail = g_list_remove( person->listEMail, email ); } /* Unlink reference to person. */ ADDRITEM_PARENT(email) = NULL; } return email; }
/* * Create new address cache. */ AddressCache *addrcache_create() { AddressCache *cache; gint t; cache = g_new0( AddressCache, 1 ); cache->itemHash = g_hash_table_new( g_str_hash, g_str_equal ); cache->cacheID = g_strdup_printf( "%d", addrcache_next_cache_id() ); cache->dataRead = FALSE; cache->modified = FALSE; cache->dirtyFlag = FALSE; cache->accessFlag = FALSE; cache->name = NULL; cache->modifyTime = 0; /* Generate the next ID using system time */ cache->nextID = 1; t = time( NULL ); if( t > 0 ) { cache->nextID = t - ID_TIME_OFFSET; } cache->tempList = NULL; cache->rootFolder = addritem_create_item_folder(); cache->rootFolder->isRoot = TRUE; ADDRITEM_PARENT(cache->rootFolder) = NULL; return cache; }
/** * Remove email address for specified person. * \param person Person. * \param email EMail to remove. * \return EMail object, or <i>NULL</i> if not found. Note that object should * still be freed after calling this method. */ ItemEMail *addritem_person_remove_email( ItemPerson *person, ItemEMail *email ) { gboolean found = FALSE; GList *node; g_return_val_if_fail( person != NULL, NULL ); if( email == NULL ) return NULL; /* Look for email */ node = person->listEMail; while( node ) { if( node-> data == email ) { found = TRUE; break; } node = g_list_next( node ); } if( found ) { /* Remove email from person's address list */ if( person->listEMail ) { person->listEMail = g_list_remove( person->listEMail, email ); } /* Unlink reference to person. */ ADDRITEM_PARENT(email) = NULL; return email; } return NULL; }
/** * Print address group item for debug. * \param group Group to print. * \param stream Output stream. */ void addritem_print_item_group( ItemGroup *group, FILE *stream ) { GList *node; ItemPerson *person; ItemEMail *item; g_return_if_fail( group != NULL ); fprintf( stream, "Group:\n" ); fprintf( stream, "\tt/u: %d : '%s'\n", ADDRITEM_TYPE(group), ADDRITEM_ID(group) ); fprintf( stream, "\tsub: %d\n", ADDRITEM_SUBTYPE(group) ); fprintf( stream, "\tgrp: '%s'\n", ADDRITEM_NAME(group) ); fprintf( stream, "\trem: '%s'\n", group->remarks ); fprintf( stream, "\t---\n" ); node = group->listEMail; while( node ) { item = node->data; person = ( ItemPerson * ) ADDRITEM_PARENT(item); if( person ) { fprintf( stream, "\t\tpid : '%s'\n", ADDRITEM_ID(person) ); fprintf( stream, "\t\tcomn: '%s'\n", ADDRITEM_NAME(person) ); } else { fprintf( stream, "\t\tpid : ???\n" ); fprintf( stream, "\t\tcomn: ???\n" ); } addritem_print_item_email( item, stream ); node = g_list_next( node ); } fprintf( stream, "\t***\n" ); }
/** * Format E-Mail address. * \param email EMail item to format. * \return Formatted string. Should be freed after use. */ gchar *addritem_format_email( ItemEMail *email ) { gchar *address; gchar *name; ItemPerson *person; address = NULL; name = NULL; if( ADDRITEM_NAME( email ) ) { if( strlen( ADDRITEM_NAME( email ) ) ) { name = ADDRITEM_NAME( email ); } } if( ! name ) { person = ( ItemPerson * ) ADDRITEM_PARENT( email ); name = ADDRITEM_NAME( person ); } if( name ) { if( strchr_with_skip_quote( name, '"', ',' ) ) { address = g_strdup_printf( "\"%s\" <%s>", name, email->address ); } else { address = g_strdup_printf( "%s <%s>", name, email->address ); } } else { address = g_strdup_printf( "%s", email->address ); } return address; }
/** * Replace an incompleted address with a completed one. * \param entry Address entry field. * \param newtext New text. * \param start_pos Insertion point in entry field. */ static void replace_address_in_edit(GtkEntry *entry, const gchar *newtext, gint start_pos, gboolean is_group, GList *grp_emails) { if (!newtext) return; gtk_editable_delete_text(GTK_EDITABLE(entry), start_pos, -1); if (!is_group) { gtk_editable_insert_text(GTK_EDITABLE(entry), newtext, strlen(newtext), &start_pos); } else { gchar *addresses = NULL; GList *cur = grp_emails; for (; cur; cur = cur->next) { gchar *tmp; ItemEMail *email = (ItemEMail *)cur->data; ItemPerson *person = ( ItemPerson * ) ADDRITEM_PARENT(email); gchar *addr = get_complete_address_from_name_email( ADDRITEM_NAME(person), email->address); if (addresses) tmp = g_strdup_printf("%s, %s", addresses, addr); else tmp = g_strdup_printf("%s", addr); g_free(addr); g_free(addresses); addresses = tmp; } gtk_editable_insert_text(GTK_EDITABLE(entry), addresses, strlen(addresses), &start_pos); g_free(addresses); } gtk_editable_set_position(GTK_EDITABLE(entry), -1); }
/** * Add person into folder. * \param folder Folder. * \param item Person to add. * \return <i>TRUE</i> if person added. */ gboolean addritem_folder_add_person( ItemFolder *folder, ItemPerson *item ) { g_return_val_if_fail( folder != NULL, FALSE ); g_return_val_if_fail( item != NULL, FALSE ); folder->listPerson = g_list_append( folder->listPerson, item ); ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder); return TRUE; }
/** * Add folder into folder. * \param folder Folder. * \param item Folder to add. * \return <i>TRUE</i> if folder added. */ gboolean addritem_folder_add_folder( ItemFolder *folder, ItemFolder *item ) { cm_return_val_if_fail( folder != NULL, FALSE ); cm_return_val_if_fail( item != NULL, FALSE ); folder->listFolder = g_list_append( folder->listFolder, item ); ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder); return TRUE; }
/** * Add group into folder. * \param folder Folder. * \param item Group to add. * \return <i>TRUE</i> if group added. */ gboolean addritem_folder_add_group( ItemFolder *folder, ItemGroup *item ) { g_return_val_if_fail( folder != NULL, FALSE ); g_return_val_if_fail( item != NULL, FALSE ); folder->listGroup = g_list_append( folder->listGroup, item ); ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder); return TRUE; }
/** * Build a path of all ancestor folders for specified folder. * \param folder Folder. * \param seq Path sequence, FALSE top down, TRUE bottom up. * \return List of folders from the top down. */ GList *addritem_folder_path( const ItemFolder *folder, const gboolean seq ) { GList *list; AddrItemObject *item; list = NULL; item = ( AddrItemObject * ) folder; if( seq ) { while( item ) { list = g_list_prepend( list, item ); item = ADDRITEM_PARENT( item ); } } else { while( item ) { list = g_list_append( list, item ); item = ADDRITEM_PARENT( item ); } } return list; }
/** * Create new email address item. * \return Initialized email item. */ ItemEMail *addritem_create_item_email( void ) { ItemEMail *item; item = g_new0( ItemEMail, 1 ); ADDRITEM_TYPE(item) = ITEMTYPE_EMAIL; ADDRITEM_ID(item) = NULL; ADDRITEM_NAME(item) = NULL; ADDRITEM_PARENT(item) = NULL; ADDRITEM_SUBTYPE(item) = 0; item->address = NULL; item->remarks = NULL; return item; }
/** * Create new address book group object. * \return Initialized group object. */ ItemGroup *addritem_create_item_group( void ) { ItemGroup *group; group = g_new0( ItemGroup, 1 ); ADDRITEM_TYPE(group) = ITEMTYPE_GROUP; ADDRITEM_ID(group) = NULL; ADDRITEM_NAME(group) = NULL; ADDRITEM_PARENT(group) = NULL; ADDRITEM_SUBTYPE(group) = 0; group->remarks = NULL; group->listEMail = NULL; return group; }
/* * Clear the address cache. */ void addrcache_clear( AddressCache *cache ) { cm_return_if_fail( cache != NULL ); /* g_print( "...addrcache_clear :%s:\n", cache->name ); */ /* Free up folders and hash table */ addrcache_free_all_folders( cache->rootFolder ); addrcache_free_item_hash( cache->itemHash ); g_hash_table_destroy( cache->itemHash ); cache->itemHash = NULL; ADDRITEM_PARENT(cache->rootFolder) = NULL; addritem_free_item_folder( cache->rootFolder ); cache->rootFolder = NULL; if( cache->tempList ) g_list_free( cache->tempList ); cache->tempList = NULL; /* Reset to initial state */ cache->itemHash = g_hash_table_new( g_str_hash, g_str_equal ); cache->rootFolder = addritem_create_item_folder(); cache->rootFolder->isRoot = TRUE; ADDRITEM_PARENT(cache->rootFolder) = NULL; addrcache_refresh( cache ); }
/** * Add E-Mail address object to person. * \param person Person. * \param email E-Mail object to add. * \return <i>TRUE</i> if E-Mail added. */ gboolean addritem_person_add_email( ItemPerson *person, ItemEMail *email ) { GList *node; g_return_val_if_fail( person != NULL, FALSE ); g_return_val_if_fail( email != NULL, FALSE ); node = person->listEMail; while( node ) { if( node->data == email ) return FALSE; node = g_list_next( node ); } person->listEMail = g_list_append( person->listEMail, email ); ADDRITEM_PARENT(email) = ADDRITEM_OBJECT(person); return TRUE; }
/** * Create new address book person. * \return Initialized person object. */ ItemPerson *addritem_create_item_person( void ) { ItemPerson *person; person = g_new0( ItemPerson, 1 ); ADDRITEM_TYPE(person) = ITEMTYPE_PERSON; ADDRITEM_ID(person) = NULL; ADDRITEM_NAME(person) = NULL; ADDRITEM_PARENT(person) = NULL; ADDRITEM_SUBTYPE(person) = 0; person->firstName = NULL; person->lastName = NULL; person->nickName = NULL; person->listEMail = NULL; person->listAttrib = NULL; person->externalID = NULL; person->isOpened = FALSE; return person; }
/* * Create new address folder. */ ItemFolder *addritem_create_item_folder( void ) { ItemFolder *folder; folder = g_new0( ItemFolder, 1 ); ADDRITEM_TYPE(folder) = ITEMTYPE_FOLDER; ADDRITEM_ID(folder) = NULL; ADDRITEM_NAME(folder) = NULL; ADDRITEM_PARENT(folder) = NULL; ADDRITEM_SUBTYPE(folder) = 0; folder->remarks = NULL; folder->isRoot = FALSE; folder->listItems = NULL; folder->listFolder = NULL; folder->listPerson = NULL; folder->listGroup = NULL; folder->userData = NULL; return folder; }
/** * Free address item email object. * \param item E-Mail item to free. */ void addritem_free_item_email( ItemEMail *item ) { g_return_if_fail( item != NULL ); /* Free internal stuff */ g_free( ADDRITEM_ID(item) ); g_free( ADDRITEM_NAME(item) ); g_free( item->address ); g_free( item->remarks ); ADDRITEM_OBJECT(item)->type = ITEMTYPE_NONE; ADDRITEM_ID(item) = NULL; ADDRITEM_NAME(item) = NULL; ADDRITEM_PARENT(item) = NULL; ADDRITEM_SUBTYPE(item) = 0; item->address = NULL; item->remarks = NULL; g_free( item ); }
/* * Free address cache. */ void addrcache_free( AddressCache *cache ) { cm_return_if_fail( cache != NULL ); cache->dirtyFlag = FALSE; addrcache_free_all_folders( cache->rootFolder ); addrcache_free_item_hash( cache->itemHash ); g_hash_table_destroy( cache->itemHash ); cache->itemHash = NULL; ADDRITEM_PARENT(cache->rootFolder) = NULL; addritem_free_item_folder( cache->rootFolder ); cache->rootFolder = NULL; g_list_free( cache->tempList ); cache->tempList = NULL; g_free( cache->cacheID ); cache->cacheID = NULL; g_free( cache->name ); cache->name = NULL; g_free( cache ); }
/* * Group visitor function. */ static void addrcache_get_grp_person_vis( gpointer key, gpointer value, gpointer data ) { AddrItemObject *obj = ( AddrItemObject * ) value; if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { AddressCache *cache = data; ItemGroup *group = ( ItemGroup * ) obj; ItemPerson *person = ( ItemPerson * ) cache->tempList->data; GList *node = group->listEMail; while( node ) { ItemEMail *email = ( ItemEMail * ) node->data; if( ADDRITEM_PARENT(email) == ADDRITEM_OBJECT(person) ) { if( ! g_list_find( cache->tempList, group ) ) { cache->tempList = g_list_append( cache->tempList, group ); } } node = g_list_next( node ); } } }
/* * Insert person and address into address cache. * Enter: muttFile MUTT control data. * cache Address cache. * address E-Mail address. * name Name. * Return: E-Mail object, either inserted or found in hash table. */ static ItemEMail *mutt_insert_table( MuttFile *muttFile, AddressCache *cache, gchar *address, gchar *name ) { ItemPerson *person; ItemEMail *email; gchar *key; /* Test whether address already in hash table */ key = g_strdup( address ); g_strdown( key ); email = g_hash_table_lookup( muttFile->uniqTable, key ); if( email == NULL ) { /* No - create person */ person = addritem_create_item_person(); addritem_person_set_common_name( person, name ); addrcache_id_person( cache, person ); addrcache_add_person( cache, person ); /* Add email for person */ email = addritem_create_item_email(); addritem_email_set_address( email, address ); addrcache_id_email( cache, email ); addrcache_person_add_email( cache, person, email ); /* Insert entry */ g_hash_table_insert( muttFile->uniqTable, key, email ); } else { /* Yes - update person with longest name */ person = ( ItemPerson * ) ADDRITEM_PARENT(email); if( strlen( name ) > strlen( ADDRITEM_NAME(person) ) ) { addritem_person_set_common_name( person, name ); } /* Free up */ g_free( key ); } return email; }
/* * Remove specified person from address cache. * param: person Person to remove. * return: Person, or NULL if not found. Note that object should still be freed. */ ItemPerson *addrcache_remove_person( AddressCache *cache, ItemPerson *person ) { AddrItemObject *obj = NULL; gchar *uid; cm_return_val_if_fail( cache != NULL, NULL ); if( person ) { uid = ADDRITEM_ID(person); if( uid == NULL || *uid == '\0' ) return NULL; obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); if( obj ) { if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { ItemFolder *parent; GList *node; /* Remove all email addresses for person */ /* from groups and from hash table */ node = person->listEMail; while( node ) { ItemEMail *email; gchar *eid; email = node->data; g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_email_vis, email ); eid = ADDRITEM_ID( email ); g_hash_table_remove( cache->itemHash, eid ); node = g_list_next( node ); } /* Remove person from owning folder */ parent = ( ItemFolder * ) ADDRITEM_PARENT(person); if( ! parent ) parent = cache->rootFolder; parent->listPerson = g_list_remove( parent->listPerson, person ); g_hash_table_remove( cache->itemHash, uid ); cache->dirtyFlag = TRUE; return person; } } } return NULL; }
/** * Free address group object. * \param group Group to free. */ void addritem_free_item_group( ItemGroup *group ) { g_return_if_fail( group != NULL ); /* Free internal stuff */ g_free( ADDRITEM_ID(group) ); g_free( ADDRITEM_NAME(group) ); g_free( group->remarks ); mgu_clear_list( group->listEMail ); g_list_free( group->listEMail ); ADDRITEM_TYPE(group) = ITEMTYPE_NONE; ADDRITEM_ID(group) = NULL; ADDRITEM_NAME(group) = NULL; ADDRITEM_PARENT(group) = NULL; ADDRITEM_SUBTYPE(group) = 0; group->remarks = NULL; group->listEMail = NULL; g_free( group ); }
/** * Create a new folder and add to address cache. * \param cache Address cache. * \param folder Parent folder where to add folder, or <i>NULL</i> for * root folder. * \return Folder that was created. This should <b>*NOT*</b> be * <code>g_free()</code> when done. */ ItemFolder *addrcache_add_new_folder( AddressCache *cache, ItemFolder *parent ) { ItemFolder *folder; ItemFolder *p = parent; cm_return_val_if_fail( cache != NULL, NULL ); if( !p ) p = cache->rootFolder; folder = addritem_create_item_folder(); addrcache_id_folder( cache, folder ); if( addrcache_hash_add_folder( cache, folder ) ) { p->listFolder = g_list_append( p->listFolder, folder ); ADDRITEM_PARENT(folder) = ADDRITEM_OBJECT(p); addrcache_set_dirty( cache, TRUE ); } else { addritem_free_item_folder( folder ); folder = NULL; } return folder; }