2007-11-27 [wwp] 3.1.0cvs35
[claws.git] / src / addressbook.c
index 07275e1d14c90368ea4a3b122a44847826a454e1..924176416fbcb45e05735f0b99cf89e6ddbfc748 100644 (file)
 #include "exphtmldlg.h"
 #include "expldifdlg.h"
 #include "browseldap.h"
+#include "addrcustomattr.h"
 
 typedef enum
 {
@@ -370,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 );
@@ -467,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}
 };
@@ -1300,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;
@@ -1753,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 );
@@ -1775,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.
@@ -1863,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;
@@ -1888,6 +1872,9 @@ static void addressbook_list_menu_setup( void ) {
        gboolean canCopy = FALSE;
        gboolean canPaste = FALSE;
        gboolean canBrowse = FALSE;
+       AddrSelectItem *item;
+       AddrItemObject *aio;
+       GList *list, *node;
 
        pobj = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), addrbook.treeSelected );
        if( pobj == NULL ) return;
@@ -1903,17 +1890,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 */
@@ -1921,6 +1911,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 ) {
@@ -1934,17 +1926,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 ) {
@@ -1952,6 +1952,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 );
@@ -1959,18 +1966,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 );
@@ -2063,8 +2064,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;
        }
 
@@ -2074,8 +2074,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;
                }
        }
@@ -2278,8 +2277,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,
@@ -2321,7 +2324,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
@@ -2375,17 +2384,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 );
                }
@@ -2394,36 +2400,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;
@@ -2441,10 +2440,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;
@@ -2453,15 +2452,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 */
@@ -2476,9 +2484,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);
@@ -3199,7 +3208,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();
        }
@@ -3220,10 +3232,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 ) {
@@ -3387,10 +3395,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;
@@ -3406,6 +3414,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,
@@ -3437,23 +3456,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,
@@ -3481,7 +3500,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(
@@ -5371,6 +5390,11 @@ static void addressbook_find_duplicates_cb(void)
        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)
@@ -5497,7 +5521,6 @@ static gboolean addressbook_drag_motion_cb(GtkWidget      *widget,
        } else {
                gdk_drag_status(context, 0, time);
        }
-
        return acceptable;
 }
 
@@ -5558,4 +5581,3 @@ static void addressbook_drag_received_cb(GtkWidget        *widget,
 /*
 * End of Source.
 */
-