update contributors list
[claws.git] / src / editaddress.c
blob0dc34d5ccd6b055e6b1f397ccd17f63c54e51eb3
1 /*
2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2016 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/>.
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #include "claws-features.h"
22 #endif
24 #include "defs.h"
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <gtk/gtk.h>
31 #include "alertpanel.h"
32 #include "stock_pixmap.h"
33 #include "mgutils.h"
34 #include "addressbook.h"
35 #include "addressitem.h"
36 #include "addritem.h"
37 #include "addrbook.h"
38 #include "manage_window.h"
39 #include "gtkutils.h"
40 #include "filesel.h"
41 #include "codeconv.h"
42 #include "editaddress.h"
43 #include "editaddress_other_attributes_ldap.h"
44 #include "prefs_common.h"
45 #include "menu.h"
46 #include "combobox.h"
47 #include "file-utils.h"
49 /* transient data */
50 static struct _PersonEdit_dlg personeditdlg;
51 static AddressBookFile *current_abf = NULL;
52 static ItemPerson *current_person = NULL;
53 static ItemFolder *current_parent_folder = NULL;
54 static EditAddressPostUpdateCallback edit_person_close_post_update_cb = NULL;
56 typedef enum {
57 EMAIL_COL_EMAIL,
58 EMAIL_COL_ALIAS,
59 EMAIL_COL_REMARKS,
60 EMAIL_COL_PTR
61 } PersonEditEMailColumnPos;
63 #define EDITPERSON_WIDTH 520
64 #define EDITPERSON_HEIGHT 320
66 #ifndef GENERIC_UMPC
67 # define EMAIL_N_COLS 4
68 # define EMAIL_COL_WIDTH_EMAIL 180
69 # define EMAIL_COL_WIDTH_ALIAS 80
70 #else
71 # define EMAIL_N_COLS 2
72 # define EMAIL_COL_WIDTH_EMAIL 130
73 # define EMAIL_COL_WIDTH_ALIAS 130
74 #endif
76 #ifndef GENERIC_UMPC
77 # define ATTRIB_COL_WIDTH_NAME 240
78 # define ATTRIB_COL_WIDTH_VALUE 0
79 #else
80 # define ATTRIB_COL_WIDTH_NAME 120
81 # define ATTRIB_COL_WIDTH_VALUE 120
82 #endif
84 #define PAGE_BASIC 0
85 #define PAGE_EMAIL 1
86 #define PAGE_ATTRIBUTES 2
88 static gboolean addressbook_edit_person_close( gboolean cancelled );
89 static GList *edit_person_build_email_list();
90 static GList *edit_person_build_attrib_list();
92 static gchar* edit_person_get_common_name_from_widgets(void)
94 gchar *cn = NULL; /* cn must be freed by caller */
96 #ifndef GENERIC_UMPC
98 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
99 if ( cn == NULL || *cn == '\0' ) {
100 gchar *first = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
101 gchar *last = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
102 cn = g_strdup_printf("%s%s%s", first?first:"", (first && last && *first && *last)?" ":"", last?last:"");
103 g_free(first);
104 g_free(last);
106 if ( cn == NULL || *cn == '\0' ) {
107 g_free(cn);
108 cn = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );;
111 #else
113 gchar *first = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
114 gchar *last = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
115 cn = g_strdup_printf("%s%s%s", first?first:"", (first && last && *first && *last)?" ":"", last?last:"");
116 g_free(first);
117 g_free(last);
119 #endif
120 if ( cn != NULL )
121 g_strstrip(cn);
122 return cn;
125 static void edit_person_status_show( gchar *msg ) {
126 if( personeditdlg.statusbar != NULL ) {
127 gtk_statusbar_pop( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid );
128 if( msg ) {
129 gtk_statusbar_push( GTK_STATUSBAR(personeditdlg.statusbar), personeditdlg.status_cid, msg );
134 static void edit_person_cancel(GtkWidget *widget, gboolean *cancelled) {
135 *cancelled = TRUE;
136 if (prefs_common.addressbook_use_editaddress_dialog)
137 gtk_main_quit();
138 else
139 addressbook_edit_person_close( *cancelled );
142 static void edit_person_ok(GtkWidget *widget, gboolean *cancelled) {
143 GList *listEMail = edit_person_build_email_list();
144 GList *listAttrib = edit_person_build_attrib_list();
145 gchar *cn = edit_person_get_common_name_from_widgets();
147 if( (cn == NULL || *cn == '\0') && listEMail == NULL && listAttrib == NULL ) {
148 gint val;
150 val = alertpanel( _("Add New Person"),
151 #ifndef GENERIC_UMPC
152 _("Adding a new person requires at least one of the\n"
153 "following values to be set:\n"
154 " - Display Name\n"
155 " - First Name\n"
156 " - Last Name\n"
157 " - Nickname\n"
158 " - any email address\n"
159 " - any additional attribute\n\n"
160 "Click OK to keep editing this contact.\n"
161 "Click Cancel to close without saving."),
162 #else
163 _("Adding a new person requires at least one of the\n"
164 "following values to be set:\n"
165 " - First Name\n"
166 " - Last Name\n"
167 " - any email address\n"
168 " - any additional attribute\n\n"
169 "Click OK to keep editing this contact.\n"
170 "Click Cancel to close without saving."),
171 #endif
172 GTK_STOCK_CANCEL, GTK_STOCK_OK, NULL, ALERTFOCUS_SECOND );
173 if( val == G_ALERTDEFAULT ) {
174 edit_person_cancel(widget, cancelled);
176 g_free( cn );
177 return;
179 g_free( cn );
181 *cancelled = FALSE;
182 if (prefs_common.addressbook_use_editaddress_dialog)
183 gtk_main_quit();
184 else
185 addressbook_edit_person_close( *cancelled );
188 /* Updated up/down buttons sensitivity, depending on list
189 * cursor position */
190 static void edit_person_email_update_buttons()
192 GtkTreeModel *model;
193 GtkTreeIter iter, otheriter;
194 GtkTreePath *path;
195 gboolean has_prev;
196 ItemEMail *email;
198 email = gtkut_tree_view_get_selected_pointer(
199 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
200 &model, NULL, &iter);
202 if (email) {
203 if (!personeditdlg.read_only) {
204 otheriter = iter;
205 path = gtk_tree_model_get_path(model, &otheriter);
206 has_prev = gtk_tree_path_prev(path);
207 if (has_prev) {
208 gtk_tree_model_get_iter(model, &otheriter, path);
210 gtk_widget_set_sensitive(personeditdlg.email_up, has_prev);
212 otheriter = iter;
213 gtk_widget_set_sensitive(personeditdlg.email_down,
214 gtk_tree_model_iter_next(model, &otheriter));
216 } else {
217 gtk_widget_set_sensitive(personeditdlg.email_del, FALSE);
218 gtk_widget_set_sensitive(personeditdlg.email_up, FALSE);
219 gtk_widget_set_sensitive(personeditdlg.email_down, FALSE);
223 static void edit_person_email_cursor_changed(GtkTreeView *view,
224 gpointer user_data)
226 GtkTreeModel *model;
227 GtkTreeIter iter;
228 ItemEMail *email;
230 email = gtkut_tree_view_get_selected_pointer(
231 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
232 &model, NULL, &iter);
234 if (email != NULL) {
235 if (email->address != NULL)
236 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_email),
237 email->address);
238 if (ADDRITEM_NAME(email) != NULL)
239 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_alias),
240 ADDRITEM_NAME(email));
241 if (email->remarks != NULL)
242 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_remarks),
243 email->remarks);
246 edit_person_email_update_buttons();
250 static gint edit_person_delete_event(GtkWidget *widget, GdkEventAny *event, gboolean *cancelled) {
251 *cancelled = TRUE;
252 if (prefs_common.addressbook_use_editaddress_dialog)
253 gtk_main_quit();
254 else
255 addressbook_edit_person_close( *cancelled );
256 return TRUE;
259 static gboolean edit_person_key_pressed(GtkWidget *widget, GdkEventKey *event, gboolean *cancelled) {
260 if (prefs_common.addressbook_use_editaddress_dialog) {
261 if (event && event->keyval == GDK_KEY_Escape) {
262 *cancelled = TRUE;
263 gtk_main_quit();
266 return FALSE;
269 static gchar *_title_new_ = NULL;
270 static gchar *_title_edit_ = NULL;
272 static void edit_person_set_widgets_title( gchar *text )
274 gchar *label = NULL;
276 cm_return_if_fail( text != NULL );
278 gtk_label_set_text(GTK_LABEL(personeditdlg.title), "");
279 label = g_markup_printf_escaped("<b>%s</b>", text);
280 gtk_label_set_markup(GTK_LABEL(personeditdlg.title), label);
281 g_free(label);
284 static void edit_person_set_window_title( gint pageNum ) {
285 gchar *sTitle;
287 if( _title_new_ == NULL ) {
288 _title_new_ = g_strdup( _("Add New Person") );
289 _title_edit_ = g_strdup( _("Edit Person Details") );
292 if( pageNum == PAGE_BASIC ) {
293 if( personeditdlg.editNew ) {
294 if (prefs_common.addressbook_use_editaddress_dialog)
295 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_new_ );
296 else
297 edit_person_set_widgets_title( _title_new_ );
299 else {
300 if (prefs_common.addressbook_use_editaddress_dialog)
301 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), _title_edit_ );
302 else
303 edit_person_set_widgets_title( _title_edit_ );
306 else {
307 if( personeditdlg.entry_name == NULL ) {
308 sTitle = g_strdup( _title_edit_ );
310 else {
311 gchar *name;
312 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_name), 0, -1 );
313 g_strstrip(name);
314 if ( *name != '\0' )
315 sTitle = g_strdup_printf( "%s - %s", _title_edit_, name );
316 else
317 sTitle = g_strdup( _title_edit_ );
318 g_free( name );
320 if (prefs_common.addressbook_use_editaddress_dialog)
321 gtk_window_set_title( GTK_WINDOW(personeditdlg.container), sTitle );
322 else
323 edit_person_set_widgets_title( sTitle );
324 g_free( sTitle );
328 static void edit_person_email_clear( gpointer data ) {
329 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_email), "" );
330 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_alias), "" );
331 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_remarks), "" );
334 static void edit_person_attrib_clear( gpointer data ) {
335 if (!personeditdlg.ldap) {
336 gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))), "" );
337 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), "" );
341 static void edit_person_switch_page( GtkNotebook *notebook, gpointer page,
342 gint pageNum, gpointer user_data)
344 edit_person_set_window_title( pageNum );
345 edit_person_status_show( "" );
349 * Load clist with a copy of person's email addresses.
351 static void edit_person_load_email( ItemPerson *person ) {
352 GList *node = person->listEMail;
353 GtkTreeModel *model = gtk_tree_view_get_model(
354 GTK_TREE_VIEW(personeditdlg.view_email));
355 GtkTreeIter iter;
357 while( node ) {
358 ItemEMail *emorig = ( ItemEMail * ) node->data;
359 ItemEMail *email = addritem_copyfull_item_email( emorig );
361 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
362 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
363 EMAIL_COL_EMAIL, email->address,
364 #ifndef GENERIC_UMPC
365 EMAIL_COL_ALIAS, email->obj.name,
366 EMAIL_COL_REMARKS, email->remarks,
367 #endif
368 EMAIL_COL_PTR, email,
369 -1);
371 node = g_list_next( node );
375 static void edit_person_email_move_up( gpointer data ) {
376 GtkTreeModel *model;
377 GtkTreeIter iter, otheriter;
378 GtkTreePath *path;
379 ItemEMail *email;
380 gboolean has_prev;
382 edit_person_email_clear( NULL );
383 edit_person_status_show( NULL );
385 email = gtkut_tree_view_get_selected_pointer(
386 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
387 &model, NULL, &iter);
389 if( email ) {
390 otheriter = iter;
391 /* GTK+2 does not have gtk_tree_model_iter_previous(), so
392 * we have to go through GtkTreePath */
393 path = gtk_tree_model_get_path(model, &otheriter);
394 has_prev = gtk_tree_path_prev(path);
395 if (has_prev) {
396 gtk_tree_model_get_iter(model, &otheriter, path);
397 gtk_list_store_move_before(GTK_LIST_STORE(model), &iter, &otheriter);
399 gtk_tree_path_free(path);
402 edit_person_email_update_buttons();
405 static void edit_person_email_move_down( gpointer data ) {
406 GtkTreeModel *model;
407 GtkTreeIter iter, otheriter;
408 ItemEMail *email;
410 edit_person_email_clear( NULL );
411 edit_person_status_show( NULL );
413 email = gtkut_tree_view_get_selected_pointer(
414 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
415 &model, NULL, &iter);
417 if( email ) {
418 otheriter = iter;
419 if (gtk_tree_model_iter_next(model, &otheriter)) {
420 gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &otheriter);
424 edit_person_email_update_buttons();
427 static void edit_person_attrib_cursor_changed(GtkTreeView *view,
428 gpointer user_data)
430 UserAttribute *attrib = gtkut_tree_view_get_selected_pointer(
431 view, ATTRIB_COL_PTR, NULL, NULL, NULL);
433 if( attrib && !personeditdlg.read_only && !personeditdlg.ldap ) {
434 gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname))) ), attrib->name );
435 gtk_entry_set_text( GTK_ENTRY(personeditdlg.entry_atvalue), attrib->value );
436 gtk_widget_set_sensitive(personeditdlg.attrib_del, TRUE);
437 } else {
438 gtk_widget_set_sensitive(personeditdlg.attrib_del, FALSE);
440 edit_person_status_show( NULL );
444 static void edit_person_email_delete( gpointer data ) {
445 GtkTreeModel *model;
446 GtkTreeIter iter;
447 GtkTreeSelection *sel;
448 ItemEMail *email;
449 gboolean has_row = FALSE;
450 gint n;
452 edit_person_email_clear( NULL );
453 edit_person_status_show( NULL );
455 email = gtkut_tree_view_get_selected_pointer(
456 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
457 &model, &sel, &iter);
459 if( email ) {
460 /* Remove list entry and set iter to next row, if any */
461 has_row = gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
462 addritem_free_item_email( email );
463 email = NULL;
466 /* Position hilite bar */
467 if (!has_row) {
468 /* The removed row was the last in the list, so iter is not
469 * valid. Find out if there is at least one row remaining
470 * in the list, and select the last one if so. */
471 n = gtk_tree_model_iter_n_children(model, NULL);
472 if (n > 0 && gtk_tree_model_iter_nth_child(model, &iter, NULL, n-1)) {
473 /* It exists */
474 has_row = TRUE;
478 if (has_row)
479 gtk_tree_selection_select_iter(sel, &iter);
481 edit_person_email_cursor_changed(
482 GTK_TREE_VIEW(personeditdlg.view_email), NULL);
485 static ItemEMail *edit_person_email_edit( gboolean *error, ItemEMail *email ) {
486 ItemEMail *retVal = NULL;
487 gchar *sEmail, *sAlias, *sRemarks, *sEmail_;
489 *error = TRUE;
490 sEmail_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_email), 0, -1 );
491 sAlias = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_alias), 0, -1 );
492 sRemarks = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_remarks), 0, -1 );
493 sEmail = mgu_email_check_empty( sEmail_ );
494 g_free( sEmail_ );
496 if( sEmail ) {
497 if( email == NULL ) {
498 email = addritem_create_item_email();
500 addritem_email_set_address( email, sEmail );
501 addritem_email_set_alias( email, sAlias );
502 addritem_email_set_remarks( email, sRemarks );
503 retVal = email;
504 *error = FALSE;
506 else {
507 edit_person_status_show( _( "An Email address must be supplied." ) );
510 g_free( sEmail );
511 g_free( sAlias );
512 g_free( sRemarks );
514 return retVal;
517 static void edit_person_email_modify( gpointer data ) {
518 GtkTreeModel *model;
519 GtkTreeIter iter;
520 gboolean errFlg = FALSE;
521 ItemEMail *email;
523 email = gtkut_tree_view_get_selected_pointer(
524 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
525 &model, NULL, &iter);
527 if( email ) {
528 edit_person_email_edit( &errFlg, email );
529 if( ! errFlg ) {
530 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
531 EMAIL_COL_EMAIL, email->address,
532 #ifndef GENERIC_UMPC
533 EMAIL_COL_ALIAS, email->obj.name,
534 EMAIL_COL_REMARKS, email->remarks,
535 #endif
536 -1);
537 edit_person_email_clear( NULL );
542 static void edit_person_email_add( gpointer data ) {
543 GtkTreeModel *model;
544 GtkTreeIter iter, otheriter;
545 GtkTreeSelection *sel;
546 gboolean errFlg = FALSE, prev_exists = FALSE;
547 ItemEMail *email = NULL;
549 email = gtkut_tree_view_get_selected_pointer(
550 GTK_TREE_VIEW(personeditdlg.view_email), EMAIL_COL_PTR,
551 &model, &sel, &otheriter);
552 if (email != NULL)
553 prev_exists = TRUE;
555 email = edit_person_email_edit( &errFlg, NULL );
556 if( ! errFlg ) {
557 if (prev_exists)
558 gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter, &otheriter);
559 else /* list is empty */
560 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
562 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
563 EMAIL_COL_EMAIL, email->address,
564 #ifndef GENERIC_UMPC
565 EMAIL_COL_ALIAS, email->obj.name,
566 EMAIL_COL_REMARKS, email->remarks,
567 #endif
568 EMAIL_COL_PTR, email,
569 -1);
570 gtk_tree_selection_select_iter(sel, &iter);
571 edit_person_email_update_buttons();
573 edit_person_email_clear( NULL );
577 static gboolean list_find_email(const gchar *addr)
579 GtkWidget *view = personeditdlg.view_email;
580 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
581 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
582 GtkTreeIter iter;
583 ItemEMail *email;
585 if (!gtk_tree_model_get_iter_first(model, &iter))
586 return FALSE;
588 do {
589 gtk_tree_model_get(model, &iter, EMAIL_COL_PTR, &email, -1);
590 if (!g_ascii_strcasecmp(email->address, addr)) {
591 gtk_tree_selection_select_iter(sel, &iter);
592 return TRUE;
594 } while (gtk_tree_model_iter_next(model, &iter));
596 return FALSE;
599 static gboolean list_find_attribute(const gchar *attr)
601 GtkWidget *view = personeditdlg.view_attrib;
602 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
603 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
604 GtkTreeIter iter;
605 UserAttribute *attrib;
607 if (!gtk_tree_model_get_iter_first(model, &iter))
608 return FALSE;
610 do {
611 gtk_tree_model_get(model, &iter, ATTRIB_COL_PTR, &attrib, -1);
612 if (!g_ascii_strcasecmp(attrib->name, attr)) {
613 gtk_tree_selection_select_iter(sel, &iter);
614 return TRUE;
616 } while (gtk_tree_model_iter_next(model, &iter));
618 return FALSE;
622 * Load list with a copy of person's email addresses.
624 static void edit_person_load_attrib( ItemPerson *person ) {
625 GList *node = person->listAttrib;
626 GtkWidget *view = personeditdlg.view_attrib;
627 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
628 GtkTreeIter iter;
630 while( node ) {
631 UserAttribute *atorig = ( UserAttribute * ) node->data;
632 UserAttribute *attrib = addritem_copy_attribute( atorig );
634 debug_print("name: %s value: %s\n", attrib->name, attrib->value);
636 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
637 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
638 ATTRIB_COL_NAME, attrib->name,
639 ATTRIB_COL_VALUE, attrib->value,
640 ATTRIB_COL_PTR, attrib,
641 -1);
643 node = g_list_next( node );
647 static void edit_person_attrib_delete(gpointer data) {
648 UserAttribute *attrib;
649 GtkTreeModel *model;
650 GtkTreeSelection *sel;
651 GtkTreeIter iter;
652 gboolean has_row = FALSE;
653 gint n;
655 edit_person_attrib_clear(NULL);
656 edit_person_status_show(NULL);
658 attrib = gtkut_tree_view_get_selected_pointer(
659 GTK_TREE_VIEW(personeditdlg.view_attrib), ATTRIB_COL_PTR,
660 &model, &sel, &iter);
662 if (attrib) {
663 /* Remove list entry, and set iter to next row, if any */
664 has_row = gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
665 addritem_free_attribute(attrib);
666 attrib = NULL;
669 /* Position hilite bar */
670 if (!has_row) {
671 /* The removed row was the last in the list, so iter is not
672 * valid. Find out if there is at least one row remaining
673 * in the list, and select the last one if so. */
674 n = gtk_tree_model_iter_n_children(model, NULL);
675 if (n > 0 && gtk_tree_model_iter_nth_child(model, &iter, NULL, n-1)) {
676 /* It exists. */
677 has_row = TRUE;
681 if (has_row)
682 gtk_tree_selection_select_iter(sel, &iter);
684 edit_person_attrib_cursor_changed(
685 GTK_TREE_VIEW(personeditdlg.view_attrib), NULL);
688 static UserAttribute *edit_person_attrib_edit( gboolean *error, UserAttribute *attrib ) {
689 UserAttribute *retVal = NULL;
690 gchar *sName, *sValue, *sName_, *sValue_;
692 *error = TRUE;
693 sName_ = gtk_editable_get_chars( GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))), 0, -1 );
694 sValue_ = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_atvalue), 0, -1 );
695 sName = mgu_email_check_empty( sName_ );
696 sValue = mgu_email_check_empty( sValue_ );
697 g_free( sName_ );
698 g_free( sValue_ );
700 if( sName && sValue ) {
701 if( attrib == NULL ) {
702 attrib = addritem_create_attribute();
704 addritem_attrib_set_name( attrib, sName );
705 addritem_attrib_set_value( attrib, sValue );
706 retVal = attrib;
707 *error = FALSE;
709 else {
710 edit_person_status_show( _( "A Name and Value must be supplied." ) );
713 g_free( sName );
714 g_free( sValue );
716 return retVal;
719 static void edit_person_attrib_modify(gpointer data) {
720 gboolean errFlg = FALSE;
721 GtkTreeModel *model;
722 GtkTreeIter iter;
723 UserAttribute *attrib;
725 attrib = gtkut_tree_view_get_selected_pointer(
726 GTK_TREE_VIEW(personeditdlg.view_attrib), ATTRIB_COL_PTR,
727 &model, NULL, &iter);
728 if (attrib) {
729 edit_person_attrib_edit(&errFlg, attrib);
730 if (!errFlg) {
731 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
732 ATTRIB_COL_NAME, attrib->name,
733 ATTRIB_COL_VALUE, attrib->value,
734 -1);
735 edit_person_attrib_clear(NULL);
740 static void edit_person_attrib_add(gpointer data) {
741 gboolean errFlg = FALSE;
742 GtkTreeModel *model;
743 GtkTreeSelection *sel;
744 GtkTreeIter iter, iter2;
745 UserAttribute *prev_attrib, *attrib;
747 attrib = edit_person_attrib_edit(&errFlg, NULL);
748 if (attrib == NULL) /* input for new attribute is not valid */
749 return;
751 prev_attrib = gtkut_tree_view_get_selected_pointer(
752 GTK_TREE_VIEW(personeditdlg.view_attrib), ATTRIB_COL_PTR,
753 &model, &sel, &iter);
755 if (prev_attrib == NULL) {
756 /* No row selected, or list empty, add new attribute as first row. */
757 gtk_list_store_insert(GTK_LIST_STORE(model), &iter, 0);
758 } else {
759 /* Add it after the currently selected row. */
760 gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter2,
761 &iter);
762 iter = iter2;
765 /* Fill out the new row. */
766 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
767 ATTRIB_COL_NAME, attrib->name,
768 ATTRIB_COL_VALUE, attrib->value,
769 ATTRIB_COL_PTR, attrib,
770 -1);
771 gtk_tree_selection_select_iter(sel, &iter);
772 edit_person_attrib_clear(NULL);
776 *\brief Save Gtk object size to prefs dataset
778 static void edit_person_size_allocate_cb(GtkWidget *widget,
779 GtkAllocation *allocation)
781 cm_return_if_fail(allocation != NULL);
783 prefs_common.addressbookeditpersonwin_width = allocation->width;
784 prefs_common.addressbookeditpersonwin_height = allocation->height;
787 /* build edit person widgets, return a pointer to the main container of the widgetset (a vbox) */
788 static GtkWidget* addressbook_edit_person_widgets_create( GtkWidget* container, gboolean *cancelled )
790 GtkWidget *vbox;
791 GtkWidget *vnbox;
792 GtkWidget *notebook;
793 GtkWidget *hbbox;
794 GtkWidget *ok_btn;
795 GtkWidget *cancel_btn;
797 vbox = gtk_vbox_new(FALSE, 4);
798 gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH);
799 gtk_widget_show(vbox);
800 gtk_container_add(GTK_CONTAINER(container), vbox);
802 vnbox = gtk_vbox_new(FALSE, 4);
803 gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
804 gtk_widget_show(vnbox);
805 gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
807 /* Notebook */
808 notebook = gtk_notebook_new();
809 gtk_widget_show(notebook);
810 gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
811 gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
813 /* Button panel */
814 if (prefs_common.addressbook_use_editaddress_dialog)
815 gtkut_stock_button_set_create(&hbbox, &cancel_btn, GTK_STOCK_CANCEL,
816 &ok_btn, GTK_STOCK_OK,
817 NULL, NULL);
818 else
819 gtkut_stock_with_text_button_set_create(&hbbox,
820 &cancel_btn, GTK_STOCK_CANCEL, _("Discard"),
821 &ok_btn, GTK_STOCK_OK, _("Apply"),
822 NULL, NULL, NULL);
823 gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
824 gtk_widget_grab_default(ok_btn);
826 g_signal_connect(G_OBJECT(ok_btn), "clicked",
827 G_CALLBACK(edit_person_ok), cancelled);
828 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
829 G_CALLBACK(edit_person_cancel), cancelled);
830 g_signal_connect(G_OBJECT(notebook), "switch_page",
831 G_CALLBACK(edit_person_switch_page), NULL );
833 gtk_widget_show_all(vbox);
835 personeditdlg.notebook = notebook;
836 personeditdlg.ok_btn = ok_btn;
837 personeditdlg.cancel_btn = cancel_btn;
839 return vbox;
842 static void addressbook_edit_person_dialog_create( gboolean *cancelled ) {
843 GtkWidget *window;
844 GtkWidget *hsbox;
845 GtkWidget *vbox;
846 GtkWidget *statusbar;
847 static GdkGeometry geometry;
849 window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "editaddress");
850 /* gtk_container_set_border_width(GTK_CONTAINER(window), 0); */
851 gtk_window_set_title(GTK_WINDOW(window), _("Edit Person Data"));
852 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
853 gtk_window_set_modal(GTK_WINDOW(window), FALSE);
854 gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG);
855 g_signal_connect(G_OBJECT(window), "delete_event",
856 G_CALLBACK(edit_person_delete_event),
857 cancelled);
858 g_signal_connect(G_OBJECT(window), "size_allocate",
859 G_CALLBACK(edit_person_size_allocate_cb),
860 cancelled);
861 g_signal_connect(G_OBJECT(window), "key_press_event",
862 G_CALLBACK(edit_person_key_pressed),
863 cancelled);
865 vbox = addressbook_edit_person_widgets_create(window, cancelled);
867 /* Status line */
868 hsbox = gtk_hbox_new(FALSE, 0);
869 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
870 statusbar = gtk_statusbar_new();
871 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
873 if (!geometry.min_height) {
874 geometry.min_width = EDITPERSON_WIDTH;
875 geometry.min_height = EDITPERSON_HEIGHT;
878 gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
879 GDK_HINT_MIN_SIZE);
880 gtk_widget_set_size_request(window, prefs_common.addressbookeditpersonwin_width,
881 prefs_common.addressbookeditpersonwin_height);
883 personeditdlg.container = window;
884 personeditdlg.statusbar = statusbar;
885 personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
889 /* parent must be a box */
890 static void addressbook_edit_person_widgetset_create( GtkWidget *parent, gboolean *cancelled )
892 GtkWidget *vbox;
893 GtkWidget *label;
895 if ( parent == NULL )
896 g_warning("addressbook_edit_person_widgetset_create: parent is NULL");
898 vbox = gtk_vbox_new(FALSE, 0);
899 gtk_box_pack_end(GTK_BOX(parent), vbox, TRUE, TRUE, 0);
901 label = gtk_label_new(_("Edit Person Data"));
902 gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER);
903 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
905 addressbook_edit_person_widgets_create(vbox, cancelled);
907 gtk_widget_set_size_request(vbox, EDITPERSON_WIDTH, EDITPERSON_HEIGHT);
909 personeditdlg.container = vbox;
910 personeditdlg.title = label;
911 personeditdlg.statusbar = NULL;
912 personeditdlg.status_cid = 0;
915 void addressbook_edit_person_widgetset_hide( void )
917 if ( personeditdlg.container )
918 gtk_widget_hide( personeditdlg.container );
921 static void addressbook_edit_person_set_picture(void)
923 GError *error = NULL;
924 gchar *filename;
925 int width, height, scalewidth, scaleheight;
927 if (personeditdlg.ldap)
928 return;
930 if ( (filename = filesel_select_file_open(_("Choose a picture"), NULL)) ) {
931 GdkPixbuf *pixbuf = NULL;
932 gdk_pixbuf_get_file_info(filename, &width, &height);
934 if ( width > 128 || height > 128 ) {
935 if (width > height) {
936 scaleheight = (height * 128) / width;
937 scalewidth = 128;
939 else {
940 scalewidth = (width * 128) / height;
941 scaleheight = 128;
943 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
944 scalewidth, scaleheight, TRUE, &error);
945 } else {
946 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
948 if (error) {
949 alertpanel_error(_("Failed to import image: \n%s"),
950 error->message);
951 g_error_free(error);
952 error = NULL;
953 /* keep the previous picture if any */
954 g_free(filename);
955 if (pixbuf)
956 g_object_unref(pixbuf);
957 return;
959 personeditdlg.picture_set = TRUE;
960 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", personeditdlg.picture_set);
961 g_free(filename);
962 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
963 g_object_unref(pixbuf);
967 static void addressbook_edit_person_clear_picture(void)
969 GdkPixbuf *pixbuf;
971 stock_pixbuf_gdk(STOCK_PIXMAP_ANONYMOUS, &pixbuf);
972 personeditdlg.picture_set = FALSE;
973 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", personeditdlg.picture_set);
974 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
977 static void addressbook_edit_person_set_picture_menu_cb (GtkAction *action, gpointer data)
979 addressbook_edit_person_set_picture();
982 static void addressbook_edit_person_unset_picture_menu_cb (GtkAction *action, gpointer data)
984 addressbook_edit_person_clear_picture();
987 static GtkWidget *editaddr_popup_menu = NULL;
988 static GtkActionEntry editaddr_popup_entries[] =
990 {"EditAddressPopup", NULL, "EditAddressPopup", NULL, NULL, NULL },
991 {"EditAddressPopup/SetPicture", NULL, N_("_Set picture"), NULL, NULL, G_CALLBACK(addressbook_edit_person_set_picture_menu_cb) },
992 {"EditAddressPopup/UnsetPicture", NULL, N_("_Unset picture"), NULL, NULL, G_CALLBACK(addressbook_edit_person_unset_picture_menu_cb) },
995 static void addressbook_edit_person_set_picture_cb(GtkWidget *widget,
996 GdkEventButton *event, gpointer data)
998 if (event->button == 1) {
999 addressbook_edit_person_set_picture();
1000 } else {
1001 gtk_menu_popup(GTK_MENU(editaddr_popup_menu),
1002 NULL, NULL, NULL, NULL,
1003 event->button, event->time);
1007 static gboolean addressbook_edit_person_picture_popup_menu(GtkWidget *widget, gpointer data)
1009 GdkEventButton event;
1011 event.button = 3;
1012 event.time = gtk_get_current_event_time();
1014 addressbook_edit_person_set_picture_cb(NULL, &event, data);
1016 return TRUE;
1019 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
1020 GtkWidget *vbox;
1021 GtkWidget *hbox;
1022 GtkWidget *table;
1023 GtkWidget *label;
1024 GtkWidget *ebox_picture;
1025 GtkWidget *frame_picture;
1026 GtkWidget *entry_name;
1027 GtkWidget *entry_fn;
1028 GtkWidget *entry_ln;
1029 GtkWidget *entry_nn;
1030 const gchar *locale;
1031 gint top = 0;
1033 vbox = gtk_vbox_new( FALSE, 20 );
1034 hbox = gtk_hbox_new( FALSE, 8 );
1036 gtk_widget_show( vbox );
1038 if (!editaddr_popup_menu) {
1039 cm_menu_create_action_group("EditAddressPopup", editaddr_popup_entries,
1040 G_N_ELEMENTS(editaddr_popup_entries), (gpointer)NULL);
1041 MENUITEM_ADDUI("/Menus", "EditAddressPopup", "EditAddressPopup", GTK_UI_MANAGER_MENU)
1042 MENUITEM_ADDUI("/Menus/EditAddressPopup", "SetPicture", "EditAddressPopup/SetPicture", GTK_UI_MANAGER_MENUITEM)
1043 MENUITEM_ADDUI("/Menus/EditAddressPopup", "UnsetPicture", "EditAddressPopup/UnsetPicture", GTK_UI_MANAGER_MENUITEM)
1045 editaddr_popup_menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
1046 gtk_ui_manager_get_widget(gtkut_ui_manager(), "/Menus/EditAddressPopup")) );
1048 /* User's picture */
1049 ebox_picture = gtk_event_box_new();
1050 frame_picture = gtk_frame_new(_("Photo"));
1052 /* Room for a photo */
1053 personeditdlg.image = gtk_image_new();
1054 addressbook_edit_person_clear_picture();
1056 gtk_container_add(GTK_CONTAINER(ebox_picture), personeditdlg.image);
1057 gtk_container_add(GTK_CONTAINER(frame_picture), ebox_picture);
1058 gtk_container_add(GTK_CONTAINER( personeditdlg.notebook ), hbox );
1059 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1060 gtk_container_set_border_width( GTK_CONTAINER (hbox), BORDER_WIDTH );
1062 label = gtk_label_new_with_mnemonic( pageLbl );
1063 gtk_widget_show( label );
1065 gtk_box_pack_start(GTK_BOX(hbox), frame_picture, TRUE, TRUE, 0);
1067 gtk_notebook_set_tab_label(
1068 GTK_NOTEBOOK( personeditdlg.notebook ),
1069 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1071 g_signal_connect(G_OBJECT(ebox_picture), "popup-menu",
1072 G_CALLBACK(addressbook_edit_person_picture_popup_menu), NULL);
1073 g_signal_connect(G_OBJECT(ebox_picture), "button_press_event",
1074 G_CALLBACK(addressbook_edit_person_set_picture_cb), NULL);
1076 table = gtk_table_new( 3, 3, FALSE);
1078 #define ATTACH_ROW(text, entry) \
1080 label = gtk_label_new(text); \
1081 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), \
1082 GTK_FILL, 0, 0, 0); \
1083 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \
1085 entry = gtk_entry_new(); \
1086 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, top, (top + 1), \
1087 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); \
1088 top++; \
1091 #define ATTACH_HIDDEN_ROW(text, entry) \
1093 entry = gtk_entry_new(); \
1096 #ifndef GENERIC_UMPC
1097 ATTACH_ROW(_("Display Name"), entry_name);
1098 #else
1099 ATTACH_HIDDEN_ROW(_("Display Name"), entry_name);
1100 #endif
1101 locale = conv_get_current_locale();
1102 if (locale &&
1103 (!g_ascii_strncasecmp(locale, "hu", 2) ||
1104 !g_ascii_strncasecmp(locale, "ja", 2) ||
1105 !g_ascii_strncasecmp(locale, "ko", 2) ||
1106 !g_ascii_strncasecmp(locale, "vi", 2) ||
1107 !g_ascii_strncasecmp(locale, "zh", 2))) {
1108 ATTACH_ROW(_("Last Name"), entry_ln);
1109 ATTACH_ROW(_("First Name"), entry_fn);
1110 } else {
1111 ATTACH_ROW(_("First Name"), entry_fn);
1112 ATTACH_ROW(_("Last Name"), entry_ln);
1114 #ifndef GENERIC_UMPC
1115 ATTACH_ROW(_("Nickname"), entry_nn);
1116 #else
1117 ATTACH_HIDDEN_ROW(_("Nickname"), entry_nn);
1118 #endif
1120 #undef ATTACH_ROW
1121 #undef ATTACH_HIDDEN_ROW
1122 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
1123 gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1124 gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
1125 gtk_table_set_row_spacings(GTK_TABLE(table), 15);
1126 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
1128 gtk_widget_show_all(vbox);
1129 personeditdlg.entry_name = entry_name;
1130 personeditdlg.entry_first = entry_fn;
1131 personeditdlg.entry_last = entry_ln;
1132 personeditdlg.entry_nick = entry_nn;
1135 static gboolean email_adding = FALSE, email_saving = FALSE;
1137 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
1139 GtkTreeModel *model = gtk_tree_view_get_model(
1140 GTK_TREE_VIEW(personeditdlg.view_email));
1141 gboolean non_empty = (gtk_tree_model_iter_n_children(model, NULL) > 0);
1143 if (personeditdlg.read_only)
1144 return;
1146 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)) == NULL
1147 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email))) == 0) {
1148 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
1149 gtk_widget_set_sensitive(personeditdlg.email_mod,FALSE);
1150 email_adding = FALSE;
1151 email_saving = FALSE;
1152 } else if (list_find_email(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)))) {
1153 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
1154 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
1155 email_adding = FALSE;
1156 email_saving = non_empty;
1157 } else {
1158 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
1159 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
1160 email_adding = TRUE;
1161 email_saving = non_empty;
1165 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1167 if (event && event->keyval == GDK_KEY_Return) {
1168 if (email_saving)
1169 edit_person_email_modify(NULL);
1170 else if (email_adding)
1171 edit_person_email_add(NULL);
1173 return FALSE;
1177 static void addressbook_edit_person_page_email( gint pageNum, gchar *pageLbl ) {
1178 GtkWidget *vbox;
1179 GtkWidget *hbox;
1180 GtkWidget *vboxl;
1181 GtkWidget *vboxb;
1182 GtkWidget *vbuttonbox;
1183 GtkWidget *buttonUp;
1184 GtkWidget *buttonDown;
1185 GtkWidget *buttonDel;
1186 GtkWidget *buttonMod;
1187 GtkWidget *buttonAdd;
1189 GtkWidget *table;
1190 GtkWidget *label;
1191 GtkWidget *scrollwin;
1192 GtkWidget *view;
1193 GtkWidget *entry_email;
1194 GtkWidget *entry_alias;
1195 GtkWidget *entry_remarks;
1196 gint top;
1197 GtkListStore *store;
1198 GtkTreeViewColumn *col;
1199 GtkCellRenderer *rdr;
1200 GtkTreeSelection *sel;
1202 vbox = gtk_vbox_new( FALSE, 8 );
1203 gtk_widget_show( vbox );
1204 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1205 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1207 label = gtk_label_new_with_mnemonic( pageLbl );
1208 gtk_widget_show( label );
1209 gtk_notebook_set_tab_label(
1210 GTK_NOTEBOOK( personeditdlg.notebook ),
1211 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1213 /* Split into two areas */
1214 hbox = gtk_hbox_new( FALSE, 0 );
1215 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1217 /* Address list */
1218 vboxl = gtk_vbox_new( FALSE, 4 );
1219 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1220 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1222 scrollwin = gtk_scrolled_window_new( NULL, NULL );
1223 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
1224 GTK_POLICY_AUTOMATIC,
1225 GTK_POLICY_AUTOMATIC);
1227 store = gtk_list_store_new(EMAIL_N_COLS,
1228 G_TYPE_STRING,
1229 #ifndef GENERIC_UMPC
1230 G_TYPE_STRING,
1231 G_TYPE_STRING,
1232 #endif
1233 G_TYPE_POINTER,
1234 -1);
1236 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1237 g_object_unref(store);
1238 #ifndef GENERIC_UMPC
1239 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), TRUE);
1240 #else
1241 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1242 #endif
1243 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1244 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1246 rdr = gtk_cell_renderer_text_new();
1247 col = gtk_tree_view_column_new_with_attributes(_("Email Address"), rdr,
1248 "markup", EMAIL_COL_EMAIL, NULL);
1249 gtk_tree_view_column_set_min_width(col, EMAIL_COL_WIDTH_EMAIL);
1250 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1252 #ifndef GENERIC_UMPC
1253 col = gtk_tree_view_column_new_with_attributes(_("Alias"), rdr,
1254 "markup", EMAIL_COL_ALIAS, NULL);
1255 gtk_tree_view_column_set_min_width(col, EMAIL_COL_WIDTH_ALIAS);
1256 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1258 col = gtk_tree_view_column_new_with_attributes(_("Remarks"), rdr,
1259 "markup", EMAIL_COL_REMARKS, NULL);
1260 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1261 #endif
1263 gtk_container_add( GTK_CONTAINER(scrollwin), view );
1265 /* Data entry area */
1266 table = gtk_table_new( 4, 2, FALSE);
1268 #ifndef GENERIC_UMPC
1269 gtk_container_add( GTK_CONTAINER(vboxl), scrollwin );
1270 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1271 #else
1272 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1273 gtk_container_add( GTK_CONTAINER(vboxl), scrollwin );
1274 #endif
1275 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1276 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1277 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1279 entry_email = gtk_entry_new();
1280 entry_alias = gtk_entry_new();
1281 entry_remarks = gtk_entry_new();
1283 /* First row */
1284 top = 0;
1285 label = gtk_label_new(_("Email Address"));
1286 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1287 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1289 gtk_table_attach(GTK_TABLE(table), entry_email, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1291 #ifndef GENERIC_UMPC
1292 /* Next row */
1293 ++top;
1294 label = gtk_label_new(_("Alias"));
1295 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1296 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1298 gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1300 /* Next row */
1301 ++top;
1302 label = gtk_label_new(_("Remarks"));
1303 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1304 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1306 gtk_table_attach(GTK_TABLE(table), entry_remarks, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1307 #endif
1309 /* Button box */
1310 vboxb = gtk_vbox_new( FALSE, 4 );
1311 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1313 vbuttonbox = gtk_vbutton_box_new();
1314 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1315 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1316 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1317 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1319 /* Buttons */
1320 buttonUp = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
1321 buttonDown = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
1322 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1323 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1324 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1327 #ifndef GENERIC_UMPC
1328 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
1330 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
1331 #endif
1332 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1334 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1336 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1338 gtk_widget_show_all(vbox);
1340 /* Event handlers */
1341 g_signal_connect( G_OBJECT(view), "cursor-changed",
1342 G_CALLBACK( edit_person_email_cursor_changed ), NULL );
1343 g_signal_connect( G_OBJECT(buttonUp), "clicked",
1344 G_CALLBACK( edit_person_email_move_up ), NULL );
1345 g_signal_connect( G_OBJECT(buttonDown), "clicked",
1346 G_CALLBACK( edit_person_email_move_down ), NULL );
1347 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1348 G_CALLBACK( edit_person_email_delete ), NULL );
1349 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1350 G_CALLBACK( edit_person_email_modify ), NULL );
1351 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1352 G_CALLBACK( edit_person_email_add ), NULL );
1353 g_signal_connect(G_OBJECT(entry_email), "changed",
1354 G_CALLBACK(edit_person_entry_email_changed), NULL);
1355 g_signal_connect(G_OBJECT(entry_email), "key_press_event",
1356 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1357 g_signal_connect(G_OBJECT(entry_alias), "key_press_event",
1358 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1359 g_signal_connect(G_OBJECT(entry_remarks), "key_press_event",
1360 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1362 personeditdlg.view_email = view;
1363 personeditdlg.entry_email = entry_email;
1364 personeditdlg.entry_alias = entry_alias;
1365 personeditdlg.entry_remarks = entry_remarks;
1366 personeditdlg.email_up = buttonUp;
1367 personeditdlg.email_down = buttonDown;
1368 personeditdlg.email_del = buttonDel;
1369 personeditdlg.email_mod = buttonMod;
1370 personeditdlg.email_add = buttonAdd;
1373 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
1375 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
1377 GtkTreeModel *model = gtk_tree_view_get_model(
1378 GTK_TREE_VIEW(personeditdlg.view_attrib));
1379 gboolean non_empty = (gtk_tree_model_iter_n_children(model, NULL) > 0);
1380 const gchar *atname;
1382 if (personeditdlg.read_only || personeditdlg.ldap)
1383 return;
1385 atname = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))));
1386 if ( atname == NULL
1387 || strlen(atname) == 0) {
1388 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1389 gtk_widget_set_sensitive(personeditdlg.attrib_mod,FALSE);
1390 attrib_adding = FALSE;
1391 attrib_saving = FALSE;
1392 } else if (list_find_attribute(atname)) {
1393 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1394 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1395 attrib_adding = FALSE;
1396 attrib_saving = non_empty;
1397 } else {
1398 gtk_widget_set_sensitive(personeditdlg.attrib_add,TRUE);
1399 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1400 attrib_adding = TRUE;
1401 attrib_saving = non_empty;
1405 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1407 if (event && event->keyval == GDK_KEY_Return) {
1408 if (attrib_saving)
1409 edit_person_attrib_modify(NULL);
1410 else if (attrib_adding)
1411 edit_person_attrib_add(NULL);
1413 return FALSE;
1416 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
1417 GtkWidget *vbox;
1418 GtkWidget *hbox;
1419 GtkWidget *vboxl;
1420 GtkWidget *vboxb;
1421 GtkWidget *vbuttonbox;
1422 GtkWidget *buttonDel;
1423 GtkWidget *buttonMod;
1424 GtkWidget *buttonAdd;
1426 GtkWidget *table;
1427 GtkWidget *label;
1428 GtkWidget *scrollwin;
1429 GtkWidget *view;
1430 GtkWidget *entry_name;
1431 GtkWidget *entry_value;
1432 gint top;
1433 GtkListStore *store;
1434 GtkTreeViewColumn *col;
1435 GtkCellRenderer *rdr;
1436 GtkTreeSelection *sel;
1438 vbox = gtk_vbox_new( FALSE, 8 );
1439 gtk_widget_show( vbox );
1440 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1441 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1443 label = gtk_label_new_with_mnemonic( pageLbl );
1444 gtk_widget_show( label );
1445 gtk_notebook_set_tab_label(
1446 GTK_NOTEBOOK( personeditdlg.notebook ),
1447 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1449 /* Split into two areas */
1450 hbox = gtk_hbox_new( FALSE, 0 );
1451 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1453 /* Attribute list */
1454 vboxl = gtk_vbox_new( FALSE, 4 );
1455 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1456 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1458 scrollwin = gtk_scrolled_window_new( NULL, NULL );
1459 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
1460 GTK_POLICY_AUTOMATIC,
1461 GTK_POLICY_AUTOMATIC);
1463 store = gtk_list_store_new(ATTRIB_N_COLS,
1464 G_TYPE_STRING, G_TYPE_STRING,
1465 G_TYPE_POINTER, -1);
1467 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1468 g_object_unref(store);
1469 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), TRUE);
1470 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1471 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1473 rdr = gtk_cell_renderer_text_new();
1474 col = gtk_tree_view_column_new_with_attributes(_("Name"), rdr,
1475 "markup", ATTRIB_COL_NAME, NULL);
1476 gtk_tree_view_column_set_min_width(col, ATTRIB_COL_WIDTH_NAME);
1477 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1479 col = gtk_tree_view_column_new_with_attributes(_("Value"), rdr,
1480 "markup", ATTRIB_COL_VALUE, NULL);
1481 gtk_tree_view_column_set_min_width(col, ATTRIB_COL_WIDTH_VALUE);
1482 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1484 gtk_container_add( GTK_CONTAINER(scrollwin), view );
1486 /* Data entry area */
1487 #ifndef GENERIC_UMPC
1488 table = gtk_table_new( 4, 2, FALSE);
1489 gtk_container_add( GTK_CONTAINER(vboxl), scrollwin );
1490 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1491 #else
1492 table = gtk_table_new( 2, 4, FALSE);
1493 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1494 gtk_container_add( GTK_CONTAINER(vboxl), scrollwin );
1495 #endif
1496 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1497 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
1498 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
1500 /* First row */
1501 top = 0;
1502 #ifndef GENERIC_UMPC
1503 label = gtk_label_new(_("Name"));
1504 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1505 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1507 entry_name = gtk_combo_box_text_new_with_entry ();
1508 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1510 /* Next row */
1511 ++top;
1512 label = gtk_label_new(_("Value"));
1513 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
1514 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1516 entry_value = gtk_entry_new();
1517 gtk_table_attach(GTK_TABLE(table), entry_value, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1518 #else
1519 label = gtk_label_new(_("Name"));
1520 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1521 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1523 entry_name = gtk_combo_box_text_new_with_entry ();
1524 gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1526 /* Next row */
1527 ++top;
1528 label = gtk_label_new(_("Value"));
1529 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
1530 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1532 entry_value = gtk_entry_new();
1533 gtk_table_attach(GTK_TABLE(table), entry_value, 3, 4, 0, 1, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
1534 #endif
1535 gtk_combo_box_set_active(GTK_COMBO_BOX(entry_name), -1);
1536 if (prefs_common.addressbook_custom_attributes)
1537 combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(entry_name),
1538 prefs_common.addressbook_custom_attributes);
1539 /* Button box */
1540 vboxb = gtk_vbox_new( FALSE, 4 );
1541 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1543 vbuttonbox = gtk_vbutton_box_new();
1544 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1545 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1546 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1547 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1549 /* Buttons */
1550 buttonDel = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1551 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1553 buttonMod = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1554 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1556 buttonAdd = gtk_button_new_from_stock(GTK_STOCK_ADD);
1557 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1559 gtk_widget_set_sensitive(buttonDel,FALSE);
1560 gtk_widget_set_sensitive(buttonMod,FALSE);
1561 gtk_widget_set_sensitive(buttonAdd,FALSE);
1563 gtk_widget_show_all(vbox);
1565 /* Event handlers */
1566 g_signal_connect( G_OBJECT(view), "cursor-changed",
1567 G_CALLBACK( edit_person_attrib_cursor_changed ), NULL );
1568 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1569 G_CALLBACK( edit_person_attrib_delete ), NULL );
1570 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1571 G_CALLBACK( edit_person_attrib_modify ), NULL );
1572 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1573 G_CALLBACK( edit_person_attrib_add ), NULL );
1574 g_signal_connect(G_OBJECT(entry_name), "changed",
1575 G_CALLBACK(edit_person_entry_att_changed), NULL);
1576 g_signal_connect(G_OBJECT(entry_name), "key_press_event",
1577 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1578 g_signal_connect(G_OBJECT(entry_value), "key_press_event",
1579 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1581 personeditdlg.view_attrib = view;
1582 personeditdlg.entry_atname = entry_name;
1583 personeditdlg.entry_atvalue = entry_value;
1584 personeditdlg.attrib_add = buttonAdd;
1585 personeditdlg.attrib_del = buttonDel;
1586 personeditdlg.attrib_mod = buttonMod;
1589 static void addressbook_edit_person_create( GtkWidget *parent, gboolean *cancelled ) {
1590 if (prefs_common.addressbook_use_editaddress_dialog)
1591 addressbook_edit_person_dialog_create( cancelled );
1592 else
1593 addressbook_edit_person_widgetset_create( parent, cancelled );
1594 addressbook_edit_person_page_basic( PAGE_BASIC, _( "_User Data" ) );
1595 addressbook_edit_person_page_email( PAGE_EMAIL, _( "_Email Addresses" ) );
1596 #ifdef USE_LDAP
1597 if (personeditdlg.ldap)
1598 addressbook_edit_person_page_attrib_ldap(&personeditdlg, PAGE_ATTRIBUTES, _("O_ther Attributes"));
1599 else
1600 #endif
1601 addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "O_ther Attributes" ) );
1602 gtk_widget_show_all( personeditdlg.container );
1606 * Return list of email items.
1608 static GList *edit_person_build_email_list() {
1609 GtkWidget *view = personeditdlg.view_email;
1610 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
1611 GtkTreeIter iter;
1612 GList *listEMail = NULL;
1613 ItemEMail *email;
1615 if (!gtk_tree_model_get_iter_first(model, &iter))
1616 return NULL;
1618 do {
1619 gtk_tree_model_get(model, &iter, EMAIL_COL_PTR, &email, -1);
1620 listEMail = g_list_append( listEMail, email );
1621 } while (gtk_tree_model_iter_next(model, &iter));
1623 return listEMail;
1627 * Return list of attributes.
1629 static GList *edit_person_build_attrib_list() {
1630 GtkTreeModel *model = gtk_tree_view_get_model(
1631 GTK_TREE_VIEW(personeditdlg.view_attrib));
1632 GtkTreeIter iter;
1633 GList *listAttrib = NULL;
1634 UserAttribute *attrib;
1636 /* Iterate through all the rows, selecting the one that
1637 * matches. */
1638 if (!gtk_tree_model_get_iter_first(model, &iter))
1639 return FALSE;
1641 do {
1642 gtk_tree_model_get(model, &iter, ATTRIB_COL_PTR, &attrib, -1);
1643 listAttrib = g_list_append( listAttrib, attrib );
1644 } while (gtk_tree_model_iter_next(model, &iter));
1646 return listAttrib;
1649 static void update_sensitivity(void)
1651 gtk_widget_set_sensitive(personeditdlg.entry_name, !personeditdlg.read_only);
1652 gtk_widget_set_sensitive(personeditdlg.entry_first, !personeditdlg.read_only);
1653 gtk_widget_set_sensitive(personeditdlg.entry_last, !personeditdlg.read_only);
1654 gtk_widget_set_sensitive(personeditdlg.entry_nick, !personeditdlg.read_only && !personeditdlg.ldap);
1655 gtk_widget_set_sensitive(personeditdlg.entry_email, !personeditdlg.read_only);
1656 gtk_widget_set_sensitive(personeditdlg.entry_alias, !personeditdlg.read_only && !personeditdlg.ldap);
1657 gtk_widget_set_sensitive(personeditdlg.entry_remarks, !personeditdlg.read_only && !personeditdlg.ldap);
1658 gtk_widget_set_sensitive(personeditdlg.email_up, !personeditdlg.read_only);
1659 gtk_widget_set_sensitive(personeditdlg.email_down, !personeditdlg.read_only);
1660 gtk_widget_set_sensitive(personeditdlg.email_del, !personeditdlg.read_only);
1661 gtk_widget_set_sensitive(personeditdlg.email_mod, !personeditdlg.read_only);
1662 gtk_widget_set_sensitive(personeditdlg.email_add, !personeditdlg.read_only);
1663 gtk_widget_set_sensitive(personeditdlg.entry_atname, !personeditdlg.read_only);
1664 gtk_widget_set_sensitive(personeditdlg.entry_atvalue, !personeditdlg.read_only);
1665 gtk_widget_set_sensitive(personeditdlg.attrib_add, !personeditdlg.read_only);
1666 gtk_widget_set_sensitive(personeditdlg.attrib_del, !personeditdlg.read_only);
1667 gtk_widget_set_sensitive(personeditdlg.attrib_mod, !personeditdlg.read_only);
1670 static void addressbook_edit_person_flush_transient( void )
1672 ItemPerson *person = current_person;
1673 EditAddressPostUpdateCallback callback = edit_person_close_post_update_cb;
1675 /* reset transient data */
1676 current_abf = NULL;
1677 current_person = NULL;
1678 current_parent_folder = NULL;
1679 edit_person_close_post_update_cb = NULL;
1681 /* post action to perform on addressbook side */
1682 if (callback)
1683 callback( person );
1686 void addressbook_edit_person_invalidate( AddressBookFile *abf, ItemFolder *parent_folder,
1687 ItemPerson *person )
1689 if (current_abf == NULL &&
1690 current_person == NULL &&
1691 current_parent_folder == NULL)
1692 /* edit address form is already hidden */
1693 return;
1695 /* unconditional invalidation or invalidating the currently edited item */
1696 if ( ( abf == NULL && person == NULL && parent_folder == NULL )
1697 || (current_abf == abf ||
1698 current_person == person ||
1699 current_parent_folder == parent_folder))
1700 addressbook_edit_person_close( TRUE );
1703 static gboolean addressbook_edit_person_close( gboolean cancelled )
1705 GList *listEMail = NULL;
1706 GList *listAttrib = NULL;
1707 GError *error = NULL;
1708 GtkTreeModel *model;
1710 listEMail = edit_person_build_email_list();
1711 listAttrib = edit_person_build_attrib_list();
1712 if( cancelled ) {
1713 addritem_free_list_email( listEMail );
1714 addritem_free_list_attribute( listAttrib );
1715 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1716 gtk_list_store_clear(GTK_LIST_STORE(model));
1717 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1718 gtk_list_store_clear(GTK_LIST_STORE(model));
1720 if (!prefs_common.addressbook_use_editaddress_dialog)
1721 gtk_widget_hide( personeditdlg.container );
1723 /* no callback, as we're discarding the form */
1724 edit_person_close_post_update_cb = NULL;
1725 addressbook_edit_person_flush_transient();
1726 current_person = NULL;
1728 /* set focus to the address list (this is done by the post_update_cb usually) */
1729 addressbook_address_list_set_focus();
1730 return FALSE;
1733 if( current_person && current_abf ) {
1734 /* Update email/attribute list for existing current_person */
1735 addrbook_update_address_list( current_abf, current_person, listEMail );
1736 addrbook_update_attrib_list( current_abf, current_person, listAttrib );
1738 else {
1739 /* Create new current_person and email/attribute list */
1740 if( ! cancelled && current_abf ) {
1741 current_person = addrbook_add_address_list( current_abf, current_parent_folder, listEMail );
1742 addrbook_add_attrib_list( current_abf, current_person, listAttrib );
1745 listEMail = NULL;
1746 listAttrib = NULL;
1748 if(!cancelled && current_person != NULL) {
1749 /* Set current_person stuff */
1751 gchar *name;
1752 gchar *cn = edit_person_get_common_name_from_widgets();
1754 addritem_person_set_common_name( current_person, cn );
1755 g_free( cn );
1757 if (personeditdlg.picture_set) {
1758 GdkPixbuf * pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(personeditdlg.image));
1760 if (!current_person->picture)
1761 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1762 ADDRITEM_ID(current_person), ".png", NULL );
1763 else
1764 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1765 current_person->picture, ".png", NULL );
1767 gdk_pixbuf_save(pixbuf, name, "png", &error, NULL);
1768 if (error) {
1769 alertpanel_error(_("Failed to save image: \n%s"),
1770 error->message);
1771 g_error_free(error);
1772 } else {
1773 debug_print("saved picture to %s\n", name);
1775 if (!current_person->picture)
1776 addritem_person_set_picture( current_person, ADDRITEM_ID(current_person) ) ;
1777 g_free( name );
1778 } else {
1779 if (!current_person->picture)
1780 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1781 ADDRITEM_ID(current_person), ".png", NULL );
1782 else
1783 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1784 current_person->picture, ".png", NULL );
1785 claws_unlink(name);
1786 g_free(name);
1788 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1789 addritem_person_set_first_name( current_person, name );
1790 g_free( name );
1791 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1792 addritem_person_set_last_name( current_person, name );
1793 g_free( name );
1794 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1795 addritem_person_set_nick_name( current_person, name );
1796 g_free( name );
1799 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1800 gtk_list_store_clear(GTK_LIST_STORE(model));
1801 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1802 gtk_list_store_clear(GTK_LIST_STORE(model));
1804 if (!prefs_common.addressbook_use_editaddress_dialog)
1805 gtk_widget_hide( personeditdlg.container );
1807 addressbook_edit_person_flush_transient();
1809 return TRUE;
1813 * Edit person.
1814 * Enter: abf Address book.
1815 * parent Parent folder for person (or NULL if adding to root folder). Argument is
1816 * only required for new objects).
1817 * person Person to edit, or NULL for a new person object.
1818 * pgMail If TRUE, E-Mail page will be activated.
1819 * Return: Edited object, or NULL if cancelled.*/
1820 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent_folder, ItemPerson *person,
1821 gboolean pgMail, GtkWidget *parent_container,
1822 void (*post_update_cb) (ItemPerson *person),
1823 gboolean get_focus) {
1824 static gboolean cancelled;
1825 GError *error = NULL;
1826 GdkPixbuf *pixbuf = NULL;
1827 GtkTreeModel *model;
1828 GtkTreeSelection *sel;
1829 GtkTreeIter iter;
1831 /* set transient data */
1832 current_abf = abf;
1833 current_person = person;
1834 current_parent_folder = parent_folder;
1835 edit_person_close_post_update_cb = post_update_cb;
1836 personeditdlg.ldap = (abf && abf->type == ADBOOKTYPE_LDAP)? TRUE : FALSE;
1838 if( personeditdlg.container ) {
1839 gtk_widget_destroy(personeditdlg.container);
1840 personeditdlg.container = NULL;
1842 addressbook_edit_person_create(parent_container, &cancelled);
1844 /* typically, get focus when dialog mode is enabled, or when editing a new address */
1845 if( get_focus ) {
1846 gtk_widget_grab_focus(personeditdlg.ok_btn);
1847 gtk_widget_grab_focus(personeditdlg.entry_name);
1850 personeditdlg.read_only = (current_abf == NULL);
1851 update_sensitivity();
1853 gtk_widget_show(personeditdlg.container);
1854 if (prefs_common.addressbook_use_editaddress_dialog)
1855 manage_window_set_transient(GTK_WINDOW(personeditdlg.container));
1856 else
1857 if (get_focus)
1858 addressbook_address_list_disable_some_actions();
1860 /* Clear all fields */
1861 edit_person_status_show( "" );
1863 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1864 gtk_list_store_clear(GTK_LIST_STORE(model));
1865 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1866 gtk_list_store_clear(GTK_LIST_STORE(model));
1868 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1869 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1870 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1871 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1873 personeditdlg.editNew = FALSE;
1874 if( current_person ) {
1875 gchar *filename = NULL;
1877 if( ADDRITEM_NAME(current_person) )
1878 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1880 cm_menu_set_sensitive("EditAddressPopup/SetPicture", !personeditdlg.ldap);
1881 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", !personeditdlg.ldap);
1882 if( current_person->picture ) {
1883 filename = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1884 current_person->picture, ".png", NULL );
1885 if (is_file_exist(filename)) {
1886 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
1887 if (error) {
1888 debug_print("Failed to import image: %s\n",
1889 error->message);
1890 g_error_free(error);
1891 goto no_img;
1893 personeditdlg.picture_set = TRUE;
1894 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", !personeditdlg.ldap && personeditdlg.picture_set);
1895 } else {
1896 goto no_img;
1898 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
1899 } else {
1900 no_img:
1901 addressbook_edit_person_clear_picture();
1904 g_free(filename);
1905 if (pixbuf) {
1906 g_object_unref(pixbuf);
1907 pixbuf = NULL;
1910 if( current_person->firstName )
1911 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), current_person->firstName );
1912 if( current_person->lastName )
1913 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), current_person->lastName );
1914 if( current_person->nickName )
1915 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), current_person->nickName );
1916 edit_person_load_email( current_person );
1917 edit_person_load_attrib( current_person );
1918 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_atvalue), "");
1920 else {
1921 personeditdlg.editNew = TRUE;
1924 /* Select appropriate start page */
1925 if( pgMail ) {
1926 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1928 else {
1929 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1932 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(personeditdlg.view_email));
1933 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1934 if (gtk_tree_model_get_iter_first(model, &iter)) {
1935 gtk_tree_selection_select_iter(sel, &iter);
1936 edit_person_email_cursor_changed(
1937 GTK_TREE_VIEW(personeditdlg.view_email), NULL);
1940 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(personeditdlg.view_attrib));
1941 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1942 if (gtk_tree_model_get_iter_first(model, &iter))
1943 gtk_tree_selection_select_iter(sel, &iter);
1944 edit_person_attrib_cursor_changed(
1945 GTK_TREE_VIEW(personeditdlg.view_attrib), NULL);
1947 edit_person_email_clear( NULL );
1948 edit_person_attrib_clear( NULL );
1950 if (prefs_common.addressbook_use_editaddress_dialog) {
1951 gtk_main();
1952 gtk_widget_hide( personeditdlg.container );
1954 if (!addressbook_edit_person_close( cancelled )) {
1955 return NULL;
1959 return person;
1962 void addressbook_edit_reload_attr_list( void )
1964 if (personeditdlg.entry_atname) {
1965 combobox_unset_popdown_strings(GTK_COMBO_BOX_TEXT(personeditdlg.entry_atname));
1966 if (prefs_common.addressbook_custom_attributes)
1967 combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(personeditdlg.entry_atname),
1968 prefs_common.addressbook_custom_attributes);
1973 * End of Source.