2005-10-16 [colin] 1.9.15cvs58
[claws.git] / src / addrselect.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2002 Match Grun
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 /*
21  * Address list item selection objects.
22  */
23
24 #include <stdio.h>
25 #include <glib.h>
26
27 #include "addrselect.h"
28 #include "addressitem.h"
29 #include "mgutils.h"
30
31 /**
32  * Create a selection record from an address cache item.
33  * \param  aio Item object.
34  * \return Address select item.
35  */
36 AddrSelectItem *addrselect_create_item( AddrItemObject *aio ) {
37         AddrSelectItem *item = NULL;
38
39         if( aio ) {
40                 item = g_new0( AddrSelectItem, 1 );
41                 item->objectType = aio->type;
42                 item->addressItem = aio;
43                 item->uid = g_strdup( aio->uid );
44                 item->cacheID = NULL;
45         }
46         return item;
47 }
48
49 /**
50  * Create a selection record from an address object (in tree node).
51  * \param obj Address object.
52  * \return Address select item.
53  */
54 AddrSelectItem *addrselect_create_node( AddressObject *obj ) {
55         AddrSelectItem *item = NULL;
56
57         if( obj ) {
58                 item = g_new0( AddrSelectItem, 1 );
59                 item->objectType = addressbook_type2item( obj->type );
60                 item->addressItem = NULL;
61                 item->uid = NULL;
62                 item->cacheID = NULL;
63         }
64         return item;
65 }
66
67 /**
68  * Create a copy of a selection record.
69  * Enter: item Address entry to copy.
70  * \return Address select item.
71  */
72 AddrSelectItem *addrselect_item_copy( AddrSelectItem *item ) {
73         AddrSelectItem *copy = NULL;
74
75         if( item ) {
76                 copy = g_new0( AddrSelectItem, 1 );
77                 copy->objectType = item->objectType;
78                 copy->addressItem = item->addressItem;
79                 copy->uid = g_strdup( item->uid );
80                 copy->cacheID = g_strdup( item->cacheID );
81         }
82         return copy;
83 }
84
85 /**
86  * Free selection record.
87  * \return Address select item.
88  */
89 void addrselect_item_free( AddrSelectItem *item ) {
90         if( item ) {
91                 g_free( item->uid );
92                 g_free( item->cacheID );
93                 item->objectType = ITEMTYPE_NONE;
94                 item->addressItem = NULL;
95                 item->uid = NULL;
96                 item->cacheID = NULL;
97         }
98         g_free( item );
99 }
100
101 /**
102  * Specify cache ID for specified item.
103  * \param item  Address select item.
104  * \param value Cache ID.
105  */
106 void addrselect_set_cache_id( AddrSelectItem *item, const gchar *value ) {
107         g_return_if_fail( item != NULL );
108         item->cacheID = mgu_replace_string( item->cacheID, value );
109 }
110
111 /**
112  * Print address selection item.
113  * \param item   Address select item.
114  * \param stream Output stream.
115  */
116 void addrselect_item_print( AddrSelectItem *item, FILE *stream ) {
117         fprintf( stream, "Select Record\n" );
118         fprintf( stream, "obj type: %d\n", item->objectType );
119         fprintf( stream, "     uid: %s\n", item->uid );
120         fprintf( stream, "cache id: %s\n", item->cacheID );
121         fprintf( stream, "---\n" );
122 }
123
124 /**
125  * Create a new address selection object.
126  * \return Initialized object.
127  */
128 AddrSelectList *addrselect_list_create() {
129         AddrSelectList *asl;
130
131         asl = g_new0( AddrSelectList, 1 );
132         asl->listSelect = NULL;
133         return asl;
134 }
135
136 /**
137  * Clear list of selection records.
138  * \param asl  List to process.
139  */
140 void addrselect_list_clear( AddrSelectList *asl ) {
141         GList *node;
142
143         g_return_if_fail( asl != NULL );
144         node = asl->listSelect;
145         while( node ) {
146                 AddrSelectItem *item;
147
148                 item = node->data;
149                 addrselect_item_free( item );
150                 node->data = NULL;
151                 node = g_list_next( node );
152         }
153         g_list_free( asl->listSelect );
154         asl->listSelect = NULL;
155 }
156
157 /**
158  * Free selection list.
159  * \param asl  List to free.
160  */
161 void addrselect_list_free( AddrSelectList *asl ) {
162         g_return_if_fail( asl != NULL );
163
164         addrselect_list_clear( asl );
165         g_list_free( asl->listSelect );
166         asl->listSelect = NULL;
167         g_free( asl );
168 }
169
170 /**
171  * Test whether selection is empty.
172  * \param  asl List to test.
173  * \return <i>TRUE</i> if list is empty.
174  */
175 gboolean addrselect_test_empty( AddrSelectList *asl ) {
176         g_return_val_if_fail( asl != NULL, TRUE );
177         return ( asl->listSelect == NULL );
178 }
179
180 /**
181  * Return list of AddrSelectItem objects.
182  * \param  asl  List to process.
183  * \return List of selection items. The list should should be freed with
184  *         <code>g_list_free()</code> when done. Items contained in the
185  *         list should <b>not</b> be freed!!!
186  */
187 GList *addrselect_get_list( AddrSelectList *asl ) {
188         GList *node, *list;
189
190         g_return_val_if_fail(asl != NULL, NULL);
191         list = NULL;
192         node = asl->listSelect;
193         while( node ) {
194                 list = g_list_append( list, node->data );
195                 node = g_list_next( node );
196         }
197         return list;
198 }
199
200 /**
201  * Format address item.
202  * \param  aio Item.
203  * \return Formatted address.
204  */
205 static gchar *addrselect_format_address( AddrItemObject * aio ) {
206         gchar *buf = NULL;
207         gchar *name = NULL;
208         gchar *address = NULL;
209
210         if( aio->type == ADDR_ITEM_EMAIL ) {
211                 ItemPerson *person = NULL;
212                 ItemEMail *email = ( ItemEMail * ) aio;
213
214                 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
215                 if( email->address ) {
216                         if( ADDRITEM_NAME(email) ) {
217                                 name = ADDRITEM_NAME(email);
218                                 if( *name == '\0' ) {
219                                         name = ADDRITEM_NAME(person);
220                                 }
221                         }
222                         else if( ADDRITEM_NAME(person) ) {
223                                 name = ADDRITEM_NAME(person);
224                         }
225                         else {
226                                 buf = g_strdup( email->address );
227                         }
228                         address = email->address;
229                 }
230         }
231         else if( aio->type == ADDR_ITEM_PERSON ) {
232                 ItemPerson *person = ( ItemPerson * ) aio;
233                 GList *node = person->listEMail;
234
235                 name = ADDRITEM_NAME(person);
236                 if( node ) {
237                         ItemEMail *email = ( ItemEMail * ) node->data;
238                         address = email->address;
239                 }
240         }
241         if( address ) {
242                 if( name ) {
243                         buf = g_strdup_printf( "%s <%s>", name, address );
244                 }
245                 else {
246                         buf = g_strdup( address );
247                 }
248         }
249         return buf;
250 }
251
252 /**
253  * Print formatted addresses list to specified stream.
254  * \param asl    List to process.
255  * \param stream Stream.
256  */
257 void addrselect_list_print( AddrSelectList *asl, FILE *stream ) {
258         GList *node;
259
260         g_return_if_fail( asl != NULL );
261         fprintf( stream, "show selection...>>>\n" );
262         node = asl->listSelect;
263         while( node != NULL ) {
264                 AddrSelectItem *item;
265                 AddrItemObject *aio;
266                 gchar *addr;
267
268                 item = node->data;
269                 aio = ( AddrItemObject * ) item->addressItem;
270                 if( aio ) {
271                         fprintf( stream, "- %d : '%s'\n", aio->type, aio->name );
272                         if( aio->type == ADDR_ITEM_GROUP ) {
273                                 ItemGroup *group = ( ItemGroup * ) aio;
274                                 GList *node = group->listEMail;
275                                 while( node ) {
276                                         ItemEMail *email = node->data;
277                                         addr = addrselect_format_address(
278                                                 ( AddrItemObject * ) email );
279                                         if( addr ) {
280                                                 fprintf( stream, "\tgrp >%s<\n", addr );
281                                                 g_free( addr );
282                                         }
283                                         node = g_list_next( node );
284                                 }
285                         }
286                         else {
287                                 addr = addrselect_format_address( aio );
288                                 if( addr ) {
289                                         fprintf( stream, "\t>%s<\n", addr );
290                                         g_free( addr );
291                                 }
292                         }
293                 }
294                 else {
295                         fprintf( stream, "- NULL" );
296                 }
297                 node = g_list_next( node );
298         }
299         fprintf( stream, "show selection...<<<\n" );
300 }
301
302 /**
303  * Print address items to specified stream.
304  * \param asl    List to process.
305  * \param stream Stream.
306  */
307 void addrselect_list_show( AddrSelectList *asl, FILE *stream ) {
308         GList *node;
309
310         g_return_if_fail( asl != NULL );
311         fprintf( stream, "show selection...>>>\n" );
312         node = asl->listSelect;
313         while( node != NULL ) {
314                 AddrSelectItem *item;
315
316                 item = node->data;
317                 addrselect_item_print( item, stream );
318                 node = g_list_next( node );
319         }
320         fprintf( stream, "show selection...<<<\n" );
321 }
322
323 /**
324  * Test whether specified object is in list.
325  * \param list List to check.
326  * \param aio  Object to test.
327  * \param item found, or <i>NULL</i> if not in list.
328  */
329 static AddrSelectItem *addrselect_list_find( GList *list, AddrItemObject *aio ) {
330         GList *node;
331
332         node = list;
333         while( node ) {
334                 AddrSelectItem *item;
335
336                 item = node->data;
337                 if( item->addressItem == aio ) return item;
338                 node = g_list_next( node );
339         }
340         return NULL;
341 }
342
343 /**
344  * Add a single object into the list.
345  * \param asl     Address selection object.
346  * \param aio     Address object.
347  * \param cacheID Cache ID. Should be freed after calling function.
348  */
349 void addrselect_list_add_obj( AddrSelectList *asl, AddrItemObject *aio, gchar *cacheID ) {
350         AddrSelectItem *item;
351
352         g_return_if_fail( asl != NULL );
353         if( aio == NULL ) return;
354
355         /* Check whether object is in list */
356         if( addrselect_list_find( asl->listSelect, aio ) ) return;
357
358         if( aio->type == ADDR_ITEM_PERSON ||
359             aio->type == ADDR_ITEM_EMAIL ||
360             aio->type == ADDR_ITEM_GROUP ) {
361                 item = addrselect_create_item( aio );
362                 item->cacheID = g_strdup( cacheID );
363                 asl->listSelect = g_list_append( asl->listSelect, item );
364         }
365         /* addrselect_list_show( asl, stdout ); */
366 }
367
368 /**
369  * Add a single item into the list.
370  * \param  asl     Address selection object.
371  * \param  item    Address select item.
372  * \param  cacheID Cache ID. Should be g_free() after calling function.
373  */
374 void addrselect_list_add( AddrSelectList *asl, AddrSelectItem *item, gchar *cacheID ) {
375         g_return_if_fail( asl != NULL );
376         if( item == NULL ) return;
377
378         /* Check whether object is in list */
379         if( g_list_find( asl->listSelect, item ) ) return;
380
381         item->cacheID = g_strdup( cacheID );
382         asl->listSelect = g_list_append( asl->listSelect, item );
383 }
384
385 /**
386  * Remove specified object from list.
387  * \param asl  Address selection object.
388  * \param aio  Object to remove.
389  */
390 void addrselect_list_remove( AddrSelectList *asl, AddrItemObject *aio ) {
391         GList *node;
392         AddrSelectItem *item;
393
394         g_return_if_fail( asl != NULL );
395         if( aio == NULL ) return;
396         node = asl->listSelect;
397         while( node ) {
398                 item = node->data;
399                 if( item->addressItem == aio ) {
400                         addrselect_item_free( item );
401                         node->data = NULL;
402                         asl->listSelect = g_list_remove_link( asl->listSelect, node );
403                         break;
404                 }
405                 node = g_list_next( node );
406         }
407         /* addrselect_list_show( list, stdout ); */
408 }
409
410 /**
411  * Build list of formatted addresses.
412  * \param  asl List to process.
413  * \return List of addresses, formatted as character strings. List should be
414  *         freed when no longer required.
415  */
416 GList *addrselect_build_list( AddrSelectList *asl ) {
417         GList *list;
418         GList *node;
419
420         g_return_val_if_fail(asl != NULL, NULL);
421         list = NULL;
422         node = asl->listSelect;
423         while( node != NULL ) {
424                 AddrSelectItem *item;
425                 AddrItemObject *aio;
426                 gchar *addr;
427
428                 item = node->data;
429                 aio = ( AddrItemObject * ) item->addressItem;
430                 if( aio ) {
431                         if( aio->type == ADDR_ITEM_GROUP ) {
432                                 ItemGroup *group = ( ItemGroup * ) aio;
433                                 GList *node = group->listEMail;
434                                 while( node ) {
435                                         ItemEMail *email = node->data;
436                                         addr = addrselect_format_address(
437                                                 ( AddrItemObject * ) email );
438                                         if( addr ) {
439                                                 list = g_list_append( list, addr );
440                                         }
441                                         node = g_list_next( node );
442                                 }
443                         }
444                         else {
445                                 addr = addrselect_format_address( aio );
446                                 if( addr ) {
447                                         list = g_list_append( list, addr );
448                                 }
449                         }
450                 }
451                 node = g_list_next( node );
452         }
453         return list;
454 }
455
456 /*
457 * End of Source.
458 */
459
460