2007-12-06 [colin] 3.1.0cvs62
[claws.git] / src / addressbook.c
index e1917c06c3708f28218afd32c2247beada25c86c..43fedc7c81281e4577312cc96e82e1e84622fe23 100644 (file)
@@ -44,6 +44,8 @@
 #include <gtk/gtkitemfactory.h>
 #include <string.h>
 #include <setjmp.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 #include "main.h"
 #include "addressbook.h"
 #include "exphtmldlg.h"
 #include "expldifdlg.h"
 #include "browseldap.h"
+#include "addrcustomattr.h"
 
 typedef enum
 {
@@ -368,6 +371,7 @@ static void addressbook_list_select_remove  ( AddrItemObject    *aio );
 
 static void addressbook_import_ldif_cb         ( void );
 static void addressbook_find_duplicates_cb     ( void );
+static void addressbook_edit_custom_attr_cb    ( void );
 static void addressbook_import_mutt_cb         ( void );
 static void addressbook_import_pine_cb         ( void );
 static void addressbook_export_html_cb         ( void );
@@ -465,6 +469,7 @@ static GtkItemFactoryEntry addressbook_entries[] =
        {N_("/_Tools/Export LDI_F..."), NULL,           addressbook_export_ldif_cb,     0, NULL, NULL},
        {N_("/_Tools/---"),             NULL,           NULL, 0, "<Separator>", NULL},
        {N_("/_Tools/Find duplicates..."), NULL, addressbook_find_duplicates_cb,        0, NULL, NULL},
+       {N_("/_Tools/Edit custom attributes..."), NULL, addressbook_edit_custom_attr_cb,        0, NULL, NULL},
        {N_("/_Help"),                  NULL,           NULL, 0, "<Branch>", NULL},
        {N_("/_Help/_About"),           NULL,           about_show, 0, NULL, NULL}
 };
@@ -549,7 +554,7 @@ static ErrMsgTableEntry _lutErrorsLDAP_[] = {
        { LDAPRC_NOENTRIES,                     N_("No LDAP entries found for search criteria") },
        { LDAPRC_STOP_FLAG,                     N_("LDAP search terminated on request") },
        { LDAPRC_TLS,                           N_("Error starting TLS connection") },
-       { LDAPRC_NODN,                          N_("Distinguised Name (dn) is missing") },
+       { LDAPRC_NODN,                          N_("Distinguished Name (dn) is missing") },
        { LDAPRC_NAMING_VIOLATION,              N_("Missing required information") },
        { LDAPRC_ALREADY_EXIST,                 N_("Another contact exists with that key") },
        { LDAPRC_STRONG_AUTH,                   N_("Strong(er) authentication required") },
@@ -690,7 +695,7 @@ Compose *addressbook_get_target_compose(void)
 /**
  * Refresh addressbook and save to file(s).
  */
-static void addressbook_refresh( void )
+void addressbook_refresh( void )
 {
        if (addrbook.window) {
                if (addrbook.treeSelected) {
@@ -1298,22 +1303,6 @@ static void addressbook_status_show( gchar *msg ) {
        }
 }
 
-static void addressbook_ds_status_message( AddressDataSource *ds, gchar *msg ) {
-       *addressbook_msgbuf = '\0';
-       if( ds ) {
-               gchar *name;
-
-               name = addrindex_ds_get_name( ds );
-               g_snprintf( addressbook_msgbuf, sizeof(addressbook_msgbuf),
-                           "%s: %s", name, msg );
-       }
-       else {
-               g_snprintf( addressbook_msgbuf, sizeof(addressbook_msgbuf),
-                           "%s", msg );
-       }
-       addressbook_status_show( addressbook_msgbuf );
-}
-
 static void addressbook_ds_show_message( AddressDataSource *ds ) {
        gint retVal;
        gchar *name;
@@ -1450,6 +1439,8 @@ static void addressbook_del_clicked(GtkButton *button, gpointer data)
                        item = node->data;
                        node = g_list_next( node );
                        aio = ( AddrItemObject * ) item->addressItem;
+                       if (!aio)
+                               continue;
                        if( aio->type == ADDR_ITEM_GROUP ) {
                                ItemGroup *item = ( ItemGroup * ) aio;
                                GtkCTreeNode *nd = NULL;
@@ -1478,6 +1469,10 @@ static void addressbook_del_clicked(GtkButton *button, gpointer data)
                                }
 #endif
                                if( item ) {
+                                       gchar *filename = addritem_person_get_picture(item);
+                                       if (filename && is_file_exist(filename))
+                                               g_unlink(filename);
+                                       g_free(filename);
                                        addritem_free_item_person( item );
                                }
                        }
@@ -1745,7 +1740,8 @@ static void addressbook_menuitem_set_sensitive( AddressObject *obj, GtkCTreeNode
                }
        }
 
-       if( addrbook.listSelected == NULL ) canEdit = FALSE;
+       if( addrbook.listSelected == NULL )
+               canEdit = FALSE;
 
        /* Enable add */
        menu_set_sensitive( addrbook.menu_factory, "/Address/New Address", editAddress );
@@ -1767,8 +1763,6 @@ static void addressbook_menuitem_set_sensitive( AddressObject *obj, GtkCTreeNode
        menu_set_sensitive( addrbook.menu_factory, "/Tools/Export LDIF...", canExport );
 }
 
-static void addressbook_list_menu_setup( void );
-
 /**
  * Address book tree callback function that responds to selection of tree
  * items.
@@ -1855,9 +1849,7 @@ static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node,
 
        /* Setup main menu selections */
        addressbook_menubar_set_sensitive( FALSE );
-       addressbook_list_menu_setup();
        addressbook_menuitem_set_sensitive( obj, node );
-
        addressbook_list_select_clear();
        addressbook_list_menu_setup();
        return;
@@ -1895,17 +1887,20 @@ static void addressbook_list_menu_setup( void ) {
                /* Parent object is a data source */
                ads = ADAPTER_DSOURCE(pobj);
                ds = ads->dataSource;
+               if (!ds)
+                       return;
                iface = ds->interface;
+               if (!iface)
+                       return;
                if( ! iface->readOnly ) {
                        menu_set_sensitive( addrbook.list_factory, "/New Address", TRUE );
                        if (iface->type != ADDR_IF_LDAP)
                                menu_set_sensitive( addrbook.list_factory, "/New Group", TRUE );
                        gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
-                       if( ! addrclip_is_empty( _clipBoard_ ) ) canPaste = TRUE;
-                       if( ! addrselect_test_empty( _addressSelect_ ) ) canCut = TRUE;
-                       if( obj ) canEdit = TRUE;
+                       if( obj )
+                               canEdit = TRUE;
+                       canDelete = canEdit;
                }
-               canDelete = canEdit;
        }
        else if( pobj->type != ADDR_INTERFACE ) {
                /* Parent object is not an interface */
@@ -1913,6 +1908,8 @@ static void addressbook_list_menu_setup( void ) {
                if (!ds)
                        return;
                iface = ds->interface;
+               if (!iface)
+                       return;
                if( ! iface->readOnly ) {
                        /* Folder or group */
                        if( pobj->type == ADDR_ITEM_FOLDER || pobj->type == ADDR_ITEM_GROUP ) {
@@ -1926,17 +1923,25 @@ static void addressbook_list_menu_setup( void ) {
                                        menu_set_sensitive( addrbook.list_factory, "/New Group", TRUE );
                                if( obj ) canEdit = TRUE;
                        }
-                       if( ! addrclip_is_empty( _clipBoard_ ) ) canPaste = TRUE;
-                       if( ! addrselect_test_empty( _addressSelect_ ) ) canCut = TRUE;
                        canDelete = canEdit;
                }
-               if( iface && iface->type == ADDR_IF_LDAP ) {
+               if( iface->type == ADDR_IF_LDAP ) {
                        if( obj ) canBrowse = TRUE;
                        canEdit = TRUE;
                        canDelete = TRUE;
                }
        }
-       if( ! addrselect_test_empty( _addressSelect_ ) ) canCopy = TRUE;
+
+       if( iface ) {
+               /* Enable cut and paste */
+               if( ! addrclip_is_empty( _clipBoard_ ) )
+                       canPaste = TRUE;
+               if( ! addrselect_test_empty( _addressSelect_ ) )
+                       canCut = TRUE;
+               /* Enable copy if something is selected */
+               if( ! addrselect_test_empty( _addressSelect_ ) )
+                       canCopy = TRUE;
+       }
 
        /* Disable edit or browse if more than one row selected */
        if( GTK_CLIST(clist)->selection && GTK_CLIST(clist)->selection->next ) {
@@ -1944,6 +1949,13 @@ static void addressbook_list_menu_setup( void ) {
                canBrowse = FALSE;
        }
 
+       /* Forbid write changes when read-only */
+       if( iface && iface->readOnly ) {
+               canCut = FALSE;
+               canDelete = FALSE;
+               canPaste = FALSE;
+       }
+
        /* Now go finalize menu items */
        menu_set_sensitive( addrbook.list_factory, "/Edit",   canEdit );
        menu_set_sensitive( addrbook.list_factory, "/Delete", canDelete );
@@ -1951,18 +1963,12 @@ static void addressbook_list_menu_setup( void ) {
        menu_set_sensitive( addrbook.list_factory, "/Cut",           canCut );
        menu_set_sensitive( addrbook.list_factory, "/Copy",          canCopy );
        menu_set_sensitive( addrbook.list_factory, "/Paste",         canPaste );
-/*     menu_set_sensitive( addrbook.list_factory, "/Paste Address", canPaste );*/
 
        menu_set_sensitive( addrbook.list_factory, "/Mail To",       canCopy );
 
        menu_set_sensitive( addrbook.menu_factory, "/Address/Cut",           canCut );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Copy",          canCopy );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Paste",         canPaste );
-/*     menu_set_sensitive( addrbook.menu_factory, "/Edit/Paste Address", canPaste );*/
-
-       menu_set_sensitive( addrbook.tree_factory, "/Cut",             canCut );
-       menu_set_sensitive( addrbook.tree_factory, "/Copy",            canCopy );
-       menu_set_sensitive( addrbook.tree_factory, "/Paste",           canPaste );
 
        menu_set_sensitive( addrbook.menu_factory, "/Address/Edit",    canEdit );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Delete",  canDelete );
@@ -2055,8 +2061,7 @@ static void addressbook_clip_paste_cb( void ) {
        ds = addressbook_find_datasource( GTK_CTREE_NODE(addrbook.treeSelected) );
        if( ds == NULL ) return;
        if( addrindex_ds_get_readonly( ds ) ) {
-               addressbook_ds_status_message(
-                       ds, _( "Cannot paste. Target address book is readonly." ) );
+               alertpanel_error( _("Cannot paste. Target address book is readonly.") );
                return;
        }
 
@@ -2066,8 +2071,7 @@ static void addressbook_clip_paste_cb( void ) {
                        folder = ADAPTER_FOLDER(pobj)->itemFolder;
                }
                else if( pobj->type == ADDR_ITEM_GROUP ) {
-                       addressbook_ds_status_message(
-                               ds, _( "Cannot paste into an address group." ) );
+                       alertpanel_error( _("Cannot paste into an address group.") );
                        return;
                }
        }
@@ -2270,8 +2274,12 @@ static void addressbook_list_row_selected( GtkCTree *clist,
 
        addressbook_list_menu_setup();
 
-       if (!addrbook.target_compose && !prefs_common.addressbook_use_editaddress_dialog)
-               addressbook_edit_address(NULL, 0, NULL, FALSE);
+       if (!addrbook.target_compose && !prefs_common.addressbook_use_editaddress_dialog) {
+               AddressObject *obj = gtk_ctree_node_get_row_data( clist, addrbook.listSelected );
+
+               if (obj && obj->type != ADDR_ITEM_GROUP)
+                       addressbook_edit_address(NULL, 0, NULL, FALSE);
+       }
 }
 
 static void addressbook_list_row_unselected( GtkCTree *ctree,
@@ -2313,7 +2321,13 @@ static gboolean addressbook_list_button_pressed(GtkWidget *widget,
                                addressbook_to_clicked(NULL, GINT_TO_POINTER(COMPOSE_TO));
                        else
                                if (prefs_common.addressbook_use_editaddress_dialog)
-                               addressbook_edit_address_cb(NULL, 0, NULL);
+                                       addressbook_edit_address_cb(NULL, 0, NULL);
+                               else {
+                                       GtkCTree *clist = GTK_CTREE(addrbook.clist);
+                                       AddressObject *obj = gtk_ctree_node_get_row_data( clist, addrbook.listSelected );
+                                       if( obj && obj->type == ADDR_ITEM_GROUP )
+                                               addressbook_edit_address_cb(NULL, 0, NULL);
+                               }
 
                        lasttime = 0;
                } else
@@ -2367,17 +2381,14 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
        if( ! addrclip_is_empty( _clipBoard_ ) ) {
                canTreePaste = TRUE;
        }
-
        if (obj->type == ADDR_INTERFACE) {
                AdapterInterface *adapter = ADAPTER_INTERFACE(obj);
+               if( !adapter )
+                       goto just_set_sens;
                iface = adapter->interface;
-               canEdit = FALSE;
-               canDelete = FALSE;
-               canTreeCopy = FALSE;
-               if( iface->readOnly ) {
-                       canTreePaste = FALSE;
-               }
-               else {
+               if( !iface )
+                       goto just_set_sens;
+               if( !iface->readOnly ) {
                        menu_set_sensitive( addrbook.tree_factory, "/New Book", TRUE );
                        gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
                }
@@ -2386,36 +2397,29 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
        if (obj->type == ADDR_DATASOURCE) {
                ads = ADAPTER_DSOURCE(obj);
                ds = ads->dataSource;
-               if (!ds)
+               if( !ds )
                        goto just_set_sens;
                iface = ds->interface;
-               if (!iface)
+               if( !iface )
                        goto just_set_sens;
-               canEdit = TRUE;
-               canDelete = TRUE;
-               if( iface->readOnly ) {
-                       canTreePaste = FALSE;
-               }
-               else {
+               if( !iface->readOnly ) {
+                       canDelete = TRUE;
                        menu_set_sensitive( addrbook.tree_factory, "/New Folder", TRUE );
                        menu_set_sensitive( addrbook.tree_factory, "/New Group", TRUE );
                        gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
                }
+               canEdit = TRUE;
                canTreeCopy = TRUE;
                if( iface->externalQuery ) canLookup = TRUE;
        }
        else if (obj->type == ADDR_ITEM_FOLDER) {
                ds = addressbook_find_datasource( node );
-               if (!ds) {
+               if( !ds )
                        goto just_set_sens;
-               }
                iface = ds->interface;
-               if (!iface)
+               if( !iface )
                        goto just_set_sens;
-               if( iface->readOnly ) {
-                       canTreePaste = FALSE;
-               }
-               else {
+               if( !iface->readOnly ) {
                        canEdit = TRUE;
                        canDelete = TRUE;
                        canTreeCut = TRUE;
@@ -2433,10 +2437,10 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
        }
        else if (obj->type == ADDR_ITEM_GROUP) {
                ds = addressbook_find_datasource( node );
-               if (!ds)
+               if( !ds )
                        goto just_set_sens;
                iface = ds->interface;
-               if (!iface)
+               if( !iface )
                        goto just_set_sens;
                if( ! iface->readOnly ) {
                        canEdit = TRUE;
@@ -2445,15 +2449,24 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
                        gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
                }
        }
-       else if (obj->type == ADDR_INTERFACE) {
-               canTreePaste = FALSE;
-       }
 
        if( canEdit ) {
-               if( ! addrselect_test_empty( _addressSelect_ ) ) canCut = TRUE;
+               if( ! addrselect_test_empty( _addressSelect_ ) )
+                       canCut = TRUE;
+       }
+       if( ! addrselect_test_empty( _addressSelect_ ) )
+               canCopy = TRUE;
+       if( ! addrclip_is_empty( _clipBoard_ ) )
+               canPaste = TRUE;
+
+       /* Forbid write changes when read-only */
+       if( iface && iface->readOnly ) {
+               canTreeCut = FALSE;
+               canTreePaste = FALSE;
+               canCut = FALSE;
+               canDelete = FALSE;
+               canPaste = FALSE;
        }
-       if( ! addrselect_test_empty( _addressSelect_ ) ) canCopy = TRUE;
-       if( ! addrclip_is_empty( _clipBoard_ ) ) canPaste = TRUE;
 
 just_set_sens:
        /* Enable edit */
@@ -2468,9 +2481,10 @@ just_set_sens:
        menu_set_sensitive( addrbook.menu_factory, "/Address/Cut",           canCut );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Copy",          canCopy );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Paste",         canPaste );
-/*     menu_set_sensitive( addrbook.menu_factory, "/Edit/Paste Address", canPaste );*/
 
-       addressbook_show_buttons(addrbook.target_compose == NULL, canLookup, addrbook.target_compose != NULL);
+       addressbook_show_buttons(addrbook.target_compose == NULL, canLookup,
+                       addrbook.target_compose != NULL);
+
        if( event->button == 3 ) {
                gtk_menu_popup(GTK_MENU(addrbook.tree_popup), NULL, NULL, NULL, NULL,
                               event->button, event->time);
@@ -3191,7 +3205,10 @@ static void addressbook_move_nodes_up( GtkCTree *ctree, GtkCTreeNode *node ) {
 static void addressbook_edit_address_post_cb( ItemPerson *person )
 {
        if( person ) {
-
+#ifdef USE_LDAP
+               if (strcmp2(person->nickName, ADDRITEM_NAME(person)))
+                       addritem_person_set_nick_name( person, ADDRITEM_NAME(person));
+#endif
                addressbook_folder_refresh_one_person( GTK_CTREE(addrbook.clist), person );
                invalidate_address_completion();
        }
@@ -3212,10 +3229,6 @@ void addressbook_address_list_disable_some_actions(void)
        menu_set_sensitive( addrbook.menu_factory, "/Address/Cut",   FALSE );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Copy",  FALSE );
        menu_set_sensitive( addrbook.menu_factory, "/Address/Paste", FALSE );
-
-       /* we're already editing contact's detail here */
-       menu_set_sensitive( addrbook.menu_factory, "/Address/Edit",  FALSE );
-       gtk_widget_set_sensitive( addrbook.edit_btn, FALSE );
 }
 
 static void addressbook_edit_address_cb( gpointer data, guint action, GtkWidget *widget ) {
@@ -3379,10 +3392,10 @@ static void addressbook_load_group( GtkCTree *clist, ItemGroup *itemGroup ) {
                person = ( ItemPerson * ) ADDRITEM_PARENT(email);
                str = addressbook_format_item_clist( person, email );
                if( str ) {
-                       text[COL_NAME] = str;
+                       text[COL_NAME] = addressbook_set_col_name_guard(str);
                }
                else {
-                       text[COL_NAME] = ADDRITEM_NAME(person);
+                       text[COL_NAME] = addressbook_set_col_name_guard(ADDRITEM_NAME(person));
                }
                text[COL_ADDRESS] = email->address;
                text[COL_REMARKS] = email->remarks;
@@ -3398,6 +3411,17 @@ static void addressbook_load_group( GtkCTree *clist, ItemGroup *itemGroup ) {
        }
 }
 
+gchar *addressbook_set_col_name_guard(gchar *value)
+{
+       gchar *ret = "<not set>";
+       gchar *tmp = g_strdup(value);
+       g_strstrip(tmp);
+       if (tmp !=NULL && *tmp != '\0')
+               ret = value;
+       g_free(tmp);
+       return ret;
+}
+
 static void addressbook_folder_load_one_person(
                GtkCTree *clist, ItemPerson *person,
                AddressTypeControlItem *atci,
@@ -3429,23 +3453,23 @@ static void addressbook_folder_load_one_person(
                        /* First email belongs with person */
                        gchar *str = addressbook_format_item_clist( person, email );
                        if( str ) {
-                               text[COL_NAME] = str;
+                               text[COL_NAME] = addressbook_set_col_name_guard(str);
                        }
 #ifdef USE_LDAP
                        else if( abf && abf->type == ADDR_IF_LDAP && 
                                 person && person->nickName ) {
                                if (person->nickName) {
                                        if (strcmp(person->nickName, "") != 0) {
-                                               text[COL_NAME] = person->nickName;
+                                               text[COL_NAME] = addressbook_set_col_name_guard(person->nickName);
                                        }
                                        else {
-                                               text[COL_NAME] = ADDRITEM_NAME(person);
+                                               text[COL_NAME] = addressbook_set_col_name_guard(ADDRITEM_NAME(person));
                                        }
                                }
                        }
 #endif
                        else {
-                               text[COL_NAME] = ADDRITEM_NAME(person);
+                               text[COL_NAME] = addressbook_set_col_name_guard(ADDRITEM_NAME(person));
                        }
                        nodePerson = gtk_sctree_insert_node(
                                        clist, NULL, NULL,
@@ -3473,7 +3497,7 @@ static void addressbook_folder_load_one_person(
        }
        if( ! haveAddr ) {
                /* Have name without EMail */
-               text[COL_NAME] = ADDRITEM_NAME(person);
+               text[COL_NAME] = addressbook_set_col_name_guard(ADDRITEM_NAME(person));
                text[COL_ADDRESS] = "";
                text[COL_REMARKS] = "";
                nodePerson = gtk_sctree_insert_node(
@@ -3915,9 +3939,61 @@ static gboolean addressbook_convert( AddressIndex *addrIndex ) {
        return retVal;
 }
 
+static gboolean migrate_addrbook(const gchar *origdir, const gchar *destdir)
+{
+       DIR *dp;
+       struct dirent *d;
+       gboolean failed = FALSE;
+
+       if( ( dp = opendir( origdir ) ) == NULL ) {
+               return FALSE;
+       }
+       
+       while( ( d = readdir( dp ) ) != NULL ) {
+               if (strncmp(d->d_name, "addrbook-", strlen("addrbook-")))
+                       continue;
+               else {
+                       gchar *orig_file = g_strconcat(origdir, G_DIR_SEPARATOR_S, 
+                                       d->d_name, NULL);
+                       gchar *dest_file = g_strconcat(destdir, G_DIR_SEPARATOR_S, 
+                                       d->d_name, NULL);
+                       if (copy_file(orig_file, dest_file, FALSE) < 0) {
+                               failed = TRUE;
+                       }
+                       g_free(orig_file);
+                       g_free(dest_file);
+                       if (failed) {
+                               break;
+                       }
+               }
+       }
+
+       closedir( dp );
+       if (!failed) {
+               /* all copies succeeded, we can remove source files */
+               if( ( dp = opendir( origdir ) ) == NULL ) {
+                       return FALSE;
+               }
+               while( ( d = readdir( dp ) ) != NULL ) {
+                       if (strncmp(d->d_name, "addrbook-", strlen("addrbook-")))
+                               continue;
+                       else {
+                               gchar *orig_file = g_strconcat(origdir, G_DIR_SEPARATOR_S, 
+                                               d->d_name, NULL);
+                               g_unlink(orig_file);
+                               g_free(orig_file);
+                       }
+               }
+               closedir( dp );
+       }
+       
+       return !failed;
+}
+
 void addressbook_read_file( void ) {
        AddressIndex *addrIndex = NULL;
-
+       gchar *indexdir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, NULL);
+       
        debug_print( "Reading address index...\n" );
        if( _addressIndex_ ) {
                debug_print( "address book already read!!!\n" );
@@ -3928,7 +4004,24 @@ void addressbook_read_file( void ) {
        addrindex_initialize();
 
        /* Use new address book index. */
-       addrindex_set_file_path( addrIndex, get_rc_dir() );
+       
+       if ( !is_dir_exist(indexdir) ) {
+               if ( make_dir(indexdir) < 0 ) {
+                       addrindex_set_file_path( addrIndex, get_rc_dir() );
+                       g_warning( "couldn't create dir %s\n", indexdir);
+               } else {
+                       if (!migrate_addrbook(get_rc_dir(), indexdir)) {
+                               remove_dir_recursive(indexdir);
+                               addrindex_set_file_path( addrIndex, get_rc_dir() );
+                               g_error("couldn't migrate dir %s", indexdir);
+                       } else {
+                               addrindex_set_file_path( addrIndex, indexdir);
+                       }
+               }
+       } else {
+               addrindex_set_file_path( addrIndex, indexdir);
+       }
+       g_free(indexdir);
        addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
        addrindex_read_data( addrIndex );
        if( addrIndex->retVal == MGU_NO_FILE ) {
@@ -4583,7 +4676,7 @@ static void addrbookctl_build_map( GtkWidget *window ) {
        atci->showInTree = FALSE;
        atci->treeExpand = FALSE;
        atci->treeLeaf = TRUE;
-       atci->displayName = _( "EMail Address" );
+       atci->displayName = _( "Email Address" );
        atci->iconXpm = addressxpm;
        atci->maskXpm = addressxpmmask;
        atci->iconXpmOpen = addressxpm;
@@ -4872,10 +4965,11 @@ static void addrbookctl_build_ifselect( void ) {
  * This function is used by the Add sender to address book function.
  */
 gboolean addressbook_add_contact(
-               const gchar *name, const gchar *address, const gchar *remarks )
+               const gchar *name, const gchar *address, const gchar *remarks,
+               GdkPixbuf *picture )
 {
        debug_print( "addressbook_add_contact: name/address: %s - %s\n", name, address );
-       if( addressadd_selection( _addressIndex_, name, address, remarks ) ) {
+       if( addressadd_selection( _addressIndex_, name, address, remarks, picture ) ) {
                debug_print( "addressbook_add_contact - added\n" );
                addressbook_refresh();
        }
@@ -4890,17 +4984,15 @@ gboolean addressbook_add_contact(
 /*
  * This function is used by the matcher dialog to select a book/folder.
  */
-gboolean addressbook_folder_selection( gchar **folderpath )
+gchar *addressbook_folder_selection( const gchar *folderpath)
 {
        AddressBookFile *book = NULL;
        ItemFolder *folder = NULL;
-       gchar *path;
+       gchar *path = NULL;
 
-       g_return_val_if_fail( folderpath != NULL, FALSE);
+       g_return_val_if_fail( folderpath != NULL, NULL);
 
-       path = *folderpath;
-       *folderpath = NULL;
-       if ( addressbook_foldersel_selection( _addressIndex_, &book, &folder, path )
+       if ( addressbook_foldersel_selection( _addressIndex_, &book, &folder, folderpath )
                && book != NULL ) {
                if ( folder != NULL) {
                        gchar *tmp = NULL;
@@ -4920,15 +5012,15 @@ gboolean addressbook_folder_selection( gchar **folderpath )
                                        g_free(oldtmp);
                                }
                        }
-                       *folderpath = g_strdup_printf("%s/%s", book->fileName, tmp);
+                       path = g_strdup_printf("%s/%s", book->fileName, tmp);
                        g_free(tmp);
                } else {
-                       *folderpath = g_strdup_printf("%s", book->fileName);
+                       path = g_strdup_printf("%s", book->fileName);
                }
-               debug_print( "addressbook_foldersel: %s\n", *folderpath?*folderpath:"(null)");
-               return (*folderpath != NULL);
+               debug_print( "addressbook_foldersel: %s\n", path?path:"(null)");
+               return path;
        }
-       return FALSE;
+       return NULL;
 }
 
 /* ***********************************************************************
@@ -5290,9 +5382,14 @@ static void addressbook_export_ldif_cb( void ) {
 
 static void addressbook_find_duplicates_cb(void)
 {
-       addrduplicates_find();  
+       addrduplicates_find(GTK_WINDOW(addrbook.window));       
 }
 
+static void addressbook_edit_custom_attr_cb(void)
+{
+       addressbook_custom_attr_edit();
+}
+               
 static void addressbook_start_drag(GtkWidget *widget, gint button, 
                                   GdkEvent *event,
                                   void *data)
@@ -5350,11 +5447,11 @@ static void addressbook_drag_data_get(GtkWidget        *widget,
                if( ds && ds->interface && ds->interface->readOnly)
                        gtk_selection_data_set(selection_data,
                                       selection_data->target, 8,
-                                      "Dummy_addr_copy", 15);
+                                      (const guchar *)"Dummy_addr_copy", 15);
                else
                        gtk_selection_data_set(selection_data,
                                       selection_data->target, 8,
-                                      "Dummy_addr_move", 15);
+                                      (const guchar *)"Dummy_addr_move", 15);
        } 
 }
 
@@ -5419,7 +5516,6 @@ static gboolean addressbook_drag_motion_cb(GtkWidget      *widget,
        } else {
                gdk_drag_status(context, 0, time);
        }
-
        return acceptable;
 }
 
@@ -5480,4 +5576,3 @@ static void addressbook_drag_received_cb(GtkWidget        *widget,
 /*
 * End of Source.
 */
-