2007-08-27 [colin] 2.10.0cvs179
[claws.git] / src / editaddress.c
blob03700b3fe11e7754fc7d22cad389e24cb90ca22c
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 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/>.
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"
45 #include "editaddress_other_attributes_ldap.h"
46 #include "prefs_common.h"
48 /* transient data */
49 static struct _PersonEdit_dlg personeditdlg;
50 static AddressBookFile *current_abf = NULL;
51 static ItemPerson *current_person = NULL;
52 static ItemFolder *current_parent_folder = NULL;
53 static EditAddressPostUpdateCallback edit_person_close_post_update_cb = NULL;
55 typedef enum {
56 EMAIL_COL_EMAIL = 0,
57 EMAIL_COL_ALIAS = 1,
58 EMAIL_COL_REMARKS = 2
59 } PersonEditEMailColumnPos;
61 typedef enum {
62 ATTRIB_COL_NAME = 0,
63 ATTRIB_COL_VALUE = 1
64 } PersonEditAttribColumnPos;
66 #define EDITPERSON_WIDTH 520
67 #define EDITPERSON_HEIGHT 320
69 #ifndef MAEMO
70 # define EMAIL_N_COLS 3
71 # define EMAIL_COL_WIDTH_EMAIL 180
72 # define EMAIL_COL_WIDTH_ALIAS 80
73 #else
74 # define EMAIL_N_COLS 1
75 # define EMAIL_COL_WIDTH_EMAIL 130
76 # define EMAIL_COL_WIDTH_ALIAS 130
77 #endif
79 #ifndef MAEMO
80 # define ATTRIB_N_COLS 2
81 # define ATTRIB_COL_WIDTH_NAME 240
82 # define ATTRIB_COL_WIDTH_VALUE 0
83 #else
84 # define ATTRIB_N_COLS 2
85 # define ATTRIB_COL_WIDTH_NAME 120
86 # define ATTRIB_COL_WIDTH_VALUE 120
87 #endif
89 #define PAGE_BASIC 0
90 #define PAGE_EMAIL 1
91 #define PAGE_ATTRIBUTES 2
93 static gboolean addressbook_edit_person_close( gboolean cancelled );
95 static void edit_person_status_show( gchar *msg ) {
96 if( personeditdlg.statusbar != NULL ) {
97 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
98 if( msg ) {
99 gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
104 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
105 *cancelled = FALSE;
106 if (prefs_common.addressbook_use_editaddress_dialog)
107 gtk_main_quit();
108 else
109 addressbook_edit_person_close( *cancelled );
112 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
113 *cancelled = TRUE;
114 if (prefs_common.addressbook_use_editaddress_dialog)
115 gtk_main_quit();
116 else
117 addressbook_edit_person_close( *cancelled );
120 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
121 *cancelled = TRUE;
122 if (prefs_common.addressbook_use_editaddress_dialog)
123 gtk_main_quit();
124 else
125 addressbook_edit_person_close( *cancelled );
126 return TRUE;
129 static gboolean edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
130 if (prefs_common.addressbook_use_editaddress_dialog) {
131 if (event && event->keyval == GDK_Escape) {
132 *cancelled = TRUE;
133 gtk_main_quit();
136 return FALSE;
139 static gchar *_title_new_ = NULL;
140 static gchar *_title_edit_ = NULL;
142 static void edit_person_set_widgets_title( gchar *text )
144 gchar *label = NULL;
146 g_return_if_fail( text != NULL );
148 gtk_label_set_text(GTK_LABEL(personeditdlg.title), "");
149 label = g_markup_printf_escaped("<b>%s</b>", text);
150 gtk_label_set_markup(GTK_LABEL(personeditdlg.title), label);
151 g_free(label);
154 static void edit_person_set_window_title( gint pageNum ) {
155 gchar *sTitle;
157 if( _title_new_ == NULL ) {
158 _title_new_ = g_strdup( _("Add New Person") );
159 _title_edit_ = g_strdup( _("Edit Person Details") );
162 if( pageNum == PAGE_BASIC ) {
163 if( personeditdlg.editNew ) {
164 if (prefs_common.addressbook_use_editaddress_dialog)
165 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_new_ );
166 else
167 edit_person_set_widgets_title( _title_new_ );
169 else {
170 if (prefs_common.addressbook_use_editaddress_dialog)
171 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_edit_ );
172 else
173 edit_person_set_widgets_title( _title_edit_ );
176 else {
177 if( personeditdlg.entry_name == NULL ) {
178 sTitle = g_strdup( _title_edit_ );
180 else {
181 gchar *name;
182 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
183 sTitle = g_strdup_printf( "%s - %s", _title_edit_, name );
184 g_free( name );
186 if (prefs_common.addressbook_use_editaddress_dialog)
187 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), sTitle );
188 else
189 edit_person_set_widgets_title( sTitle );
190 g_free( sTitle );
194 static void edit_person_email_clear( gpointer data ) {
195 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
196 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
197 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
200 static void edit_person_attrib_clear( gpointer data ) {
201 if (!personeditdlg.ldap) {
202 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), "" );
203 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
207 static void edit_person_switch_page( GtkNotebook *notebook, GtkNotebookPage *page,
208 gint pageNum, gpointer user_data)
210 edit_person_set_window_title( pageNum );
211 edit_person_status_show( "" );
215 * Load clist with a copy of person's email addresses.
217 static void edit_person_load_email( ItemPerson *person ) {
218 GList *node = person->listEMail;
219 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
220 gchar *text[ EMAIL_N_COLS ];
221 while( node ) {
222 ItemEMail *emorig = ( ItemEMail * ) node->data;
223 ItemEMail *email = addritem_copyfull_item_email( emorig );
224 gint row;
225 text[ EMAIL_COL_EMAIL ] = email->address;
226 #ifndef MAEMO
227 text[ EMAIL_COL_ALIAS ] = email->obj.name;
228 text[ EMAIL_COL_REMARKS ] = email->remarks;
229 #endif
230 row = gtk_clist_append( clist, text );
231 gtk_clist_set_row_data( clist, row, email );
232 node = g_list_next( node );
236 static void edit_person_email_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
237 ItemEMail *email = gtk_clist_get_row_data( clist, row );
238 if( email ) {
239 if( email->address )
240 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), email->address );
241 if( ADDRITEM_NAME(email) )
242 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), ADDRITEM_NAME(email) );
243 if( email->remarks )
244 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), email->remarks );
245 if (!personeditdlg.read_only) {
246 gtk_widget_set_sensitive(personeditdlg.email_del, TRUE);
247 gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
248 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, row + 1) != NULL);
250 } else {
251 gtk_widget_set_sensitive(personeditdlg.email_del, FALSE);
252 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
253 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
255 personeditdlg.rowIndEMail = row;
256 edit_person_status_show( NULL );
259 static void edit_person_email_move( gint dir ) {
260 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
261 gint row = personeditdlg.rowIndEMail + dir;
262 ItemEMail *email = gtk_clist_get_row_data( clist, row );
263 if( email ) {
264 gtk_clist_row_move( clist, personeditdlg.rowIndEMail, row );
265 personeditdlg.rowIndEMail = row;
266 if (!personeditdlg.read_only) {
267 gtk_widget_set_sensitive(personeditdlg.email_up, row > 0);
268 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, row + 1) != NULL);
270 } else {
271 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
272 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
274 edit_person_email_clear( NULL );
275 edit_person_status_show( NULL );
278 static void edit_person_email_move_up( gpointer data ) {
279 edit_person_email_move( -1 );
282 static void edit_person_email_move_down( gpointer data ) {
283 edit_person_email_move( +1 );
286 static void edit_person_email_delete( gpointer data ) {
287 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
288 gint row = personeditdlg.rowIndEMail;
289 ItemEMail *email = gtk_clist_get_row_data( clist, row );
290 edit_person_email_clear( NULL );
291 if( email ) {
292 /* Remove list entry */
293 gtk_clist_remove( clist, row );
294 addritem_free_item_email( email );
295 email = NULL;
298 /* Position hilite bar */
299 email = gtk_clist_get_row_data( clist, row );
300 if( ! email ) {
301 personeditdlg.rowIndEMail = -1 + row;
303 if (!personeditdlg.read_only) {
304 gtk_widget_set_sensitive(personeditdlg.email_del, gtk_clist_get_row_data(clist, 0) != NULL);
305 gtk_widget_set_sensitive(personeditdlg.email_up, gtk_clist_get_row_data(clist, personeditdlg.rowIndEMail + 1) != NULL);
306 gtk_widget_set_sensitive(personeditdlg.email_down, gtk_clist_get_row_data(clist, personeditdlg.rowIndEMail - 1) != NULL);
308 edit_person_status_show( NULL );
311 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
312 ItemEMail *retVal = NULL;
313 gchar *sEmail, *sAlias, *sRemarks, *sEmail_;
315 *error = TRUE;
316 sEmail_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
317 sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
318 sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
319 sEmail = mgu_email_check_empty( sEmail_ );
320 g_free( sEmail_ );
322 if( sEmail ) {
323 if( email == NULL ) {
324 email = addritem_create_item_email();
326 addritem_email_set_address( email, sEmail );
327 addritem_email_set_alias( email, sAlias );
328 addritem_email_set_remarks( email, sRemarks );
329 retVal = email;
330 *error = FALSE;
332 else {
333 edit_person_status_show( _( "An Email address must be supplied." ) );
336 g_free( sEmail );
337 g_free( sAlias );
338 g_free( sRemarks );
340 return retVal;
343 static void edit_person_email_modify( gpointer data ) {
344 gboolean errFlg = FALSE;
345 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
346 gint row = personeditdlg.rowIndEMail;
347 ItemEMail *email = gtk_clist_get_row_data( clist, row );
348 if( email ) {
349 edit_person_email_edit( &errFlg, email );
350 if( ! errFlg ) {
351 gtk_clist_set_text( clist, row, EMAIL_COL_EMAIL, email->address );
352 gtk_clist_set_text( clist, row, EMAIL_COL_ALIAS, email->obj.name );
353 gtk_clist_set_text( clist, row, EMAIL_COL_REMARKS, email->remarks );
354 edit_person_email_clear( NULL );
359 static void edit_person_email_add( gpointer data ) {
360 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
361 gboolean errFlg = FALSE;
362 ItemEMail *email = NULL;
363 gint row = personeditdlg.rowIndEMail;
364 if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
366 email = edit_person_email_edit( &errFlg, NULL );
367 if( ! errFlg ) {
368 gchar *text[ EMAIL_N_COLS ];
369 text[ EMAIL_COL_EMAIL ] = email->address;
370 #ifndef MAEMO
371 text[ EMAIL_COL_ALIAS ] = email->obj.name;
372 text[ EMAIL_COL_REMARKS ] = email->remarks;
373 #endif
374 row = gtk_clist_insert( clist, 1 + row, text );
375 gtk_clist_set_row_data( clist, row, email );
376 gtk_clist_select_row( clist, row, 0 );
377 edit_person_email_clear( NULL );
382 * Comparison using cell contents (text in first column). Used for sort
383 * address index widget.
385 static gint edit_person_attrib_compare_func(
386 GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2 )
388 GtkCell *cell1 = ((GtkCListRow *)ptr1)->cell;
389 GtkCell *cell2 = ((GtkCListRow *)ptr2)->cell;
390 gchar *name1 = NULL, *name2 = NULL;
392 if( cell1 ) name1 = cell1->u.text;
393 if( cell2 ) name2 = cell2->u.text;
394 if( ! name1 ) return ( name2 != NULL );
395 if( ! name2 ) return -1;
396 return g_utf8_collate( name1, name2 );
399 static gboolean list_find_attribute(const gchar *attr)
401 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
402 UserAttribute *attrib;
403 gint row = 0;
404 while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
405 if (!g_ascii_strcasecmp(attrib->name, attr)) {
406 gtk_clist_select_row(clist, row, 0);
407 return TRUE;
409 row++;
411 return FALSE;
414 static gboolean list_find_email(const gchar *addr)
416 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
417 ItemEMail *email;
418 gint row = 0;
419 while( (email = gtk_clist_get_row_data( clist, row )) ) {
420 if (!g_ascii_strcasecmp(email->address, addr)) {
421 gtk_clist_select_row(clist, row, 0);
422 return TRUE;
424 row++;
426 return FALSE;
430 * Load clist with a copy of person's email addresses.
432 static void edit_person_load_attrib( ItemPerson *person ) {
433 GList *node = person->listAttrib;
434 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
435 gchar *text[ ATTRIB_N_COLS ];
436 while( node ) {
437 UserAttribute *atorig = ( UserAttribute * ) node->data;
438 UserAttribute *attrib = addritem_copy_attribute( atorig );
439 gint row;
440 text[ ATTRIB_COL_NAME ] = attrib->name;
441 text[ ATTRIB_COL_VALUE ] = attrib->value;
443 row = gtk_clist_append( clist, text );
444 gtk_clist_set_row_data( clist, row, attrib );
445 node = g_list_next( node );
449 static void edit_person_attrib_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer data ) {
450 UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
451 if( attrib && !personeditdlg.read_only && !personeditdlg.ldap ) {
452 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atname), attrib->name );
453 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
454 gtk_widget_set_sensitive(personeditdlg.attrib_del, TRUE);
455 } else {
456 gtk_widget_set_sensitive(personeditdlg.attrib_del, FALSE);
458 personeditdlg.rowIndAttrib = row;
459 edit_person_status_show( NULL );
462 static void edit_person_attrib_delete( gpointer data ) {
463 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
464 gint row = personeditdlg.rowIndAttrib;
465 UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
466 edit_person_attrib_clear( NULL );
467 if( attrib ) {
468 /* Remove list entry */
469 gtk_clist_remove( clist, row );
470 addritem_free_attribute( attrib );
471 attrib = NULL;
474 /* Position hilite bar */
475 attrib = gtk_clist_get_row_data( clist, row );
476 if( ! attrib ) {
477 personeditdlg.rowIndAttrib = -1 + row;
480 if (!personeditdlg.read_only && !personeditdlg.ldap)
481 gtk_widget_set_sensitive(personeditdlg.attrib_del, gtk_clist_get_row_data(clist, 0) != NULL);
483 edit_person_status_show( NULL );
486 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
487 UserAttribute *retVal = NULL;
488 gchar *sName, *sValue, *sName_, *sValue_;
490 *error = TRUE;
491 sName_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atname), 0, -1 );
492 sValue_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
493 sName = mgu_email_check_empty( sName_ );
494 sValue = mgu_email_check_empty( sValue_ );
495 g_free( sName_ );
496 g_free( sValue_ );
498 if( sName && sValue ) {
499 if( attrib == NULL ) {
500 attrib = addritem_create_attribute();
502 addritem_attrib_set_name( attrib, sName );
503 addritem_attrib_set_value( attrib, sValue );
504 retVal = attrib;
505 *error = FALSE;
507 else {
508 edit_person_status_show( _( "A Name and Value must be supplied." ) );
511 g_free( sName );
512 g_free( sValue );
514 return retVal;
517 static void edit_person_attrib_modify( gpointer data ) {
518 gboolean errFlg = FALSE;
519 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
520 gint row = personeditdlg.rowIndAttrib;
521 UserAttribute *attrib = gtk_clist_get_row_data( clist, row );
522 if( attrib ) {
523 edit_person_attrib_edit( &errFlg, attrib );
524 if( ! errFlg ) {
525 gtk_clist_set_text( clist, row, ATTRIB_COL_NAME, attrib->name );
526 gtk_clist_set_text( clist, row, ATTRIB_COL_VALUE, attrib->value );
527 edit_person_attrib_clear( NULL );
532 static void edit_person_attrib_add( gpointer data ) {
533 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
534 gboolean errFlg = FALSE;
535 UserAttribute *attrib = NULL;
536 gint row = personeditdlg.rowIndAttrib;
537 if( gtk_clist_get_row_data( clist, row ) == NULL ) row = 0;
539 attrib = edit_person_attrib_edit( &errFlg, NULL );
540 if( ! errFlg ) {
541 gchar *text[ ATTRIB_N_COLS ];
542 text[ ATTRIB_COL_NAME ] = attrib->name;
543 text[ ATTRIB_COL_VALUE ] = attrib->value;
545 row = gtk_clist_insert( clist, 1 + row, text );
546 gtk_clist_set_row_data( clist, row, attrib );
547 gtk_clist_select_row( clist, row, 0 );
548 edit_person_attrib_clear( NULL );
553 *\brief Save Gtk object size to prefs dataset
555 static void edit_person_size_allocate_cb(GtkWidget *widget,
556 GtkAllocation *allocation)
558 g_return_if_fail(allocation != NULL);
560 prefs_common.addressbookeditpersonwin_width = allocation->width;
561 prefs_common.addressbookeditpersonwin_height = allocation->height;
564 /* build edit person widgets, return a pointer to the main container of the widgetset (a vbox) */
565 static GtkWidget* addressbook_edit_person_widgets_create( GtkWidget* container, gboolean *cancelled )
567 GtkWidget *vbox;
568 GtkWidget *vnbox;
569 GtkWidget *notebook;
570 GtkWidget *hbbox;
571 GtkWidget *ok_btn;
572 GtkWidget *cancel_btn;
574 vbox = gtk_vbox_new(FALSE, 4);
575 /* gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH); */
576 gtk_widget_show(vbox);
577 gtk_container_add(GTK_CONTAINER(container), vbox);
579 vnbox = gtk_vbox_new(FALSE, 4);
580 gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
581 gtk_widget_show(vnbox);
582 gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
584 /* Notebook */
585 notebook = gtk_notebook_new();
586 gtk_widget_show(notebook);
587 gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
588 gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
590 /* Button panel */
591 if (prefs_common.addressbook_use_editaddress_dialog)
592 gtkut_stock_button_set_create(&hbbox, &cancel_btn, GTK_STOCK_CANCEL,
593 &ok_btn, GTK_STOCK_OK,
594 NULL, NULL);
595 else
596 gtkut_stock_with_text_button_set_create(&hbbox,
597 &cancel_btn, GTK_STOCK_CANCEL, _("Discard"),
598 &ok_btn, GTK_STOCK_OK, _("Apply"),
599 NULL, NULL, NULL);
600 gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
601 gtk_widget_grab_default(ok_btn);
603 g_signal_connect(G_OBJECT(ok_btn), "clicked",
604 G_CALLBACK(edit_person_ok), cancelled);
605 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
606 G_CALLBACK(edit_person_cancel), cancelled);
607 g_signal_connect(G_OBJECT(notebook), "switch_page",
608 G_CALLBACK(edit_person_switch_page), NULL );
610 gtk_widget_show_all(vbox);
612 personeditdlg.notebook = notebook;
613 personeditdlg.ok_btn = ok_btn;
614 personeditdlg.cancel_btn = cancel_btn;
616 return vbox;
619 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
620 GtkWidget *window;
621 GtkWidget *hsbox;
622 GtkWidget *vbox;
623 GtkWidget *statusbar;
624 static GdkGeometry geometry;
626 window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "editaddress");
627 /* gtk_container_set_border_width(GTK_CONTAINER(window), 0); */
628 gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
629 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
630 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
631 g_signal_connect(G_OBJECT(window), "delete_event",
632 G_CALLBACK(edit_person_delete_event),
633 cancelled);
634 g_signal_connect(G_OBJECT(window), "size_allocate",
635 G_CALLBACK(edit_person_size_allocate_cb),
636 cancelled);
637 g_signal_connect(G_OBJECT(window), "key_press_event",
638 G_CALLBACK(edit_person_key_pressed),
639 cancelled);
641 vbox = addressbook_edit_person_widgets_create(window, cancelled);
643 /* Status line */
644 hsbox = gtk_hbox_new(FALSE, 0);
645 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
646 statusbar = gtk_statusbar_new();
647 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
649 if (!geometry.min_height) {
650 geometry.min_width = EDITPERSON_WIDTH;
651 geometry.min_height = EDITPERSON_HEIGHT;
654 gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
655 GDK_HINT_MIN_SIZE);
656 gtk_widget_set_size_request(window, prefs_common.addressbookeditpersonwin_width,
657 prefs_common.addressbookeditpersonwin_height);
659 personeditdlg.container = window;
660 personeditdlg.statusbar = statusbar;
661 personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
665 /* parent must be a box */
666 static void addressbook_edit_person_widgetset_create( GtkWidget *parent, gboolean *cancelled )
668 GtkWidget *vbox;
669 GtkWidget *label;
671 if ( parent == NULL )
672 g_warning("addressbook_edit_person_widgetset_create: parent is NULL");
674 vbox = gtk_vbox_new(FALSE, 0);
675 gtk_box_pack_end(GTK_BOX(parent), vbox, TRUE, TRUE, 0);
677 label = gtk_label_new(_("Edit Person Data"));
678 gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER);
679 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
681 addressbook_edit_person_widgets_create(vbox, cancelled);
683 gtk_widget_set_size_request(vbox, EDITPERSON_WIDTH, EDITPERSON_HEIGHT);
685 personeditdlg.container = vbox;
686 personeditdlg.title = label;
687 personeditdlg.statusbar = NULL;
688 personeditdlg.status_cid = 0;
691 void addressbook_edit_person_widgetset_hide( void )
693 if ( personeditdlg.container )
694 gtk_widget_hide( personeditdlg.container );
697 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
698 GtkWidget *vbox;
699 GtkWidget *table;
700 GtkWidget *label;
701 GtkWidget *entry_name;
702 GtkWidget *entry_fn;
703 GtkWidget *entry_ln;
704 GtkWidget *entry_nn;
705 const gchar *locale;
706 gint top = 0;
708 vbox = gtk_vbox_new( FALSE, 8 );
709 gtk_widget_show( vbox );
710 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
711 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
713 label = gtk_label_new_with_mnemonic( pageLbl );
714 gtk_widget_show( label );
715 gtk_notebook_set_tab_label(
716 GTK_NOTEBOOK( personeditdlg.notebook ),
717 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
719 table = gtk_table_new( 4, 3, FALSE);
720 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
721 gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
722 gtk_table_set_row_spacings(GTK_TABLE(table), 8);
723 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
725 #define ATTACH_ROW(text, entry) \
727 label = gtk_label_new(text); \
728 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
729 GTK_FILL, 0, 0, 0); \
730 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
732 entry = gtk_entry_new(); \
733 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
734 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
735 top++; \
738 #define ATTACH_HIDDEN_ROW(text, entry) \
740 entry = gtk_entry_new(); \
743 #ifndef MAEMO
744 ATTACH_ROW(_("Display Name"), entry_name);
745 #else
746 ATTACH_HIDDEN_ROW(_("Display Name"), entry_name);
747 #endif
748 locale = conv_get_current_locale();
749 if (locale &&
750 (!g_ascii_strncasecmp(locale, "ja", 2) ||
751 !g_ascii_strncasecmp(locale, "ko", 2) ||
752 !g_ascii_strncasecmp(locale, "zh", 2))) {
753 ATTACH_ROW(_("Last Name"), entry_ln);
754 ATTACH_ROW(_("First Name"), entry_fn);
755 } else {
756 ATTACH_ROW(_("First Name"), entry_fn);
757 ATTACH_ROW(_("Last Name"), entry_ln);
759 #ifndef MAEMO
760 ATTACH_ROW(_("Nickname"), entry_nn);
761 #else
762 ATTACH_HIDDEN_ROW(_("Nickname"), entry_nn);
763 #endif
765 #undef ATTACH_ROW
766 #undef ATTACH_HIDDEN_ROW
768 gtk_widget_show_all(vbox);
770 personeditdlg.entry_name = entry_name;
771 personeditdlg.entry_first = entry_fn;
772 personeditdlg.entry_last = entry_ln;
773 personeditdlg.entry_nick = entry_nn;
776 static gboolean email_adding = FALSE, email_saving = FALSE;
778 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
780 gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_email), 0) != NULL;
782 if (personeditdlg.read_only)
783 return;
785 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)) == NULL
786 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email))) == 0) {
787 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
788 gtk_widget_set_sensitive(personeditdlg.email_mod,FALSE);
789 email_adding = FALSE;
790 email_saving = FALSE;
791 } else if (list_find_email(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)))) {
792 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
793 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
794 email_adding = FALSE;
795 email_saving = non_empty;
796 } else {
797 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
798 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
799 email_adding = TRUE;
800 email_saving = non_empty;
804 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
806 if (event && event->keyval == GDK_Return) {
807 if (email_saving)
808 edit_person_email_modify(NULL);
809 else if (email_adding)
810 edit_person_email_add(NULL);
812 return FALSE;
816 static void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
817 GtkWidget *vbox;
818 GtkWidget *hbox;
819 GtkWidget *vboxl;
820 GtkWidget *vboxb;
821 GtkWidget *vbuttonbox;
822 GtkWidget *buttonUp;
823 GtkWidget *buttonDown;
824 GtkWidget *buttonDel;
825 GtkWidget *buttonMod;
826 GtkWidget *buttonAdd;
828 GtkWidget *table;
829 GtkWidget *label;
830 GtkWidget *clist_swin;
831 GtkWidget *clist;
832 GtkWidget *entry_email;
833 GtkWidget *entry_alias;
834 GtkWidget *entry_remarks;
835 gint top;
837 gchar *titles[ EMAIL_N_COLS ];
838 gint i;
840 titles[ EMAIL_COL_EMAIL ] = _("Email Address");
841 #ifndef MAEMO
842 titles[ EMAIL_COL_ALIAS ] = _("Alias");
843 titles[ EMAIL_COL_REMARKS ] = _("Remarks");
844 #endif
845 vbox = gtk_vbox_new( FALSE, 8 );
846 gtk_widget_show( vbox );
847 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
848 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
850 label = gtk_label_new_with_mnemonic( pageLbl );
851 gtk_widget_show( label );
852 gtk_notebook_set_tab_label(
853 GTK_NOTEBOOK( personeditdlg.notebook ),
854 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
856 /* Split into two areas */
857 hbox = gtk_hbox_new( FALSE, 0 );
858 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
860 /* Address list */
861 vboxl = gtk_vbox_new( FALSE, 4 );
862 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
863 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
865 clist_swin = gtk_scrolled_window_new( NULL, NULL );
866 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
867 GTK_POLICY_AUTOMATIC,
868 GTK_POLICY_AUTOMATIC);
870 clist = gtk_clist_new_with_titles( EMAIL_N_COLS, titles );
872 gtk_container_add( GTK_CONTAINER(clist_swin), clist );
873 gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
874 gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_EMAIL, EMAIL_COL_WIDTH_EMAIL );
875 gtk_clist_set_column_width( GTK_CLIST(clist), EMAIL_COL_ALIAS, EMAIL_COL_WIDTH_ALIAS );
877 for( i = 0; i < EMAIL_N_COLS; i++ )
878 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
880 /* Data entry area */
881 table = gtk_table_new( 4, 2, FALSE);
883 #ifndef MAEMO
884 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
885 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
886 #else
887 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
888 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
889 gtk_clist_column_titles_hide(GTK_CLIST(clist));
890 #endif
891 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
892 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
893 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
895 entry_email = gtk_entry_new();
896 entry_alias = gtk_entry_new();
897 entry_remarks = gtk_entry_new();
899 /* First row */
900 top = 0;
901 label = gtk_label_new(_("Email Address"));
902 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
903 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
905 gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
907 #ifndef MAEMO
908 /* Next row */
909 ++top;
910 label = gtk_label_new(_("Alias"));
911 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
912 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
914 gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
916 /* Next row */
917 ++top;
918 label = gtk_label_new(_("Remarks"));
919 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
920 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
922 gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
923 #endif
925 /* Button box */
926 vboxb = gtk_vbox_new( FALSE, 4 );
927 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
929 vbuttonbox = gtk_vbutton_box_new();
930 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
931 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
932 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
933 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
935 /* Buttons */
936 buttonUp = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
937 buttonDown = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
938 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
939 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
940 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
942 #ifndef MAEMO
943 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
945 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
946 #endif
947 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
949 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
951 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
953 gtk_widget_show_all(vbox);
955 /* Event handlers */
956 g_signal_connect( G_OBJECT(clist), "select_row",
957 G_CALLBACK( edit_person_email_list_selected), NULL );
958 g_signal_connect( G_OBJECT(buttonUp), "clicked",
959 G_CALLBACK( edit_person_email_move_up ), NULL );
960 g_signal_connect( G_OBJECT(buttonDown), "clicked",
961 G_CALLBACK( edit_person_email_move_down ), NULL );
962 g_signal_connect( G_OBJECT(buttonDel), "clicked",
963 G_CALLBACK( edit_person_email_delete ), NULL );
964 g_signal_connect( G_OBJECT(buttonMod), "clicked",
965 G_CALLBACK( edit_person_email_modify ), NULL );
966 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
967 G_CALLBACK( edit_person_email_add ), NULL );
968 g_signal_connect(G_OBJECT(entry_email), "changed",
969 G_CALLBACK(edit_person_entry_email_changed), NULL);
970 g_signal_connect(G_OBJECT(entry_email), "key_press_event",
971 G_CALLBACK(edit_person_entry_email_pressed), NULL);
972 g_signal_connect(G_OBJECT(entry_alias), "key_press_event",
973 G_CALLBACK(edit_person_entry_email_pressed), NULL);
974 g_signal_connect(G_OBJECT(entry_remarks), "key_press_event",
975 G_CALLBACK(edit_person_entry_email_pressed), NULL);
977 personeditdlg.clist_email = clist;
978 personeditdlg.entry_email = entry_email;
979 personeditdlg.entry_alias = entry_alias;
980 personeditdlg.entry_remarks = entry_remarks;
981 personeditdlg.email_up = buttonUp;
982 personeditdlg.email_down = buttonDown;
983 personeditdlg.email_del = buttonDel;
984 personeditdlg.email_mod = buttonMod;
985 personeditdlg.email_add = buttonAdd;
988 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
990 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
992 gboolean non_empty = gtk_clist_get_row_data(GTK_CLIST(personeditdlg.clist_attrib), 0) != NULL;
994 if (personeditdlg.read_only || personeditdlg.ldap)
995 return;
997 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname)) == NULL
998 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname))) == 0) {
999 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1000 gtk_widget_set_sensitive(personeditdlg.attrib_mod,FALSE);
1001 attrib_adding = FALSE;
1002 attrib_saving = FALSE;
1003 } else if (list_find_attribute(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_atname)))) {
1004 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1005 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1006 attrib_adding = FALSE;
1007 attrib_saving = non_empty;
1008 } else {
1009 gtk_widget_set_sensitive(personeditdlg.attrib_add,TRUE);
1010 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1011 attrib_adding = TRUE;
1012 attrib_saving = non_empty;
1016 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1018 if (event && event->keyval == GDK_Return) {
1019 if (attrib_saving)
1020 edit_person_attrib_modify(NULL);
1021 else if (attrib_adding)
1022 edit_person_attrib_add(NULL);
1024 return FALSE;
1027 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
1028 GtkWidget *vbox;
1029 GtkWidget *hbox;
1030 GtkWidget *vboxl;
1031 GtkWidget *vboxb;
1032 GtkWidget *vbuttonbox;
1033 GtkWidget *buttonDel;
1034 GtkWidget *buttonMod;
1035 GtkWidget *buttonAdd;
1037 GtkWidget *table;
1038 GtkWidget *label;
1039 GtkWidget *clist_swin;
1040 GtkWidget *clist;
1041 GtkWidget *entry_name;
1042 GtkWidget *entry_value;
1043 gint top;
1045 gchar *titles[ ATTRIB_N_COLS ];
1046 gint i;
1048 titles[ ATTRIB_COL_NAME ] = _("Name");
1049 titles[ ATTRIB_COL_VALUE ] = _("Value");
1051 vbox = gtk_vbox_new( FALSE, 8 );
1052 gtk_widget_show( vbox );
1053 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1054 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1056 label = gtk_label_new_with_mnemonic( pageLbl );
1057 gtk_widget_show( label );
1058 gtk_notebook_set_tab_label(
1059 GTK_NOTEBOOK( personeditdlg.notebook ),
1060 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1062 /* Split into two areas */
1063 hbox = gtk_hbox_new( FALSE, 0 );
1064 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1066 /* Attribute list */
1067 vboxl = gtk_vbox_new( FALSE, 4 );
1068 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1069 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1071 clist_swin = gtk_scrolled_window_new( NULL, NULL );
1072 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
1073 GTK_POLICY_AUTOMATIC,
1074 GTK_POLICY_AUTOMATIC);
1076 clist = gtk_clist_new_with_titles( ATTRIB_N_COLS, titles );
1077 gtk_container_add( GTK_CONTAINER(clist_swin), clist );
1078 gtk_clist_set_selection_mode( GTK_CLIST(clist), GTK_SELECTION_BROWSE );
1079 gtk_clist_set_compare_func( GTK_CLIST(clist), edit_person_attrib_compare_func );
1080 gtk_clist_set_auto_sort( GTK_CLIST(clist), TRUE );
1081 gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_NAME, ATTRIB_COL_WIDTH_NAME );
1082 gtk_clist_set_column_width( GTK_CLIST(clist), ATTRIB_COL_VALUE, ATTRIB_COL_WIDTH_VALUE );
1084 for( i = 0; i < ATTRIB_N_COLS; i++ )
1085 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button, GTK_CAN_FOCUS);
1087 /* Data entry area */
1088 #ifndef MAEMO
1089 table = gtk_table_new( 4, 2, FALSE);
1090 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1091 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1092 #else
1093 table = gtk_table_new( 2, 4, FALSE);
1094 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1095 gtk_container_add( GTK_CONTAINER(vboxl), clist_swin );
1096 gtk_clist_column_titles_hide(GTK_CLIST(clist));
1097 #endif
1098 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1099 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1100 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1102 /* First row */
1103 top = 0;
1104 #ifndef MAEMO
1105 label = gtk_label_new(_("Name"));
1106 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1107 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1109 entry_name = gtk_entry_new();
1110 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1112 /* Next row */
1113 ++top;
1114 label = gtk_label_new(_("Value"));
1115 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1116 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1118 entry_value = gtk_entry_new();
1119 gtk_table_attach(GTK_TABLE(table), entry_value, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1120 #else
1121 label = gtk_label_new(_("Name"));
1122 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1123 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1125 entry_name = gtk_entry_new();
1126 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1128 /* Next row */
1129 ++top;
1130 label = gtk_label_new(_("Value"));
1131 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
1132 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1134 entry_value = gtk_entry_new();
1135 gtk_table_attach(GTK_TABLE(table), entry_value, 3, 4, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1136 #endif
1137 /* Button box */
1138 vboxb = gtk_vbox_new( FALSE, 4 );
1139 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1141 vbuttonbox = gtk_vbutton_box_new();
1142 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1143 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1144 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1145 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1147 /* Buttons */
1148 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1149 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1151 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1152 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1154 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1155 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1157 gtk_widget_set_sensitive(buttonDel,FALSE);
1158 gtk_widget_set_sensitive(buttonMod,FALSE);
1159 gtk_widget_set_sensitive(buttonAdd,FALSE);
1161 gtk_widget_show_all(vbox);
1163 /* Event handlers */
1164 g_signal_connect( G_OBJECT(clist), "select_row",
1165 G_CALLBACK( edit_person_attrib_list_selected), NULL );
1166 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1167 G_CALLBACK( edit_person_attrib_delete ), NULL );
1168 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1169 G_CALLBACK( edit_person_attrib_modify ), NULL );
1170 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1171 G_CALLBACK( edit_person_attrib_add ), NULL );
1172 g_signal_connect(G_OBJECT(entry_name), "changed",
1173 G_CALLBACK(edit_person_entry_att_changed), NULL);
1174 g_signal_connect(G_OBJECT(entry_name), "key_press_event",
1175 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1176 g_signal_connect(G_OBJECT(entry_value), "key_press_event",
1177 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1179 personeditdlg.clist_attrib = clist;
1180 personeditdlg.entry_atname = entry_name;
1181 personeditdlg.entry_atvalue = entry_value;
1182 personeditdlg.attrib_add = buttonAdd;
1183 personeditdlg.attrib_del = buttonDel;
1184 personeditdlg.attrib_mod = buttonMod;
1187 static void addressbook_edit_person_create( GtkWidget *parent, gboolean *cancelled ) {
1188 if (prefs_common.addressbook_use_editaddress_dialog)
1189 addressbook_edit_person_dialog_create( cancelled );
1190 else
1191 addressbook_edit_person_widgetset_create( parent, cancelled );
1192 addressbook_edit_person_page_basic( PAGE_BASIC, _( "_User Data" ) );
1193 addressbook_edit_person_page_email( PAGE_EMAIL, _( "_Email Addresses" ) );
1194 #ifdef USE_LDAP
1195 if (personeditdlg.ldap)
1196 addressbook_edit_person_page_attrib_ldap(&personeditdlg, PAGE_ATTRIBUTES, _("O_ther Attributes"));
1197 else
1198 #endif
1199 addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "O_ther Attributes" ) );
1200 gtk_widget_show_all( personeditdlg.container );
1204 * Return list of email items.
1206 static GList *edit_person_build_email_list() {
1207 GtkCList *clist = GTK_CLIST(personeditdlg.clist_email);
1208 GList *listEMail = NULL;
1209 ItemEMail *email;
1210 gint row = 0;
1211 while( (email = gtk_clist_get_row_data( clist, row )) ) {
1212 listEMail = g_list_append( listEMail, email );
1213 row++;
1215 return listEMail;
1219 * Return list of attributes.
1221 static GList *edit_person_build_attrib_list() {
1222 GtkCList *clist = GTK_CLIST(personeditdlg.clist_attrib);
1223 GList *listAttrib = NULL;
1224 UserAttribute *attrib;
1225 gint row = 0;
1226 while( (attrib = gtk_clist_get_row_data( clist, row )) ) {
1227 listAttrib = g_list_append( listAttrib, attrib );
1228 row++;
1230 return listAttrib;
1233 static void update_sensitivity(void)
1235 gtk_widget_set_sensitive(personeditdlg.entry_name, !personeditdlg.read_only);
1236 gtk_widget_set_sensitive(personeditdlg.entry_first, !personeditdlg.read_only);
1237 gtk_widget_set_sensitive(personeditdlg.entry_last, !personeditdlg.read_only);
1238 gtk_widget_set_sensitive(personeditdlg.entry_nick, !personeditdlg.read_only && !personeditdlg.ldap);
1239 gtk_widget_set_sensitive(personeditdlg.entry_email, !personeditdlg.read_only);
1240 gtk_widget_set_sensitive(personeditdlg.entry_alias, !personeditdlg.read_only && !personeditdlg.ldap);
1241 gtk_widget_set_sensitive(personeditdlg.entry_remarks, !personeditdlg.read_only && !personeditdlg.ldap);
1242 gtk_widget_set_sensitive(personeditdlg.email_up, !personeditdlg.read_only);
1243 gtk_widget_set_sensitive(personeditdlg.email_down, !personeditdlg.read_only);
1244 gtk_widget_set_sensitive(personeditdlg.email_del, !personeditdlg.read_only);
1245 gtk_widget_set_sensitive(personeditdlg.email_mod, !personeditdlg.read_only);
1246 gtk_widget_set_sensitive(personeditdlg.email_add, !personeditdlg.read_only);
1247 gtk_widget_set_sensitive(personeditdlg.entry_atname, !personeditdlg.read_only);
1248 gtk_widget_set_sensitive(personeditdlg.entry_atvalue, !personeditdlg.read_only);
1249 gtk_widget_set_sensitive(personeditdlg.attrib_add, !personeditdlg.read_only);
1250 gtk_widget_set_sensitive(personeditdlg.attrib_del, !personeditdlg.read_only);
1251 gtk_widget_set_sensitive(personeditdlg.attrib_mod, !personeditdlg.read_only);
1254 static void addressbook_edit_person_flush_transient( void )
1256 ItemPerson *person = current_person;
1257 EditAddressPostUpdateCallback callback = edit_person_close_post_update_cb;
1259 /* reset transient data */
1260 current_abf = NULL;
1261 current_person = NULL;
1262 current_parent_folder = NULL;
1263 edit_person_close_post_update_cb = NULL;
1265 /* post action to perform on addressbook side */
1266 if (callback)
1267 callback( person );
1270 void addressbook_edit_person_invalidate( AddressBookFile *abf, ItemFolder *parent_folder,
1271 ItemPerson *person )
1273 if (current_abf == NULL &&
1274 current_person == NULL &&
1275 current_parent_folder == NULL)
1276 /* edit address form is already hidden */
1277 return;
1279 /* unconditional invalidation or invalidating the currently edited item */
1280 if ( ( abf == NULL && person == NULL && parent_folder == NULL )
1281 || (current_abf == abf ||
1282 current_person == person ||
1283 current_parent_folder == parent_folder))
1284 addressbook_edit_person_close( TRUE );
1287 static gboolean addressbook_edit_person_close( gboolean cancelled )
1289 GList *listEMail = NULL;
1290 GList *listAttrib = NULL;
1291 gchar *cn = NULL;
1293 listEMail = edit_person_build_email_list();
1294 listAttrib = edit_person_build_attrib_list();
1295 if( cancelled ) {
1296 addritem_free_list_email( listEMail );
1297 addritem_free_list_attribute( listAttrib );
1298 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1299 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1301 if (!prefs_common.addressbook_use_editaddress_dialog)
1302 gtk_widget_hide( personeditdlg.container );
1304 /* no callback, as we're discarding the form */
1305 edit_person_close_post_update_cb = NULL;
1306 addressbook_edit_person_flush_transient();
1308 /* set focus to the address list (this is done by the post_update_cb usually) */
1309 addressbook_address_list_set_focus();
1310 return FALSE;
1313 #ifndef MAEMO
1314 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
1315 #else
1317 gchar *first = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1318 gchar *last = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1319 cn = g_strdup_printf("%s%s%s", first, (first && last && *first && *last)?" ":"", last);
1320 g_free(first);
1321 g_free(last);
1323 #endif
1324 if( current_person && current_abf ) {
1325 /* Update email/attribute list for existing current_person */
1326 addrbook_update_address_list( current_abf, current_person, listEMail );
1327 addrbook_update_attrib_list( current_abf, current_person, listAttrib );
1329 else {
1330 /* Create new current_person and email/attribute list */
1331 if( cn == NULL || *cn == '\0' ) {
1332 /* Wasting our time */
1333 if( listEMail == NULL && listAttrib == NULL ) cancelled = TRUE;
1335 if( ! cancelled && current_abf ) {
1336 current_person = addrbook_add_address_list( current_abf, current_parent_folder, listEMail );
1337 addrbook_add_attrib_list( current_abf, current_person, listAttrib );
1340 listEMail = NULL;
1341 listAttrib = NULL;
1343 if( ! cancelled ) {
1344 /* Set current_person stuff */
1345 gchar *name;
1346 addritem_person_set_common_name( current_person, cn );
1347 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1348 addritem_person_set_first_name( current_person, name );
1349 g_free( name );
1350 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1351 addritem_person_set_last_name( current_person, name );
1352 g_free( name );
1353 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1354 addritem_person_set_nick_name( current_person, name );
1355 g_free( name );
1357 g_free( cn );
1359 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1360 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1362 if (!prefs_common.addressbook_use_editaddress_dialog)
1363 gtk_widget_hide( personeditdlg.container );
1365 addressbook_edit_person_flush_transient();
1367 return TRUE;
1371 * Edit person.
1372 * Enter: abf Address book.
1373 * parent Parent folder for person (or NULL if adding to root folder). Argument is
1374 * only required for new objects).
1375 * person Person to edit, or NULL for a new person object.
1376 * pgMail If TRUE, E-Mail page will be activated.
1377 * Return: Edited object, or NULL if cancelled.
1379 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent_folder, ItemPerson *person,
1380 gboolean pgMail, GtkWidget *parent_container,
1381 void (*post_update_cb) (ItemPerson *person),
1382 gboolean get_focus) {
1383 static gboolean cancelled;
1385 /* set transient data */
1386 current_abf = abf;
1387 current_person = person;
1388 current_parent_folder = parent_folder;
1389 edit_person_close_post_update_cb = post_update_cb;
1390 personeditdlg.ldap = (abf && abf->type == ADBOOKTYPE_LDAP)? TRUE : FALSE;
1392 if( !personeditdlg.container )
1393 addressbook_edit_person_create(parent_container, &cancelled);
1395 /* typically, get focus when dialog mode is enabled, or when editing a new address */
1396 if( get_focus ) {
1397 gtk_widget_grab_focus(personeditdlg.ok_btn);
1398 gtk_widget_grab_focus(personeditdlg.entry_name);
1401 personeditdlg.read_only = (current_abf == NULL);
1402 update_sensitivity();
1404 gtk_widget_show(personeditdlg.container);
1405 if (prefs_common.addressbook_use_editaddress_dialog)
1406 manage_window_set_transient(GTK_WINDOW(personeditdlg.container));
1407 else
1408 if (get_focus)
1409 addressbook_address_list_disable_some_actions();
1411 /* Clear all fields */
1412 personeditdlg.rowIndEMail = -1;
1413 personeditdlg.rowIndAttrib = -1;
1414 edit_person_status_show( "" );
1415 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_email) );
1416 gtk_clist_clear( GTK_CLIST(personeditdlg.clist_attrib) );
1417 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1418 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1419 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1420 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1422 personeditdlg.editNew = FALSE;
1423 if( person ) {
1424 if( ADDRITEM_NAME(person) )
1425 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1426 if( person->firstName )
1427 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), person->firstName );
1428 if( person->lastName )
1429 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), person->lastName );
1430 if( person->nickName )
1431 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), person->nickName );
1432 edit_person_load_email( person );
1433 edit_person_load_attrib( person );
1434 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_atvalue), "");
1436 else {
1437 personeditdlg.editNew = TRUE;
1440 /* Select appropriate start page */
1441 if( pgMail ) {
1442 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1444 else {
1445 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1448 gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_email), 0, 0 );
1449 gtk_clist_select_row( GTK_CLIST(personeditdlg.clist_attrib), 0, 0 );
1450 edit_person_email_clear( NULL );
1451 if (person)
1452 edit_person_email_list_selected(GTK_CLIST(personeditdlg.clist_email), 0, 0, NULL, NULL);
1454 edit_person_attrib_clear( NULL );
1456 if (prefs_common.addressbook_use_editaddress_dialog) {
1458 gtk_main();
1459 gtk_widget_hide( personeditdlg.container );
1461 if (!addressbook_edit_person_close( cancelled ))
1462 return NULL;
1465 return person;
1469 * End of Source.