2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
27 #include <glib/gi18n.h>
28 #include <gdk/gdkkeysyms.h>
31 #include "alertpanel.h"
33 #include "addressbook.h"
34 #include "addressitem.h"
37 #include "manage_window.h"
41 #include "editaddress.h"
42 #include "editaddress_other_attributes_ldap.h"
43 #include "prefs_common.h"
48 static struct _PersonEdit_dlg personeditdlg;
49 static AddressBookFile *current_abf = NULL;
50 static ItemPerson *current_person = NULL;
51 static ItemFolder *current_parent_folder = NULL;
52 static EditAddressPostUpdateCallback edit_person_close_post_update_cb = NULL;
58 } PersonEditEMailColumnPos;
63 } PersonEditAttribColumnPos;
65 #define EDITPERSON_WIDTH 520
66 #define EDITPERSON_HEIGHT 320
69 # define EMAIL_N_COLS 3
70 # define EMAIL_COL_WIDTH_EMAIL 180
71 # define EMAIL_COL_WIDTH_ALIAS 80
73 # define EMAIL_N_COLS 1
74 # define EMAIL_COL_WIDTH_EMAIL 130
75 # define EMAIL_COL_WIDTH_ALIAS 130
79 # define ATTRIB_N_COLS 2
80 # define ATTRIB_COL_WIDTH_NAME 240
81 # define ATTRIB_COL_WIDTH_VALUE 0
83 # define ATTRIB_N_COLS 2
84 # define ATTRIB_COL_WIDTH_NAME 120
85 # define ATTRIB_COL_WIDTH_VALUE 120
90 #define PAGE_ATTRIBUTES 2
92 static gboolean addressbook_edit_person_close( gboolean cancelled );
93 static GList *edit_person_build_email_list();
94 static GList *edit_person_build_attrib_list();
96 static gchar* edit_person_get_common_name_from_widgets(void)
98 gchar *cn = NULL; /* cn must be freed by caller */
102 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
103 if ( cn == NULL || *cn == '\0' ) {
104 gchar *first = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
105 gchar *last = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
106 cn = g_strdup_printf("%s%s%s", first?first:"", (first && last && *first && *last)?" ":"", last?last:"");
110 if ( cn == NULL || *cn == '\0' ) {
112 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );;
117 gchar *first = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
118 gchar *last = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
119 cn = g_strdup_printf("%s%s%s", first?first:"", (first && last && *first && *last)?" ":"", last?last:"");
129 static void edit_person_status_show( gchar *msg ) {
130 if( personeditdlg.statusbar != NULL ) {
131 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
133 gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
138 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
140 if (prefs_common.addressbook_use_editaddress_dialog)
143 addressbook_edit_person_close( *cancelled );
146 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
147 GList *listEMail = edit_person_build_email_list();
148 GList *listAttrib = edit_person_build_attrib_list();
149 gchar *cn = edit_person_get_common_name_from_widgets();
151 if( (cn == NULL || *cn == '\0') && listEMail == NULL && listAttrib == NULL ) {
154 val = alertpanel( _("Add New Person"),
156 _("Adding a new person requires at least one of the\n"
157 "following values to be set:\n"
162 " - any email address\n"
163 " - any additional attribute\n\n"
164 "Click OK to keep editing this contact.\n"
165 "Click Cancel to close without saving."),
167 _("Adding a new person requires at least one of the\n"
168 "following values to be set:\n"
171 " - any email address\n"
172 " - any additional attribute\n\n"
173 "Click OK to keep editing this contact.\n"
174 "Click Cancel to close without saving."),
176 GTK_STOCK_CANCEL, "+"GTK_STOCK_OK, NULL );
177 if( val == G_ALERTDEFAULT ) {
178 edit_person_cancel(widget, cancelled);
186 if (prefs_common.addressbook_use_editaddress_dialog)
189 addressbook_edit_person_close( *cancelled );
192 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
194 if (prefs_common.addressbook_use_editaddress_dialog)
197 addressbook_edit_person_close( *cancelled );
201 static gboolean edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
202 if (prefs_common.addressbook_use_editaddress_dialog) {
203 if (event && event->keyval == GDK_Escape) {
211 static gchar *_title_new_ = NULL;
212 static gchar *_title_edit_ = NULL;
214 static void edit_person_set_widgets_title( gchar *text )
218 cm_return_if_fail( text != NULL );
220 gtk_label_set_text(GTK_LABEL(personeditdlg.title), "");
221 label = g_markup_printf_escaped("<b>%s</b>", text);
222 gtk_label_set_markup(GTK_LABEL(personeditdlg.title), label);
226 static void edit_person_set_window_title( gint pageNum ) {
229 if( _title_new_ == NULL ) {
230 _title_new_ = g_strdup( _("Add New Person") );
231 _title_edit_ = g_strdup( _("Edit Person Details") );
234 if( pageNum == PAGE_BASIC ) {
235 if( personeditdlg.editNew ) {
236 if (prefs_common.addressbook_use_editaddress_dialog)
237 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_new_ );
239 edit_person_set_widgets_title( _title_new_ );
242 if (prefs_common.addressbook_use_editaddress_dialog)
243 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_edit_ );
245 edit_person_set_widgets_title( _title_edit_ );
249 if( personeditdlg.entry_name == NULL ) {
250 sTitle = g_strdup( _title_edit_ );
254 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
257 sTitle = g_strdup_printf( "%s - %s", _title_edit_, name );
259 sTitle = g_strdup( _title_edit_ );
262 if (prefs_common.addressbook_use_editaddress_dialog)
263 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), sTitle );
265 edit_person_set_widgets_title( sTitle );
270 static void edit_person_email_clear( gpointer data ) {
271 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
272 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
273 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
276 static void edit_person_attrib_clear( gpointer data ) {
277 if (!personeditdlg.ldap) {
278 gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))), "" );
279 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
283 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
284 gint pageNum, gpointer user_data)
286 edit_person_set_window_title( pageNum );
287 edit_person_status_show( "" );
291 * Load clist with a copy of person's email addresses.
293 static void edit_person_load_email( ItemPerson *person ) {
294 GList *node = person->listEMail;
295 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
296 gchar *text[ EMAIL_N_COLS ];
298 ItemEMail *emorig = ( ItemEMail * ) node->data;
299 ItemEMail *email = addritem_copyfull_item_email( emorig );
301 text[ EMAIL_COL_EMAIL ] = email->address;
303 text[ EMAIL_COL_ALIAS ] = email->obj.name;
304 text[ EMAIL_COL_REMARKS ] = email->remarks;
306 row = gtk_cmclist_append( clist, text );
307 gtk_cmclist_set_row_data( clist, row, email );
308 node = g_list_next( node );
312 static void edit_person_email_list_selected( GtkCMCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
313 ItemEMail *email = gtk_cmclist_get_row_data( clist, row );
316 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), email->address );
317 if( ADDRITEM_NAME(email) )
318 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), ADDRITEM_NAME(email) );
320 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), email->remarks );
321 if (!personeditdlg.read_only) {
322 gtk_widget_set_sensitive(personeditdlg.email_del, TRUE);
323 gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
324 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_cmclist_get_row_data(clist, row + 1) != NULL);
327 gtk_widget_set_sensitive(personeditdlg.email_del, FALSE);
328 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
329 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
331 personeditdlg.rowIndEMail = row;
332 edit_person_status_show( NULL );
335 static void edit_person_email_move( gint dir ) {
336 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
337 gint row = personeditdlg.rowIndEMail + dir;
338 ItemEMail *email = gtk_cmclist_get_row_data( clist, row );
340 gtk_cmclist_row_move( clist, personeditdlg.rowIndEMail, row );
341 personeditdlg.rowIndEMail = row;
342 if (!personeditdlg.read_only) {
343 gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
344 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_cmclist_get_row_data(clist, row + 1) != NULL);
347 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
348 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
350 edit_person_email_clear( NULL );
351 edit_person_status_show( NULL );
354 static void edit_person_email_move_up( gpointer data ) {
355 edit_person_email_move( -1 );
358 static void edit_person_email_move_down( gpointer data ) {
359 edit_person_email_move( +1 );
362 static void edit_person_email_delete( gpointer data ) {
363 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
364 gint row = personeditdlg.rowIndEMail;
365 ItemEMail *email = gtk_cmclist_get_row_data( clist, row );
366 edit_person_email_clear( NULL );
368 /* Remove list entry */
369 gtk_cmclist_remove( clist, row );
370 addritem_free_item_email( email );
374 /* Position hilite bar */
375 email = gtk_cmclist_get_row_data( clist, row );
377 personeditdlg.rowIndEMail = -1 + row;
379 if (!personeditdlg.read_only) {
380 gtk_widget_set_sensitive(personeditdlg.email_del, gtk_cmclist_get_row_data(clist, 0) != NULL);
381 gtk_widget_set_sensitive(personeditdlg.email_up, gtk_cmclist_get_row_data(clist, personeditdlg.rowIndEMail + 1) != NULL);
382 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_cmclist_get_row_data(clist, personeditdlg.rowIndEMail - 1) != NULL);
384 edit_person_status_show( NULL );
387 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
388 ItemEMail *retVal = NULL;
389 gchar *sEmail, *sAlias, *sRemarks, *sEmail_;
392 sEmail_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
393 sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
394 sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
395 sEmail = mgu_email_check_empty( sEmail_ );
399 if( email == NULL ) {
400 email = addritem_create_item_email();
402 addritem_email_set_address( email, sEmail );
403 addritem_email_set_alias( email, sAlias );
404 addritem_email_set_remarks( email, sRemarks );
409 edit_person_status_show( _( "An Email address must be supplied." ) );
419 static void edit_person_email_modify( gpointer data ) {
420 gboolean errFlg = FALSE;
421 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
422 gint row = personeditdlg.rowIndEMail;
423 ItemEMail *email = gtk_cmclist_get_row_data( clist, row );
425 edit_person_email_edit( &errFlg, email );
427 gtk_cmclist_set_text( clist, row, EMAIL_COL_EMAIL, email->address );
428 gtk_cmclist_set_text( clist, row, EMAIL_COL_ALIAS, email->obj.name );
429 gtk_cmclist_set_text( clist, row, EMAIL_COL_REMARKS, email->remarks );
430 edit_person_email_clear( NULL );
435 static void edit_person_email_add( gpointer data ) {
436 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
437 gboolean errFlg = FALSE;
438 ItemEMail *email = NULL;
439 gint row = personeditdlg.rowIndEMail;
440 if( gtk_cmclist_get_row_data( clist, row ) == NULL ) row = 0;
442 email = edit_person_email_edit( &errFlg, NULL );
444 gchar *text[ EMAIL_N_COLS ];
445 text[ EMAIL_COL_EMAIL ] = email->address;
447 text[ EMAIL_COL_ALIAS ] = email->obj.name;
448 text[ EMAIL_COL_REMARKS ] = email->remarks;
450 row = gtk_cmclist_insert( clist, 1 + row, text );
451 gtk_cmclist_set_row_data( clist, row, email );
452 gtk_cmclist_select_row( clist, row, 0 );
453 edit_person_email_clear( NULL );
458 * Comparison using cell contents (text in first column). Used for sort
459 * address index widget.
461 static gint edit_person_attrib_compare_func(
462 GtkCMCList *clist, gconstpointer ptr1, gconstpointer ptr2 )
464 GtkCMCell *cell1 = ((GtkCMCListRow *)ptr1)->cell;
465 GtkCMCell *cell2 = ((GtkCMCListRow *)ptr2)->cell;
466 gchar *name1 = NULL, *name2 = NULL;
468 if( cell1 ) name1 = cell1->u.text;
469 if( cell2 ) name2 = cell2->u.text;
470 if( ! name1 ) return ( name2 != NULL );
471 if( ! name2 ) return -1;
472 return g_utf8_collate( name1, name2 );
475 static gboolean list_find_attribute(const gchar *attr)
477 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_attrib);
478 UserAttribute *attrib;
480 while( (attrib = gtk_cmclist_get_row_data( clist, row )) ) {
481 if (!g_ascii_strcasecmp(attrib->name, attr)) {
482 gtk_cmclist_select_row(clist, row, 0);
490 static gboolean list_find_email(const gchar *addr)
492 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
495 while( (email = gtk_cmclist_get_row_data( clist, row )) ) {
496 if (!g_ascii_strcasecmp(email->address, addr)) {
497 gtk_cmclist_select_row(clist, row, 0);
506 * Load clist with a copy of person's email addresses.
508 static void edit_person_load_attrib( ItemPerson *person ) {
509 GList *node = person->listAttrib;
510 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_attrib);
511 gchar *text[ ATTRIB_N_COLS ];
513 UserAttribute *atorig = ( UserAttribute * ) node->data;
514 UserAttribute *attrib = addritem_copy_attribute( atorig );
516 debug_print("name: %s value: %s\n", attrib->name, attrib->value);
517 text[ ATTRIB_COL_NAME ] = attrib->name;
518 text[ ATTRIB_COL_VALUE ] = attrib->value;
520 row = gtk_cmclist_append( clist, text );
521 gtk_cmclist_set_row_data( clist, row, attrib );
522 node = g_list_next( node );
526 static void edit_person_attrib_list_selected( GtkCMCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
527 UserAttribute *attrib = gtk_cmclist_get_row_data( clist, row );
528 if( attrib && !personeditdlg.read_only && !personeditdlg.ldap ) {
529 gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname))) ), attrib->name );
530 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
531 gtk_widget_set_sensitive(personeditdlg.attrib_del, TRUE);
533 gtk_widget_set_sensitive(personeditdlg.attrib_del, FALSE);
535 personeditdlg.rowIndAttrib = row;
536 edit_person_status_show( NULL );
539 static void edit_person_attrib_delete( gpointer data ) {
540 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_attrib);
541 gint row = personeditdlg.rowIndAttrib;
542 UserAttribute *attrib = gtk_cmclist_get_row_data( clist, row );
543 edit_person_attrib_clear( NULL );
545 /* Remove list entry */
546 gtk_cmclist_remove( clist, row );
547 addritem_free_attribute( attrib );
551 /* Position hilite bar */
552 attrib = gtk_cmclist_get_row_data( clist, row );
554 personeditdlg.rowIndAttrib = -1 + row;
557 if (!personeditdlg.read_only && !personeditdlg.ldap)
558 gtk_widget_set_sensitive(personeditdlg.attrib_del, gtk_cmclist_get_row_data(clist, 0) != NULL);
560 edit_person_status_show( NULL );
563 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
564 UserAttribute *retVal = NULL;
565 gchar *sName, *sValue, *sName_, *sValue_;
568 sName_ = gtk_editable_get_chars( GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))), 0, -1 );
569 sValue_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
570 sName = mgu_email_check_empty( sName_ );
571 sValue = mgu_email_check_empty( sValue_ );
575 if( sName && sValue ) {
576 if( attrib == NULL ) {
577 attrib = addritem_create_attribute();
579 addritem_attrib_set_name( attrib, sName );
580 addritem_attrib_set_value( attrib, sValue );
585 edit_person_status_show( _( "A Name and Value must be supplied." ) );
594 static void edit_person_attrib_modify( gpointer data ) {
595 gboolean errFlg = FALSE;
596 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_attrib);
597 gint row = personeditdlg.rowIndAttrib;
598 UserAttribute *attrib = gtk_cmclist_get_row_data( clist, row );
600 edit_person_attrib_edit( &errFlg, attrib );
602 gtk_cmclist_set_text( clist, row, ATTRIB_COL_NAME, attrib->name );
603 gtk_cmclist_set_text( clist, row, ATTRIB_COL_VALUE, attrib->value );
604 edit_person_attrib_clear( NULL );
609 static void edit_person_attrib_add( gpointer data ) {
610 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_attrib);
611 gboolean errFlg = FALSE;
612 UserAttribute *attrib = NULL;
613 gint row = personeditdlg.rowIndAttrib;
614 if( gtk_cmclist_get_row_data( clist, row ) == NULL ) row = 0;
616 attrib = edit_person_attrib_edit( &errFlg, NULL );
618 gchar *text[ ATTRIB_N_COLS ];
619 text[ ATTRIB_COL_NAME ] = attrib->name;
620 text[ ATTRIB_COL_VALUE ] = attrib->value;
622 row = gtk_cmclist_insert( clist, 1 + row, text );
623 gtk_cmclist_set_row_data( clist, row, attrib );
624 gtk_cmclist_select_row( clist, row, 0 );
625 edit_person_attrib_clear( NULL );
630 *\brief Save Gtk object size to prefs dataset
632 static void edit_person_size_allocate_cb(GtkWidget *widget,
633 GtkAllocation *allocation)
635 cm_return_if_fail(allocation != NULL);
637 prefs_common.addressbookeditpersonwin_width = allocation->width;
638 prefs_common.addressbookeditpersonwin_height = allocation->height;
641 /* build edit person widgets, return a pointer to the main container of the widgetset (a vbox) */
642 static GtkWidget* addressbook_edit_person_widgets_create( GtkWidget* container, gboolean *cancelled )
649 GtkWidget *cancel_btn;
651 vbox = gtk_vbox_new(FALSE, 4);
652 gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH);
653 gtk_widget_show(vbox);
654 gtk_container_add(GTK_CONTAINER(container), vbox);
656 vnbox = gtk_vbox_new(FALSE, 4);
657 gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
658 gtk_widget_show(vnbox);
659 gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
662 notebook = gtk_notebook_new();
663 gtk_widget_show(notebook);
664 gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
665 gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
668 if (prefs_common.addressbook_use_editaddress_dialog)
669 gtkut_stock_button_set_create(&hbbox, &cancel_btn, GTK_STOCK_CANCEL,
670 &ok_btn, GTK_STOCK_OK,
673 gtkut_stock_with_text_button_set_create(&hbbox,
674 &cancel_btn, GTK_STOCK_CANCEL, _("Discard"),
675 &ok_btn, GTK_STOCK_OK, _("Apply"),
677 gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
678 gtk_widget_grab_default(ok_btn);
680 g_signal_connect(G_OBJECT(ok_btn), "clicked",
681 G_CALLBACK(edit_person_ok), cancelled);
682 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
683 G_CALLBACK(edit_person_cancel), cancelled);
684 g_signal_connect(G_OBJECT(notebook), "switch_page",
685 G_CALLBACK(edit_person_switch_page), NULL );
687 gtk_widget_show_all(vbox);
689 personeditdlg.notebook = notebook;
690 personeditdlg.ok_btn = ok_btn;
691 personeditdlg.cancel_btn = cancel_btn;
696 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
700 GtkWidget *statusbar;
701 static GdkGeometry geometry;
703 window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "editaddress");
704 /* gtk_container_set_border_width(GTK_CONTAINER(window), 0); */
705 gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
706 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
707 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
708 g_signal_connect(G_OBJECT(window), "delete_event",
709 G_CALLBACK(edit_person_delete_event),
711 g_signal_connect(G_OBJECT(window), "size_allocate",
712 G_CALLBACK(edit_person_size_allocate_cb),
714 g_signal_connect(G_OBJECT(window), "key_press_event",
715 G_CALLBACK(edit_person_key_pressed),
718 vbox = addressbook_edit_person_widgets_create(window, cancelled);
721 hsbox = gtk_hbox_new(FALSE, 0);
722 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
723 statusbar = gtk_statusbar_new();
724 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
726 if (!geometry.min_height) {
727 geometry.min_width = EDITPERSON_WIDTH;
728 geometry.min_height = EDITPERSON_HEIGHT;
731 gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
733 gtk_widget_set_size_request(window, prefs_common.addressbookeditpersonwin_width,
734 prefs_common.addressbookeditpersonwin_height);
736 personeditdlg.container = window;
737 personeditdlg.statusbar = statusbar;
738 personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
742 /* parent must be a box */
743 static void addressbook_edit_person_widgetset_create( GtkWidget *parent, gboolean *cancelled )
748 if ( parent == NULL )
749 g_warning("addressbook_edit_person_widgetset_create: parent is NULL");
751 vbox = gtk_vbox_new(FALSE, 0);
752 gtk_box_pack_end(GTK_BOX(parent), vbox, TRUE, TRUE, 0);
754 label = gtk_label_new(_("Edit Person Data"));
755 gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER);
756 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
758 addressbook_edit_person_widgets_create(vbox, cancelled);
760 gtk_widget_set_size_request(vbox, EDITPERSON_WIDTH, EDITPERSON_HEIGHT);
762 personeditdlg.container = vbox;
763 personeditdlg.title = label;
764 personeditdlg.statusbar = NULL;
765 personeditdlg.status_cid = 0;
768 void addressbook_edit_person_widgetset_hide( void )
770 if ( personeditdlg.container )
771 gtk_widget_hide( personeditdlg.container );
774 static void addressbook_edit_person_set_picture(void)
776 GError *error = NULL;
778 int width, height, scalewidth, scaleheight;
780 if (personeditdlg.ldap)
783 if ( (filename = filesel_select_file_open(_("Choose a picture"), NULL)) ) {
784 GdkPixbuf *pixbuf = NULL;
785 gdk_pixbuf_get_file_info(filename, &width, &height);
787 if ( width > 128 || height > 128 ) {
788 if (width > height) {
789 scaleheight = (height * 128) / width;
793 scalewidth = (width * 128) / height;
796 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
797 scalewidth, scaleheight, TRUE, &error);
799 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
802 alertpanel_error(_("Failed to import image: \n%s"),
806 /* keep the previous picture if any */
809 g_object_unref(pixbuf);
812 personeditdlg.picture_set = TRUE;
813 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", personeditdlg.picture_set);
815 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
816 g_object_unref(pixbuf);
820 static void addressbook_edit_person_clear_picture(void)
824 stock_pixbuf_gdk(NULL, STOCK_PIXMAP_ANONYMOUS, &pixbuf);
825 personeditdlg.picture_set = FALSE;
826 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", personeditdlg.picture_set);
827 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
830 static void addressbook_edit_person_set_picture_menu_cb (GtkAction *action, gpointer data)
832 addressbook_edit_person_set_picture();
835 static void addressbook_edit_person_unset_picture_menu_cb (GtkAction *action, gpointer data)
837 addressbook_edit_person_clear_picture();
840 static GtkWidget *editaddr_popup_menu = NULL;
841 static GtkActionEntry editaddr_popup_entries[] =
843 {"EditAddressPopup", NULL, "EditAddressPopup" },
844 {"EditAddressPopup/SetPicture", NULL, N_("_Set picture"), NULL, NULL, G_CALLBACK(addressbook_edit_person_set_picture_menu_cb) },
845 {"EditAddressPopup/UnsetPicture", NULL, N_("_Unset picture"), NULL, NULL, G_CALLBACK(addressbook_edit_person_unset_picture_menu_cb) },
848 static void addressbook_edit_person_set_picture_cb(GtkWidget *widget,
849 GdkEventButton *event, gpointer data)
851 if (event->button == 1) {
852 addressbook_edit_person_set_picture();
854 gtk_menu_popup(GTK_MENU(editaddr_popup_menu),
855 NULL, NULL, NULL, NULL,
856 event->button, event->time);
860 static gboolean addressbook_edit_person_picture_popup_menu(GtkWidget *widget, gpointer data)
862 GdkEventButton event;
865 event.time = gtk_get_current_event_time();
867 addressbook_edit_person_set_picture_cb(NULL, &event, data);
872 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
877 GtkWidget *ebox_picture;
878 GtkWidget *frame_picture;
879 GtkWidget *entry_name;
885 GtkActionGroup *action_group;
887 vbox = gtk_vbox_new( FALSE, 20 );
888 hbox = gtk_hbox_new( FALSE, 8 );
890 gtk_widget_show( vbox );
892 if (!editaddr_popup_menu) {
893 action_group = cm_menu_create_action_group("EditAddressPopup", editaddr_popup_entries,
894 G_N_ELEMENTS(editaddr_popup_entries), (gpointer)NULL);
895 MENUITEM_ADDUI("/Menus", "EditAddressPopup", "EditAddressPopup", GTK_UI_MANAGER_MENU)
896 MENUITEM_ADDUI("/Menus/EditAddressPopup", "SetPicture", "EditAddressPopup/SetPicture", GTK_UI_MANAGER_MENUITEM)
897 MENUITEM_ADDUI("/Menus/EditAddressPopup", "UnsetPicture", "EditAddressPopup/UnsetPicture", GTK_UI_MANAGER_MENUITEM)
899 editaddr_popup_menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
900 gtk_ui_manager_get_widget(gtkut_ui_manager(), "/Menus/EditAddressPopup")) );
903 ebox_picture = gtk_event_box_new();
904 frame_picture = gtk_frame_new(_("Photo"));
906 /* Room for a photo */
907 personeditdlg.image = gtk_image_new();
908 addressbook_edit_person_clear_picture();
910 gtk_container_add(GTK_CONTAINER(ebox_picture), personeditdlg.image);
911 gtk_container_add(GTK_CONTAINER(frame_picture), ebox_picture);
912 gtk_container_add(GTK_CONTAINER( personeditdlg.notebook ), hbox );
913 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
914 gtk_container_set_border_width( GTK_CONTAINER (hbox), BORDER_WIDTH );
916 label = gtk_label_new_with_mnemonic( pageLbl );
917 gtk_widget_show( label );
919 gtk_box_pack_start(GTK_BOX(hbox), frame_picture, TRUE, TRUE, 0);
921 gtk_notebook_set_tab_label(
922 GTK_NOTEBOOK( personeditdlg.notebook ),
923 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
926 g_signal_connect(G_OBJECT(ebox_picture), "popup-menu",
927 G_CALLBACK(addressbook_edit_person_picture_popup_menu), NULL);
929 gtk_widget_tap_and_hold_setup(GTK_WIDGET(ebox_picture), NULL, NULL,
930 GTK_TAP_AND_HOLD_NONE | GTK_TAP_AND_HOLD_NO_INTERNALS);
931 g_signal_connect(G_OBJECT(ebox_picture), "tap-and-hold",
932 G_CALLBACK(addressbook_edit_person_picture_popup_menu), NULL);
934 g_signal_connect(G_OBJECT(ebox_picture), "button_press_event",
935 G_CALLBACK(addressbook_edit_person_set_picture_cb), NULL);
937 table = gtk_table_new( 3, 3, FALSE);
939 #define ATTACH_ROW(text, entry) \
941 label = gtk_label_new(text); \
942 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
943 GTK_FILL, 0, 0, 0); \
944 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
946 entry = gtk_entry_new(); \
947 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
948 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
952 #define ATTACH_HIDDEN_ROW(text, entry) \
954 entry = gtk_entry_new(); \
958 ATTACH_ROW(_("Display Name"), entry_name);
960 ATTACH_HIDDEN_ROW(_("Display Name"), entry_name);
962 locale = conv_get_current_locale();
964 (!g_ascii_strncasecmp(locale, "ja", 2) ||
965 !g_ascii_strncasecmp(locale, "ko", 2) ||
966 !g_ascii_strncasecmp(locale, "zh", 2))) {
967 ATTACH_ROW(_("Last Name"), entry_ln);
968 ATTACH_ROW(_("First Name"), entry_fn);
970 ATTACH_ROW(_("First Name"), entry_fn);
971 ATTACH_ROW(_("Last Name"), entry_ln);
974 ATTACH_ROW(_("Nickname"), entry_nn);
976 ATTACH_HIDDEN_ROW(_("Nickname"), entry_nn);
980 #undef ATTACH_HIDDEN_ROW
981 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
982 gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
983 gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
984 gtk_table_set_row_spacings(GTK_TABLE(table), 15);
985 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
987 gtk_widget_show_all(vbox);
988 personeditdlg.entry_name = entry_name;
989 personeditdlg.entry_first = entry_fn;
990 personeditdlg.entry_last = entry_ln;
991 personeditdlg.entry_nick = entry_nn;
994 static gboolean email_adding = FALSE, email_saving = FALSE;
996 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
998 gboolean non_empty = gtk_cmclist_get_row_data(GTK_CMCLIST(personeditdlg.clist_email), 0) != NULL;
1000 if (personeditdlg.read_only)
1003 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)) == NULL
1004 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email))) == 0) {
1005 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
1006 gtk_widget_set_sensitive(personeditdlg.email_mod,FALSE);
1007 email_adding = FALSE;
1008 email_saving = FALSE;
1009 } else if (list_find_email(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)))) {
1010 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
1011 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
1012 email_adding = FALSE;
1013 email_saving = non_empty;
1015 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
1016 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
1017 email_adding = TRUE;
1018 email_saving = non_empty;
1022 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1024 if (event && event->keyval == GDK_Return) {
1026 edit_person_email_modify(NULL);
1027 else if (email_adding)
1028 edit_person_email_add(NULL);
1034 static void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
1039 GtkWidget *vbuttonbox;
1040 GtkWidget *buttonUp;
1041 GtkWidget *buttonDown;
1042 GtkWidget *buttonDel;
1043 GtkWidget *buttonMod;
1044 GtkWidget *buttonAdd;
1048 GtkWidget *clist_swin;
1050 GtkWidget *entry_email;
1051 GtkWidget *entry_alias;
1052 GtkWidget *entry_remarks;
1055 gchar *titles[ EMAIL_N_COLS ];
1058 titles[ EMAIL_COL_EMAIL ] = _("Email Address");
1059 #ifndef GENERIC_UMPC
1060 titles[ EMAIL_COL_ALIAS ] = _("Alias");
1061 titles[ EMAIL_COL_REMARKS ] = _("Remarks");
1063 vbox = gtk_vbox_new( FALSE, 8 );
1064 gtk_widget_show( vbox );
1065 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1066 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1068 label = gtk_label_new_with_mnemonic( pageLbl );
1069 gtk_widget_show( label );
1070 gtk_notebook_set_tab_label(
1071 GTK_NOTEBOOK( personeditdlg.notebook ),
1072 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1074 /* Split into two areas */
1075 hbox = gtk_hbox_new( FALSE, 0 );
1076 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1079 vboxl = gtk_vbox_new( FALSE, 4 );
1080 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1081 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1083 clist_swin = gtk_scrolled_window_new( NULL, NULL );
1084 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
1085 GTK_POLICY_AUTOMATIC,
1086 GTK_POLICY_AUTOMATIC);
1088 clist = gtk_cmclist_new_with_titles( EMAIL_N_COLS, titles );
1090 gtk_container_add( GTK_CONTAINER(clist_swin), clist );
1091 gtk_cmclist_set_selection_mode( GTK_CMCLIST(clist), GTK_SELECTION_BROWSE );
1092 gtk_cmclist_set_column_width( GTK_CMCLIST(clist), EMAIL_COL_EMAIL, EMAIL_COL_WIDTH_EMAIL );
1093 gtk_cmclist_set_column_width( GTK_CMCLIST(clist), EMAIL_COL_ALIAS, EMAIL_COL_WIDTH_ALIAS );
1095 for( i = 0; i < EMAIL_N_COLS; i++ )
1096 GTK_WIDGET_UNSET_FLAGS(GTK_CMCLIST(clist)->column[i].button, GTK_CAN_FOCUS);
1098 /* Data entry area */
1099 table = gtk_table_new( 4, 2, FALSE);
1101 #ifndef GENERIC_UMPC
1102 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1103 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1105 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1106 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1107 gtk_cmclist_column_titles_hide(GTK_CMCLIST(clist));
1109 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1110 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1111 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1113 entry_email = gtk_entry_new();
1114 entry_alias = gtk_entry_new();
1115 entry_remarks = gtk_entry_new();
1119 label = gtk_label_new(_("Email Address"));
1120 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1121 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1123 gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1125 #ifndef GENERIC_UMPC
1128 label = gtk_label_new(_("Alias"));
1129 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1130 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1132 gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1136 label = gtk_label_new(_("Remarks"));
1137 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1138 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1140 gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1144 vboxb = gtk_vbox_new( FALSE, 4 );
1145 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1147 vbuttonbox = gtk_vbutton_box_new();
1148 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1149 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1150 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1151 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1154 buttonUp = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
1155 buttonDown = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
1156 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1157 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1158 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1161 #ifndef GENERIC_UMPC
1162 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
1164 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
1166 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1168 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1170 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1172 gtk_widget_show_all(vbox);
1174 /* Event handlers */
1175 g_signal_connect( G_OBJECT(clist), "select_row",
1176 G_CALLBACK( edit_person_email_list_selected), NULL );
1177 g_signal_connect( G_OBJECT(buttonUp), "clicked",
1178 G_CALLBACK( edit_person_email_move_up ), NULL );
1179 g_signal_connect( G_OBJECT(buttonDown), "clicked",
1180 G_CALLBACK( edit_person_email_move_down ), NULL );
1181 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1182 G_CALLBACK( edit_person_email_delete ), NULL );
1183 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1184 G_CALLBACK( edit_person_email_modify ), NULL );
1185 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1186 G_CALLBACK( edit_person_email_add ), NULL );
1187 g_signal_connect(G_OBJECT(entry_email), "changed",
1188 G_CALLBACK(edit_person_entry_email_changed), NULL);
1189 g_signal_connect(G_OBJECT(entry_email), "key_press_event",
1190 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1191 g_signal_connect(G_OBJECT(entry_alias), "key_press_event",
1192 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1193 g_signal_connect(G_OBJECT(entry_remarks), "key_press_event",
1194 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1196 personeditdlg.clist_email = clist;
1197 personeditdlg.entry_email = entry_email;
1198 personeditdlg.entry_alias = entry_alias;
1199 personeditdlg.entry_remarks = entry_remarks;
1200 personeditdlg.email_up = buttonUp;
1201 personeditdlg.email_down = buttonDown;
1202 personeditdlg.email_del = buttonDel;
1203 personeditdlg.email_mod = buttonMod;
1204 personeditdlg.email_add = buttonAdd;
1207 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
1209 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
1211 gboolean non_empty = gtk_cmclist_get_row_data(GTK_CMCLIST(personeditdlg.clist_attrib), 0) != NULL;
1212 const gchar *atname;
1214 if (personeditdlg.read_only || personeditdlg.ldap)
1217 atname = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))));
1219 || strlen(atname) == 0) {
1220 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1221 gtk_widget_set_sensitive(personeditdlg.attrib_mod,FALSE);
1222 attrib_adding = FALSE;
1223 attrib_saving = FALSE;
1224 } else if (list_find_attribute(atname)) {
1225 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1226 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1227 attrib_adding = FALSE;
1228 attrib_saving = non_empty;
1230 gtk_widget_set_sensitive(personeditdlg.attrib_add,TRUE);
1231 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1232 attrib_adding = TRUE;
1233 attrib_saving = non_empty;
1237 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1239 if (event && event->keyval == GDK_Return) {
1241 edit_person_attrib_modify(NULL);
1242 else if (attrib_adding)
1243 edit_person_attrib_add(NULL);
1248 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
1253 GtkWidget *vbuttonbox;
1254 GtkWidget *buttonDel;
1255 GtkWidget *buttonMod;
1256 GtkWidget *buttonAdd;
1260 GtkWidget *clist_swin;
1262 GtkWidget *entry_name;
1263 GtkWidget *entry_value;
1266 gchar *titles[ ATTRIB_N_COLS ];
1269 titles[ ATTRIB_COL_NAME ] = _("Name");
1270 titles[ ATTRIB_COL_VALUE ] = _("Value");
1272 vbox = gtk_vbox_new( FALSE, 8 );
1273 gtk_widget_show( vbox );
1274 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1275 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1277 label = gtk_label_new_with_mnemonic( pageLbl );
1278 gtk_widget_show( label );
1279 gtk_notebook_set_tab_label(
1280 GTK_NOTEBOOK( personeditdlg.notebook ),
1281 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1283 /* Split into two areas */
1284 hbox = gtk_hbox_new( FALSE, 0 );
1285 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1287 /* Attribute list */
1288 vboxl = gtk_vbox_new( FALSE, 4 );
1289 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1290 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1292 clist_swin = gtk_scrolled_window_new( NULL, NULL );
1293 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
1294 GTK_POLICY_AUTOMATIC,
1295 GTK_POLICY_AUTOMATIC);
1297 clist = gtk_cmclist_new_with_titles( ATTRIB_N_COLS, titles );
1298 gtk_container_add( GTK_CONTAINER(clist_swin), clist );
1299 gtk_cmclist_set_selection_mode( GTK_CMCLIST(clist), GTK_SELECTION_BROWSE );
1300 gtk_cmclist_set_compare_func( GTK_CMCLIST(clist), edit_person_attrib_compare_func );
1301 gtk_cmclist_set_auto_sort( GTK_CMCLIST(clist), TRUE );
1302 gtk_cmclist_set_column_width( GTK_CMCLIST(clist), ATTRIB_COL_NAME, ATTRIB_COL_WIDTH_NAME );
1303 gtk_cmclist_set_column_width( GTK_CMCLIST(clist), ATTRIB_COL_VALUE, ATTRIB_COL_WIDTH_VALUE );
1305 for( i = 0; i < ATTRIB_N_COLS; i++ )
1306 GTK_WIDGET_UNSET_FLAGS(GTK_CMCLIST(clist)->column[i].button, GTK_CAN_FOCUS);
1308 /* Data entry area */
1309 #ifndef GENERIC_UMPC
1310 table = gtk_table_new( 4, 2, FALSE);
1311 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1312 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1314 table = gtk_table_new( 2, 4, FALSE);
1315 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1316 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1317 gtk_cmclist_column_titles_hide(GTK_CMCLIST(clist));
1319 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1320 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1321 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1325 #ifndef GENERIC_UMPC
1326 label = gtk_label_new(_("Name"));
1327 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1328 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1330 entry_name = gtk_combo_box_entry_new_text ();
1331 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1335 label = gtk_label_new(_("Value"));
1336 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1337 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1339 entry_value = gtk_entry_new();
1340 gtk_table_attach(GTK_TABLE(table), entry_value, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1342 label = gtk_label_new(_("Name"));
1343 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1344 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1346 entry_name = gtk_combo_box_entry_new_text ();
1347 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1351 label = gtk_label_new(_("Value"));
1352 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
1353 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1355 entry_value = gtk_entry_new();
1356 gtk_table_attach(GTK_TABLE(table), entry_value, 3, 4, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1358 gtk_combo_box_set_active(GTK_COMBO_BOX(entry_name), -1);
1359 if (prefs_common.addressbook_custom_attributes)
1360 combobox_set_popdown_strings(GTK_COMBO_BOX(entry_name),
1361 prefs_common.addressbook_custom_attributes);
1364 vboxb = gtk_vbox_new( FALSE, 4 );
1365 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1367 vbuttonbox = gtk_vbutton_box_new();
1368 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1369 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1370 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1371 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1374 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1375 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1377 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1378 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1380 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1381 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1383 gtk_widget_set_sensitive(buttonDel,FALSE);
1384 gtk_widget_set_sensitive(buttonMod,FALSE);
1385 gtk_widget_set_sensitive(buttonAdd,FALSE);
1387 gtk_widget_show_all(vbox);
1389 /* Event handlers */
1390 g_signal_connect( G_OBJECT(clist), "select_row",
1391 G_CALLBACK( edit_person_attrib_list_selected), NULL );
1392 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1393 G_CALLBACK( edit_person_attrib_delete ), NULL );
1394 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1395 G_CALLBACK( edit_person_attrib_modify ), NULL );
1396 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1397 G_CALLBACK( edit_person_attrib_add ), NULL );
1398 g_signal_connect(G_OBJECT(entry_name), "changed",
1399 G_CALLBACK(edit_person_entry_att_changed), NULL);
1400 g_signal_connect(G_OBJECT(entry_name), "key_press_event",
1401 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1402 g_signal_connect(G_OBJECT(entry_value), "key_press_event",
1403 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1405 personeditdlg.clist_attrib = clist;
1406 personeditdlg.entry_atname = entry_name;
1407 personeditdlg.entry_atvalue = entry_value;
1408 personeditdlg.attrib_add = buttonAdd;
1409 personeditdlg.attrib_del = buttonDel;
1410 personeditdlg.attrib_mod = buttonMod;
1413 static void addressbook_edit_person_create( GtkWidget *parent, gboolean *cancelled ) {
1414 if (prefs_common.addressbook_use_editaddress_dialog)
1415 addressbook_edit_person_dialog_create( cancelled );
1417 addressbook_edit_person_widgetset_create( parent, cancelled );
1418 addressbook_edit_person_page_basic( PAGE_BASIC, _( "_User Data" ) );
1419 addressbook_edit_person_page_email( PAGE_EMAIL, _( "_Email Addresses" ) );
1421 if (personeditdlg.ldap)
1422 addressbook_edit_person_page_attrib_ldap(&personeditdlg, PAGE_ATTRIBUTES, _("O_ther Attributes"));
1425 addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "O_ther Attributes" ) );
1426 gtk_widget_show_all( personeditdlg.container );
1430 * Return list of email items.
1432 static GList *edit_person_build_email_list() {
1433 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_email);
1434 GList *listEMail = NULL;
1437 while( (email = gtk_cmclist_get_row_data( clist, row )) ) {
1438 listEMail = g_list_append( listEMail, email );
1445 * Return list of attributes.
1447 static GList *edit_person_build_attrib_list() {
1448 GtkCMCList *clist = GTK_CMCLIST(personeditdlg.clist_attrib);
1449 GList *listAttrib = NULL;
1450 UserAttribute *attrib;
1452 while( (attrib = gtk_cmclist_get_row_data( clist, row )) ) {
1453 listAttrib = g_list_append( listAttrib, attrib );
1459 static void update_sensitivity(void)
1461 gtk_widget_set_sensitive(personeditdlg.entry_name, !personeditdlg.read_only);
1462 gtk_widget_set_sensitive(personeditdlg.entry_first, !personeditdlg.read_only);
1463 gtk_widget_set_sensitive(personeditdlg.entry_last, !personeditdlg.read_only);
1464 gtk_widget_set_sensitive(personeditdlg.entry_nick, !personeditdlg.read_only && !personeditdlg.ldap);
1465 gtk_widget_set_sensitive(personeditdlg.entry_email, !personeditdlg.read_only);
1466 gtk_widget_set_sensitive(personeditdlg.entry_alias, !personeditdlg.read_only && !personeditdlg.ldap);
1467 gtk_widget_set_sensitive(personeditdlg.entry_remarks, !personeditdlg.read_only && !personeditdlg.ldap);
1468 gtk_widget_set_sensitive(personeditdlg.email_up, !personeditdlg.read_only);
1469 gtk_widget_set_sensitive(personeditdlg.email_down, !personeditdlg.read_only);
1470 gtk_widget_set_sensitive(personeditdlg.email_del, !personeditdlg.read_only);
1471 gtk_widget_set_sensitive(personeditdlg.email_mod, !personeditdlg.read_only);
1472 gtk_widget_set_sensitive(personeditdlg.email_add, !personeditdlg.read_only);
1473 gtk_widget_set_sensitive(personeditdlg.entry_atname, !personeditdlg.read_only);
1474 gtk_widget_set_sensitive(personeditdlg.entry_atvalue, !personeditdlg.read_only);
1475 gtk_widget_set_sensitive(personeditdlg.attrib_add, !personeditdlg.read_only);
1476 gtk_widget_set_sensitive(personeditdlg.attrib_del, !personeditdlg.read_only);
1477 gtk_widget_set_sensitive(personeditdlg.attrib_mod, !personeditdlg.read_only);
1480 static void addressbook_edit_person_flush_transient( void )
1482 ItemPerson *person = current_person;
1483 EditAddressPostUpdateCallback callback = edit_person_close_post_update_cb;
1485 /* reset transient data */
1487 current_person = NULL;
1488 current_parent_folder = NULL;
1489 edit_person_close_post_update_cb = NULL;
1491 /* post action to perform on addressbook side */
1496 void addressbook_edit_person_invalidate( AddressBookFile *abf, ItemFolder *parent_folder,
1497 ItemPerson *person )
1499 if (current_abf == NULL &&
1500 current_person == NULL &&
1501 current_parent_folder == NULL)
1502 /* edit address form is already hidden */
1505 /* unconditional invalidation or invalidating the currently edited item */
1506 if ( ( abf == NULL && person == NULL && parent_folder == NULL )
1507 || (current_abf == abf ||
1508 current_person == person ||
1509 current_parent_folder == parent_folder))
1510 addressbook_edit_person_close( TRUE );
1513 static gboolean addressbook_edit_person_close( gboolean cancelled )
1515 GList *listEMail = NULL;
1516 GList *listAttrib = NULL;
1517 GError *error = NULL;
1519 listEMail = edit_person_build_email_list();
1520 listAttrib = edit_person_build_attrib_list();
1522 addritem_free_list_email( listEMail );
1523 addritem_free_list_attribute( listAttrib );
1524 gtk_cmclist_clear( GTK_CMCLIST(personeditdlg.clist_email) );
1525 gtk_cmclist_clear( GTK_CMCLIST(personeditdlg.clist_attrib) );
1527 if (!prefs_common.addressbook_use_editaddress_dialog)
1528 gtk_widget_hide( personeditdlg.container );
1530 /* no callback, as we're discarding the form */
1531 edit_person_close_post_update_cb = NULL;
1532 addressbook_edit_person_flush_transient();
1533 current_person = NULL;
1535 /* set focus to the address list (this is done by the post_update_cb usually) */
1536 addressbook_address_list_set_focus();
1540 if( current_person && current_abf ) {
1541 /* Update email/attribute list for existing current_person */
1542 addrbook_update_address_list( current_abf, current_person, listEMail );
1543 addrbook_update_attrib_list( current_abf, current_person, listAttrib );
1546 /* Create new current_person and email/attribute list */
1547 if( ! cancelled && current_abf ) {
1548 current_person = addrbook_add_address_list( current_abf, current_parent_folder, listEMail );
1549 addrbook_add_attrib_list( current_abf, current_person, listAttrib );
1556 /* Set current_person stuff */
1559 gchar *cn = edit_person_get_common_name_from_widgets();
1561 addritem_person_set_common_name( current_person, cn );
1564 if (personeditdlg.picture_set) {
1565 GdkPixbuf * pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(personeditdlg.image));
1567 if (!current_person->picture)
1568 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1569 ADDRITEM_ID(current_person), ".png", NULL );
1571 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1572 current_person->picture, ".png", NULL );
1574 gdk_pixbuf_save(pixbuf, name, "png", &error, NULL);
1576 alertpanel_error(_("Failed to save image: \n%s"),
1578 g_error_free(error);
1580 debug_print("saved picture to %s\n", name);
1582 if (!current_person->picture)
1583 addritem_person_set_picture( current_person, ADDRITEM_ID(current_person) ) ;
1586 if (!current_person->picture)
1587 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1588 ADDRITEM_ID(current_person), ".png", NULL );
1590 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1591 current_person->picture, ".png", NULL );
1595 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1596 addritem_person_set_first_name( current_person, name );
1598 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1599 addritem_person_set_last_name( current_person, name );
1601 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1602 addritem_person_set_nick_name( current_person, name );
1606 gtk_cmclist_clear( GTK_CMCLIST(personeditdlg.clist_email) );
1607 gtk_cmclist_clear( GTK_CMCLIST(personeditdlg.clist_attrib) );
1609 if (!prefs_common.addressbook_use_editaddress_dialog)
1610 gtk_widget_hide( personeditdlg.container );
1612 addressbook_edit_person_flush_transient();
1619 * Enter: abf Address book.
1620 * parent Parent folder for person (or NULL if adding to root folder). Argument is
1621 * only required for new objects).
1622 * person Person to edit, or NULL for a new person object.
1623 * pgMail If TRUE, E-Mail page will be activated.
1624 * Return: Edited object, or NULL if cancelled.*/
1625 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent_folder, ItemPerson *person,
1626 gboolean pgMail, GtkWidget *parent_container,
1627 void (*post_update_cb) (ItemPerson *person),
1628 gboolean get_focus) {
1629 static gboolean cancelled;
1630 GError *error = NULL;
1631 GdkPixbuf *pixbuf = NULL;
1632 /* set transient data */
1634 current_person = person;
1635 current_parent_folder = parent_folder;
1636 edit_person_close_post_update_cb = post_update_cb;
1637 personeditdlg.ldap = (abf && abf->type == ADBOOKTYPE_LDAP)? TRUE : FALSE;
1639 if( personeditdlg.container ) {
1640 gtk_widget_destroy(personeditdlg.container);
1641 personeditdlg.container = NULL;
1643 addressbook_edit_person_create(parent_container, &cancelled);
1645 /* typically, get focus when dialog mode is enabled, or when editing a new address */
1647 gtk_widget_grab_focus(personeditdlg.ok_btn);
1648 gtk_widget_grab_focus(personeditdlg.entry_name);
1651 personeditdlg.read_only = (current_abf == NULL);
1652 update_sensitivity();
1654 gtk_widget_show(personeditdlg.container);
1655 if (prefs_common.addressbook_use_editaddress_dialog)
1656 manage_window_set_transient(GTK_WINDOW(personeditdlg.container));
1659 addressbook_address_list_disable_some_actions();
1661 /* Clear all fields */
1662 personeditdlg.rowIndEMail = -1;
1663 personeditdlg.rowIndAttrib = -1;
1664 edit_person_status_show( "" );
1665 gtk_cmclist_clear( GTK_CMCLIST(personeditdlg.clist_email) );
1666 gtk_cmclist_clear( GTK_CMCLIST(personeditdlg.clist_attrib) );
1667 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1668 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1669 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1670 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1672 personeditdlg.editNew = FALSE;
1673 if( current_person ) {
1674 gchar *filename = NULL;
1676 if( ADDRITEM_NAME(current_person) )
1677 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1679 cm_menu_set_sensitive("EditAddressPopup/SetPicture", !personeditdlg.ldap);
1680 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", !personeditdlg.ldap);
1681 if( current_person->picture ) {
1682 filename = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1683 current_person->picture, ".png", NULL );
1684 if (is_file_exist(filename)) {
1685 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
1687 debug_print("Failed to import image: \n%s",
1689 g_error_free(error);
1692 personeditdlg.picture_set = TRUE;
1693 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", !personeditdlg.ldap && personeditdlg.picture_set);
1697 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
1700 addressbook_edit_person_clear_picture();
1705 g_object_unref(pixbuf);
1709 if( current_person->firstName )
1710 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), current_person->firstName );
1711 if( current_person->lastName )
1712 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), current_person->lastName );
1713 if( current_person->nickName )
1714 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), current_person->nickName );
1715 edit_person_load_email( current_person );
1716 edit_person_load_attrib( current_person );
1717 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_atvalue), "");
1720 personeditdlg.editNew = TRUE;
1723 /* Select appropriate start page */
1725 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1728 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1731 gtk_cmclist_select_row( GTK_CMCLIST(personeditdlg.clist_email), 0, 0 );
1732 gtk_cmclist_select_row( GTK_CMCLIST(personeditdlg.clist_attrib), 0, 0 );
1733 edit_person_email_clear( NULL );
1735 edit_person_email_list_selected(GTK_CMCLIST(personeditdlg.clist_email), 0, 0, NULL, NULL);
1737 edit_person_attrib_clear( NULL );
1739 if (prefs_common.addressbook_use_editaddress_dialog) {
1741 gtk_widget_hide( personeditdlg.container );
1743 if (!addressbook_edit_person_close( cancelled )) {
1751 void addressbook_edit_reload_attr_list( void )
1753 if (personeditdlg.entry_atname) {
1754 combobox_unset_popdown_strings(GTK_COMBO_BOX(personeditdlg.entry_atname));
1755 if (prefs_common.addressbook_custom_attributes)
1756 combobox_set_popdown_strings(GTK_COMBO_BOX(personeditdlg.entry_atname),
1757 prefs_common.addressbook_custom_attributes);