b182b181620b6cfdd923e1a3ecec0af5fd2dd78c
[claws.git] / src / editaddress.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * 
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include "defs.h"
25
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <gtk/gtkwindow.h>
30 #include <gtk/gtksignal.h>
31 #include <gtk/gtklabel.h>
32 #include <gtk/gtkvbox.h>
33 #include <gtk/gtkentry.h>
34 #include <gtk/gtktable.h>
35
36 #include "mgutils.h"
37 #include "addressbook.h"
38 #include "addressitem.h"
39 #include "addritem.h"
40 #include "addrbook.h"
41 #include "manage_window.h"
42 #include "gtkutils.h"
43 #include "filesel.h"
44 #include "codeconv.h"
45 #include "editaddress.h"
46 #include "editaddress_other_attributes_ldap.h"
47 #include "prefs_common.h"
48 #include "menu.h"
49
50 /* transient data */
51 static struct _PersonEdit_dlg personeditdlg;
52 static AddressBookFile *current_abf = NULL;
53 static ItemPerson *current_person = NULL;
54 static ItemFolder *current_parent_folder = NULL;
55 static EditAddressPostUpdateCallback edit_person_close_post_update_cb = NULL;
56
57 typedef enum {
58         EMAIL_COL_EMAIL   = 0,
59         EMAIL_COL_ALIAS   = 1,
60         EMAIL_COL_REMARKS = 2
61 } PersonEditEMailColumnPos;
62
63 typedef enum {
64         ATTRIB_COL_NAME    = 0,
65         ATTRIB_COL_VALUE   = 1
66 } PersonEditAttribColumnPos;
67
68 #define EDITPERSON_WIDTH      520
69 #define EDITPERSON_HEIGHT     320
70
71 #ifndef MAEMO
72 # define EMAIL_N_COLS          3
73 # define EMAIL_COL_WIDTH_EMAIL 180
74 # define EMAIL_COL_WIDTH_ALIAS 80
75 #else
76 # define EMAIL_N_COLS          1
77 # define EMAIL_COL_WIDTH_EMAIL 130
78 # define EMAIL_COL_WIDTH_ALIAS 130
79 #endif
80
81 #ifndef MAEMO
82 # define ATTRIB_N_COLS          2
83 # define ATTRIB_COL_WIDTH_NAME  240
84 # define ATTRIB_COL_WIDTH_VALUE 0
85 #else
86 # define ATTRIB_N_COLS          2
87 # define ATTRIB_COL_WIDTH_NAME  120
88 # define ATTRIB_COL_WIDTH_VALUE 120
89 #endif
90
91 #define PAGE_BASIC             0
92 #define PAGE_EMAIL             1
93 #define PAGE_ATTRIBUTES        2
94
95 static gboolean addressbook_edit_person_close( gboolean cancelled );
96
97 static void edit_person_status_show( gchar *msg ) {
98         if( personeditdlg.statusbar != NULL ) {
99                 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
100                 if( msg ) {
101                         gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
102                 }
103         }
104 }
105
106 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
107         *cancelled = FALSE;
108         if (prefs_common.addressbook_use_editaddress_dialog)
109                 gtk_main_quit();
110         else
111                 addressbook_edit_person_close( *cancelled );
112 }
113
114 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
115         *cancelled = TRUE;
116         if (prefs_common.addressbook_use_editaddress_dialog)
117                 gtk_main_quit();
118         else
119                 addressbook_edit_person_close( *cancelled );
120 }
121
122 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
123         *cancelled = TRUE;
124         if (prefs_common.addressbook_use_editaddress_dialog)
125                 gtk_main_quit();
126         else
127                 addressbook_edit_person_close( *cancelled );
128         return TRUE;
129 }
130
131 static gboolean edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
132         if (prefs_common.addressbook_use_editaddress_dialog) {
133         if (event && event->keyval == GDK_Escape) {
134                 *cancelled = TRUE;
135                 gtk_main_quit();
136         }
137         }
138         return FALSE;
139 }
140
141 static gchar *_title_new_ = NULL;
142 static gchar *_title_edit_ = NULL;
143
144 static void edit_person_set_widgets_title( gchar *text )
145 {
146         gchar *label = NULL;
147
148         g_return_if_fail( text != NULL );
149
150         gtk_label_set_text(GTK_LABEL(personeditdlg.title), "");
151         label = g_markup_printf_escaped("<b>%s</b>", text);
152         gtk_label_set_markup(GTK_LABEL(personeditdlg.title), label);
153         g_free(label);
154 }
155
156 static void edit_person_set_window_title( gint pageNum ) {
157         gchar *sTitle;
158
159         if( _title_new_ == NULL ) {
160                 _title_new_ = g_strdup( _("Add New Person") );
161                 _title_edit_ = g_strdup( _("Edit Person Details") );
162         }
163
164         if( pageNum == PAGE_BASIC ) {
165                 if( personeditdlg.editNew ) {
166                         if (prefs_common.addressbook_use_editaddress_dialog)
167                                 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_new_ );
168                         else
169                                 edit_person_set_widgets_title( _title_new_ );
170                 }
171                 else {
172                         if (prefs_common.addressbook_use_editaddress_dialog)
173                                 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_edit_ );
174                         else
175                                 edit_person_set_widgets_title( _title_edit_ );
176                 }
177         }
178         else {
179                 if( personeditdlg.entry_name == NULL ) {
180                         sTitle = g_strdup( _title_edit_ );
181                 }
182                 else {
183                         gchar *name;
184                         name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
185                         sTitle = g_strdup_printf( "%s - %s", _title_edit_, name );
186                         g_free( name );
187                 }
188                 if (prefs_common.addressbook_use_editaddress_dialog)
189                         gtk_window_set_title( GTK_WINDOW(personeditdlg.container), sTitle );
190                 else
191                         edit_person_set_widgets_title( sTitle );
192                 g_free( sTitle );
193         }
194 }
195
196 static void edit_person_email_clear( gpointer data ) {
197         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
198         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
199         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
200 }
201
202 static void edit_person_attrib_clear( gpointer data ) {
203         if (!personeditdlg.ldap) {
204                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), "" );
205                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
206         }
207 }
208
209 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
210                                         gint pageNum, gpointer user_data)
211 {
212         edit_person_set_window_title( pageNum );
213         edit_person_status_show( "" );
214 }
215
216 /*
217 * Load clist with a copy of person's email addresses.
218 */
219 static void edit_person_load_email( ItemPerson *person ) {
220         GList *node = person->listEMail;
221         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
222         gchar *text[ EMAIL_N_COLS ];
223         while( node ) {
224                 ItemEMail *emorig = ( ItemEMail * ) node->data;
225                 ItemEMail *email = addritem_copyfull_item_email( emorig );
226                 gint row;
227                 text[ EMAIL_COL_EMAIL   ] = email->address;
228 #ifndef MAEMO
229                 text[ EMAIL_COL_ALIAS   ] = email->obj.name;
230                 text[ EMAIL_COL_REMARKS ] = email->remarks;
231 #endif
232                 row = gtk_clist_append( clist, text );
233                 gtk_clist_set_row_data( clist, row, email );
234                 node = g_list_next( node );
235         }
236 }
237
238 static void edit_person_email_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
239         ItemEMail *email = gtk_clist_get_row_data( clist, row );
240         if( email ) {
241                 if( email->address )
242                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), email->address );
243                 if( ADDRITEM_NAME(email) )
244                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), ADDRITEM_NAME(email) );
245                 if( email->remarks )
246                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), email->remarks );
247                 if (!personeditdlg.read_only) {
248                         gtk_widget_set_sensitive(personeditdlg.email_del, TRUE);
249                         gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
250                         gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, row + 1) != NULL);
251                 }
252         } else {
253                 gtk_widget_set_sensitive(personeditdlg.email_del, FALSE);
254                 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
255                 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
256         }
257         personeditdlg.rowIndEMail = row;
258         edit_person_status_show( NULL );
259 }
260
261 static void edit_person_email_move( gint dir ) {
262         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
263         gint row = personeditdlg.rowIndEMail + dir;
264         ItemEMail *email = gtk_clist_get_row_data( clist, row );
265         if( email ) {
266                 gtk_clist_row_move( clist, personeditdlg.rowIndEMail, row );
267                 personeditdlg.rowIndEMail = row;
268                 if (!personeditdlg.read_only) {
269                         gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
270                         gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, row + 1) != NULL);
271                 }
272         } else {
273                 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
274                 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
275         }
276         edit_person_email_clear( NULL );
277         edit_person_status_show( NULL );
278 }
279
280 static void edit_person_email_move_up( gpointer data ) {
281         edit_person_email_move( -1 );
282 }
283
284 static void edit_person_email_move_down( gpointer data ) {
285         edit_person_email_move( +1 );
286 }
287
288 static void edit_person_email_delete( gpointer data ) {
289         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
290         gint row = personeditdlg.rowIndEMail;
291         ItemEMail *email = gtk_clist_get_row_data( clist, row );
292         edit_person_email_clear( NULL );
293         if( email ) {
294                 /* Remove list entry */
295                 gtk_clist_remove( clist, row );
296                 addritem_free_item_email( email );
297                 email = NULL;
298         }
299
300         /* Position hilite bar */
301         email = gtk_clist_get_row_data( clist, row );
302         if( ! email ) {
303                 personeditdlg.rowIndEMail = -1 + row;
304         }
305         if (!personeditdlg.read_only) {
306                 gtk_widget_set_sensitive(personeditdlg.email_del, gtk_clist_get_row_data(clist, 0) != NULL);
307                 gtk_widget_set_sensitive(personeditdlg.email_up, gtk_clist_get_row_data(clist, personeditdlg.rowIndEMail + 1) != NULL);
308                 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, personeditdlg.rowIndEMail - 1) != NULL);
309         }
310         edit_person_status_show( NULL );
311 }
312
313 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
314         ItemEMail *retVal = NULL;
315         gchar *sEmail, *sAlias, *sRemarks, *sEmail_;
316
317         *error = TRUE;
318         sEmail_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
319         sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
320         sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
321         sEmail = mgu_email_check_empty( sEmail_ );
322         g_free( sEmail_ );
323
324         if( sEmail ) {
325                 if( email == NULL ) {
326                         email = addritem_create_item_email();
327                 }
328                 addritem_email_set_address( email, sEmail );
329                 addritem_email_set_alias( email, sAlias );
330                 addritem_email_set_remarks( email, sRemarks );
331                 retVal = email;
332                 *error = FALSE;
333         }
334         else {
335                 edit_person_status_show( _( "An Email address must be supplied." ) );
336         }
337
338         g_free( sEmail );
339         g_free( sAlias );
340         g_free( sRemarks );
341
342         return retVal;
343 }
344
345 static void edit_person_email_modify( gpointer data ) {
346         gboolean errFlg = FALSE;
347         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
348         gint row = personeditdlg.rowIndEMail;
349         ItemEMail *email = gtk_clist_get_row_data( clist, row );
350         if( email ) {
351                 edit_person_email_edit( &errFlg, email );
352                 if( ! errFlg ) {
353                         gtk_clist_set_text( clist, row, EMAIL_COL_EMAIL, email->address );
354                         gtk_clist_set_text( clist, row, EMAIL_COL_ALIAS, email->obj.name );
355                         gtk_clist_set_text( clist, row, EMAIL_COL_REMARKS, email->remarks );
356                         edit_person_email_clear( NULL );
357                 }
358         }
359 }
360
361 static void edit_person_email_add( gpointer data ) {
362         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
363         gboolean errFlg = FALSE;
364         ItemEMail *email = NULL;
365         gint row = personeditdlg.rowIndEMail;
366         if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
367
368         email = edit_person_email_edit( &errFlg, NULL );
369         if( ! errFlg ) {
370                 gchar *text[ EMAIL_N_COLS ];
371                 text[ EMAIL_COL_EMAIL   ] = email->address;
372 #ifndef MAEMO
373                 text[ EMAIL_COL_ALIAS   ] = email->obj.name;
374                 text[ EMAIL_COL_REMARKS ] = email->remarks;
375 #endif
376                 row = gtk_clist_insert( clist, 1 + row, text );
377                 gtk_clist_set_row_data( clist, row, email );
378                 gtk_clist_select_row( clist, row, 0 );
379                 edit_person_email_clear( NULL );
380         }
381 }
382
383 /*
384 * Comparison using cell contents (text in first column). Used for sort
385 * address index widget.
386 */
387 static gint edit_person_attrib_compare_func(
388         GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2 )
389 {
390         GtkCell *cell1 = ((GtkCListRow *)ptr1)->cell;
391         GtkCell *cell2 = ((GtkCListRow *)ptr2)->cell;
392         gchar *name1 = NULL, *name2 = NULL;
393
394         if( cell1 ) name1 = cell1->u.text;
395         if( cell2 ) name2 = cell2->u.text;
396         if( ! name1 ) return ( name2 != NULL );
397         if( ! name2 ) return -1;
398         return g_utf8_collate( name1, name2 );
399 }
400
401 static gboolean list_find_attribute(const gchar *attr)
402 {
403         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
404         UserAttribute *attrib;
405         gint row = 0;
406         while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
407                 if (!g_ascii_strcasecmp(attrib->name, attr)) {
408                         gtk_clist_select_row(clist, row, 0);
409                         return TRUE;
410                 }
411                 row++;
412         }
413         return FALSE;
414 }
415
416 static gboolean list_find_email(const gchar *addr)
417 {
418         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
419         ItemEMail *email;
420         gint row = 0;
421         while( (email = gtk_clist_get_row_data( clist, row )) ) {
422                 if (!g_ascii_strcasecmp(email->address, addr)) {
423                         gtk_clist_select_row(clist, row, 0);
424                         return TRUE;
425                 }
426                 row++;
427         }
428         return FALSE;
429 }
430
431 /*
432 * Load clist with a copy of person's email addresses.
433 */
434 static void edit_person_load_attrib( ItemPerson *person ) {
435         GList *node = person->listAttrib;
436         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
437         gchar *text[ ATTRIB_N_COLS ];
438         while( node ) {
439                 UserAttribute *atorig = ( UserAttribute * ) node->data;
440                 UserAttribute *attrib = addritem_copy_attribute( atorig );
441                 gint row;
442                 debug_print("name: %s value: %s\n", attrib->name, attrib->value);
443                 text[ ATTRIB_COL_NAME  ] = attrib->name;
444                 text[ ATTRIB_COL_VALUE ] = attrib->value;
445
446                 row = gtk_clist_append( clist, text );
447                 gtk_clist_set_row_data( clist, row, attrib );
448                 node = g_list_next( node );
449         }
450 }
451
452 static void edit_person_attrib_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
453         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
454         if( attrib && !personeditdlg.read_only && !personeditdlg.ldap ) {
455                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), attrib->name );
456                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
457                 gtk_widget_set_sensitive(personeditdlg.attrib_del, TRUE);
458         } else {
459                 gtk_widget_set_sensitive(personeditdlg.attrib_del, FALSE);
460         }
461         personeditdlg.rowIndAttrib = row;
462         edit_person_status_show( NULL );
463 }
464
465 static void edit_person_attrib_delete( gpointer data ) {
466         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
467         gint row = personeditdlg.rowIndAttrib;
468         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
469         edit_person_attrib_clear( NULL );
470         if( attrib ) {
471                 /* Remove list entry */
472                 gtk_clist_remove( clist, row );
473                 addritem_free_attribute( attrib );
474                 attrib = NULL;
475         }
476
477         /* Position hilite bar */
478         attrib = gtk_clist_get_row_data( clist, row );
479         if( ! attrib ) {
480                 personeditdlg.rowIndAttrib = -1 + row;
481         } 
482         
483         if (!personeditdlg.read_only && !personeditdlg.ldap)
484                 gtk_widget_set_sensitive(personeditdlg.attrib_del, gtk_clist_get_row_data(clist, 0) != NULL);
485         
486         edit_person_status_show( NULL );
487 }
488
489 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
490         UserAttribute *retVal = NULL;
491         gchar *sName, *sValue, *sName_, *sValue_;
492
493         *error = TRUE;
494         sName_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atname), 0, -1 );
495         sValue_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
496         sName = mgu_email_check_empty( sName_ );
497         sValue = mgu_email_check_empty( sValue_ );
498         g_free( sName_ );
499         g_free( sValue_ );
500
501         if( sName && sValue ) {
502                 if( attrib == NULL ) {
503                         attrib = addritem_create_attribute();
504                 }
505                 addritem_attrib_set_name( attrib, sName );
506                 addritem_attrib_set_value( attrib, sValue );
507                 retVal = attrib;
508                 *error = FALSE;
509         }
510         else {
511                 edit_person_status_show( _( "A Name and Value must be supplied." ) );
512         }
513
514         g_free( sName );
515         g_free( sValue );
516
517         return retVal;
518 }
519
520 static void edit_person_attrib_modify( gpointer data ) {
521         gboolean errFlg = FALSE;
522         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
523         gint row = personeditdlg.rowIndAttrib;
524         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
525         if( attrib ) {
526                 edit_person_attrib_edit( &errFlg, attrib );
527                 if( ! errFlg ) {
528                         gtk_clist_set_text( clist, row, ATTRIB_COL_NAME, attrib->name );
529                         gtk_clist_set_text( clist, row, ATTRIB_COL_VALUE, attrib->value );
530                         edit_person_attrib_clear( NULL );
531                 }
532         }
533 }
534
535 static void edit_person_attrib_add( gpointer data ) {
536         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
537         gboolean errFlg = FALSE;
538         UserAttribute *attrib = NULL;
539         gint row = personeditdlg.rowIndAttrib;
540         if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
541
542         attrib = edit_person_attrib_edit( &errFlg, NULL );
543         if( ! errFlg ) {
544                 gchar *text[ ATTRIB_N_COLS ];
545                 text[ ATTRIB_COL_NAME  ] = attrib->name;
546                 text[ ATTRIB_COL_VALUE ] = attrib->value;
547
548                 row = gtk_clist_insert( clist, 1 + row, text );
549                 gtk_clist_set_row_data( clist, row, attrib );
550                 gtk_clist_select_row( clist, row, 0 );
551                 edit_person_attrib_clear( NULL );
552         }
553 }
554
555 /*!
556  *\brief        Save Gtk object size to prefs dataset
557  */
558 static void edit_person_size_allocate_cb(GtkWidget *widget,
559                                          GtkAllocation *allocation)
560 {
561         g_return_if_fail(allocation != NULL);
562
563         prefs_common.addressbookeditpersonwin_width = allocation->width;
564         prefs_common.addressbookeditpersonwin_height = allocation->height;
565 }
566
567 /* build edit person widgets, return a pointer to the main container of the widgetset (a vbox) */
568 static GtkWidget* addressbook_edit_person_widgets_create( GtkWidget* container, gboolean *cancelled )
569 {
570         GtkWidget *vbox;
571         GtkWidget *vnbox;
572         GtkWidget *notebook;
573         GtkWidget *hbbox;
574         GtkWidget *ok_btn;
575         GtkWidget *cancel_btn;
576
577         vbox = gtk_vbox_new(FALSE, 4);
578          gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH); 
579         gtk_widget_show(vbox);
580         gtk_container_add(GTK_CONTAINER(container), vbox);
581
582         vnbox = gtk_vbox_new(FALSE, 4);
583         gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
584         gtk_widget_show(vnbox);
585         gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
586
587         /* Notebook */
588         notebook = gtk_notebook_new();
589         gtk_widget_show(notebook);
590         gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
591         gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
592
593         /* Button panel */
594         if (prefs_common.addressbook_use_editaddress_dialog)
595         gtkut_stock_button_set_create(&hbbox, &cancel_btn, GTK_STOCK_CANCEL,
596                                       &ok_btn, GTK_STOCK_OK,
597                                       NULL, NULL);
598         else
599                 gtkut_stock_with_text_button_set_create(&hbbox,
600                                           &cancel_btn, GTK_STOCK_CANCEL, _("Discard"),
601                                       &ok_btn, GTK_STOCK_OK, _("Apply"),
602                                       NULL, NULL, NULL);
603         gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
604         gtk_widget_grab_default(ok_btn);
605
606         g_signal_connect(G_OBJECT(ok_btn), "clicked",
607                          G_CALLBACK(edit_person_ok), cancelled);
608         g_signal_connect(G_OBJECT(cancel_btn), "clicked",
609                          G_CALLBACK(edit_person_cancel), cancelled);
610         g_signal_connect(G_OBJECT(notebook), "switch_page",
611                          G_CALLBACK(edit_person_switch_page), NULL );
612
613         gtk_widget_show_all(vbox);
614
615         personeditdlg.notebook   = notebook;
616         personeditdlg.ok_btn     = ok_btn;
617         personeditdlg.cancel_btn = cancel_btn;
618
619         return vbox;
620 }
621
622 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
623         GtkWidget *window;
624         GtkWidget *hsbox;
625         GtkWidget *vbox;
626         GtkWidget *statusbar;
627         static GdkGeometry geometry;
628
629         window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "editaddress");
630         /* gtk_container_set_border_width(GTK_CONTAINER(window), 0); */
631         gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
632         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
633         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
634         g_signal_connect(G_OBJECT(window), "delete_event",
635                          G_CALLBACK(edit_person_delete_event),
636                          cancelled);
637         g_signal_connect(G_OBJECT(window), "size_allocate",
638                          G_CALLBACK(edit_person_size_allocate_cb),
639                         cancelled);
640         g_signal_connect(G_OBJECT(window), "key_press_event",
641                          G_CALLBACK(edit_person_key_pressed),
642                          cancelled);
643
644         vbox = addressbook_edit_person_widgets_create(window, cancelled);
645
646         /* Status line */
647         hsbox = gtk_hbox_new(FALSE, 0);
648         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
649         statusbar = gtk_statusbar_new();
650         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
651
652         if (!geometry.min_height) {
653                 geometry.min_width = EDITPERSON_WIDTH;
654                 geometry.min_height = EDITPERSON_HEIGHT;
655         }
656
657         gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
658                                       GDK_HINT_MIN_SIZE);
659         gtk_widget_set_size_request(window, prefs_common.addressbookeditpersonwin_width,
660                                     prefs_common.addressbookeditpersonwin_height);
661
662         personeditdlg.container  = window;
663         personeditdlg.statusbar  = statusbar;
664         personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
665
666 }
667
668 /* parent must be a box */
669 static void addressbook_edit_person_widgetset_create( GtkWidget *parent, gboolean *cancelled )
670 {
671         GtkWidget *vbox;
672         GtkWidget *label;
673
674         if ( parent == NULL )
675                 g_warning("addressbook_edit_person_widgetset_create: parent is NULL");
676
677         vbox = gtk_vbox_new(FALSE, 0);
678         gtk_box_pack_end(GTK_BOX(parent), vbox, TRUE, TRUE, 0);
679
680         label = gtk_label_new(_("Edit Person Data"));
681         gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER);
682         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
683
684         addressbook_edit_person_widgets_create(vbox, cancelled);
685
686         gtk_widget_set_size_request(vbox, EDITPERSON_WIDTH, EDITPERSON_HEIGHT);
687
688         personeditdlg.container = vbox;
689         personeditdlg.title = label;
690         personeditdlg.statusbar  = NULL;
691         personeditdlg.status_cid = 0;
692 }
693
694 void addressbook_edit_person_widgetset_hide( void )
695 {
696         if ( personeditdlg.container )
697                 gtk_widget_hide( personeditdlg.container );
698 }
699
700 static void addressbook_edit_person_unset_picture (void *obj, guint action, void *data)
701 {
702         personeditdlg.pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 48, 48);
703         gdk_pixbuf_fill(personeditdlg.pixbuf, 0xffffff00);
704         personeditdlg.picture_set = FALSE;
705         gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), personeditdlg.pixbuf);
706 }
707
708 static GtkItemFactoryEntry editaddr_popup_entries[] =
709 {
710         {N_("/_Unset picture"),         NULL, addressbook_edit_person_unset_picture, 0, NULL},
711 };
712
713 static void addressbook_edit_person_set_picture(GtkWidget *widget, 
714                 GdkEventButton *event, gpointer data)
715 {
716         GError *error = NULL;
717         gchar *filename;
718         int width, height, scalewidth, scaleheight;
719         
720         if (event->button == 1) {
721                 if ( (filename = filesel_select_file_open(_("Choose a picture"), NULL)) ) {
722                         personeditdlg.pixbuf = gdk_pixbuf_new_from_file(filename, &error);
723                         personeditdlg.picture_set = TRUE;
724                         g_free(filename);
725                         width = gdk_pixbuf_get_width(personeditdlg.pixbuf);
726                         height = gdk_pixbuf_get_height(personeditdlg.pixbuf);
727
728                         if ( width > 128 || height > 128 ) {
729                                 if (width > height) {
730                                         scaleheight = (height * 128) / width;
731                                         scalewidth = 128;
732                                 }
733                                 else {
734                                         scalewidth = (width * 128) / height;
735                                         scaleheight = 128;
736                                 }
737                                 personeditdlg.pixbuf = gdk_pixbuf_scale_simple(personeditdlg.pixbuf, scalewidth, scaleheight, GDK_INTERP_BILINEAR);
738                         }
739                 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), personeditdlg.pixbuf);
740                 }
741         } else {
742                 gtk_menu_popup(GTK_MENU(personeditdlg.editaddr_popupmenu), 
743                                NULL, NULL, NULL, NULL, 
744                                event->button, event->time);
745         }
746 }
747
748 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
749         GtkWidget *vbox;
750         GtkWidget *hbox;
751         GtkWidget *table;
752         GtkWidget *label;
753         GtkWidget *ebox_picture;
754         GtkWidget *frame_picture;
755         GtkWidget *entry_name;
756         GtkWidget *entry_fn;
757         GtkWidget *entry_ln;
758         GtkWidget *entry_nn;
759         const gchar *locale;
760         gint top = 0;
761         gint n_entries;
762
763         vbox = gtk_vbox_new( FALSE, 20 );
764         hbox = gtk_hbox_new( FALSE, 8 );
765
766         gtk_widget_show( vbox );        
767         
768         /* User's picture */
769         ebox_picture = gtk_event_box_new();
770         frame_picture = gtk_frame_new("Photo");
771         
772         /* Room for a photo */
773         personeditdlg.pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 48, 48);
774         gdk_pixbuf_fill(personeditdlg.pixbuf, 0xffffff00);
775         personeditdlg.picture_set = FALSE;
776         personeditdlg.image = gtk_image_new_from_pixbuf(personeditdlg.pixbuf);
777         
778         gtk_container_add(GTK_CONTAINER(ebox_picture), personeditdlg.image);
779         gtk_container_add(GTK_CONTAINER(frame_picture), ebox_picture);  
780         gtk_container_add(GTK_CONTAINER( personeditdlg.notebook ), hbox );
781         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
782         gtk_container_set_border_width( GTK_CONTAINER (hbox), BORDER_WIDTH );
783
784         label = gtk_label_new_with_mnemonic( pageLbl );
785         gtk_widget_show( label );
786         
787         gtk_box_pack_start(GTK_BOX(hbox), frame_picture, TRUE, TRUE, 0);
788         
789         gtk_notebook_set_tab_label(
790                 GTK_NOTEBOOK( personeditdlg.notebook ),
791                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
792         
793         g_signal_connect(G_OBJECT(ebox_picture), "button_press_event", 
794                         G_CALLBACK(addressbook_edit_person_set_picture), NULL);
795
796         n_entries = sizeof(editaddr_popup_entries) /
797                 sizeof(editaddr_popup_entries[0]);
798         personeditdlg.editaddr_popupmenu = menu_create_items(editaddr_popup_entries, n_entries,
799                                       "<EditAddrPopupMenu>", &personeditdlg.editaddr_popupfactory,
800                                       NULL);
801
802         table = gtk_table_new( 3, 3, FALSE);
803
804 #define ATTACH_ROW(text, entry) \
805 { \
806         label = gtk_label_new(text); \
807         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
808                          GTK_FILL, 0, 0, 0); \
809         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
810  \
811         entry = gtk_entry_new(); \
812         gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
813                          GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
814         top++; \
815 }
816
817 #define ATTACH_HIDDEN_ROW(text, entry) \
818 { \
819         entry = gtk_entry_new(); \
820 }
821
822 #ifndef MAEMO
823         ATTACH_ROW(_("Display Name"), entry_name);
824 #else
825         ATTACH_HIDDEN_ROW(_("Display Name"), entry_name);
826 #endif
827         locale = conv_get_current_locale();
828         if (locale &&
829             (!g_ascii_strncasecmp(locale, "ja", 2) ||
830              !g_ascii_strncasecmp(locale, "ko", 2) ||
831              !g_ascii_strncasecmp(locale, "zh", 2))) {
832                 ATTACH_ROW(_("Last Name"), entry_ln);
833                 ATTACH_ROW(_("First Name"), entry_fn);
834         } else {
835                 ATTACH_ROW(_("First Name"), entry_fn);
836                 ATTACH_ROW(_("Last Name"), entry_ln);
837         }
838 #ifndef MAEMO
839         ATTACH_ROW(_("Nickname"), entry_nn);
840 #else
841         ATTACH_HIDDEN_ROW(_("Nickname"), entry_nn);
842 #endif
843
844 #undef ATTACH_ROW
845 #undef ATTACH_HIDDEN_ROW
846         gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
847         gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
848         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
849         gtk_table_set_row_spacings(GTK_TABLE(table), 15);
850         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
851
852         gtk_widget_show_all(vbox);
853         personeditdlg.entry_name  = entry_name;
854         personeditdlg.entry_first = entry_fn;
855         personeditdlg.entry_last  = entry_ln;
856         personeditdlg.entry_nick  = entry_nn;
857 }
858
859 static gboolean email_adding = FALSE, email_saving = FALSE;
860
861 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
862 {
863         gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_email), 0) != NULL;
864
865         if (personeditdlg.read_only)
866                 return;
867
868         if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)) == NULL
869         ||  strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email))) == 0) {
870                 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
871                 gtk_widget_set_sensitive(personeditdlg.email_mod,FALSE);
872                 email_adding = FALSE;
873                 email_saving = FALSE;
874         } else if (list_find_email(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)))) {
875                 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
876                 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
877                 email_adding = FALSE;
878                 email_saving = non_empty;
879         } else {
880                 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
881                 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
882                 email_adding = TRUE;
883                 email_saving = non_empty;
884         }
885 }
886
887 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
888 {
889         if (event && event->keyval == GDK_Return) {
890                 if (email_saving)
891                         edit_person_email_modify(NULL);         
892                 else if (email_adding)
893                         edit_person_email_add(NULL);
894         }
895         return FALSE;
896 }
897
898
899 static void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
900         GtkWidget *vbox;
901         GtkWidget *hbox;
902         GtkWidget *vboxl;
903         GtkWidget *vboxb;
904         GtkWidget *vbuttonbox;
905         GtkWidget *buttonUp;
906         GtkWidget *buttonDown;
907         GtkWidget *buttonDel;
908         GtkWidget *buttonMod;
909         GtkWidget *buttonAdd;
910
911         GtkWidget *table;
912         GtkWidget *label;
913         GtkWidget *clist_swin;
914         GtkWidget *clist;
915         GtkWidget *entry_email;
916         GtkWidget *entry_alias;
917         GtkWidget *entry_remarks;
918         gint top;
919
920         gchar *titles[ EMAIL_N_COLS ];
921         gint i;
922
923         titles[ EMAIL_COL_EMAIL   ] = _("Email Address");
924 #ifndef MAEMO
925         titles[ EMAIL_COL_ALIAS   ] = _("Alias");
926         titles[ EMAIL_COL_REMARKS ] = _("Remarks");
927 #endif
928         vbox = gtk_vbox_new( FALSE, 8 );
929         gtk_widget_show( vbox );
930         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
931         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
932
933         label = gtk_label_new_with_mnemonic( pageLbl );
934         gtk_widget_show( label );
935         gtk_notebook_set_tab_label(
936                 GTK_NOTEBOOK( personeditdlg.notebook ),
937                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
938
939         /* Split into two areas */
940         hbox = gtk_hbox_new( FALSE, 0 );
941         gtk_container_add( GTK_CONTAINER( vbox ), hbox );
942
943         /* Address list */
944         vboxl = gtk_vbox_new( FALSE, 4 );
945         gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
946         gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
947
948         clist_swin = gtk_scrolled_window_new( NULL, NULL );
949         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
950                                        GTK_POLICY_AUTOMATIC,
951                                        GTK_POLICY_AUTOMATIC);
952
953         clist = gtk_clist_new_with_titles( EMAIL_N_COLS, titles );
954
955         gtk_container_add( GTK_CONTAINER(clist_swin), clist );
956         gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
957         gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_EMAIL, EMAIL_COL_WIDTH_EMAIL );
958         gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_ALIAS, EMAIL_COL_WIDTH_ALIAS );
959
960         for( i = 0; i < EMAIL_N_COLS; i++ )
961                 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
962
963         /* Data entry area */
964         table = gtk_table_new( 4, 2, FALSE);
965
966 #ifndef MAEMO
967         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
968         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
969 #else
970         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
971         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
972         gtk_clist_column_titles_hide(GTK_CLIST(clist));
973 #endif
974         gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
975         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
976         gtk_table_set_col_spacings(GTK_TABLE(table), 4);
977
978         entry_email = gtk_entry_new();
979         entry_alias = gtk_entry_new();
980         entry_remarks = gtk_entry_new();
981
982         /* First row */
983         top = 0;
984         label = gtk_label_new(_("Email Address"));
985         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
986         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
987
988         gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
989
990 #ifndef MAEMO
991         /* Next row */
992         ++top;
993         label = gtk_label_new(_("Alias"));
994         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
995         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
996
997         gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
998
999         /* Next row */
1000         ++top;
1001         label = gtk_label_new(_("Remarks"));
1002         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1003         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1004
1005         gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1006 #endif
1007
1008         /* Button box */
1009         vboxb = gtk_vbox_new( FALSE, 4 );
1010         gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1011
1012         vbuttonbox = gtk_vbutton_box_new();
1013         gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1014         gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1015         gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1016         gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1017
1018         /* Buttons */
1019         buttonUp = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
1020         buttonDown = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
1021         buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1022         buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1023         buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1024         
1025
1026 #ifndef MAEMO
1027         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
1028
1029         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
1030 #endif
1031         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1032
1033         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1034
1035         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1036
1037         gtk_widget_show_all(vbox);
1038
1039         /* Event handlers */
1040         g_signal_connect( G_OBJECT(clist), "select_row",
1041                           G_CALLBACK( edit_person_email_list_selected), NULL );
1042         g_signal_connect( G_OBJECT(buttonUp), "clicked",
1043                           G_CALLBACK( edit_person_email_move_up ), NULL );
1044         g_signal_connect( G_OBJECT(buttonDown), "clicked",
1045                           G_CALLBACK( edit_person_email_move_down ), NULL );
1046         g_signal_connect( G_OBJECT(buttonDel), "clicked",
1047                           G_CALLBACK( edit_person_email_delete ), NULL );
1048         g_signal_connect( G_OBJECT(buttonMod), "clicked",
1049                           G_CALLBACK( edit_person_email_modify ), NULL );
1050         g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1051                           G_CALLBACK( edit_person_email_add ), NULL );
1052         g_signal_connect(G_OBJECT(entry_email), "changed",
1053                          G_CALLBACK(edit_person_entry_email_changed), NULL);
1054         g_signal_connect(G_OBJECT(entry_email), "key_press_event",
1055                          G_CALLBACK(edit_person_entry_email_pressed), NULL);
1056         g_signal_connect(G_OBJECT(entry_alias), "key_press_event",
1057                          G_CALLBACK(edit_person_entry_email_pressed), NULL);
1058         g_signal_connect(G_OBJECT(entry_remarks), "key_press_event",
1059                          G_CALLBACK(edit_person_entry_email_pressed), NULL);
1060
1061         personeditdlg.clist_email   = clist;
1062         personeditdlg.entry_email   = entry_email;
1063         personeditdlg.entry_alias   = entry_alias;
1064         personeditdlg.entry_remarks = entry_remarks;
1065         personeditdlg.email_up = buttonUp;
1066         personeditdlg.email_down = buttonDown;
1067         personeditdlg.email_del = buttonDel;
1068         personeditdlg.email_mod = buttonMod;
1069         personeditdlg.email_add = buttonAdd;
1070 }
1071
1072 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
1073
1074 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
1075 {
1076         gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_attrib), 0) != NULL;
1077
1078         if (personeditdlg.read_only || personeditdlg.ldap)
1079                 return;
1080
1081         if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname)) == NULL
1082         ||  strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname))) == 0) {
1083                 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1084                 gtk_widget_set_sensitive(personeditdlg.attrib_mod,FALSE);
1085                 attrib_adding = FALSE;
1086                 attrib_saving = FALSE;
1087         } else if (list_find_attribute(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname)))) {
1088                 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1089                 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1090                 attrib_adding = FALSE;
1091                 attrib_saving = non_empty;
1092         } else {
1093                 gtk_widget_set_sensitive(personeditdlg.attrib_add,TRUE);
1094                 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1095                 attrib_adding = TRUE;
1096                 attrib_saving = non_empty;
1097         }
1098 }
1099
1100 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1101 {
1102         if (event && event->keyval == GDK_Return) {
1103                 if (attrib_saving)
1104                         edit_person_attrib_modify(NULL);
1105                 else if (attrib_adding)
1106                         edit_person_attrib_add(NULL);
1107         }
1108         return FALSE;
1109 }
1110
1111 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
1112         GtkWidget *vbox;
1113         GtkWidget *hbox;
1114         GtkWidget *vboxl;
1115         GtkWidget *vboxb;
1116         GtkWidget *vbuttonbox;
1117         GtkWidget *buttonDel;
1118         GtkWidget *buttonMod;
1119         GtkWidget *buttonAdd;
1120
1121         GtkWidget *table;
1122         GtkWidget *label;
1123         GtkWidget *clist_swin;
1124         GtkWidget *clist;
1125         GtkWidget *entry_name;
1126         GtkWidget *entry_value;
1127         gint top;
1128
1129         gchar *titles[ ATTRIB_N_COLS ];
1130         gint i;
1131
1132         titles[ ATTRIB_COL_NAME  ] = _("Name");
1133         titles[ ATTRIB_COL_VALUE ] = _("Value");
1134
1135         vbox = gtk_vbox_new( FALSE, 8 );
1136         gtk_widget_show( vbox );
1137         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1138         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1139
1140         label = gtk_label_new_with_mnemonic( pageLbl );
1141         gtk_widget_show( label );
1142         gtk_notebook_set_tab_label(
1143                 GTK_NOTEBOOK( personeditdlg.notebook ),
1144                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1145
1146         /* Split into two areas */
1147         hbox = gtk_hbox_new( FALSE, 0 );
1148         gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1149
1150         /* Attribute list */
1151         vboxl = gtk_vbox_new( FALSE, 4 );
1152         gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1153         gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1154
1155         clist_swin = gtk_scrolled_window_new( NULL, NULL );
1156         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
1157                                        GTK_POLICY_AUTOMATIC,
1158                                        GTK_POLICY_AUTOMATIC);
1159
1160         clist = gtk_clist_new_with_titles( ATTRIB_N_COLS, titles );
1161         gtk_container_add( GTK_CONTAINER(clist_swin), clist );
1162         gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
1163         gtk_clist_set_compare_func( GTK_CLIST(clist), edit_person_attrib_compare_func );
1164         gtk_clist_set_auto_sort( GTK_CLIST(clist), TRUE );
1165         gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_NAME, ATTRIB_COL_WIDTH_NAME );
1166         gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_VALUE, ATTRIB_COL_WIDTH_VALUE );
1167
1168         for( i = 0; i < ATTRIB_N_COLS; i++ )
1169                 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
1170
1171         /* Data entry area */
1172 #ifndef MAEMO
1173         table = gtk_table_new( 4, 2, FALSE);
1174         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1175         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1176 #else
1177         table = gtk_table_new( 2, 4, FALSE);
1178         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1179         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1180         gtk_clist_column_titles_hide(GTK_CLIST(clist));
1181 #endif
1182         gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1183         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1184         gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1185
1186         /* First row */
1187         top = 0;
1188 #ifndef MAEMO
1189         label = gtk_label_new(_("Name"));
1190         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1191         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1192
1193         entry_name = gtk_entry_new();
1194         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1195
1196         /* Next row */
1197         ++top;
1198         label = gtk_label_new(_("Value"));
1199         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1200         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1201
1202         entry_value = gtk_entry_new();
1203         gtk_table_attach(GTK_TABLE(table), entry_value, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1204 #else
1205         label = gtk_label_new(_("Name"));
1206         gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1207         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1208
1209         entry_name = gtk_entry_new();
1210         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1211
1212         /* Next row */
1213         ++top;
1214         label = gtk_label_new(_("Value"));
1215         gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
1216         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1217
1218         entry_value = gtk_entry_new();
1219         gtk_table_attach(GTK_TABLE(table), entry_value, 3, 4, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1220 #endif
1221         /* Button box */
1222         vboxb = gtk_vbox_new( FALSE, 4 );
1223         gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1224
1225         vbuttonbox = gtk_vbutton_box_new();
1226         gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1227         gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1228         gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1229         gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1230
1231         /* Buttons */
1232         buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1233         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1234
1235         buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1236         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1237
1238         buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1239         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1240         
1241         gtk_widget_set_sensitive(buttonDel,FALSE);
1242         gtk_widget_set_sensitive(buttonMod,FALSE);
1243         gtk_widget_set_sensitive(buttonAdd,FALSE);
1244
1245         gtk_widget_show_all(vbox);
1246
1247         /* Event handlers */
1248         g_signal_connect( G_OBJECT(clist), "select_row",
1249                           G_CALLBACK( edit_person_attrib_list_selected), NULL );
1250         g_signal_connect( G_OBJECT(buttonDel), "clicked",
1251                           G_CALLBACK( edit_person_attrib_delete ), NULL );
1252         g_signal_connect( G_OBJECT(buttonMod), "clicked",
1253                           G_CALLBACK( edit_person_attrib_modify ), NULL );
1254         g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1255                           G_CALLBACK( edit_person_attrib_add ), NULL );
1256         g_signal_connect(G_OBJECT(entry_name), "changed",
1257                          G_CALLBACK(edit_person_entry_att_changed), NULL);
1258         g_signal_connect(G_OBJECT(entry_name), "key_press_event",
1259                          G_CALLBACK(edit_person_entry_att_pressed), NULL);
1260         g_signal_connect(G_OBJECT(entry_value), "key_press_event",
1261                          G_CALLBACK(edit_person_entry_att_pressed), NULL);
1262
1263         personeditdlg.clist_attrib  = clist;
1264         personeditdlg.entry_atname  = entry_name;
1265         personeditdlg.entry_atvalue = entry_value;
1266         personeditdlg.attrib_add = buttonAdd;
1267         personeditdlg.attrib_del = buttonDel;
1268         personeditdlg.attrib_mod = buttonMod;
1269 }
1270
1271 static void addressbook_edit_person_create( GtkWidget *parent, gboolean *cancelled ) {
1272         if (prefs_common.addressbook_use_editaddress_dialog)
1273                 addressbook_edit_person_dialog_create( cancelled );
1274         else
1275                 addressbook_edit_person_widgetset_create( parent, cancelled );
1276         addressbook_edit_person_page_basic( PAGE_BASIC, _( "_User Data" ) );
1277         addressbook_edit_person_page_email( PAGE_EMAIL, _( "_Email Addresses" ) );
1278 #ifdef USE_LDAP
1279         if (personeditdlg.ldap)
1280                 addressbook_edit_person_page_attrib_ldap(&personeditdlg, PAGE_ATTRIBUTES, _("O_ther Attributes"));
1281         else
1282 #endif
1283                 addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "O_ther Attributes" ) );
1284         gtk_widget_show_all( personeditdlg.container );
1285 }
1286
1287 /*
1288 * Return list of email items.
1289 */
1290 static GList *edit_person_build_email_list() {
1291         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
1292         GList *listEMail = NULL;
1293         ItemEMail *email;
1294         gint row = 0;
1295         while( (email = gtk_clist_get_row_data( clist, row )) ) {
1296                 listEMail = g_list_append( listEMail, email );
1297                 row++;
1298         }
1299         return listEMail;
1300 }
1301
1302 /*
1303 * Return list of attributes.
1304 */
1305 static GList *edit_person_build_attrib_list() {
1306         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
1307         GList *listAttrib = NULL;
1308         UserAttribute *attrib;
1309         gint row = 0;
1310         while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
1311                 listAttrib = g_list_append( listAttrib, attrib );
1312                 row++;
1313         }
1314         return listAttrib;
1315 }
1316
1317 static void update_sensitivity(void)
1318 {
1319         gtk_widget_set_sensitive(personeditdlg.entry_name,    !personeditdlg.read_only);
1320         gtk_widget_set_sensitive(personeditdlg.entry_first,   !personeditdlg.read_only);
1321         gtk_widget_set_sensitive(personeditdlg.entry_last,    !personeditdlg.read_only);
1322         gtk_widget_set_sensitive(personeditdlg.entry_nick,    !personeditdlg.read_only && !personeditdlg.ldap);
1323         gtk_widget_set_sensitive(personeditdlg.entry_email,   !personeditdlg.read_only);
1324         gtk_widget_set_sensitive(personeditdlg.entry_alias,   !personeditdlg.read_only && !personeditdlg.ldap);
1325         gtk_widget_set_sensitive(personeditdlg.entry_remarks, !personeditdlg.read_only && !personeditdlg.ldap);
1326         gtk_widget_set_sensitive(personeditdlg.email_up,      !personeditdlg.read_only);
1327         gtk_widget_set_sensitive(personeditdlg.email_down,    !personeditdlg.read_only);
1328         gtk_widget_set_sensitive(personeditdlg.email_del,     !personeditdlg.read_only);
1329         gtk_widget_set_sensitive(personeditdlg.email_mod,     !personeditdlg.read_only);
1330         gtk_widget_set_sensitive(personeditdlg.email_add,     !personeditdlg.read_only);
1331         gtk_widget_set_sensitive(personeditdlg.entry_atname,  !personeditdlg.read_only);
1332         gtk_widget_set_sensitive(personeditdlg.entry_atvalue, !personeditdlg.read_only);
1333         gtk_widget_set_sensitive(personeditdlg.attrib_add,    !personeditdlg.read_only);
1334         gtk_widget_set_sensitive(personeditdlg.attrib_del,    !personeditdlg.read_only);
1335         gtk_widget_set_sensitive(personeditdlg.attrib_mod,    !personeditdlg.read_only);
1336 }
1337
1338 static void addressbook_edit_person_flush_transient( void )
1339 {
1340         ItemPerson *person = current_person;
1341         EditAddressPostUpdateCallback callback = edit_person_close_post_update_cb;
1342
1343         /* reset transient data */
1344         current_abf = NULL;
1345         current_person = NULL;
1346         current_parent_folder = NULL;
1347         edit_person_close_post_update_cb = NULL;
1348
1349         /* post action to perform on addressbook side */
1350         if (callback)
1351                 callback( person );
1352 }
1353
1354 void addressbook_edit_person_invalidate( AddressBookFile *abf, ItemFolder *parent_folder,
1355                                                                                  ItemPerson *person )
1356 {
1357         if (current_abf == NULL &&
1358                 current_person == NULL &&
1359                 current_parent_folder == NULL)
1360                 /* edit address form is already hidden */
1361                 return;
1362
1363         /* unconditional invalidation or invalidating the currently edited item */
1364         if ( ( abf == NULL && person == NULL && parent_folder == NULL )
1365                 || (current_abf == abf ||
1366                         current_person == person ||
1367                         current_parent_folder == parent_folder))
1368                 addressbook_edit_person_close( TRUE );
1369 }
1370
1371 static gboolean addressbook_edit_person_close( gboolean cancelled )
1372 {
1373         GList *listEMail = NULL;
1374         GList *listAttrib = NULL;
1375         GError *error;
1376         gchar *cn = NULL;
1377
1378         listEMail = edit_person_build_email_list();
1379         listAttrib = edit_person_build_attrib_list();
1380         if( cancelled ) {
1381                 addritem_free_list_email( listEMail );
1382                 addritem_free_list_attribute( listAttrib );
1383                 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1384                 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1385
1386                 if (!prefs_common.addressbook_use_editaddress_dialog)
1387                         gtk_widget_hide( personeditdlg.container );
1388
1389                 /* no callback, as we're discarding the form */
1390                 edit_person_close_post_update_cb = NULL;
1391                 addressbook_edit_person_flush_transient();
1392
1393                 /* set focus to the address list (this is done by the post_update_cb usually) */
1394                 addressbook_address_list_set_focus();
1395                 return FALSE;
1396         }
1397
1398 #ifndef MAEMO
1399         cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
1400 #else
1401         {
1402                 gchar *first = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1403                 gchar *last = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1404                 cn = g_strdup_printf("%s%s%s", first, (first && last && *first && *last)?" ":"", last);
1405                 g_free(first);
1406                 g_free(last);
1407         }
1408 #endif
1409         if( current_person && current_abf ) {
1410                 /* Update email/attribute list for existing current_person */
1411                 addrbook_update_address_list( current_abf, current_person, listEMail );
1412                 addrbook_update_attrib_list( current_abf, current_person, listAttrib );
1413         }
1414         else {
1415                 /* Create new current_person and email/attribute list */
1416                 if( cn == NULL || *cn == '\0' ) {
1417                         /* Wasting our time */
1418                         if( listEMail == NULL && listAttrib == NULL ) cancelled = TRUE;
1419                 }
1420                 if( ! cancelled && current_abf ) {
1421                         current_person = addrbook_add_address_list( current_abf, current_parent_folder, listEMail );
1422                         addrbook_add_attrib_list( current_abf, current_person, listAttrib );
1423                 }
1424         }
1425         listEMail = NULL;
1426         listAttrib = NULL;
1427
1428         if( ! cancelled ) {
1429                 /* Set current_person stuff */          
1430
1431                 gchar *name;
1432                 addritem_person_set_common_name( current_person, cn );
1433                 if (personeditdlg.picture_set) {
1434                         name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S, 
1435                                                         ADDRITEM_ID(current_person), NULL );
1436                         gdk_pixbuf_save(personeditdlg.pixbuf, name, "png", &error, NULL);
1437                         addritem_person_set_picture( current_person, ADDRITEM_ID(current_person) ) ;
1438                         g_free( name );
1439                 } else {
1440                         name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S, 
1441                                                         ADDRITEM_ID(current_person), NULL );
1442                         g_unlink(name);
1443                         g_free(name);
1444                 }
1445                 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1446                 addritem_person_set_first_name( current_person, name );
1447                 g_free( name );
1448                 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1449                 addritem_person_set_last_name( current_person, name );
1450                 g_free( name );
1451                 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1452                 addritem_person_set_nick_name( current_person, name );
1453                 g_free( name );
1454         }
1455         g_free( cn );
1456
1457         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1458         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1459
1460         if (!prefs_common.addressbook_use_editaddress_dialog)
1461                 gtk_widget_hide( personeditdlg.container );
1462
1463         addressbook_edit_person_flush_transient();
1464
1465         return TRUE;
1466 }
1467  
1468 /*
1469 * Edit person.
1470 * Enter: abf    Address book.
1471 *        parent Parent folder for person (or NULL if adding to root folder). Argument is
1472 *               only required for new objects).
1473 *        person Person to edit, or NULL for a new person object.
1474 *        pgMail If TRUE, E-Mail page will be activated.
1475 * Return: Edited object, or NULL if cancelled.*/
1476 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent_folder, ItemPerson *person,
1477                                                                          gboolean pgMail, GtkWidget *parent_container,
1478                                                                          void (*post_update_cb) (ItemPerson *person),
1479                                                                          gboolean get_focus) {
1480         static gboolean cancelled;
1481         GError *error = NULL;
1482
1483         /* set transient data */
1484         current_abf = abf;
1485         current_person = person;
1486         current_parent_folder = parent_folder;
1487         edit_person_close_post_update_cb = post_update_cb;
1488         personeditdlg.ldap = (abf && abf->type == ADBOOKTYPE_LDAP)? TRUE : FALSE;
1489         if( !personeditdlg.container )
1490                 addressbook_edit_person_create(parent_container, &cancelled);
1491
1492         /* typically, get focus when dialog mode is enabled, or when editing a new address */
1493         if( get_focus ) {
1494                 gtk_widget_grab_focus(personeditdlg.ok_btn);
1495                 gtk_widget_grab_focus(personeditdlg.entry_name);
1496         }
1497         
1498         personeditdlg.read_only = (current_abf == NULL);
1499         update_sensitivity();
1500
1501         gtk_widget_show(personeditdlg.container);
1502         if (prefs_common.addressbook_use_editaddress_dialog)
1503                 manage_window_set_transient(GTK_WINDOW(personeditdlg.container));
1504         else
1505                 if (get_focus)
1506                         addressbook_address_list_disable_some_actions();
1507
1508         /* Clear all fields */
1509         personeditdlg.rowIndEMail = -1;
1510         personeditdlg.rowIndAttrib = -1;
1511         edit_person_status_show( "" );
1512         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1513         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1514         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1515         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1516         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1517         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1518
1519         personeditdlg.editNew = FALSE;
1520         if( current_person ) {
1521                 if( ADDRITEM_NAME(current_person) )
1522                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1523
1524                 if( current_person->picture ) { 
1525                         gchar *filename = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S, 
1526                                                         current_person->picture, NULL );
1527                         if (is_file_exist(filename)) {
1528                                 personeditdlg.pixbuf = gdk_pixbuf_new_from_file(filename, &error);
1529                                 personeditdlg.picture_set = TRUE;
1530                         } else {
1531                                 personeditdlg.picture_set = FALSE;
1532                                 personeditdlg.pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 48, 48);
1533                                 gdk_pixbuf_fill(personeditdlg.pixbuf, 0xffffff00);
1534                         }
1535                         g_free(filename);
1536                 } else {
1537                         personeditdlg.picture_set = FALSE;
1538                         personeditdlg.pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 48, 48);
1539                         gdk_pixbuf_fill(personeditdlg.pixbuf, 0xffffff00);
1540                 }
1541                 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), personeditdlg.pixbuf);
1542
1543                 if( current_person->firstName )
1544                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), current_person->firstName );
1545                 if( current_person->lastName )
1546                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), current_person->lastName );
1547                 if( current_person->nickName )
1548                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), current_person->nickName );
1549                 edit_person_load_email( current_person );
1550                 edit_person_load_attrib( current_person );
1551                 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_atvalue), "");
1552         }
1553         else {
1554                 personeditdlg.editNew = TRUE;
1555         }
1556
1557         /* Select appropriate start page */
1558         if( pgMail ) {
1559                 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1560         }
1561         else {
1562                 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1563         }
1564
1565         gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_email), 0, 0 );
1566         gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_attrib), 0, 0 );
1567         edit_person_email_clear( NULL );
1568         if (current_person)
1569                 edit_person_email_list_selected(GTK_CLIST(personeditdlg.clist_email), 0, 0, NULL, NULL);
1570
1571         edit_person_attrib_clear( NULL );
1572
1573         if (prefs_common.addressbook_use_editaddress_dialog) {
1574
1575         gtk_main();
1576                 gtk_widget_hide( personeditdlg.container );
1577
1578                 if (!addressbook_edit_person_close( cancelled ))
1579                         return NULL;
1580         }
1581
1582         return current_person;
1583 }
1584
1585 /*
1586 * End of Source.
1587 */
1588