2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2003 Hiroyuki Yamamoto
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.
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.
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.
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>
37 #include "addressbook.h"
38 #include "addressitem.h"
41 #include "manage_window.h"
45 #include "prefs_common.h"
47 static struct _PersonEdit_dlg {
51 GtkWidget *cancel_btn;
56 GtkWidget *entry_name;
57 GtkWidget *entry_first;
58 GtkWidget *entry_last;
59 GtkWidget *entry_nick;
62 GtkWidget *entry_email;
63 GtkWidget *entry_alias;
64 GtkWidget *entry_remarks;
65 GtkWidget *clist_email;
67 GtkWidget *email_down;
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;
90 } PersonEditEMailColumnPos;
95 } PersonEditAttribColumnPos;
97 #define EDITPERSON_WIDTH 520
98 #define EDITPERSON_HEIGHT 340
100 #define EMAIL_N_COLS 3
101 #define EMAIL_COL_WIDTH_EMAIL 180
102 #define EMAIL_COL_WIDTH_ALIAS 80
104 #define ATTRIB_N_COLS 2
105 #define ATTRIB_COL_WIDTH_NAME 120
106 #define ATTRIB_COL_WIDTH_VALUE 180
110 #define PAGE_ATTRIBUTES 2
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 );
116 gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
121 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
126 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
131 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
137 static gboolean edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
138 if (event && event->keyval == GDK_Escape) {
145 static gchar *_title_new_ = NULL;
146 static gchar *_title_edit_ = NULL;
148 static void edit_person_set_window_title( gint pageNum ) {
151 if( _title_new_ == NULL ) {
152 _title_new_ = g_strdup( _("Add New Person") );
153 _title_edit_ = g_strdup( _("Edit Person Details") );
156 if( pageNum == PAGE_BASIC ) {
157 if( personeditdlg.editNew ) {
158 gtk_window_set_title( GTK_WINDOW(personeditdlg.window), _title_new_ );
161 gtk_window_set_title( GTK_WINDOW(personeditdlg.window), _title_edit_ );
165 if( personeditdlg.entry_name == NULL ) {
166 sTitle = g_strdup( _title_edit_ );
170 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
171 sTitle = g_strdup_printf( "%s - %s", _title_edit_, name );
174 gtk_window_set_title( GTK_WINDOW(personeditdlg.window), sTitle );
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), "" );
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), "" );
190 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
191 gint pageNum, gpointer user_data)
193 edit_person_set_window_title( pageNum );
194 edit_person_status_show( "" );
198 * Load clist with a copy of person's email addresses.
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 ];
205 ItemEMail *emorig = ( ItemEMail * ) node->data;
206 ItemEMail *email = addritem_copyfull_item_email( emorig );
208 text[ EMAIL_COL_EMAIL ] = email->address;
209 text[ EMAIL_COL_ALIAS ] = email->obj.name;
210 text[ EMAIL_COL_REMARKS ] = email->remarks;
212 row = gtk_clist_append( clist, text );
213 gtk_clist_set_row_data( clist, row, email );
214 node = g_list_next( node );
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 );
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) );
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);
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);
235 personeditdlg.rowIndEMail = row;
236 edit_person_status_show( NULL );
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 );
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);
249 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
250 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
252 edit_person_email_clear( NULL );
253 edit_person_status_show( NULL );
256 static void edit_person_email_move_up( gpointer data ) {
257 edit_person_email_move( -1 );
260 static void edit_person_email_move_down( gpointer data ) {
261 edit_person_email_move( +1 );
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 );
270 /* Remove list entry */
271 gtk_clist_remove( clist, row );
272 addritem_free_item_email( email );
276 /* Position hilite bar */
277 email = gtk_clist_get_row_data( clist, row );
279 personeditdlg.rowIndEMail = -1 + row;
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 );
287 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
288 ItemEMail *retVal = NULL;
289 gchar *sEmail, *sAlias, *sRemarks, *sEmail_;
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_ );
299 if( email == NULL ) {
300 email = addritem_create_item_email();
302 addritem_email_set_address( email, sEmail );
303 addritem_email_set_alias( email, sAlias );
304 addritem_email_set_remarks( email, sRemarks );
309 edit_person_status_show( _( "An E-Mail address must be supplied." ) );
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 );
325 edit_person_email_edit( &errFlg, email );
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 );
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;
342 email = edit_person_email_edit( &errFlg, NULL );
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;
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 );
357 * Comparison using cell contents (text in first column). Used for sort
358 * address index widget.
360 static gint edit_person_attrib_compare_func(
361 GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2 )
363 GtkCell *cell1 = ((GtkCListRow *)ptr1)->cell;
364 GtkCell *cell2 = ((GtkCListRow *)ptr2)->cell;
365 gchar *name1 = NULL, *name2 = NULL;
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 );
374 static gboolean list_find_attribute(const gchar *attr)
376 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
377 UserAttribute *attrib;
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);
389 static gboolean list_find_email(const gchar *addr)
391 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
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);
405 * Load clist with a copy of person's email addresses.
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 ];
412 UserAttribute *atorig = ( UserAttribute * ) node->data;
413 UserAttribute *attrib = addritem_copy_attribute( atorig );
415 text[ ATTRIB_COL_NAME ] = attrib->name;
416 text[ ATTRIB_COL_VALUE ] = attrib->value;
418 row = gtk_clist_append( clist, text );
419 gtk_clist_set_row_data( clist, row, attrib );
420 node = g_list_next( node );
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 );
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);
431 gtk_widget_set_sensitive(personeditdlg.attrib_del, FALSE);
433 personeditdlg.rowIndAttrib = row;
434 edit_person_status_show( NULL );
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 );
443 /* Remove list entry */
444 gtk_clist_remove( clist, row );
445 addritem_free_attribute( attrib );
449 /* Position hilite bar */
450 attrib = gtk_clist_get_row_data( clist, row );
452 personeditdlg.rowIndAttrib = -1 + row;
455 gtk_widget_set_sensitive(personeditdlg.attrib_del, gtk_clist_get_row_data(clist, 0) != NULL);
457 edit_person_status_show( NULL );
460 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
461 UserAttribute *retVal = NULL;
462 gchar *sName, *sValue, *sName_, *sValue_;
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_ );
472 if( sName && sValue ) {
473 if( attrib == NULL ) {
474 attrib = addritem_create_attribute();
476 addritem_attrib_set_name( attrib, sName );
477 addritem_attrib_set_value( attrib, sValue );
482 edit_person_status_show( _( "A Name and Value must be supplied." ) );
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 );
497 edit_person_attrib_edit( &errFlg, attrib );
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 );
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;
513 attrib = edit_person_attrib_edit( &errFlg, NULL );
515 gchar *text[ EMAIL_N_COLS ];
516 text[ ATTRIB_COL_NAME ] = attrib->name;
517 text[ ATTRIB_COL_VALUE ] = attrib->value;
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 );
526 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
533 GtkWidget *cancel_btn;
535 GtkWidget *statusbar;
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),
546 g_signal_connect(G_OBJECT(window), "key_press_event",
547 G_CALLBACK(edit_person_key_pressed),
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);
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);
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);
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);
573 gtkut_stock_button_set_create(&hbbox, &ok_btn, GTK_STOCK_OK,
574 &cancel_btn, GTK_STOCK_CANCEL,
576 gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
577 gtk_widget_grab_default(ok_btn);
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 );
586 gtk_widget_show_all(vbox);
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" );
597 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
601 GtkWidget *entry_name;
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 );
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 );
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);
625 #define ATTACH_ROW(text, entry) \
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); \
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); \
638 ATTACH_ROW(_("Display Name"), entry_name);
639 locale = conv_get_current_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);
647 ATTACH_ROW(_("First Name"), entry_fn);
648 ATTACH_ROW(_("Last Name"), entry_ln);
650 ATTACH_ROW(_("Nickname"), entry_nn);
654 gtk_widget_show_all(vbox);
656 personeditdlg.entry_name = entry_name;
657 personeditdlg.entry_first = entry_fn;
658 personeditdlg.entry_last = entry_ln;
659 personeditdlg.entry_nick = entry_nn;
662 static gboolean email_adding = FALSE, email_saving = FALSE;
664 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
666 gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_email), 0) != NULL;
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;
680 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
681 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
683 email_saving = non_empty;
687 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
689 if (event && event->keyval == GDK_Return) {
691 edit_person_email_modify(NULL);
692 else if (email_adding)
693 edit_person_email_add(NULL);
699 static void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
704 GtkWidget *vbuttonbox;
706 GtkWidget *buttonDown;
707 GtkWidget *buttonDel;
708 GtkWidget *buttonMod;
709 GtkWidget *buttonAdd;
713 GtkWidget *clist_swin;
715 GtkWidget *entry_email;
716 GtkWidget *entry_alias;
717 GtkWidget *entry_remarks;
720 gchar *titles[ EMAIL_N_COLS ];
723 titles[ EMAIL_COL_EMAIL ] = _("E-Mail Address");
724 titles[ EMAIL_COL_ALIAS ] = _("Alias");
725 titles[ EMAIL_COL_REMARKS ] = _("Remarks");
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 );
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 );
738 /* Split into two areas */
739 hbox = gtk_hbox_new( FALSE, 0 );
740 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
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 );
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);
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 );
759 for( i = 0; i < EMAIL_N_COLS; i++ )
760 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
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);
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);
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);
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);
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);
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);
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);
797 vboxb = gtk_vbox_new( FALSE, 4 );
798 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
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 );
807 buttonUp = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
808 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
810 buttonDown = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
811 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
813 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
814 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
816 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
817 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
819 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
820 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
822 gtk_widget_show_all(vbox);
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);
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;
857 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
859 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
861 gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_attrib), 0) != NULL;
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;
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;
882 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
884 if (event && event->keyval == GDK_Return) {
886 edit_person_attrib_modify(NULL);
887 else if (attrib_adding)
888 edit_person_attrib_add(NULL);
893 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
898 GtkWidget *vbuttonbox;
899 GtkWidget *buttonDel;
900 GtkWidget *buttonMod;
901 GtkWidget *buttonAdd;
905 GtkWidget *clist_swin;
907 GtkWidget *entry_name;
908 GtkWidget *entry_value;
911 gchar *titles[ ATTRIB_N_COLS ];
914 titles[ ATTRIB_COL_NAME ] = _("Name");
915 titles[ ATTRIB_COL_VALUE ] = _("Value");
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 );
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 );
928 /* Split into two areas */
929 hbox = gtk_hbox_new( FALSE, 0 );
930 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
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 );
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);
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 );
951 for( i = 0; i < ATTRIB_N_COLS; i++ )
952 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
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);
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);
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);
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);
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);
980 vboxb = gtk_vbox_new( FALSE, 4 );
981 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
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 );
990 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
991 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
993 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
994 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
996 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
997 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
999 gtk_widget_set_sensitive(buttonDel,FALSE);
1000 gtk_widget_set_sensitive(buttonMod,FALSE);
1001 gtk_widget_set_sensitive(buttonAdd,FALSE);
1003 gtk_widget_show_all(vbox);
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);
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;
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 );
1038 * Return list of email items.
1040 static GList *edit_person_build_email_list() {
1041 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
1042 GList *listEMail = NULL;
1045 while( (email = gtk_clist_get_row_data( clist, row )) ) {
1046 listEMail = g_list_append( listEMail, email );
1053 * Return list of attributes.
1055 static GList *edit_person_build_attrib_list() {
1056 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
1057 GList *listAttrib = NULL;
1058 UserAttribute *attrib;
1060 while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
1061 listAttrib = g_list_append( listAttrib, attrib );
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.
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;
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));
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), "" );
1100 personeditdlg.editNew = FALSE;
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 );
1114 personeditdlg.editNew = TRUE;
1117 /* Select appropriate start page */
1119 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1122 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
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 );
1129 edit_person_email_list_selected(GTK_CLIST(personeditdlg.clist_email), 0, 0, NULL, NULL);
1131 edit_person_attrib_clear( NULL );
1134 gtk_widget_hide( personeditdlg.window );
1136 listEMail = edit_person_build_email_list();
1137 listAttrib = edit_person_build_attrib_list();
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) );
1146 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
1148 /* Update email/attribute list for existing person */
1149 addrbook_update_address_list( abf, person, listEMail );
1150 addrbook_update_attrib_list( abf, person, listAttrib );
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;
1159 person = addrbook_add_address_list( abf, parent, listEMail );
1160 addrbook_add_attrib_list( abf, person, listAttrib );
1167 /* Set person stuff */
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 );
1173 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1174 addritem_person_set_last_name( person, name );
1176 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1177 addritem_person_set_nick_name( person, name );
1182 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1183 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );