2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 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 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include <gdk/gdkkeysyms.h>
28 #include <gtk/gtkwindow.h>
29 #include <gtk/gtksignal.h>
30 #include <gtk/gtkvbox.h>
31 #include <gtk/gtkscrolledwindow.h>
32 #include <gtk/gtkhpaned.h>
33 #include <gtk/gtkhbox.h>
34 #include <gtk/gtklabel.h>
35 #include <gtk/gtkentry.h>
36 #include <gtk/gtkctree.h>
37 #include <gtk/gtkclist.h>
38 #include <gtk/gtktable.h>
39 #include <gtk/gtkhbbox.h>
40 #include <gtk/gtkbutton.h>
41 #include <gtk/gtkmenu.h>
42 #include <gtk/gtkmenuitem.h>
43 #include <gtk/gtkitemfactory.h>
49 #include "addressbook.h"
50 #include "manage_window.h"
51 #include "prefs_common.h"
52 #include "alertpanel.h"
53 #include "inputdialog.h"
62 #include "addr_compl.h"
65 #include "addressitem.h"
67 #include "addrcache.h"
69 #include "addrindex.h"
70 #include "addressadd.h"
72 #include "editvcard.h"
73 #include "editgroup.h"
74 #include "editaddress.h"
77 #include "importldif.h"
79 #include "importmutt.h"
83 #include "editjpilot.h"
91 #define ADDRESSBOOK_LDAP_BUSYMSG "Busy"
94 #include "pixmaps/dir-close.xpm"
95 #include "pixmaps/dir-open.xpm"
96 #include "pixmaps/group.xpm"
97 #include "pixmaps/interface.xpm"
98 #include "pixmaps/book.xpm"
99 #include "pixmaps/address.xpm"
100 #include "pixmaps/vcard.xpm"
101 #include "pixmaps/jpilot.xpm"
102 #include "pixmaps/category.xpm"
103 #include "pixmaps/ldap.xpm"
110 } AddressBookColumnPos;
113 #define COL_NAME_WIDTH 164
114 #define COL_ADDRESS_WIDTH 156
116 #define COL_FOLDER_WIDTH 170
117 #define ADDRESSBOOK_WIDTH 640
118 #define ADDRESSBOOK_HEIGHT 360
120 #define ADDRESSBOOK_MSGBUF_SIZE 2048
122 static GdkPixmap *folderxpm;
123 static GdkBitmap *folderxpmmask;
124 static GdkPixmap *folderopenxpm;
125 static GdkBitmap *folderopenxpmmask;
126 static GdkPixmap *groupxpm;
127 static GdkBitmap *groupxpmmask;
128 static GdkPixmap *interfacexpm;
129 static GdkBitmap *interfacexpmmask;
130 static GdkPixmap *bookxpm;
131 static GdkBitmap *bookxpmmask;
132 static GdkPixmap *addressxpm;
133 static GdkBitmap *addressxpmmask;
134 static GdkPixmap *vcardxpm;
135 static GdkBitmap *vcardxpmmask;
136 static GdkPixmap *jpilotxpm;
137 static GdkBitmap *jpilotxpmmask;
138 static GdkPixmap *categoryxpm;
139 static GdkBitmap *categoryxpmmask;
140 static GdkPixmap *ldapxpm;
141 static GdkBitmap *ldapxpmmask;
144 static gchar addressbook_msgbuf[ ADDRESSBOOK_MSGBUF_SIZE ];
146 /* Address list selection */
147 static GList *_addressListSelection_ = NULL;
149 /* Address index file and interfaces */
150 static AddressIndex *_addressIndex_ = NULL;
151 static GList *_addressInterfaceList_ = NULL;
152 static GList *_addressIFaceSelection_ = NULL;
153 #define ADDRESSBOOK_IFACE_SELECTION "1/y,3/y,4/y,2/n"
155 static AddressBook_win addrbook;
157 static GHashTable *_addressBookTypeHash_ = NULL;
158 static GList *_addressBookTypeList_ = NULL;
160 static void addressbook_create (void);
161 static gint addressbook_close (void);
162 static void addressbook_button_set_sensitive (void);
164 /* callback functions */
165 static void addressbook_del_clicked (GtkButton *button,
167 static void addressbook_reg_clicked (GtkButton *button,
169 static void addressbook_to_clicked (GtkButton *button,
171 static void addressbook_lup_clicked (GtkButton *button,
174 static void addressbook_tree_selected (GtkCTree *ctree,
178 static void addressbook_list_selected (GtkCList *clist,
183 static void addressbook_list_row_selected (GtkCTree *clist,
187 static void addressbook_list_row_unselected (GtkCTree *clist,
191 static void addressbook_person_expand_node (GtkCTree *ctree,
194 static void addressbook_person_collapse_node (GtkCTree *ctree,
197 static void addressbook_entry_gotfocus (GtkWidget *widget);
200 static void addressbook_entry_changed (GtkWidget *widget);
203 static void addressbook_list_button_pressed (GtkWidget *widget,
204 GdkEventButton *event,
206 static void addressbook_list_button_released (GtkWidget *widget,
207 GdkEventButton *event,
209 static void addressbook_tree_button_pressed (GtkWidget *ctree,
210 GdkEventButton *event,
212 static void addressbook_tree_button_released (GtkWidget *ctree,
213 GdkEventButton *event,
215 static void addressbook_popup_close (GtkMenuShell *menu_shell,
218 static void addressbook_new_folder_cb (gpointer data,
221 static void addressbook_new_group_cb (gpointer data,
224 static void addressbook_treenode_edit_cb (gpointer data,
227 static void addressbook_treenode_delete_cb (gpointer data,
231 static void addressbook_change_node_name (GtkCTreeNode *node,
234 static void addressbook_new_address_cb (gpointer data,
237 static void addressbook_edit_address_cb (gpointer data,
240 static void addressbook_delete_address_cb (gpointer data,
244 static void close_cb (gpointer data,
247 static void addressbook_file_save_cb (gpointer data,
251 /* Data source edit stuff */
252 static void addressbook_new_book_cb (gpointer data,
255 static void addressbook_new_vcard_cb (gpointer data,
260 static void addressbook_new_jpilot_cb (gpointer data,
266 static void addressbook_new_ldap_cb (gpointer data,
271 static void addressbook_set_clist (AddressObject *obj);
273 static void addressbook_load_tree (void);
274 void addressbook_read_file (void);
276 static GtkCTreeNode *addressbook_add_object (GtkCTreeNode *node,
278 static AddressDataSource *addressbook_find_datasource
279 (GtkCTreeNode *node );
281 static AddressBookFile *addressbook_get_book_file();
283 static GtkCTreeNode *addressbook_node_add_folder
285 AddressDataSource *ds,
286 ItemFolder *itemFolder,
287 AddressObjectType otype);
288 static GtkCTreeNode *addressbook_node_add_group (GtkCTreeNode *node,
289 AddressDataSource *ds,
290 ItemGroup *itemGroup);
291 /* static GtkCTreeNode *addressbook_node_add_category */
292 /* (GtkCTreeNode *node, */
293 /* AddressDataSource *ds, */
294 /* ItemFolder *itemFolder); */
295 static void addressbook_tree_remove_children (GtkCTree *ctree,
296 GtkCTreeNode *parent);
297 static void addressbook_move_nodes_up (GtkCTree *ctree,
299 static GtkCTreeNode *addressbook_find_group_node (GtkCTreeNode *parent,
302 static void addressbook_delete_object (AddressObject *obj);
304 static void key_pressed (GtkWidget *widget,
307 static gint addressbook_list_compare_func (GtkCList *clist,
310 /* static gint addressbook_obj_name_compare (gconstpointer a, */
311 /* gconstpointer b); */
313 static void addressbook_book_show_message (AddressBookFile *book);
314 static void addressbook_vcard_show_message (VCardFile *vcf);
316 static void addressbook_jpilot_show_message (JPilotFile *jpf);
319 static void addressbook_ldap_show_message (SyldapServer *server);
322 /* LUT's and IF stuff */
323 static void addressbook_free_adapter (GtkCTreeNode *node);
324 static void addressbook_free_child_adapters (GtkCTreeNode *node);
325 AddressTypeControlItem *addrbookctl_lookup (gint ot);
326 AddressTypeControlItem *addrbookctl_lookup_iface(AddressIfType ifType);
328 void addrbookctl_build_map (GtkWidget *window);
329 void addrbookctl_build_iflist (void);
330 AdapterInterface *addrbookctl_find_interface (AddressIfType ifType);
331 void addrbookctl_build_ifselect (void);
333 static void addrbookctl_free_interface (AdapterInterface *adapter);
334 static void addrbookctl_free_datasource (AdapterDSource *adapter);
335 static void addrbookctl_free_folder (AdapterFolder *adapter);
336 static void addrbookctl_free_group (AdapterGroup *adapter);
338 static void addressbook_list_select_clear (void);
339 static void addressbook_list_select_add (AddressObject *obj);
340 static void addressbook_list_select_remove (AddressObject *obj);
342 static void addressbook_import_ldif_cb ();
343 static void addressbook_import_mutt_cb ();
345 static GtkItemFactoryEntry addressbook_entries[] =
347 {N_("/_File"), NULL, NULL, 0, "<Branch>"},
348 {N_("/_File/New _Book"), "<alt>B", addressbook_new_book_cb, 0, NULL},
349 {N_("/_File/New _vCard"), "<alt>D", addressbook_new_vcard_cb, 0, NULL},
351 {N_("/_File/New _J-Pilot"), "<alt>J", addressbook_new_jpilot_cb, 0, NULL},
354 {N_("/_File/New _Server"), "<alt>S", addressbook_new_ldap_cb, 0, NULL},
356 {N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
357 {N_("/_File/_Edit"), NULL, addressbook_treenode_edit_cb, 0, NULL},
358 {N_("/_File/_Delete"), NULL, addressbook_treenode_delete_cb, 0, NULL},
359 {N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
360 {N_("/_File/_Save"), "<alt>S", addressbook_file_save_cb, 0, NULL},
361 {N_("/_File/_Close"), "<alt>W", close_cb, 0, NULL},
362 {N_("/_Address"), NULL, NULL, 0, "<Branch>"},
363 {N_("/_Address/New _Address"), "<alt>N", addressbook_new_address_cb, 0, NULL},
364 {N_("/_Address/New _Group"), "<alt>G", addressbook_new_group_cb, 0, NULL},
365 {N_("/_Address/New _Folder"), "<alt>R", addressbook_new_folder_cb, 0, NULL},
366 {N_("/_Address/---"), NULL, NULL, 0, "<Separator>"},
367 {N_("/_Address/_Edit"), "<alt>Return", addressbook_edit_address_cb, 0, NULL},
368 {N_("/_Address/_Delete"), NULL, addressbook_delete_address_cb, 0, NULL},
369 {N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
370 {N_("/_Tools/Import _LDIF"), NULL, addressbook_import_ldif_cb, 0, NULL},
371 {N_("/_Tools/Import M_utt"), NULL, addressbook_import_mutt_cb, 0, NULL},
372 {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"},
373 {N_("/_Help/_About"), NULL, about_show, 0, NULL}
376 /* New options to be added. */
378 {N_("/_Edit"), NULL, NULL, 0, "<Branch>"},
379 {N_("/_Edit/C_ut"), "<ctl>X", NULL, 0, NULL},
380 {N_("/_Edit/_Copy"), "<ctl>C", NULL, 0, NULL},
381 {N_("/_Edit/_Paste"), "<ctl>V", NULL, 0, NULL},
382 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
383 {N_("/_Tools/Import _Mozilla"), NULL, NULL, 0, NULL},
384 {N_("/_Tools/Import _vCard"), NULL, NULL, 0, NULL},
385 {N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
386 {N_("/_Tools/Export _LDIF"), NULL, NULL, 0, NULL},
387 {N_("/_Tools/Export V-_Card"), NULL, NULL, 0, NULL},
390 static GtkItemFactoryEntry addressbook_tree_popup_entries[] =
392 {N_("/New _Address"), NULL, addressbook_new_address_cb, 0, NULL},
393 {N_("/New _Group"), NULL, addressbook_new_group_cb, 0, NULL},
394 {N_("/New _Folder"), NULL, addressbook_new_folder_cb, 0, NULL},
395 {N_("/---"), NULL, NULL, 0, "<Separator>"},
396 {N_("/_Edit"), NULL, addressbook_treenode_edit_cb, 0, NULL},
397 {N_("/_Delete"), NULL, addressbook_treenode_delete_cb, 0, NULL}
400 static GtkItemFactoryEntry addressbook_list_popup_entries[] =
402 {N_("/New _Address"), NULL, addressbook_new_address_cb, 0, NULL},
403 {N_("/New _Group"), NULL, addressbook_new_group_cb, 0, NULL},
404 {N_("/New _Folder"), NULL, addressbook_new_folder_cb, 0, NULL},
405 {N_("/---"), NULL, NULL, 0, "<Separator>"},
406 {N_("/_Edit"), NULL, addressbook_edit_address_cb, 0, NULL},
407 {N_("/_Delete"), NULL, addressbook_delete_address_cb, 0, NULL}
410 void addressbook_open(Compose *target)
412 if (!addrbook.window) {
413 addressbook_read_file();
414 addressbook_create();
415 addressbook_load_tree();
416 gtk_ctree_select(GTK_CTREE(addrbook.ctree),
417 GTK_CTREE_NODE(GTK_CLIST(addrbook.ctree)->row_list));
419 gtk_widget_hide(addrbook.window);
421 gtk_widget_show_all(addrbook.window);
423 addressbook_set_target_compose(target);
426 void addressbook_set_target_compose(Compose *target)
428 addrbook.target_compose = target;
430 addressbook_button_set_sensitive();
433 Compose *addressbook_get_target_compose(void)
435 return addrbook.target_compose;
438 void addressbook_refresh(void)
440 if (addrbook.window) {
441 if (addrbook.treeSelected) {
442 gtk_ctree_select(GTK_CTREE(addrbook.ctree),
443 addrbook.treeSelected);
446 addressbook_export_to_file();
450 * Create the address book widgets. The address book contains two CTree widgets: the
451 * address index tree on the left and the address list on the right.
453 * The address index tree displays a hierarchy of interfaces and groups. Each node in
454 * this tree is linked to an address Adapter. Adapters have been created for interfaces,
455 * data sources and folder objects.
457 * The address list displays group, person and email objects. These items are linked
458 * directly to ItemGroup, ItemPerson and ItemEMail objects inside the address book data
461 * In the tradition of MVC architecture, the data stores have been separated from the
462 * GUI components. The addrindex.c file provides the interface to all data stores.
464 static void addressbook_create(void)
470 GtkWidget *ctree_swin;
472 GtkWidget *clist_vbox;
473 GtkWidget *clist_swin;
479 GtkWidget *statusbar;
488 GtkWidget *tree_popup;
489 GtkWidget *list_popup;
490 GtkItemFactory *tree_factory;
491 GtkItemFactory *list_factory;
492 GtkItemFactory *menu_factory;
496 gchar *titles[N_COLS] = {_("Name"), _("E-Mail address"), _("Remarks")};
500 debug_print("Creating addressbook window...\n");
502 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
503 gtk_window_set_title(GTK_WINDOW(window), _("Address book"));
504 gtk_widget_set_usize(window, ADDRESSBOOK_WIDTH, ADDRESSBOOK_HEIGHT);
505 gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);
506 gtk_widget_realize(window);
508 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
509 GTK_SIGNAL_FUNC(addressbook_close), NULL);
510 gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
511 GTK_SIGNAL_FUNC(key_pressed), NULL);
512 gtk_signal_connect(GTK_OBJECT(window), "focus_in_event",
513 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
514 gtk_signal_connect(GTK_OBJECT(window), "focus_out_event",
515 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
517 vbox = gtk_vbox_new(FALSE, 0);
518 gtk_container_add(GTK_CONTAINER(window), vbox);
520 n_entries = sizeof(addressbook_entries) /
521 sizeof(addressbook_entries[0]);
522 menubar = menubar_create(window, addressbook_entries, n_entries,
523 "<AddressBook>", NULL);
524 gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
525 menu_factory = gtk_item_factory_from_widget(menubar);
527 vbox2 = gtk_vbox_new(FALSE, 4);
528 gtk_container_set_border_width(GTK_CONTAINER(vbox2), BORDER_WIDTH);
529 gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);
531 ctree_swin = gtk_scrolled_window_new(NULL, NULL);
532 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ctree_swin),
533 GTK_POLICY_AUTOMATIC,
535 gtk_widget_set_usize(ctree_swin, COL_FOLDER_WIDTH + 40, -1);
538 ctree = gtk_ctree_new(1, 0);
539 gtk_container_add(GTK_CONTAINER(ctree_swin), ctree);
540 gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
541 gtk_clist_set_column_width(GTK_CLIST(ctree), 0, COL_FOLDER_WIDTH);
542 gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_DOTTED);
543 gtk_ctree_set_expander_style(GTK_CTREE(ctree),
544 GTK_CTREE_EXPANDER_SQUARE);
545 gtk_ctree_set_indent(GTK_CTREE(ctree), CTREE_INDENT);
546 gtk_clist_set_compare_func(GTK_CLIST(ctree),
547 addressbook_list_compare_func);
549 gtk_signal_connect(GTK_OBJECT(ctree), "tree_select_row",
550 GTK_SIGNAL_FUNC(addressbook_tree_selected), NULL);
551 gtk_signal_connect(GTK_OBJECT(ctree), "button_press_event",
552 GTK_SIGNAL_FUNC(addressbook_tree_button_pressed),
554 gtk_signal_connect(GTK_OBJECT(ctree), "button_release_event",
555 GTK_SIGNAL_FUNC(addressbook_tree_button_released),
558 clist_vbox = gtk_vbox_new(FALSE, 4);
560 clist_swin = gtk_scrolled_window_new(NULL, NULL);
561 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
562 GTK_POLICY_AUTOMATIC,
564 gtk_box_pack_start(GTK_BOX(clist_vbox), clist_swin, TRUE, TRUE, 0);
567 clist = gtk_ctree_new_with_titles(N_COLS, 0, titles);
568 gtk_container_add(GTK_CONTAINER(clist_swin), clist);
569 gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_EXTENDED);
570 gtk_ctree_set_line_style(GTK_CTREE(clist), GTK_CTREE_LINES_NONE);
571 gtk_ctree_set_expander_style(GTK_CTREE(clist), GTK_CTREE_EXPANDER_SQUARE);
572 gtk_ctree_set_indent(GTK_CTREE(clist), CTREE_INDENT);
573 gtk_clist_set_column_width(GTK_CLIST(clist), COL_NAME,
575 gtk_clist_set_column_width(GTK_CLIST(clist), COL_ADDRESS,
577 gtk_clist_set_compare_func(GTK_CLIST(clist),
578 addressbook_list_compare_func);
580 for (i = 0; i < N_COLS; i++)
581 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button,
584 gtk_signal_connect(GTK_OBJECT(clist), "tree_select_row",
585 GTK_SIGNAL_FUNC(addressbook_list_row_selected), NULL);
586 gtk_signal_connect(GTK_OBJECT(clist), "tree_unselect_row",
587 GTK_SIGNAL_FUNC(addressbook_list_row_unselected), NULL);
588 gtk_signal_connect(GTK_OBJECT(clist), "button_press_event",
589 GTK_SIGNAL_FUNC(addressbook_list_button_pressed),
591 gtk_signal_connect(GTK_OBJECT(clist), "button_release_event",
592 GTK_SIGNAL_FUNC(addressbook_list_button_released),
594 gtk_signal_connect(GTK_OBJECT(clist), "select_row",
595 GTK_SIGNAL_FUNC(addressbook_list_selected), NULL);
596 gtk_signal_connect(GTK_OBJECT(clist), "tree_expand",
597 GTK_SIGNAL_FUNC(addressbook_person_expand_node), NULL );
598 gtk_signal_connect(GTK_OBJECT(clist), "tree_collapse",
599 GTK_SIGNAL_FUNC(addressbook_person_collapse_node), NULL );
601 hbox = gtk_hbox_new(FALSE, 4);
602 gtk_box_pack_start(GTK_BOX(clist_vbox), hbox, FALSE, FALSE, 0);
604 label = gtk_label_new(_("Name:"));
605 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
607 entry = gtk_entry_new();
608 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
610 address_completion_register_entry(GTK_ENTRY(entry));
611 gtk_signal_connect(GTK_OBJECT(entry), "focus_in_event",
612 GTK_SIGNAL_FUNC(addressbook_entry_gotfocus), NULL);
615 gtk_signal_connect(GTK_OBJECT(entry), "changed",
616 GTK_SIGNAL_FUNC(addressbook_entry_changed), NULL);
619 paned = gtk_hpaned_new();
620 gtk_box_pack_start(GTK_BOX(vbox2), paned, TRUE, TRUE, 0);
621 gtk_paned_add1(GTK_PANED(paned), ctree_swin);
622 gtk_paned_add2(GTK_PANED(paned), clist_vbox);
625 hsbox = gtk_hbox_new(FALSE, 0);
626 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
627 statusbar = gtk_statusbar_new();
628 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
631 hbbox = gtk_hbutton_box_new();
632 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_END);
633 gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbbox), 2);
634 gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
636 del_btn = gtk_button_new_with_label(_("Delete"));
637 GTK_WIDGET_SET_FLAGS(del_btn, GTK_CAN_DEFAULT);
638 gtk_box_pack_start(GTK_BOX(hbbox), del_btn, TRUE, TRUE, 0);
639 reg_btn = gtk_button_new_with_label(_("Add"));
640 GTK_WIDGET_SET_FLAGS(reg_btn, GTK_CAN_DEFAULT);
641 gtk_box_pack_start(GTK_BOX(hbbox), reg_btn, TRUE, TRUE, 0);
642 lup_btn = gtk_button_new_with_label(_("Lookup"));
643 GTK_WIDGET_SET_FLAGS(lup_btn, GTK_CAN_DEFAULT);
644 gtk_box_pack_start(GTK_BOX(hbbox), lup_btn, TRUE, TRUE, 0);
646 gtk_signal_connect(GTK_OBJECT(del_btn), "clicked",
647 GTK_SIGNAL_FUNC(addressbook_del_clicked), NULL);
648 gtk_signal_connect(GTK_OBJECT(reg_btn), "clicked",
649 GTK_SIGNAL_FUNC(addressbook_reg_clicked), NULL);
650 gtk_signal_connect(GTK_OBJECT(lup_btn), "clicked",
651 GTK_SIGNAL_FUNC(addressbook_lup_clicked), NULL);
653 to_btn = gtk_button_new_with_label
654 (prefs_common.trans_hdr ? _("To:") : "To:");
655 GTK_WIDGET_SET_FLAGS(to_btn, GTK_CAN_DEFAULT);
656 gtk_box_pack_start(GTK_BOX(hbbox), to_btn, TRUE, TRUE, 0);
657 cc_btn = gtk_button_new_with_label
658 (prefs_common.trans_hdr ? _("Cc:") : "Cc:");
659 GTK_WIDGET_SET_FLAGS(cc_btn, GTK_CAN_DEFAULT);
660 gtk_box_pack_start(GTK_BOX(hbbox), cc_btn, TRUE, TRUE, 0);
661 bcc_btn = gtk_button_new_with_label
662 (prefs_common.trans_hdr ? _("Bcc:") : "Bcc:");
663 GTK_WIDGET_SET_FLAGS(bcc_btn, GTK_CAN_DEFAULT);
664 gtk_box_pack_start(GTK_BOX(hbbox), bcc_btn, TRUE, TRUE, 0);
666 gtk_signal_connect(GTK_OBJECT(to_btn), "clicked",
667 GTK_SIGNAL_FUNC(addressbook_to_clicked),
668 GINT_TO_POINTER(COMPOSE_TO));
669 gtk_signal_connect(GTK_OBJECT(cc_btn), "clicked",
670 GTK_SIGNAL_FUNC(addressbook_to_clicked),
671 GINT_TO_POINTER(COMPOSE_CC));
672 gtk_signal_connect(GTK_OBJECT(bcc_btn), "clicked",
673 GTK_SIGNAL_FUNC(addressbook_to_clicked),
674 GINT_TO_POINTER(COMPOSE_BCC));
676 /* Build icons for interface */
677 PIXMAP_CREATE( window, interfacexpm, interfacexpmmask, interface_xpm );
679 /* Build control tables */
680 addrbookctl_build_map(window);
681 addrbookctl_build_iflist();
682 addrbookctl_build_ifselect();
684 /* Add each interface into the tree as a root level folder */
685 nodeIf = _addressInterfaceList_;
687 AdapterInterface *adapter = nodeIf->data;
688 AddressInterface *iface = adapter->interface;
689 nodeIf = g_list_next(nodeIf);
691 if(iface->useInterface) {
692 AddressTypeControlItem *atci = adapter->atci;
693 text = atci->displayName;
695 gtk_ctree_insert_node( GTK_CTREE(ctree),
696 NULL, NULL, &text, FOLDER_SPACING,
697 interfacexpm, interfacexpmmask,
698 interfacexpm, interfacexpmmask,
700 menu_set_sensitive( menu_factory, atci->menuCommand, adapter->haveLibrary );
701 gtk_ctree_node_set_row_data( GTK_CTREE(ctree), adapter->treeNode, adapter );
706 n_entries = sizeof(addressbook_tree_popup_entries) /
707 sizeof(addressbook_tree_popup_entries[0]);
708 tree_popup = menu_create_items(addressbook_tree_popup_entries,
710 "<AddressBookTree>", &tree_factory,
712 gtk_signal_connect(GTK_OBJECT(tree_popup), "selection_done",
713 GTK_SIGNAL_FUNC(addressbook_popup_close), NULL);
714 n_entries = sizeof(addressbook_list_popup_entries) /
715 sizeof(addressbook_list_popup_entries[0]);
716 list_popup = menu_create_items(addressbook_list_popup_entries,
718 "<AddressBookList>", &list_factory,
721 addrbook.window = window;
722 addrbook.menubar = menubar;
723 addrbook.ctree = ctree;
724 addrbook.clist = clist;
725 addrbook.entry = entry;
726 addrbook.statusbar = statusbar;
727 addrbook.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Addressbook Window" );
729 addrbook.del_btn = del_btn;
730 addrbook.reg_btn = reg_btn;
731 addrbook.lup_btn = lup_btn;
732 addrbook.to_btn = to_btn;
733 addrbook.cc_btn = cc_btn;
734 addrbook.bcc_btn = bcc_btn;
736 addrbook.tree_popup = tree_popup;
737 addrbook.list_popup = list_popup;
738 addrbook.tree_factory = tree_factory;
739 addrbook.list_factory = list_factory;
740 addrbook.menu_factory = menu_factory;
742 addrbook.listSelected = NULL;
743 address_completion_start(window);
744 gtk_widget_show_all(window);
748 static gint addressbook_close(void)
750 gtk_widget_hide(addrbook.window);
751 addressbook_export_to_file();
755 static void addressbook_status_show( gchar *msg ) {
756 if( addrbook.statusbar != NULL ) {
757 gtk_statusbar_pop( GTK_STATUSBAR(addrbook.statusbar), addrbook.status_cid );
759 gtk_statusbar_push( GTK_STATUSBAR(addrbook.statusbar), addrbook.status_cid, msg );
764 static void addressbook_ds_show_message( AddressDataSource *ds ) {
767 *addressbook_msgbuf = '\0';
769 name = addrindex_ds_get_name( ds );
770 retVal = addrindex_ds_get_status_code( ds );
771 if( retVal == MGU_SUCCESS ) {
773 sprintf( addressbook_msgbuf, "%s", name );
778 sprintf( addressbook_msgbuf, "%s", mgu_error2string( retVal ) );
781 sprintf( addressbook_msgbuf, "%s: %s", name, mgu_error2string( retVal ) );
785 addressbook_status_show( addressbook_msgbuf );
788 static void addressbook_button_set_sensitive(void)
790 gboolean to_sens = FALSE;
791 gboolean cc_sens = FALSE;
792 gboolean bcc_sens = FALSE;
794 if (!addrbook.window) return;
796 if (addrbook.target_compose) {
799 if (addrbook.target_compose->use_bcc)
803 gtk_widget_set_sensitive(addrbook.to_btn, to_sens);
804 gtk_widget_set_sensitive(addrbook.cc_btn, cc_sens);
805 gtk_widget_set_sensitive(addrbook.bcc_btn, bcc_sens);
809 * Delete one or more objects from address list.
811 static void addressbook_del_clicked(GtkButton *button, gpointer data)
813 GtkCTree *clist = GTK_CTREE(addrbook.clist);
814 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
815 AddressObject *pobj, *obj;
816 AdapterDSource *ads = NULL;
817 GtkCTreeNode *nodeList;
820 AddressBookFile *abf = NULL;
821 AddressDataSource *ds = NULL;
823 pobj = gtk_ctree_node_get_row_data(ctree, addrbook.opened );
824 g_return_if_fail(pobj != NULL);
826 nodeList = addrbook.listSelected;
827 obj = gtk_ctree_node_get_row_data( clist, nodeList );
828 if( obj == NULL) return;
829 ds = addressbook_find_datasource( addrbook.treeSelected );
830 if( ds == NULL ) return;
833 if( pobj->type == ADDR_DATASOURCE ) {
834 ads = ADAPTER_DSOURCE(pobj);
835 if( ads->subType == ADDR_BOOK ) procFlag = TRUE;
837 else if( pobj->type == ADDR_ITEM_FOLDER ) {
840 else if( pobj->type == ADDR_ITEM_GROUP ) {
843 if( ! procFlag ) return;
844 abf = ds->rawDataSource;
845 if( abf == NULL ) return;
847 /* Confirm deletion */
848 aval = alertpanel( _("Delete address(es)"),
849 _("Really delete the address(es)?"),
850 _("Yes"), _("No"), NULL );
851 if( aval != G_ALERTDEFAULT ) return;
853 /* Process deletions */
854 if( pobj->type == ADDR_DATASOURCE || pobj->type == ADDR_ITEM_FOLDER ) {
855 /* Items inside folders */
857 node = _addressListSelection_;
859 AddrItemObject *aio = node->data;
860 node = g_list_next( node );
861 if( aio->type == ADDR_ITEM_GROUP ) {
862 ItemGroup *item = ( ItemGroup * ) aio;
863 GtkCTreeNode *nd = NULL;
865 nd = addressbook_find_group_node( addrbook.opened, item );
866 item = addrbook_remove_group( abf, item );
868 addritem_free_item_group( item );
871 /* Remove group from parent node */
872 gtk_ctree_remove_node( ctree, nd );
874 else if( aio->type == ADDR_ITEM_PERSON ) {
875 ItemPerson *item = ( ItemPerson * ) aio;
876 item = addrbook_remove_person( abf, item );
878 addritem_free_item_person( item );
882 else if( aio->type == ADDR_ITEM_EMAIL ) {
883 ItemEMail *item = ( ItemEMail * ) aio;
884 ItemPerson *person = ( ItemPerson * ) ADDRITEM_PARENT(item);
885 item = addrbook_person_remove_email( abf, person, item );
887 addritem_free_item_email( item );
892 addressbook_list_select_clear();
893 gtk_ctree_select( ctree, addrbook.opened);
896 else if( pobj->type == ADDR_ITEM_GROUP ) {
897 /* Items inside groups */
899 node = _addressListSelection_;
901 AddrItemObject *aio = node->data;
902 node = g_list_next( node );
903 if( aio->type == ADDR_ITEM_EMAIL ) {
904 ItemEMail *item = ( ItemEMail * ) aio;
905 ItemPerson *person = ( ItemPerson * ) ADDRITEM_PARENT(item);
906 item = addrbook_person_remove_email( abf, person, item );
908 addritem_print_item_email( item, stdout );
909 addritem_free_item_email( item );
914 addressbook_list_select_clear();
915 gtk_ctree_select( ctree, addrbook.opened);
919 gtk_ctree_node_set_row_data( clist, nodeList, NULL );
920 gtk_ctree_remove_node( clist, nodeList );
921 addressbook_list_select_remove( obj );
925 static void addressbook_reg_clicked(GtkButton *button, gpointer data)
927 addressbook_new_address_cb( NULL, 0, NULL );
930 gchar *addressbook_format_address( AddressObject * obj ) {
933 gchar *address = NULL;
935 if( obj->type == ADDR_ITEM_EMAIL ) {
936 ItemPerson *person = NULL;
937 ItemEMail *email = ( ItemEMail * ) obj;
939 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
940 if( email->address ) {
941 if( ADDRITEM_NAME(email) ) {
942 name = ADDRITEM_NAME(email);
943 if( *name == '\0' ) {
944 name = ADDRITEM_NAME(person);
947 else if( ADDRITEM_NAME(person) ) {
948 name = ADDRITEM_NAME(person);
951 buf = g_strdup( email->address );
953 address = email->address;
956 else if( obj->type == ADDR_ITEM_PERSON ) {
957 ItemPerson *person = ( ItemPerson * ) obj;
958 GList *node = person->listEMail;
960 name = ADDRITEM_NAME(person);
962 ItemEMail *email = ( ItemEMail * ) node->data;
963 address = email->address;
968 buf = g_strdup_printf( "%s <%s>", name, address );
971 buf = g_strdup( address );
978 static void addressbook_to_clicked(GtkButton *button, gpointer data)
980 GList *node = _addressListSelection_;
981 if (!addrbook.target_compose) return;
983 AddressObject *obj = node->data;
984 Compose *compose = addrbook.target_compose;
985 node = g_list_next( node );
986 if( obj->type == ADDR_ITEM_PERSON || obj->type == ADDR_ITEM_EMAIL ) {
987 gchar *addr = addressbook_format_address( obj );
988 compose_entry_append( compose, addr, (ComposeEntryType) data );
992 else if( obj->type == ADDR_ITEM_GROUP ) {
993 ItemGroup *group = ( ItemGroup * ) obj;
994 GList *nodeMail = group->listEMail;
996 ItemEMail *email = nodeMail->data;
997 gchar *addr = addressbook_format_address( ( AddressObject * ) email );
998 compose_entry_append( compose, addr, (ComposeEntryType) data );
1000 nodeMail = g_list_next( nodeMail );
1006 static void addressbook_menubar_set_sensitive( gboolean sensitive ) {
1007 menu_set_sensitive( addrbook.menu_factory, "/File/New Book", sensitive );
1008 menu_set_sensitive( addrbook.menu_factory, "/File/New vCard", sensitive );
1010 menu_set_sensitive( addrbook.menu_factory, "/File/New J-Pilot", sensitive );
1013 menu_set_sensitive( addrbook.menu_factory, "/File/New Server", sensitive );
1015 menu_set_sensitive( addrbook.menu_factory, "/File/Edit", sensitive );
1016 menu_set_sensitive( addrbook.menu_factory, "/File/Delete", sensitive );
1018 menu_set_sensitive( addrbook.menu_factory, "/Address/New Address", sensitive );
1019 menu_set_sensitive( addrbook.menu_factory, "/Address/New Group", sensitive );
1020 menu_set_sensitive( addrbook.menu_factory, "/Address/New Folder", sensitive );
1021 gtk_widget_set_sensitive( addrbook.reg_btn, sensitive );
1022 gtk_widget_set_sensitive( addrbook.del_btn, sensitive );
1025 static void addressbook_menuitem_set_sensitive( AddressObject *obj, GtkCTreeNode *node ) {
1026 gboolean canEdit = FALSE;
1027 gboolean canAdd = FALSE;
1028 gboolean canEditTr = TRUE;
1029 gboolean editAddress = FALSE;
1030 AddressTypeControlItem *atci = NULL;
1031 AddressDataSource *ds = NULL;
1032 AddressInterface *iface = NULL;
1034 if( obj == NULL ) return;
1035 if( obj->type == ADDR_INTERFACE ) {
1036 AdapterInterface *adapter = ADAPTER_INTERFACE(obj);
1037 iface = adapter->interface;
1039 if( iface->haveLibrary ) {
1040 /* Enable appropriate File / New command */
1041 atci = adapter->atci;
1042 menu_set_sensitive( addrbook.menu_factory, atci->menuCommand, TRUE );
1047 else if( obj->type == ADDR_DATASOURCE ) {
1048 AdapterDSource *ads = ADAPTER_DSOURCE(obj);
1049 ds = ads->dataSource;
1050 iface = ds->interface;
1051 if( ! iface->readOnly ) {
1052 canAdd = canEdit = editAddress = TRUE;
1054 if( ! iface->haveLibrary ) {
1055 canAdd = canEdit = editAddress = FALSE;
1058 else if( obj->type == ADDR_ITEM_FOLDER ) {
1059 ds = addressbook_find_datasource( addrbook.treeSelected );
1061 iface = ds->interface;
1062 if( ! iface->readOnly ) {
1063 canAdd = editAddress = TRUE;
1067 else if( obj->type == ADDR_ITEM_GROUP ) {
1068 ds = addressbook_find_datasource( addrbook.treeSelected );
1070 iface = ds->interface;
1071 if( ! iface->readOnly ) {
1077 if( addrbook.listSelected == NULL ) canEdit = FALSE;
1080 menu_set_sensitive( addrbook.menu_factory, "/Address/New Address", editAddress );
1081 menu_set_sensitive( addrbook.menu_factory, "/Address/New Group", canAdd );
1082 menu_set_sensitive( addrbook.menu_factory, "/Address/New Folder", canAdd );
1083 gtk_widget_set_sensitive( addrbook.reg_btn, editAddress );
1086 menu_set_sensitive( addrbook.menu_factory, "/Address/Edit", canEdit );
1087 menu_set_sensitive( addrbook.menu_factory, "/Address/Delete", canEdit );
1088 gtk_widget_set_sensitive( addrbook.del_btn, canEdit );
1090 menu_set_sensitive( addrbook.menu_factory, "/File/Edit", canEditTr );
1091 menu_set_sensitive( addrbook.menu_factory, "/File/Delete", canEditTr );
1094 static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node,
1095 gint column, gpointer data)
1097 AddressObject *obj = NULL;
1098 AdapterDSource *ads = NULL;
1099 AddressDataSource *ds = NULL;
1100 ItemFolder *rootFolder = NULL;
1102 addrbook.treeSelected = node;
1103 addrbook.listSelected = NULL;
1104 addressbook_status_show( "" );
1105 if( addrbook.entry != NULL ) gtk_entry_set_text(GTK_ENTRY(addrbook.entry), "");
1107 if( addrbook.clist ) gtk_clist_clear( GTK_CLIST(addrbook.clist) );
1108 if( node ) obj = gtk_ctree_node_get_row_data( ctree, node );
1109 if( obj == NULL ) return;
1111 addrbook.opened = node;
1113 if( obj->type == ADDR_DATASOURCE ) {
1114 /* Read from file */
1115 static gboolean tVal = TRUE;
1117 ads = ADAPTER_DSOURCE(obj);
1118 if( ads == NULL ) return;
1119 ds = ads->dataSource;
1120 if( ds == NULL ) return;
1122 if( addrindex_ds_get_modify_flag( ds ) ) {
1123 addrindex_ds_read_data( ds );
1126 if( ! addrindex_ds_get_read_flag( ds ) ) {
1127 addrindex_ds_read_data( ds );
1129 addressbook_ds_show_message( ds );
1131 if( ! addrindex_ds_get_access_flag( ds ) ) {
1132 /* Remove existing folders and groups */
1133 gtk_clist_freeze( GTK_CLIST(ctree) );
1134 addressbook_tree_remove_children( ctree, node );
1135 gtk_clist_thaw( GTK_CLIST(ctree) );
1137 /* Load folders into the tree */
1138 rootFolder = addrindex_ds_get_root_folder( ds );
1139 if( ds->type == ADDR_IF_JPILOT ) {
1140 addressbook_node_add_folder( node, ds, rootFolder, ADDR_CATEGORY );
1143 addressbook_node_add_folder( node, ds, rootFolder, ADDR_ITEM_FOLDER );
1145 addrindex_ds_set_access_flag( ds, &tVal );
1146 gtk_ctree_expand( ctree, node );
1150 /* Update address list */
1151 addressbook_set_clist( obj );
1153 /* Setup main menu selections */
1154 addressbook_menubar_set_sensitive( FALSE );
1155 addressbook_menuitem_set_sensitive( obj, node );
1157 addressbook_list_select_clear();
1161 static void addressbook_list_selected(GtkCList *clist, gint row, gint column,
1162 GdkEvent *event, gpointer data)
1164 if (event && event->type == GDK_2BUTTON_PRESS) {
1165 /* Handle double click */
1166 if (prefs_common.add_address_by_click &&
1167 addrbook.target_compose)
1168 addressbook_to_clicked(NULL, NULL);
1170 addressbook_edit_address_cb(NULL, 0, NULL);
1175 static void addressbook_list_select_show() {
1176 GList *node = _addressListSelection_;
1178 printf( "show selection...>>>\n" );
1179 while( node != NULL ) {
1180 AddressObject *obj = ( AddressObject * ) node->data;
1182 printf( "- %d : '%s'\n", obj->type, obj->name );
1183 if( obj->type == ADDR_ITEM_GROUP ) {
1184 ItemGroup *group = ( ItemGroup * ) obj;
1185 GList *node = group->listEMail;
1187 ItemEMail *email = node->data;
1188 addr = addressbook_format_address( ( AddressObject * ) email );
1190 printf( "\tgrp >%s<\n", addr );
1193 node = g_list_next( node );
1197 addr = addressbook_format_address( obj );
1199 printf( "\t>%s<\n", addr );
1207 node = g_list_next( node );
1209 printf( "show selection...<<<\n" );
1213 static void addressbook_list_select_clear() {
1214 if( _addressListSelection_ ) {
1215 g_list_free( _addressListSelection_ );
1217 _addressListSelection_ = NULL;
1220 static void addressbook_list_select_add( AddressObject *obj ) {
1222 if( obj->type == ADDR_ITEM_PERSON ||
1223 obj->type == ADDR_ITEM_EMAIL ||
1224 obj->type == ADDR_ITEM_GROUP ) {
1225 if( ! g_list_find( _addressListSelection_, obj ) ) {
1226 _addressListSelection_ = g_list_append( _addressListSelection_, obj );
1230 /* addressbook_list_select_show(); */
1233 static void addressbook_list_select_remove( AddressObject *obj ) {
1234 if( obj == NULL ) return;
1235 if( _addressListSelection_ ) {
1236 _addressListSelection_ = g_list_remove( _addressListSelection_, obj );
1238 /* addressbook_list_select_show(); */
1241 static void addressbook_list_row_selected( GtkCTree *clist, GtkCTreeNode *node, gint column, gpointer data ) {
1242 GtkEntry *entry = GTK_ENTRY(addrbook.entry);
1243 AddressObject *obj = NULL;
1244 AddressObject *pobj = NULL;
1245 AdapterDSource *ads = NULL;
1246 AddressInterface *iface = NULL;
1247 AddressDataSource *ds = NULL;
1248 gboolean canEdit = FALSE;
1249 gboolean canDelete = FALSE;
1251 gtk_entry_set_text( entry, "" );
1252 addrbook.listSelected = node;
1253 obj = gtk_ctree_node_get_row_data( clist, node );
1255 /* printf( "list select: %d : '%s'\n", obj->type, obj->name ); */
1256 addressbook_list_select_add( obj );
1259 pobj = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), addrbook.treeSelected );
1260 if( pobj == NULL ) return;
1262 menu_set_insensitive_all( GTK_MENU_SHELL(addrbook.list_popup) );
1264 if( pobj->type == ADDR_DATASOURCE ) {
1265 ads = ADAPTER_DSOURCE(pobj);
1266 ds = ads->dataSource;
1267 iface = ds->interface;
1268 if( ! iface->readOnly ) {
1270 menu_set_sensitive( addrbook.list_factory, "/New Address", TRUE );
1271 menu_set_sensitive( addrbook.list_factory, "/New Folder", TRUE );
1272 menu_set_sensitive( addrbook.list_factory, "/New Group", TRUE );
1273 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1276 else if( pobj->type != ADDR_INTERFACE ) {
1277 ds = addressbook_find_datasource( addrbook.treeSelected );
1278 iface = ds->interface;
1279 if( ! iface->readOnly ) {
1280 if( pobj->type == ADDR_ITEM_FOLDER || pobj->type == ADDR_ITEM_GROUP ) {
1282 menu_set_sensitive( addrbook.list_factory, "/New Address", TRUE );
1283 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1285 if( pobj->type == ADDR_ITEM_FOLDER ) {
1287 menu_set_sensitive( addrbook.list_factory, "/New Folder", TRUE );
1288 menu_set_sensitive( addrbook.list_factory, "/New Group", TRUE );
1292 if( obj == NULL ) canEdit = FALSE;
1293 canDelete = canEdit;
1294 if( GTK_CLIST(clist)->selection && GTK_CLIST(clist)->selection->next ) canEdit = FALSE;
1296 menu_set_sensitive( addrbook.list_factory, "/Edit", canEdit );
1297 menu_set_sensitive( addrbook.list_factory, "/Delete", canDelete );
1299 menu_set_sensitive( addrbook.menu_factory, "/Address/Edit", canEdit );
1300 menu_set_sensitive( addrbook.menu_factory, "/Address/Delete", canDelete );
1302 gtk_widget_set_sensitive( addrbook.del_btn, canDelete );
1306 static void addressbook_list_row_unselected( GtkCTree *ctree, GtkCTreeNode *node, gint column, gpointer data ) {
1309 obj = gtk_ctree_node_get_row_data( ctree, node );
1311 /* g_print( "list unselect: %d : '%s'\n", obj->type, obj->name ); */
1312 addressbook_list_select_remove( obj );
1316 static void addressbook_entry_gotfocus( GtkWidget *widget ) {
1317 gtk_editable_select_region( GTK_EDITABLE(addrbook.entry), 0, -1 );
1320 static void addressbook_list_button_pressed(GtkWidget *widget,
1321 GdkEventButton *event,
1324 if( ! event ) return;
1325 if( event->button == 3 ) {
1326 gtk_menu_popup( GTK_MENU(addrbook.list_popup), NULL, NULL, NULL, NULL,
1327 event->button, event->time );
1331 static void addressbook_list_button_released(GtkWidget *widget,
1332 GdkEventButton *event,
1337 static void addressbook_tree_button_pressed(GtkWidget *ctree,
1338 GdkEventButton *event,
1341 GtkCList *clist = GTK_CLIST(ctree);
1343 AddressObject *obj = NULL;
1344 /* GtkCTreeNode *node; */
1345 AdapterDSource *ads = NULL;
1346 AddressInterface *iface = NULL;
1347 AddressDataSource *ds = NULL;
1348 /* AddressTypeControlItem *atci = NULL; */
1349 gboolean canEdit = FALSE;
1351 if( ! event ) return;
1352 addressbook_menubar_set_sensitive( FALSE );
1354 if( gtk_clist_get_selection_info( clist, event->x, event->y, &row, &column ) ) {
1355 gtk_clist_select_row( clist, row, column );
1356 gtkut_clist_set_focus_row(clist, row);
1357 obj = gtk_clist_get_row_data( clist, row );
1360 menu_set_insensitive_all(GTK_MENU_SHELL(addrbook.tree_popup));
1362 if( obj == NULL ) return;
1363 if (obj->type == ADDR_DATASOURCE) {
1364 ads = ADAPTER_DSOURCE(obj);
1365 ds = ads->dataSource;
1366 iface = ds->interface;
1368 if( ! iface->readOnly ) {
1369 menu_set_sensitive( addrbook.tree_factory, "/New Address", TRUE );
1370 menu_set_sensitive( addrbook.tree_factory, "/New Folder", TRUE );
1371 menu_set_sensitive( addrbook.tree_factory, "/New Group", TRUE );
1372 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1375 else if (obj->type == ADDR_ITEM_FOLDER) {
1376 ds = addressbook_find_datasource( addrbook.treeSelected );
1377 iface = ds->interface;
1378 if( ! iface->readOnly ) {
1380 menu_set_sensitive( addrbook.tree_factory, "/New Address", TRUE );
1381 menu_set_sensitive( addrbook.tree_factory, "/New Folder", TRUE );
1382 menu_set_sensitive( addrbook.tree_factory, "/New Group", TRUE );
1383 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1386 else if (obj->type == ADDR_ITEM_GROUP) {
1387 ds = addressbook_find_datasource( addrbook.treeSelected );
1388 iface = ds->interface;
1389 if( ! iface->readOnly ) {
1391 menu_set_sensitive( addrbook.tree_factory, "/New Address", TRUE );
1392 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1397 menu_set_sensitive( addrbook.tree_factory, "/Edit", canEdit );
1398 menu_set_sensitive( addrbook.tree_factory, "/Delete", canEdit );
1399 menu_set_sensitive( addrbook.menu_factory, "/File/Edit", canEdit );
1400 menu_set_sensitive( addrbook.menu_factory, "/File/Delete", canEdit );
1402 if( event->button == 3 ) {
1403 gtk_menu_popup(GTK_MENU(addrbook.tree_popup), NULL, NULL, NULL, NULL,
1404 event->button, event->time);
1409 static void addressbook_tree_button_released(GtkWidget *ctree,
1410 GdkEventButton *event,
1413 gtk_ctree_select(GTK_CTREE(addrbook.ctree), addrbook.opened);
1414 gtkut_ctree_set_focus_row(GTK_CTREE(addrbook.ctree), addrbook.opened);
1417 static void addressbook_popup_close(GtkMenuShell *menu_shell, gpointer data)
1419 if (!addrbook.opened) return;
1421 gtk_ctree_select(GTK_CTREE(addrbook.ctree), addrbook.opened);
1422 gtkut_ctree_set_focus_row(GTK_CTREE(addrbook.ctree),
1426 static void addressbook_new_folder_cb(gpointer data, guint action,
1429 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1430 AddressObject *obj = NULL;
1431 AddressDataSource *ds = NULL;
1432 AddressBookFile *abf = NULL;
1433 ItemFolder *parentFolder = NULL;
1434 ItemFolder *folder = NULL;
1436 if( ! addrbook.treeSelected ) return;
1437 obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
1438 if( obj == NULL ) return;
1439 ds = addressbook_find_datasource( addrbook.treeSelected );
1440 if( ds == NULL ) return;
1442 if( obj->type == ADDR_DATASOURCE ) {
1443 if( ADAPTER_DSOURCE(obj)->subType != ADDR_BOOK ) return;
1445 else if( obj->type == ADDR_ITEM_FOLDER ) {
1446 parentFolder = ADAPTER_FOLDER(obj)->itemFolder;
1452 abf = ds->rawDataSource;
1453 if( abf == NULL ) return;
1454 folder = addressbook_edit_folder( abf, parentFolder, NULL );
1457 nn = addressbook_node_add_folder( addrbook.treeSelected, ds, folder, ADDR_ITEM_FOLDER );
1458 gtk_ctree_expand( ctree, addrbook.treeSelected );
1459 if( addrbook.treeSelected == addrbook.opened ) addressbook_set_clist(obj);
1464 static void addressbook_new_group_cb(gpointer data, guint action,
1467 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1468 AddressObject *obj = NULL;
1469 AddressDataSource *ds = NULL;
1470 AddressBookFile *abf = NULL;
1471 ItemFolder *parentFolder = NULL;
1472 ItemGroup *group = NULL;
1474 if( ! addrbook.treeSelected ) return;
1475 obj = gtk_ctree_node_get_row_data(ctree, addrbook.treeSelected);
1476 if( obj == NULL ) return;
1477 ds = addressbook_find_datasource( addrbook.treeSelected );
1478 if( ds == NULL ) return;
1480 if( obj->type == ADDR_DATASOURCE ) {
1481 if( ADAPTER_DSOURCE(obj)->subType != ADDR_BOOK ) return;
1483 else if( obj->type == ADDR_ITEM_FOLDER ) {
1484 parentFolder = ADAPTER_FOLDER(obj)->itemFolder;
1490 abf = ds->rawDataSource;
1491 if( abf == NULL ) return;
1492 group = addressbook_edit_group( abf, parentFolder, NULL );
1495 nn = addressbook_node_add_group( addrbook.treeSelected, ds, group );
1496 gtk_ctree_expand( ctree, addrbook.treeSelected );
1497 if( addrbook.treeSelected == addrbook.opened ) addressbook_set_clist(obj);
1502 static void addressbook_change_node_name(GtkCTreeNode *node, const gchar *name)
1504 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1507 GdkPixmap *pix_cl, *pix_op;
1508 GdkBitmap *mask_cl, *mask_op;
1509 gboolean is_leaf, expanded;
1511 gtk_ctree_get_node_info(ctree, node, text, &spacing,
1512 &pix_cl, &mask_cl, &pix_op, &mask_op,
1513 &is_leaf, &expanded);
1514 gtk_ctree_set_node_info(ctree, node, name, spacing,
1515 pix_cl, mask_cl, pix_op, mask_op,
1521 * Enter: obj Address object to edit.
1522 * node Node in tree.
1523 * Return: New name of data source.
1525 static gchar *addressbook_edit_datasource( AddressObject *obj, GtkCTreeNode *node ) {
1526 gchar *newName = NULL;
1527 AddressDataSource *ds = NULL;
1528 AddressInterface *iface = NULL;
1529 AdapterDSource *ads = NULL;
1531 ds = addressbook_find_datasource( node );
1532 if( ds == NULL ) return NULL;
1533 iface = ds->interface;
1534 if( ! iface->haveLibrary ) return NULL;
1536 /* Read data from data source */
1537 if( ! addrindex_ds_get_read_flag( ds ) ) {
1538 addrindex_ds_read_data( ds );
1542 ads = ADAPTER_DSOURCE(obj);
1543 if( ads->subType == ADDR_BOOK ) {
1544 if( addressbook_edit_book( _addressIndex_, ads ) == NULL ) return NULL;
1546 else if( ads->subType == ADDR_VCARD ) {
1547 if( addressbook_edit_vcard( _addressIndex_, ads ) == NULL ) return NULL;
1550 else if( ads->subType == ADDR_JPILOT ) {
1551 if( addressbook_edit_jpilot( _addressIndex_, ads ) == NULL ) return NULL;
1555 else if( ads->subType == ADDR_LDAP ) {
1556 if( addressbook_edit_ldap( _addressIndex_, ads ) == NULL ) return NULL;
1562 newName = obj->name;
1567 * Edit an object that is in the address tree area.
1569 static void addressbook_treenode_edit_cb(gpointer data, guint action,
1572 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1574 AddressDataSource *ds = NULL;
1575 AddressBookFile *abf = NULL;
1576 GtkCTreeNode *node = NULL, *parentNode = NULL;
1579 if( ! addrbook.treeSelected ) return;
1580 node = addrbook.treeSelected;
1581 if( GTK_CTREE_ROW(node)->level == 1 ) return;
1582 obj = gtk_ctree_node_get_row_data( ctree, node );
1583 if( obj == NULL ) return;
1584 parentNode = GTK_CTREE_ROW(node)->parent;
1586 ds = addressbook_find_datasource( node );
1587 if( ds == NULL ) return;
1589 if( obj->type == ADDR_DATASOURCE ) {
1590 name = addressbook_edit_datasource( obj, node );
1591 if( name == NULL ) return;
1594 abf = ds->rawDataSource;
1595 if( abf == NULL ) return;
1596 if( obj->type == ADDR_ITEM_FOLDER ) {
1597 AdapterFolder *adapter = ADAPTER_FOLDER(obj);
1598 ItemFolder *item = adapter->itemFolder;
1599 ItemFolder *parentFolder = NULL;
1600 parentFolder = ( ItemFolder * ) ADDRITEM_PARENT(item);
1601 if( addressbook_edit_folder( abf, parentFolder, item ) == NULL ) return;
1602 name = ADDRITEM_NAME(item);
1604 else if( obj->type == ADDR_ITEM_GROUP ) {
1605 AdapterGroup *adapter = ADAPTER_GROUP(obj);
1606 ItemGroup *item = adapter->itemGroup;
1607 ItemFolder *parentFolder = NULL;
1608 parentFolder = ( ItemFolder * ) ADDRITEM_PARENT(item);
1609 if( addressbook_edit_group( abf, parentFolder, item ) == NULL ) return;
1610 name = ADDRITEM_NAME(item);
1613 if( name && parentNode ) {
1614 /* Update node in tree view */
1615 addressbook_change_node_name( node, name );
1616 gtk_ctree_sort_node(ctree, parentNode);
1617 gtk_ctree_expand( ctree, node );
1618 gtk_ctree_select( ctree, node );
1623 * Delete an item from the tree widget.
1625 static void addressbook_treenode_delete_cb(gpointer data, guint action,
1628 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1629 GtkCTreeNode *node = NULL;
1633 AddressBookFile *abf = NULL;
1634 AdapterDSource *ads = NULL;
1635 AddressInterface *iface = NULL;
1636 AddressDataSource *ds = NULL;
1637 gboolean remFlag = FALSE;
1639 if( ! addrbook.treeSelected ) return;
1640 node = addrbook.treeSelected;
1641 if( GTK_CTREE_ROW(node)->level == 1 ) return;
1643 obj = gtk_ctree_node_get_row_data( ctree, node );
1644 g_return_if_fail(obj != NULL);
1646 if( obj->type == ADDR_DATASOURCE ) {
1647 ads = ADAPTER_DSOURCE(obj);
1648 if( ads == NULL ) return;
1649 ds = ads->dataSource;
1650 if( ds == NULL ) return;
1653 /* Must be folder or something else */
1654 ds = addressbook_find_datasource( node );
1655 if( ds == NULL ) return;
1657 /* Only allow deletion from non-readOnly data sources */
1658 iface = ds->interface;
1659 if( iface->readOnly ) return;
1662 /* Confirm deletion */
1663 if( obj->type == ADDR_ITEM_FOLDER ) {
1664 message = g_strdup_printf( _(
1665 "Do you want to delete the folder AND all addresses in `%s' ? \n" \
1666 "If deleting the folder only, addresses will be moved into parent folder." ),
1668 aval = alertpanel( _("Delete"), message, _("Folder only"), _("Folder and Addresses"), _("Cancel") );
1670 if( aval == G_ALERTOTHER ) return;
1673 message = g_strdup_printf(_("Really delete `%s' ?"), obj->name);
1674 aval = alertpanel(_("Delete"), message, _("Yes"), _("No"), NULL);
1676 if (aval != G_ALERTDEFAULT) return;
1679 /* Proceed with deletion */
1680 if( obj->type == ADDR_DATASOURCE ) {
1681 /* Remove data source. */
1682 if( addrindex_index_remove_datasource( _addressIndex_, ds ) ) {
1683 addressbook_free_child_adapters( node );
1688 abf = addressbook_get_book_file();
1689 if( abf == NULL ) return;
1692 if( obj->type == ADDR_ITEM_FOLDER ) {
1693 AdapterFolder *adapter = ADAPTER_FOLDER(obj);
1694 ItemFolder *item = adapter->itemFolder;
1695 if( aval == G_ALERTDEFAULT ) {
1696 /* Remove folder only */
1697 item = addrbook_remove_folder( abf, item );
1699 addritem_free_item_folder( item );
1700 addressbook_move_nodes_up( ctree, node );
1704 else if( aval == G_ALERTALTERNATE ) {
1705 /* Remove folder and addresses */
1706 item = addrbook_remove_folder_delete( abf, item );
1708 addritem_free_item_folder( item );
1709 addressbook_free_child_adapters( node );
1714 else if( obj->type == ADDR_ITEM_GROUP ) {
1715 AdapterGroup *adapter = ADAPTER_GROUP(obj);
1716 ItemGroup *item = adapter->itemGroup;
1718 item = addrbook_remove_group( abf, item );
1720 addritem_free_item_group( item );
1726 /* Free up adapter and remove node. */
1727 addressbook_free_adapter( node );
1728 gtk_ctree_remove_node(ctree, node );
1732 static void addressbook_new_address_cb( gpointer data, guint action, GtkWidget *widget ) {
1733 AddressObject *pobj = NULL;
1734 AddressDataSource *ds = NULL;
1735 AddressBookFile *abf = NULL;
1737 pobj = gtk_ctree_node_get_row_data(GTK_CTREE(addrbook.ctree), addrbook.treeSelected);
1738 if( pobj == NULL ) return;
1739 ds = addressbook_find_datasource( GTK_CTREE_NODE(addrbook.treeSelected) );
1740 if( ds == NULL ) return;
1742 abf = ds->rawDataSource;
1743 if( abf == NULL ) return;
1745 if( pobj->type == ADDR_DATASOURCE ) {
1746 if( ADAPTER_DSOURCE(pobj)->subType == ADDR_BOOK ) {
1748 ItemPerson *person = addressbook_edit_person( abf, NULL, NULL, FALSE );
1750 if( addrbook.treeSelected == addrbook.opened ) {
1751 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
1756 else if( pobj->type == ADDR_ITEM_FOLDER ) {
1758 ItemFolder *folder = ADAPTER_FOLDER(pobj)->itemFolder;
1759 ItemPerson *person = addressbook_edit_person( abf, folder, NULL, FALSE );
1761 if (addrbook.treeSelected == addrbook.opened) {
1762 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
1766 else if( pobj->type == ADDR_ITEM_GROUP ) {
1767 /* New address in group */
1768 ItemGroup *group = ADAPTER_GROUP(pobj)->itemGroup;
1769 if( addressbook_edit_group( abf, NULL, group ) == NULL ) return;
1770 if (addrbook.treeSelected == addrbook.opened) {
1771 /* Change node name in tree. */
1772 addressbook_change_node_name( addrbook.treeSelected, ADDRITEM_NAME(group) );
1773 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
1779 * Search for specified group in address index tree.
1781 static GtkCTreeNode *addressbook_find_group_node( GtkCTreeNode *parent, ItemGroup *group ) {
1782 GtkCTreeNode *node = NULL;
1783 GtkCTreeRow *currRow;
1785 currRow = GTK_CTREE_ROW( parent );
1787 node = currRow->children;
1789 AddressObject *obj = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), node );
1790 if( obj->type == ADDR_ITEM_GROUP ) {
1791 ItemGroup *g = ADAPTER_GROUP(obj)->itemGroup;
1792 if( g == group ) return node;
1794 currRow = GTK_CTREE_ROW(node);
1795 node = currRow->sibling;
1801 static AddressBookFile *addressbook_get_book_file() {
1802 AddressBookFile *abf = NULL;
1803 AddressDataSource *ds = NULL;
1805 ds = addressbook_find_datasource( addrbook.treeSelected );
1806 if( ds == NULL ) return NULL;
1807 if( ds->type == ADDR_IF_BOOK ) abf = ds->rawDataSource;
1811 static void addressbook_tree_remove_children( GtkCTree *ctree, GtkCTreeNode *parent ) {
1815 /* Remove existing folders and groups */
1816 row = GTK_CTREE_ROW( parent );
1818 while( (node = row->children) ) {
1819 gtk_ctree_remove_node( ctree, node );
1824 static void addressbook_move_nodes_up( GtkCTree *ctree, GtkCTreeNode *node ) {
1825 GtkCTreeNode *parent, *child;
1826 GtkCTreeRow *currRow;
1827 currRow = GTK_CTREE_ROW( node );
1829 parent = currRow->parent;
1830 while( (child = currRow->children) ) {
1831 gtk_ctree_move( ctree, child, parent, node );
1833 gtk_ctree_sort_node( ctree, parent );
1837 static void addressbook_edit_address_cb( gpointer data, guint action, GtkWidget *widget ) {
1838 GtkCTree *clist = GTK_CTREE(addrbook.clist);
1840 AddressObject *obj = NULL, *pobj = NULL;
1841 AddressDataSource *ds = NULL;
1842 GtkCTreeNode *node = NULL, *parentNode = NULL;
1844 AddressBookFile *abf = NULL;
1846 if( addrbook.listSelected == NULL ) return;
1847 obj = gtk_ctree_node_get_row_data( clist, addrbook.listSelected );
1848 g_return_if_fail(obj != NULL);
1850 ctree = GTK_CTREE( addrbook.ctree );
1851 pobj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
1852 node = gtk_ctree_find_by_row_data( ctree, addrbook.treeSelected, obj );
1854 ds = addressbook_find_datasource( GTK_CTREE_NODE(addrbook.treeSelected) );
1855 if( ds == NULL ) return;
1857 abf = addressbook_get_book_file();
1858 if( abf == NULL ) return;
1859 if( obj->type == ADDR_ITEM_EMAIL ) {
1860 ItemEMail *email = ( ItemEMail * ) obj;
1862 if( email == NULL ) return;
1863 if( pobj && pobj->type == ADDR_ITEM_GROUP ) {
1864 /* Edit parent group */
1865 AdapterGroup *adapter = ADAPTER_GROUP(pobj);
1866 ItemGroup *itemGrp = adapter->itemGroup;
1867 if( addressbook_edit_group( abf, NULL, itemGrp ) == NULL ) return;
1868 name = ADDRITEM_NAME(itemGrp);
1869 node = addrbook.treeSelected;
1870 parentNode = GTK_CTREE_ROW(node)->parent;
1873 /* Edit person - email page */
1874 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
1875 if( addressbook_edit_person( abf, NULL, person, TRUE ) == NULL ) return;
1876 gtk_ctree_select( ctree, addrbook.opened );
1877 invalidate_address_completion();
1881 else if( obj->type == ADDR_ITEM_PERSON ) {
1882 /* Edit person - basic page */
1883 ItemPerson *person = ( ItemPerson * ) obj;
1884 if( addressbook_edit_person( abf, NULL, person, FALSE ) == NULL ) return;
1885 gtk_ctree_select( ctree, addrbook.opened);
1886 invalidate_address_completion();
1889 else if( obj->type == ADDR_ITEM_GROUP ) {
1890 ItemGroup *itemGrp = ( ItemGroup * ) obj;
1891 if( addressbook_edit_group( abf, NULL, itemGrp ) == NULL ) return;
1892 parentNode = addrbook.treeSelected;
1893 node = addressbook_find_group_node( parentNode, itemGrp );
1894 name = ADDRITEM_NAME(itemGrp);
1900 /* Update tree node with node name */
1901 if( node == NULL ) return;
1902 addressbook_change_node_name( node, name );
1903 gtk_ctree_sort_node( ctree, parentNode );
1904 gtk_ctree_select( ctree, addrbook.opened );
1907 static void addressbook_delete_address_cb(gpointer data, guint action,
1910 addressbook_del_clicked(NULL, NULL);
1913 static void close_cb(gpointer data, guint action, GtkWidget *widget)
1915 addressbook_close();
1918 static void addressbook_file_save_cb( gpointer data, guint action, GtkWidget *widget ) {
1919 addressbook_export_to_file();
1922 static void addressbook_person_expand_node( GtkCTree *ctree, GList *node, gpointer *data ) {
1924 ItemPerson *person = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
1925 if( person ) addritem_person_set_opened( person, TRUE );
1929 static void addressbook_person_collapse_node( GtkCTree *ctree, GList *node, gpointer *data ) {
1931 ItemPerson *person = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
1932 if( person ) addritem_person_set_opened( person, FALSE );
1936 static gchar *addressbook_format_item_clist( ItemPerson *person, ItemEMail *email ) {
1938 gchar *eMailAlias = ADDRITEM_NAME(email);
1939 if( eMailAlias && *eMailAlias != '\0' ) {
1941 str = g_strdup_printf( "%s - %s", ADDRITEM_NAME(person), eMailAlias );
1944 str = g_strdup( eMailAlias );
1950 static void addressbook_load_group( GtkCTree *clist, ItemGroup *itemGroup ) {
1951 GList *items = itemGroup->listEMail;
1952 AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_EMAIL );
1953 for( ; items != NULL; items = g_list_next( items ) ) {
1954 GtkCTreeNode *nodeEMail = NULL;
1955 gchar *text[N_COLS];
1956 ItemEMail *email = items->data;
1960 if( ! email ) continue;
1962 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
1963 str = addressbook_format_item_clist( person, email );
1965 text[COL_NAME] = str;
1968 text[COL_NAME] = ADDRITEM_NAME(person);
1970 text[COL_ADDRESS] = email->address;
1971 text[COL_REMARKS] = email->remarks;
1972 nodeEMail = gtk_ctree_insert_node(
1974 text, FOLDER_SPACING,
1975 atci->iconXpm, atci->maskXpm,
1976 atci->iconXpmOpen, atci->maskXpmOpen,
1978 gtk_ctree_node_set_row_data( clist, nodeEMail, email );
1984 static void addressbook_folder_load_person( GtkCTree *clist, ItemFolder *itemFolder ) {
1986 AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_PERSON );
1987 AddressTypeControlItem *atciMail = addrbookctl_lookup( ADDR_ITEM_EMAIL );
1989 if( atci == NULL ) return;
1990 if( atciMail == NULL ) return;
1992 /* Load email addresses */
1993 items = addritem_folder_get_person_list( itemFolder );
1994 for( ; items != NULL; items = g_list_next( items ) ) {
1995 GtkCTreeNode *nodePerson = NULL;
1996 GtkCTreeNode *nodeEMail = NULL;
1997 gchar *text[N_COLS];
1998 gboolean flgFirst = TRUE, haveAddr = FALSE;
2003 person = ( ItemPerson * ) items->data;
2004 if( person == NULL ) continue;
2006 text[COL_NAME] = NULL;
2007 node = person->listEMail;
2009 ItemEMail *email = node->data;
2010 gchar *eMailAddr = NULL;
2011 node = g_list_next( node );
2013 text[COL_ADDRESS] = email->address;
2014 text[COL_REMARKS] = email->remarks;
2015 eMailAddr = ADDRITEM_NAME(email);
2016 if( eMailAddr && *eMailAddr == '\0' ) eMailAddr = NULL;
2018 /* First email belongs with person */
2019 gchar *str = addressbook_format_item_clist( person, email );
2021 text[COL_NAME] = str;
2024 text[COL_NAME] = ADDRITEM_NAME(person);
2026 nodePerson = gtk_ctree_insert_node(
2028 text, FOLDER_SPACING,
2029 atci->iconXpm, atci->maskXpm,
2030 atci->iconXpmOpen, atci->maskXpmOpen,
2031 FALSE, person->isOpened );
2034 gtk_ctree_node_set_row_data(clist, nodePerson, person );
2037 /* Subsequent email is a child node of person */
2038 text[COL_NAME] = ADDRITEM_NAME(email);
2039 nodeEMail = gtk_ctree_insert_node(
2040 clist, nodePerson, NULL,
2041 text, FOLDER_SPACING,
2042 atciMail->iconXpm, atciMail->maskXpm,
2043 atciMail->iconXpmOpen, atciMail->maskXpmOpen,
2045 gtk_ctree_node_set_row_data(clist, nodeEMail, email );
2051 /* Have name without EMail */
2052 text[COL_NAME] = ADDRITEM_NAME(person);
2053 text[COL_ADDRESS] = NULL;
2054 text[COL_REMARKS] = NULL;
2055 nodePerson = gtk_ctree_insert_node(
2057 text, FOLDER_SPACING,
2058 atci->iconXpm, atci->maskXpm,
2059 atci->iconXpmOpen, atci->maskXpmOpen,
2060 FALSE, person->isOpened );
2061 gtk_ctree_node_set_row_data(clist, nodePerson, person );
2063 gtk_ctree_sort_node(GTK_CTREE(clist), NULL);
2065 /* Free up the list */
2066 mgu_clear_list( items );
2067 g_list_free( items );
2070 static void addressbook_folder_load_group( GtkCTree *clist, ItemFolder *itemFolder ) {
2072 AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_GROUP );
2074 /* Load any groups */
2075 if( ! atci ) return;
2076 items = addritem_folder_get_group_list( itemFolder );
2077 for( ; items != NULL; items = g_list_next( items ) ) {
2078 GtkCTreeNode *nodeGroup = NULL;
2079 gchar *text[N_COLS];
2080 ItemGroup *group = items->data;
2081 if( group == NULL ) continue;
2082 text[COL_NAME] = ADDRITEM_NAME(group);
2083 text[COL_ADDRESS] = NULL;
2084 text[COL_REMARKS] = NULL;
2085 nodeGroup = gtk_ctree_insert_node(clist, NULL, NULL,
2086 text, FOLDER_SPACING,
2087 atci->iconXpm, atci->maskXpm,
2088 atci->iconXpmOpen, atci->maskXpmOpen,
2090 gtk_ctree_node_set_row_data(clist, nodeGroup, group );
2091 gtk_ctree_sort_node(clist, NULL);
2093 /* Free up the list */
2094 mgu_clear_list( items );
2095 g_list_free( items );
2099 * Load data sources into list.
2101 static void addressbook_node_load_datasource( GtkCTree *clist, AddressObject *obj ) {
2102 AdapterInterface *adapter;
2103 AddressInterface *iface;
2104 AddressTypeControlItem *atci = NULL;
2105 /* AddressDataSource *ds; */
2106 GtkCTreeNode *newNode, *node;
2108 GtkCell *cell = NULL;
2109 gchar *text[N_COLS];
2111 adapter = ADAPTER_INTERFACE(obj);
2112 if( adapter == NULL ) return;
2113 iface = adapter->interface;
2114 atci = adapter->atci;
2115 if( atci == NULL ) return;
2117 /* Create nodes in list copying values for data sources in tree */
2118 row = GTK_CTREE_ROW( adapter->treeNode );
2120 node = row->children;
2122 gpointer data = gtk_ctree_node_get_row_data( clist, node );
2123 row = GTK_CTREE_ROW( node );
2124 cell = ( ( GtkCListRow * )row )->cell;
2125 text[COL_NAME] = cell->u.text;
2126 text[COL_ADDRESS] = NULL;
2127 text[COL_REMARKS] = NULL;
2128 newNode = gtk_ctree_insert_node( clist, NULL, NULL,
2129 text, FOLDER_SPACING,
2130 atci->iconXpm, atci->maskXpm,
2131 atci->iconXpmOpen, atci->maskXpmOpen,
2133 gtk_ctree_node_set_row_data( clist, newNode, data );
2134 node = row->sibling;
2138 gtk_ctree_sort_node( clist, NULL );
2141 static AddressDataSource *addressbook_find_datasource( GtkCTreeNode *node ) {
2142 AddressDataSource *ds = NULL;
2145 g_return_val_if_fail(addrbook.ctree != NULL, NULL);
2148 if( GTK_CTREE_ROW(node)->level < 2 ) return NULL;
2149 ao = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), node );
2151 /* printf( "ao->type = %d\n", ao->type ); */
2152 if( ao->type == ADDR_DATASOURCE ) {
2153 AdapterDSource *ads = ADAPTER_DSOURCE(ao);
2154 /* printf( "found it\n" ); */
2155 ds = ads->dataSource;
2159 node = GTK_CTREE_ROW(node)->parent;
2165 * Load address list widget with children of specified object.
2166 * Enter: obj Parent object to be loaded.
2168 static void addressbook_set_clist( AddressObject *obj ) {
2169 GtkCTree *ctreelist = GTK_CTREE(addrbook.clist);
2170 GtkCList *clist = GTK_CLIST(addrbook.clist);
2171 AddressDataSource *ds = NULL;
2172 AdapterDSource *ads = NULL;
2175 gtk_clist_clear(clist);
2179 if( obj->type == ADDR_INTERFACE ) {
2180 /* printf( "set_clist: loading datasource...\n" ); */
2181 /* addressbook_node_load_datasource( clist, obj ); */
2185 gtk_clist_freeze(clist);
2186 gtk_clist_clear(clist);
2188 if( obj->type == ADDR_DATASOURCE ) {
2189 ads = ADAPTER_DSOURCE(obj);
2190 ds = ADAPTER_DSOURCE(obj)->dataSource;
2192 /* Load root folder */
2193 ItemFolder *rootFolder = NULL;
2194 rootFolder = addrindex_ds_get_root_folder( ds );
2195 addressbook_folder_load_person( ctreelist, addrindex_ds_get_root_folder( ds ) );
2196 addressbook_folder_load_group( ctreelist, addrindex_ds_get_root_folder( ds ) );
2200 if( obj->type == ADDR_ITEM_GROUP ) {
2202 ItemGroup *itemGroup = ADAPTER_GROUP(obj)->itemGroup;
2203 addressbook_load_group( ctreelist, itemGroup );
2205 else if( obj->type == ADDR_ITEM_FOLDER ) {
2207 ItemFolder *itemFolder = ADAPTER_FOLDER(obj)->itemFolder;
2208 addressbook_folder_load_person( ctreelist, itemFolder );
2209 addressbook_folder_load_group( ctreelist, itemFolder );
2213 gtk_clist_sort(clist);
2214 gtk_clist_thaw(clist);
2218 * Free adaptor for specified node.
2220 static void addressbook_free_adapter( GtkCTreeNode *node ) {
2223 g_return_if_fail(addrbook.ctree != NULL);
2226 if( GTK_CTREE_ROW(node)->level < 2 ) return;
2227 ao = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), node );
2228 if( ao == NULL ) return;
2229 if( ao->type == ADDR_INTERFACE ) {
2230 AdapterInterface *ai = ADAPTER_INTERFACE(ao);
2231 addrbookctl_free_interface( ai );
2233 else if( ao->type == ADDR_DATASOURCE ) {
2234 AdapterDSource *ads = ADAPTER_DSOURCE(ao);
2235 addrbookctl_free_datasource( ads );
2237 else if( ao->type == ADDR_ITEM_FOLDER ) {
2238 AdapterFolder *af = ADAPTER_FOLDER(ao);
2239 addrbookctl_free_folder( af );
2241 else if( ao->type == ADDR_ITEM_GROUP ) {
2242 AdapterGroup *ag = ADAPTER_GROUP(ao);
2243 addrbookctl_free_group( ag );
2245 gtk_ctree_node_set_row_data( GTK_CTREE(addrbook.ctree), node, NULL );
2250 * Free all children adapters.
2252 static void addressbook_free_child_adapters( GtkCTreeNode *node ) {
2253 GtkCTreeNode *parent, *child;
2254 GtkCTreeRow *currRow;
2256 if( node == NULL ) return;
2257 currRow = GTK_CTREE_ROW( node );
2259 parent = currRow->parent;
2260 child = currRow->children;
2262 addressbook_free_child_adapters( child );
2263 addressbook_free_adapter( child );
2264 currRow = GTK_CTREE_ROW( child );
2265 child = currRow->sibling;
2270 AdapterDSource *addressbook_create_ds_adapter( AddressDataSource *ds,
2271 AddressObjectType otype, gchar *name )
2273 AdapterDSource *adapter = g_new0( AdapterDSource, 1 );
2274 ADDRESS_OBJECT(adapter)->type = ADDR_DATASOURCE;
2275 ADDRESS_OBJECT_NAME(adapter) = g_strdup( name );
2276 adapter->dataSource = ds;
2277 adapter->subType = otype;
2281 void addressbook_ads_set_name( AdapterDSource *adapter, gchar *value ) {
2282 ADDRESS_OBJECT_NAME(adapter) = mgu_replace_string( ADDRESS_OBJECT_NAME(adapter), value );
2286 * Load tree from address index with the initial data.
2288 static void addressbook_load_tree( void ) {
2289 GtkCTree *ctree = GTK_CTREE( addrbook.ctree );
2290 GList *nodeIf, *nodeDS;
2291 AdapterInterface *adapter;
2292 AddressInterface *iface;
2293 AddressTypeControlItem *atci;
2294 AddressDataSource *ds;
2295 AdapterDSource *ads;
2296 GtkCTreeNode *node, *newNode;
2299 nodeIf = _addressInterfaceList_;
2301 adapter = nodeIf->data;
2302 node = adapter->treeNode;
2303 iface = adapter->interface;
2304 atci = adapter->atci;
2306 if( iface->useInterface ) {
2307 /* Load data sources below interface node */
2308 nodeDS = iface->listSource;
2312 name = addrindex_ds_get_name( ds );
2313 ads = addressbook_create_ds_adapter( ds, atci->objectType, name );
2314 newNode = addressbook_add_object( node, ADDRESS_OBJECT(ads) );
2315 nodeDS = g_list_next( nodeDS );
2317 gtk_ctree_expand( ctree, node );
2320 nodeIf = g_list_next( nodeIf );
2325 * Convert the old address book to new format.
2327 static gboolean addressbook_convert( AddressIndex *addrIndex ) {
2328 gboolean retVal = FALSE;
2329 gboolean errFlag = TRUE;
2332 /* Read old address book, performing conversion */
2333 debug_print( "Reading and converting old address book...\n" );
2334 addrindex_set_file_name( addrIndex, ADDRESSBOOK_OLD_FILE );
2335 addrindex_read_data( addrIndex );
2336 if( addrIndex->retVal == MGU_NO_FILE ) {
2337 /* We do not have a file - new user */
2338 debug_print( "New user... create new books...\n" );
2339 addrindex_create_new_books( addrIndex );
2340 if( addrIndex->retVal == MGU_SUCCESS ) {
2341 /* Save index file */
2342 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2343 addrindex_save_data( addrIndex );
2344 if( addrIndex->retVal == MGU_SUCCESS ) {
2349 msg = _( "New user, could not save index file." );
2353 msg = _( "New user, could not save address book files." );
2357 /* We have an old file */
2358 if( addrIndex->wasConverted ) {
2359 /* Converted successfully - save address index */
2360 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2361 addrindex_save_data( addrIndex );
2362 if( addrIndex->retVal == MGU_SUCCESS ) {
2363 msg = _( "Old address book converted successfully." );
2368 msg = _("Old address book converted,\n"
2369 "could not save new address index file" );
2373 /* File conversion failed - just create new books */
2374 debug_print( "File conversion failed... just create new books...\n" );
2375 addrindex_create_new_books( addrIndex );
2376 if( addrIndex->retVal == MGU_SUCCESS ) {
2378 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2379 addrindex_save_data( addrIndex );
2380 if( addrIndex->retVal == MGU_SUCCESS ) {
2381 msg = _("Could not convert address book,\n"
2382 "but created empty new address book files." );
2387 msg = _("Could not convert address book,\n"
2388 "could not create new address book files." );
2392 msg = _("Could not convert address book\n"
2393 "and could not create new address book files." );
2398 debug_print( "Error\n%s\n", msg );
2399 alertpanel( _( "Addressbook conversion error" ), msg, _( "Close" ), NULL, NULL );
2402 debug_print( "Warning\n%s\n", msg );
2403 alertpanel( _( "Addressbook conversion" ), msg, _( "Close" ), NULL, NULL );
2409 void addressbook_read_file( void ) {
2410 AddressIndex *addrIndex = NULL;
2412 debug_print( "Reading address index...\n" );
2413 if( _addressIndex_ ) {
2414 debug_print( "address book already read!!!\n" );
2418 addrIndex = addrindex_create_index();
2420 /* Use new address book index. */
2421 addrindex_set_file_path( addrIndex, get_rc_dir() );
2422 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2423 addrindex_read_data( addrIndex );
2424 if( addrIndex->retVal == MGU_NO_FILE ) {
2425 /* Conversion required */
2426 debug_print( "Converting...\n" );
2427 if( addressbook_convert( addrIndex ) ) {
2428 _addressIndex_ = addrIndex;
2431 else if( addrIndex->retVal == MGU_SUCCESS ) {
2432 _addressIndex_ = addrIndex;
2435 /* Error reading address book */
2436 debug_print( "Could not read address index.\n" );
2437 addrindex_print_index( addrIndex, stdout );
2438 alertpanel( _( "Addressbook Error" ),
2439 _( "Could not read address index" ),
2440 _( "Close" ), NULL, NULL );
2442 debug_print( "done.\n" );
2446 void addressbook_read_file_old( void ) {
2447 AddressIndex *addrIndex = NULL;
2448 gboolean errFlag = TRUE;
2451 if( _addressIndex_ ) {
2452 debug_print( "address book already read!!!\n" );
2456 addrIndex = addrindex_create_index();
2458 /* Use use new address book. */
2459 /* addrindex_set_file_path( addrIndex, "/home/match/tmp/empty-dir" ); */
2460 addrindex_set_file_path( addrIndex, get_rc_dir() );
2461 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2463 debug_print( "Reading address index...\n" );
2464 addrindex_read_data( addrIndex );
2465 if( addrIndex->retVal == MGU_NO_FILE ) {
2466 /* Read old address book, performing conversion */
2467 debug_print( "Reading and converting old address book...\n" );
2468 addrindex_set_file_name( addrIndex, ADDRESSBOOK_OLD_FILE );
2469 addrindex_read_data( addrIndex );
2470 if( addrIndex->retVal == MGU_NO_FILE ) {
2471 /* We do not have a file - new user */
2472 debug_print( "New user... create new books...\n" );
2473 addrindex_create_new_books( addrIndex );
2474 if( addrIndex->retVal == MGU_SUCCESS ) {
2475 /* Save index file */
2476 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2477 addrindex_save_data( addrIndex );
2478 if( addrIndex->retVal == MGU_SUCCESS ) {
2482 msg = g_strdup( _( "New user, could not save index file." ) );
2486 msg = g_strdup( _( "New user, could not save address book files." ) );
2490 /* We have an old file */
2491 if( addrIndex->wasConverted ) {
2492 /* Converted successfully - save address index */
2493 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2494 addrindex_save_data( addrIndex );
2495 if( addrIndex->retVal == MGU_SUCCESS ) {
2496 msg = g_strdup( _( "Old address book converted successfully." ) );
2501 "Old address book converted, " \
2502 "could not save new address index file" ) );
2506 /* File conversion failed - just create new books */
2507 debug_print( "File conversion failed... just create new books...\n" );
2508 addrindex_create_new_books( addrIndex );
2509 if( addrIndex->retVal == MGU_SUCCESS ) {
2511 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2512 addrindex_save_data( addrIndex );
2513 if( addrIndex->retVal == MGU_SUCCESS ) {
2515 "Could not convert address book, " \
2516 "but created empty new address book files." ) );
2521 "Could not convert address book, " \
2522 "could not create new address book files." ) );
2527 "Could not convert address book " \
2528 "and could not create new address book files." ) );
2533 else if( addrIndex->retVal == MGU_SUCCESS ) {
2537 debug_print( "Could not read address index.\n" );
2538 addrindex_print_index( addrIndex, stdout );
2539 msg = g_strdup( _( "Could not read address index" ) );
2541 _addressIndex_ = addrIndex;
2544 debug_print( "Error\n%s\n", msg );
2545 alertpanel( _( "Addressbook Conversion Error" ), msg,
2546 _( "Close" ), NULL, NULL );
2550 debug_print( "Warning\n%s\n", msg );
2551 alertpanel( _( "Addressbook Conversion" ), msg,
2552 _( "Close" ), NULL, NULL );
2555 if( msg ) g_free( msg );
2556 debug_print( "done.\n" );
2561 * Add object into the address index tree widget.
2562 * Enter: node Parent node.
2563 * obj Object to add.
2564 * Return: Node that was added, or NULL if object not added.
2566 static GtkCTreeNode *addressbook_add_object(GtkCTreeNode *node,
2569 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2570 GtkCTreeNode *added;
2571 AddressObject *pobj;
2572 AddressObjectType otype;
2573 AddressTypeControlItem *atci = NULL;
2575 g_return_val_if_fail(node != NULL, NULL);
2576 g_return_val_if_fail(obj != NULL, NULL);
2578 pobj = gtk_ctree_node_get_row_data(ctree, node);
2579 g_return_val_if_fail(pobj != NULL, NULL);
2581 /* Determine object type to be displayed */
2582 if( obj->type == ADDR_DATASOURCE ) {
2583 otype = ADAPTER_DSOURCE(obj)->subType;
2589 /* Handle any special conditions. */
2591 atci = addrbookctl_lookup( otype );
2593 if( atci->showInTree ) {
2594 /* Add object to tree */
2597 added = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
2598 atci->iconXpm, atci->maskXpm, atci->iconXpmOpen, atci->maskXpmOpen,
2599 atci->treeLeaf, atci->treeExpand );
2600 gtk_ctree_node_set_row_data(ctree, added, obj);
2604 gtk_ctree_sort_node(ctree, node);
2610 * Add group into the address index tree.
2611 * Enter: node Parent node.
2613 * itemGroup Group to add.
2614 * Return: Inserted node.
2616 static GtkCTreeNode *addressbook_node_add_group( GtkCTreeNode *node, AddressDataSource *ds, ItemGroup *itemGroup ) {
2617 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2618 GtkCTreeNode *newNode;
2619 AdapterGroup *adapter;
2620 AddressTypeControlItem *atci = NULL;
2623 if( ds == NULL ) return NULL;
2624 if( node == NULL || itemGroup == NULL ) return NULL;
2626 name = &itemGroup->obj.name;
2628 atci = addrbookctl_lookup( ADDR_ITEM_GROUP );
2630 adapter = g_new0( AdapterGroup, 1 );
2631 ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_GROUP;
2632 ADDRESS_OBJECT_NAME(adapter) = g_strdup( ADDRITEM_NAME(itemGroup) );
2633 adapter->itemGroup = itemGroup;
2635 newNode = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
2636 atci->iconXpm, atci->maskXpm, atci->iconXpm, atci->maskXpm,
2637 atci->treeLeaf, atci->treeExpand );
2638 gtk_ctree_node_set_row_data( ctree, newNode, adapter );
2639 gtk_ctree_sort_node( ctree, node );
2644 * Add folder into the address index tree.
2645 * Enter: node Parent node.
2647 * itemFolder Folder to add.
2648 * otype Object type to display.
2649 * Return: Inserted node.
2651 static GtkCTreeNode *addressbook_node_add_folder(
2652 GtkCTreeNode *node, AddressDataSource *ds, ItemFolder *itemFolder, AddressObjectType otype )
2654 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2655 GtkCTreeNode *newNode = NULL;
2656 AdapterFolder *adapter;
2657 AddressTypeControlItem *atci = NULL;
2658 GList *listItems = NULL;
2660 ItemFolder *rootFolder;
2662 if( ds == NULL ) return NULL;
2663 if( node == NULL || itemFolder == NULL ) return NULL;
2665 /* Determine object type */
2666 atci = addrbookctl_lookup( otype );
2667 if( atci == NULL ) return NULL;
2669 rootFolder = addrindex_ds_get_root_folder( ds );
2670 if( itemFolder == rootFolder ) {
2674 name = &itemFolder->obj.name;
2676 adapter = g_new0( AdapterFolder, 1 );
2677 ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_FOLDER;
2678 ADDRESS_OBJECT_NAME(adapter) = g_strdup( ADDRITEM_NAME(itemFolder) );
2679 adapter->itemFolder = itemFolder;
2681 newNode = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
2682 atci->iconXpm, atci->maskXpm, atci->iconXpm, atci->maskXpm,
2683 atci->treeLeaf, atci->treeExpand );
2684 gtk_ctree_node_set_row_data( ctree, newNode, adapter );
2687 listItems = itemFolder->listFolder;
2688 while( listItems ) {
2689 ItemFolder *item = listItems->data;
2690 addressbook_node_add_folder( newNode, ds, item, otype );
2691 listItems = g_list_next( listItems );
2693 listItems = itemFolder->listGroup;
2694 while( listItems ) {
2695 ItemGroup *item = listItems->data;
2696 addressbook_node_add_group( newNode, ds, item );
2697 listItems = g_list_next( listItems );
2699 gtk_ctree_sort_node( ctree, node );
2703 static void addressbook_delete_object(AddressObject *obj) {
2704 AdapterDSource *ads = NULL;
2705 AddressDataSource *ds = NULL;
2708 /* Remove data source. */
2709 /* printf( "Delete obj type : %d\n", obj->type ); */
2711 ads = ADAPTER_DSOURCE(obj);
2712 if( ads == NULL ) return;
2713 ds = ads->dataSource;
2714 if( ds == NULL ) return;
2716 /* Remove data source */
2717 if( addrindex_index_remove_datasource( _addressIndex_, ds ) ) {
2718 addrindex_free_datasource( _addressIndex_, ds );
2720 /* Free up Adapter object */
2721 g_free( ADAPTER_DSOURCE(obj) );
2724 void addressbook_export_to_file( void ) {
2725 if( _addressIndex_ ) {
2726 /* Save all new address book data */
2727 debug_print( "Saving address books...\n" );
2728 addrindex_save_all_books( _addressIndex_ );
2730 debug_print( "Exporting addressbook to file...\n" );
2731 addrindex_save_data( _addressIndex_ );
2732 if( _addressIndex_->retVal != MGU_SUCCESS ) {
2733 addrindex_print_index( _addressIndex_, stdout );
2736 /* Notify address completion of new data */
2737 invalidate_address_completion();
2741 static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
2743 if (event && event->keyval == GDK_Escape)
2744 addressbook_close();
2748 * Comparsion using names of AddressItem objects.
2751 static gint addressbook_list_compare_func(GtkCList *clist,
2755 AddressObject *obj1 = ((GtkCListRow *)ptr1)->data;
2756 AddressObject *obj2 = ((GtkCListRow *)ptr2)->data;
2757 gchar *name1 = NULL, *name2 = NULL;
2758 if( obj1 ) name1 = obj1->name;
2759 if( obj2 ) name2 = obj2->name;
2760 if( ! name1 ) return ( name2 != NULL );
2761 if( ! name2 ) return -1;
2762 return strcasecmp(name1, name2);
2767 * Comparison using cell contents (text in first column).
2769 static gint addressbook_list_compare_func( GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2 ) {
2770 GtkCell *cell1 = ((GtkCListRow *)ptr1)->cell;
2771 GtkCell *cell2 = ((GtkCListRow *)ptr2)->cell;
2772 gchar *name1 = NULL, *name2 = NULL;
2773 if( cell1 ) name1 = cell1->u.text;
2774 if( cell2 ) name2 = cell2->u.text;
2775 if( ! name1 ) return ( name2 != NULL );
2776 if( ! name2 ) return -1;
2777 return strcasecmp( name1, name2 );
2781 gint addressbook_obj_name_compare(gconstpointer a, gconstpointer b)
2783 const AddressObject *obj = a;
2784 const gchar *name = b;
2785 AddressTypeControlItem *atci = NULL;
2787 if (!obj || !name) return -1;
2789 atci = addrbookctl_lookup( obj->type );
2790 if( ! atci ) return -1;
2791 if( ! obj->name ) return -1;
2792 return strcasecmp(obj->name, name);
2795 static void addressbook_book_show_message( AddressBookFile *abf ) {
2796 *addressbook_msgbuf = '\0';
2798 if( abf->retVal == MGU_SUCCESS ) {
2799 sprintf( addressbook_msgbuf, "%s", abf->name );
2802 sprintf( addressbook_msgbuf, "%s: %s", abf->name, mgu_error2string( abf->retVal ) );
2805 addressbook_status_show( addressbook_msgbuf );
2808 static void addressbook_new_book_cb( gpointer data, guint action, GtkWidget *widget ) {
2809 AdapterDSource *ads;
2810 AdapterInterface *adapter;
2812 adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
2813 if( adapter == NULL ) return;
2814 if( addrbook.treeSelected == NULL ) return;
2815 if( addrbook.treeSelected != adapter->treeNode ) return;
2816 ads = addressbook_edit_book( _addressIndex_, NULL );
2818 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2819 if( addrbook.treeSelected == addrbook.opened ) {
2820 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2825 static void addressbook_new_vcard_cb( gpointer data, guint action, GtkWidget *widget ) {
2826 AdapterDSource *ads;
2827 AdapterInterface *adapter;
2829 adapter = addrbookctl_find_interface( ADDR_IF_VCARD );
2830 if( adapter == NULL ) return;
2831 if( addrbook.treeSelected != adapter->treeNode ) return;
2832 ads = addressbook_edit_vcard( _addressIndex_, NULL );
2834 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2835 if( addrbook.treeSelected == addrbook.opened ) {
2836 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2841 static void addressbook_vcard_show_message( VCardFile *vcf ) {
2842 *addressbook_msgbuf = '\0';
2844 if( vcf->retVal == MGU_SUCCESS ) {
2845 sprintf( addressbook_msgbuf, "%s", vcf->name );
2848 sprintf( addressbook_msgbuf, "%s: %s", vcf->name, mgu_error2string( vcf->retVal ) );
2851 addressbook_status_show( addressbook_msgbuf );
2855 static void addressbook_new_jpilot_cb( gpointer data, guint action, GtkWidget *widget ) {
2856 AdapterDSource *ads;
2857 AdapterInterface *adapter;
2858 AddressInterface *iface;
2860 adapter = addrbookctl_find_interface( ADDR_IF_JPILOT );
2861 if( adapter == NULL ) return;
2862 if( addrbook.treeSelected != adapter->treeNode ) return;
2863 iface = adapter->interface;
2864 if( ! iface->haveLibrary ) return;
2865 ads = addressbook_edit_jpilot( _addressIndex_, NULL );
2867 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2868 if( addrbook.treeSelected == addrbook.opened ) {
2869 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2874 static void addressbook_jpilot_show_message( JPilotFile *jpf ) {
2875 *addressbook_msgbuf = '\0';
2877 if( jpf->retVal == MGU_SUCCESS ) {
2878 sprintf( addressbook_msgbuf, "%s", jpf->name );
2881 sprintf( addressbook_msgbuf, "%s: %s", jpf->name, mgu_error2string( jpf->retVal ) );
2884 addressbook_status_show( addressbook_msgbuf );
2890 static void addressbook_new_ldap_cb( gpointer data, guint action, GtkWidget *widget ) {
2891 AdapterDSource *ads;
2892 AdapterInterface *adapter;
2893 AddressInterface *iface;
2895 adapter = addrbookctl_find_interface( ADDR_IF_LDAP );
2896 if( adapter == NULL ) return;
2897 if( addrbook.treeSelected != adapter->treeNode ) return;
2898 iface = adapter->interface;
2899 if( ! iface->haveLibrary ) return;
2900 ads = addressbook_edit_ldap( _addressIndex_, NULL );
2902 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2903 if( addrbook.treeSelected == addrbook.opened ) {
2904 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2909 static void addressbook_ldap_show_message( SyldapServer *svr ) {
2910 *addressbook_msgbuf = '\0';
2912 if( svr->busyFlag ) {
2913 sprintf( addressbook_msgbuf, "%s: %s", svr->name, ADDRESSBOOK_LDAP_BUSYMSG );
2916 if( svr->retVal == MGU_SUCCESS ) {
2917 sprintf( addressbook_msgbuf, "%s", svr->name );
2920 sprintf( addressbook_msgbuf, "%s: %s", svr->name, mgu_error2string( svr->retVal ) );
2924 addressbook_status_show( addressbook_msgbuf );
2927 static void ldapsearch_callback( SyldapServer *sls ) {
2928 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2930 AdapterDSource *ads = NULL;
2931 AddressDataSource *ds = NULL;
2932 AddressInterface *iface = NULL;
2934 if( sls == NULL ) return;
2935 if( ! addrbook.treeSelected ) return;
2936 if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
2938 obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
2939 if( obj == NULL ) return;
2940 if( obj->type == ADDR_DATASOURCE ) {
2941 ads = ADAPTER_DSOURCE(obj);
2942 if( ads->subType == ADDR_LDAP ) {
2943 SyldapServer *server;
2945 ds = ads->dataSource;
2946 if( ds == NULL ) return;
2947 iface = ds->interface;
2948 if( ! iface->haveLibrary ) return;
2949 server = ds->rawDataSource;
2950 if( server == sls ) {
2951 /* Read from cache */
2952 gtk_widget_show_all(addrbook.window);
2953 addressbook_set_clist( obj );
2954 addressbook_ldap_show_message( sls );
2955 gtk_widget_show_all(addrbook.window);
2956 gtk_entry_set_text( GTK_ENTRY(addrbook.entry), "" );
2964 * Lookup button handler.
2966 static void addressbook_lup_clicked( GtkButton *button, gpointer data ) {
2967 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2970 AdapterDSource *ads = NULL;
2971 AddressDataSource *ds = NULL;
2972 AddressInterface *iface = NULL;
2976 sLookup = gtk_editable_get_chars( GTK_EDITABLE(addrbook.entry), 0, -1 );
2977 g_strchomp( sLookup );
2979 if( ! addrbook.treeSelected ) return;
2980 if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
2982 obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
2983 if( obj == NULL ) return;
2986 if( obj->type == ADDR_DATASOURCE ) {
2987 ads = ADAPTER_DSOURCE(obj);
2988 if( ads->subType == ADDR_LDAP ) {
2989 SyldapServer *server;
2991 ds = ads->dataSource;
2992 if( ds == NULL ) return;
2993 iface = ds->interface;
2994 if( ! iface->haveLibrary ) return;
2995 server = ds->rawDataSource;
2997 syldap_cancel_read( server );
2998 if( *sLookup == '\0' || strlen( sLookup ) < 1 ) return;
2999 syldap_set_search_value( server, sLookup );
3000 syldap_set_callback( server, ldapsearch_callback );
3001 syldap_read_data_th( server );
3002 addressbook_ldap_show_message( server );
3010 /* **********************************************************************
3011 * Build lookup tables.
3012 * ***********************************************************************
3016 * Build table that controls the rendering of object types.
3018 void addrbookctl_build_map( GtkWidget *window ) {
3019 AddressTypeControlItem *atci;
3022 PIXMAP_CREATE(window, folderxpm, folderxpmmask, dir_close_xpm);
3023 PIXMAP_CREATE(window, folderopenxpm, folderopenxpmmask, dir_open_xpm);
3024 PIXMAP_CREATE(window, groupxpm, groupxpmmask, group_xpm);
3025 PIXMAP_CREATE(window, vcardxpm, vcardxpmmask, vcard_xpm);
3026 PIXMAP_CREATE(window, bookxpm, bookxpmmask, book_xpm);
3027 PIXMAP_CREATE(window, addressxpm, addressxpmmask, address_xpm);
3028 PIXMAP_CREATE(window, jpilotxpm, jpilotxpmmask, jpilot_xpm);
3029 PIXMAP_CREATE(window, categoryxpm, categoryxpmmask, category_xpm);
3030 PIXMAP_CREATE(window, ldapxpm, ldapxpmmask, ldap_xpm);
3032 _addressBookTypeHash_ = g_hash_table_new( g_int_hash, g_int_equal );
3033 _addressBookTypeList_ = NULL;
3036 atci = g_new0( AddressTypeControlItem, 1 );
3037 atci->objectType = ADDR_INTERFACE;
3038 atci->interfaceType = ADDR_IF_NONE;
3039 atci->showInTree = TRUE;
3040 atci->treeExpand = TRUE;
3041 atci->treeLeaf = FALSE;
3042 atci->displayName = _( "Interface" );
3043 atci->iconXpm = folderxpm;
3044 atci->maskXpm = folderxpmmask;
3045 atci->iconXpmOpen = folderopenxpm;
3046 atci->maskXpmOpen = folderopenxpmmask;
3047 atci->menuCommand = NULL;
3048 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3049 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3052 atci = g_new0( AddressTypeControlItem, 1 );
3053 atci->objectType = ADDR_BOOK;
3054 atci->interfaceType = ADDR_IF_BOOK;
3055 atci->showInTree = TRUE;
3056 atci->treeExpand = TRUE;
3057 atci->treeLeaf = FALSE;
3058 atci->displayName = _( "Address Book" );
3059 atci->iconXpm = bookxpm;
3060 atci->maskXpm = bookxpmmask;
3061 atci->iconXpmOpen = bookxpm;
3062 atci->maskXpmOpen = bookxpmmask;
3063 atci->menuCommand = "/File/New Book";
3064 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3065 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3068 atci = g_new0( AddressTypeControlItem, 1 );
3069 atci->objectType = ADDR_ITEM_PERSON;
3070 atci->interfaceType = ADDR_IF_NONE;
3071 atci->showInTree = FALSE;
3072 atci->treeExpand = FALSE;
3073 atci->treeLeaf = FALSE;
3074 atci->displayName = _( "Person" );
3075 atci->iconXpm = NULL;
3076 atci->maskXpm = NULL;
3077 atci->iconXpmOpen = NULL;
3078 atci->maskXpmOpen = NULL;
3079 atci->menuCommand = NULL;
3080 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3081 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3084 atci = g_new0( AddressTypeControlItem, 1 );
3085 atci->objectType = ADDR_ITEM_EMAIL;
3086 atci->interfaceType = ADDR_IF_NONE;
3087 atci->showInTree = FALSE;
3088 atci->treeExpand = FALSE;
3089 atci->treeLeaf = TRUE;
3090 atci->displayName = _( "EMail Address" );
3091 atci->iconXpm = addressxpm;
3092 atci->maskXpm = addressxpmmask;
3093 atci->iconXpmOpen = addressxpm;
3094 atci->maskXpmOpen = addressxpmmask;
3095 atci->menuCommand = NULL;
3096 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3097 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3100 atci = g_new0( AddressTypeControlItem, 1 );
3101 atci->objectType = ADDR_ITEM_GROUP;
3102 atci->interfaceType = ADDR_IF_BOOK;
3103 atci->showInTree = TRUE;
3104 atci->treeExpand = FALSE;
3105 atci->treeLeaf = FALSE;
3106 atci->displayName = _( "Group" );
3107 atci->iconXpm = groupxpm;
3108 atci->maskXpm = groupxpmmask;
3109 atci->iconXpmOpen = groupxpm;
3110 atci->maskXpmOpen = groupxpmmask;
3111 atci->menuCommand = NULL;
3112 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3113 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3116 atci = g_new0( AddressTypeControlItem, 1 );
3117 atci->objectType = ADDR_ITEM_FOLDER;
3118 atci->interfaceType = ADDR_IF_BOOK;
3119 atci->showInTree = TRUE;
3120 atci->treeExpand = FALSE;
3121 atci->treeLeaf = FALSE;
3122 atci->displayName = _( "Folder" );
3123 atci->iconXpm = folderxpm;
3124 atci->maskXpm = folderxpmmask;
3125 atci->iconXpmOpen = folderopenxpm;
3126 atci->maskXpmOpen = folderopenxpmmask;
3127 atci->menuCommand = NULL;
3128 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3129 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3132 atci = g_new0( AddressTypeControlItem, 1 );
3133 atci->objectType = ADDR_VCARD;
3134 atci->interfaceType = ADDR_IF_VCARD;
3135 atci->showInTree = TRUE;
3136 atci->treeExpand = TRUE;
3137 atci->treeLeaf = TRUE;
3138 atci->displayName = _( "vCard" );
3139 atci->iconXpm = vcardxpm;
3140 atci->maskXpm = vcardxpmmask;
3141 atci->iconXpmOpen = vcardxpm;
3142 atci->maskXpmOpen = vcardxpmmask;
3143 atci->menuCommand = "/File/New vCard";
3144 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3145 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3148 atci = g_new0( AddressTypeControlItem, 1 );
3149 atci->objectType = ADDR_JPILOT;
3150 atci->interfaceType = ADDR_IF_JPILOT;
3151 atci->showInTree = TRUE;
3152 atci->treeExpand = TRUE;
3153 atci->treeLeaf = FALSE;
3154 atci->displayName = _( "J-Pilot" );
3155 atci->iconXpm = jpilotxpm;
3156 atci->maskXpm = jpilotxpmmask;
3157 atci->iconXpmOpen = jpilotxpm;
3158 atci->maskXpmOpen = jpilotxpmmask;
3159 atci->menuCommand = "/File/New J-Pilot";
3160 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3161 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3164 atci = g_new0( AddressTypeControlItem, 1 );
3165 atci->objectType = ADDR_CATEGORY;
3166 atci->interfaceType = ADDR_IF_JPILOT;
3167 atci->showInTree = TRUE;
3168 atci->treeExpand = TRUE;
3169 atci->treeLeaf = TRUE;
3170 atci->displayName = _( "J-Pilot" );
3171 atci->iconXpm = categoryxpm;
3172 atci->maskXpm = categoryxpmmask;
3173 atci->iconXpmOpen = categoryxpm;
3174 atci->maskXpmOpen = categoryxpmmask;
3175 atci->menuCommand = NULL;
3176 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3177 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3180 atci = g_new0( AddressTypeControlItem, 1 );
3181 atci->objectType = ADDR_LDAP;
3182 atci->interfaceType = ADDR_IF_LDAP;
3183 atci->showInTree = TRUE;
3184 atci->treeExpand = TRUE;
3185 atci->treeLeaf = TRUE;
3186 atci->displayName = _( "LDAP Server" );
3187 atci->iconXpm = ldapxpm;
3188 atci->maskXpm = ldapxpmmask;
3189 atci->iconXpmOpen = ldapxpm;
3190 atci->maskXpmOpen = ldapxpmmask;
3191 atci->menuCommand = "/File/New Server";
3192 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3193 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3198 * Search for specified object type.
3200 AddressTypeControlItem *addrbookctl_lookup( gint ot ) {
3202 return ( AddressTypeControlItem * ) g_hash_table_lookup( _addressBookTypeHash_, &objType );
3206 * Search for specified interface type.
3208 AddressTypeControlItem *addrbookctl_lookup_iface( AddressIfType ifType ) {
3209 GList *node = _addressBookTypeList_;
3211 AddressTypeControlItem *atci = node->data;
3212 if( atci->interfaceType == ifType ) return atci;
3213 node = g_list_next( node );
3218 static void addrbookctl_free_address( AddressObject *obj ) {
3219 g_free( obj->name );
3220 obj->type = ADDR_NONE;
3224 static void addrbookctl_free_interface( AdapterInterface *adapter ) {
3225 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3226 adapter->interface = NULL;
3227 adapter->interfaceType = ADDR_IF_NONE;
3228 adapter->atci = NULL;
3229 adapter->enabled = FALSE;
3230 adapter->haveLibrary = FALSE;
3231 adapter->treeNode = NULL;
3235 static void addrbookctl_free_datasource( AdapterDSource *adapter ) {
3236 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3237 adapter->dataSource = NULL;
3238 adapter->subType = ADDR_NONE;
3242 static void addrbookctl_free_folder( AdapterFolder *adapter ) {
3243 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3244 adapter->itemFolder = NULL;
3248 static void addrbookctl_free_group( AdapterGroup *adapter ) {
3249 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3250 adapter->itemGroup = NULL;
3255 * Build GUI interface list.
3257 void addrbookctl_build_iflist() {
3258 AddressTypeControlItem *atci;
3259 AdapterInterface *adapter;
3262 if( _addressIndex_ == NULL ) {
3263 _addressIndex_ = addrindex_create_index();
3265 _addressInterfaceList_ = NULL;
3266 list = addrindex_get_interface_list( _addressIndex_ );
3268 AddressInterface *interface = list->data;
3269 atci = addrbookctl_lookup_iface( interface->type );
3271 adapter = g_new0( AdapterInterface, 1 );
3272 adapter->interfaceType = interface->type;
3273 adapter->atci = atci;
3274 adapter->interface = interface;
3275 adapter->treeNode = NULL;
3276 adapter->enabled = TRUE;
3277 adapter->haveLibrary = interface->haveLibrary;
3278 ADDRESS_OBJECT(adapter)->type = ADDR_INTERFACE;
3279 ADDRESS_OBJECT_NAME(adapter) = g_strdup( atci->displayName );
3280 _addressInterfaceList_ = g_list_append( _addressInterfaceList_, adapter );
3282 list = g_list_next( list );
3286 void addrbookctl_free_selection( GList *list ) {
3289 AdapterInterface *adapter = node->data;
3291 node = g_list_next( node );
3293 g_list_free( list );
3297 * Find GUI interface type specified interface type.
3298 * Return: Interface item, or NULL if not found.
3300 AdapterInterface *addrbookctl_find_interface( AddressIfType ifType ) {
3301 GList *node = _addressInterfaceList_;
3303 AdapterInterface *adapter = node->data;
3304 if( adapter->interfaceType == ifType ) return adapter;
3305 node = g_list_next( node );
3311 * Build interface list selection.
3313 void addrbookctl_build_ifselect() {
3314 GList *newList = NULL;
3319 gchar *endptr = NULL;
3321 AdapterInterface *adapter;
3324 selectStr = g_strdup( ADDRESSBOOK_IFACE_SELECTION );
3327 splitStr = g_strsplit( selectStr, ",", -1 );
3328 for( i = 0; i < ADDRESSBOOK_MAX_IFACE; i++ ) {
3330 /* printf( "%d : %s\n", i, splitStr[i] ); */
3331 ifType = strtol( splitStr[i], &endptr, 10 );
3334 if( strcmp( endptr, "/n" ) == 0 ) {
3338 /* printf( "\t%d : %s\n", ifType, enabled ? "yes" : "no" ); */
3339 adapter = addrbookctl_find_interface( ifType );
3341 newList = g_list_append( newList, adapter );
3348 /* printf( "i=%d\n", i ); */
3349 g_strfreev( splitStr );
3350 g_free( selectStr );
3352 /* Replace existing list */
3353 mgu_clear_list( _addressIFaceSelection_ );
3354 g_list_free( _addressIFaceSelection_ );
3355 _addressIFaceSelection_ = newList;
3360 /* **********************************************************************
3361 * Add sender to address book.
3362 * ***********************************************************************
3366 * This function is used by the Add sender to address book function.
3368 gboolean addressbook_add_contact( const gchar *name, const gchar *address, const gchar *remarks ) {
3369 debug_print( "addressbook_add_contact: name/address: %s - %s\n", name, address );
3370 if( addressadd_selection( _addressIndex_, name, address, remarks ) ) {
3371 debug_print( "addressbook_add_contact - added\n" );
3372 addressbook_refresh();
3377 /* **********************************************************************
3378 * Address completion support.
3379 * ***********************************************************************
3383 * This function is used by the address completion function to load
3385 * Enter: callBackFunc Function to be called when an address is
3387 * Return: TRUE if data loaded, FALSE if address index not loaded.
3389 gboolean addressbook_load_completion( gint (*callBackFunc) ( const gchar *, const gchar * ) ) {
3390 /* AddressInterface *interface; */
3391 AddressDataSource *ds;
3392 GList *nodeIf, *nodeDS;
3393 GList *listP, *nodeP;
3395 gchar *sName, *sAddress, *sAlias, *sFriendly;
3397 debug_print( "addressbook_load_completion\n" );
3399 if( _addressIndex_ == NULL ) return FALSE;
3401 nodeIf = addrindex_get_interface_list( _addressIndex_ );
3403 AddressInterface *interface = nodeIf->data;
3404 nodeDS = interface->listSource;
3408 /* Read address book */
3409 if( ! addrindex_ds_get_read_flag( ds ) ) {
3410 addrindex_ds_read_data( ds );
3413 /* Get all persons */
3414 listP = addrindex_ds_get_all_persons( ds );
3417 ItemPerson *person = nodeP->data;
3418 nodeM = person->listEMail;
3420 /* Figure out name to use */
3421 sName = person->nickName;
3422 if( sName == NULL || *sName == '\0' ) {
3423 sName = ADDRITEM_NAME(person);
3426 /* Process each E-Mail address */
3428 ItemEMail *email = nodeM->data;
3431 sAddress = email->address;
3432 if( sAddress || *sAddress != '\0' ) {
3433 sAlias = ADDRITEM_NAME(email);
3434 if( sAlias && *sAlias != '\0' ) {
3437 ( callBackFunc ) ( sFriendly, sAddress );
3440 nodeM = g_list_next( nodeM );
3442 nodeP = g_list_next( nodeP );
3444 /* Free up the list */
3445 g_list_free( listP );
3447 nodeDS = g_list_next( nodeDS );
3449 nodeIf = g_list_next( nodeIf );
3451 debug_print( "addressbook_load_completion... done\n" );
3456 /* **********************************************************************
3458 * ***********************************************************************
3464 static void addressbook_import_ldif_cb() {
3465 AddressDataSource *ds = NULL;
3466 AdapterDSource *ads = NULL;
3467 AddressBookFile *abf = NULL;
3468 AdapterInterface *adapter;
3469 GtkCTreeNode *newNode;
3471 adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
3473 if( adapter->treeNode ) {
3474 abf = addressbook_imp_ldif( _addressIndex_ );
3476 ds = addrindex_index_add_datasource( _addressIndex_, ADDR_IF_BOOK, abf );
3477 ads = addressbook_create_ds_adapter( ds, ADDR_BOOK, NULL );
3478 addressbook_ads_set_name( ads, abf->name );
3479 newNode = addressbook_add_object( adapter->treeNode, ADDRESS_OBJECT(ads) );
3481 gtk_ctree_select( GTK_CTREE(addrbook.ctree), newNode );
3482 addrbook.treeSelected = newNode;
3485 /* Notify address completion */
3486 invalidate_address_completion();
3496 static void addressbook_import_mutt_cb() {
3497 AddressDataSource *ds = NULL;
3498 AdapterDSource *ads = NULL;
3499 AddressBookFile *abf = NULL;
3500 AdapterInterface *adapter;
3501 GtkCTreeNode *newNode;
3503 adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
3505 if( adapter->treeNode ) {
3506 abf = addressbook_imp_mutt( _addressIndex_ );
3508 ds = addrindex_index_add_datasource( _addressIndex_, ADDR_IF_BOOK, abf );
3509 ads = addressbook_create_ds_adapter( ds, ADDR_BOOK, NULL );
3510 addressbook_ads_set_name( ads, abf->name );
3511 newNode = addressbook_add_object( adapter->treeNode, ADDRESS_OBJECT(ads) );
3513 gtk_ctree_select( GTK_CTREE(addrbook.ctree), newNode );
3514 addrbook.treeSelected = newNode;
3517 /* Notify address completion */
3518 invalidate_address_completion();