talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

addrselect.c (9400B)


      1 /*
      2  * Claws Mail -- a GTK based, lightweight, and fast e-mail client
      3  * Copyright (C) 2002-2012 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 	cm_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 	cm_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 	cm_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 	cm_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 == ITEMTYPE_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 == ITEMTYPE_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 && name[0] != '\0' ) {
    235 			if( strchr_with_skip_quote( name, '"', ',' ) )
    236 				buf = g_strdup_printf( "\"%s\" <%s>", name, address );
    237 			else
    238 				buf = g_strdup_printf( "%s <%s>", name, address );
    239 		}
    240 		else {
    241 			buf = g_strdup( address );
    242 		}
    243 	}
    244 	return buf;
    245 }
    246 
    247 /**
    248  * Test whether specified object is in list.
    249  * \param list List to check.
    250  * \param aio  Object to test.
    251  * \param item found, or <i>NULL</i> if not in list.
    252  */
    253 static AddrSelectItem *addrselect_list_find( GList *list, AddrItemObject *aio ) {
    254 	GList *node;
    255 
    256 	node = list;
    257 	while( node ) {
    258 		AddrSelectItem *item;
    259 
    260 		item = node->data;
    261 		if( item->addressItem == aio ) return item;
    262 		node = g_list_next( node );
    263 	}
    264 	return NULL;
    265 }
    266 
    267 /**
    268  * Add a single object into the list.
    269  * \param asl     Address selection object.
    270  * \param aio     Address object.
    271  * \param cacheID Cache ID. Should be freed after calling function.
    272  */
    273 void addrselect_list_add_obj( AddrSelectList *asl, AddrItemObject *aio, gchar *cacheID ) {
    274 	AddrSelectItem *item;
    275 
    276 	cm_return_if_fail( asl != NULL );
    277 	if( aio == NULL ) return;
    278 
    279 	/* Check whether object is in list */
    280 	if( addrselect_list_find( asl->listSelect, aio ) ) return;
    281 
    282 	if( aio->type == ITEMTYPE_PERSON ||
    283 	    aio->type == ITEMTYPE_EMAIL ||
    284 	    aio->type == ITEMTYPE_GROUP ) {
    285 		item = addrselect_create_item( aio );
    286 		item->cacheID = g_strdup( cacheID );
    287 		asl->listSelect = g_list_append( asl->listSelect, item );
    288 	}
    289 	/* addrselect_list_show( asl, stdout ); */
    290 }
    291 
    292 /**
    293  * Add a single item into the list.
    294  * \param  asl     Address selection object.
    295  * \param  item    Address select item.
    296  * \param  cacheID Cache ID. Should be g_free() after calling function.
    297  */
    298 void addrselect_list_add( AddrSelectList *asl, AddrSelectItem *item, gchar *cacheID ) {
    299 	cm_return_if_fail( asl != NULL );
    300 	if( item == NULL ) return;
    301 
    302 	/* Check whether object is in list */
    303 	if( g_list_find( asl->listSelect, item ) ) return;
    304 
    305 	item->cacheID = g_strdup( cacheID );
    306 	asl->listSelect = g_list_append( asl->listSelect, item );
    307 }
    308 
    309 /**
    310  * Remove specified object from list.
    311  * \param asl  Address selection object.
    312  * \param aio  Object to remove.
    313  */
    314 void addrselect_list_remove( AddrSelectList *asl, AddrItemObject *aio ) {
    315 	GList *node;
    316 	AddrSelectItem *item;
    317 
    318 	cm_return_if_fail( asl != NULL );
    319 	if( aio == NULL ) return;
    320 	node = asl->listSelect;
    321 	while( node ) {
    322 		item = node->data;
    323 		if( item->addressItem == aio ) {
    324 			addrselect_item_free( item );
    325 			node->data = NULL;
    326 			asl->listSelect = g_list_remove_link( asl->listSelect, node );
    327 			break;
    328 		}
    329 		node = g_list_next( node );
    330 	}
    331 	/* addrselect_list_show( list, stdout ); */
    332 }
    333 
    334 /**
    335  * Build list of formatted addresses.
    336  * \param  asl List to process.
    337  * \return List of addresses, formatted as character strings. List should be
    338  *         freed when no longer required.
    339  */
    340 GList *addrselect_build_list( AddrSelectList *asl ) {
    341 	GList *list;
    342 	GList *node;
    343 
    344 	cm_return_val_if_fail(asl != NULL, NULL);
    345 	list = NULL;
    346 	node = asl->listSelect;
    347 	while( node != NULL ) {
    348 		AddrSelectItem *item;
    349 		AddrItemObject *aio;
    350 		gchar *addr;
    351 
    352 		item = node->data;
    353 		aio = ( AddrItemObject * ) item->addressItem;
    354 		if( aio ) {
    355 			if( aio->type == ITEMTYPE_GROUP ) {
    356 				ItemGroup *group = ( ItemGroup * ) aio;
    357 				GList *node = group->listEMail;
    358 				while( node ) {
    359 					ItemEMail *email = node->data;
    360 					addr = addrselect_format_address(
    361 						( AddrItemObject * ) email );
    362 					if( addr ) {
    363 						list = g_list_append( list, addr );
    364 					}
    365 					node = g_list_next( node );
    366 				}
    367 			}
    368 			else {
    369 				addr = addrselect_format_address( aio );
    370 				if( addr ) {
    371 					list = g_list_append( list, addr );
    372 				}
    373 			}
    374 		}
    375 		node = g_list_next( node );
    376 	}
    377 	return list;
    378 }