bca341f1bb9eb2b6dd7d3af9ad5504209cc7606f
[claws.git] / src / editaddress.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2001 Hiroyuki Yamamoto
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 2 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, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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 <gdk/gdkkeysyms.h>
28 #include <gtk/gtkwindow.h>
29 #include <gtk/gtksignal.h>
30 #include <gtk/gtklabel.h>
31 #include <gtk/gtkvbox.h>
32 #include <gtk/gtkentry.h>
33 #include <gtk/gtktable.h>
34
35 #include "intl.h"
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
44 #include "prefs_common.h"
45
46 /*
47 static struct _AddressEdit_dlg {
48         GtkWidget *window;
49         GtkWidget *name_entry;
50         GtkWidget *addr_entry;
51         GtkWidget *rem_entry;
52         GtkWidget *ok_btn;
53         GtkWidget *cancel_btn;
54 } addredit;
55 */
56
57 static struct _PersonEdit_dlg {
58         GtkWidget *window;
59         GtkWidget *notebook;
60         GtkWidget *ok_btn;
61         GtkWidget *cancel_btn;
62         GtkWidget *statusbar;
63         gint status_cid;
64
65         // Basic data tab
66         GtkWidget *entry_name;
67         GtkWidget *entry_first;
68         GtkWidget *entry_last;
69         GtkWidget *entry_nick;
70
71         // EMail data tab
72         GtkWidget *entry_email;
73         GtkWidget *entry_alias;
74         GtkWidget *entry_remarks;
75         GtkWidget *clist_email;
76
77         // Attribute data tab
78         GtkWidget *entry_atname;
79         GtkWidget *entry_atvalue;
80         GtkWidget *clist_attrib;
81
82         gint rowIndEMail;
83         gint rowIndAttrib;
84         gboolean editNew;
85
86 } personeditdlg;
87
88 typedef enum {
89         EMAIL_COL_EMAIL   = 0,
90         EMAIL_COL_ALIAS   = 1,
91         EMAIL_COL_REMARKS = 2
92 } PersonEditEMailColumnPos;
93
94 typedef enum {
95         ATTRIB_COL_NAME    = 0,
96         ATTRIB_COL_VALUE   = 1
97 } PersonEditAttribColumnPos;
98
99 #define EDITPERSON_WIDTH      520
100 #define EDITPERSON_HEIGHT     340
101
102 #define EMAIL_N_COLS          3
103 #define EMAIL_COL_WIDTH_EMAIL 180
104 #define EMAIL_COL_WIDTH_ALIAS 80
105
106 #define ATTRIB_N_COLS          2
107 #define ATTRIB_COL_WIDTH_NAME  120
108 #define ATTRIB_COL_WIDTH_VALUE 180
109
110 #define PAGE_BASIC             0
111 #define PAGE_EMAIL             1
112 #define PAGE_ATTRIBUTES        2
113
114 /*
115 #define SET_LABEL_AND_ENTRY(str, entry, top) \
116 { \
117         label = gtk_label_new(str); \
118         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
119                          GTK_FILL, 0, 0, 0); \
120         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
121  \
122         entry = gtk_entry_new(); \
123         gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
124                          GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
125 }
126
127 static void edit_address_ok(GtkWidget *widget, gboolean *cancelled)
128 {
129         *cancelled = FALSE;
130         gtk_main_quit();
131 }
132
133 static void edit_address_cancel(GtkWidget *widget, gboolean *cancelled)
134 {
135         *cancelled = TRUE;
136         gtk_main_quit();
137 }
138
139 static gint edit_address_delete_event(GtkWidget *widget, GdkEventAny *event,
140                                       gboolean *cancelled)
141 {
142         *cancelled = TRUE;
143         gtk_main_quit();
144
145         return TRUE;
146 }
147
148 static void edit_address_key_pressed(GtkWidget *widget, GdkEventKey *event,
149                                      gboolean *cancelled)
150 {
151         if (event && event->keyval == GDK_Escape) {
152                 *cancelled = TRUE;
153                 gtk_main_quit();
154         }
155 }
156
157 static void addressbook_edit_address_create(gboolean *cancelled)
158 {
159         GtkWidget *window;
160         GtkWidget *vbox;
161         GtkWidget *table;
162         GtkWidget *label;
163         GtkWidget *name_entry;
164         GtkWidget *addr_entry;
165         GtkWidget *rem_entry;
166         GtkWidget *hbbox;
167         GtkWidget *ok_btn;
168         GtkWidget *cancel_btn;
169
170         debug_print("Creating edit_address window...\n");
171
172         window = gtk_window_new(GTK_WINDOW_DIALOG);
173         gtk_widget_set_usize(window, 400, -1);
174         gtk_container_set_border_width(GTK_CONTAINER(window), 8);
175         gtk_window_set_title(GTK_WINDOW(window), _("Edit address"));
176         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
177         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
178         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
179                            GTK_SIGNAL_FUNC(edit_address_delete_event),
180                            cancelled);
181         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
182                            GTK_SIGNAL_FUNC(edit_address_key_pressed),
183                            cancelled);
184
185         vbox = gtk_vbox_new(FALSE, 8);
186         gtk_container_add(GTK_CONTAINER(window), vbox);
187
188         table = gtk_table_new(3, 2, FALSE);
189         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
190         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
191         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
192
193         SET_LABEL_AND_ENTRY(_("Name"),    name_entry, 0);
194         SET_LABEL_AND_ENTRY(_("Address"), addr_entry, 1);
195         SET_LABEL_AND_ENTRY(_("Remarks"), rem_entry,  2);
196
197         gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
198                                 &cancel_btn, _("Cancel"), NULL, NULL);
199         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
200         gtk_widget_grab_default(ok_btn);
201
202         gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
203                            GTK_SIGNAL_FUNC(edit_address_ok), cancelled);
204         gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
205                            GTK_SIGNAL_FUNC(edit_address_cancel), cancelled);
206
207         gtk_widget_show_all(vbox);
208
209         addredit.window     = window;
210         addredit.name_entry = name_entry;
211         addredit.addr_entry = addr_entry;
212         addredit.rem_entry  = rem_entry;
213         addredit.ok_btn     = ok_btn;
214         addredit.cancel_btn = cancel_btn;
215 }
216
217 AddressItem *addressbook_edit_address(AddressItem *item)
218 {
219         static gboolean cancelled;
220         const gchar *str;
221
222         if (!addredit.window)
223                 addressbook_edit_address_create(&cancelled);
224         gtk_widget_grab_focus(addredit.ok_btn);
225         gtk_widget_grab_focus(addredit.name_entry);
226         gtk_widget_show(addredit.window);
227         manage_window_set_transient(GTK_WINDOW(addredit.window));
228
229         gtk_entry_set_text(GTK_ENTRY(addredit.name_entry), "");
230         gtk_entry_set_text(GTK_ENTRY(addredit.addr_entry), "");
231         gtk_entry_set_text(GTK_ENTRY(addredit.rem_entry),  "");
232
233         if (item) {
234                 if (ADDRESS_OBJECT_NAME(item))
235                         gtk_entry_set_text(GTK_ENTRY(addredit.name_entry),
236                                            ADDRESS_OBJECT_NAME(item));
237                 if (item->address)
238                         gtk_entry_set_text(GTK_ENTRY(addredit.addr_entry),
239                                            item->address);
240                 if (item->remarks)
241                         gtk_entry_set_text(GTK_ENTRY(addredit.rem_entry),
242                                            item->remarks);
243         }
244
245         gtk_main();
246         gtk_widget_hide(addredit.window);
247         if (cancelled == TRUE) return NULL;
248
249         str = gtk_entry_get_text(GTK_ENTRY(addredit.name_entry));
250         if (*str == '\0') return NULL;
251
252         if (!item) {
253                 item = mgu_create_address();
254                 ADDRESS_OBJECT_TYPE(item) = ADDR_ITEM;
255         }
256
257         g_free(ADDRESS_OBJECT_NAME(item));
258         ADDRESS_OBJECT_NAME(item) = g_strdup(str);
259
260         str = gtk_entry_get_text(GTK_ENTRY(addredit.addr_entry));
261         g_free(item->address);
262         if (*str == '\0')
263                 item->address = NULL;
264         else
265                 item->address = g_strdup(str);
266
267         str = gtk_entry_get_text(GTK_ENTRY(addredit.rem_entry));
268         g_free(item->remarks);
269         if (*str == '\0')
270                 item->remarks = NULL;
271         else
272                 item->remarks = g_strdup(str);
273
274         return item;
275 }
276 */
277
278 static void edit_person_status_show( gchar *msg ) {
279         if( personeditdlg.statusbar != NULL ) {
280                 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
281                 if( msg ) {
282                         gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
283                 }
284         }
285 }
286
287 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
288         *cancelled = FALSE;
289         gtk_main_quit();
290 }
291
292 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
293         *cancelled = TRUE;
294         gtk_main_quit();
295 }
296
297 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
298         *cancelled = TRUE;
299         gtk_main_quit();
300         return TRUE;
301 }
302
303 static void edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
304         if (event && event->keyval == GDK_Escape) {
305                 *cancelled = TRUE;
306                 gtk_main_quit();
307         }
308 }
309
310 static gchar *_title_new_ = NULL;
311 static gchar *_title_edit_ = NULL;
312
313 static void edit_person_set_window_title( gint pageNum ) {
314         gchar *sTitle;
315
316         if( _title_new_ == NULL ) {
317                 _title_new_ = g_strdup( _("Add New Person") );
318                 _title_edit_ = g_strdup( _("Edit Person Details") );
319         }
320
321         if( pageNum == PAGE_BASIC ) {
322                 if( personeditdlg.editNew ) {
323                         gtk_window_set_title( GTK_WINDOW(personeditdlg.window), _title_new_ );
324                 }
325                 else {
326                         gtk_window_set_title( GTK_WINDOW(personeditdlg.window), _title_edit_ );
327                 }
328         }
329         else {
330                 if( personeditdlg.entry_name == NULL ) {
331                         sTitle = g_strdup( _title_edit_ );
332                 }
333                 else {
334                         sTitle = g_strdup_printf( "%s - %s", _title_edit_,
335                                         gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 ) );
336                 }
337                 gtk_window_set_title( GTK_WINDOW(personeditdlg.window), sTitle );
338                 g_free( sTitle );
339         }
340 }
341
342 static void edit_person_email_clear( gpointer data ) {
343         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
344         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
345         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
346 }
347
348 static void edit_person_attrib_clear( gpointer data ) {
349         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), "" );
350         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
351 }
352
353 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
354                                         gint pageNum, gpointer user_data)
355 {
356         edit_person_set_window_title( pageNum );
357         edit_person_status_show( "" );
358 }
359
360 /*
361 * Load clist with a copy of person's email addresses.
362 */
363 void edit_person_load_email( ItemPerson *person ) {
364         GList *node = person->listEMail;
365         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
366         gchar *text[ EMAIL_N_COLS ];
367         while( node ) {
368                 ItemEMail *emorig = ( ItemEMail * ) node->data;
369                 ItemEMail *email = addritem_copy_item_email( emorig );
370                 gint row;
371                 text[ EMAIL_COL_EMAIL   ] = email->address;
372                 text[ EMAIL_COL_ALIAS   ] = email->obj.name;
373                 text[ EMAIL_COL_REMARKS ] = email->remarks;
374
375                 row = gtk_clist_append( clist, text );
376                 gtk_clist_set_row_data( clist, row, email );
377                 node = g_list_next( node );
378         }
379 }
380
381 static void edit_person_email_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
382         ItemEMail *email = gtk_clist_get_row_data( clist, row );
383         if( email ) {
384                 if( email->address )
385                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), email->address );
386                 if( ADDRITEM_NAME(email) )
387                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), ADDRITEM_NAME(email) );
388                 if( email->remarks )
389                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), email->remarks );
390         }
391         personeditdlg.rowIndEMail = row;
392         edit_person_status_show( NULL );
393 }
394
395 static void edit_person_email_move( gint dir ) {
396         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
397         gint row = personeditdlg.rowIndEMail + dir;
398         ItemEMail *email = gtk_clist_get_row_data( clist, row );
399         if( email ) {
400                 gtk_clist_row_move( clist, personeditdlg.rowIndEMail, row );
401                 personeditdlg.rowIndEMail = row;
402         }
403         edit_person_email_clear( NULL );
404         edit_person_status_show( NULL );
405 }
406
407 static void edit_person_email_move_up( gpointer data ) {
408         edit_person_email_move( -1 );
409 }
410
411 static void edit_person_email_move_down( gpointer data ) {
412         edit_person_email_move( +1 );
413 }
414
415 static void edit_person_email_delete( gpointer data ) {
416         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
417         gint row = personeditdlg.rowIndEMail;
418         ItemEMail *email = gtk_clist_get_row_data( clist, row );
419         edit_person_email_clear( NULL );
420         if( email ) {
421                 // Remove list entry
422                 gtk_clist_remove( clist, row );
423                 addritem_free_item_email( email );
424                 email = NULL;
425         }
426
427         // Position hilite bar
428         email = gtk_clist_get_row_data( clist, row );
429         if( ! email ) {
430                 personeditdlg.rowIndEMail = -1 + row;
431         }
432         edit_person_status_show( NULL );
433 }
434
435 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
436         ItemEMail *retVal = NULL;
437         gchar *sEmail, *sAlias, *sRemarks;
438         *error = TRUE;
439         sEmail = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
440         sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
441         sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
442         sEmail = mgu_email_check_empty( sEmail );
443         if( sEmail ) {
444                 if( email == NULL ) {
445                         email = addritem_create_item_email();
446                 }
447                 addritem_email_set_address( email, sEmail );
448                 addritem_email_set_alias( email, sAlias );
449                 addritem_email_set_remarks( email, sRemarks );
450                 retVal = email;
451                 *error = FALSE;
452         }
453         else {
454                 edit_person_status_show( _( "An E-Mail address must be supplied." ) );
455         }
456         return retVal;
457 }
458
459 static void edit_person_email_modify( gpointer data ) {
460         gboolean errFlg = FALSE;
461         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
462         gint row = personeditdlg.rowIndEMail;
463         ItemEMail *email = gtk_clist_get_row_data( clist, row );
464         if( email ) {
465                 edit_person_email_edit( &errFlg, email );
466                 if( ! errFlg ) {
467                         gtk_clist_set_text( clist, row, EMAIL_COL_EMAIL, email->address );
468                         gtk_clist_set_text( clist, row, EMAIL_COL_ALIAS, email->obj.name );
469                         gtk_clist_set_text( clist, row, EMAIL_COL_REMARKS, email->remarks );
470                         edit_person_email_clear( NULL );
471                 }
472         }
473 }
474
475 static void edit_person_email_add( gpointer data ) {
476         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
477         gboolean errFlg = FALSE;
478         ItemEMail *email = NULL;
479         gint row = personeditdlg.rowIndEMail;
480         if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
481
482         email = edit_person_email_edit( &errFlg, NULL );
483         if( ! errFlg ) {
484                 gchar *text[ EMAIL_N_COLS ];
485                 text[ EMAIL_COL_EMAIL   ] = email->address;
486                 text[ EMAIL_COL_ALIAS   ] = email->obj.name;
487                 text[ EMAIL_COL_REMARKS ] = email->remarks;
488
489                 row = gtk_clist_insert( clist, 1 + row, text );
490                 gtk_clist_set_row_data( clist, row, email );
491                 gtk_clist_select_row( clist, row, 0 );
492                 edit_person_email_clear( NULL );
493         }
494 }
495
496 /*
497 * Load clist with a copy of person's email addresses.
498 */
499 void edit_person_load_attrib( ItemPerson *person ) {
500         GList *node = person->listAttrib;
501         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
502         gchar *text[ ATTRIB_N_COLS ];
503         while( node ) {
504                 UserAttribute *atorig = ( UserAttribute * ) node->data;
505                 UserAttribute *attrib = addritem_copy_attribute( atorig );
506                 gint row;
507                 text[ ATTRIB_COL_NAME  ] = attrib->name;
508                 text[ ATTRIB_COL_VALUE ] = attrib->value;
509
510                 row = gtk_clist_append( clist, text );
511                 gtk_clist_set_row_data( clist, row, attrib );
512                 node = g_list_next( node );
513         }
514 }
515
516 static void edit_person_attrib_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
517         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
518         if( attrib ) {
519                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), attrib->name );
520                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
521         }
522         personeditdlg.rowIndAttrib = row;
523         edit_person_status_show( NULL );
524 }
525
526 static void edit_person_attrib_delete( gpointer data ) {
527         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
528         gint row = personeditdlg.rowIndAttrib;
529         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
530         edit_person_attrib_clear( NULL );
531         if( attrib ) {
532                 // Remove list entry
533                 gtk_clist_remove( clist, row );
534                 addritem_free_attribute( attrib );
535                 attrib = NULL;
536         }
537
538         // Position hilite bar
539         attrib = gtk_clist_get_row_data( clist, row );
540         if( ! attrib ) {
541                 personeditdlg.rowIndAttrib = -1 + row;
542         }
543         edit_person_status_show( NULL );
544 }
545
546 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
547         UserAttribute *retVal = NULL;
548         gchar *sName, *sValue;
549         *error = TRUE;
550         sName = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atname), 0, -1 );
551         sValue = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
552         sName = mgu_email_check_empty( sName );
553         sValue = mgu_email_check_empty( sValue );
554         if( sName && sValue ) {
555                 if( attrib == NULL ) {
556                         attrib = addritem_create_attribute();
557                 }
558                 addritem_attrib_set_name( attrib, sName );
559                 addritem_attrib_set_value( attrib, sValue );
560                 retVal = attrib;
561                 *error = FALSE;
562         }
563         else {
564                 edit_person_status_show( _( "A Name and Value must be supplied." ) );
565         }
566         return retVal;
567 }
568
569 static void edit_person_attrib_modify( gpointer data ) {
570         gboolean errFlg = FALSE;
571         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
572         gint row = personeditdlg.rowIndAttrib;
573         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
574         if( attrib ) {
575                 edit_person_attrib_edit( &errFlg, attrib );
576                 if( ! errFlg ) {
577                         gtk_clist_set_text( clist, row, ATTRIB_COL_NAME, attrib->name );
578                         gtk_clist_set_text( clist, row, ATTRIB_COL_VALUE, attrib->value );
579                         edit_person_attrib_clear( NULL );
580                 }
581         }
582 }
583
584 static void edit_person_attrib_add( gpointer data ) {
585         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
586         gboolean errFlg = FALSE;
587         UserAttribute *attrib = NULL;
588         gint row = personeditdlg.rowIndAttrib;
589         if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
590
591         attrib = edit_person_attrib_edit( &errFlg, NULL );
592         if( ! errFlg ) {
593                 gchar *text[ EMAIL_N_COLS ];
594                 text[ ATTRIB_COL_NAME  ] = attrib->name;
595                 text[ ATTRIB_COL_VALUE ] = attrib->value;
596
597                 row = gtk_clist_insert( clist, 1 + row, text );
598                 gtk_clist_set_row_data( clist, row, attrib );
599                 gtk_clist_select_row( clist, row, 0 );
600                 edit_person_attrib_clear( NULL );
601         }
602 }
603
604 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
605         GtkWidget *window;
606         GtkWidget *vbox;
607         GtkWidget *notebook;
608         GtkWidget *hbbox;
609         GtkWidget *ok_btn;
610         GtkWidget *cancel_btn;
611         GtkWidget *hsbox;
612         GtkWidget *statusbar;
613
614         window = gtk_window_new(GTK_WINDOW_DIALOG);
615         gtk_widget_set_usize(window, EDITPERSON_WIDTH, EDITPERSON_HEIGHT );
616         gtk_container_set_border_width(GTK_CONTAINER(window), 0);
617         gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
618         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
619         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
620         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
621                            GTK_SIGNAL_FUNC(edit_person_delete_event),
622                            cancelled);
623         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
624                            GTK_SIGNAL_FUNC(edit_person_key_pressed),
625                            cancelled);
626
627         vbox = gtk_vbox_new( FALSE, 6 );
628         gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH);
629         gtk_widget_show( vbox );
630         gtk_container_add( GTK_CONTAINER( window ), vbox );
631
632         // Notebook
633         notebook = gtk_notebook_new();
634         gtk_widget_show( notebook );
635         gtk_box_pack_start( GTK_BOX( vbox ), notebook, TRUE, TRUE, 0 );
636         gtk_container_set_border_width( GTK_CONTAINER( notebook ), 6 );
637
638         // Status line
639         hsbox = gtk_hbox_new(FALSE, 0);
640         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
641         statusbar = gtk_statusbar_new();
642         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
643
644         // Button panel
645         gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
646                                 &cancel_btn, _("Cancel"), NULL, NULL);
647         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
648         gtk_widget_grab_default(ok_btn);
649
650         gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
651                            GTK_SIGNAL_FUNC(edit_person_ok), cancelled);
652         gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
653                            GTK_SIGNAL_FUNC(edit_person_cancel), cancelled);
654         gtk_signal_connect(GTK_OBJECT(notebook), "switch_page",
655                            GTK_SIGNAL_FUNC(edit_person_switch_page), NULL );
656
657         gtk_widget_show_all(vbox);
658
659         personeditdlg.window     = window;
660         personeditdlg.notebook   = notebook;
661         personeditdlg.ok_btn     = ok_btn;
662         personeditdlg.cancel_btn = cancel_btn;
663         personeditdlg.statusbar  = statusbar;
664         personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
665
666 }
667
668 void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
669         GtkWidget *vbox;
670         GtkWidget *table;
671         GtkWidget *label;
672         GtkWidget *entry_name;
673         GtkWidget *entry_fn;
674         GtkWidget *entry_ln;
675         GtkWidget *entry_nn;
676         gint top;
677
678         vbox = gtk_vbox_new( FALSE, 8 );
679         gtk_widget_show( vbox );
680         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
681         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
682
683         label = gtk_label_new( pageLbl );
684         gtk_widget_show( label );
685         gtk_notebook_set_tab_label(
686                 GTK_NOTEBOOK( personeditdlg.notebook ),
687                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
688
689         table = gtk_table_new( 4, 3, FALSE);
690         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
691         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
692         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
693         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
694
695         // First row
696         top = 0;
697         label = gtk_label_new(_("Display Name"));
698         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
699         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
700
701         entry_name = gtk_entry_new();
702         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
703
704         // Next row
705         ++top;
706         label = gtk_label_new(_("First Name"));
707         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
708         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
709
710         entry_fn = gtk_entry_new();
711         gtk_table_attach(GTK_TABLE(table), entry_fn, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
712
713         // Next row
714         ++top;
715         label = gtk_label_new(_("Last Name"));
716         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
717         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
718
719         entry_ln = gtk_entry_new();
720         gtk_table_attach(GTK_TABLE(table), entry_ln, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
721
722         // Next row
723         ++top;
724         label = gtk_label_new(_("Nick Name"));
725         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
726         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
727
728         entry_nn = gtk_entry_new();
729         gtk_table_attach(GTK_TABLE(table), entry_nn, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
730
731         gtk_widget_show_all(vbox);
732
733         personeditdlg.entry_name  = entry_name;
734         personeditdlg.entry_first = entry_fn;
735         personeditdlg.entry_last  = entry_ln;
736         personeditdlg.entry_nick  = entry_nn;
737 }
738
739 void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
740         GtkWidget *vbox;
741         GtkWidget *hbox;
742         GtkWidget *vboxl;
743         GtkWidget *vboxb;
744         GtkWidget *vbuttonbox;
745         GtkWidget *buttonUp;
746         GtkWidget *buttonDown;
747         GtkWidget *buttonDel;
748         GtkWidget *buttonMod;
749         GtkWidget *buttonAdd;
750         GtkWidget *buttonClr;
751
752         GtkWidget *table;
753         GtkWidget *label;
754         GtkWidget *clist_swin;
755         GtkWidget *clist;
756         GtkWidget *entry_email;
757         GtkWidget *entry_alias;
758         GtkWidget *entry_remarks;
759         gint top;
760
761         gchar *titles[ EMAIL_N_COLS ] = { _("E-Mail Address"), _("Alias"), _("Remarks") };
762         gint i;
763
764         vbox = gtk_vbox_new( FALSE, 8 );
765         gtk_widget_show( vbox );
766         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
767         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
768
769         label = gtk_label_new( pageLbl );
770         gtk_widget_show( label );
771         gtk_notebook_set_tab_label(
772                 GTK_NOTEBOOK( personeditdlg.notebook ),
773                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
774
775         // Split into two areas
776         hbox = gtk_hbox_new( FALSE, 0 );
777         gtk_container_add( GTK_CONTAINER( vbox ), hbox );
778
779         // EMail list
780         vboxl = gtk_vbox_new( FALSE, 4 );
781         gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
782         gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
783
784         // Address list
785         clist_swin = gtk_scrolled_window_new( NULL, NULL );
786         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
787         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
788                                        GTK_POLICY_AUTOMATIC,
789                                        GTK_POLICY_ALWAYS);
790
791         clist = gtk_clist_new_with_titles( EMAIL_N_COLS, titles );
792         gtk_container_add( GTK_CONTAINER(clist_swin), clist );
793         gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
794         gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_EMAIL, EMAIL_COL_WIDTH_EMAIL );
795         gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_ALIAS, EMAIL_COL_WIDTH_ALIAS );
796
797         for( i = 0; i < EMAIL_N_COLS; i++ )
798                 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
799
800         // Data entry area
801         table = gtk_table_new( 4, 2, FALSE);
802         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
803         gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
804         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
805         gtk_table_set_col_spacings(GTK_TABLE(table), 4);
806
807         // First row
808         top = 0;
809         label = gtk_label_new(_("E-Mail Address"));
810         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
811         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
812
813         entry_email = gtk_entry_new();
814         gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
815
816         // Next row
817         ++top;
818         label = gtk_label_new(_("Alias"));
819         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
820         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
821
822         entry_alias = gtk_entry_new();
823         gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
824
825         // Next row
826         ++top;
827         label = gtk_label_new(_("Remarks"));
828         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
829         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
830
831         entry_remarks = gtk_entry_new();
832         gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
833
834         // Button box
835         vboxb = gtk_vbox_new( FALSE, 4 );
836         gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
837
838         vbuttonbox = gtk_vbutton_box_new();
839         gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
840         gtk_button_box_set_spacing( GTK_BUTTON_BOX(vbuttonbox), 8 );
841         gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
842         gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
843
844         // Buttons
845         buttonUp = gtk_button_new_with_label( _( "Move Up" ) );
846         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
847
848         buttonDown = gtk_button_new_with_label( _( "Move Down" ) );
849         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
850
851         buttonDel = gtk_button_new_with_label( _( "Delete" ) );
852         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
853
854         buttonMod = gtk_button_new_with_label( _( "Modify" ) );
855         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
856
857         buttonAdd = gtk_button_new_with_label( _( "Add" ) );
858         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
859
860         buttonClr = gtk_button_new_with_label( _( "Clear" ) );
861         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonClr );
862
863         gtk_widget_show_all(vbox);
864
865         // Event handlers
866         gtk_signal_connect( GTK_OBJECT(clist), "select_row",
867                         GTK_SIGNAL_FUNC( edit_person_email_list_selected), NULL );
868         gtk_signal_connect( GTK_OBJECT(buttonUp), "clicked",
869                         GTK_SIGNAL_FUNC( edit_person_email_move_up ), NULL );
870         gtk_signal_connect( GTK_OBJECT(buttonDown), "clicked",
871                         GTK_SIGNAL_FUNC( edit_person_email_move_down ), NULL );
872         gtk_signal_connect( GTK_OBJECT(buttonDel), "clicked",
873                         GTK_SIGNAL_FUNC( edit_person_email_delete ), NULL );
874         gtk_signal_connect( GTK_OBJECT(buttonMod), "clicked",
875                         GTK_SIGNAL_FUNC( edit_person_email_modify ), NULL );
876         gtk_signal_connect( GTK_OBJECT(buttonAdd), "clicked",
877                         GTK_SIGNAL_FUNC( edit_person_email_add ), NULL );
878         gtk_signal_connect( GTK_OBJECT(buttonClr), "clicked",
879                         GTK_SIGNAL_FUNC( edit_person_email_clear ), NULL );
880
881         personeditdlg.clist_email   = clist;
882         personeditdlg.entry_email   = entry_email;
883         personeditdlg.entry_alias   = entry_alias;
884         personeditdlg.entry_remarks = entry_remarks;
885 }
886
887 void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
888         GtkWidget *vbox;
889         GtkWidget *hbox;
890         GtkWidget *vboxl;
891         GtkWidget *vboxb;
892         GtkWidget *vbuttonbox;
893         GtkWidget *buttonDel;
894         GtkWidget *buttonMod;
895         GtkWidget *buttonAdd;
896         GtkWidget *buttonClr;
897
898         GtkWidget *table;
899         GtkWidget *label;
900         GtkWidget *clist_swin;
901         GtkWidget *clist;
902         GtkWidget *entry_name;
903         GtkWidget *entry_value;
904         gint top;
905
906         gchar *titles[ ATTRIB_N_COLS ] = { _("Name"), _("Value") };
907         gint i;
908
909         vbox = gtk_vbox_new( FALSE, 8 );
910         gtk_widget_show( vbox );
911         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
912         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
913
914         label = gtk_label_new( pageLbl );
915         gtk_widget_show( label );
916         gtk_notebook_set_tab_label(
917                 GTK_NOTEBOOK( personeditdlg.notebook ),
918                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
919
920         // Split into two areas
921         hbox = gtk_hbox_new( FALSE, 0 );
922         gtk_container_add( GTK_CONTAINER( vbox ), hbox );
923
924         // Attribute list
925         vboxl = gtk_vbox_new( FALSE, 4 );
926         gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
927         gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
928
929         // Address list
930         clist_swin = gtk_scrolled_window_new( NULL, NULL );
931         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
932         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
933                                        GTK_POLICY_AUTOMATIC,
934                                        GTK_POLICY_ALWAYS);
935
936         clist = gtk_clist_new_with_titles( ATTRIB_N_COLS, titles );
937         gtk_container_add( GTK_CONTAINER(clist_swin), clist );
938         gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
939         gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_NAME, ATTRIB_COL_WIDTH_NAME );
940         gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_VALUE, ATTRIB_COL_WIDTH_VALUE );
941
942         for( i = 0; i < ATTRIB_N_COLS; i++ )
943                 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
944
945         // Data entry area
946         table = gtk_table_new( 4, 2, FALSE);
947         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
948         gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
949         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
950         gtk_table_set_col_spacings(GTK_TABLE(table), 4);
951
952         // First row
953         top = 0;
954         label = gtk_label_new(_("Name"));
955         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
956         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
957
958         entry_name = gtk_entry_new();
959         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
960
961         // Next row
962         ++top;
963         label = gtk_label_new(_("Value"));
964         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
965         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
966
967         entry_value = gtk_entry_new();
968         gtk_table_attach(GTK_TABLE(table), entry_value, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
969
970         // Button box
971         vboxb = gtk_vbox_new( FALSE, 4 );
972         gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
973
974         vbuttonbox = gtk_vbutton_box_new();
975         gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
976         gtk_button_box_set_spacing( GTK_BUTTON_BOX(vbuttonbox), 8 );
977         gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
978         gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
979
980         // Buttons
981         buttonDel = gtk_button_new_with_label( _( "Delete" ) );
982         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
983
984         buttonMod = gtk_button_new_with_label( _( "Modify" ) );
985         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
986
987         buttonAdd = gtk_button_new_with_label( _( "Add" ) );
988         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
989
990         buttonClr = gtk_button_new_with_label( _( "Clear" ) );
991         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonClr );
992
993         gtk_widget_show_all(vbox);
994
995         // Event handlers
996         gtk_signal_connect( GTK_OBJECT(clist), "select_row",
997                         GTK_SIGNAL_FUNC( edit_person_attrib_list_selected), NULL );
998         gtk_signal_connect( GTK_OBJECT(buttonDel), "clicked",
999                         GTK_SIGNAL_FUNC( edit_person_attrib_delete ), NULL );
1000         gtk_signal_connect( GTK_OBJECT(buttonMod), "clicked",
1001                         GTK_SIGNAL_FUNC( edit_person_attrib_modify ), NULL );
1002         gtk_signal_connect( GTK_OBJECT(buttonAdd), "clicked",
1003                         GTK_SIGNAL_FUNC( edit_person_attrib_add ), NULL );
1004         gtk_signal_connect( GTK_OBJECT(buttonClr), "clicked",
1005                         GTK_SIGNAL_FUNC( edit_person_attrib_clear ), NULL );
1006
1007         personeditdlg.clist_attrib  = clist;
1008         personeditdlg.entry_atname  = entry_name;
1009         personeditdlg.entry_atvalue = entry_value;
1010 }
1011
1012 static void addressbook_edit_person_create( gboolean *cancelled ) {
1013         addressbook_edit_person_dialog_create( cancelled );
1014         addressbook_edit_person_page_basic( PAGE_BASIC, _( "Basic Data" ) );
1015         addressbook_edit_person_page_email( PAGE_EMAIL, _( "E-Mail Address" ) );
1016         addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "User Attributes" ) );
1017         gtk_widget_show_all( personeditdlg.window );
1018 }
1019
1020 /*
1021 * Return list of email items.
1022 */
1023 static GList *edit_person_build_email_list() {
1024         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
1025         GList *listEMail = NULL;
1026         ItemEMail *email;
1027         gint row = 0;
1028         while( (email = gtk_clist_get_row_data( clist, row )) ) {
1029                 listEMail = g_list_append( listEMail, email );
1030                 row++;
1031         }
1032         return listEMail;
1033 }
1034
1035 /*
1036 * Return list of attributes.
1037 */
1038 static GList *edit_person_build_attrib_list() {
1039         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
1040         GList *listAttrib = NULL;
1041         UserAttribute *attrib;
1042         gint row = 0;
1043         while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
1044                 listAttrib = g_list_append( listAttrib, attrib );
1045                 row++;
1046         }
1047         return listAttrib;
1048 }
1049
1050 /*
1051 * Edit person.
1052 * Enter: abf    Address book.
1053 *        parent Parent folder for person (or NULL if adding to root folder). Argument is
1054 *               only required for new objects).
1055 *        person Person to edit, or NULL for a new person object.
1056 *        pgMail If TRUE, E-Mail page will be activated.
1057 * Return: Edited object, or NULL if cancelled.
1058 */
1059 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent, ItemPerson *person, gboolean pgMail ) {
1060         static gboolean cancelled;
1061         GList *listEMail = NULL;
1062         GList *listAttrib = NULL;
1063         gchar *cn = NULL;
1064
1065         if (!personeditdlg.window)
1066                 addressbook_edit_person_create(&cancelled);
1067         gtk_widget_grab_focus(personeditdlg.ok_btn);
1068         gtk_widget_grab_focus(personeditdlg.entry_name);
1069         gtk_widget_show(personeditdlg.window);
1070         manage_window_set_transient(GTK_WINDOW(personeditdlg.window));
1071
1072         // Clear all fields
1073         personeditdlg.rowIndEMail = -1;
1074         personeditdlg.rowIndAttrib = -1;
1075         edit_person_status_show( "" );
1076         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1077         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1078         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1079         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1080         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1081         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1082
1083         personeditdlg.editNew = FALSE;
1084         if( person ) {
1085                 if( ADDRITEM_NAME(person) )
1086                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1087                 if( person->firstName )
1088                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), person->firstName );
1089                 if( person->lastName )
1090                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), person->lastName );
1091                 if( person->nickName )
1092                         gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), person->nickName );
1093                 edit_person_load_email( person );
1094                 edit_person_load_attrib( person );
1095         }
1096         else {
1097                 personeditdlg.editNew = TRUE;
1098         }
1099
1100         // Select appropriate start page
1101         if( pgMail ) {
1102                 gtk_notebook_set_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1103         }
1104         else {
1105                 gtk_notebook_set_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1106         }
1107
1108         gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_email), 0, 0 );
1109         gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_attrib), 0, 0 );
1110         edit_person_email_clear( NULL );
1111         edit_person_attrib_clear( NULL );
1112
1113         gtk_main();
1114         gtk_widget_hide( personeditdlg.window );
1115
1116         listEMail = edit_person_build_email_list();
1117         listAttrib = edit_person_build_attrib_list();
1118         if( cancelled ) {
1119                 addritem_free_list_email( listEMail );
1120                 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1121                 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1122                 return NULL;
1123         }
1124
1125         cn = g_strdup( gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 ) );
1126         if( person ) {
1127                 // Update email/attribute list
1128                 addrbook_update_address_list( abf, person, listEMail );
1129                 addrbook_update_attrib_list( abf, person, listAttrib );
1130         }
1131         else {
1132                 // Create new person and email/attribute list
1133                 if( cn == NULL || *cn == '\0' ) {
1134                         // Wasting our time
1135                         if( listEMail == NULL && listAttrib == NULL ) cancelled = TRUE;
1136                 }
1137                 if( ! cancelled ) {
1138                         person = addrbook_add_address_list( abf, parent, listEMail );
1139                         addrbook_add_attrib_list( abf, person, listAttrib );
1140                 }
1141         }
1142
1143         if( ! cancelled ) {
1144                 // Set person stuff
1145                 addritem_person_set_common_name( person, cn );
1146                 addritem_person_set_first_name( person,
1147                         gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 ) );
1148                 addritem_person_set_last_name( person,
1149                         gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 ) );
1150                 addritem_person_set_nick_name( person,
1151                         gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 ) );
1152         }
1153         g_free( cn );
1154
1155         listEMail = NULL;
1156
1157         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1158         gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1159
1160         return person;
1161 }
1162
1163 /*
1164 * End of Source.
1165 */
1166