2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2002-2003 Match Grun
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Functions to maintain address completion index.
29 #include "addrcindex.h"
32 static gint _n_created = 0;
33 static gint _n_freed = 0;
42 static gchar *addrcindex_function( gpointer data ) {
43 return ( ( AddrIndexEntry * ) data )->name;
47 * Create new completion index.
49 AddrCacheIndex *addrcindex_create( void ) {
50 AddrCacheIndex *index;
54 printf( "addrcindex_create/1/%d\n", _n_created );
56 index = g_new0( AddrCacheIndex, 1 );
57 index->completion = g_completion_new( addrcindex_function );
58 index->addressList = NULL;
59 index->invalid = TRUE;
65 * Clear the completion index.
67 void addrcindex_clear( AddrCacheIndex *index ) {
69 /* Clear completion index */
70 g_completion_clear_items( index->completion );
72 /* Clear address list */
73 g_list_free( index->addressList );
74 index->addressList = NULL;
75 index->invalid = TRUE;
80 * Free completion index.
82 void addrcindex_free( AddrCacheIndex *index ) {
86 printf( "addrcindex_free/2/%d\n", _n_freed );
89 addrcindex_clear( index );
92 g_completion_free( index->completion );
93 index->completion = NULL;
94 index->invalid = FALSE;
101 * Mark index as invalid. Will need to be rebuilt.
102 * \param index Address completion index.
104 void addrcindex_invalidate( AddrCacheIndex *index ) {
105 g_return_if_fail( index != NULL );
106 index->invalid = TRUE;
110 * Mark index as valid.
111 * \param index Address completion index.
113 void addrcindex_validate( AddrCacheIndex *index ) {
114 g_return_if_fail( index != NULL );
115 index->invalid = FALSE;
119 * Add completion entry to index.
120 * Enter: index Index.
122 * email EMail entry to add.
124 void addrcindex_add_entry(
125 AddrCacheIndex *index, gchar *name, ItemEMail *email )
127 AddrIndexEntry *entry;
129 entry = g_new0( AddrIndexEntry, 1 );
130 entry->name = g_strdup( name );
131 entry->address = email;
132 g_strdown( entry->name );
133 index->addressList = g_list_append( index->addressList, entry );
137 * Add an email entry into index. The index will also include all name fields
140 * Add address into index.
141 * Enter: index Index.
142 * email E-Mail to add.
144 void addrcindex_add_email( AddrCacheIndex *index, ItemEMail *email ) {
151 g_return_if_fail( index != NULL );
152 g_return_if_fail( email != NULL );
156 name = ADDRITEM_NAME( email );
158 if( strlen( name ) > 0 ) {
159 uniqName = g_slist_append( uniqName, name );
162 name = email->address;
163 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
164 uniqName = g_slist_append( uniqName, name );
167 if( strlen( name ) > 0 ) flag = TRUE;
170 /* Bail if no email address */
172 g_slist_free( uniqName );
176 person = ( ItemPerson * ) ADDRITEM_PARENT( email );
177 if( person != NULL ) {
178 name = ADDRITEM_NAME( person );
179 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
180 uniqName = g_slist_append( uniqName, name );
183 name = person->nickName;
184 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
185 uniqName = g_slist_append( uniqName, name );
188 name = person->firstName;
189 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
190 uniqName = g_slist_append( uniqName, name );
193 name = person->lastName;
194 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
195 uniqName = g_slist_append( uniqName, name );
199 /* Create a completion entry for each unique name */
202 addrcindex_add_entry( index, node->data, email );
203 node = g_slist_next( node );
205 g_slist_free( uniqName );
210 * Process email address entry, checking for unique alias and address. If the
211 * address field is empty, no entries will be generated.
212 * Enter: index Index.
213 * uniqName List of unique names to examine.
214 * email EMail address item to process.
215 * Return: List of entries from email object to add to index.
217 static GSList *addrcindex_proc_mail(
218 AddrCacheIndex *index, GSList *uniqName, ItemEMail *email )
223 /* Test for address */
225 name = email->address;
227 if( strlen( name ) > 0 ) {
228 /* Address was supplied */
229 /* Append alias if unique */
230 name = ADDRITEM_NAME( email );
231 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
232 list = g_slist_append( list, name );
234 /* Then append the address if unique */
235 /* Note is possible that the address has already */
236 /* been entered into one of the name fields. */
237 if( mgu_slist_test_unq_nc( uniqName, email->address ) ) {
238 list = g_slist_append( list, email->address );
246 * Add person's address entries into index. Each email address is processed.
247 * If the address field has been supplied, entries will be made. The index
248 * will include the address, alias and all name fields for the person.
250 * Enter: index Index.
251 * person Person to add.
253 void addrcindex_add_person( AddrCacheIndex *index, ItemPerson *person ) {
261 g_return_if_fail( index != NULL );
262 g_return_if_fail( person != NULL );
264 /* Build list of all unique names in person's name fields */
266 name = ADDRITEM_NAME( person );
267 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
268 uniqName = g_slist_append( uniqName, name );
271 name = person->nickName;
272 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
273 uniqName = g_slist_append( uniqName, name );
276 name = person->firstName;
277 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
278 uniqName = g_slist_append( uniqName, name );
281 name = person->lastName;
282 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
283 uniqName = g_slist_append( uniqName, name );
286 /* Process each email address entry */
287 listEMail = person->listEMail;
289 email = listEMail->data;
290 listMail = addrcindex_proc_mail( index, uniqName, email );
292 /* Create a completion entry for the address item */
295 /* printf( "\tname-m::%s::\n", node->data ); */
296 addrcindex_add_entry( index, node->data, email );
297 node = g_slist_next( node );
299 /* ... and all person's name entries */
302 /* printf( "\tname-p::%s::\n", node->data ); */
303 addrcindex_add_entry( index, node->data, email );
304 node = g_slist_next( node );
306 g_slist_free( listMail );
308 listEMail = g_list_next( listEMail );
311 /* Free up the list */
312 g_slist_free( uniqName );
316 * Print index to stream.
317 * Enter: index Index.
318 * stream Output stream.
320 void addrcindex_print( AddrCacheIndex *index, FILE *stream ) {
322 AddrIndexEntry *entry;
325 g_return_if_fail( index != NULL );
326 fprintf( stream, "AddressSearchIndex:\n" );
327 node = index->addressList;
330 email = entry->address;
331 fprintf( stream, "\tname: '%s'\t'%s'\n", entry->name, email->address );
332 node = g_list_next( node );
337 * Perform search for specified search term.
338 * Enter: index Completion index.
339 * search Search string.
340 * Return: List of references to ItemEMail objects meeting search criteria. The
341 * list should be g_list_free() when no longer required.
343 GList *addrcindex_search( AddrCacheIndex *index, const gchar *search ) {
344 AddrIndexEntry *entry;
350 g_return_if_fail( index != NULL );
351 g_return_if_fail( search != NULL );
354 if( index->addressList != NULL ) {
355 /* Add items to list */
356 g_completion_add_items( index->completion, index->addressList );
358 /* Perform the search */
359 prefix = g_strdup( search );
361 list = g_completion_complete( index->completion, prefix, NULL );
364 /* Build list of unique EMail objects */
368 /* printf( "\tname ::%s::\n", entry->name ); */
369 if( NULL == g_list_find( listEMail, entry->address ) ) {
370 listEMail = g_list_append(
371 listEMail, entry->address );
373 node = g_list_next( node );