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