Statistics
| Revision:

root / src / addrcache.c @ 365

History | View | Annotate | Download (34.9 kB)

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