claws-mail/src/addrclip.c
Paul Mangan 4afa1432ff 2006-01-13 [paul] 1.9.100cvs142
* src/account.c
	* src/account.h
	* src/action.c
	* src/action.h
	* src/adbookbase.h
	* src/addr_compl.c
	* src/addr_compl.h
	* src/addrbook.c
	* src/addrcache.c
	* src/addrcache.h
	* src/addrcindex.c
	* src/addrcindex.h
	* src/addrclip.c
	* src/addrclip.h
	* src/addrdefs.h
	* src/addressadd.c
	* src/addressadd.h
	* src/addressbook.c
	* src/addressbook.h
	* src/addrgather.c
	* src/addrgather.h
	* src/addrharvest.c
	* src/addrharvest.h
	* src/addrindex.c
	* src/addrindex.h
	* src/addritem.c
	* src/addritem.h
	* src/addrquery.c
	* src/addrquery.h
	* src/addrselect.c
	* src/addrselect.h
	* src/alertpanel.c
	* src/alertpanel.h
	* src/browseldap.c
	* src/browseldap.h
	* src/codeconv.c
	* src/codeconv.h
	* src/compose.c
	* src/compose.h
	* src/customheader.c
	* src/customheader.h
	* src/displayheader.c
	* src/displayheader.h
	* src/editaddress.c
	* src/editaddress.h
	* src/editbook.c
	* src/editbook.h
	* src/editgroup.c
	* src/editgroup.h
	* src/editjpilot.c
	* src/editjpilot.h
	* src/editldap.c
	* src/editldap.h
	* src/editldap_basedn.c
	* src/editldap_basedn.h
	* src/editvcard.c
	* src/editvcard.h
	* src/exphtmldlg.c
	* src/exphtmldlg.h
	* src/expldifdlg.c
	* src/expldifdlg.h
	* src/export.h
	* src/exporthtml.c
	* src/exporthtml.h
	* src/exportldif.c
	* src/exportldif.h
	* src/filtering.c
	* src/filtering.h
	* src/folder.c
	* src/folder.h
	* src/folder_item_prefs.c
	* src/folder_item_prefs.h
	* src/foldersel.c
	* src/foldersel.h
	* src/folderutils.c
	* src/folderutils.h
	* src/folderview.c
	* src/folderview.h
	* src/grouplistdialog.c
	* src/grouplistdialog.h
	* src/headerview.c
	* src/html.c
	* src/html.h
	* src/image_viewer.c
	* src/image_viewer.h
	* src/imap.c
	* src/imap.h
	* src/imap_gtk.c
	* src/imap_gtk.h
	* src/import.h
	* src/importldif.c
	* src/importldif.h
	* src/importmutt.c
	* src/importmutt.h
	* src/importpine.c
	* src/importpine.h
	* src/inc.c
	* src/inc.h
	* src/jpilot.c
	* src/jpilot.h
	* src/ldapctrl.c
	* src/ldapctrl.h
	* src/ldaplocate.c
	* src/ldaplocate.h
	* src/ldapquery.c
	* src/ldapquery.h
	* src/ldapserver.c
	* src/ldapserver.h
	* src/ldaputil.c
	* src/ldaputil.h
	* src/ldif.c
	* src/ldif.h
	* src/main.c
	* src/main.h
	* src/mainwindow.c
	* src/mainwindow.h
	* src/manual.c
	* src/manual.h
	* src/mbox.c
	* src/mbox.h
	* src/message_search.c
	* src/message_search.h
	* src/messageview.c
	* src/messageview.h
	* src/mh.c
	* src/mh.h
	* src/mh_gtk.c
	* src/mh_gtk.h
	* src/mimeview.c
	* src/mimeview.h
	* src/msgcache.c
	* src/msgcache.h
	* src/mutt.c
	* src/mutt.h
	* src/news.c
	* src/news.h
	* src/news_gtk.c
	* src/news_gtk.h
	* src/partial_download.c
	* src/partial_download.h
	* src/pine.c
	* src/pine.h
	* src/pop.c
	* src/pop.h
	* src/prefs_account.c
	* src/prefs_account.h
	* src/prefs_actions.c
	* src/prefs_actions.h
	* src/prefs_common.c
	* src/prefs_common.h
	* src/prefs_compose_writing.c
	* src/prefs_compose_writing.h
	* src/prefs_customheader.c
	* src/prefs_customheader.h
	* src/prefs_display_header.c
	* src/prefs_display_header.h
	* src/prefs_filtering.c
	* src/prefs_filtering.h
	* src/prefs_filtering_action.c
	* src/prefs_filtering_action.h
	* src/prefs_folder_column.c
	* src/prefs_folder_column.h
	* src/prefs_folder_item.c
	* src/prefs_folder_item.h
	* src/prefs_fonts.c
	* src/prefs_fonts.h
	* src/prefs_gtk.c
	* src/prefs_gtk.h
	* src/prefs_image_viewer.c
	* src/prefs_image_viewer.h
	* src/prefs_matcher.c
	* src/prefs_matcher.h
	* src/prefs_message.c
	* src/prefs_msg_colors.c
	* src/prefs_msg_colors.h
	* src/prefs_other.c
	* src/prefs_quote.c
	* src/prefs_receive.c
	* src/prefs_send.c
	* src/prefs_spelling.c
	* src/prefs_spelling.h
	* src/prefs_summaries.c
	* src/prefs_summaries.h
	* src/prefs_summary_column.c
	* src/prefs_summary_column.h
	* src/prefs_template.c
	* src/prefs_template.h
	* src/prefs_themes.c
	* src/prefs_themes.h
	* src/prefs_toolbar.c
	* src/prefs_toolbar.h
	* src/prefs_wrapping.c
	* src/prefs_wrapping.h
	* src/privacy.c
	* src/privacy.h
	* src/procheader.c
	* src/procheader.h
	* src/procmime.c
	* src/procmime.h
	* src/procmsg.c
	* src/procmsg.h
	* src/quote_fmt.c
	* src/quote_fmt_parse.y
	* src/recv.c
	* src/recv.h
	* src/remotefolder.c
	* src/remotefolder.h
	* src/send_message.c
	* src/send_message.h
	* src/setup.c
	* src/setup.h
	* src/sourcewindow.c
	* src/sourcewindow.h
	* src/ssl_manager.c
	* src/ssl_manager.h
	* src/statusbar.c
	* src/statusbar.h
	* src/stock_pixmap.c
	* src/stock_pixmap.h
	* src/summary_search.c
	* src/summary_search.h
	* src/summaryview.c
	* src/summaryview.h
	* src/syldap.c
	* src/syldap.h
	* src/textview.c
	* src/textview.h
	* src/toolbar.c
	* src/toolbar.h
	* src/undo.c
	* src/undo.h
	* src/unmime.c
	* src/unmime.h
	* src/vcard.c
	* src/vcard.h
	* src/wizard.c
	* src/wizard.h
	* src/common/base64.c
	* src/common/base64.h
	* src/common/defs.h
	* src/common/hooks.c
	* src/common/hooks.h
	* src/common/log.c
	* src/common/log.h
	* src/common/mgutils.c
	* src/common/mgutils.h
	* src/common/nntp.c
	* src/common/nntp.h
	* src/common/passcrypt.c
	* src/common/passcrypt.h.in
	* src/common/plugin.c
	* src/common/plugin.h
	* src/common/prefs.c
	* src/common/prefs.h
	* src/common/progressindicator.c
	* src/common/progressindicator.h
	* src/common/quoted-printable.c
	* src/common/quoted-printable.h
	* src/common/session.c
	* src/common/session.h
	* src/common/smtp.c
	* src/common/smtp.h
	* src/common/socket.c
	* src/common/socket.h
	* src/common/ssl.c
	* src/common/ssl.h
	* src/common/ssl_certificate.c
	* src/common/ssl_certificate.h
	* src/common/stringtable.c
	* src/common/stringtable.h
	* src/common/sylpheed.c
	* src/common/sylpheed.h
	* src/common/template.c
	* src/common/template.h
	* src/common/timing.h
	* src/common/utils.c
	* src/common/utils.h
	* src/common/version.h.in
	* src/common/xml.c
	* src/common/xml.h
	* src/common/xmlprops.c
	* src/common/xmlprops.h
	* src/gtk/colorlabel.c
	* src/gtk/colorsel.c
	* src/gtk/colorsel.h
	* src/gtk/description_window.c
	* src/gtk/description_window.h
	* src/gtk/filesel.c
	* src/gtk/filesel.h
	* src/gtk/foldersort.c
	* src/gtk/foldersort.h
	* src/gtk/gtkutils.c
	* src/gtk/gtkutils.h
	* src/gtk/inputdialog.c
	* src/gtk/inputdialog.h
	* src/gtk/logwindow.c
	* src/gtk/logwindow.h
	* src/gtk/manage_window.c
	* src/gtk/manage_window.h
	* src/gtk/menu.c
	* src/gtk/menu.h
	* src/gtk/pluginwindow.c
	* src/gtk/pluginwindow.h
	* src/gtk/prefswindow.c
	* src/gtk/prefswindow.h
	* src/gtk/progressdialog.c
	* src/gtk/progressdialog.h
	* src/gtk/sslcertwindow.c
	* src/gtk/sslcertwindow.h
	* src/plugins/clamav/clamav_plugin.c
	* src/plugins/clamav/clamav_plugin.h
	* src/plugins/clamav/clamav_plugin_gtk.c
	* src/plugins/demo/demo.c
	* src/plugins/dillo_viewer/dillo_prefs.c
	* src/plugins/dillo_viewer/dillo_prefs.h
	* src/plugins/dillo_viewer/dillo_viewer.c
	* src/plugins/pgpcore/passphrase.c
	* src/plugins/pgpcore/passphrase.h
	* src/plugins/pgpcore/plugin.c
	* src/plugins/pgpcore/select-keys.c
	* src/plugins/pgpcore/select-keys.h
	* src/plugins/pgpcore/sgpgme.c
	* src/plugins/pgpcore/sgpgme.h
	* src/plugins/pgpinline/pgpinline.c
	* src/plugins/pgpinline/pgpinline.h
	* src/plugins/pgpinline/plugin.c
	* src/plugins/pgpmime/pgpmime.c
	* src/plugins/pgpmime/pgpmime.h
	* src/plugins/pgpmime/plugin.c
	* src/plugins/spamassassin/spamassassin.c
	* src/plugins/spamassassin/spamassassin.h
	* src/plugins/spamassassin/spamassassin_gtk.c
	* src/plugins/trayicon/trayicon.c
		update copyright header
2006-01-13 17:24:38 +00:00

1051 lines
27 KiB
C

/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
* Copyright (C) 2002-2006 Match Grun and the Sylpheed-Claws team
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 <stdio.h>
#include <glib.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 );
}
}
/*
* 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 );
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 );
}
}
/* 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;
}
/*
* 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) != NULL ) {
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 );
if( addritem_person_empty( fromPerson ) ) {
fromPerson =
addrcache_remove_person(
cacheFrom, fromPerson );
if( fromPerson != NULL ) {
addritem_free_item_person( fromPerson );
}
}
fromPerson = NULL;
}
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 ) {
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.
*/