Statistics
| Revision:

root / src / addrcache.c @ 2408

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