From ec0cdacb29f909f4e4060c1179f54e26b824201d Mon Sep 17 00:00:00 2001 From: Match Grun Date: Sat, 19 Jan 2002 06:05:08 +0000 Subject: [PATCH] addressbook cut, copy and paste --- src/adbookbase.h | 51 +++ src/addrclip.c | 1124 ++++++++++++++++++++++++++++++++++++++++++++++ src/addrclip.h | 79 ++++ src/addrselect.c | 400 +++++++++++++++++ src/addrselect.h | 75 ++++ 5 files changed, 1729 insertions(+) create mode 100644 src/adbookbase.h create mode 100644 src/addrclip.c create mode 100644 src/addrclip.h create mode 100644 src/addrselect.c create mode 100644 src/addrselect.h diff --git a/src/adbookbase.h b/src/adbookbase.h new file mode 100644 index 000000000..87a602fbe --- /dev/null +++ b/src/adbookbase.h @@ -0,0 +1,51 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 2002 Match Grun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Address book base data. + */ + +#ifndef __ADBOOKBASE_H__ +#define __ADBOOKBASE_H__ + +#include + +#include "addrcache.h" + +typedef enum { + ADBOOKTYPE_NONE, + ADBOOKTYPE_BOOK, + ADBOOKTYPE_VCARD, + ADBOOKTYPE_JPILOT, + ADBOOKTYPE_LDAP +} AddressBookType; + +/* + * All address book interfaces should implement the following data + * structure at the start of their data structure. + */ +typedef struct _AddrBook_Base AddrBookBase; +struct _AddrBook_Base { + AddressBookType type; + AddressCache *addressCache; +}; + +#endif /* __ADBOOKBASE_H__ */ + + diff --git a/src/addrclip.c b/src/addrclip.c new file mode 100644 index 000000000..bbf4fb099 --- /dev/null +++ b/src/addrclip.c @@ -0,0 +1,1124 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 2002 Match Grun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Contains address clipboard objects and related functions. The address + * clipboard is implemented as a linked list of AddrSelectItem objects. + * The address clipboard offers two groups of functions: + * + * a) Cut, copy and paste of address item objects (ItemFolder, ItemGroup, + * ItemPerson) into a folder. With this method, we can paste ItemPerson + * objects but not unattached ItemEMail objects into a folder. ItemEMail + * objects are owned by an ItemPerson object. Any ItemEMail objects that + * appear in the clipboard are ignored. If an ItemPerson object is found, + * the ItemPerson *and* ItemEMail objects that it owns are pasted. + * + * b) Copy and paste of ItemEMail address objects only into (below) + * ItemPerson objects. All ItemEMail objects which are owned by + * ItemPerson and referenced by ItemGroup objects are pasted. Any + * ItemFolder objects in the clipboard, and any objects owned by + * ItemFolder objects are ignored. + * + * Objects are inserted to the clipboard by copying (cloning) + * AddrSelectItem objects from the address books selection list to the + * clipboard's internal selection list. The clipboard makes use of the + * object id's and address cache id's to access objects contained in + * the address cache. If the referenced object is not found, it is + * ignored. This eliminates the need to delete pointers in multiple + * linked lists when an address object is deleted. + * + */ + +#include +#include + +#include "addritem.h" +#include "addrcache.h" +#include "addrbook.h" +#include "addrselect.h" +#include "addrindex.h" +#include "addrclip.h" + +/* +* Create a clipboard. +*/ +AddressClipboard *addrclip_create( void ) { + AddressClipboard *clipBoard; + + clipBoard = g_new0( AddressClipboard, 1 ); + clipBoard->cutFlag = FALSE; + clipBoard->objectList = NULL; + return clipBoard; +} + +/* +* Clear clipboard. +*/ +void addrclip_clear( AddressClipboard *clipBoard ) { + GList *node; + AddrSelectItem *item; + + g_return_if_fail( clipBoard != NULL ); + node = clipBoard->objectList; + while( node ) { + item = node->data; + addrselect_item_free( item ); + node->data = NULL; + node = g_list_next( node ); + } + g_list_free( clipBoard->objectList ); + clipBoard->objectList = NULL; +} + +/* +* Free up a clipboard. +*/ +void addrclip_free( AddressClipboard *clipBoard ) { + g_return_if_fail( clipBoard != NULL ); + + addrclip_clear( clipBoard ); + clipBoard->cutFlag = FALSE; +} + +/* +* Setup reference to address index. +*/ +void addrclip_set_index( + AddressClipboard *clipBoard, AddressIndex *addrIndex ) +{ + g_return_if_fail( clipBoard != NULL ); + g_return_if_fail( addrIndex != NULL ); + clipBoard->addressIndex = addrIndex; +} + +/* +* Test whether clipboard is empty. +* Enter: clipBoard Clipboard. +* Return: TRUE if clipboard is empty. +*/ +gboolean addrclip_is_empty( AddressClipboard *clipBoard ) { + gboolean retVal = TRUE; + + if( clipBoard ) { + if( clipBoard->objectList ) retVal = FALSE; + } + return retVal; +} + +/* +* Add a list of address selection objects to clipbard. +* Enter: clipBoard Clipboard. +* addrList List of address selection objects. +*/ +void addrclip_add( AddressClipboard *clipBoard, AddrSelectList *asl ) { + GList *node; + + g_return_if_fail( clipBoard != NULL ); + g_return_if_fail( asl != NULL ); + node = asl->listSelect; + while( node ) { + AddrSelectItem *item, *itemCopy; + + item = node->data; + itemCopy = addrselect_item_copy( item ); + clipBoard->objectList = + g_list_append( clipBoard->objectList, itemCopy ); + node = g_list_next( node ); + } +} + +/* +* Add a single address selection objects to clipbard. +* Enter: clipBoard Clipboard. +* item Address selection object. +*/ +void addrclip_add_item( + AddressClipboard *clipBoard, AddrSelectItem *item ) +{ + g_return_if_fail( clipBoard != NULL ); + if( item ) { + AddrSelectItem *itemCopy; + + itemCopy = addrselect_item_copy( item ); + clipBoard->objectList = + g_list_append( clipBoard->objectList, itemCopy ); + } +} + +static void addrclip_print( AddrSelectItem *item, FILE *stream ) { + fprintf( stream, "Select Record\n" ); + fprintf( stream, "obj type: %d\n", item->objectType ); + fprintf( stream, " uid: %s\n", item->uid ); + fprintf( stream, "---\n" ); +} + +/* +* Show clipboard contents. +* Enter: clipBoard Clipboard. +* stream Output stream. +*/ +void addrclip_list_show( AddressClipboard *clipBoard, FILE *stream ) { + GList *node; + AddrItemObject *aio; + AddressCache *cache; + + g_return_if_fail( clipBoard != NULL ); + fprintf( stream, "clipboard show selection...>>>\n" ); + node = clipBoard->objectList; + while( node != NULL ) { + AddrSelectItem *item; + + item = node->data; + addrselect_item_print( item, stream ); + + cache = addrindex_get_cache( clipBoard->addressIndex, item->cacheID ); + aio = addrcache_get_object( cache, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + addritem_print_item_person( ( ItemPerson * ) aio, stream ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) { + addritem_print_item_email( ( ItemEMail * ) aio, stream ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + addritem_print_item_group( ( ItemGroup * ) aio, stream ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) { + addritem_print_item_folder( ( ItemFolder * ) aio, stream ); + } + } + node = g_list_next( node ); + } + fprintf( stream, "clipboard show selection...<<<\n" ); +} + +/* Pasted address pointers */ +typedef struct _AddrClip_EMail_ AddrClip_EMail; +struct _AddrClip_EMail_ { + ItemEMail *original; + ItemEMail *copy; +}; + +/* + * Free up specified list of addresses. + */ +static void addrclip_free_copy_list( GList *copyList ) { + GList *node; + + node = copyList; + while( node ) { + AddrClip_EMail *em = node->data; + em->original = NULL; + em->copy = NULL; + g_free( em ); + em = NULL; + node = g_list_next( node ); + } +} + +/* + * Paste person into cache. + * Enter: cache Address cache to paste into. + * folder Folder to store + * person Person to paste. + * copyLIst List of email addresses pasted. + * Return: Update list of email addresses pasted. + */ +static GList *addrclip_cache_add_person( + AddressCache *cache, ItemFolder *folder, ItemPerson *person, + GList *copyList ) +{ + ItemPerson *newPerson; + ItemEMail *email; + ItemEMail *newEMail; + UserAttribute *attrib; + UserAttribute *newAttrib; + GList *node; + AddrClip_EMail *em; + + /* Copy person */ + newPerson = addritem_copy_item_person( person ); + addrcache_id_person( cache, newPerson ); + addrcache_folder_add_person( cache, folder, newPerson ); + + /* Copy email addresses */ + node = person->listEMail; + while( node ) { + email = node->data; + newEMail = addritem_copy_item_email( email ); + addrcache_id_email( cache, newEMail ); + addrcache_person_add_email( cache, newPerson, newEMail ); + node = g_list_next( node ); + + /* Take a copy of the original */ + em = g_new0( AddrClip_EMail, 1 ); + em->original = email; + em->copy = newEMail; + copyList = g_list_append( copyList, em ); + } + + /* Copy user attributes */ + node = person->listAttrib; + while( node ) { + attrib = node->data; + newAttrib = addritem_copy_attribute( attrib ); + addrcache_id_attribute( cache, newAttrib ); + addritem_person_add_attribute( newPerson, newAttrib ); + node = g_list_next( node ); + } + + return copyList; +} + +/* + * Paste unattached email into cache. + * Enter: cache Address cache to paste into. + * folder Folder to store + * email EMail to add. + * copyList List of email addresses pasted. + * Return: Update list of email addresses pasted. + */ +static GList *addrclip_cache_add_email( + AddressCache *cache, ItemFolder *folder, ItemEMail *email, + GList *copyList ) +{ + ItemPerson *newPerson; + ItemEMail *newEMail; + AddrClip_EMail *em; + + /* Create a person */ + newPerson = addritem_create_item_person(); + addritem_person_set_common_name( newPerson, "" ); + addrcache_id_person( cache, newPerson ); + addrcache_folder_add_person( cache, folder, newPerson ); + + /* Copy email addresses */ + newEMail = addritem_copy_item_email( email ); + addrcache_id_email( cache, newEMail ); + addrcache_person_add_email( cache, newPerson, newEMail ); + + /* Take a copy of the original */ + em = g_new0( AddrClip_EMail, 1 ); + em->original = email; + em->copy = newEMail; + copyList = g_list_append( copyList, em ); + + return copyList; +} + +/* + * Test whether specified E-Mail address object is already in clipboard and + * owned by an ItemPerson objects. + * Enter: email E-Mail to test. + * Return: TRUE if duplicate found. + */ +static gboolean addrclip_test_email( + AddressClipboard *clipBoard, ItemEMail *testEMail ) +{ + ItemPerson *person; + ItemEMail *email; + GList *node, *nodeMail; + AddrSelectItem *item; + AddrItemObject *aio; + AddressCache *cache; + + node = clipBoard->objectList; + while( node ) { + item = node->data; + cache = addrindex_get_cache( clipBoard->addressIndex, item->cacheID ); + aio = addrcache_get_object( cache, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + person = ( ItemPerson * ) aio; + nodeMail = person->listEMail; + while( nodeMail ) { + email = nodeMail->data; + if( email == testEMail ) return TRUE; + nodeMail = g_list_next( nodeMail ); + } + } + } + node = g_list_next( node ); + } + return FALSE; +} + +/* + * Search for new email record in copied email list. + * Enter: copyList List of copied email address mappings. + * emailOrig Original email item. + * Return: New email item corresponding to original item if pasted. Or NULL if + * not found. + */ +static ItemEMail *addrclip_find_copied_email( + GList *copyList, ItemEMail *emailOrig ) +{ + ItemEMail *emailCopy; + GList *node; + AddrClip_EMail *em; + + emailCopy = NULL; + node = copyList; + while( node ) { + em = node->data; + if( em->original == emailOrig ) { + emailCopy = em->copy; + break; + } + node = g_list_next( node ); + } + return emailCopy; +} + +/* + * Paste group into cache. + * Enter: cache Address cache to paste into. + * folder Folder to store + * group Group to paste. + * copyList List of email addresses pasted. + * Return: Group added. + */ +static ItemGroup *addrclip_cache_add_group( + AddressCache *cache, ItemFolder *folder, ItemGroup *group, + GList *copyList ) +{ + ItemGroup *newGroup; + ItemEMail *emailOrig, *emailCopy; + GList *node; + + /* Copy group */ + newGroup = addritem_copy_item_group( group ); + addrcache_id_group( cache, newGroup ); + addrcache_folder_add_group( cache, folder, newGroup ); + + /* Add references of copied addresses to group */ + node = group->listEMail; + while( node ) { + emailOrig = ( ItemEMail * ) node->data; + emailCopy = addrclip_find_copied_email( copyList, emailOrig ); + if( emailCopy ) { + addrcache_group_add_email( cache, newGroup, emailCopy ); + } + node = g_list_next( node ); + } + return newGroup; +} + +/* + * Copy specified folder into cache. Note this functions uses pointers to + * folders to copy from. There should not be any deleted items referenced + * by these pointers!!! + * Enter: cache Address cache to copy into. + * targetFolder Target folder. + * folder Folder to copy. + * Return: Folder added. + */ +static ItemFolder *addrclip_cache_copy_folder( + AddressCache *cache, ItemFolder *targetFolder, ItemFolder *folder ) +{ + ItemFolder *newFolder; + ItemGroup *newGroup; + GList *node; + GList *copyList; + + /* Copy folder */ + newFolder = addritem_copy_item_folder( folder ); + addrcache_id_folder( cache, newFolder ); + addrcache_folder_add_folder( cache, targetFolder, newFolder ); + + /* Copy people to new folder */ + copyList = NULL; + node = folder->listPerson; + while( node ) { + ItemPerson *item = node->data; + node = g_list_next( node ); + copyList = addrclip_cache_add_person( + cache, newFolder, item, copyList ); + } + + /* Copy groups to new folder */ + node = folder->listGroup; + while( node ) { + ItemGroup *item = node->data; + node = g_list_next( node ); + newGroup = addrclip_cache_add_group( + cache, newFolder, item, copyList ); + } + g_list_free( copyList ); + + /* Copy folders to new folder (recursive) */ + node = folder->listFolder; + while( node ) { + ItemFolder *item = node->data; + node = g_list_next( node ); + addrclip_cache_copy_folder( cache, newFolder, item ); + } + + return newFolder; +} + +/* +* Paste item list into address book. +* Enter: cache Target address cache. +* folder Target folder where data is pasted. +* itemList List of items to paste. +* clipBoard Clipboard. +* Return: List of group or folder items added. +*/ +static GList *addrclip_cache_add_folder( + AddressCache *cache, ItemFolder *folder, GList *itemList, + AddressClipboard *clipBoard ) +{ + GList *folderGroup; + GList *node; + AddrSelectItem *item; + AddrItemObject *aio; + AddressCache *cacheFrom; + gboolean haveGroups; + GList *copyList; + + folderGroup = NULL; + copyList = NULL; + haveGroups = FALSE; + node = itemList; + while( node ) { + item = node->data; + node = g_list_next( node ); + + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + if( item->uid ) { + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + ItemPerson *person; + + person = ( ItemPerson * ) aio; + copyList = addrclip_cache_add_person( + cache, folder, person, copyList ); + } + /* + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) { + } + */ + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + haveGroups = TRUE; /* Process later */ + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) { + ItemFolder *itemFolder, *newFolder; + + itemFolder = ( ItemFolder * ) aio; + newFolder = addrclip_cache_copy_folder( + cache, folder, itemFolder ); + folderGroup = + g_list_append( folderGroup, newFolder ); + } + } + } + else { + if( item->objectType == ITEMTYPE_DATASOURCE ) { + /* + * Must be an address book - allow copy only if + * copying from a different cache. + */ + if( cache != cacheFrom ) { + ItemFolder *itemFolder, *newFolder; + + itemFolder = cacheFrom->rootFolder; + newFolder = addrclip_cache_copy_folder( + cache, folder, itemFolder ); + addritem_folder_set_name( newFolder, + addrcache_get_name( cacheFrom ) ); + folderGroup = + g_list_append( folderGroup, newFolder ); + } + } + } + } + + /* Finally add any groups */ + if( haveGroups ) { + node = itemList; + while( node ) { + item = node->data; + node = g_list_next( node ); + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + ItemGroup *group, *newGroup; + + group = ( ItemGroup * ) aio; + newGroup = addrclip_cache_add_group( + cache, folder, group, copyList ); + folderGroup = + g_list_append( folderGroup, newGroup ); + } + } + } + } + + /* Free up stuff */ + addrclip_free_copy_list( copyList ); + g_list_free( copyList ); + copyList = NULL; + + return folderGroup; +} + +/* +* Move items in list into new folder +* Enter: cache Target address cache. +* targetFolder Target folder where data is pasted. +* itemList List of items to paste. +* clipBoard Clipboard. +* Return: List of group or folder items added. +*/ +static GList *addrclip_cache_move_items( + AddressCache *cache, ItemFolder *targetFolder, GList *itemList, + AddressClipboard *clipBoard ) +{ + GList *folderGroup; + GList *node; + AddrSelectItem *item; + AddrItemObject *aio; + AddressCache *cacheFrom; + + folderGroup = NULL; + node = itemList; + while( node ) { + item = node->data; + node = g_list_next( node ); + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + ItemPerson *person; + + person = ( ItemPerson * ) aio; + addrcache_folder_move_person( + cache, person, targetFolder ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + ItemGroup *group; + + group = ( ItemGroup * ) aio; + addrcache_folder_move_group( + cache, group, targetFolder ); + folderGroup = g_list_append( folderGroup, group ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) { + ItemFolder *folder; + + folder = ( ItemFolder * ) aio; + addrcache_folder_move_folder( + cache, folder, targetFolder ); + folderGroup = + g_list_append( folderGroup, folder ); + } + } + } + return folderGroup; +} + +/* +* Get address cache of first item in list. This assumes that all items in +* the clipboard are located in the same cache. +* Enter: clipBoard Clipboard. +* Return: List of group or folder items added. +*/ +static AddressCache *addrclip_list_get_cache( AddressClipboard *clipBoard ) { + AddressCache *cache; + GList *itemList; + AddrSelectItem *item; + + cache = NULL; + itemList = clipBoard->objectList; + if( itemList ) { + item = itemList->data; + cache = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + } + return cache; +} + +/* +* Paste (copy) clipboard into address book. +* Enter: clipBoard Clipboard. +* book Target address book. +* folder Target folder where data is pasted, or null for root folder. +* Return: List of group or folder items added. +*/ +GList *addrclip_paste_copy( + AddressClipboard *clipBoard, AddressBookFile *book, + ItemFolder *folder ) +{ + AddressCache *cache; + GList *itemList; + GList *folderGroup; + + g_return_val_if_fail( clipBoard != NULL, NULL ); + + cache = book->addressCache; + if( folder == NULL ) folder = cache->rootFolder; + + folderGroup = NULL; + itemList = clipBoard->objectList; + folderGroup = addrclip_cache_add_folder( + cache, folder, itemList, clipBoard ); + + return folderGroup; +} + +/* +* Remove items that were cut from clipboard. +* Enter: clipBoard Clipboard. +*/ +void addrclip_delete_item( AddressClipboard *clipBoard ) { + AddrSelectItem *item; + AddrItemObject *aio; + AddressCache *cacheFrom; + GList *node; + + /* If cutting within current cache, no deletion is necessary */ + if( clipBoard->moveFlag ) return; + + /* Remove groups */ + node = clipBoard->objectList; + while( node ) { + item = node->data; + node = g_list_next( node ); + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + ItemGroup *group; + + group = ( ItemGroup * ) aio; + group = addrcache_remove_group( cacheFrom, group ); + if( group ) { + addritem_free_item_group( group ); + } + } + } + } + + /* Remove persons and folders */ + node = clipBoard->objectList; + while( node ) { + item = node->data; + node = g_list_next( node ); + + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + ItemPerson *person; + + person = ( ItemPerson * ) aio; + person = addrcache_remove_person( cacheFrom, person ); + if( person ) { + addritem_free_item_person( person ); + } + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) { + ItemFolder *itemFolder; + + itemFolder = ( ItemFolder * ) aio; + itemFolder = addrcache_remove_folder_delete( + cacheFrom, itemFolder ); + addritem_free_item_folder( itemFolder ); + } + } + } +} + +/* +* Paste (move) clipboard into address book. +* Enter: clipBoard Clipboard. +* book Target address book. +* folder Target folder where data is pasted, or null for root folder. +* Return: List of group or folder items added. +*/ +GList *addrclip_paste_cut( + AddressClipboard *clipBoard, AddressBookFile *book, + ItemFolder *folder ) +{ + AddressCache *cache, *cacheFrom; + GList *itemList; + GList *folderGroup; + + g_return_val_if_fail( clipBoard != NULL, NULL ); + + cache = book->addressCache; + if( folder == NULL ) folder = cache->rootFolder; + + folderGroup = NULL; + clipBoard->moveFlag = FALSE; + cacheFrom = addrclip_list_get_cache( clipBoard ); + if( cacheFrom && cacheFrom == cache ) { + /* Move items between folders in same book */ + itemList = clipBoard->objectList; + folderGroup = addrclip_cache_move_items( + cache, folder, itemList, clipBoard ); + clipBoard->moveFlag = TRUE; + } + else { + /* Move items across address books */ + itemList = clipBoard->objectList; + folderGroup = addrclip_cache_add_folder( + cache, folder, itemList, clipBoard ); + } + + return folderGroup; +} + +/* + * ============================================================================ + * Paste address only. + * ============================================================================ + */ + +/* + * Copy email addresses from specified list. + * Enter: cache Address cache to paste into. + * target Person to receive email addresses. + * listEMail List of email addresses. + * Return: Number of addresses added. + */ +static gint addrclip_person_add_email( + AddressCache *cache, ItemPerson *target, GList *listEMail ) +{ + gint cnt; + GList *node; + + /* Copy email addresses */ + cnt = 0; + node = listEMail; + while( node ) { + ItemEMail *email, *newEMail; + + email = node->data; + newEMail = addritem_copy_item_email( email ); + addrcache_id_email( cache, newEMail ); + addrcache_person_add_email( cache, target, newEMail ); + node = g_list_next( node ); + cnt++; + } + return cnt; +} + +/* +* Paste (copy) E-Mail addresses from clipboard into specified person. +* Enter: aio Address item to copy from. +* cache Target address cache. +* person Target person where data is pasted. +* Return: Number of EMail records added. +*/ +static gint addrclip_copy_email_to_person( + AddrItemObject *aio, AddressCache *cache, ItemPerson *person ) +{ + gint cnt; + GList *listEMail; + + cnt = 0; + + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + ItemPerson *fromPerson; + + fromPerson = ( ItemPerson * ) aio; + listEMail = fromPerson->listEMail; + cnt += addrclip_person_add_email( + cache, person, listEMail ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) { + ItemEMail *email, *newEMail; + + email = ( ItemEMail * ) aio; + newEMail = addritem_copy_item_email( email ); + addrcache_id_email( cache, newEMail ); + addrcache_person_add_email( cache, person, newEMail ); + cnt++; + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + ItemGroup *group; + + group = ( ItemGroup * ) aio; + listEMail = group->listEMail; + cnt += addrclip_person_add_email( + cache, person, listEMail ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_FOLDER ) { + ItemFolder *folder; + AddrItemObject *item; + GList *node; + + folder = ( ItemFolder * ) aio; + node = folder->listPerson; + while( node ) { + item = node->data; + node = g_list_next( node ); + cnt += addrclip_copy_email_to_person( item, cache, person ); + } + + node = folder->listGroup; + while( node ) { + item = node->data; + node = g_list_next( node ); + cnt += addrclip_copy_email_to_person( item, cache, person ); + } + + node = folder->listFolder; + while( node ) { + item = node->data; + node = g_list_next( node ); + cnt += addrclip_copy_email_to_person( item, cache, person ); + } + } + return cnt; +} + +/* +* Paste (copy) E-Mail addresses from clipboard into specified person. +* Enter: clipBoard Clipboard. +* cache Target address cache. +* person Target person where data is pasted. +* Return: Number of EMail records added. +*/ +static gint addrclip_copyto_person( + AddressClipboard *clipBoard, AddressCache *cache, ItemPerson *person ) +{ + gint cnt; + GList *node; + + cnt = 0; + node = clipBoard->objectList; + while( node ) { + AddressCache *cacheFrom; + AddrSelectItem *item; + AddrItemObject *aio; + + item = node->data; + node = g_list_next( node ); + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + cnt += addrclip_copy_email_to_person( aio, cache, person ); + } + } + return cnt; +} + +/* +* Paste (copy) E-Mail addresses from clipboard into specified person. +* Enter: clipBoard Clipboard. +* book Target address book. +* person Target person where data is pasted. +* Return: Number of EMail records added. +*/ +gint addrclip_paste_person_copy( + AddressClipboard *clipBoard, AddressBookFile *book, + ItemPerson *person ) +{ + gint cnt; + AddressCache *cache; + + cnt = 0; + g_return_val_if_fail( clipBoard != NULL, cnt ); + + cache = book->addressCache; + if( person ) { + cnt = addrclip_copyto_person( clipBoard, cache, person ); + } + return cnt; +} + +/* + * Move email addresses for specified person to target person. + * Enter: cache Address cache to paste into. + * fromPerson Person supplying email addresses. + * target Person to receive email addresses. + * Return: Number of addresses moved. + */ +static gint addrclip_person_move_email( + AddressCache *cache, ItemPerson *fromPerson, ItemPerson *target ) +{ + gint cnt; + GList *node; + + cnt = 0; + while( node = fromPerson->listEMail ) { + ItemEMail *email; + + email = node->data; + addrcache_person_move_email( cache, email, target ); + cnt++; + } + return cnt; +} + +/* +* Paste (cut) E-Mail addresses from clipboard into specified person. +* Enter: clipBoard Clipboard. +* cache Target address cache. +* person Target person where data is pasted. +* Return: Number of EMail records added. +*/ +static gint addrclip_paste_person_move( + AddressClipboard *clipBoard, AddressCache *cache, ItemPerson *person ) +{ + gint cnt; + AddressCache *cacheFrom; + AddrSelectItem *item; + AddrItemObject *aio; + GList *node; + GList *listEMail; + + cnt = 0; + node = clipBoard->objectList; + while( node ) { + item = node->data; + node = g_list_next( node ); + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_PERSON ) { + ItemPerson *fromPerson; + + fromPerson = ( ItemPerson * ) aio; + cnt += addrclip_person_move_email( + cache, fromPerson, person ); + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) { + ItemEMail *email; + + email = ( ItemEMail * ) aio; + addrcache_person_move_email( + cache, email, person ); + cnt++; + } + else if( ADDRITEM_TYPE(aio) == ITEMTYPE_GROUP ) { + ItemGroup *group; + + group = ( ItemGroup * ) aio; + listEMail = group->listEMail; + cnt += addrclip_person_add_email( + cache, person, listEMail ); + } + } + } + return cnt; +} + +/* +* Paste (cut) E-Mail addresses from clipboard into specified person. +* Enter: clipBoard Clipboard. +* book Target address book. +* person Target person where data is pasted. +* Return: Number of EMail records added. +*/ +gint addrclip_paste_person_cut( + AddressClipboard *clipBoard, AddressBookFile *book, + ItemPerson *person ) +{ + gint cnt; + AddressCache *cache, *cacheFrom; + + cnt = 0; + g_return_val_if_fail( clipBoard != NULL, cnt ); + + cache = book->addressCache; + if( person ) { + clipBoard->moveFlag = FALSE; + cacheFrom = addrclip_list_get_cache( clipBoard ); + if( cacheFrom && cacheFrom == cache ) { + /* Move items between folders in same book */ + cnt = addrclip_paste_person_move( + clipBoard, cache, person ); + clipBoard->moveFlag = TRUE; + } + else { + /* Move items across address books */ + cnt = addrclip_copyto_person( + clipBoard, cache, person ); + } + } + return cnt; +} + +/* +* Remove address items that were cut from clipboard. Note that that only +* E-Mail items are actually deleted. Any Person items will not be deleted +* (not even E-Mail items that owned by a person). Any Group or Folder +* items will *NOT* be deleted. +* Enter: clipBoard Clipboard. +*/ +void addrclip_delete_address( AddressClipboard *clipBoard ) { + AddrSelectItem *item; + AddrItemObject *aio; + AddressCache *cacheFrom; + GList *node; + + /* If cutting within current cache, no deletion is necessary */ + if( clipBoard->moveFlag ) return; + + /* Remove groups */ + node = clipBoard->objectList; + while( node ) { + item = node->data; + node = g_list_next( node ); + cacheFrom = addrindex_get_cache( + clipBoard->addressIndex, item->cacheID ); + if( cacheFrom == NULL ) continue; + aio = addrcache_get_object( cacheFrom, item->uid ); + if( aio ) { + if( ADDRITEM_TYPE(aio) == ITEMTYPE_EMAIL ) { + ItemEMail *email; + ItemPerson *person; + + email = ( ItemEMail * ) aio; + person = ( ItemPerson * ) ADDRITEM_PARENT(email); + email = addrcache_person_remove_email( + cacheFrom, person, email ); + if( email ) { + addritem_free_item_email( email ); + } + } + } + } +} + +/* +* End of Source. +*/ + diff --git a/src/addrclip.h b/src/addrclip.h new file mode 100644 index 000000000..05afec4b3 --- /dev/null +++ b/src/addrclip.h @@ -0,0 +1,79 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 2002 Match Grun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Address clip board selection. + */ + +#ifndef __ADDRESS_CLIP_H__ +#define __ADDRESS_CLIP_H__ + +#include +#include + +#include "addrindex.h" +#include "addrselect.h" + +/* +* Selection data. +*/ +typedef struct _AddressClipboard_ AddressClipboard; +struct _AddressClipboard_ { + gboolean cutFlag; /* Indicates cut/copy operation */ + gboolean moveFlag; /* Internal move indicator for cut */ + AddressIndex *addressIndex; /* Reference to address index */ + GList *objectList; /* List of objects in clipboard */ +}; + +/* +* Function prototypes. +*/ +AddressClipboard *addrclip_create ( void ); +void addrclip_clear ( AddressClipboard *clipBoard ); +void addrclip_free ( AddressClipboard *clipBoard ); +void addrclip_set_index ( AddressClipboard *clipBoard, + AddressIndex *addrIndex ); +void addrclip_add ( AddressClipboard *clipBoard, + AddrSelectList *asl ); +/* +void addrclip_add ( AddressClipboard *clipBoard, + GList *addrList ); +*/ +void addrclip_add_item ( AddressClipboard *clipBoard, + AddrSelectItem *item ); +gboolean addrclip_is_empty ( AddressClipboard *clipBoard ); +void addrclip_list_show ( AddressClipboard *clipBoard, + FILE *stream ); +void addrclip_delete_item ( AddressClipboard *clipBoard ); +GList *addrclip_paste_copy ( AddressClipboard *clipBoard, + AddressBookFile *book, + ItemFolder *folder ); +GList *addrclip_paste_cut ( AddressClipboard *clipBoard, + AddressBookFile *book, + ItemFolder *folder ); +void addrclip_delete_address ( AddressClipboard *clipBoard ); +gint addrclip_paste_person_copy ( AddressClipboard *clipBoard, + AddressBookFile *book, + ItemPerson *person ); +gint addrclip_paste_person_cut ( AddressClipboard *clipBoard, + AddressBookFile *book, + ItemPerson *person ); + +#endif /* __ADDRRESS_CLIP_H__ */ + diff --git a/src/addrselect.c b/src/addrselect.c new file mode 100644 index 000000000..d867d7851 --- /dev/null +++ b/src/addrselect.c @@ -0,0 +1,400 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 2002 Match Grun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Address list item selection objects. + */ + +#include +#include + +#include "addritem.h" +#include "addrselect.h" +#include "addressitem.h" +#include "mgutils.h" + +/* +* Create a selection record from an address cache item. +* Enter: aio Item object. +*/ +AddrSelectItem *addrselect_create_item( AddrItemObject *aio ) { + AddrSelectItem *item = NULL; + + if( aio ) { + item = g_new0( AddrSelectItem, 1 ); + item->objectType = aio->type; + item->addressItem = aio; + item->uid = g_strdup( aio->uid ); + item->cacheID = NULL; + } + return item; +} + +/* +* Create a selection record from an address object (in tree node). +* Enter: obj Address object. +*/ +AddrSelectItem *addrselect_create_node( AddressObject *obj ) { + AddrSelectItem *item = NULL; + + if( obj ) { + item = g_new0( AddrSelectItem, 1 ); + item->objectType = addressbook_type2item( obj->type ); + item->addressItem = NULL; + item->uid = NULL; + item->cacheID = NULL; + } + return item; +} + +/* +* Create a copy of a selection record. +* Enter: item Address entry to copy. +*/ +AddrSelectItem *addrselect_item_copy( AddrSelectItem *item ) { + AddrSelectItem *copy = NULL; + + if( item ) { + copy = g_new0( AddrSelectItem, 1 ); + copy->objectType = item->objectType; + copy->addressItem = item->addressItem; + copy->uid = g_strdup( item->uid ); + copy->cacheID = g_strdup( item->cacheID ); + } + return copy; +} + +/* +* Free selection record. +*/ +void addrselect_item_free( AddrSelectItem *item ) { + if( item ) { + g_free( item->uid ); + g_free( item->cacheID ); + item->objectType = ITEMTYPE_NONE; + item->addressItem = NULL; + item->uid = NULL; + item->cacheID = NULL; + } + g_free( item ); +} + +/* +* Properties. +*/ +void addrselect_set_cache_id( AddrSelectItem *item, const gchar *value ) { + g_return_if_fail( item != NULL ); + item->cacheID = mgu_replace_string( item->cacheID, value ); +} + +void addrselect_item_print( AddrSelectItem *item, FILE *stream ) { + fprintf( stream, "Select Record\n" ); + fprintf( stream, "obj type: %d\n", item->objectType ); + fprintf( stream, " uid: %s\n", item->uid ); + fprintf( stream, "cache id: %s\n", item->cacheID ); + fprintf( stream, "---\n" ); +} + +/* +* Create a new selection. +* Return: Initialized object. +*/ +AddrSelectList *addrselect_list_create() { + AddrSelectList *asl; + + asl = g_new0( AddrSelectList, 1 ); + asl->listSelect = NULL; + return asl; +} + +/* +* Clear list of selection records. +* Enter: asl List to process. +*/ +void addrselect_list_clear( AddrSelectList *asl ) { + GList *node; + + g_return_if_fail( asl != NULL ); + node = asl->listSelect; + while( node ) { + AddrSelectItem *item; + + item = node->data; + addrselect_item_free( item ); + node->data = NULL; + node = g_list_next( node ); + } + g_list_free( asl->listSelect ); + asl->listSelect = NULL; +} + +/* +* Free selection list. +* Enter: asl List to free. +*/ +void addrselect_list_free( AddrSelectList *asl ) { + g_return_if_fail( asl != NULL ); + + addrselect_list_clear( asl ); + g_list_free( asl->listSelect ); + asl->listSelect = NULL; + g_free( asl ); +} + +/* +* Test whether selection is empty. +* Enter: asl List to test. +* Return: TRUE if list is empty. +*/ +gboolean addrselect_test_empty( AddrSelectList *asl ) { + g_return_val_if_fail( asl != NULL, TRUE ); + return ( asl->listSelect == NULL ); +} + +/* +* Return list of AddrSelectItem objects. +* Enter: asl List to process. +* Return: List of selection items. The list should should be g_list_free() +* when done. Items contained in the list should not be freed!!! +*/ +GList *addrselect_get_list( AddrSelectList *asl ) { + GList *node, *list; + + g_return_if_fail( asl != NULL ); + list = NULL; + node = asl->listSelect; + while( node ) { + list = g_list_append( list, node->data ); + node = g_list_next( node ); + } + return list; +} + +static gchar *addrselect_format_address( AddrItemObject * aio ) { + gchar *buf = NULL; + gchar *name = NULL; + gchar *address = NULL; + + if( aio->type == ADDR_ITEM_EMAIL ) { + ItemPerson *person = NULL; + ItemEMail *email = ( ItemEMail * ) aio; + + person = ( ItemPerson * ) ADDRITEM_PARENT(email); + if( email->address ) { + if( ADDRITEM_NAME(email) ) { + name = ADDRITEM_NAME(email); + if( *name == '\0' ) { + name = ADDRITEM_NAME(person); + } + } + else if( ADDRITEM_NAME(person) ) { + name = ADDRITEM_NAME(person); + } + else { + buf = g_strdup( email->address ); + } + address = email->address; + } + } + else if( aio->type == ADDR_ITEM_PERSON ) { + ItemPerson *person = ( ItemPerson * ) aio; + GList *node = person->listEMail; + + name = ADDRITEM_NAME(person); + if( node ) { + ItemEMail *email = ( ItemEMail * ) node->data; + address = email->address; + } + } + if( address ) { + if( name ) { + buf = g_strdup_printf( "%s <%s>", name, address ); + } + else { + buf = g_strdup( address ); + } + } + return buf; +} + +/* +* Print formatted addresses list to specified stream. +* Enter: asl List to process. +* stream Stream. +*/ +void addrselect_list_print( AddrSelectList *asl, FILE *stream ) { + GList *node; + + g_return_if_fail( asl != NULL ); + fprintf( stream, "show selection...>>>\n" ); + node = asl->listSelect; + while( node != NULL ) { + AddrSelectItem *item; + AddrItemObject *aio; + gchar *addr; + + item = node->data; + aio = ( AddrItemObject * ) item->addressItem; + if( aio ) { + fprintf( stream, "- %d : '%s'\n", aio->type, aio->name ); + if( aio->type == ADDR_ITEM_GROUP ) { + ItemGroup *group = ( ItemGroup * ) aio; + GList *node = group->listEMail; + while( node ) { + ItemEMail *email = node->data; + addr = addrselect_format_address( + ( AddrItemObject * ) email ); + if( addr ) { + fprintf( stream, "\tgrp >%s<\n", addr ); + g_free( addr ); + } + node = g_list_next( node ); + } + } + else { + addr = addrselect_format_address( aio ); + if( addr ) { + fprintf( stream, "\t>%s<\n", addr ); + g_free( addr ); + } + } + } + else { + fprintf( stream, "- NULL" ); + } + node = g_list_next( node ); + } + fprintf( stream, "show selection...<<<\n" ); +} + +/* +* Print address items to specified stream. +* Enter: asl List to process. +* stream Stream. +*/ +void addrselect_list_show( AddrSelectList *asl, FILE *stream ) { + GList *node; + + g_return_if_fail( asl != NULL ); + fprintf( stream, "show selection...>>>\n" ); + node = asl->listSelect; + while( node != NULL ) { + AddrSelectItem *item; + + item = node->data; + addrselect_item_print( item, stream ); + node = g_list_next( node ); + } + fprintf( stream, "show selection...<<<\n" ); +} + +/* +* Test whether specified object is in list. +* Enter: list List to check. +* aio Object to test. +* Return item found, or NULL if not in list. +*/ +static AddrSelectItem *addrselect_list_find( GList *list, AddrItemObject *aio ) { + GList *node; + + node = list; + while( node ) { + AddrSelectItem *item; + + item = node->data; + if( item->addressItem == aio ) return item; + node = g_list_next( node ); + } + return NULL; +} + +/* +* Add a single object into the list. +* Enter: asl Address selection object. +* obj Address object. +* cacheID Cache ID. Should be g_free() after calling function. +* Return: Adjusted list. +*/ +void addrselect_list_add_obj( AddrSelectList *asl, AddrItemObject *aio, gchar *cacheID ) { + AddrSelectItem *item; + + g_return_if_fail( asl != NULL ); + if( aio == NULL ) return; + + /* Check whether object is in list */ + if( addrselect_list_find( asl->listSelect, aio ) ) return; + + if( aio->type == ADDR_ITEM_PERSON || + aio->type == ADDR_ITEM_EMAIL || + aio->type == ADDR_ITEM_GROUP ) { + item = addrselect_create_item( aio ); + item->cacheID = g_strdup( cacheID ); + asl->listSelect = g_list_append( asl->listSelect, item ); + } + /* addrselect_list_show( asl, stdout ); */ +} + +/* +* Add a single item into the list. +* Enter: asl Address selection object. +* item Address select item. +* cacheID Cache ID. Should be g_free() after calling function. +* Return: Adjusted list. +*/ +void addrselect_list_add( AddrSelectList *asl, AddrSelectItem *item, gchar *cacheID ) { + g_return_if_fail( asl != NULL ); + if( item == NULL ) return; + + /* Check whether object is in list */ + if( g_list_find( asl->listSelect, item ) ) return; + + item->cacheID = g_strdup( cacheID ); + asl->listSelect = g_list_append( asl->listSelect, item ); +} + +/* +* Remove specified object from list. +* Enter: asl Address selection object. +* aio Object to remove. +*/ +void addrselect_list_remove( AddrSelectList *asl, AddrItemObject *aio ) { + GList *node; + AddrSelectItem *item; + + g_return_if_fail( asl != NULL ); + if( aio == NULL ) return; + node = asl->listSelect; + while( node ) { + item = node->data; + if( item->addressItem == aio ) { + addrselect_item_free( item ); + node->data = NULL; + asl->listSelect = g_list_remove_link( asl->listSelect, node ); + break; + } + node = g_list_next( node ); + } + /* addrselect_list_show( list, stdout ); */ +} + +/* +* End of Source. +*/ + + diff --git a/src/addrselect.h b/src/addrselect.h new file mode 100644 index 000000000..78d7e2b4b --- /dev/null +++ b/src/addrselect.h @@ -0,0 +1,75 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 2002 Match Grun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Address list item selection. + */ + +#ifndef __ADDR_SELECT_H__ +#define __ADDR_SELECT_H__ + +#include "addritem.h" +#include "addressitem.h" +#include "addrcache.h" + +/* +* Selection item data. +*/ +typedef struct _AddrSelectItem_ AddrSelectItem; +struct _AddrSelectItem_ { + ItemObjectType objectType; + AddrItemObject *addressItem; + gchar *uid; + gchar *cacheID; +}; + +/* + * Selection list object. + */ +typedef struct _AddrSelectList_ AddrSelectList; +struct _AddrSelectList_ { + GList *listSelect; +}; + +AddrSelectItem *addrselect_create_item ( AddrItemObject *aio ); +AddrSelectItem *addrselect_create_node ( AddressObject *obj ); +AddrSelectItem *addrselect_item_copy ( AddrSelectItem *item ); +void addrselect_item_free ( AddrSelectItem *item ); +void addrselect_item_print ( AddrSelectItem *item, + FILE *stream ); +AddrSelectList *addrselect_list_create ( void ); +void addrselect_list_free ( AddrSelectList *asl ); +GList *addrselect_get_list ( AddrSelectList *asl ); +void addrselect_list_clear ( AddrSelectList *asl ); +gboolean addrselect_test_empty ( AddrSelectList *asl ); +void addrselect_list_add_obj ( AddrSelectList *asl, + AddrItemObject *aio, + gchar *cacheID ); +void addrselect_list_add ( AddrSelectList *asl, + AddrSelectItem *item, + gchar *cacheID ); +void addrselect_list_remove ( AddrSelectList *asl, + AddrItemObject *aio ); +void addrselect_list_show ( AddrSelectList *asl, + FILE *stream ); +void addrselect_list_print ( AddrSelectList *asl, + FILE *stream ); + +#endif /* __ADDR_SELECT_H__ */ + -- 2.25.1