2007-01-25 [paul] 2.7.1cvs2-stable
[claws.git] / src / editaddress.c
blob91aad647eeaba84ebc40f8ec0217357a2d928a12
1 /*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include "defs.h"
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <gtk/gtkwindow.h>
30 #include <gtk/gtksignal.h>
31 #include <gtk/gtklabel.h>
32 #include <gtk/gtkvbox.h>
33 #include <gtk/gtkentry.h>
34 #include <gtk/gtktable.h>
36 #include "mgutils.h"
37 #include "addressbook.h"
38 #include "addressitem.h"
39 #include "addritem.h"
40 #include "addrbook.h"
41 #include "manage_window.h"
42 #include "gtkutils.h"
43 #include "codeconv.h"
44 #include "editaddress.h"
46 #include "prefs_common.h"
48 static struct _PersonEdit_dlg {
49 GtkWidget *container;
50 GtkWidget *notebook;
51 GtkWidget *ok_btn;
52 GtkWidget *cancel_btn;
53 GtkWidget *statusbar; /* used when prefs_common.addressbook_use_editaddress_dialog is TRUE */
54 GtkWidget *title; /* used when prefs_common.addressbook_use_editaddress_dialog is FALSE */
55 gint status_cid;
57 /* User data tab */
58 GtkWidget *entry_name;
59 GtkWidget *entry_first;
60 GtkWidget *entry_last;
61 GtkWidget *entry_nick;
63 /* EMail data tab */
64 GtkWidget *entry_email;
65 GtkWidget *entry_alias;
66 GtkWidget *entry_remarks;
67 GtkWidget *clist_email;
68 GtkWidget *email_up;
69 GtkWidget *email_down;
70 GtkWidget *email_del;
71 GtkWidget *email_mod;
72 GtkWidget *email_add;
74 /* Attribute data tab */
75 GtkWidget *entry_atname;
76 GtkWidget *entry_atvalue;
77 GtkWidget *clist_attrib;
78 GtkWidget *attrib_add;
79 GtkWidget *attrib_del;
80 GtkWidget *attrib_mod;
82 gint rowIndEMail;
83 gint rowIndAttrib;
84 gboolean editNew;
85 gboolean read_only;
86 } personeditdlg;
88 /* transient data */
89 static AddressBookFile *current_abf = NULL;
90 static ItemPerson *current_person = NULL;
91 static ItemFolder *current_parent_folder = NULL;
92 static EditAddressPostUpdateCallback edit_person_close_post_update_cb = NULL;
94 typedef enum {
95 EMAIL_COL_EMAIL = 0,
96 EMAIL_COL_ALIAS = 1,
97 EMAIL_COL_REMARKS = 2
98 } PersonEditEMailColumnPos;
100 typedef enum {
101 ATTRIB_COL_NAME = 0,
102 ATTRIB_COL_VALUE = 1
103 } PersonEditAttribColumnPos;
105 #define EDITPERSON_WIDTH 520
106 #define EDITPERSON_HEIGHT 320
108 #define EMAIL_N_COLS 3
109 #define EMAIL_COL_WIDTH_EMAIL 180
110 #define EMAIL_COL_WIDTH_ALIAS 80
112 #define ATTRIB_N_COLS 2
113 #define ATTRIB_COL_WIDTH_NAME 120
114 #define ATTRIB_COL_WIDTH_VALUE 180
116 #define PAGE_BASIC 0
117 #define PAGE_EMAIL 1
118 #define PAGE_ATTRIBUTES 2
120 static void edit_person_status_show( gchar *msg ) {
121 if( personeditdlg.statusbar != NULL ) {
122 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
123 if( msg ) {
124 gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
129 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
130 *cancelled = FALSE;
131 if (prefs_common.addressbook_use_editaddress_dialog)
132 gtk_main_quit();
133 else
134 addressbook_edit_person_close( *cancelled );
137 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
138 *cancelled = TRUE;
139 if (prefs_common.addressbook_use_editaddress_dialog)
140 gtk_main_quit();
141 else
142 addressbook_edit_person_close( *cancelled );
145 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
146 *cancelled = TRUE;
147 if (prefs_common.addressbook_use_editaddress_dialog)
148 gtk_main_quit();
149 else
150 addressbook_edit_person_close( *cancelled );
151 return TRUE;
154 static gboolean edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
155 if (prefs_common.addressbook_use_editaddress_dialog) {
156 if (event && event->keyval == GDK_Escape) {
157 *cancelled = TRUE;
158 gtk_main_quit();
161 return FALSE;
164 static gchar *_title_new_ = NULL;
165 static gchar *_title_edit_ = NULL;
167 static void edit_person_set_widgets_title( gchar *text )
169 gchar *label = NULL;
171 g_return_if_fail( text != NULL );
173 gtk_label_set_text(GTK_LABEL(personeditdlg.title), "");
174 label = g_markup_printf_escaped("<b>%s</b>", text);
175 gtk_label_set_markup(GTK_LABEL(personeditdlg.title), label);
176 g_free(label);
179 static void edit_person_set_window_title( gint pageNum ) {
180 gchar *sTitle;
182 if( _title_new_ == NULL ) {
183 _title_new_ = g_strdup( _("Add New Person") );
184 _title_edit_ = g_strdup( _("Edit Person Details") );
187 if( pageNum == PAGE_BASIC ) {
188 if( personeditdlg.editNew ) {
189 if (prefs_common.addressbook_use_editaddress_dialog)
190 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_new_ );
191 else
192 edit_person_set_widgets_title( _title_new_ );
194 else {
195 if (prefs_common.addressbook_use_editaddress_dialog)
196 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_edit_ );
197 else
198 edit_person_set_widgets_title( _title_edit_ );
201 else {
202 if( personeditdlg.entry_name == NULL ) {
203 sTitle = g_strdup( _title_edit_ );
205 else {
206 gchar *name;
207 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
208 sTitle = g_strdup_printf( "%s - %s", _title_edit_, name );
209 g_free( name );
211 if (prefs_common.addressbook_use_editaddress_dialog)
212 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), sTitle );
213 else
214 edit_person_set_widgets_title( sTitle );
215 g_free( sTitle );
219 static void edit_person_email_clear( gpointer data ) {
220 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
221 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
222 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
225 static void edit_person_attrib_clear( gpointer data ) {
226 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), "" );
227 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
230 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
231 gint pageNum, gpointer user_data)
233 edit_person_set_window_title( pageNum );
234 edit_person_status_show( "" );
238 * Load clist with a copy of person's email addresses.
240 static void edit_person_load_email( ItemPerson *person ) {
241 GList *node = person->listEMail;
242 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
243 gchar *text[ EMAIL_N_COLS ];
244 while( node ) {
245 ItemEMail *emorig = ( ItemEMail * ) node->data;
246 ItemEMail *email = addritem_copyfull_item_email( emorig );
247 gint row;
248 text[ EMAIL_COL_EMAIL ] = email->address;
249 text[ EMAIL_COL_ALIAS ] = email->obj.name;
250 text[ EMAIL_COL_REMARKS ] = email->remarks;
252 row = gtk_clist_append( clist, text );
253 gtk_clist_set_row_data( clist, row, email );
254 node = g_list_next( node );
258 static void edit_person_email_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
259 ItemEMail *email = gtk_clist_get_row_data( clist, row );
260 if( email ) {
261 if( email->address )
262 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), email->address );
263 if( ADDRITEM_NAME(email) )
264 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), ADDRITEM_NAME(email) );
265 if( email->remarks )
266 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), email->remarks );
267 if (!personeditdlg.read_only) {
268 gtk_widget_set_sensitive(personeditdlg.email_del, TRUE);
269 gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
270 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, row + 1) != NULL);
272 } else {
273 gtk_widget_set_sensitive(personeditdlg.email_del, FALSE);
274 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
275 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
277 personeditdlg.rowIndEMail = row;
278 edit_person_status_show( NULL );
281 static void edit_person_email_move( gint dir ) {
282 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
283 gint row = personeditdlg.rowIndEMail + dir;
284 ItemEMail *email = gtk_clist_get_row_data( clist, row );
285 if( email ) {
286 gtk_clist_row_move( clist, personeditdlg.rowIndEMail, row );
287 personeditdlg.rowIndEMail = row;
288 if (!personeditdlg.read_only) {
289 gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
290 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, row + 1) != NULL);
292 } else {
293 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
294 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
296 edit_person_email_clear( NULL );
297 edit_person_status_show( NULL );
300 static void edit_person_email_move_up( gpointer data ) {
301 edit_person_email_move( -1 );
304 static void edit_person_email_move_down( gpointer data ) {
305 edit_person_email_move( +1 );
308 static void edit_person_email_delete( gpointer data ) {
309 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
310 gint row = personeditdlg.rowIndEMail;
311 ItemEMail *email = gtk_clist_get_row_data( clist, row );
312 edit_person_email_clear( NULL );
313 if( email ) {
314 /* Remove list entry */
315 gtk_clist_remove( clist, row );
316 addritem_free_item_email( email );
317 email = NULL;
320 /* Position hilite bar */
321 email = gtk_clist_get_row_data( clist, row );
322 if( ! email ) {
323 personeditdlg.rowIndEMail = -1 + row;
325 if (!personeditdlg.read_only) {
326 gtk_widget_set_sensitive(personeditdlg.email_del, gtk_clist_get_row_data(clist, 0) != NULL);
327 gtk_widget_set_sensitive(personeditdlg.email_up, gtk_clist_get_row_data(clist, personeditdlg.rowIndEMail + 1) != NULL);
328 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, personeditdlg.rowIndEMail - 1) != NULL);
330 edit_person_status_show( NULL );
333 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
334 ItemEMail *retVal = NULL;
335 gchar *sEmail, *sAlias, *sRemarks, *sEmail_;
337 *error = TRUE;
338 sEmail_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
339 sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
340 sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
341 sEmail = mgu_email_check_empty( sEmail_ );
342 g_free( sEmail_ );
344 if( sEmail ) {
345 if( email == NULL ) {
346 email = addritem_create_item_email();
348 addritem_email_set_address( email, sEmail );
349 addritem_email_set_alias( email, sAlias );
350 addritem_email_set_remarks( email, sRemarks );
351 retVal = email;
352 *error = FALSE;
354 else {
355 edit_person_status_show( _( "An Email address must be supplied." ) );
358 g_free( sEmail );
359 g_free( sAlias );
360 g_free( sRemarks );
362 return retVal;
365 static void edit_person_email_modify( gpointer data ) {
366 gboolean errFlg = FALSE;
367 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
368 gint row = personeditdlg.rowIndEMail;
369 ItemEMail *email = gtk_clist_get_row_data( clist, row );
370 if( email ) {
371 edit_person_email_edit( &errFlg, email );
372 if( ! errFlg ) {
373 gtk_clist_set_text( clist, row, EMAIL_COL_EMAIL, email->address );
374 gtk_clist_set_text( clist, row, EMAIL_COL_ALIAS, email->obj.name );
375 gtk_clist_set_text( clist, row, EMAIL_COL_REMARKS, email->remarks );
376 edit_person_email_clear( NULL );
381 static void edit_person_email_add( gpointer data ) {
382 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
383 gboolean errFlg = FALSE;
384 ItemEMail *email = NULL;
385 gint row = personeditdlg.rowIndEMail;
386 if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
388 email = edit_person_email_edit( &errFlg, NULL );
389 if( ! errFlg ) {
390 gchar *text[ EMAIL_N_COLS ];
391 text[ EMAIL_COL_EMAIL ] = email->address;
392 text[ EMAIL_COL_ALIAS ] = email->obj.name;
393 text[ EMAIL_COL_REMARKS ] = email->remarks;
395 row = gtk_clist_insert( clist, 1 + row, text );
396 gtk_clist_set_row_data( clist, row, email );
397 gtk_clist_select_row( clist, row, 0 );
398 edit_person_email_clear( NULL );
403 * Comparison using cell contents (text in first column). Used for sort
404 * address index widget.
406 static gint edit_person_attrib_compare_func(
407 GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2 )
409 GtkCell *cell1 = ((GtkCListRow *)ptr1)->cell;
410 GtkCell *cell2 = ((GtkCListRow *)ptr2)->cell;
411 gchar *name1 = NULL, *name2 = NULL;
413 if( cell1 ) name1 = cell1->u.text;
414 if( cell2 ) name2 = cell2->u.text;
415 if( ! name1 ) return ( name2 != NULL );
416 if( ! name2 ) return -1;
417 return g_utf8_collate( name1, name2 );
420 static gboolean list_find_attribute(const gchar *attr)
422 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
423 UserAttribute *attrib;
424 gint row = 0;
425 while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
426 if (!g_ascii_strcasecmp(attrib->name, attr)) {
427 gtk_clist_select_row(clist, row, 0);
428 return TRUE;
430 row++;
432 return FALSE;
435 static gboolean list_find_email(const gchar *addr)
437 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
438 ItemEMail *email;
439 gint row = 0;
440 while( (email = gtk_clist_get_row_data( clist, row )) ) {
441 if (!g_ascii_strcasecmp(email->address, addr)) {
442 gtk_clist_select_row(clist, row, 0);
443 return TRUE;
445 row++;
447 return FALSE;
451 * Load clist with a copy of person's email addresses.
453 static void edit_person_load_attrib( ItemPerson *person ) {
454 GList *node = person->listAttrib;
455 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
456 gchar *text[ ATTRIB_N_COLS ];
457 while( node ) {
458 UserAttribute *atorig = ( UserAttribute * ) node->data;
459 UserAttribute *attrib = addritem_copy_attribute( atorig );
460 gint row;
461 text[ ATTRIB_COL_NAME ] = attrib->name;
462 text[ ATTRIB_COL_VALUE ] = attrib->value;
464 row = gtk_clist_append( clist, text );
465 gtk_clist_set_row_data( clist, row, attrib );
466 node = g_list_next( node );
470 static void edit_person_attrib_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
471 UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
472 if( attrib && !personeditdlg.read_only) {
473 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), attrib->name );
474 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
475 gtk_widget_set_sensitive(personeditdlg.attrib_del, TRUE);
476 } else {
477 gtk_widget_set_sensitive(personeditdlg.attrib_del, FALSE);
479 personeditdlg.rowIndAttrib = row;
480 edit_person_status_show( NULL );
483 static void edit_person_attrib_delete( gpointer data ) {
484 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
485 gint row = personeditdlg.rowIndAttrib;
486 UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
487 edit_person_attrib_clear( NULL );
488 if( attrib ) {
489 /* Remove list entry */
490 gtk_clist_remove( clist, row );
491 addritem_free_attribute( attrib );
492 attrib = NULL;
495 /* Position hilite bar */
496 attrib = gtk_clist_get_row_data( clist, row );
497 if( ! attrib ) {
498 personeditdlg.rowIndAttrib = -1 + row;
501 if (!personeditdlg.read_only)
502 gtk_widget_set_sensitive(personeditdlg.attrib_del, gtk_clist_get_row_data(clist, 0) != NULL);
504 edit_person_status_show( NULL );
507 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
508 UserAttribute *retVal = NULL;
509 gchar *sName, *sValue, *sName_, *sValue_;
511 *error = TRUE;
512 sName_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atname), 0, -1 );
513 sValue_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
514 sName = mgu_email_check_empty( sName_ );
515 sValue = mgu_email_check_empty( sValue_ );
516 g_free( sName_ );
517 g_free( sValue_ );
519 if( sName && sValue ) {
520 if( attrib == NULL ) {
521 attrib = addritem_create_attribute();
523 addritem_attrib_set_name( attrib, sName );
524 addritem_attrib_set_value( attrib, sValue );
525 retVal = attrib;
526 *error = FALSE;
528 else {
529 edit_person_status_show( _( "A Name and Value must be supplied." ) );
532 g_free( sName );
533 g_free( sValue );
535 return retVal;
538 static void edit_person_attrib_modify( gpointer data ) {
539 gboolean errFlg = FALSE;
540 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
541 gint row = personeditdlg.rowIndAttrib;
542 UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
543 if( attrib ) {
544 edit_person_attrib_edit( &errFlg, attrib );
545 if( ! errFlg ) {
546 gtk_clist_set_text( clist, row, ATTRIB_COL_NAME, attrib->name );
547 gtk_clist_set_text( clist, row, ATTRIB_COL_VALUE, attrib->value );
548 edit_person_attrib_clear( NULL );
553 static void edit_person_attrib_add( gpointer data ) {
554 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
555 gboolean errFlg = FALSE;
556 UserAttribute *attrib = NULL;
557 gint row = personeditdlg.rowIndAttrib;
558 if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
560 attrib = edit_person_attrib_edit( &errFlg, NULL );
561 if( ! errFlg ) {
562 gchar *text[ EMAIL_N_COLS ];
563 text[ ATTRIB_COL_NAME ] = attrib->name;
564 text[ ATTRIB_COL_VALUE ] = attrib->value;
566 row = gtk_clist_insert( clist, 1 + row, text );
567 gtk_clist_set_row_data( clist, row, attrib );
568 gtk_clist_select_row( clist, row, 0 );
569 edit_person_attrib_clear( NULL );
574 *\brief Save Gtk object size to prefs dataset
576 static void edit_person_size_allocate_cb(GtkWidget *widget,
577 GtkAllocation *allocation)
579 g_return_if_fail(allocation != NULL);
581 prefs_common.addressbookeditpersonwin_width = allocation->width;
582 prefs_common.addressbookeditpersonwin_height = allocation->height;
585 /* build edit person widgets, return a pointer to the main container of the widgetset (a vbox) */
586 static GtkWidget* addressbook_edit_person_widgets_create( GtkWidget* container, gboolean *cancelled )
588 GtkWidget *vbox;
589 GtkWidget *vnbox;
590 GtkWidget *notebook;
591 GtkWidget *hbbox;
592 GtkWidget *ok_btn;
593 GtkWidget *cancel_btn;
595 vbox = gtk_vbox_new(FALSE, 4);
596 /* gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH); */
597 gtk_widget_show(vbox);
598 gtk_container_add(GTK_CONTAINER(container), vbox);
600 vnbox = gtk_vbox_new(FALSE, 4);
601 gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
602 gtk_widget_show(vnbox);
603 gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
605 /* Notebook */
606 notebook = gtk_notebook_new();
607 gtk_widget_show(notebook);
608 gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
609 gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
611 /* Button panel */
612 if (prefs_common.addressbook_use_editaddress_dialog)
613 gtkut_stock_button_set_create(&hbbox, &cancel_btn, GTK_STOCK_CANCEL,
614 &ok_btn, GTK_STOCK_OK,
615 NULL, NULL);
616 else
617 gtkut_stock_with_text_button_set_create(&hbbox,
618 &cancel_btn, GTK_STOCK_CANCEL, _("Discard"),
619 &ok_btn, GTK_STOCK_OK, _("Apply"),
620 NULL, NULL, NULL);
621 gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
622 gtk_widget_grab_default(ok_btn);
624 g_signal_connect(G_OBJECT(ok_btn), "clicked",
625 G_CALLBACK(edit_person_ok), cancelled);
626 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
627 G_CALLBACK(edit_person_cancel), cancelled);
628 g_signal_connect(G_OBJECT(notebook), "switch_page",
629 G_CALLBACK(edit_person_switch_page), NULL );
631 gtk_widget_show_all(vbox);
633 personeditdlg.notebook = notebook;
634 personeditdlg.ok_btn = ok_btn;
635 personeditdlg.cancel_btn = cancel_btn;
637 return vbox;
640 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
641 GtkWidget *window;
642 GtkWidget *hsbox;
643 GtkWidget *vbox;
644 GtkWidget *statusbar;
645 static GdkGeometry geometry;
647 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
648 /* gtk_container_set_border_width(GTK_CONTAINER(window), 0); */
649 gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
650 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
651 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
652 g_signal_connect(G_OBJECT(window), "delete_event",
653 G_CALLBACK(edit_person_delete_event),
654 cancelled);
655 g_signal_connect(G_OBJECT(window), "size_allocate",
656 G_CALLBACK(edit_person_size_allocate_cb),
657 cancelled);
658 g_signal_connect(G_OBJECT(window), "key_press_event",
659 G_CALLBACK(edit_person_key_pressed),
660 cancelled);
662 vbox = addressbook_edit_person_widgets_create(window, cancelled);
664 /* Status line */
665 hsbox = gtk_hbox_new(FALSE, 0);
666 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
667 statusbar = gtk_statusbar_new();
668 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
670 if (!geometry.min_height) {
671 geometry.min_width = EDITPERSON_WIDTH;
672 geometry.min_height = EDITPERSON_HEIGHT;
675 gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
676 GDK_HINT_MIN_SIZE);
677 gtk_widget_set_size_request(window, prefs_common.addressbookeditpersonwin_width,
678 prefs_common.addressbookeditpersonwin_height);
680 personeditdlg.container = window;
681 personeditdlg.statusbar = statusbar;
682 personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
686 /* parent must be a box */
687 static void addressbook_edit_person_widgetset_create( GtkWidget *parent, gboolean *cancelled )
689 GtkWidget *vbox;
690 GtkWidget *label;
692 if ( parent == NULL )
693 g_warning("addressbook_edit_person_widgetset_create: parent is NULL");
695 vbox = gtk_vbox_new(FALSE, 0);
696 gtk_box_pack_end(GTK_BOX(parent), vbox, TRUE, TRUE, 0);
698 label = gtk_label_new(_("Edit Person Data"));
699 gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER);
700 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
702 addressbook_edit_person_widgets_create(vbox, cancelled);
704 gtk_widget_set_size_request(vbox, EDITPERSON_WIDTH, EDITPERSON_HEIGHT);
706 personeditdlg.container = vbox;
707 personeditdlg.title = label;
708 personeditdlg.statusbar = NULL;
709 personeditdlg.status_cid = 0;
712 void addressbook_edit_person_widgetset_hide( void )
714 if ( personeditdlg.container )
715 gtk_widget_hide( personeditdlg.container );
718 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
719 GtkWidget *vbox;
720 GtkWidget *table;
721 GtkWidget *label;
722 GtkWidget *entry_name;
723 GtkWidget *entry_fn;
724 GtkWidget *entry_ln;
725 GtkWidget *entry_nn;
726 const gchar *locale;
727 gint top = 0;
729 vbox = gtk_vbox_new( FALSE, 8 );
730 gtk_widget_show( vbox );
731 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
732 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
734 label = gtk_label_new_with_mnemonic( pageLbl );
735 gtk_widget_show( label );
736 gtk_notebook_set_tab_label(
737 GTK_NOTEBOOK( personeditdlg.notebook ),
738 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
740 table = gtk_table_new( 4, 3, FALSE);
741 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
742 gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
743 gtk_table_set_row_spacings(GTK_TABLE(table), 8);
744 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
746 #define ATTACH_ROW(text, entry) \
748 label = gtk_label_new(text); \
749 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
750 GTK_FILL, 0, 0, 0); \
751 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
753 entry = gtk_entry_new(); \
754 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
755 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
756 top++; \
759 ATTACH_ROW(_("Display Name"), entry_name);
760 locale = conv_get_current_locale();
761 if (locale &&
762 (!g_ascii_strncasecmp(locale, "ja", 2) ||
763 !g_ascii_strncasecmp(locale, "ko", 2) ||
764 !g_ascii_strncasecmp(locale, "zh", 2))) {
765 ATTACH_ROW(_("Last Name"), entry_ln);
766 ATTACH_ROW(_("First Name"), entry_fn);
767 } else {
768 ATTACH_ROW(_("First Name"), entry_fn);
769 ATTACH_ROW(_("Last Name"), entry_ln);
771 ATTACH_ROW(_("Nickname"), entry_nn);
773 #undef ATTACH_ROW
775 gtk_widget_show_all(vbox);
777 personeditdlg.entry_name = entry_name;
778 personeditdlg.entry_first = entry_fn;
779 personeditdlg.entry_last = entry_ln;
780 personeditdlg.entry_nick = entry_nn;
783 static gboolean email_adding = FALSE, email_saving = FALSE;
785 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
787 gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_email), 0) != NULL;
789 if (personeditdlg.read_only)
790 return;
792 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)) == NULL
793 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email))) == 0) {
794 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
795 gtk_widget_set_sensitive(personeditdlg.email_mod,FALSE);
796 email_adding = FALSE;
797 email_saving = FALSE;
798 } else if (list_find_email(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)))) {
799 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
800 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
801 email_adding = FALSE;
802 email_saving = non_empty;
803 } else {
804 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
805 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
806 email_adding = TRUE;
807 email_saving = non_empty;
811 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
813 if (event && event->keyval == GDK_Return) {
814 if (email_saving)
815 edit_person_email_modify(NULL);
816 else if (email_adding)
817 edit_person_email_add(NULL);
819 return FALSE;
823 static void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
824 GtkWidget *vbox;
825 GtkWidget *hbox;
826 GtkWidget *vboxl;
827 GtkWidget *vboxb;
828 GtkWidget *vbuttonbox;
829 GtkWidget *buttonUp;
830 GtkWidget *buttonDown;
831 GtkWidget *buttonDel;
832 GtkWidget *buttonMod;
833 GtkWidget *buttonAdd;
835 GtkWidget *table;
836 GtkWidget *label;
837 GtkWidget *clist_swin;
838 GtkWidget *clist;
839 GtkWidget *entry_email;
840 GtkWidget *entry_alias;
841 GtkWidget *entry_remarks;
842 gint top;
844 gchar *titles[ EMAIL_N_COLS ];
845 gint i;
847 titles[ EMAIL_COL_EMAIL ] = _("Email Address");
848 titles[ EMAIL_COL_ALIAS ] = _("Alias");
849 titles[ EMAIL_COL_REMARKS ] = _("Remarks");
851 vbox = gtk_vbox_new( FALSE, 8 );
852 gtk_widget_show( vbox );
853 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
854 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
856 label = gtk_label_new_with_mnemonic( pageLbl );
857 gtk_widget_show( label );
858 gtk_notebook_set_tab_label(
859 GTK_NOTEBOOK( personeditdlg.notebook ),
860 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
862 /* Split into two areas */
863 hbox = gtk_hbox_new( FALSE, 0 );
864 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
866 /* Address list */
867 vboxl = gtk_vbox_new( FALSE, 4 );
868 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
869 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
871 clist_swin = gtk_scrolled_window_new( NULL, NULL );
872 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
873 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
874 GTK_POLICY_AUTOMATIC,
875 GTK_POLICY_AUTOMATIC);
877 clist = gtk_clist_new_with_titles( EMAIL_N_COLS, titles );
878 gtk_container_add( GTK_CONTAINER(clist_swin), clist );
879 gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
880 gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_EMAIL, EMAIL_COL_WIDTH_EMAIL );
881 gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_ALIAS, EMAIL_COL_WIDTH_ALIAS );
883 for( i = 0; i < EMAIL_N_COLS; i++ )
884 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
886 /* Data entry area */
887 table = gtk_table_new( 4, 2, FALSE);
888 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
889 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
890 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
891 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
893 /* First row */
894 top = 0;
895 label = gtk_label_new(_("Email Address"));
896 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
897 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
899 entry_email = gtk_entry_new();
900 gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
902 /* Next row */
903 ++top;
904 label = gtk_label_new(_("Alias"));
905 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
906 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
908 entry_alias = gtk_entry_new();
909 gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
911 /* Next row */
912 ++top;
913 label = gtk_label_new(_("Remarks"));
914 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
915 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
917 entry_remarks = gtk_entry_new();
918 gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
920 /* Button box */
921 vboxb = gtk_vbox_new( FALSE, 4 );
922 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
924 vbuttonbox = gtk_vbutton_box_new();
925 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
926 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
927 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
928 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
930 /* Buttons */
931 buttonUp = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
932 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
934 buttonDown = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
935 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
937 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
938 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
940 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
941 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
943 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
944 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
946 gtk_widget_show_all(vbox);
948 /* Event handlers */
949 g_signal_connect( G_OBJECT(clist), "select_row",
950 G_CALLBACK( edit_person_email_list_selected), NULL );
951 g_signal_connect( G_OBJECT(buttonUp), "clicked",
952 G_CALLBACK( edit_person_email_move_up ), NULL );
953 g_signal_connect( G_OBJECT(buttonDown), "clicked",
954 G_CALLBACK( edit_person_email_move_down ), NULL );
955 g_signal_connect( G_OBJECT(buttonDel), "clicked",
956 G_CALLBACK( edit_person_email_delete ), NULL );
957 g_signal_connect( G_OBJECT(buttonMod), "clicked",
958 G_CALLBACK( edit_person_email_modify ), NULL );
959 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
960 G_CALLBACK( edit_person_email_add ), NULL );
961 g_signal_connect(G_OBJECT(entry_email), "changed",
962 G_CALLBACK(edit_person_entry_email_changed), NULL);
963 g_signal_connect(G_OBJECT(entry_email), "key_press_event",
964 G_CALLBACK(edit_person_entry_email_pressed), NULL);
965 g_signal_connect(G_OBJECT(entry_alias), "key_press_event",
966 G_CALLBACK(edit_person_entry_email_pressed), NULL);
967 g_signal_connect(G_OBJECT(entry_remarks), "key_press_event",
968 G_CALLBACK(edit_person_entry_email_pressed), NULL);
970 personeditdlg.clist_email = clist;
971 personeditdlg.entry_email = entry_email;
972 personeditdlg.entry_alias = entry_alias;
973 personeditdlg.entry_remarks = entry_remarks;
974 personeditdlg.email_up = buttonUp;
975 personeditdlg.email_down = buttonDown;
976 personeditdlg.email_del = buttonDel;
977 personeditdlg.email_mod = buttonMod;
978 personeditdlg.email_add = buttonAdd;
981 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
983 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
985 gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_attrib), 0) != NULL;
987 if (personeditdlg.read_only)
988 return;
990 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname)) == NULL
991 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname))) == 0) {
992 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
993 gtk_widget_set_sensitive(personeditdlg.attrib_mod,FALSE);
994 attrib_adding = FALSE;
995 attrib_saving = FALSE;
996 } else if (list_find_attribute(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname)))) {
997 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
998 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
999 attrib_adding = FALSE;
1000 attrib_saving = non_empty;
1001 } else {
1002 gtk_widget_set_sensitive(personeditdlg.attrib_add,TRUE);
1003 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1004 attrib_adding = TRUE;
1005 attrib_saving = non_empty;
1009 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1011 if (event && event->keyval == GDK_Return) {
1012 if (attrib_saving)
1013 edit_person_attrib_modify(NULL);
1014 else if (attrib_adding)
1015 edit_person_attrib_add(NULL);
1017 return FALSE;
1020 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
1021 GtkWidget *vbox;
1022 GtkWidget *hbox;
1023 GtkWidget *vboxl;
1024 GtkWidget *vboxb;
1025 GtkWidget *vbuttonbox;
1026 GtkWidget *buttonDel;
1027 GtkWidget *buttonMod;
1028 GtkWidget *buttonAdd;
1030 GtkWidget *table;
1031 GtkWidget *label;
1032 GtkWidget *clist_swin;
1033 GtkWidget *clist;
1034 GtkWidget *entry_name;
1035 GtkWidget *entry_value;
1036 gint top;
1038 gchar *titles[ ATTRIB_N_COLS ];
1039 gint i;
1041 titles[ ATTRIB_COL_NAME ] = _("Name");
1042 titles[ ATTRIB_COL_VALUE ] = _("Value");
1044 vbox = gtk_vbox_new( FALSE, 8 );
1045 gtk_widget_show( vbox );
1046 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1047 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1049 label = gtk_label_new_with_mnemonic( pageLbl );
1050 gtk_widget_show( label );
1051 gtk_notebook_set_tab_label(
1052 GTK_NOTEBOOK( personeditdlg.notebook ),
1053 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1055 /* Split into two areas */
1056 hbox = gtk_hbox_new( FALSE, 0 );
1057 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1059 /* Attribute list */
1060 vboxl = gtk_vbox_new( FALSE, 4 );
1061 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1062 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1064 clist_swin = gtk_scrolled_window_new( NULL, NULL );
1065 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1066 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
1067 GTK_POLICY_AUTOMATIC,
1068 GTK_POLICY_AUTOMATIC);
1070 clist = gtk_clist_new_with_titles( ATTRIB_N_COLS, titles );
1071 gtk_container_add( GTK_CONTAINER(clist_swin), clist );
1072 gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
1073 gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_NAME, ATTRIB_COL_WIDTH_NAME );
1074 gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_VALUE, ATTRIB_COL_WIDTH_VALUE );
1075 gtk_clist_set_compare_func( GTK_CLIST(clist), edit_person_attrib_compare_func );
1076 gtk_clist_set_auto_sort( GTK_CLIST(clist), TRUE );
1078 for( i = 0; i < ATTRIB_N_COLS; i++ )
1079 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
1081 /* Data entry area */
1082 table = gtk_table_new( 4, 2, FALSE);
1083 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1084 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1085 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1086 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1088 /* First row */
1089 top = 0;
1090 label = gtk_label_new(_("Name"));
1091 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1092 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1094 entry_name = gtk_entry_new();
1095 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1097 /* Next row */
1098 ++top;
1099 label = gtk_label_new(_("Value"));
1100 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1101 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1103 entry_value = gtk_entry_new();
1104 gtk_table_attach(GTK_TABLE(table), entry_value, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1106 /* Button box */
1107 vboxb = gtk_vbox_new( FALSE, 4 );
1108 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1110 vbuttonbox = gtk_vbutton_box_new();
1111 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1112 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1113 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1114 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1116 /* Buttons */
1117 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1118 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1120 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1121 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1123 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1124 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1126 gtk_widget_set_sensitive(buttonDel,FALSE);
1127 gtk_widget_set_sensitive(buttonMod,FALSE);
1128 gtk_widget_set_sensitive(buttonAdd,FALSE);
1130 gtk_widget_show_all(vbox);
1132 /* Event handlers */
1133 g_signal_connect( G_OBJECT(clist), "select_row",
1134 G_CALLBACK( edit_person_attrib_list_selected), NULL );
1135 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1136 G_CALLBACK( edit_person_attrib_delete ), NULL );
1137 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1138 G_CALLBACK( edit_person_attrib_modify ), NULL );
1139 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1140 G_CALLBACK( edit_person_attrib_add ), NULL );
1141 g_signal_connect(G_OBJECT(entry_name), "changed",
1142 G_CALLBACK(edit_person_entry_att_changed), NULL);
1143 g_signal_connect(G_OBJECT(entry_name), "key_press_event",
1144 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1145 g_signal_connect(G_OBJECT(entry_value), "key_press_event",
1146 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1148 personeditdlg.clist_attrib = clist;
1149 personeditdlg.entry_atname = entry_name;
1150 personeditdlg.entry_atvalue = entry_value;
1151 personeditdlg.attrib_add = buttonAdd;
1152 personeditdlg.attrib_del = buttonDel;
1153 personeditdlg.attrib_mod = buttonMod;
1156 static void addressbook_edit_person_create( GtkWidget *parent, gboolean *cancelled ) {
1157 if (prefs_common.addressbook_use_editaddress_dialog)
1158 addressbook_edit_person_dialog_create( cancelled );
1159 else
1160 addressbook_edit_person_widgetset_create( parent, cancelled );
1161 addressbook_edit_person_page_basic( PAGE_BASIC, _( "_User Data" ) );
1162 addressbook_edit_person_page_email( PAGE_EMAIL, _( "_Email Addresses" ) );
1163 addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "O_ther Attributes" ) );
1164 gtk_widget_show_all( personeditdlg.container );
1168 * Return list of email items.
1170 static GList *edit_person_build_email_list() {
1171 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
1172 GList *listEMail = NULL;
1173 ItemEMail *email;
1174 gint row = 0;
1175 while( (email = gtk_clist_get_row_data( clist, row )) ) {
1176 listEMail = g_list_append( listEMail, email );
1177 row++;
1179 return listEMail;
1183 * Return list of attributes.
1185 static GList *edit_person_build_attrib_list() {
1186 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
1187 GList *listAttrib = NULL;
1188 UserAttribute *attrib;
1189 gint row = 0;
1190 while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
1191 listAttrib = g_list_append( listAttrib, attrib );
1192 row++;
1194 return listAttrib;
1197 static void update_sensitivity(void)
1199 gtk_widget_set_sensitive(personeditdlg.entry_name, !personeditdlg.read_only);
1200 gtk_widget_set_sensitive(personeditdlg.entry_first, !personeditdlg.read_only);
1201 gtk_widget_set_sensitive(personeditdlg.entry_last, !personeditdlg.read_only);
1202 gtk_widget_set_sensitive(personeditdlg.entry_nick, !personeditdlg.read_only);
1203 gtk_widget_set_sensitive(personeditdlg.entry_email, !personeditdlg.read_only);
1204 gtk_widget_set_sensitive(personeditdlg.entry_alias, !personeditdlg.read_only);
1205 gtk_widget_set_sensitive(personeditdlg.entry_remarks, !personeditdlg.read_only);
1206 gtk_widget_set_sensitive(personeditdlg.email_up, !personeditdlg.read_only);
1207 gtk_widget_set_sensitive(personeditdlg.email_down, !personeditdlg.read_only);
1208 gtk_widget_set_sensitive(personeditdlg.email_del, !personeditdlg.read_only);
1209 gtk_widget_set_sensitive(personeditdlg.email_mod, !personeditdlg.read_only);
1210 gtk_widget_set_sensitive(personeditdlg.email_add, !personeditdlg.read_only);
1211 gtk_widget_set_sensitive(personeditdlg.entry_atname, !personeditdlg.read_only);
1212 gtk_widget_set_sensitive(personeditdlg.entry_atvalue, !personeditdlg.read_only);
1213 gtk_widget_set_sensitive(personeditdlg.attrib_add, !personeditdlg.read_only);
1214 gtk_widget_set_sensitive(personeditdlg.attrib_del, !personeditdlg.read_only);
1215 gtk_widget_set_sensitive(personeditdlg.attrib_mod, !personeditdlg.read_only);
1218 static void addressbook_edit_person_flush_transient( void )
1220 ItemPerson *person = current_person;
1221 EditAddressPostUpdateCallback callback = edit_person_close_post_update_cb;
1223 /* reset transient data */
1224 current_abf = NULL;
1225 current_person = NULL;
1226 current_parent_folder = NULL;
1227 edit_person_close_post_update_cb = NULL;
1229 /* post action to perform on addressbook side */
1230 if (callback)
1231 callback( person );
1234 void addressbook_edit_person_invalidate( AddressBookFile *abf, ItemFolder *parent_folder,
1235 ItemPerson *person )
1237 if (current_abf == NULL &&
1238 current_person == NULL &&
1239 current_parent_folder == NULL)
1240 /* edit address form is already hidden */
1241 return;
1243 /* unconditional invalidation or invalidating the currently edited item */
1244 if ( ( abf == NULL && person == NULL && parent_folder == NULL )
1245 || (current_abf == abf ||
1246 current_person == person ||
1247 current_parent_folder == parent_folder))
1248 addressbook_edit_person_close( TRUE );
1251 gboolean addressbook_edit_person_close( gboolean cancelled )
1253 GList *listEMail = NULL;
1254 GList *listAttrib = NULL;
1255 gchar *cn = NULL;
1257 listEMail = edit_person_build_email_list();
1258 listAttrib = edit_person_build_attrib_list();
1259 if( cancelled ) {
1260 addritem_free_list_email( listEMail );
1261 addritem_free_list_attribute( listAttrib );
1262 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1263 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1265 if (!prefs_common.addressbook_use_editaddress_dialog)
1266 gtk_widget_hide( personeditdlg.container );
1268 /* no callback, as we're discarding the form */
1269 edit_person_close_post_update_cb = NULL;
1270 addressbook_edit_person_flush_transient();
1272 /* set focus to the address list (this is done by the post_update_cb usually) */
1273 addressbook_address_list_set_focus();
1274 return FALSE;
1277 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
1278 if( current_person && current_abf ) {
1279 /* Update email/attribute list for existing current_person */
1280 addrbook_update_address_list( current_abf, current_person, listEMail );
1281 addrbook_update_attrib_list( current_abf, current_person, listAttrib );
1283 else {
1284 /* Create new current_person and email/attribute list */
1285 if( cn == NULL || *cn == '\0' ) {
1286 /* Wasting our time */
1287 if( listEMail == NULL && listAttrib == NULL ) cancelled = TRUE;
1289 if( ! cancelled && current_abf ) {
1290 current_person = addrbook_add_address_list( current_abf, current_parent_folder, listEMail );
1291 addrbook_add_attrib_list( current_abf, current_person, listAttrib );
1294 listEMail = NULL;
1295 listAttrib = NULL;
1297 if( ! cancelled ) {
1298 /* Set current_person stuff */
1299 gchar *name;
1300 addritem_person_set_common_name( current_person, cn );
1301 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1302 addritem_person_set_first_name( current_person, name );
1303 g_free( name );
1304 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1305 addritem_person_set_last_name( current_person, name );
1306 g_free( name );
1307 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1308 addritem_person_set_nick_name( current_person, name );
1309 g_free( name );
1311 g_free( cn );
1313 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1314 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1316 if (!prefs_common.addressbook_use_editaddress_dialog)
1317 gtk_widget_hide( personeditdlg.container );
1319 addressbook_edit_person_flush_transient();
1321 return TRUE;
1325 * Edit person.
1326 * Enter: abf Address book.
1327 * parent Parent folder for person (or NULL if adding to root folder). Argument is
1328 * only required for new objects).
1329 * person Person to edit, or NULL for a new person object.
1330 * pgMail If TRUE, E-Mail page will be activated.
1331 * Return: Edited object, or NULL if cancelled.
1333 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent_folder, ItemPerson *person,
1334 gboolean pgMail, GtkWidget *parent_container,
1335 void (*post_update_cb) (ItemPerson *person),
1336 gboolean get_focus) {
1337 static gboolean cancelled;
1339 /* set transient data */
1340 current_abf = abf;
1341 current_person = person;
1342 current_parent_folder = parent_folder;
1343 edit_person_close_post_update_cb = post_update_cb;
1345 if( !personeditdlg.container )
1346 addressbook_edit_person_create(parent_container, &cancelled);
1348 /* typically, get focus when dialog mode is enabled, or when editing a new address */
1349 if( get_focus ) {
1350 gtk_widget_grab_focus(personeditdlg.ok_btn);
1351 gtk_widget_grab_focus(personeditdlg.entry_name);
1354 personeditdlg.read_only = (current_abf == NULL);
1355 update_sensitivity();
1357 gtk_widget_show(personeditdlg.container);
1358 if (prefs_common.addressbook_use_editaddress_dialog)
1359 manage_window_set_transient(GTK_WINDOW(personeditdlg.container));
1360 else
1361 if (get_focus)
1362 addressbook_address_list_disable_some_actions();
1364 /* Clear all fields */
1365 personeditdlg.rowIndEMail = -1;
1366 personeditdlg.rowIndAttrib = -1;
1367 edit_person_status_show( "" );
1368 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1369 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1370 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1371 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1372 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1373 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1375 personeditdlg.editNew = FALSE;
1376 if( person ) {
1377 if( ADDRITEM_NAME(person) )
1378 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1379 if( person->firstName )
1380 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), person->firstName );
1381 if( person->lastName )
1382 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), person->lastName );
1383 if( person->nickName )
1384 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), person->nickName );
1385 edit_person_load_email( person );
1386 edit_person_load_attrib( person );
1388 else {
1389 personeditdlg.editNew = TRUE;
1392 /* Select appropriate start page */
1393 if( pgMail ) {
1394 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1396 else {
1397 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1400 gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_email), 0, 0 );
1401 gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_attrib), 0, 0 );
1402 edit_person_email_clear( NULL );
1403 if (person)
1404 edit_person_email_list_selected(GTK_CLIST(personeditdlg.clist_email), 0, 0, NULL, NULL);
1406 edit_person_attrib_clear( NULL );
1408 if (prefs_common.addressbook_use_editaddress_dialog) {
1410 gtk_main();
1411 gtk_widget_hide( personeditdlg.container );
1413 if (!addressbook_edit_person_close( cancelled ))
1414 return NULL;
1417 return person;
1421 * End of Source.