Fix CID 1596595: Resource leak
[claws.git] / src / editaddress.c
blob10114debec9350c43738a6938025dfceb01a9d51
1 /*
2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2022 the Claws Mail team and Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 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 NULL, _("_Cancel"), NULL, _("_OK"), NULL, 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 gtk_window_get_size(GTK_WINDOW(widget),
784 &prefs_common.addressbookeditpersonwin_width, &prefs_common.addressbookeditpersonwin_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_box_new(GTK_ORIENTATION_VERTICAL, 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_box_new(GTK_ORIENTATION_VERTICAL, 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, NULL, _("_Cancel"),
816 &ok_btn, NULL, _("_OK"),
817 NULL, NULL, NULL);
818 else
819 gtkut_stock_with_text_button_set_create(&hbbox,
820 &cancel_btn, NULL, _("Discard"),
821 &ok_btn, NULL, _("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), TRUE);
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_box_new(GTK_ORIENTATION_HORIZONTAL, 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_window_set_default_size(GTK_WINDOW(window),
881 prefs_common.addressbookeditpersonwin_width,
882 prefs_common.addressbookeditpersonwin_height);
884 personeditdlg.container = window;
885 personeditdlg.statusbar = statusbar;
886 personeditdlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit Person Dialog" );
890 /* parent must be a box */
891 static void addressbook_edit_person_widgetset_create( GtkWidget *parent, gboolean *cancelled )
893 GtkWidget *vbox;
894 GtkWidget *label;
896 if ( parent == NULL )
897 g_warning("addressbook_edit_person_widgetset_create: parent is NULL");
899 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
900 gtk_box_pack_end(GTK_BOX(parent), vbox, TRUE, TRUE, 0);
902 label = gtk_label_new(_("Edit Person Data"));
903 gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER);
904 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
906 addressbook_edit_person_widgets_create(vbox, cancelled);
908 gtk_widget_set_size_request(vbox, EDITPERSON_WIDTH, EDITPERSON_HEIGHT);
910 personeditdlg.container = vbox;
911 personeditdlg.title = label;
912 personeditdlg.statusbar = NULL;
913 personeditdlg.status_cid = 0;
916 void addressbook_edit_person_widgetset_hide( void )
918 if ( personeditdlg.container )
919 gtk_widget_hide( personeditdlg.container );
922 static void addressbook_edit_person_set_picture(void)
924 GError *error = NULL;
925 gchar *filename;
926 int width, height, scalewidth, scaleheight;
928 if (personeditdlg.ldap)
929 return;
931 if ( (filename = filesel_select_file_open(_("Choose a picture"), NULL)) ) {
932 GdkPixbuf *pixbuf = NULL;
933 gdk_pixbuf_get_file_info(filename, &width, &height);
935 if ( width > 128 || height > 128 ) {
936 if (width > height) {
937 scaleheight = (height * 128) / width;
938 scalewidth = 128;
940 else {
941 scalewidth = (width * 128) / height;
942 scaleheight = 128;
944 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
945 scalewidth, scaleheight, TRUE, &error);
946 } else {
947 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
949 if (error) {
950 alertpanel_error(_("Failed to import image: \n%s"),
951 error->message);
952 g_error_free(error);
953 error = NULL;
954 /* keep the previous picture if any */
955 g_free(filename);
956 if (pixbuf)
957 g_object_unref(pixbuf);
958 return;
960 personeditdlg.picture_set = TRUE;
961 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", personeditdlg.picture_set);
962 g_free(filename);
963 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
964 g_object_unref(pixbuf);
968 static void addressbook_edit_person_clear_picture(void)
970 GdkPixbuf *pixbuf;
972 stock_pixbuf_gdk(STOCK_PIXMAP_ANONYMOUS, &pixbuf);
973 personeditdlg.picture_set = FALSE;
974 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", personeditdlg.picture_set);
975 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
978 static void addressbook_edit_person_set_picture_menu_cb (GtkAction *action, gpointer data)
980 addressbook_edit_person_set_picture();
983 static void addressbook_edit_person_unset_picture_menu_cb (GtkAction *action, gpointer data)
985 addressbook_edit_person_clear_picture();
988 static GtkWidget *editaddr_popup_menu = NULL;
989 static GtkActionEntry editaddr_popup_entries[] =
991 {"EditAddressPopup", NULL, "EditAddressPopup", NULL, NULL, NULL },
992 {"EditAddressPopup/SetPicture", NULL, N_("_Set picture"), NULL, NULL, G_CALLBACK(addressbook_edit_person_set_picture_menu_cb) },
993 {"EditAddressPopup/UnsetPicture", NULL, N_("_Unset picture"), NULL, NULL, G_CALLBACK(addressbook_edit_person_unset_picture_menu_cb) },
996 static void addressbook_edit_person_set_picture_cb(GtkWidget *widget,
997 GdkEventButton *event, gpointer data)
999 if (event->button == 1) {
1000 addressbook_edit_person_set_picture();
1001 } else {
1002 gtk_menu_popup_at_pointer(GTK_MENU(editaddr_popup_menu), NULL);
1006 static gboolean addressbook_edit_person_picture_popup_menu(GtkWidget *widget, gpointer data)
1008 GdkEventButton event;
1010 event.button = 3;
1011 event.time = gtk_get_current_event_time();
1013 addressbook_edit_person_set_picture_cb(NULL, &event, data);
1015 return TRUE;
1018 static void addressbook_edit_person_page_basic( gint pageNum, gchar *pageLbl ) {
1019 GtkWidget *vbox;
1020 GtkWidget *hbox;
1021 GtkWidget *table;
1022 GtkWidget *label;
1023 GtkWidget *ebox_picture;
1024 GtkWidget *frame_picture;
1025 GtkWidget *entry_name;
1026 GtkWidget *entry_fn;
1027 GtkWidget *entry_ln;
1028 GtkWidget *entry_nn;
1029 const gchar *locale;
1030 gint top = 0;
1032 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 20 );
1033 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8 );
1035 gtk_widget_show( vbox );
1037 if (!editaddr_popup_menu) {
1038 cm_menu_create_action_group("EditAddressPopup", editaddr_popup_entries,
1039 G_N_ELEMENTS(editaddr_popup_entries), (gpointer)NULL);
1040 MENUITEM_ADDUI("/Menus", "EditAddressPopup", "EditAddressPopup", GTK_UI_MANAGER_MENU)
1041 MENUITEM_ADDUI("/Menus/EditAddressPopup", "SetPicture", "EditAddressPopup/SetPicture", GTK_UI_MANAGER_MENUITEM)
1042 MENUITEM_ADDUI("/Menus/EditAddressPopup", "UnsetPicture", "EditAddressPopup/UnsetPicture", GTK_UI_MANAGER_MENUITEM)
1044 editaddr_popup_menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
1045 gtk_ui_manager_get_widget(gtkut_ui_manager(), "/Menus/EditAddressPopup")) );
1047 /* User's picture */
1048 ebox_picture = gtk_event_box_new();
1049 frame_picture = gtk_frame_new(_("Photo"));
1051 /* Room for a photo */
1052 personeditdlg.image = gtk_image_new();
1053 addressbook_edit_person_clear_picture();
1055 gtk_container_add(GTK_CONTAINER(ebox_picture), personeditdlg.image);
1056 gtk_container_add(GTK_CONTAINER(frame_picture), ebox_picture);
1057 gtk_container_add(GTK_CONTAINER( personeditdlg.notebook ), hbox );
1058 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1059 gtk_container_set_border_width( GTK_CONTAINER (hbox), BORDER_WIDTH );
1061 label = gtk_label_new_with_mnemonic( pageLbl );
1062 gtk_widget_show( label );
1064 gtk_box_pack_start(GTK_BOX(hbox), frame_picture, TRUE, TRUE, 0);
1066 gtk_notebook_set_tab_label(
1067 GTK_NOTEBOOK( personeditdlg.notebook ),
1068 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1070 g_signal_connect(G_OBJECT(ebox_picture), "popup-menu",
1071 G_CALLBACK(addressbook_edit_person_picture_popup_menu), NULL);
1072 g_signal_connect(G_OBJECT(ebox_picture), "button_press_event",
1073 G_CALLBACK(addressbook_edit_person_set_picture_cb), NULL);
1075 table = gtk_grid_new();
1077 #define ATTACH_ROW(text, entry) \
1079 label = gtk_label_new(text); \
1080 gtk_grid_attach(GTK_GRID(table), label, 0, top, 1, 1); \
1081 gtk_label_set_xalign(GTK_LABEL(label), 0.0); \
1083 entry = gtk_entry_new(); \
1084 gtk_grid_attach(GTK_GRID(table), entry, 1, top, 1, 1); \
1085 gtk_widget_set_hexpand(entry, TRUE); \
1086 gtk_widget_set_halign(entry, GTK_ALIGN_FILL); \
1087 top++; \
1090 #define ATTACH_HIDDEN_ROW(text, entry) \
1092 entry = gtk_entry_new(); \
1095 #ifndef GENERIC_UMPC
1096 ATTACH_ROW(_("Display Name"), entry_name);
1097 #else
1098 ATTACH_HIDDEN_ROW(_("Display Name"), entry_name);
1099 #endif
1100 locale = conv_get_current_locale();
1101 if (locale &&
1102 (!g_ascii_strncasecmp(locale, "hu", 2) ||
1103 !g_ascii_strncasecmp(locale, "ja", 2) ||
1104 !g_ascii_strncasecmp(locale, "ko", 2) ||
1105 !g_ascii_strncasecmp(locale, "vi", 2) ||
1106 !g_ascii_strncasecmp(locale, "zh", 2))) {
1107 ATTACH_ROW(_("Last Name"), entry_ln);
1108 ATTACH_ROW(_("First Name"), entry_fn);
1109 } else {
1110 ATTACH_ROW(_("First Name"), entry_fn);
1111 ATTACH_ROW(_("Last Name"), entry_ln);
1113 #ifndef GENERIC_UMPC
1114 ATTACH_ROW(_("Nickname"), entry_nn);
1115 #else
1116 ATTACH_HIDDEN_ROW(_("Nickname"), entry_nn);
1117 #endif
1119 #undef ATTACH_ROW
1120 #undef ATTACH_HIDDEN_ROW
1121 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
1122 gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1123 gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
1124 gtk_grid_set_row_spacing(GTK_GRID(table), 15);
1125 gtk_grid_set_column_spacing(GTK_GRID(table), 8);
1127 gtk_widget_show_all(vbox);
1128 personeditdlg.entry_name = entry_name;
1129 personeditdlg.entry_first = entry_fn;
1130 personeditdlg.entry_last = entry_ln;
1131 personeditdlg.entry_nick = entry_nn;
1134 static gboolean email_adding = FALSE, email_saving = FALSE;
1136 static void edit_person_entry_email_changed (GtkWidget *entry, gpointer data)
1138 GtkTreeModel *model = gtk_tree_view_get_model(
1139 GTK_TREE_VIEW(personeditdlg.view_email));
1140 gboolean non_empty = (gtk_tree_model_iter_n_children(model, NULL) > 0);
1142 if (personeditdlg.read_only)
1143 return;
1145 if (gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)) == NULL
1146 || strlen(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email))) == 0) {
1147 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
1148 gtk_widget_set_sensitive(personeditdlg.email_mod,FALSE);
1149 email_adding = FALSE;
1150 email_saving = FALSE;
1151 } else if (list_find_email(gtk_entry_get_text(GTK_ENTRY(personeditdlg.entry_email)))) {
1152 gtk_widget_set_sensitive(personeditdlg.email_add,FALSE);
1153 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
1154 email_adding = FALSE;
1155 email_saving = non_empty;
1156 } else {
1157 gtk_widget_set_sensitive(personeditdlg.email_add,TRUE);
1158 gtk_widget_set_sensitive(personeditdlg.email_mod,non_empty);
1159 email_adding = TRUE;
1160 email_saving = non_empty;
1164 static gboolean edit_person_entry_email_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1166 if (event && (event->keyval == GDK_KEY_KP_Enter ||
1167 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 GtkListStore *store;
1197 GtkTreeViewColumn *col;
1198 GtkCellRenderer *rdr;
1199 GtkTreeSelection *sel;
1201 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8 );
1202 gtk_widget_show( vbox );
1203 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1204 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1206 label = gtk_label_new_with_mnemonic( pageLbl );
1207 gtk_widget_show( label );
1208 gtk_notebook_set_tab_label(
1209 GTK_NOTEBOOK( personeditdlg.notebook ),
1210 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1212 /* Split into two areas */
1213 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0 );
1214 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1216 /* Address list */
1217 vboxl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4 );
1218 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1219 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1221 scrollwin = gtk_scrolled_window_new( NULL, NULL );
1222 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
1223 GTK_POLICY_AUTOMATIC,
1224 GTK_POLICY_AUTOMATIC);
1225 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrollwin), TRUE);
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_grid_new();
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_grid_set_row_spacing(GTK_GRID(table), 4);
1277 gtk_grid_set_column_spacing(GTK_GRID(table), 4);
1279 entry_email = gtk_entry_new();
1280 entry_alias = gtk_entry_new();
1281 entry_remarks = gtk_entry_new();
1283 /* First row */
1284 label = gtk_label_new(_("Email Address"));
1285 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1286 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
1288 gtk_grid_attach(GTK_GRID(table), entry_email, 1, 0, 1, 1);
1289 gtk_widget_set_hexpand(entry_email, TRUE);
1290 gtk_widget_set_halign(entry_email, GTK_ALIGN_FILL);
1292 #ifndef GENERIC_UMPC
1293 /* Next row */
1294 label = gtk_label_new(_("Alias"));
1295 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1296 gtk_grid_attach(GTK_GRID(table), label, 0, 1, 1, 1);
1298 gtk_grid_attach(GTK_GRID(table), entry_alias, 1, 1, 1, 1);
1299 gtk_widget_set_hexpand(entry_alias, TRUE);
1300 gtk_widget_set_halign(entry_alias, GTK_ALIGN_FILL);
1302 /* Next row */
1303 label = gtk_label_new(_("Remarks"));
1304 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1305 gtk_grid_attach(GTK_GRID(table), label, 0, 2, 1, 1);
1307 gtk_grid_attach(GTK_GRID(table), entry_remarks, 1, 2, 1, 1);
1308 gtk_widget_set_hexpand(entry_remarks, TRUE);
1309 gtk_widget_set_halign(entry_remarks, GTK_ALIGN_FILL);
1310 #endif
1312 /* Button box */
1313 vboxb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4 );
1314 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1316 vbuttonbox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
1317 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1318 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1319 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1320 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1322 /* Buttons */
1323 buttonUp = gtkut_stock_button("go-up", _("_Up"));
1324 buttonDown = gtkut_stock_button("go-down", _("_Down"));
1325 buttonDel = gtkut_stock_button("edit-delete", _("D_elete"));
1326 buttonMod = gtkut_stock_button("document-save", _("_Save"));
1327 buttonAdd = gtkut_stock_button("list-add", _("_Add"));
1330 #ifndef GENERIC_UMPC
1331 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonUp );
1333 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDown );
1334 #endif
1335 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1337 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1339 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1341 gtk_widget_show_all(vbox);
1343 /* Event handlers */
1344 g_signal_connect( G_OBJECT(view), "cursor-changed",
1345 G_CALLBACK( edit_person_email_cursor_changed ), NULL );
1346 g_signal_connect( G_OBJECT(buttonUp), "clicked",
1347 G_CALLBACK( edit_person_email_move_up ), NULL );
1348 g_signal_connect( G_OBJECT(buttonDown), "clicked",
1349 G_CALLBACK( edit_person_email_move_down ), NULL );
1350 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1351 G_CALLBACK( edit_person_email_delete ), NULL );
1352 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1353 G_CALLBACK( edit_person_email_modify ), NULL );
1354 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1355 G_CALLBACK( edit_person_email_add ), NULL );
1356 g_signal_connect(G_OBJECT(entry_email), "changed",
1357 G_CALLBACK(edit_person_entry_email_changed), NULL);
1358 g_signal_connect(G_OBJECT(entry_email), "key_press_event",
1359 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1360 g_signal_connect(G_OBJECT(entry_alias), "key_press_event",
1361 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1362 g_signal_connect(G_OBJECT(entry_remarks), "key_press_event",
1363 G_CALLBACK(edit_person_entry_email_pressed), NULL);
1365 personeditdlg.view_email = view;
1366 personeditdlg.entry_email = entry_email;
1367 personeditdlg.entry_alias = entry_alias;
1368 personeditdlg.entry_remarks = entry_remarks;
1369 personeditdlg.email_up = buttonUp;
1370 personeditdlg.email_down = buttonDown;
1371 personeditdlg.email_del = buttonDel;
1372 personeditdlg.email_mod = buttonMod;
1373 personeditdlg.email_add = buttonAdd;
1376 static gboolean attrib_adding = FALSE, attrib_saving = FALSE;
1378 static void edit_person_entry_att_changed (GtkWidget *entry, gpointer data)
1380 GtkTreeModel *model = gtk_tree_view_get_model(
1381 GTK_TREE_VIEW(personeditdlg.view_attrib));
1382 gboolean non_empty = (gtk_tree_model_iter_n_children(model, NULL) > 0);
1383 const gchar *atname;
1385 if (personeditdlg.read_only || personeditdlg.ldap)
1386 return;
1388 atname = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((personeditdlg.entry_atname)))));
1389 if ( atname == NULL
1390 || strlen(atname) == 0) {
1391 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1392 gtk_widget_set_sensitive(personeditdlg.attrib_mod,FALSE);
1393 attrib_adding = FALSE;
1394 attrib_saving = FALSE;
1395 } else if (list_find_attribute(atname)) {
1396 gtk_widget_set_sensitive(personeditdlg.attrib_add,FALSE);
1397 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1398 attrib_adding = FALSE;
1399 attrib_saving = non_empty;
1400 } else {
1401 gtk_widget_set_sensitive(personeditdlg.attrib_add,TRUE);
1402 gtk_widget_set_sensitive(personeditdlg.attrib_mod,non_empty);
1403 attrib_adding = TRUE;
1404 attrib_saving = non_empty;
1408 static gboolean edit_person_entry_att_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
1410 if (event && (event->keyval == GDK_KEY_KP_Enter ||
1411 event->keyval == GDK_KEY_Return)) {
1412 if (attrib_saving)
1413 edit_person_attrib_modify(NULL);
1414 else if (attrib_adding)
1415 edit_person_attrib_add(NULL);
1417 return FALSE;
1420 static void addressbook_edit_person_page_attrib( gint pageNum, gchar *pageLbl ) {
1421 GtkWidget *vbox;
1422 GtkWidget *hbox;
1423 GtkWidget *vboxl;
1424 GtkWidget *vboxb;
1425 GtkWidget *vbuttonbox;
1426 GtkWidget *buttonDel;
1427 GtkWidget *buttonMod;
1428 GtkWidget *buttonAdd;
1430 GtkWidget *table;
1431 GtkWidget *label;
1432 GtkWidget *scrollwin;
1433 GtkWidget *view;
1434 GtkWidget *entry_name;
1435 GtkWidget *entry_value;
1436 GtkListStore *store;
1437 GtkTreeViewColumn *col;
1438 GtkCellRenderer *rdr;
1439 GtkTreeSelection *sel;
1441 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8 );
1442 gtk_widget_show( vbox );
1443 gtk_container_add( GTK_CONTAINER( personeditdlg.notebook ), vbox );
1444 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
1446 label = gtk_label_new_with_mnemonic( pageLbl );
1447 gtk_widget_show( label );
1448 gtk_notebook_set_tab_label(
1449 GTK_NOTEBOOK( personeditdlg.notebook ),
1450 gtk_notebook_get_nth_page( GTK_NOTEBOOK( personeditdlg.notebook ), pageNum ), label );
1452 /* Split into two areas */
1453 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0 );
1454 gtk_container_add( GTK_CONTAINER( vbox ), hbox );
1456 /* Attribute list */
1457 vboxl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4 );
1458 gtk_container_add( GTK_CONTAINER( hbox ), vboxl );
1459 gtk_container_set_border_width( GTK_CONTAINER(vboxl), 4 );
1461 scrollwin = gtk_scrolled_window_new( NULL, NULL );
1462 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
1463 GTK_POLICY_AUTOMATIC,
1464 GTK_POLICY_AUTOMATIC);
1465 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrollwin), TRUE);
1467 store = gtk_list_store_new(ATTRIB_N_COLS,
1468 G_TYPE_STRING, G_TYPE_STRING,
1469 G_TYPE_POINTER, -1);
1471 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1472 g_object_unref(store);
1473 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), TRUE);
1474 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1475 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1477 rdr = gtk_cell_renderer_text_new();
1478 col = gtk_tree_view_column_new_with_attributes(_("Name"), rdr,
1479 "markup", ATTRIB_COL_NAME, NULL);
1480 gtk_tree_view_column_set_min_width(col, ATTRIB_COL_WIDTH_NAME);
1481 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1483 col = gtk_tree_view_column_new_with_attributes(_("Value"), rdr,
1484 "markup", ATTRIB_COL_VALUE, NULL);
1485 gtk_tree_view_column_set_min_width(col, ATTRIB_COL_WIDTH_VALUE);
1486 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1488 gtk_container_add( GTK_CONTAINER(scrollwin), view );
1490 /* Data entry area */
1491 table = gtk_grid_new();
1492 gtk_box_pack_start(GTK_BOX(vboxl), table, FALSE, FALSE, 0);
1493 gtk_container_add( GTK_CONTAINER(vboxl), scrollwin );
1494 gtk_container_set_border_width( GTK_CONTAINER(table), 4 );
1495 gtk_grid_set_row_spacing(GTK_GRID(table), 4);
1496 gtk_grid_set_column_spacing(GTK_GRID(table), 4);
1498 /* First row */
1499 #ifndef GENERIC_UMPC
1500 label = gtk_label_new(_("Name"));
1501 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1502 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
1504 entry_name = gtk_combo_box_text_new_with_entry ();
1505 gtk_grid_attach(GTK_GRID(table), entry_name, 1, 0, 1, 1);
1506 gtk_widget_set_hexpand(entry_name, TRUE);
1507 gtk_widget_set_halign(entry_name, GTK_ALIGN_FILL);
1509 /* Next row */
1510 label = gtk_label_new(_("Value"));
1511 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1512 gtk_grid_attach(GTK_GRID(table), label, 0, 1, 1, 1);
1514 entry_value = gtk_entry_new();
1515 gtk_grid_attach(GTK_GRID(table), entry_value, 1, 1, 1, 1);
1516 gtk_widget_set_hexpand(entry_value, TRUE);
1517 gtk_widget_set_halign(entry_value, GTK_ALIGN_FILL);
1518 #else
1519 label = gtk_label_new(_("Name"));
1520 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1521 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
1523 entry_name = gtk_combo_box_text_new_with_entry ();
1524 gtk_grid_attach(GTK_GRID(table), entry_name, 1, 0, 1, 1);
1525 gtk_widget_set_hexpand(entry_name, TRUE);
1526 gtk_widget_set_halign(entry_name, GTK_ALIGN_FILL);
1528 /* Next row */
1529 label = gtk_label_new(_("Value"));
1530 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
1531 gtk_grid_attach(GTK_GRID(table), label, 2, 0, 1, 1);
1533 entry_value = gtk_entry_new();
1534 gtk_grid_attach(GTK_GRID(table), entry_value, 3, 0, 1, 1);
1535 gtk_widget_set_hexpand(entry_value, TRUE);
1536 gtk_widget_set_halign(entry_value, GTK_ALIGN_FILL);
1537 #endif
1538 gtk_combo_box_set_active(GTK_COMBO_BOX(entry_name), -1);
1539 if (prefs_common.addressbook_custom_attributes)
1540 combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(entry_name),
1541 prefs_common.addressbook_custom_attributes);
1542 /* Button box */
1543 vboxb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4 );
1544 gtk_box_pack_start(GTK_BOX(hbox), vboxb, FALSE, FALSE, 2);
1546 vbuttonbox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
1547 gtk_button_box_set_layout( GTK_BUTTON_BOX(vbuttonbox), GTK_BUTTONBOX_START );
1548 gtk_box_set_spacing( GTK_BOX(vbuttonbox), 8 );
1549 gtk_container_set_border_width( GTK_CONTAINER(vbuttonbox), 4 );
1550 gtk_container_add( GTK_CONTAINER(vboxb), vbuttonbox );
1552 /* Buttons */
1553 buttonDel = gtkut_stock_button("edit-delete", _("D_elete"));
1554 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonDel );
1556 buttonMod = gtkut_stock_button("document-save", _("_Save"));
1557 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonMod );
1559 buttonAdd = gtkut_stock_button("list-add", _("_Add"));
1560 gtk_container_add( GTK_CONTAINER(vbuttonbox), buttonAdd );
1562 gtk_widget_set_sensitive(buttonDel,FALSE);
1563 gtk_widget_set_sensitive(buttonMod,FALSE);
1564 gtk_widget_set_sensitive(buttonAdd,FALSE);
1566 gtk_widget_show_all(vbox);
1568 /* Event handlers */
1569 g_signal_connect( G_OBJECT(view), "cursor-changed",
1570 G_CALLBACK( edit_person_attrib_cursor_changed ), NULL );
1571 g_signal_connect( G_OBJECT(buttonDel), "clicked",
1572 G_CALLBACK( edit_person_attrib_delete ), NULL );
1573 g_signal_connect( G_OBJECT(buttonMod), "clicked",
1574 G_CALLBACK( edit_person_attrib_modify ), NULL );
1575 g_signal_connect( G_OBJECT(buttonAdd), "clicked",
1576 G_CALLBACK( edit_person_attrib_add ), NULL );
1577 g_signal_connect(G_OBJECT(entry_name), "changed",
1578 G_CALLBACK(edit_person_entry_att_changed), NULL);
1579 g_signal_connect(G_OBJECT(entry_name), "key_press_event",
1580 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1581 g_signal_connect(G_OBJECT(entry_value), "key_press_event",
1582 G_CALLBACK(edit_person_entry_att_pressed), NULL);
1584 personeditdlg.view_attrib = view;
1585 personeditdlg.entry_atname = entry_name;
1586 personeditdlg.entry_atvalue = entry_value;
1587 personeditdlg.attrib_add = buttonAdd;
1588 personeditdlg.attrib_del = buttonDel;
1589 personeditdlg.attrib_mod = buttonMod;
1592 static void addressbook_edit_person_create( GtkWidget *parent, gboolean *cancelled ) {
1593 if (prefs_common.addressbook_use_editaddress_dialog)
1594 addressbook_edit_person_dialog_create( cancelled );
1595 else
1596 addressbook_edit_person_widgetset_create( parent, cancelled );
1597 addressbook_edit_person_page_basic( PAGE_BASIC, _( "_User Data" ) );
1598 addressbook_edit_person_page_email( PAGE_EMAIL, _( "_Email Addresses" ) );
1599 #ifdef USE_LDAP
1600 if (personeditdlg.ldap)
1601 addressbook_edit_person_page_attrib_ldap(&personeditdlg, PAGE_ATTRIBUTES, _("O_ther Attributes"));
1602 else
1603 #endif
1604 addressbook_edit_person_page_attrib( PAGE_ATTRIBUTES, _( "O_ther Attributes" ) );
1605 gtk_widget_show_all( personeditdlg.container );
1609 * Return list of email items.
1611 static GList *edit_person_build_email_list() {
1612 GtkWidget *view = personeditdlg.view_email;
1613 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
1614 GtkTreeIter iter;
1615 GList *listEMail = NULL;
1616 ItemEMail *email;
1618 if (!gtk_tree_model_get_iter_first(model, &iter))
1619 return NULL;
1621 do {
1622 gtk_tree_model_get(model, &iter, EMAIL_COL_PTR, &email, -1);
1623 listEMail = g_list_append( listEMail, email );
1624 } while (gtk_tree_model_iter_next(model, &iter));
1626 return listEMail;
1630 * Return list of attributes.
1632 static GList *edit_person_build_attrib_list() {
1633 GtkTreeModel *model = gtk_tree_view_get_model(
1634 GTK_TREE_VIEW(personeditdlg.view_attrib));
1635 GtkTreeIter iter;
1636 GList *listAttrib = NULL;
1637 UserAttribute *attrib;
1639 /* Iterate through all the rows, selecting the one that
1640 * matches. */
1641 if (!gtk_tree_model_get_iter_first(model, &iter))
1642 return FALSE;
1644 do {
1645 gtk_tree_model_get(model, &iter, ATTRIB_COL_PTR, &attrib, -1);
1646 listAttrib = g_list_append( listAttrib, attrib );
1647 } while (gtk_tree_model_iter_next(model, &iter));
1649 return listAttrib;
1652 static void update_sensitivity(void)
1654 gtk_widget_set_sensitive(personeditdlg.entry_name, !personeditdlg.read_only);
1655 gtk_widget_set_sensitive(personeditdlg.entry_first, !personeditdlg.read_only);
1656 gtk_widget_set_sensitive(personeditdlg.entry_last, !personeditdlg.read_only);
1657 gtk_widget_set_sensitive(personeditdlg.entry_nick, !personeditdlg.read_only && !personeditdlg.ldap);
1658 gtk_widget_set_sensitive(personeditdlg.entry_email, !personeditdlg.read_only);
1659 gtk_widget_set_sensitive(personeditdlg.entry_alias, !personeditdlg.read_only && !personeditdlg.ldap);
1660 gtk_widget_set_sensitive(personeditdlg.entry_remarks, !personeditdlg.read_only && !personeditdlg.ldap);
1661 gtk_widget_set_sensitive(personeditdlg.email_up, !personeditdlg.read_only);
1662 gtk_widget_set_sensitive(personeditdlg.email_down, !personeditdlg.read_only);
1663 gtk_widget_set_sensitive(personeditdlg.email_del, !personeditdlg.read_only);
1664 gtk_widget_set_sensitive(personeditdlg.email_mod, !personeditdlg.read_only);
1665 gtk_widget_set_sensitive(personeditdlg.email_add, !personeditdlg.read_only);
1666 gtk_widget_set_sensitive(personeditdlg.entry_atname, !personeditdlg.read_only);
1667 gtk_widget_set_sensitive(personeditdlg.entry_atvalue, !personeditdlg.read_only);
1668 gtk_widget_set_sensitive(personeditdlg.attrib_add, !personeditdlg.read_only);
1669 gtk_widget_set_sensitive(personeditdlg.attrib_del, !personeditdlg.read_only);
1670 gtk_widget_set_sensitive(personeditdlg.attrib_mod, !personeditdlg.read_only);
1673 static void addressbook_edit_person_flush_transient( void )
1675 ItemPerson *person = current_person;
1676 EditAddressPostUpdateCallback callback = edit_person_close_post_update_cb;
1678 /* reset transient data */
1679 current_abf = NULL;
1680 current_person = NULL;
1681 current_parent_folder = NULL;
1682 edit_person_close_post_update_cb = NULL;
1684 /* post action to perform on addressbook side */
1685 if (callback)
1686 callback( person );
1689 void addressbook_edit_person_invalidate( AddressBookFile *abf, ItemFolder *parent_folder,
1690 ItemPerson *person )
1692 if (current_abf == NULL &&
1693 current_person == NULL &&
1694 current_parent_folder == NULL)
1695 /* edit address form is already hidden */
1696 return;
1698 /* unconditional invalidation or invalidating the currently edited item */
1699 if ( ( abf == NULL && person == NULL && parent_folder == NULL )
1700 || (current_abf == abf ||
1701 current_person == person ||
1702 current_parent_folder == parent_folder))
1703 addressbook_edit_person_close( TRUE );
1706 static gboolean addressbook_edit_person_close( gboolean cancelled )
1708 GList *listEMail = NULL;
1709 GList *listAttrib = NULL;
1710 GError *error = NULL;
1711 GtkTreeModel *model;
1713 listEMail = edit_person_build_email_list();
1714 listAttrib = edit_person_build_attrib_list();
1715 if( cancelled ) {
1716 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1717 gtk_list_store_clear(GTK_LIST_STORE(model));
1718 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1719 gtk_list_store_clear(GTK_LIST_STORE(model));
1720 addritem_free_list_email( listEMail );
1721 addritem_free_list_attribute( listAttrib );
1723 if (!prefs_common.addressbook_use_editaddress_dialog)
1724 gtk_widget_hide( personeditdlg.container );
1726 /* no callback, as we're discarding the form */
1727 edit_person_close_post_update_cb = NULL;
1728 addressbook_edit_person_flush_transient();
1729 current_person = NULL;
1731 /* set focus to the address list (this is done by the post_update_cb usually) */
1732 addressbook_address_list_set_focus();
1733 return FALSE;
1736 if( current_person && current_abf ) {
1737 /* Update email/attribute list for existing current_person */
1738 addrbook_update_address_list( current_abf, current_person, listEMail );
1739 addrbook_update_attrib_list( current_abf, current_person, listAttrib );
1741 else {
1742 /* Create new current_person and email/attribute list */
1743 if( ! cancelled && current_abf ) {
1744 current_person = addrbook_add_address_list( current_abf, current_parent_folder, listEMail );
1745 addrbook_add_attrib_list( current_abf, current_person, listAttrib );
1748 listEMail = NULL;
1749 listAttrib = NULL;
1751 if(!cancelled && current_person != NULL) {
1752 /* Set current_person stuff */
1754 gchar *name;
1755 gchar *cn = edit_person_get_common_name_from_widgets();
1757 addritem_person_set_common_name( current_person, cn );
1758 g_free( cn );
1760 if (personeditdlg.picture_set) {
1761 GdkPixbuf * pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(personeditdlg.image));
1763 if (!current_person->picture)
1764 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1765 ADDRITEM_ID(current_person), ".png", NULL );
1766 else
1767 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1768 current_person->picture, ".png", NULL );
1770 gdk_pixbuf_save(pixbuf, name, "png", &error, NULL);
1771 if (error) {
1772 alertpanel_error(_("Failed to save image: \n%s"),
1773 error->message);
1774 g_error_free(error);
1775 } else {
1776 debug_print("saved picture to %s\n", name);
1778 if (!current_person->picture)
1779 addritem_person_set_picture( current_person, ADDRITEM_ID(current_person) ) ;
1780 g_free( name );
1781 } else {
1782 if (!current_person->picture)
1783 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1784 ADDRITEM_ID(current_person), ".png", NULL );
1785 else
1786 name = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1787 current_person->picture, ".png", NULL );
1788 claws_unlink(name);
1789 g_free(name);
1791 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_first), 0, -1 );
1792 addritem_person_set_first_name( current_person, name );
1793 g_free( name );
1794 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_last), 0, -1 );
1795 addritem_person_set_last_name( current_person, name );
1796 g_free( name );
1797 name = gtk_editable_get_chars( GTK_EDITABLE(personeditdlg.entry_nick), 0, -1 );
1798 addritem_person_set_nick_name( current_person, name );
1799 g_free( name );
1802 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1803 gtk_list_store_clear(GTK_LIST_STORE(model));
1804 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1805 gtk_list_store_clear(GTK_LIST_STORE(model));
1807 if (!prefs_common.addressbook_use_editaddress_dialog)
1808 gtk_widget_hide( personeditdlg.container );
1810 addressbook_edit_person_flush_transient();
1812 return TRUE;
1816 * Edit person.
1817 * Enter: abf Address book.
1818 * parent Parent folder for person (or NULL if adding to root folder). Argument is
1819 * only required for new objects).
1820 * person Person to edit, or NULL for a new person object.
1821 * pgMail If TRUE, E-Mail page will be activated.
1822 * Return: Edited object, or NULL if cancelled.*/
1823 ItemPerson *addressbook_edit_person( AddressBookFile *abf, ItemFolder *parent_folder, ItemPerson *person,
1824 gboolean pgMail, GtkWidget *parent_container,
1825 void (*post_update_cb) (ItemPerson *person),
1826 gboolean get_focus) {
1827 static gboolean cancelled;
1828 GError *error = NULL;
1829 GdkPixbuf *pixbuf = NULL;
1830 GtkTreeModel *model;
1831 GtkTreeSelection *sel;
1832 GtkTreeIter iter;
1834 /* set transient data */
1835 current_abf = abf;
1836 current_person = person;
1837 current_parent_folder = parent_folder;
1838 edit_person_close_post_update_cb = post_update_cb;
1839 personeditdlg.ldap = (abf && abf->type == ADBOOKTYPE_LDAP)? TRUE : FALSE;
1841 if( personeditdlg.container ) {
1842 gtk_widget_destroy(personeditdlg.container);
1843 personeditdlg.container = NULL;
1845 addressbook_edit_person_create(parent_container, &cancelled);
1847 /* typically, get focus when dialog mode is enabled, or when editing a new address */
1848 if( get_focus ) {
1849 gtk_widget_grab_focus(personeditdlg.ok_btn);
1850 gtk_widget_grab_focus(personeditdlg.entry_name);
1853 personeditdlg.read_only = (current_abf == NULL);
1854 update_sensitivity();
1856 gtk_widget_show(personeditdlg.container);
1857 if (prefs_common.addressbook_use_editaddress_dialog)
1858 manage_window_set_transient(GTK_WINDOW(personeditdlg.container));
1859 else
1860 if (get_focus)
1861 addressbook_address_list_disable_some_actions();
1863 /* Clear all fields */
1864 edit_person_status_show( "" );
1866 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1867 gtk_list_store_clear(GTK_LIST_STORE(model));
1868 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1869 gtk_list_store_clear(GTK_LIST_STORE(model));
1871 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), "" );
1872 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), "" );
1873 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), "" );
1874 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), "" );
1876 personeditdlg.editNew = FALSE;
1877 if( current_person ) {
1878 gchar *filename = NULL;
1880 if( ADDRITEM_NAME(current_person) )
1881 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_name), ADDRITEM_NAME(person) );
1883 cm_menu_set_sensitive("EditAddressPopup/SetPicture", !personeditdlg.ldap);
1884 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", !personeditdlg.ldap);
1885 if( current_person->picture ) {
1886 filename = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, ADDRBOOK_DIR, G_DIR_SEPARATOR_S,
1887 current_person->picture, ".png", NULL );
1888 if (is_file_exist(filename)) {
1889 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
1890 if (error) {
1891 debug_print("Failed to import image: %s\n",
1892 error->message);
1893 g_error_free(error);
1894 goto no_img;
1896 personeditdlg.picture_set = TRUE;
1897 cm_menu_set_sensitive("EditAddressPopup/UnsetPicture", !personeditdlg.ldap && personeditdlg.picture_set);
1898 } else {
1899 goto no_img;
1901 gtk_image_set_from_pixbuf(GTK_IMAGE(personeditdlg.image), pixbuf);
1902 } else {
1903 no_img:
1904 addressbook_edit_person_clear_picture();
1907 g_free(filename);
1908 if (pixbuf) {
1909 g_object_unref(pixbuf);
1910 pixbuf = NULL;
1913 if( current_person->firstName )
1914 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_first), current_person->firstName );
1915 if( current_person->lastName )
1916 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_last), current_person->lastName );
1917 if( current_person->nickName )
1918 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_nick), current_person->nickName );
1919 edit_person_load_email( current_person );
1920 edit_person_load_attrib( current_person );
1921 gtk_entry_set_text(GTK_ENTRY(personeditdlg.entry_atvalue), "");
1923 else {
1924 personeditdlg.editNew = TRUE;
1927 /* Select appropriate start page */
1928 if( pgMail ) {
1929 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_EMAIL );
1931 else {
1932 gtk_notebook_set_current_page( GTK_NOTEBOOK(personeditdlg.notebook), PAGE_BASIC );
1935 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(personeditdlg.view_email));
1936 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_email));
1937 if (gtk_tree_model_get_iter_first(model, &iter)) {
1938 gtk_tree_selection_select_iter(sel, &iter);
1939 edit_person_email_cursor_changed(
1940 GTK_TREE_VIEW(personeditdlg.view_email), NULL);
1943 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(personeditdlg.view_attrib));
1944 model = gtk_tree_view_get_model(GTK_TREE_VIEW(personeditdlg.view_attrib));
1945 if (gtk_tree_model_get_iter_first(model, &iter))
1946 gtk_tree_selection_select_iter(sel, &iter);
1947 edit_person_attrib_cursor_changed(
1948 GTK_TREE_VIEW(personeditdlg.view_attrib), NULL);
1950 edit_person_email_clear( NULL );
1951 edit_person_attrib_clear( NULL );
1953 if (prefs_common.addressbook_use_editaddress_dialog) {
1954 gtk_main();
1955 gtk_widget_hide( personeditdlg.container );
1957 if (!addressbook_edit_person_close( cancelled )) {
1958 return NULL;
1962 return person;
1965 void addressbook_edit_reload_attr_list( void )
1967 if (personeditdlg.entry_atname) {
1968 combobox_unset_popdown_strings(GTK_COMBO_BOX_TEXT(personeditdlg.entry_atname));
1969 if (prefs_common.addressbook_custom_attributes)
1970 combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(personeditdlg.entry_atname),
1971 prefs_common.addressbook_custom_attributes);
1976 * End of Source.