eea5c8c9f0133a605ac29df45a769b17ad53585f
[claws.git] / src / editaddress.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999,2000 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
42 #include "prefs_common.h"
43
44 /*
45 static struct _AddressEdit_dlg {
46         GtkWidget *window;
47         GtkWidget *name_entry;
48         GtkWidget *addr_entry;
49         GtkWidget *rem_entry;
50         GtkWidget *ok_btn;
51         GtkWidget *cancel_btn;
52 } addredit;
53 */
54
55 static struct _PersonEdit_dlg {
56         GtkWidget *window;
57         GtkWidget *notebook;
58         GtkWidget *ok_btn;
59         GtkWidget *cancel_btn;
60         GtkWidget *statusbar;
61         gint status_cid;
62
63         // Basic data tab
64         GtkWidget *entry_name;
65         GtkWidget *entry_first;
66         GtkWidget *entry_last;
67         GtkWidget *entry_nick;
68
69         // EMail data tab
70         GtkWidget *entry_email;
71         GtkWidget *entry_alias;
72         GtkWidget *entry_remarks;
73         GtkWidget *clist_email;
74
75         // Attribute data tab
76         GtkWidget *entry_atname;
77         GtkWidget *entry_atvalue;
78         GtkWidget *clist_attrib;
79
80         gint rowIndEMail;
81         gint rowIndAttrib;
82         gboolean editNew;
83
84 } personeditdlg;
85
86 typedef enum {
87         EMAIL_COL_EMAIL   = 0,
88         EMAIL_COL_ALIAS   = 1,
89         EMAIL_COL_REMARKS = 2
90 } PersonEditEMailColumnPos;
91
92 typedef enum {
93         ATTRIB_COL_NAME    = 0,
94         ATTRIB_COL_VALUE   = 1
95 } PersonEditAttribColumnPos;
96
97 #define EDITPERSON_WIDTH      520
98 #define EDITPERSON_HEIGHT     340
99
100 #define EMAIL_N_COLS          3
101 #define EMAIL_COL_WIDTH_EMAIL 180
102 #define EMAIL_COL_WIDTH_ALIAS 80
103
104 #define ATTRIB_N_COLS          2
105 #define ATTRIB_COL_WIDTH_NAME  120
106 #define ATTRIB_COL_WIDTH_VALUE 180
107
108 #define PAGE_BASIC             0
109 #define PAGE_EMAIL             1
110 #define PAGE_ATTRIBUTES        2
111
112 /*
113 #define SET_LABEL_AND_ENTRY(str, entry, top) \
114 { \
115         label = gtk_label_new(str); \
116         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
117                          GTK_FILL, 0, 0, 0); \
118         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
119  \
120         entry = gtk_entry_new(); \
121         gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
122                          GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
123 }
124
125 static void edit_address_ok(GtkWidget *widget, gboolean *cancelled)
126 {
127         *cancelled = FALSE;
128         gtk_main_quit();
129 }
130
131 static void edit_address_cancel(GtkWidget *widget, gboolean *cancelled)
132 {
133         *cancelled = TRUE;
134         gtk_main_quit();
135 }
136
137 static gint edit_address_delete_event(GtkWidget *widget, GdkEventAny *event,
138                                       gboolean *cancelled)
139 {
140         *cancelled = TRUE;
141         gtk_main_quit();
142
143         return TRUE;
144 }
145
146 static void edit_address_key_pressed(GtkWidget *widget, GdkEventKey *event,
147                                      gboolean *cancelled)
148 {
149         if (event && event->keyval == GDK_Escape) {
150                 *cancelled = TRUE;
151                 gtk_main_quit();
152         }
153 }
154
155 static void addressbook_edit_address_create(gboolean *cancelled)
156 {
157         GtkWidget *window;
158         GtkWidget *vbox;
159         GtkWidget *table;
160         GtkWidget *label;
161         GtkWidget *name_entry;
162         GtkWidget *addr_entry;
163         GtkWidget *rem_entry;
164         GtkWidget *hbbox;
165         GtkWidget *ok_btn;
166         GtkWidget *cancel_btn;
167
168         debug_print("Creating edit_address window...\n");
169
170         window = gtk_window_new(GTK_WINDOW_DIALOG);
171         gtk_widget_set_usize(window, 400, -1);
172         gtk_container_set_border_width(GTK_CONTAINER(window), 8);
173         gtk_window_set_title(GTK_WINDOW(window), _("Edit address"));
174         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
175         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
176         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
177                            GTK_SIGNAL_FUNC(edit_address_delete_event),
178                            cancelled);
179         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
180                            GTK_SIGNAL_FUNC(edit_address_key_pressed),
181                            cancelled);
182
183         vbox = gtk_vbox_new(FALSE, 8);
184         gtk_container_add(GTK_CONTAINER(window), vbox);
185
186         table = gtk_table_new(3, 2, FALSE);
187         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
188         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
189         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
190
191         SET_LABEL_AND_ENTRY(_("Name"),    name_entry, 0);
192         SET_LABEL_AND_ENTRY(_("Address"), addr_entry, 1);
193         SET_LABEL_AND_ENTRY(_("Remarks"), rem_entry,  2);
194
195         gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
196                                 &cancel_btn, _("Cancel"), NULL, NULL);
197         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
198         gtk_widget_grab_default(ok_btn);
199
200         gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
201                            GTK_SIGNAL_FUNC(edit_address_ok), cancelled);
202         gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
203                            GTK_SIGNAL_FUNC(edit_address_cancel), cancelled);
204
205         gtk_widget_show_all(vbox);
206
207         addredit.window     = window;
208         addredit.name_entry = name_entry;
209         addredit.addr_entry = addr_entry;
210         addredit.rem_entry  = rem_entry;
211         addredit.ok_btn     = ok_btn;
212         addredit.cancel_btn = cancel_btn;
213 }
214
215 AddressItem *addressbook_edit_address(AddressItem *item)
216 {
217         static gboolean cancelled;
218         const gchar *str;
219
220         if (!addredit.window)
221                 addressbook_edit_address_create(&cancelled);
222         gtk_widget_grab_focus(addredit.ok_btn);
223         gtk_widget_grab_focus(addredit.name_entry);
224         gtk_widget_show(addredit.window);
225         manage_window_set_transient(GTK_WINDOW(addredit.window));
226
227         gtk_entry_set_text(GTK_ENTRY(addredit.name_entry), "");
228         gtk_entry_set_text(GTK_ENTRY(addredit.addr_entry), "");
229         gtk_entry_set_text(GTK_ENTRY(addredit.rem_entry),  "");
230
231         if (item) {
232                 if (ADDRESS_OBJECT_NAME(item))
233                         gtk_entry_set_text(GTK_ENTRY(addredit.name_entry),
234                                            ADDRESS_OBJECT_NAME(item));
235                 if (item->address)
236                         gtk_entry_set_text(GTK_ENTRY(addredit.addr_entry),
237                                            item->address);
238                 if (item->remarks)
239                         gtk_entry_set_text(GTK_ENTRY(addredit.rem_entry),
240                                            item->remarks);
241         }
242
243         gtk_main();
244         gtk_widget_hide(addredit.window);
245         if (cancelled == TRUE) return NULL;
246
247         str = gtk_entry_get_text(GTK_ENTRY(addredit.name_entry));
248         if (*str == '\0') return NULL;
249
250         if (!item) {
251                 item = mgu_create_address();
252                 ADDRESS_OBJECT_TYPE(item) = ADDR_ITEM;
253         }
254
255         g_free(ADDRESS_OBJECT_NAME(item));
256         ADDRESS_OBJECT_NAME(item) = g_strdup(str);
257
258         str = gtk_entry_get_text(GTK_ENTRY(addredit.addr_entry));
259         g_free(item->address);
260         if (*str == '\0')
261                 item->address = NULL;
262         else
263                 item->address = g_strdup(str);
264
265         str = gtk_entry_get_text(GTK_ENTRY(addredit.rem_entry));
266         g_free(item->remarks);
267         if (*str == '\0')
268                 item->remarks = NULL;
269         else
270                 item->remarks = g_strdup(str);
271
272         return item;
273 }
274 */
275
276 static void edit_person_status_show( gchar *msg ) {
277         if( personeditdlg.statusbar != NULL ) {
278                 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
279                 if( msg ) {
280                         gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
281                 }
282         }
283 }
284
285 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
286         *cancelled = FALSE;
287         gtk_main_quit();
288 }
289
290 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
291         *cancelled = TRUE;
292         gtk_main_quit();
293 }
294
295 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
296         *cancelled = TRUE;
297         gtk_main_quit();
298         return TRUE;
299 }
300
301 static void edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
302         if (event && event->keyval == GDK_Escape) {
303                 *cancelled = TRUE;
304                 gtk_main_quit();
305         }
306 }
307
308 static gchar *_title_new_ = NULL;
309 static gchar *_title_edit_ = NULL;
310
311 static void edit_person_set_window_title( gint pageNum ) {
312         gchar *sTitle;
313
314         if( _title_new_ == NULL ) {
315                 _title_new_ = g_strdup( _("Add New Person") );
316                 _title_edit_ = g_strdup( _("Edit Person Details") );
317         }
318
319         if( pageNum == PAGE_BASIC ) {
320                 if( personeditdlg.editNew ) {
321                         gtk_window_set_title( GTK_WINDOW(personeditdlg.window), _title_new_ );
322                 }
323                 else {
324                         gtk_window_set_title( GTK_WINDOW(personeditdlg.window), _title_edit_ );
325                 }
326         }
327         else {
328                 if( personeditdlg.entry_name == NULL ) {
329                         sTitle = g_strdup( _title_edit_ );
330                 }
331                 else {
332                         sTitle = g_strdup_printf( "%s - %s", _title_edit_,
333                                         gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 ) );
334                 }
335                 gtk_window_set_title( GTK_WINDOW(personeditdlg.window), sTitle );
336                 g_free( sTitle );
337         }
338 }
339
340 static void edit_person_email_clear( gpointer data ) {
341         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
342         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
343         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
344 }
345
346 static void edit_person_attrib_clear( gpointer data ) {
347         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), "" );
348         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
349 }
350
351 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
352                                         gint pageNum, gpointer user_data)
353 {
354         edit_person_set_window_title( pageNum );
355         edit_person_status_show( "" );
356 }
357
358 /*
359 * Load clist with a copy of person's email addresses.
360 */
361 void edit_person_load_email( ItemPerson *person ) {
362         GList *node = person->listEMail;
363         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
364         gchar *text[ EMAIL_N_COLS ];
365         while( node ) {
366                 ItemEMail *emorig = ( ItemEMail * ) node->data;
367                 ItemEMail *email = addritem_copy_item_email( emorig );
368                 gint row;
369                 text[ EMAIL_COL_EMAIL   ] = email->address;
370                 text[ EMAIL_COL_ALIAS   ] = email->obj.name;
371                 text[ EMAIL_COL_REMARKS ] = email->remarks;
372
373                 row = gtk_clist_append( clist, text );
374                 gtk_clist_set_row_data( clist, row, email );
375                 node = g_list_next( node );
376         }
377 }
378
379 static void edit_person_email_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
380         ItemEMail *email = gtk_clist_get_row_data( clist, row );
381         if( email ) {
382                 if( email->address )
383                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), email->address );
384                 if( ADDRITEM_NAME(email) )
385                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), ADDRITEM_NAME(email) );
386                 if( email->remarks )
387                         gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), email->remarks );
388         }
389         personeditdlg.rowIndEMail = row;
390         edit_person_status_show( NULL );
391 }
392
393 static void edit_person_email_move( gint dir ) {
394         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
395         gint row = personeditdlg.rowIndEMail + dir;
396         ItemEMail *email = gtk_clist_get_row_data( clist, row );
397         if( email ) {
398                 gtk_clist_row_move( clist, personeditdlg.rowIndEMail, row );
399                 personeditdlg.rowIndEMail = row;
400         }
401         edit_person_email_clear( NULL );
402         edit_person_status_show( NULL );
403 }
404
405 static void edit_person_email_move_up( gpointer data ) {
406         edit_person_email_move( -1 );
407 }
408
409 static void edit_person_email_move_down( gpointer data ) {
410         edit_person_email_move( +1 );
411 }
412
413 static void edit_person_email_delete( gpointer data ) {
414         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
415         gint row = personeditdlg.rowIndEMail;
416         ItemEMail *email = gtk_clist_get_row_data( clist, row );
417         edit_person_email_clear( NULL );
418         if( email ) {
419                 // Remove list entry
420                 gtk_clist_remove( clist, row );
421                 addritem_free_item_email( email );
422                 email = NULL;
423         }
424
425         // Position hilite bar
426         email = gtk_clist_get_row_data( clist, row );
427         if( ! email ) {
428                 personeditdlg.rowIndEMail = -1 + row;
429         }
430         edit_person_status_show( NULL );
431 }
432
433 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
434         ItemEMail *retVal = NULL;
435         gchar *sEmail, *sAlias, *sRemarks;
436         *error = TRUE;
437         sEmail = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
438         sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
439         sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
440         sEmail = mgu_email_check_empty( sEmail );
441         if( sEmail ) {
442                 if( email == NULL ) {
443                         email = addritem_create_item_email();
444                 }
445                 addritem_email_set_address( email, sEmail );
446                 addritem_email_set_alias( email, sAlias );
447                 addritem_email_set_remarks( email, sRemarks );
448                 retVal = email;
449                 *error = FALSE;
450         }
451         else {
452                 edit_person_status_show( _( "An E-Mail address must be supplied." ) );
453         }
454         return retVal;
455 }
456
457 static void edit_person_email_modify( gpointer data ) {
458         gboolean errFlg = FALSE;
459         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
460         gint row = personeditdlg.rowIndEMail;
461         ItemEMail *email = gtk_clist_get_row_data( clist, row );
462         if( email ) {
463                 edit_person_email_edit( &errFlg, email );
464                 if( ! errFlg ) {
465                         gtk_clist_set_text( clist, row, EMAIL_COL_EMAIL, email->address );
466                         gtk_clist_set_text( clist, row, EMAIL_COL_ALIAS, email->obj.name );
467                         gtk_clist_set_text( clist, row, EMAIL_COL_REMARKS, email->remarks );
468                         edit_person_email_clear( NULL );
469                 }
470         }
471 }
472
473 static void edit_person_email_add( gpointer data ) {
474         GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
475         gboolean errFlg = FALSE;
476         ItemEMail *email = NULL;
477         gint row = personeditdlg.rowIndEMail;
478         if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
479
480         email = edit_person_email_edit( &errFlg, NULL );
481         if( ! errFlg ) {
482                 gchar *text[ EMAIL_N_COLS ];
483                 text[ EMAIL_COL_EMAIL   ] = email->address;
484                 text[ EMAIL_COL_ALIAS   ] = email->obj.name;
485                 text[ EMAIL_COL_REMARKS ] = email->remarks;
486
487                 row = gtk_clist_insert( clist, 1 + row, text );
488                 gtk_clist_set_row_data( clist, row, email );
489                 gtk_clist_select_row( clist, row, 0 );
490                 edit_person_email_clear( NULL );
491         }
492 }
493
494 /*
495 * Load clist with a copy of person's email addresses.
496 */
497 void edit_person_load_attrib( ItemPerson *person ) {
498         GList *node = person->listAttrib;
499         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
500         gchar *text[ ATTRIB_N_COLS ];
501         while( node ) {
502                 UserAttribute *atorig = ( UserAttribute * ) node->data;
503                 UserAttribute *attrib = addritem_copy_attribute( atorig );
504                 gint row;
505                 text[ ATTRIB_COL_NAME  ] = attrib->name;
506                 text[ ATTRIB_COL_VALUE ] = attrib->value;
507
508                 row = gtk_clist_append( clist, text );
509                 gtk_clist_set_row_data( clist, row, attrib );
510                 node = g_list_next( node );
511         }
512 }
513
514 static void edit_person_attrib_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
515         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
516         if( attrib ) {
517                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), attrib->name );
518                 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
519         }
520         personeditdlg.rowIndAttrib = row;
521         edit_person_status_show( NULL );
522 }
523
524 static void edit_person_attrib_delete( gpointer data ) {
525         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
526         gint row = personeditdlg.rowIndAttrib;
527         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
528         edit_person_attrib_clear( NULL );
529         if( attrib ) {
530                 // Remove list entry
531                 gtk_clist_remove( clist, row );
532                 addritem_free_attribute( attrib );
533                 attrib = NULL;
534         }
535
536         // Position hilite bar
537         attrib = gtk_clist_get_row_data( clist, row );
538         if( ! attrib ) {
539                 personeditdlg.rowIndAttrib = -1 + row;
540         }
541         edit_person_status_show( NULL );
542 }
543
544 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
545         UserAttribute *retVal = NULL;
546         gchar *sName, *sValue;
547         *error = TRUE;
548         sName = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atname), 0, -1 );
549         sValue = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
550         sName = mgu_email_check_empty( sName );
551         sValue = mgu_email_check_empty( sValue );
552         if( sName && sValue ) {
553                 if( attrib == NULL ) {
554                         attrib = addritem_create_attribute();
555                 }
556                 addritem_attrib_set_name( attrib, sName );
557                 addritem_attrib_set_value( attrib, sValue );
558                 retVal = attrib;
559                 *error = FALSE;
560         }
561         else {
562                 edit_person_status_show( _( "A Name and Value must be supplied." ) );
563         }
564         return retVal;
565 }
566
567 static void edit_person_attrib_modify( gpointer data ) {
568         gboolean errFlg = FALSE;
569         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
570         gint row = personeditdlg.rowIndAttrib;
571         UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
572         if( attrib ) {
573                 edit_person_attrib_edit( &errFlg, attrib );
574                 if( ! errFlg ) {
575                         gtk_clist_set_text( clist, row, ATTRIB_COL_NAME, attrib->name );
576                         gtk_clist_set_text( clist, row, ATTRIB_COL_VALUE, attrib->value );
577                         edit_person_attrib_clear( NULL );
578                 }
579         }
580 }
581
582 static void edit_person_attrib_add( gpointer data ) {
583         GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
584         gboolean errFlg = FALSE;
585         UserAttribute *attrib = NULL;
586         gint row = personeditdlg.rowIndAttrib;
587         if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
588
589         attrib = edit_person_attrib_edit( &errFlg, NULL );
590         if( ! errFlg ) {
591                 gchar *text[ EMAIL_N_COLS ];
592                 text[ ATTRIB_COL_NAME  ] = attrib->name;
593                 text[ ATTRIB_COL_VALUE ] = attrib->value;
594
595                 row = gtk_clist_insert( clist, 1 + row, text );
596                 gtk_clist_set_row_data( clist, row, attrib );
597                 gtk_clist_select_row( clist, row, 0 );
598                 edit_person_attrib_clear( NULL );
599         }
600 }
601
602 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
603         GtkWidget *window;
604         GtkWidget *vbox;
605         GtkWidget *notebook;
606         GtkWidget *hbbox;
607         GtkWidget *ok_btn;
608         GtkWidget *cancel_btn;
609         GtkWidget *hsbox;
610         GtkWidget *statusbar;
611
612         window = gtk_window_new(GTK_WINDOW_DIALOG);
613         gtk_widget_set_usize(window, EDITPERSON_WIDTH, EDITPERSON_HEIGHT );
614         gtk_container_set_border_width(GTK_CONTAINER(window), 0);
615         gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
616         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
617         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
618         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
619                            GTK_SIGNAL_FUNC(edit_person_delete_event),
620                            cancelled);
621         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
622                            GTK_SIGNAL_FUNC(edit_person_key_pressed),
623                            cancelled);
624
625         vbox = gtk_vbox_new( FALSE, 6 );
626         gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH);
627         gtk_widget_show( vbox );
628         gtk_container_add( GTK_CONTAINER( window ), vbox );
629
630         // Notebook
631         notebook = gtk_notebook_new();
632         gtk_widget_show( notebook );
633         gtk_box_pack_start( GTK_BOX( vbox ), notebook, TRUE, TRUE, 0 );
634         gtk_container_set_border_width( GTK_CONTAINER( notebook ), 6 );
635
636         // Status line
637         hsbox = gtk_hbox_new(FALSE, 0);
638         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
639         statusbar = gtk_statusbar_new();
640         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
641
642         // Button panel
643         gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
644                                 &cancel_btn, _("Cancel"), NULL, NULL);
645         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
646         gtk_widget_grab_default(ok_btn);
647
648         gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
649                            GTK_SIGNAL_FUNC(edit_person_ok), cancelled);
650         gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
651                            GTK_SIGNAL_FUNC(edit_person_cancel), cancelled);
652         gtk_signal_connect(GTK_OBJECT(notebook), "switch_page",
653                            GTK_SIGNAL_FUNC(edit_person_switch_page), NULL );
654
655         gtk_widget_show_all(vbox);
656
657         personeditdlg.window     = window;
658         personeditdlg.notebook   = notebook;
659         personeditdlg.ok_btn     = ok_btn;
660         personeditdlg.cancel_btn = cancel_btn;
661         personeditdlg.statusbar  = statusbar;
662         personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
663
664 }
665
666 void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
667         GtkWidget *vbox;
668         GtkWidget *table;
669         GtkWidget *label;
670         GtkWidget *entry_name;
671         GtkWidget *entry_fn;
672         GtkWidget *entry_ln;
673         GtkWidget *entry_nn;
674         gint top;
675
676         vbox = gtk_vbox_new( FALSE, 8 );
677         gtk_widget_show( vbox );
678         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
679         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
680
681         label = gtk_label_new( pageLbl );
682         gtk_widget_show( label );
683         gtk_notebook_set_tab_label(
684                 GTK_NOTEBOOK( personeditdlg.notebook ),
685                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
686
687         table = gtk_table_new( 4, 3, FALSE);
688         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
689         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
690         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
691         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
692
693         // First row
694         top = 0;
695         label = gtk_label_new(_("Display Name"));
696         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
697         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
698
699         entry_name = gtk_entry_new();
700         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
701
702         // Next row
703         ++top;
704         label = gtk_label_new(_("First Name"));
705         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
706         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
707
708         entry_fn = gtk_entry_new();
709         gtk_table_attach(GTK_TABLE(table), entry_fn, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
710
711         // Next row
712         ++top;
713         label = gtk_label_new(_("Last Name"));
714         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
715         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
716
717         entry_ln = gtk_entry_new();
718         gtk_table_attach(GTK_TABLE(table), entry_ln, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
719
720         // Next row
721         ++top;
722         label = gtk_label_new(_("Nick Name"));
723         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
724         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
725
726         entry_nn = gtk_entry_new();
727         gtk_table_attach(GTK_TABLE(table), entry_nn, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
728
729         gtk_widget_show_all(vbox);
730
731         personeditdlg.entry_name  = entry_name;
732         personeditdlg.entry_first = entry_fn;
733         personeditdlg.entry_last  = entry_ln;
734         personeditdlg.entry_nick  = entry_nn;
735 }
736
737 void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
738         GtkWidget *vbox;
739         GtkWidget *hbox;
740         GtkWidget *vboxl;
741         GtkWidget *vboxb;
742         GtkWidget *vbuttonbox;
743         GtkWidget *buttonUp;
744         GtkWidget *buttonDown;
745         GtkWidget *buttonDel;
746         GtkWidget *buttonMod;
747         GtkWidget *buttonAdd;
748         GtkWidget *buttonClr;
749
750         GtkWidget *table;
751         GtkWidget *label;
752         GtkWidget *clist_swin;
753         GtkWidget *clist;
754         GtkWidget *entry_email;
755         GtkWidget *entry_alias;
756         GtkWidget *entry_remarks;
757         gint top;
758
759         gchar *titles[ EMAIL_N_COLS ] = { _("E-Mail Address"), _("Alias"), _("Remarks") };
760         gchar *text;
761         gint i;
762
763         vbox = gtk_vbox_new( FALSE, 8 );
764         gtk_widget_show( vbox );
765         gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
766         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
767
768         label = gtk_label_new( pageLbl );
769         gtk_widget_show( label );
770         gtk_notebook_set_tab_label(
771                 GTK_NOTEBOOK( personeditdlg.notebook ),
772                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
773
774         // Split into two areas
775         hbox = gtk_hbox_new( FALSE, 0 );
776         gtk_container_add( GTK_CONTAINER( vbox ), hbox );
777
778         // EMail list
779         vboxl = gtk_vbox_new( FALSE, 4 );
780         gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
781         gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
782
783         // Address list
784         clist_swin = gtk_scrolled_window_new( NULL, NULL );
785         gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
786         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
787                                        GTK_POLICY_AUTOMATIC,
788                                        GTK_POLICY_ALWAYS);
789
790         clist = gtk_clist_new_with_titles( EMAIL_N_COLS, titles );
791         gtk_container_add( GTK_CONTAINER(clist_swin), clist );
792         gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
793         gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_EMAIL, EMAIL_COL_WIDTH_EMAIL );
794         gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_ALIAS, EMAIL_COL_WIDTH_ALIAS );
795
796         for( i = 0; i < EMAIL_N_COLS; i++ )
797                 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
798
799         // Data entry area
800         table = gtk_table_new( 4, 2, FALSE);
801         gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
802         gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
803         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
804         gtk_table_set_col_spacings(GTK_TABLE(table), 4);
805
806         // First row
807         top = 0;
808         label = gtk_label_new(_("E-Mail Address"));
809         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
810         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
811
812         entry_email = gtk_entry_new();
813         gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
814
815         // Next row
816         ++top;
817         label = gtk_label_new(_("Alias"));
818         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
819         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
820
821         entry_alias = gtk_entry_new();
822         gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
823
824         // Next row
825         ++top;
826         label = gtk_label_new(_("Remarks"));
827         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
828         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
829
830         entry_remarks = gtk_entry_new();
831         gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
832
833         // Button box
834         vboxb = gtk_vbox_new( FALSE, 4 );
835         gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
836
837         vbuttonbox = gtk_vbutton_box_new();
838         gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
839         gtk_button_box_set_spacing( GTK_BUTTON_BOX(vbuttonbox), 8 );
840         gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
841         gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
842
843         // Buttons
844         buttonUp = gtk_button_new_with_label( _( "Move Up" ) );
845         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
846
847         buttonDown = gtk_button_new_with_label( _( "Move Down" ) );
848         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
849
850         buttonDel = gtk_button_new_with_label( _( "Delete" ) );
851         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
852
853         buttonMod = gtk_button_new_with_label( _( "Modify" ) );
854         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
855
856         buttonAdd = gtk_button_new_with_label( _( "Add" ) );
857         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
858
859         buttonClr = gtk_button_new_with_label( _( "Clear" ) );
860         gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonClr );
861
862         gtk_widget_show_all(vbox);
863
864         // Event handlers
865         gtk_signal_connect( GTK_OBJECT(clist), "select_row",
866                         GTK_SIGNAL_FUNC( edit_person_email_list_selected), NULL );
867         gtk_signal_connect( GTK_OBJECT(buttonUp), "clicked",
868                         GTK_SIGNAL_FUNC( edit_person_email_move_up ), NULL );
869         gtk_signal_connect( GTK_OBJECT(buttonDown), "clicked",
870                         GTK_SIGNAL_FUNC( edit_person_email_move_down ), NULL );
871         gtk_signal_connect( GTK_OBJECT(buttonDel), "clicked",
872                         GTK_SIGNAL_FUNC( edit_person_email_delete ), NULL );
873         gtk_signal_connect( GTK_OBJECT(buttonMod), "clicked",
874                         GTK_SIGNAL_FUNC( edit_person_email_modify ), NULL );
875         gtk_signal_connect( GTK_OBJECT(buttonAdd), "clicked",
876                         GTK_SIGNAL_FUNC( edit_person_email_add ), NULL );
877         gtk_signal_connect( GTK_OBJECT(buttonClr), "clicked",
878                         GTK_SIGNAL_FUNC( edit_person_email_clear ), NULL );
879
880         personeditdlg.clist_email   = clist;
881         personeditdlg.entry_email   = entry_email;
882         personeditdlg.entry_alias   = entry_alias;
883         personeditdlg.entry_remarks = entry_remarks;
884 }
885
886 void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
887         GtkWidget *vbox;
888         GtkWidget *hbox;
889         GtkWidget *vboxl;
890         GtkWidget *vboxb;
891         GtkWidget *vbuttonbox;
892         GtkWidget *buttonDel;
893         GtkWidget *buttonMod;
894         GtkWidget *buttonAdd;
895         GtkWidget *buttonClr;
896
897         GtkWidget *table;
898         GtkWidget *label;
899         GtkWidget *clist_swin;
900         GtkWidget *clist;
901         GtkWidget *entry_name;
902         GtkWidget *entry_value;
903         gint top;
904
905         gchar *titles[ ATTRIB_N_COLS ] = { _("Name"), _("Value") };
906         gchar *text;
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