2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2002-2009 Match Grun and the Claws Mail team
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 3 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, see <http://www.gnu.org/licenses/>.
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 g_print( "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 g_print( "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 cm_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 cm_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->address = email;
131 entry->name = g_utf8_strdown( name, -1 );
132 index->addressList = g_list_append( index->addressList, entry );
136 * Add an email entry into index. The index will also include all name fields
139 * Add address into index.
140 * Enter: index Index.
141 * email E-Mail to add.
143 void addrcindex_add_email( AddrCacheIndex *index, ItemEMail *email ) {
150 cm_return_if_fail( index != NULL );
151 cm_return_if_fail( email != NULL );
155 name = ADDRITEM_NAME( email );
157 if( strlen( name ) > 0 ) {
158 uniqName = g_slist_append( uniqName, name );
161 name = email->address;
162 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
163 uniqName = g_slist_append( uniqName, name );
166 if( strlen( name ) > 0 ) flag = TRUE;
169 /* Bail if no email address */
171 g_slist_free( uniqName );
175 person = ( ItemPerson * ) ADDRITEM_PARENT( email );
176 if( person != NULL ) {
177 name = ADDRITEM_NAME( person );
178 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
179 uniqName = g_slist_append( uniqName, name );
182 name = person->nickName;
183 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
184 uniqName = g_slist_append( uniqName, name );
187 name = person->firstName;
188 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
189 uniqName = g_slist_append( uniqName, name );
192 name = person->lastName;
193 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
194 uniqName = g_slist_append( uniqName, name );
198 /* Create a completion entry for each unique name */
201 addrcindex_add_entry( index, node->data, email );
202 node = g_slist_next( node );
204 g_slist_free( uniqName );
209 * Process email address entry, checking for unique alias and address. If the
210 * address field is empty, no entries will be generated.
211 * Enter: index Index.
212 * uniqName List of unique names to examine.
213 * email EMail address item to process.
214 * Return: List of entries from email object to add to index.
216 static GSList *addrcindex_proc_mail(
217 AddrCacheIndex *index, GSList *uniqName, ItemEMail *email )
222 /* Test for address */
224 name = email->address;
226 if( strlen( name ) > 0 ) {
227 /* Address was supplied */
228 /* Append alias if unique */
229 name = ADDRITEM_NAME( email );
230 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
231 list = g_slist_append( list, name );
233 /* Then append the address if unique */
234 /* Note is possible that the address has already */
235 /* been entered into one of the name fields. */
236 if( mgu_slist_test_unq_nc( uniqName, email->address ) ) {
237 list = g_slist_append( list, email->address );
245 * Add person's address entries into index. Each email address is processed.
246 * If the address field has been supplied, entries will be made. The index
247 * will include the address, alias and all name fields for the person.
249 * Enter: index Index.
250 * person Person to add.
252 void addrcindex_add_person( AddrCacheIndex *index, ItemPerson *person ) {
260 cm_return_if_fail( index != NULL );
261 cm_return_if_fail( person != NULL );
263 /* Build list of all unique names in person's name fields */
265 name = ADDRITEM_NAME( person );
266 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
267 uniqName = g_slist_append( uniqName, name );
270 name = person->nickName;
271 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
272 uniqName = g_slist_append( uniqName, name );
275 name = person->firstName;
276 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
277 uniqName = g_slist_append( uniqName, name );
280 name = person->lastName;
281 if( mgu_slist_test_unq_nc( uniqName, name ) ) {
282 uniqName = g_slist_append( uniqName, name );
285 /* Process each email address entry */
286 listEMail = person->listEMail;
288 email = listEMail->data;
289 listMail = addrcindex_proc_mail( index, uniqName, email );
291 /* Create a completion entry for the address item */
294 /* g_print( "\tname-m::%s::\n", node->data ); */
295 addrcindex_add_entry( index, node->data, email );
296 node = g_slist_next( node );
298 /* ... and all person's name entries */
301 /* g_print( "\tname-p::%s::\n", node->data ); */
302 addrcindex_add_entry( index, node->data, email );
303 node = g_slist_next( node );
305 g_slist_free( listMail );
307 listEMail = g_list_next( listEMail );
310 /* Free up the list */
311 g_slist_free( uniqName );
315 * Print index to stream.
316 * Enter: index Index.
317 * stream Output stream.
319 void addrcindex_print( AddrCacheIndex *index, FILE *stream ) {
321 AddrIndexEntry *entry;
324 cm_return_if_fail( index != NULL );
325 fprintf( stream, "AddressSearchIndex:\n" );
326 node = index->addressList;
329 email = entry->address;
330 fprintf( stream, "\tname: '%s'\t'%s'\n", entry->name, email->address );
331 node = g_list_next( node );
336 * Perform search for specified search term.
337 * Enter: index Completion index.
338 * search Search string.
339 * Return: List of references to ItemEMail objects meeting search criteria. The
340 * list should be g_list_free() when no longer required.
342 GList *addrcindex_search( AddrCacheIndex *index, const gchar *search ) {
343 AddrIndexEntry *entry;
349 cm_return_if_fail( index != NULL );
350 cm_return_if_fail( search != NULL );
353 if( index->addressList != NULL ) {
354 /* Add items to list */
355 g_completion_add_items( index->completion, index->addressList );
357 /* Perform the search */
358 prefix = g_utf8_strdown( search, -1 );
359 list = g_completion_complete( index->completion, prefix, NULL );
362 /* Build list of unique EMail objects */
366 /* g_print( "\tname ::%s::\n", entry->name ); */
367 if( NULL == g_list_find( listEMail, entry->address ) ) {
368 listEMail = g_list_append(
369 listEMail, entry->address );
371 node = g_list_next( node );