2008-03-12 [paul] 3.3.1cvs21
[claws.git] / src / addrselect.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2002-2007 Match Grun and the Claws Mail team
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 3 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, see <http://www.gnu.org/licenses/>.
17  * 
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 static AddrSelectItem *addrselect_create_item   ( AddrItemObject *aio );
32
33 /**
34  * Create a selection record from an address cache item.
35  * \param  aio Item object.
36  * \return Address select item.
37  */
38 static AddrSelectItem *addrselect_create_item( AddrItemObject *aio ) {
39         AddrSelectItem *item = NULL;
40
41         if( aio ) {
42                 item = g_new0( AddrSelectItem, 1 );
43                 item->objectType = aio->type;
44                 item->addressItem = aio;
45                 item->uid = g_strdup( aio->uid );
46                 item->cacheID = NULL;
47         }
48         return item;
49 }
50
51 /**
52  * Create a selection record from an address object (in tree node).
53  * \param obj Address object.
54  * \return Address select item.
55  */
56 AddrSelectItem *addrselect_create_node( AddressObject *obj ) {
57         AddrSelectItem *item = NULL;
58
59         if( obj ) {
60                 item = g_new0( AddrSelectItem, 1 );
61                 item->objectType = addressbook_type2item( obj->type );
62                 item->addressItem = NULL;
63                 item->uid = NULL;
64                 item->cacheID = NULL;
65         }
66         return item;
67 }
68
69 /**
70  * Create a copy of a selection record.
71  * Enter: item Address entry to copy.
72  * \return Address select item.
73  */
74 AddrSelectItem *addrselect_item_copy( AddrSelectItem *item ) {
75         AddrSelectItem *copy = NULL;
76
77         if( item ) {
78                 copy = g_new0( AddrSelectItem, 1 );
79                 copy->objectType = item->objectType;
80                 copy->addressItem = item->addressItem;
81                 copy->uid = g_strdup( item->uid );
82                 copy->cacheID = g_strdup( item->cacheID );
83         }
84         return copy;
85 }
86
87 /**
88  * Free selection record.
89  * \return Address select item.
90  */
91 void addrselect_item_free( AddrSelectItem *item ) {
92         if( item ) {
93                 g_free( item->uid );
94                 g_free( item->cacheID );
95                 item->objectType = ITEMTYPE_NONE;
96                 item->addressItem = NULL;
97                 item->uid = NULL;
98                 item->cacheID = NULL;
99         }
100         g_free( item );
101 }
102
103 /**
104  * Print address selection item.
105  * \param item   Address select item.
106  * \param stream Output stream.
107  */
108 void addrselect_item_print( AddrSelectItem *item, FILE *stream ) {
109         fprintf( stream, "Select Record\n" );
110         fprintf( stream, "obj type: %d\n", item->objectType );
111         fprintf( stream, "     uid: %s\n", item->uid );
112         fprintf( stream, "cache id: %s\n", item->cacheID );
113         fprintf( stream, "---\n" );
114 }
115
116 /**
117  * Create a new address selection object.
118  * \return Initialized object.
119  */
120 AddrSelectList *addrselect_list_create() {
121         AddrSelectList *asl;
122
123         asl = g_new0( AddrSelectList, 1 );
124         asl->listSelect = NULL;
125         return asl;
126 }
127
128 /**
129  * Clear list of selection records.
130  * \param asl  List to process.
131  */
132 void addrselect_list_clear( AddrSelectList *asl ) {
133         GList *node;
134
135         g_return_if_fail( asl != NULL );
136         node = asl->listSelect;
137         while( node ) {
138                 AddrSelectItem *item;
139
140                 item = node->data;
141                 addrselect_item_free( item );
142                 node->data = NULL;
143                 node = g_list_next( node );
144         }
145         g_list_free( asl->listSelect );
146         asl->listSelect = NULL;
147 }
148
149 /**
150  * Free selection list.
151  * \param asl  List to free.
152  */
153 void addrselect_list_free( AddrSelectList *asl ) {
154         g_return_if_fail( asl != NULL );
155
156         addrselect_list_clear( asl );
157         g_list_free( asl->listSelect );
158         asl->listSelect = NULL;
159         g_free( asl );
160 }
161
162 /**
163  * Test whether selection is empty.
164  * \param  asl List to test.
165  * \return <i>TRUE</i> if list is empty.
166  */
167 gboolean addrselect_test_empty( AddrSelectList *asl ) {
168         g_return_val_if_fail( asl != NULL, TRUE );
169         return ( asl->listSelect == NULL );
170 }
171
172 /**
173  * Return list of AddrSelectItem objects.
174  * \param  asl  List to process.
175  * \return List of selection items. The list should should be freed with
176  *         <code>g_list_free()</code> when done. Items contained in the
177  *         list should <b>not</b> be freed!!!
178  */
179 GList *addrselect_get_list( AddrSelectList *asl ) {
180         GList *node, *list;
181
182         g_return_val_if_fail(asl != NULL, NULL);
183         list = NULL;
184         node = asl->listSelect;
185         while( node ) {
186                 list = g_list_append( list, node->data );
187                 node = g_list_next( node );
188         }
189         return list;
190 }
191
192 /**
193  * Format address item.
194  * \param  aio Item.
195  * \return Formatted address.
196  */
197 static gchar *addrselect_format_address( AddrItemObject * aio ) {
198         gchar *buf = NULL;
199         gchar *name = NULL;
200         gchar *address = NULL;
201
202         if( aio->type == ADDR_ITEM_EMAIL ) {
203                 ItemPerson *person = NULL;
204                 ItemEMail *email = ( ItemEMail * ) aio;
205
206                 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
207                 if( email->address ) {
208                         if( ADDRITEM_NAME(email) ) {
209                                 name = ADDRITEM_NAME(email);
210                                 if( *name == '\0' ) {
211                                         name = ADDRITEM_NAME(person);
212                                 }
213                         }
214                         else if( ADDRITEM_NAME(person) ) {
215                                 name = ADDRITEM_NAME(person);
216                         }
217                         else {
218                                 buf = g_strdup( email->address );
219                         }
220                         address = email->address;
221                 }
222         }
223         else if( aio->type == ADDR_ITEM_PERSON ) {
224                 ItemPerson *person = ( ItemPerson * ) aio;
225                 GList *node = person->listEMail;
226
227                 name = ADDRITEM_NAME(person);
228                 if( node ) {
229                         ItemEMail *email = ( ItemEMail * ) node->data;
230                         address = email->address;
231                 }
232         }
233         if( address ) {
234                 if( name ) {
235                         buf = g_strdup_printf( "%s <%s>", name, address );
236                 }
237                 else {
238                         buf = g_strdup( address );
239                 }
240         }
241         return buf;
242 }
243
244 /**
245  * Test whether specified object is in list.
246  * \param list List to check.
247  * \param aio  Object to test.
248  * \param item found, or <i>NULL</i> if not in list.
249  */
250 static AddrSelectItem *addrselect_list_find( GList *list, AddrItemObject *aio ) {
251         GList *node;
252
253         node = list;
254         while( node ) {
255                 AddrSelectItem *item;
256
257                 item = node->data;
258                 if( item->addressItem == aio ) return item;
259                 node = g_list_next( node );
260         }
261         return NULL;
262 }
263
264 /**
265  * Add a single object into the list.
266  * \param asl     Address selection object.
267  * \param aio     Address object.
268  * \param cacheID Cache ID. Should be freed after calling function.
269  */
270 void addrselect_list_add_obj( AddrSelectList *asl, AddrItemObject *aio, gchar *cacheID ) {
271         AddrSelectItem *item;
272
273         g_return_if_fail( asl != NULL );
274         if( aio == NULL ) return;
275
276         /* Check whether object is in list */
277         if( addrselect_list_find( asl->listSelect, aio ) ) return;
278
279         if( aio->type == ADDR_ITEM_PERSON ||
280             aio->type == ADDR_ITEM_EMAIL ||
281             aio->type == ADDR_ITEM_GROUP ) {
282                 item = addrselect_create_item( aio );
283                 item->cacheID = g_strdup( cacheID );
284                 asl->listSelect = g_list_append( asl->listSelect, item );
285         }
286         /* addrselect_list_show( asl, stdout ); */
287 }
288
289 /**
290  * Add a single item into the list.
291  * \param  asl     Address selection object.
292  * \param  item    Address select item.
293  * \param  cacheID Cache ID. Should be g_free() after calling function.
294  */
295 void addrselect_list_add( AddrSelectList *asl, AddrSelectItem *item, gchar *cacheID ) {
296         g_return_if_fail( asl != NULL );
297         if( item == NULL ) return;
298
299         /* Check whether object is in list */
300         if( g_list_find( asl->listSelect, item ) ) return;
301
302         item->cacheID = g_strdup( cacheID );
303         asl->listSelect = g_list_append( asl->listSelect, item );
304 }
305
306 /**
307  * Remove specified object from list.
308  * \param asl  Address selection object.
309  * \param aio  Object to remove.
310  */
311 void addrselect_list_remove( AddrSelectList *asl, AddrItemObject *aio ) {
312         GList *node;
313         AddrSelectItem *item;
314
315         g_return_if_fail( asl != NULL );
316         if( aio == NULL ) return;
317         node = asl->listSelect;
318         while( node ) {
319                 item = node->data;
320                 if( item->addressItem == aio ) {
321                         addrselect_item_free( item );
322                         node->data = NULL;
323                         asl->listSelect = g_list_remove_link( asl->listSelect, node );
324                         break;
325                 }
326                 node = g_list_next( node );
327         }
328         /* addrselect_list_show( list, stdout ); */
329 }
330
331 /**
332  * Build list of formatted addresses.
333  * \param  asl List to process.
334  * \return List of addresses, formatted as character strings. List should be
335  *         freed when no longer required.
336  */
337 GList *addrselect_build_list( AddrSelectList *asl ) {
338         GList *list;
339         GList *node;
340
341         g_return_val_if_fail(asl != NULL, NULL);
342         list = NULL;
343         node = asl->listSelect;
344         while( node != NULL ) {
345                 AddrSelectItem *item;
346                 AddrItemObject *aio;
347                 gchar *addr;
348
349                 item = node->data;
350                 aio = ( AddrItemObject * ) item->addressItem;
351                 if( aio ) {
352                         if( aio->type == ADDR_ITEM_GROUP ) {
353                                 ItemGroup *group = ( ItemGroup * ) aio;
354                                 GList *node = group->listEMail;
355                                 while( node ) {
356                                         ItemEMail *email = node->data;
357                                         addr = addrselect_format_address(
358                                                 ( AddrItemObject * ) email );
359                                         if( addr ) {
360                                                 list = g_list_append( list, addr );
361                                         }
362                                         node = g_list_next( node );
363                                 }
364                         }
365                         else {
366                                 addr = addrselect_format_address( aio );
367                                 if( addr ) {
368                                         list = g_list_append( list, addr );
369                                 }
370                         }
371                 }
372                 node = g_list_next( node );
373         }
374         return list;
375 }
376
377 /*
378 * End of Source.
379 */
380
381