2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2002 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 * Contains address clipboard objects and related functions. The address
22 * clipboard is implemented as a linked list of AddrSelectItem objects.
23 * The address clipboard offers two groups of functions:
25 * a) Cut, copy and paste of address item objects (ItemFolder, ItemGroup,
26 * ItemPerson) into a folder. With this method, we can paste ItemPerson
27 * objects but not unattached ItemEMail objects into a folder. ItemEMail
28 * objects are owned by an ItemPerson object. Any ItemEMail objects that
29 * appear in the clipboard are ignored. If an ItemPerson object is found,
30 * the ItemPerson *and* ItemEMail objects that it owns are pasted.
32 * b) Copy and paste of ItemEMail address objects only into (below)
33 * ItemPerson objects. All ItemEMail objects which are owned by
34 * ItemPerson and referenced by ItemGroup objects are pasted. Any
35 * ItemFolder objects in the clipboard, and any objects owned by
36 * ItemFolder objects are ignored.
38 * Objects are inserted to the clipboard by copying (cloning)
39 * AddrSelectItem objects from the address books selection list to the
40 * clipboard's internal selection list. The clipboard makes use of the
41 * object id's and address cache id's to access objects contained in
42 * the address cache. If the referenced object is not found, it is
43 * ignored. This eliminates the need to delete pointers in multiple
44 * linked lists when an address object is deleted.
52 #include "addrcache.h"
54 #include "addrselect.h"
55 #include "addrindex.h"
61 AddressClipboard *addrclip_create( void ) {
62 AddressClipboard *clipBoard;
64 clipBoard = g_new0( AddressClipboard, 1 );
65 clipBoard->cutFlag = FALSE;
66 clipBoard->objectList = NULL;
73 void addrclip_clear( AddressClipboard *clipBoard ) {
77 g_return_if_fail( clipBoard != NULL );
78 node = clipBoard->objectList;
81 addrselect_item_free( item );
83 node = g_list_next( node );
85 g_list_free( clipBoard->objectList );
86 clipBoard->objectList = NULL;
90 * Free up a clipboard.
92 void addrclip_free( AddressClipboard *clipBoard ) {
93 g_return_if_fail( clipBoard != NULL );
95 addrclip_clear( clipBoard );
96 clipBoard->cutFlag = FALSE;
100 * Setup reference to address index.
102 void addrclip_set_index(
103 AddressClipboard *clipBoard, AddressIndex *addrIndex )
105 g_return_if_fail( clipBoard != NULL );
106 g_return_if_fail( addrIndex != NULL );
107 clipBoard->addressIndex = addrIndex;
111 * Test whether clipboard is empty.
112 * Enter: clipBoard Clipboard.
113 * Return: TRUE if clipboard is empty.
115 gboolean addrclip_is_empty( AddressClipboard *clipBoard ) {
116 gboolean retVal = TRUE;
119 if( clipBoard->objectList ) retVal = FALSE;
125 * Add a list of address selection objects to clipbard.
126 * Enter: clipBoard Clipboard.
127 * addrList List of address selection objects.
129 void addrclip_add( AddressClipboard *clipBoard, AddrSelectList *asl ) {
132 g_return_if_fail( clipBoard != NULL );
133 g_return_if_fail( asl != NULL );
134 node = asl->listSelect;
136 AddrSelectItem *item, *itemCopy;
139 itemCopy = addrselect_item_copy( item );
140 clipBoard->objectList =
141 g_list_append( clipBoard->objectList, itemCopy );
142 node = g_list_next( node );
147 * Add a single address selection objects to clipbard.
148 * Enter: clipBoard Clipboard.
149 * item Address selection object.
151 void addrclip_add_item(
152 AddressClipboard *clipBoard, AddrSelectItem *item )
154 g_return_if_fail( clipBoard != NULL );
156 AddrSelectItem *itemCopy;
158 itemCopy = addrselect_item_copy( item );
159 clipBoard->objectList =
160 g_list_append( clipBoard->objectList, itemCopy );
165 * Show clipboard contents.
166 * Enter: clipBoard Clipboard.
167 * stream Output stream.
169 void addrclip_list_show( AddressClipboard *clipBoard, FILE *stream ) {
174 g_return_if_fail( clipBoard != NULL );
175 fprintf( stream, "clipboard show selection...>>>\n" );
176 node = clipBoard->objectList;
177 while( node != NULL ) {
178 AddrSelectItem *item;
181 addrselect_item_print( item, stream );
183 cache = addrindex_get_cache( clipBoard->addressIndex, item->cacheID );
184 aio = addrcache_get_object( cache, item->uid );
186 if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) {
187 addritem_print_item_person( ( ItemPerson * ) aio, stream );
189 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) {
190 addritem_print_item_email( ( ItemEMail * ) aio, stream );
192 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
193 addritem_print_item_group( ( ItemGroup * ) aio, stream );
195 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) {
196 addritem_print_item_folder( ( ItemFolder * ) aio, stream );
199 node = g_list_next( node );
201 fprintf( stream, "clipboard show selection...<<<\n" );
204 /* Pasted address pointers */
205 typedef struct _AddrClip_EMail_ AddrClip_EMail;
206 struct _AddrClip_EMail_ {
212 * Free up specified list of addresses.
214 static void addrclip_free_copy_list( GList *copyList ) {
219 AddrClip_EMail *em = node->data;
224 node = g_list_next( node );
229 * Paste person into cache.
230 * Enter: cache Address cache to paste into.
231 * folder Folder to store
232 * person Person to paste.
233 * copyLIst List of email addresses pasted.
234 * Return: Update list of email addresses pasted.
236 static GList *addrclip_cache_add_person(
237 AddressCache *cache, ItemFolder *folder, ItemPerson *person,
240 ItemPerson *newPerson;
243 UserAttribute *attrib;
244 UserAttribute *newAttrib;
249 newPerson = addritem_copy_item_person( person );
250 addrcache_id_person( cache, newPerson );
251 addrcache_folder_add_person( cache, folder, newPerson );
253 /* Copy email addresses */
254 node = person->listEMail;
257 newEMail = addritem_copy_item_email( email );
258 addrcache_id_email( cache, newEMail );
259 addrcache_person_add_email( cache, newPerson, newEMail );
260 node = g_list_next( node );
262 /* Take a copy of the original */
263 em = g_new0( AddrClip_EMail, 1 );
264 em->original = email;
266 copyList = g_list_append( copyList, em );
269 /* Copy user attributes */
270 node = person->listAttrib;
273 newAttrib = addritem_copy_attribute( attrib );
274 addrcache_id_attribute( cache, newAttrib );
275 addritem_person_add_attribute( newPerson, newAttrib );
276 node = g_list_next( node );
283 * Search for new email record in copied email list.
284 * Enter: copyList List of copied email address mappings.
285 * emailOrig Original email item.
286 * Return: New email item corresponding to original item if pasted. Or NULL if
289 static ItemEMail *addrclip_find_copied_email(
290 GList *copyList, ItemEMail *emailOrig )
292 ItemEMail *emailCopy;
300 if( em->original == emailOrig ) {
301 emailCopy = em->copy;
304 node = g_list_next( node );
310 * Paste group into cache.
311 * Enter: cache Address cache to paste into.
312 * folder Folder to store
313 * group Group to paste.
314 * copyList List of email addresses pasted.
315 * Return: Group added.
317 static ItemGroup *addrclip_cache_add_group(
318 AddressCache *cache, ItemFolder *folder, ItemGroup *group,
322 ItemEMail *emailOrig, *emailCopy;
326 newGroup = addritem_copy_item_group( group );
327 addrcache_id_group( cache, newGroup );
328 addrcache_folder_add_group( cache, folder, newGroup );
330 /* Add references of copied addresses to group */
331 node = group->listEMail;
333 emailOrig = ( ItemEMail * ) node->data;
334 emailCopy = addrclip_find_copied_email( copyList, emailOrig );
336 addrcache_group_add_email( cache, newGroup, emailCopy );
338 node = g_list_next( node );
344 * Copy specified folder into cache. Note this functions uses pointers to
345 * folders to copy from. There should not be any deleted items referenced
346 * by these pointers!!!
347 * Enter: cache Address cache to copy into.
348 * targetFolder Target folder.
349 * folder Folder to copy.
350 * Return: Folder added.
352 static ItemFolder *addrclip_cache_copy_folder(
353 AddressCache *cache, ItemFolder *targetFolder, ItemFolder *folder )
355 ItemFolder *newFolder;
361 newFolder = addritem_copy_item_folder( folder );
362 addrcache_id_folder( cache, newFolder );
363 addrcache_folder_add_folder( cache, targetFolder, newFolder );
365 /* Copy people to new folder */
367 node = folder->listPerson;
369 ItemPerson *item = node->data;
370 node = g_list_next( node );
371 copyList = addrclip_cache_add_person(
372 cache, newFolder, item, copyList );
375 /* Copy groups to new folder */
376 node = folder->listGroup;
378 ItemGroup *item = node->data;
379 node = g_list_next( node );
380 newGroup = addrclip_cache_add_group(
381 cache, newFolder, item, copyList );
383 g_list_free( copyList );
385 /* Copy folders to new folder (recursive) */
386 node = folder->listFolder;
388 ItemFolder *item = node->data;
389 node = g_list_next( node );
390 addrclip_cache_copy_folder( cache, newFolder, item );
397 * Paste item list into address book.
398 * Enter: cache Target address cache.
399 * folder Target folder where data is pasted.
400 * itemList List of items to paste.
401 * clipBoard Clipboard.
402 * Return: List of group or folder items added.
404 static GList *addrclip_cache_add_folder(
405 AddressCache *cache, ItemFolder *folder, GList *itemList,
406 AddressClipboard *clipBoard )
410 AddrSelectItem *item;
412 AddressCache *cacheFrom;
422 node = g_list_next( node );
424 cacheFrom = addrindex_get_cache(
425 clipBoard->addressIndex, item->cacheID );
426 if( cacheFrom == NULL ) continue;
428 aio = addrcache_get_object( cacheFrom, item->uid );
430 if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) {
433 person = ( ItemPerson * ) aio;
434 copyList = addrclip_cache_add_person(
435 cache, folder, person, copyList );
438 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) {
441 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
442 haveGroups = TRUE; /* Process later */
444 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) {
445 ItemFolder *itemFolder, *newFolder;
447 itemFolder = ( ItemFolder * ) aio;
448 newFolder = addrclip_cache_copy_folder(
449 cache, folder, itemFolder );
451 g_list_append( folderGroup, newFolder );
456 if( item->objectType == ITEMTYPE_DATASOURCE ) {
458 * Must be an address book - allow copy only if
459 * copying from a different cache.
461 if( cache != cacheFrom ) {
462 ItemFolder *itemFolder, *newFolder;
464 itemFolder = cacheFrom->rootFolder;
465 newFolder = addrclip_cache_copy_folder(
466 cache, folder, itemFolder );
467 addritem_folder_set_name( newFolder,
468 addrcache_get_name( cacheFrom ) );
470 g_list_append( folderGroup, newFolder );
476 /* Finally add any groups */
481 node = g_list_next( node );
482 cacheFrom = addrindex_get_cache(
483 clipBoard->addressIndex, item->cacheID );
484 if( cacheFrom == NULL ) continue;
485 aio = addrcache_get_object( cacheFrom, item->uid );
487 if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
488 ItemGroup *group, *newGroup;
490 group = ( ItemGroup * ) aio;
491 newGroup = addrclip_cache_add_group(
492 cache, folder, group, copyList );
494 g_list_append( folderGroup, newGroup );
501 addrclip_free_copy_list( copyList );
502 g_list_free( copyList );
509 * Move items in list into new folder
510 * Enter: cache Target address cache.
511 * targetFolder Target folder where data is pasted.
512 * itemList List of items to paste.
513 * clipBoard Clipboard.
514 * Return: List of group or folder items added.
516 static GList *addrclip_cache_move_items(
517 AddressCache *cache, ItemFolder *targetFolder, GList *itemList,
518 AddressClipboard *clipBoard )
522 AddrSelectItem *item;
524 AddressCache *cacheFrom;
530 node = g_list_next( node );
531 cacheFrom = addrindex_get_cache(
532 clipBoard->addressIndex, item->cacheID );
533 if( cacheFrom == NULL ) continue;
534 aio = addrcache_get_object( cacheFrom, item->uid );
536 if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) {
539 person = ( ItemPerson * ) aio;
540 addrcache_folder_move_person(
541 cache, person, targetFolder );
543 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
546 group = ( ItemGroup * ) aio;
547 addrcache_folder_move_group(
548 cache, group, targetFolder );
549 folderGroup = g_list_append( folderGroup, group );
551 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) {
554 folder = ( ItemFolder * ) aio;
555 addrcache_folder_move_folder(
556 cache, folder, targetFolder );
558 g_list_append( folderGroup, folder );
566 * Get address cache of first item in list. This assumes that all items in
567 * the clipboard are located in the same cache.
568 * Enter: clipBoard Clipboard.
569 * Return: List of group or folder items added.
571 static AddressCache *addrclip_list_get_cache( AddressClipboard *clipBoard ) {
574 AddrSelectItem *item;
577 itemList = clipBoard->objectList;
579 item = itemList->data;
580 cache = addrindex_get_cache(
581 clipBoard->addressIndex, item->cacheID );
587 * Paste (copy) clipboard into address book.
588 * Enter: clipBoard Clipboard.
589 * book Target address book.
590 * folder Target folder where data is pasted, or null for root folder.
591 * Return: List of group or folder items added.
593 GList *addrclip_paste_copy(
594 AddressClipboard *clipBoard, AddressBookFile *book,
601 g_return_val_if_fail( clipBoard != NULL, NULL );
603 cache = book->addressCache;
604 if( folder == NULL ) folder = cache->rootFolder;
607 itemList = clipBoard->objectList;
608 folderGroup = addrclip_cache_add_folder(
609 cache, folder, itemList, clipBoard );
615 * Remove items that were cut from clipboard.
616 * Enter: clipBoard Clipboard.
618 void addrclip_delete_item( AddressClipboard *clipBoard ) {
619 AddrSelectItem *item;
621 AddressCache *cacheFrom;
624 /* If cutting within current cache, no deletion is necessary */
625 if( clipBoard->moveFlag ) return;
628 node = clipBoard->objectList;
631 node = g_list_next( node );
632 cacheFrom = addrindex_get_cache(
633 clipBoard->addressIndex, item->cacheID );
634 if( cacheFrom == NULL ) continue;
635 aio = addrcache_get_object( cacheFrom, item->uid );
637 if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
640 group = ( ItemGroup * ) aio;
641 group = addrcache_remove_group( cacheFrom, group );
643 addritem_free_item_group( group );
649 /* Remove persons and folders */
650 node = clipBoard->objectList;
653 node = g_list_next( node );
655 cacheFrom = addrindex_get_cache(
656 clipBoard->addressIndex, item->cacheID );
657 if( cacheFrom == NULL ) continue;
659 aio = addrcache_get_object( cacheFrom, item->uid );
661 if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) {
664 person = ( ItemPerson * ) aio;
665 person = addrcache_remove_person( cacheFrom, person );
667 addritem_free_item_person( person );
670 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) {
671 ItemFolder *itemFolder;
673 itemFolder = ( ItemFolder * ) aio;
674 itemFolder = addrcache_remove_folder_delete(
675 cacheFrom, itemFolder );
676 addritem_free_item_folder( itemFolder );
683 * Paste (move) clipboard into address book.
684 * Enter: clipBoard Clipboard.
685 * book Target address book.
686 * folder Target folder where data is pasted, or null for root folder.
687 * Return: List of group or folder items added.
689 GList *addrclip_paste_cut(
690 AddressClipboard *clipBoard, AddressBookFile *book,
693 AddressCache *cache, *cacheFrom;
697 g_return_val_if_fail( clipBoard != NULL, NULL );
699 cache = book->addressCache;
700 if( folder == NULL ) folder = cache->rootFolder;
703 clipBoard->moveFlag = FALSE;
704 cacheFrom = addrclip_list_get_cache( clipBoard );
705 if( cacheFrom && cacheFrom == cache ) {
706 /* Move items between folders in same book */
707 itemList = clipBoard->objectList;
708 folderGroup = addrclip_cache_move_items(
709 cache, folder, itemList, clipBoard );
710 clipBoard->moveFlag = TRUE;
713 /* Move items across address books */
714 itemList = clipBoard->objectList;
715 folderGroup = addrclip_cache_add_folder(
716 cache, folder, itemList, clipBoard );
723 * ============================================================================
724 * Paste address only.
725 * ============================================================================
729 * Copy email addresses from specified list.
730 * Enter: cache Address cache to paste into.
731 * target Person to receive email addresses.
732 * listEMail List of email addresses.
733 * Return: Number of addresses added.
735 static gint addrclip_person_add_email(
736 AddressCache *cache, ItemPerson *target, GList *listEMail )
741 /* Copy email addresses */
745 ItemEMail *email, *newEMail;
748 newEMail = addritem_copy_item_email( email );
749 addrcache_id_email( cache, newEMail );
750 addrcache_person_add_email( cache, target, newEMail );
751 node = g_list_next( node );
758 * Paste (copy) E-Mail addresses from clipboard into specified person.
759 * Enter: aio Address item to copy from.
760 * cache Target address cache.
761 * person Target person where data is pasted.
762 * Return: Number of EMail records added.
764 static gint addrclip_copy_email_to_person(
765 AddrItemObject *aio, AddressCache *cache, ItemPerson *person )
772 if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) {
773 ItemPerson *fromPerson;
775 fromPerson = ( ItemPerson * ) aio;
776 listEMail = fromPerson->listEMail;
777 cnt += addrclip_person_add_email(
778 cache, person, listEMail );
780 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) {
781 ItemEMail *email, *newEMail;
783 email = ( ItemEMail * ) aio;
784 newEMail = addritem_copy_item_email( email );
785 addrcache_id_email( cache, newEMail );
786 addrcache_person_add_email( cache, person, newEMail );
789 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
792 group = ( ItemGroup * ) aio;
793 listEMail = group->listEMail;
794 cnt += addrclip_person_add_email(
795 cache, person, listEMail );
797 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) {
799 AddrItemObject *item;
802 folder = ( ItemFolder * ) aio;
803 node = folder->listPerson;
806 node = g_list_next( node );
807 cnt += addrclip_copy_email_to_person( item, cache, person );
810 node = folder->listGroup;
813 node = g_list_next( node );
814 cnt += addrclip_copy_email_to_person( item, cache, person );
817 node = folder->listFolder;
820 node = g_list_next( node );
821 cnt += addrclip_copy_email_to_person( item, cache, person );
828 * Paste (copy) E-Mail addresses from clipboard into specified person.
829 * Enter: clipBoard Clipboard.
830 * cache Target address cache.
831 * person Target person where data is pasted.
832 * Return: Number of EMail records added.
834 static gint addrclip_copyto_person(
835 AddressClipboard *clipBoard, AddressCache *cache, ItemPerson *person )
841 node = clipBoard->objectList;
843 AddressCache *cacheFrom;
844 AddrSelectItem *item;
848 node = g_list_next( node );
849 cacheFrom = addrindex_get_cache(
850 clipBoard->addressIndex, item->cacheID );
851 if( cacheFrom == NULL ) continue;
852 aio = addrcache_get_object( cacheFrom, item->uid );
854 cnt += addrclip_copy_email_to_person( aio, cache, person );
861 * Paste (copy) E-Mail addresses from clipboard into specified person.
862 * Enter: clipBoard Clipboard.
863 * book Target address book.
864 * person Target person where data is pasted.
865 * Return: Number of EMail records added.
867 gint addrclip_paste_person_copy(
868 AddressClipboard *clipBoard, AddressBookFile *book,
875 g_return_val_if_fail( clipBoard != NULL, cnt );
877 cache = book->addressCache;
879 cnt = addrclip_copyto_person( clipBoard, cache, person );
885 * Move email addresses for specified person to target person.
886 * Enter: cache Address cache to paste into.
887 * fromPerson Person supplying email addresses.
888 * target Person to receive email addresses.
889 * Return: Number of addresses moved.
891 static gint addrclip_person_move_email(
892 AddressCache *cache, ItemPerson *fromPerson, ItemPerson *target )
898 while((node = fromPerson->listEMail) != NULL) {
902 addrcache_person_move_email( cache, email, target );
909 * Paste (cut) E-Mail addresses from clipboard into specified person.
910 * Enter: clipBoard Clipboard.
911 * cache Target address cache.
912 * person Target person where data is pasted.
913 * Return: Number of EMail records added.
915 static gint addrclip_paste_person_move(
916 AddressClipboard *clipBoard, AddressCache *cache, ItemPerson *person )
919 AddressCache *cacheFrom;
920 AddrSelectItem *item;
926 node = clipBoard->objectList;
929 node = g_list_next( node );
930 cacheFrom = addrindex_get_cache(
931 clipBoard->addressIndex, item->cacheID );
932 if( cacheFrom == NULL ) continue;
933 aio = addrcache_get_object( cacheFrom, item->uid );
935 if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) {
936 ItemPerson *fromPerson;
938 fromPerson = ( ItemPerson * ) aio;
939 cnt += addrclip_person_move_email(
940 cache, fromPerson, person );
942 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) {
945 email = ( ItemEMail * ) aio;
946 addrcache_person_move_email(
947 cache, email, person );
950 else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) {
953 group = ( ItemGroup * ) aio;
954 listEMail = group->listEMail;
955 cnt += addrclip_person_add_email(
956 cache, person, listEMail );
964 * Paste (cut) E-Mail addresses from clipboard into specified person.
965 * Enter: clipBoard Clipboard.
966 * book Target address book.
967 * person Target person where data is pasted.
968 * Return: Number of EMail records added.
970 gint addrclip_paste_person_cut(
971 AddressClipboard *clipBoard, AddressBookFile *book,
975 AddressCache *cache, *cacheFrom;
978 g_return_val_if_fail( clipBoard != NULL, cnt );
980 cache = book->addressCache;
982 clipBoard->moveFlag = FALSE;
983 cacheFrom = addrclip_list_get_cache( clipBoard );
984 if( cacheFrom && cacheFrom == cache ) {
985 /* Move items between folders in same book */
986 cnt = addrclip_paste_person_move(
987 clipBoard, cache, person );
988 clipBoard->moveFlag = TRUE;
991 /* Move items across address books */
992 cnt = addrclip_copyto_person(
993 clipBoard, cache, person );
1000 * Remove address items that were cut from clipboard. Note that that only
1001 * E-Mail items are actually deleted. Any Person items will not be deleted
1002 * (not even E-Mail items that owned by a person). Any Group or Folder
1003 * items will *NOT* be deleted.
1004 * Enter: clipBoard Clipboard.
1006 void addrclip_delete_address( AddressClipboard *clipBoard ) {
1007 AddrSelectItem *item;
1008 AddrItemObject *aio;
1009 AddressCache *cacheFrom;
1012 /* If cutting within current cache, no deletion is necessary */
1013 if( clipBoard->moveFlag ) return;
1016 node = clipBoard->objectList;
1019 node = g_list_next( node );
1020 cacheFrom = addrindex_get_cache(
1021 clipBoard->addressIndex, item->cacheID );
1022 if( cacheFrom == NULL ) continue;
1023 aio = addrcache_get_object( cacheFrom, item->uid );
1025 if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) {
1029 email = ( ItemEMail * ) aio;
1030 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
1031 email = addrcache_person_remove_email(
1032 cacheFrom, person, email );
1034 addritem_free_item_email( email );