diff options
| author | Simeon Simeonov | 2018-02-26 11:23:00 +0100 |
|---|---|---|
| committer | Simeon Simeonov | 2018-02-26 11:23:00 +0100 |
| commit | 0b3cbf57875fd692e4ba0b336fefa4bee1ed00dc (patch) | |
| tree | af916a30553c78ce9d4f2d8658656a175c5b6921 /src/addrcache.c | |
Initial commit for sylpheed 3.7.0
Diffstat (limited to 'src/addrcache.c')
| -rw-r--r-- | src/addrcache.c | 1237 |
1 files changed, 1237 insertions, 0 deletions
diff --git a/src/addrcache.c b/src/addrcache.c new file mode 100644 index 0000000..55c7212 --- /dev/null +++ b/src/addrcache.c | |||
| @@ -0,0 +1,1237 @@ | |||
| 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 | * Functions to maintain address cache. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <glib.h> | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <string.h> | ||
| 27 | #include <sys/stat.h> | ||
| 28 | |||
| 29 | /* #include "mgutils.h" */ | ||
| 30 | #include "addritem.h" | ||
| 31 | #include "addrcache.h" | ||
| 32 | #include "utils.h" | ||
| 33 | |||
| 34 | #define ID_TIME_OFFSET 998000000 | ||
| 35 | #define ADDRCACHE_MAX_SEARCH_COUNT 1000 | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Create new address cache. | ||
| 39 | */ | ||
| 40 | AddressCache *addrcache_create() { | ||
| 41 | AddressCache *cache; | ||
| 42 | gint t; | ||
| 43 | |||
| 44 | cache = g_new0( AddressCache, 1 ); | ||
| 45 | cache->itemHash = g_hash_table_new( g_str_hash, g_str_equal ); | ||
| 46 | |||
| 47 | cache->dataRead = FALSE; | ||
| 48 | cache->modified = FALSE; | ||
| 49 | cache->modifyTime = 0; | ||
| 50 | |||
| 51 | /* Generate the next ID using system time */ | ||
| 52 | cache->nextID = 1; | ||
| 53 | t = time( NULL ); | ||
| 54 | if( t > 0 ) { | ||
| 55 | cache->nextID = t - ID_TIME_OFFSET; | ||
| 56 | } | ||
| 57 | |||
| 58 | cache->tempList = NULL; | ||
| 59 | cache->rootFolder = addritem_create_item_folder(); | ||
| 60 | cache->rootFolder->isRoot = TRUE; | ||
| 61 | ADDRITEM_PARENT(cache->rootFolder) = NULL; | ||
| 62 | return cache; | ||
| 63 | } | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Properties. | ||
| 67 | */ | ||
| 68 | ItemFolder *addrcache_get_root_folder( AddressCache *cache ) { | ||
| 69 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 70 | return cache->rootFolder; | ||
| 71 | } | ||
| 72 | GList *addrcache_get_list_folder( AddressCache *cache ) { | ||
| 73 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 74 | return cache->rootFolder->listFolder; | ||
| 75 | } | ||
| 76 | GList *addrcache_get_list_person( AddressCache *cache ) { | ||
| 77 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 78 | return cache->rootFolder->listPerson; | ||
| 79 | } | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Generate next ID. | ||
| 83 | */ | ||
| 84 | void addrcache_next_id( AddressCache *cache ) { | ||
| 85 | g_return_if_fail( cache != NULL ); | ||
| 86 | cache->nextID++; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* | ||
| 90 | * Refresh internal variables. This can be used force a reload. | ||
| 91 | */ | ||
| 92 | void addrcache_refresh( AddressCache *cache ) { | ||
| 93 | cache->dataRead = FALSE; | ||
| 94 | cache->modified = TRUE; | ||
| 95 | cache->modifyTime = 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | /* | ||
| 99 | * Free hash table visitor function. | ||
| 100 | */ | ||
| 101 | static gint addrcache_free_item_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 102 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 103 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 104 | addritem_free_item_person( ( ItemPerson * ) obj ); | ||
| 105 | } | ||
| 106 | else if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 107 | addritem_free_item_group( ( ItemGroup * ) obj ); | ||
| 108 | } | ||
| 109 | else if( ADDRITEM_TYPE(obj) == ITEMTYPE_FOLDER ) { | ||
| 110 | addritem_free_item_folder( ( ItemFolder * ) obj ); | ||
| 111 | } | ||
| 112 | key = NULL; | ||
| 113 | value = NULL; | ||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Free hash table of address cache items. | ||
| 119 | */ | ||
| 120 | static void addrcache_free_item_hash( GHashTable *table ) { | ||
| 121 | g_return_if_fail( table != NULL ); | ||
| 122 | g_hash_table_freeze( table ); | ||
| 123 | g_hash_table_foreach_remove( table, addrcache_free_item_vis, NULL ); | ||
| 124 | g_hash_table_thaw( table ); | ||
| 125 | g_hash_table_destroy( table ); | ||
| 126 | } | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Free up folders and groups. | ||
| 130 | */ | ||
| 131 | static void addrcache_free_all_folders( ItemFolder *parent ) { | ||
| 132 | GList *node = parent->listFolder; | ||
| 133 | while( node ) { | ||
| 134 | ItemFolder *folder = node->data; | ||
| 135 | addrcache_free_all_folders( folder ); | ||
| 136 | node = g_list_next( node ); | ||
| 137 | } | ||
| 138 | g_list_free( parent->listPerson ); | ||
| 139 | g_list_free( parent->listGroup ); | ||
| 140 | g_list_free( parent->listFolder ); | ||
| 141 | parent->listPerson = NULL; | ||
| 142 | parent->listGroup = NULL; | ||
| 143 | parent->listFolder = NULL; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Clear the address cache. | ||
| 148 | */ | ||
| 149 | void addrcache_clear( AddressCache *cache ) { | ||
| 150 | g_return_if_fail( cache != NULL ); | ||
| 151 | |||
| 152 | /* Free up folders and hash table */ | ||
| 153 | addrcache_free_all_folders( cache->rootFolder ); | ||
| 154 | addrcache_free_item_hash( cache->itemHash ); | ||
| 155 | cache->itemHash = NULL; | ||
| 156 | ADDRITEM_PARENT(cache->rootFolder) = NULL; | ||
| 157 | addritem_free_item_folder( cache->rootFolder ); | ||
| 158 | cache->rootFolder = NULL; | ||
| 159 | g_list_free( cache->tempList ); | ||
| 160 | cache->tempList = NULL; | ||
| 161 | |||
| 162 | /* Reset to initial state */ | ||
| 163 | cache->itemHash = g_hash_table_new( g_str_hash, g_str_equal ); | ||
| 164 | cache->rootFolder = addritem_create_item_folder(); | ||
| 165 | cache->rootFolder->isRoot = TRUE; | ||
| 166 | ADDRITEM_PARENT(cache->rootFolder) = NULL; | ||
| 167 | |||
| 168 | addrcache_refresh( cache ); | ||
| 169 | |||
| 170 | } | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Free address cache. | ||
| 174 | */ | ||
| 175 | void addrcache_free( AddressCache *cache ) { | ||
| 176 | g_return_if_fail( cache != NULL ); | ||
| 177 | |||
| 178 | addrcache_free_all_folders( cache->rootFolder ); | ||
| 179 | addrcache_free_item_hash( cache->itemHash ); | ||
| 180 | cache->itemHash = NULL; | ||
| 181 | ADDRITEM_PARENT(cache->rootFolder) = NULL; | ||
| 182 | addritem_free_item_folder( cache->rootFolder ); | ||
| 183 | cache->rootFolder = NULL; | ||
| 184 | g_list_free( cache->tempList ); | ||
| 185 | cache->tempList = NULL; | ||
| 186 | g_free( cache ); | ||
| 187 | } | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Check whether file has changed by comparing with cache. | ||
| 191 | * return: TRUE if file has changed. | ||
| 192 | */ | ||
| 193 | gboolean addrcache_check_file( AddressCache *cache, gchar *path ) { | ||
| 194 | gboolean retVal; | ||
| 195 | GStatBuf filestat; | ||
| 196 | retVal = TRUE; | ||
| 197 | if( path ) { | ||
| 198 | if( 0 == g_stat( path, &filestat ) ) { | ||
| 199 | if( filestat.st_mtime == cache->modifyTime ) retVal = FALSE; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | return retVal; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* | ||
| 206 | * Save file time to cache. | ||
| 207 | * return: TRUE if time marked. | ||
| 208 | */ | ||
| 209 | gboolean addrcache_mark_file( AddressCache *cache, gchar *path ) { | ||
| 210 | gboolean retVal = FALSE; | ||
| 211 | GStatBuf filestat; | ||
| 212 | if( path ) { | ||
| 213 | if( 0 == g_stat( path, &filestat ) ) { | ||
| 214 | cache->modifyTime = filestat.st_mtime; | ||
| 215 | retVal = TRUE; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | return retVal; | ||
| 219 | } | ||
| 220 | |||
| 221 | /* | ||
| 222 | * Print list of items. | ||
| 223 | */ | ||
| 224 | void addrcache_print_item_list( GList *list, FILE *stream ) { | ||
| 225 | GList *node = list; | ||
| 226 | while( node ) { | ||
| 227 | AddrItemObject *obj = node->data; | ||
| 228 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 229 | addritem_print_item_person( ( ItemPerson * ) obj, stream ); | ||
| 230 | } | ||
| 231 | else if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 232 | addritem_print_item_group( ( ItemGroup * ) obj, stream ); | ||
| 233 | } | ||
| 234 | else if( ADDRITEM_TYPE(obj) == ITEMTYPE_FOLDER ) { | ||
| 235 | addritem_print_item_folder( ( ItemFolder * ) obj, stream ); | ||
| 236 | } | ||
| 237 | node = g_list_next( node ); | ||
| 238 | } | ||
| 239 | fprintf( stream, "\t---\n" ); | ||
| 240 | } | ||
| 241 | |||
| 242 | /* | ||
| 243 | * Print item hash table visitor function. | ||
| 244 | */ | ||
| 245 | static void addrcache_print_item_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 246 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 247 | FILE *stream = ( FILE * ) data; | ||
| 248 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 249 | addritem_print_item_person( ( ItemPerson * ) obj, stream ); | ||
| 250 | } | ||
| 251 | else if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 252 | addritem_print_item_group( ( ItemGroup * ) obj, stream ); | ||
| 253 | } | ||
| 254 | else if( ADDRITEM_TYPE(obj) == ITEMTYPE_FOLDER ) { | ||
| 255 | addritem_print_item_folder( ( ItemFolder * ) obj, stream ); | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Dump entire address cache hash table contents. | ||
| 261 | */ | ||
| 262 | void addrcache_print( AddressCache *cache, FILE *stream ) { | ||
| 263 | g_return_if_fail( cache != NULL ); | ||
| 264 | fprintf( stream, "AddressCache:\n" ); | ||
| 265 | fprintf( stream, "next id : %d\n", cache->nextID ); | ||
| 266 | fprintf( stream, "mod time : %ld\n", cache->modifyTime ); | ||
| 267 | fprintf( stream, "modified : %s\n", cache->modified ? "yes" : "no" ); | ||
| 268 | fprintf( stream, "data read: %s\n", cache->dataRead ? "yes" : "no" ); | ||
| 269 | } | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Dump entire address cache hash table contents. | ||
| 273 | */ | ||
| 274 | void addrcache_dump_hash( AddressCache *cache, FILE *stream ) { | ||
| 275 | g_return_if_fail( cache != NULL ); | ||
| 276 | addrcache_print( cache, stream ); | ||
| 277 | g_hash_table_foreach( cache->itemHash, addrcache_print_item_vis, stream ); | ||
| 278 | } | ||
| 279 | |||
| 280 | /* | ||
| 281 | * Allocate ID for person. | ||
| 282 | */ | ||
| 283 | void addrcache_id_person( AddressCache *cache, ItemPerson *person ) { | ||
| 284 | g_return_if_fail( cache != NULL ); | ||
| 285 | g_return_if_fail( person != NULL ); | ||
| 286 | if( ADDRITEM_ID(person) ) return; | ||
| 287 | addrcache_next_id( cache ); | ||
| 288 | ADDRITEM_ID(person) = g_strdup_printf( "%d", cache->nextID ); | ||
| 289 | } | ||
| 290 | |||
| 291 | /* | ||
| 292 | * Allocate ID for group. | ||
| 293 | */ | ||
| 294 | void addrcache_id_group( AddressCache *cache, ItemGroup *group ) { | ||
| 295 | g_return_if_fail( cache != NULL ); | ||
| 296 | g_return_if_fail( group != NULL ); | ||
| 297 | if( ADDRITEM_ID(group) ) return; | ||
| 298 | addrcache_next_id( cache ); | ||
| 299 | ADDRITEM_ID(group) = g_strdup_printf( "%d", cache->nextID ); | ||
| 300 | } | ||
| 301 | |||
| 302 | /* | ||
| 303 | * Allocate ID for folder. | ||
| 304 | */ | ||
| 305 | void addrcache_id_folder( AddressCache *cache, ItemFolder *folder ) { | ||
| 306 | g_return_if_fail( cache != NULL ); | ||
| 307 | g_return_if_fail( folder != NULL ); | ||
| 308 | if( ADDRITEM_ID(folder) ) return; | ||
| 309 | addrcache_next_id( cache ); | ||
| 310 | ADDRITEM_ID(folder) = g_strdup_printf( "%d", cache->nextID ); | ||
| 311 | } | ||
| 312 | |||
| 313 | /* | ||
| 314 | * Allocate ID for email address. | ||
| 315 | */ | ||
| 316 | void addrcache_id_email( AddressCache *cache, ItemEMail *email ) { | ||
| 317 | g_return_if_fail( cache != NULL ); | ||
| 318 | g_return_if_fail( email != NULL ); | ||
| 319 | if( ADDRITEM_ID(email) ) return; | ||
| 320 | addrcache_next_id( cache ); | ||
| 321 | ADDRITEM_ID(email) = g_strdup_printf( "%d", cache->nextID ); | ||
| 322 | } | ||
| 323 | |||
| 324 | /* | ||
| 325 | * Allocate ID for user attribute. | ||
| 326 | */ | ||
| 327 | void addrcache_id_attribute( AddressCache *cache, UserAttribute *attrib ) { | ||
| 328 | g_return_if_fail( cache != NULL ); | ||
| 329 | g_return_if_fail( attrib != NULL ); | ||
| 330 | if( attrib->uid ) return; | ||
| 331 | addrcache_next_id( cache ); | ||
| 332 | attrib->uid = g_strdup_printf( "%d", cache->nextID ); | ||
| 333 | } | ||
| 334 | |||
| 335 | /* | ||
| 336 | * Add person to hash table. | ||
| 337 | * return: TRUE if item added. | ||
| 338 | */ | ||
| 339 | gboolean addrcache_hash_add_person( AddressCache *cache, ItemPerson *person ) { | ||
| 340 | if( g_hash_table_lookup( cache->itemHash, ADDRITEM_ID(person) ) ) { | ||
| 341 | return FALSE; | ||
| 342 | } | ||
| 343 | g_hash_table_insert( cache->itemHash, ADDRITEM_ID(person), person ); | ||
| 344 | return TRUE; | ||
| 345 | } | ||
| 346 | |||
| 347 | /* | ||
| 348 | * Add group to hash table. | ||
| 349 | * return: TRUE if item added. | ||
| 350 | */ | ||
| 351 | gboolean addrcache_hash_add_group( AddressCache *cache, ItemGroup *group ) { | ||
| 352 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 353 | g_return_val_if_fail( group != NULL, FALSE ); | ||
| 354 | |||
| 355 | if( g_hash_table_lookup( cache->itemHash, ADDRITEM_ID(group) ) ) { | ||
| 356 | return FALSE; | ||
| 357 | } | ||
| 358 | g_hash_table_insert( cache->itemHash, ADDRITEM_ID(group), group ); | ||
| 359 | return TRUE; | ||
| 360 | } | ||
| 361 | |||
| 362 | /* | ||
| 363 | * Add folder to hash table. | ||
| 364 | * return: TRUE if item added. | ||
| 365 | */ | ||
| 366 | gboolean addrcache_hash_add_folder( AddressCache *cache, ItemFolder *folder ) { | ||
| 367 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 368 | g_return_val_if_fail( folder != NULL, FALSE ); | ||
| 369 | |||
| 370 | if( g_hash_table_lookup( cache->itemHash, ADDRITEM_ID(folder) ) ) { | ||
| 371 | return FALSE; | ||
| 372 | } | ||
| 373 | g_hash_table_insert( cache->itemHash, ADDRITEM_ID(folder), folder ); | ||
| 374 | return TRUE; | ||
| 375 | } | ||
| 376 | |||
| 377 | /* | ||
| 378 | * Add person to specified folder in cache. | ||
| 379 | */ | ||
| 380 | gboolean addrcache_folder_add_person( AddressCache *cache, ItemFolder *folder, ItemPerson *item ) { | ||
| 381 | gboolean retVal = FALSE; | ||
| 382 | |||
| 383 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 384 | g_return_val_if_fail( folder != NULL, FALSE ); | ||
| 385 | g_return_val_if_fail( item != NULL, FALSE ); | ||
| 386 | |||
| 387 | retVal = addrcache_hash_add_person( cache, item ); | ||
| 388 | if( retVal ) { | ||
| 389 | addritem_folder_add_person( folder, item ); | ||
| 390 | } | ||
| 391 | return retVal; | ||
| 392 | } | ||
| 393 | |||
| 394 | /* | ||
| 395 | * Add folder to specified folder in cache. | ||
| 396 | */ | ||
| 397 | gboolean addrcache_folder_add_folder( AddressCache *cache, ItemFolder *folder, ItemFolder *item ) { | ||
| 398 | gboolean retVal = FALSE; | ||
| 399 | |||
| 400 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 401 | g_return_val_if_fail( folder != NULL, FALSE ); | ||
| 402 | g_return_val_if_fail( item != NULL, FALSE ); | ||
| 403 | |||
| 404 | retVal = addrcache_hash_add_folder( cache, item ); | ||
| 405 | if( retVal ) { | ||
| 406 | addritem_folder_add_folder( folder, item ); | ||
| 407 | } | ||
| 408 | return TRUE; | ||
| 409 | } | ||
| 410 | |||
| 411 | /* | ||
| 412 | * Add folder to specified folder in cache. | ||
| 413 | */ | ||
| 414 | gboolean addrcache_folder_add_group( AddressCache *cache, ItemFolder *folder, ItemGroup *item ) { | ||
| 415 | gboolean retVal = FALSE; | ||
| 416 | |||
| 417 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 418 | g_return_val_if_fail( folder != NULL, FALSE ); | ||
| 419 | g_return_val_if_fail( item != NULL, FALSE ); | ||
| 420 | |||
| 421 | retVal = addrcache_hash_add_group( cache, item ); | ||
| 422 | if( retVal ) { | ||
| 423 | addritem_folder_add_group( folder, item ); | ||
| 424 | } | ||
| 425 | return retVal; | ||
| 426 | } | ||
| 427 | |||
| 428 | /* | ||
| 429 | * Add person to address cache. | ||
| 430 | * return: TRUE if item added. | ||
| 431 | */ | ||
| 432 | gboolean addrcache_add_person( AddressCache *cache, ItemPerson *person ) { | ||
| 433 | gboolean retVal = FALSE; | ||
| 434 | |||
| 435 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 436 | g_return_val_if_fail( person != NULL, FALSE ); | ||
| 437 | |||
| 438 | retVal = addrcache_hash_add_person( cache, person ); | ||
| 439 | if( retVal ) { | ||
| 440 | addritem_folder_add_person( cache->rootFolder, person ); | ||
| 441 | } | ||
| 442 | return retVal; | ||
| 443 | } | ||
| 444 | |||
| 445 | /* | ||
| 446 | * Add EMail address to person. | ||
| 447 | * return: TRUE if item added. | ||
| 448 | */ | ||
| 449 | gboolean addrcache_person_add_email( AddressCache *cache, ItemPerson *person, ItemEMail *email ) { | ||
| 450 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 451 | g_return_val_if_fail( person != NULL, FALSE ); | ||
| 452 | g_return_val_if_fail( email != NULL, FALSE ); | ||
| 453 | |||
| 454 | addritem_person_add_email( person, email ); | ||
| 455 | return TRUE; | ||
| 456 | } | ||
| 457 | |||
| 458 | /* | ||
| 459 | * Add group to address cache. | ||
| 460 | * return: TRUE if item added. | ||
| 461 | */ | ||
| 462 | gboolean addrcache_add_group( AddressCache *cache, ItemGroup *group ) { | ||
| 463 | gboolean retVal = FALSE; | ||
| 464 | |||
| 465 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 466 | g_return_val_if_fail( group != NULL, FALSE ); | ||
| 467 | |||
| 468 | retVal = addrcache_hash_add_group( cache, group ); | ||
| 469 | if( retVal ) { | ||
| 470 | addritem_folder_add_group( cache->rootFolder, group ); | ||
| 471 | } | ||
| 472 | return retVal; | ||
| 473 | } | ||
| 474 | |||
| 475 | /* | ||
| 476 | * Add EMail address to person. | ||
| 477 | * return: TRUE if item added. | ||
| 478 | */ | ||
| 479 | gboolean addrcache_group_add_email( AddressCache *cache, ItemGroup *group, ItemEMail *email ) { | ||
| 480 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 481 | g_return_val_if_fail( group != NULL, FALSE ); | ||
| 482 | g_return_val_if_fail( email != NULL, FALSE ); | ||
| 483 | |||
| 484 | addritem_group_add_email( group, email ); | ||
| 485 | return TRUE; | ||
| 486 | } | ||
| 487 | |||
| 488 | /* | ||
| 489 | * Add folder to address cache. | ||
| 490 | * return: TRUE if item added. | ||
| 491 | */ | ||
| 492 | gboolean addrcache_add_folder( AddressCache *cache, ItemFolder *folder ) { | ||
| 493 | gboolean retVal = FALSE; | ||
| 494 | |||
| 495 | g_return_val_if_fail( cache != NULL, FALSE ); | ||
| 496 | g_return_val_if_fail( folder != NULL, FALSE ); | ||
| 497 | |||
| 498 | retVal = addrcache_hash_add_folder( cache, folder ); | ||
| 499 | if( retVal ) { | ||
| 500 | addritem_folder_add_folder( cache->rootFolder, folder ); | ||
| 501 | } | ||
| 502 | return retVal; | ||
| 503 | } | ||
| 504 | |||
| 505 | /* | ||
| 506 | * Return pointer to object (either person or group) for specified ID. | ||
| 507 | * param: uid Object ID. | ||
| 508 | * return: Object, or NULL if not found. | ||
| 509 | */ | ||
| 510 | AddrItemObject *addrcache_get_object( AddressCache *cache, const gchar *uid ) { | ||
| 511 | AddrItemObject *obj = NULL; | ||
| 512 | gchar *uidH; | ||
| 513 | |||
| 514 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 515 | |||
| 516 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 517 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 518 | if( obj ) { | ||
| 519 | /* Check for matching UID */ | ||
| 520 | uidH = ADDRITEM_ID(obj); | ||
| 521 | if( uidH ) { | ||
| 522 | if( strcmp( uidH, uid ) == 0 ) return obj; | ||
| 523 | } | ||
| 524 | } | ||
| 525 | return NULL; | ||
| 526 | } | ||
| 527 | |||
| 528 | /* | ||
| 529 | * Return pointer for specified object ID. | ||
| 530 | * param: uid Object ID. | ||
| 531 | * return: Person object, or NULL if not found. | ||
| 532 | */ | ||
| 533 | ItemPerson *addrcache_get_person( AddressCache *cache, const gchar *uid ) { | ||
| 534 | ItemPerson *person = NULL; | ||
| 535 | AddrItemObject *obj = addrcache_get_object( cache, uid ); | ||
| 536 | |||
| 537 | if( obj ) { | ||
| 538 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 539 | person = ( ItemPerson * ) obj; | ||
| 540 | } | ||
| 541 | } | ||
| 542 | return person; | ||
| 543 | } | ||
| 544 | |||
| 545 | /* | ||
| 546 | * Return pointer for specified object ID. | ||
| 547 | * param: uid group ID. | ||
| 548 | * return: Group object, or NULL if not found. | ||
| 549 | */ | ||
| 550 | ItemGroup *addrcache_get_group( AddressCache *cache, const gchar *uid ) { | ||
| 551 | ItemGroup *group = NULL; | ||
| 552 | AddrItemObject *obj = addrcache_get_object( cache, uid ); | ||
| 553 | |||
| 554 | if( obj ) { | ||
| 555 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 556 | group = ( ItemGroup * ) obj; | ||
| 557 | } | ||
| 558 | } | ||
| 559 | return group; | ||
| 560 | } | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Find email address in address cache. | ||
| 564 | * param: uid Object ID for person. | ||
| 565 | * eid EMail ID. | ||
| 566 | * return: email object for specified object ID and email ID, or NULL if not found. | ||
| 567 | */ | ||
| 568 | ItemEMail *addrcache_get_email( AddressCache *cache, const gchar *uid, const gchar *eid ) { | ||
| 569 | AddrItemObject *objP; | ||
| 570 | |||
| 571 | if( eid == NULL || *eid == '\0' ) return NULL; | ||
| 572 | |||
| 573 | objP = addrcache_get_object( cache, uid ); | ||
| 574 | if( objP ) { | ||
| 575 | if( ADDRITEM_TYPE(objP) == ITEMTYPE_PERSON ) { | ||
| 576 | /* Sequential search through email addresses */ | ||
| 577 | ItemPerson *person = ( ItemPerson * ) objP; | ||
| 578 | GList *nodeMail = person->listEMail; | ||
| 579 | while( nodeMail ) { | ||
| 580 | AddrItemObject *objE = nodeMail->data; | ||
| 581 | gchar *ide = ADDRITEM_ID(objE); | ||
| 582 | if( ide ) { | ||
| 583 | if( strcmp( ide, eid ) == 0 ) { | ||
| 584 | return ( ItemEMail * ) objE; | ||
| 585 | } | ||
| 586 | } | ||
| 587 | nodeMail = g_list_next( nodeMail ); | ||
| 588 | } | ||
| 589 | } | ||
| 590 | } | ||
| 591 | return NULL; | ||
| 592 | } | ||
| 593 | |||
| 594 | /* | ||
| 595 | * Remove attribute from person. | ||
| 596 | * param: uid Object ID for person. | ||
| 597 | * aid Attribute ID. | ||
| 598 | * return: UserAttribute object, or NULL if not found. Note that object should still be freed. | ||
| 599 | */ | ||
| 600 | UserAttribute *addrcache_person_remove_attrib_id( AddressCache *cache, const gchar *uid, const gchar *aid ) { | ||
| 601 | UserAttribute *attrib = NULL; | ||
| 602 | ItemPerson *person; | ||
| 603 | |||
| 604 | if( aid == NULL || *aid == '\0' ) return NULL; | ||
| 605 | |||
| 606 | person = addrcache_get_person( cache, uid ); | ||
| 607 | if( person ) { | ||
| 608 | attrib = addritem_person_remove_attrib_id( person, aid ); | ||
| 609 | } | ||
| 610 | return attrib; | ||
| 611 | } | ||
| 612 | |||
| 613 | /* | ||
| 614 | * Remove attribute from person. | ||
| 615 | * param: person Person. | ||
| 616 | * attrib Attribute to remove. | ||
| 617 | * return: UserAttribute object. Note that object should still be freed. | ||
| 618 | */ | ||
| 619 | UserAttribute *addrcache_person_remove_attribute( AddressCache *cache, ItemPerson *person, UserAttribute *attrib ) { | ||
| 620 | UserAttribute *found = NULL; | ||
| 621 | |||
| 622 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 623 | |||
| 624 | if( person && attrib ) { | ||
| 625 | found = addritem_person_remove_attribute( person, attrib ); | ||
| 626 | } | ||
| 627 | return found; | ||
| 628 | } | ||
| 629 | |||
| 630 | /* | ||
| 631 | * Remove group from address cache for specified ID. | ||
| 632 | * param: uid Object ID. | ||
| 633 | * return: Group, or NULL if not found. Note that object should still be freed. | ||
| 634 | */ | ||
| 635 | ItemGroup *addrcache_remove_group_id( AddressCache *cache, const gchar *uid ) { | ||
| 636 | AddrItemObject *obj = NULL; | ||
| 637 | |||
| 638 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 639 | |||
| 640 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 641 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 642 | if( obj ) { | ||
| 643 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 644 | ItemGroup *group = ( ItemGroup * ) obj; | ||
| 645 | ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(group); | ||
| 646 | if( ! parent ) parent = cache->rootFolder; | ||
| 647 | /* Remove group from parent's list and hash table */ | ||
| 648 | parent->listGroup = g_list_remove( parent->listGroup, group ); | ||
| 649 | g_hash_table_remove( cache->itemHash, uid ); | ||
| 650 | return ( ItemGroup * ) obj; | ||
| 651 | } | ||
| 652 | } | ||
| 653 | return NULL; | ||
| 654 | } | ||
| 655 | |||
| 656 | /* | ||
| 657 | * Remove group from address cache. | ||
| 658 | * param: group Group to remove. | ||
| 659 | * return: Group, or NULL if not found. Note that object should still be freed. | ||
| 660 | */ | ||
| 661 | ItemGroup *addrcache_remove_group( AddressCache *cache, ItemGroup *group ) { | ||
| 662 | AddrItemObject *obj = NULL; | ||
| 663 | |||
| 664 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 665 | |||
| 666 | if( group ) { | ||
| 667 | gchar *uid = ADDRITEM_ID(group); | ||
| 668 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 669 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 670 | if( obj ) { | ||
| 671 | ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(group); | ||
| 672 | if( ! parent ) parent = cache->rootFolder; | ||
| 673 | |||
| 674 | /* Remove group from parent's list and hash table */ | ||
| 675 | parent->listGroup = g_list_remove( parent->listGroup, obj ); | ||
| 676 | g_hash_table_remove( cache->itemHash, uid ); | ||
| 677 | return group; | ||
| 678 | } | ||
| 679 | } | ||
| 680 | return NULL; | ||
| 681 | } | ||
| 682 | |||
| 683 | /* | ||
| 684 | * Remove person's email addresses from all groups. | ||
| 685 | */ | ||
| 686 | static void addrcache_allgrp_rem_person_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 687 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 688 | ItemPerson *person = ( ItemPerson * ) data; | ||
| 689 | |||
| 690 | if ( !person ) return; | ||
| 691 | |||
| 692 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 693 | ItemGroup *group = ( ItemGroup * ) obj; | ||
| 694 | if( group ) { | ||
| 695 | /* Remove each email address that belongs to the person from the list */ | ||
| 696 | GList *node = person->listEMail; | ||
| 697 | debug_print("removing email in person %p (%s) from group %p (%s)\n", person, ADDRITEM_NAME(person), group, ADDRITEM_NAME(group)); | ||
| 698 | while( node ) { | ||
| 699 | group->listEMail = g_list_remove( group->listEMail, node->data ); | ||
| 700 | node = g_list_next( node ); | ||
| 701 | } | ||
| 702 | } | ||
| 703 | } | ||
| 704 | } | ||
| 705 | |||
| 706 | /* | ||
| 707 | * Remove email from group item hash table visitor function. | ||
| 708 | */ | ||
| 709 | static void addrcache_allgrp_rem_email_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 710 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 711 | ItemEMail *email = ( ItemEMail * ) data; | ||
| 712 | |||
| 713 | if( !email ) return; | ||
| 714 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 715 | ItemGroup *group = ( ItemGroup * ) value; | ||
| 716 | if( group ) { | ||
| 717 | debug_print("removing email %p (%s) from group %p (%s)\n", email, email->address, group, ADDRITEM_NAME(group)); | ||
| 718 | /* Remove each email address that belongs to the person from the list */ | ||
| 719 | group->listEMail = g_list_remove( group->listEMail, email ); | ||
| 720 | } | ||
| 721 | } | ||
| 722 | } | ||
| 723 | |||
| 724 | /* | ||
| 725 | * Remove person from address cache for specified ID. Note that person still retains | ||
| 726 | * their EMail addresses. Also, links to these email addresses will be severed from | ||
| 727 | * the group. | ||
| 728 | * param: uid Object ID. | ||
| 729 | * return: Person, or NULL if not found. Note that object should still be freed. | ||
| 730 | */ | ||
| 731 | ItemPerson *addrcache_remove_person_id( AddressCache *cache, const gchar *uid ) { | ||
| 732 | AddrItemObject *obj = NULL; | ||
| 733 | |||
| 734 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 735 | |||
| 736 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 737 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 738 | if( obj ) { | ||
| 739 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 740 | /* Remove person's email addresses from all groups where */ | ||
| 741 | /* referenced and from hash table. */ | ||
| 742 | ItemPerson *person = ( ItemPerson * ) obj; | ||
| 743 | ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(person); | ||
| 744 | if( ! parent ) parent = cache->rootFolder; | ||
| 745 | /* Remove emails from groups, remove from parent's list */ | ||
| 746 | /* and hash table */ | ||
| 747 | g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_person_vis, person ); | ||
| 748 | parent->listPerson = g_list_remove( parent->listPerson, person ); | ||
| 749 | g_hash_table_remove( cache->itemHash, uid ); | ||
| 750 | return person; | ||
| 751 | } | ||
| 752 | } | ||
| 753 | return NULL; | ||
| 754 | } | ||
| 755 | |||
| 756 | /* | ||
| 757 | * Remove specified person from address cache. | ||
| 758 | * param: person Person to remove. | ||
| 759 | * return: Person, or NULL if not found. Note that object should still be freed. | ||
| 760 | */ | ||
| 761 | ItemPerson *addrcache_remove_person( AddressCache *cache, ItemPerson *person ) { | ||
| 762 | AddrItemObject *obj = NULL; | ||
| 763 | |||
| 764 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 765 | |||
| 766 | if( person ) { | ||
| 767 | gchar *uid = ADDRITEM_ID(person); | ||
| 768 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 769 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 770 | if( obj ) { | ||
| 771 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 772 | /* Remove person's email addresses from all groups where */ | ||
| 773 | /* referenced and from hash table. */ | ||
| 774 | ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(person); | ||
| 775 | if( ! parent ) parent = cache->rootFolder; | ||
| 776 | g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_person_vis, person ); | ||
| 777 | parent->listPerson = g_list_remove( parent->listPerson, person ); | ||
| 778 | g_hash_table_remove( cache->itemHash, uid ); | ||
| 779 | return person; | ||
| 780 | } | ||
| 781 | } | ||
| 782 | } | ||
| 783 | return NULL; | ||
| 784 | } | ||
| 785 | |||
| 786 | /* | ||
| 787 | * Remove email address in address cache for specified ID. | ||
| 788 | * param: uid Object ID for person. | ||
| 789 | * eid EMail ID. | ||
| 790 | * return: EMail object, or NULL if not found. Note that object should still be freed. | ||
| 791 | */ | ||
| 792 | ItemEMail *addrcache_person_remove_email_id( AddressCache *cache, const gchar *uid, const gchar *eid ) { | ||
| 793 | ItemEMail *email = NULL; | ||
| 794 | ItemPerson *person; | ||
| 795 | |||
| 796 | if( eid == NULL || *eid == '\0' ) return NULL; | ||
| 797 | |||
| 798 | person = addrcache_get_person( cache, uid ); | ||
| 799 | if( person ) { | ||
| 800 | email = addritem_person_remove_email_id( person, eid ); | ||
| 801 | if( email ) { | ||
| 802 | /* Remove email from all groups. */ | ||
| 803 | g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_email_vis, email ); | ||
| 804 | |||
| 805 | /* Remove email from person's address list */ | ||
| 806 | if( person->listEMail ) { | ||
| 807 | person->listEMail = g_list_remove( person->listEMail, email ); | ||
| 808 | } | ||
| 809 | /* Unlink reference to person. */ | ||
| 810 | ADDRITEM_PARENT(email) = NULL; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | return email; | ||
| 814 | } | ||
| 815 | |||
| 816 | /* | ||
| 817 | * Remove email address in address cache for specified person. | ||
| 818 | * param: person Person. | ||
| 819 | * email EMail to remove. | ||
| 820 | * return: EMail object, or NULL if not found. Note that object should still be freed. | ||
| 821 | */ | ||
| 822 | ItemEMail *addrcache_person_remove_email( AddressCache *cache, ItemPerson *person, ItemEMail *email ) { | ||
| 823 | ItemEMail *found = NULL; | ||
| 824 | |||
| 825 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 826 | |||
| 827 | if( person && email ) { | ||
| 828 | found = addritem_person_remove_email( person, email ); | ||
| 829 | if( found ) { | ||
| 830 | /* Remove email from all groups. */ | ||
| 831 | g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_email_vis, email ); | ||
| 832 | |||
| 833 | /* Remove email from person's address list */ | ||
| 834 | if( person->listEMail ) { | ||
| 835 | person->listEMail = g_list_remove( person->listEMail, email ); | ||
| 836 | } | ||
| 837 | /* Unlink reference to person. */ | ||
| 838 | ADDRITEM_PARENT(email) = NULL; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | return found; | ||
| 842 | } | ||
| 843 | |||
| 844 | /* | ||
| 845 | * Return link list of address items for root level folder. Note that the list contains | ||
| 846 | * references to items and should be g_free() when done. Do *NOT* attempt to use the | ||
| 847 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 848 | * Return: List of items, or NULL if none. | ||
| 849 | */ | ||
| 850 | GList *addrcache_folder_get_address_list( AddressCache *cache, ItemFolder *folder ) { | ||
| 851 | GList *list = NULL; | ||
| 852 | GList *node = NULL; | ||
| 853 | ItemFolder *f = folder; | ||
| 854 | |||
| 855 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 856 | |||
| 857 | if( ! f ) f = cache->rootFolder; | ||
| 858 | node = f->listPerson; | ||
| 859 | while( node ) { | ||
| 860 | list = g_list_append( list, node->data ); | ||
| 861 | node = g_list_next( node ); | ||
| 862 | } | ||
| 863 | node = f->listGroup; | ||
| 864 | while( node ) { | ||
| 865 | list = g_list_append( list, node->data ); | ||
| 866 | node = g_list_next( node ); | ||
| 867 | } | ||
| 868 | return list; | ||
| 869 | } | ||
| 870 | |||
| 871 | /* | ||
| 872 | * Return link list of persons for specified folder. Note that the list contains | ||
| 873 | * references to items and should be g_free() when done. Do *NOT* attempt to use the | ||
| 874 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 875 | * Return: List of items, or NULL if none. | ||
| 876 | */ | ||
| 877 | GList *addrcache_folder_get_person_list( AddressCache *cache, ItemFolder *folder ) { | ||
| 878 | ItemFolder *f = folder; | ||
| 879 | |||
| 880 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 881 | |||
| 882 | if( ! f ) f = cache->rootFolder; | ||
| 883 | return addritem_folder_get_person_list( f ); | ||
| 884 | } | ||
| 885 | |||
| 886 | /* | ||
| 887 | * Return link list of group items for specified folder. Note that the list contains | ||
| 888 | * references to items and should be g_free() when done. Do *NOT* attempt to use the | ||
| 889 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 890 | * Return: List of items, or NULL if none. | ||
| 891 | */ | ||
| 892 | GList *addrcache_folder_get_group_list( AddressCache *cache, ItemFolder *folder ) { | ||
| 893 | ItemFolder *f = folder; | ||
| 894 | |||
| 895 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 896 | |||
| 897 | if( ! f ) f = cache->rootFolder; | ||
| 898 | return addritem_folder_get_group_list( f ); | ||
| 899 | } | ||
| 900 | |||
| 901 | /* | ||
| 902 | * Return link list of folder items for specified folder. Note that the list contains | ||
| 903 | * references to items and should be g_free() when done. Do *NOT* attempt to used the | ||
| 904 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 905 | * Return: List of items, or NULL if none. | ||
| 906 | */ | ||
| 907 | GList *addrcache_folder_get_folder_list( AddressCache *cache, ItemFolder *folder ) { | ||
| 908 | GList *node = NULL; | ||
| 909 | GList *list = NULL; | ||
| 910 | ItemFolder *f = folder; | ||
| 911 | |||
| 912 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 913 | |||
| 914 | if( ! f ) f = cache->rootFolder; | ||
| 915 | node = f->listFolder; | ||
| 916 | while( node ) { | ||
| 917 | list = g_list_append( list, node->data ); | ||
| 918 | node = g_list_next( node ); | ||
| 919 | } | ||
| 920 | return list; | ||
| 921 | } | ||
| 922 | |||
| 923 | /* | ||
| 924 | * Return link list of address items for root level folder. Note that the list contains | ||
| 925 | * references to items and should be g_free() when done. Do *NOT* attempt to used the | ||
| 926 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 927 | * Return: List of items, or NULL if none. | ||
| 928 | */ | ||
| 929 | GList *addrcache_get_address_list( AddressCache *cache ) { | ||
| 930 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 931 | return addrcache_folder_get_address_list( cache, cache->rootFolder ); | ||
| 932 | } | ||
| 933 | |||
| 934 | /* | ||
| 935 | * Return link list of persons for root level folder. Note that the list contains | ||
| 936 | * references to items and should be g_free() when done. Do *NOT* attempt to used the | ||
| 937 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 938 | * Return: List of items, or NULL if none. | ||
| 939 | */ | ||
| 940 | GList *addrcache_get_person_list( AddressCache *cache ) { | ||
| 941 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 942 | return addritem_folder_get_person_list( cache->rootFolder ); | ||
| 943 | } | ||
| 944 | |||
| 945 | /* | ||
| 946 | * Return link list of group items in root level folder. Note that the list contains | ||
| 947 | * references to items and should be g_free() when done. Do *NOT* attempt to used the | ||
| 948 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 949 | * Return: List of items, or NULL if none. | ||
| 950 | */ | ||
| 951 | GList *addrcache_get_group_list( AddressCache *cache ) { | ||
| 952 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 953 | return cache->rootFolder->listGroup; | ||
| 954 | } | ||
| 955 | |||
| 956 | /* | ||
| 957 | * Return link list of folder items in root level folder. Note that the list contains | ||
| 958 | * references to items and should be g_free() when done. Do *NOT* attempt to used the | ||
| 959 | * addrcache_free_xxx() functions... this will destroy the address cache data! | ||
| 960 | * Return: List of items, or NULL if none. | ||
| 961 | */ | ||
| 962 | GList *addrcache_get_folder_list( AddressCache *cache ) { | ||
| 963 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 964 | return cache->rootFolder->listFolder; | ||
| 965 | } | ||
| 966 | |||
| 967 | /* | ||
| 968 | * Group visitor function. | ||
| 969 | */ | ||
| 970 | static void addrcache_get_grp_person_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 971 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 972 | |||
| 973 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 974 | AddressCache *cache = data; | ||
| 975 | ItemGroup *group = ( ItemGroup * ) obj; | ||
| 976 | ItemPerson *person = ( ItemPerson * ) cache->tempList->data; | ||
| 977 | GList *node = group->listEMail; | ||
| 978 | while( node ) { | ||
| 979 | ItemEMail *email = ( ItemEMail * ) node->data; | ||
| 980 | if( ADDRITEM_PARENT(email) == ADDRITEM_OBJECT(person) ) { | ||
| 981 | if( ! g_list_find( cache->tempList, group ) ) { | ||
| 982 | cache->tempList = g_list_append( cache->tempList, group ); | ||
| 983 | } | ||
| 984 | } | ||
| 985 | node = g_list_next( node ); | ||
| 986 | } | ||
| 987 | } | ||
| 988 | } | ||
| 989 | |||
| 990 | /* | ||
| 991 | * Return link list of groups which contain a reference to specified person's email | ||
| 992 | * address. | ||
| 993 | */ | ||
| 994 | GList *addrcache_get_group_for_person( AddressCache *cache, ItemPerson *person ) { | ||
| 995 | GList *list = NULL; | ||
| 996 | |||
| 997 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 998 | |||
| 999 | cache->tempList = NULL; | ||
| 1000 | cache->tempList = g_list_append( cache->tempList, person ); | ||
| 1001 | g_hash_table_foreach( cache->itemHash, addrcache_get_grp_person_vis, cache ); | ||
| 1002 | cache->tempList = g_list_remove( cache->tempList, person ); | ||
| 1003 | list = cache->tempList; | ||
| 1004 | cache->tempList = NULL; | ||
| 1005 | return list; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | /* | ||
| 1009 | * Find root folder for specified folder. | ||
| 1010 | * Enter: folder Folder to search. | ||
| 1011 | * Return: root folder, or NULL if not found. | ||
| 1012 | */ | ||
| 1013 | ItemFolder *addrcache_find_root_folder( ItemFolder *folder ) { | ||
| 1014 | ItemFolder *item = folder; | ||
| 1015 | gint count = 0; | ||
| 1016 | |||
| 1017 | while( item ) { | ||
| 1018 | if( item->isRoot ) break; | ||
| 1019 | if( ++count > ADDRCACHE_MAX_SEARCH_COUNT ) { | ||
| 1020 | item = NULL; | ||
| 1021 | break; | ||
| 1022 | } | ||
| 1023 | item = ( ItemFolder * ) ADDRITEM_PARENT(folder); | ||
| 1024 | } | ||
| 1025 | return item; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | /* | ||
| 1029 | * Get all person visitor function. | ||
| 1030 | */ | ||
| 1031 | static void addrcache_get_all_persons_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 1032 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 1033 | |||
| 1034 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { | ||
| 1035 | AddressCache *cache = data; | ||
| 1036 | cache->tempList = g_list_append( cache->tempList, obj ); | ||
| 1037 | } | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | /* | ||
| 1041 | * Return link list of all persons in address cache. Note that the list contains | ||
| 1042 | * references to items. Do *NOT* attempt to use the addrcache_free_xxx() functions... | ||
| 1043 | * this will destroy the address cache data! | ||
| 1044 | * Return: List of items, or NULL if none. | ||
| 1045 | */ | ||
| 1046 | GList *addrcache_get_all_persons( AddressCache *cache ) { | ||
| 1047 | GList *list = NULL; | ||
| 1048 | |||
| 1049 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 1050 | |||
| 1051 | cache->tempList = NULL; | ||
| 1052 | g_hash_table_foreach( cache->itemHash, addrcache_get_all_persons_vis, cache ); | ||
| 1053 | list = cache->tempList; | ||
| 1054 | cache->tempList = NULL; | ||
| 1055 | return list; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | /* | ||
| 1059 | * Get all groups visitor function. | ||
| 1060 | */ | ||
| 1061 | static void addrcache_get_all_groups_vis( gpointer key, gpointer value, gpointer data ) { | ||
| 1062 | AddrItemObject *obj = ( AddrItemObject * ) value; | ||
| 1063 | |||
| 1064 | if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { | ||
| 1065 | AddressCache *cache = data; | ||
| 1066 | cache->tempList = g_list_append( cache->tempList, obj ); | ||
| 1067 | } | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | /* | ||
| 1071 | * Return link list of all groups in address cache. Note that the list contains | ||
| 1072 | * references to items. Do *NOT* attempt to use the addrcache_free_xxx() functions... | ||
| 1073 | * this will destroy the address cache data! | ||
| 1074 | * Return: List of items, or NULL if none. | ||
| 1075 | */ | ||
| 1076 | GList *addrcache_get_all_groups( AddressCache *cache ) { | ||
| 1077 | GList *list = NULL; | ||
| 1078 | |||
| 1079 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 1080 | |||
| 1081 | cache->tempList = NULL; | ||
| 1082 | g_hash_table_foreach( cache->itemHash, addrcache_get_all_groups_vis, cache ); | ||
| 1083 | list = cache->tempList; | ||
| 1084 | cache->tempList = NULL; | ||
| 1085 | return list; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | /* | ||
| 1089 | * Remove folder from cache. Children are re-parented to parent folder. | ||
| 1090 | * param: folder Folder to remove. | ||
| 1091 | * return: Folder, or NULL if not found. Note that object should still be freed. | ||
| 1092 | */ | ||
| 1093 | ItemFolder *addrcache_remove_folder( AddressCache *cache, ItemFolder *folder ) { | ||
| 1094 | AddrItemObject *obj = NULL; | ||
| 1095 | |||
| 1096 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 1097 | |||
| 1098 | if( folder ) { | ||
| 1099 | gchar *uid = ADDRITEM_ID(folder); | ||
| 1100 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 1101 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 1102 | if( obj ) { | ||
| 1103 | ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(folder); | ||
| 1104 | GList *node; | ||
| 1105 | AddrItemObject *aio; | ||
| 1106 | if( ! parent ) parent = cache->rootFolder; | ||
| 1107 | |||
| 1108 | /* Re-parent children in folder */ | ||
| 1109 | node = folder->listFolder; | ||
| 1110 | while( node ) { | ||
| 1111 | aio = ( AddrItemObject * ) node->data; | ||
| 1112 | parent->listFolder = g_list_append( parent->listFolder, aio ); | ||
| 1113 | aio->parent = ADDRITEM_OBJECT(parent); | ||
| 1114 | node = g_list_next( node ); | ||
| 1115 | } | ||
| 1116 | node = folder->listPerson; | ||
| 1117 | while( node ) { | ||
| 1118 | aio = ( AddrItemObject * ) node->data; | ||
| 1119 | parent->listPerson = g_list_append( parent->listPerson, aio ); | ||
| 1120 | aio->parent = ADDRITEM_OBJECT(parent); | ||
| 1121 | node = g_list_next( node ); | ||
| 1122 | } | ||
| 1123 | node = folder->listGroup; | ||
| 1124 | while( node ) { | ||
| 1125 | aio = ( AddrItemObject * ) node->data; | ||
| 1126 | parent->listGroup = g_list_append( parent->listGroup, aio ); | ||
| 1127 | aio->parent = ADDRITEM_OBJECT(parent); | ||
| 1128 | node = g_list_next( node ); | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | /* Remove folder from parent's list and hash table */ | ||
| 1132 | parent->listFolder = g_list_remove( parent->listFolder, folder ); | ||
| 1133 | ADDRITEM_PARENT(folder) = NULL; | ||
| 1134 | g_hash_table_remove( cache->itemHash, uid ); | ||
| 1135 | return folder; | ||
| 1136 | } | ||
| 1137 | } | ||
| 1138 | return NULL; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | /* | ||
| 1142 | * Remove folder from cache. Children are deleted. | ||
| 1143 | * param: folder Folder to remove. | ||
| 1144 | * return: Folder, or NULL if not found. Note that object should still be freed. | ||
| 1145 | */ | ||
| 1146 | ItemFolder *addrcache_remove_folder_delete( AddressCache *cache, ItemFolder *folder ) { | ||
| 1147 | AddrItemObject *obj = NULL; | ||
| 1148 | |||
| 1149 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 1150 | |||
| 1151 | if( folder ) { | ||
| 1152 | gchar *uid = ADDRITEM_ID(folder); | ||
| 1153 | if( uid == NULL || *uid == '\0' ) return NULL; | ||
| 1154 | obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); | ||
| 1155 | if( obj ) { | ||
| 1156 | ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(folder); | ||
| 1157 | if( ! parent ) parent = cache->rootFolder; | ||
| 1158 | |||
| 1159 | /* Remove groups */ | ||
| 1160 | while( folder->listGroup ) { | ||
| 1161 | ItemGroup *item = ( ItemGroup * ) folder->listGroup->data; | ||
| 1162 | item = addrcache_remove_group( cache, item ); | ||
| 1163 | if( item ) { | ||
| 1164 | addritem_free_item_group( item ); | ||
| 1165 | item = NULL; | ||
| 1166 | } | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | while( folder->listPerson ) { | ||
| 1170 | ItemPerson *item = ( ItemPerson * ) folder->listPerson->data; | ||
| 1171 | item = addrcache_remove_person( cache, item ); | ||
| 1172 | if( item ) { | ||
| 1173 | addritem_free_item_person( item ); | ||
| 1174 | item = NULL; | ||
| 1175 | } | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | /* Recursive deletion of folder */ | ||
| 1179 | while( folder->listFolder ) { | ||
| 1180 | ItemFolder *item = ( ItemFolder * ) folder->listFolder->data; | ||
| 1181 | item = addrcache_remove_folder_delete( cache, item ); | ||
| 1182 | if( item ) { | ||
| 1183 | addritem_free_item_folder( item ); | ||
| 1184 | item = NULL; | ||
| 1185 | } | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | /* Remove folder from parent's list and hash table */ | ||
| 1189 | parent->listFolder = g_list_remove( parent->listFolder, folder ); | ||
| 1190 | ADDRITEM_PARENT(folder) = NULL; | ||
| 1191 | g_hash_table_remove( cache->itemHash, uid ); | ||
| 1192 | return folder; | ||
| 1193 | } | ||
| 1194 | } | ||
| 1195 | return NULL; | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | /* | ||
| 1199 | * Add person and address data to cache. | ||
| 1200 | * Enter: cache Cache. | ||
| 1201 | * folder Folder where to add person, or NULL for root folder. | ||
| 1202 | * name Common name. | ||
| 1203 | * address EMail address. | ||
| 1204 | * remarks Remarks. | ||
| 1205 | * Return: Person added. Do not *NOT* to use the addrbook_free_xxx() functions... | ||
| 1206 | * this will destroy the address book data. | ||
| 1207 | */ | ||
| 1208 | ItemPerson *addrcache_add_contact( AddressCache *cache, ItemFolder *folder, const gchar *name, | ||
| 1209 | const gchar *address, const gchar *remarks ) | ||
| 1210 | { | ||
| 1211 | ItemPerson *person = NULL; | ||
| 1212 | ItemEMail *email = NULL; | ||
| 1213 | ItemFolder *f = folder; | ||
| 1214 | |||
| 1215 | g_return_val_if_fail( cache != NULL, NULL ); | ||
| 1216 | |||
| 1217 | if( ! f ) f = cache->rootFolder; | ||
| 1218 | |||
| 1219 | /* Create person object */ | ||
| 1220 | person = addritem_create_item_person(); | ||
| 1221 | addritem_person_set_common_name( person, name ); | ||
| 1222 | addrcache_id_person( cache, person ); | ||
| 1223 | addrcache_folder_add_person( cache, f, person ); | ||
| 1224 | |||
| 1225 | /* Create email object */ | ||
| 1226 | email = addritem_create_item_email(); | ||
| 1227 | addritem_email_set_address( email, address ); | ||
| 1228 | addritem_email_set_remarks( email, remarks ); | ||
| 1229 | addrcache_id_email( cache, email ); | ||
| 1230 | addritem_person_add_email( person, email ); | ||
| 1231 | |||
| 1232 | return person; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | /* | ||
| 1236 | * End of Source. | ||
| 1237 | */ | ||
