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"
81 #include "editjpilot.h"
89 #define ADDRESSBOOK_LDAP_BUSYMSG "Busy"
92 #include "pixmaps/dir-close.xpm"
93 #include "pixmaps/dir-open.xpm"
94 #include "pixmaps/group.xpm"
95 #include "pixmaps/interface.xpm"
96 #include "pixmaps/book.xpm"
97 #include "pixmaps/address.xpm"
98 #include "pixmaps/vcard.xpm"
99 #include "pixmaps/jpilot.xpm"
100 #include "pixmaps/category.xpm"
101 #include "pixmaps/ldap.xpm"
108 } AddressBookColumnPos;
111 #define COL_NAME_WIDTH 164
112 #define COL_ADDRESS_WIDTH 156
114 #define COL_FOLDER_WIDTH 170
115 #define ADDRESSBOOK_WIDTH 640
116 #define ADDRESSBOOK_HEIGHT 360
118 #define ADDRESSBOOK_MSGBUF_SIZE 2048
120 static GdkPixmap *folderxpm;
121 static GdkBitmap *folderxpmmask;
122 static GdkPixmap *folderopenxpm;
123 static GdkBitmap *folderopenxpmmask;
124 static GdkPixmap *groupxpm;
125 static GdkBitmap *groupxpmmask;
126 static GdkPixmap *interfacexpm;
127 static GdkBitmap *interfacexpmmask;
128 static GdkPixmap *bookxpm;
129 static GdkBitmap *bookxpmmask;
130 static GdkPixmap *addressxpm;
131 static GdkBitmap *addressxpmmask;
132 static GdkPixmap *vcardxpm;
133 static GdkBitmap *vcardxpmmask;
134 static GdkPixmap *jpilotxpm;
135 static GdkBitmap *jpilotxpmmask;
136 static GdkPixmap *categoryxpm;
137 static GdkBitmap *categoryxpmmask;
138 static GdkPixmap *ldapxpm;
139 static GdkBitmap *ldapxpmmask;
142 static gchar addressbook_msgbuf[ ADDRESSBOOK_MSGBUF_SIZE ];
144 /* Address list selection */
145 static GList *_addressListSelection_ = NULL;
147 /* Address index file and interfaces */
148 static AddressIndex *_addressIndex_ = NULL;
149 static GList *_addressInterfaceList_ = NULL;
150 static GList *_addressIFaceSelection_ = NULL;
151 #define ADDRESSBOOK_IFACE_SELECTION "1/y,3/y,4/y,2/n"
153 static AddressBook_win addrbook;
155 static GHashTable *_addressBookTypeHash_ = NULL;
156 static GList *_addressBookTypeList_ = NULL;
158 static void addressbook_create (void);
159 static gint addressbook_close (void);
160 static void addressbook_button_set_sensitive (void);
162 /* callback functions */
163 static void addressbook_del_clicked (GtkButton *button,
165 static void addressbook_reg_clicked (GtkButton *button,
167 static void addressbook_to_clicked (GtkButton *button,
169 static void addressbook_lup_clicked (GtkButton *button,
172 static void addressbook_tree_selected (GtkCTree *ctree,
176 static void addressbook_list_selected (GtkCList *clist,
181 static void addressbook_list_row_selected (GtkCTree *clist,
185 static void addressbook_list_row_unselected (GtkCTree *clist,
189 static void addressbook_person_expand_node (GtkCTree *ctree,
192 static void addressbook_person_collapse_node (GtkCTree *ctree,
195 static void addressbook_entry_gotfocus (GtkWidget *widget);
198 static void addressbook_entry_changed (GtkWidget *widget);
201 static void addressbook_list_button_pressed (GtkWidget *widget,
202 GdkEventButton *event,
204 static void addressbook_list_button_released (GtkWidget *widget,
205 GdkEventButton *event,
207 static void addressbook_tree_button_pressed (GtkWidget *ctree,
208 GdkEventButton *event,
210 static void addressbook_tree_button_released (GtkWidget *ctree,
211 GdkEventButton *event,
213 static void addressbook_popup_close (GtkMenuShell *menu_shell,
216 static void addressbook_new_folder_cb (gpointer data,
219 static void addressbook_new_group_cb (gpointer data,
222 static void addressbook_treenode_edit_cb (gpointer data,
225 static void addressbook_treenode_delete_cb (gpointer data,
229 static void addressbook_change_node_name (GtkCTreeNode *node,
232 static void addressbook_new_address_cb (gpointer data,
235 static void addressbook_edit_address_cb (gpointer data,
238 static void addressbook_delete_address_cb (gpointer data,
242 static void close_cb (gpointer data,
245 static void addressbook_file_save_cb (gpointer data,
249 /* Data source edit stuff */
250 static void addressbook_new_book_cb (gpointer data,
253 static void addressbook_new_vcard_cb (gpointer data,
258 static void addressbook_new_jpilot_cb (gpointer data,
264 static void addressbook_new_ldap_cb (gpointer data,
269 static void addressbook_set_clist (AddressObject *obj);
271 static void addressbook_load_tree (void);
272 void addressbook_read_file (void);
274 static GtkCTreeNode *addressbook_add_object (GtkCTreeNode *node,
276 static AddressDataSource *addressbook_find_datasource
277 (GtkCTreeNode *node );
279 static AddressBookFile *addressbook_get_book_file();
281 static GtkCTreeNode *addressbook_node_add_folder
283 AddressDataSource *ds,
284 ItemFolder *itemFolder,
285 AddressObjectType otype);
286 static GtkCTreeNode *addressbook_node_add_group (GtkCTreeNode *node,
287 AddressDataSource *ds,
288 ItemGroup *itemGroup);
289 /* static GtkCTreeNode *addressbook_node_add_category */
290 /* (GtkCTreeNode *node, */
291 /* AddressDataSource *ds, */
292 /* ItemFolder *itemFolder); */
293 static void addressbook_tree_remove_children (GtkCTree *ctree,
294 GtkCTreeNode *parent);
295 static void addressbook_move_nodes_up (GtkCTree *ctree,
297 static GtkCTreeNode *addressbook_find_group_node (GtkCTreeNode *parent,
300 static void addressbook_delete_object (AddressObject *obj);
302 static void key_pressed (GtkWidget *widget,
305 static gint addressbook_list_compare_func (GtkCList *clist,
308 /* static gint addressbook_obj_name_compare (gconstpointer a, */
309 /* gconstpointer b); */
311 static void addressbook_book_show_message (AddressBookFile *book);
312 static void addressbook_vcard_show_message (VCardFile *vcf);
314 static void addressbook_jpilot_show_message (JPilotFile *jpf);
317 static void addressbook_ldap_show_message (SyldapServer *server);
320 /* LUT's and IF stuff */
321 static void addressbook_free_adapter (GtkCTreeNode *node);
322 static void addressbook_free_child_adapters (GtkCTreeNode *node);
323 AddressTypeControlItem *addrbookctl_lookup (gint ot);
324 AddressTypeControlItem *addrbookctl_lookup_iface(AddressIfType ifType);
326 void addrbookctl_build_map (GtkWidget *window);
327 void addrbookctl_build_iflist (void);
328 AdapterInterface *addrbookctl_find_interface (AddressIfType ifType);
329 void addrbookctl_build_ifselect (void);
331 static void addrbookctl_free_interface (AdapterInterface *adapter);
332 static void addrbookctl_free_datasource (AdapterDSource *adapter);
333 static void addrbookctl_free_folder (AdapterFolder *adapter);
334 static void addrbookctl_free_group (AdapterGroup *adapter);
336 static void addressbook_list_select_clear (void);
337 static void addressbook_list_select_add (AddressObject *obj);
338 static void addressbook_list_select_remove (AddressObject *obj);
340 static void addressbook_import_ldif_cb (void);
342 static GtkItemFactoryEntry addressbook_entries[] =
344 {N_("/_File"), NULL, NULL, 0, "<Branch>"},
345 {N_("/_File/New _Book"), "<alt>B", addressbook_new_book_cb, 0, NULL},
346 {N_("/_File/New _vCard"), "<alt>D", addressbook_new_vcard_cb, 0, NULL},
348 {N_("/_File/New _J-Pilot"), "<alt>J", addressbook_new_jpilot_cb, 0, NULL},
351 {N_("/_File/New _Server"), "<alt>S", addressbook_new_ldap_cb, 0, NULL},
353 {N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
354 {N_("/_File/_Edit"), NULL, addressbook_treenode_edit_cb, 0, NULL},
355 {N_("/_File/_Delete"), NULL, addressbook_treenode_delete_cb, 0, NULL},
356 {N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
357 {N_("/_File/_Save"), "<alt>S", addressbook_file_save_cb, 0, NULL},
358 {N_("/_File/_Close"), "<alt>W", close_cb, 0, NULL},
359 {N_("/_Address"), NULL, NULL, 0, "<Branch>"},
360 {N_("/_Address/New _Address"), "<alt>N", addressbook_new_address_cb, 0, NULL},
361 {N_("/_Address/New _Group"), "<alt>G", addressbook_new_group_cb, 0, NULL},
362 {N_("/_Address/New _Folder"), "<alt>R", addressbook_new_folder_cb, 0, NULL},
363 {N_("/_Address/---"), NULL, NULL, 0, "<Separator>"},
364 {N_("/_Address/_Edit"), "<alt>Return", addressbook_edit_address_cb, 0, NULL},
365 {N_("/_Address/_Delete"), NULL, addressbook_delete_address_cb, 0, NULL},
366 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
367 {N_("/_Tools/Import _LDIF file"), NULL, addressbook_import_ldif_cb, 0, NULL},
368 {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"},
369 {N_("/_Help/_About"), NULL, about_show, 0, NULL}
372 /* New options to be added. */
374 {N_("/_Edit"), NULL, NULL, 0, "<Branch>"},
375 {N_("/_Edit/C_ut"), "<ctl>X", NULL, 0, NULL},
376 {N_("/_Edit/_Copy"), "<ctl>C", NULL, 0, NULL},
377 {N_("/_Edit/_Paste"), "<ctl>V", NULL, 0, NULL},
378 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
379 {N_("/_Tools/Import _Mozilla"), NULL, NULL, 0, NULL},
380 {N_("/_Tools/Import _vCard"), NULL, NULL, 0, NULL},
381 {N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
382 {N_("/_Tools/Export _LDIF file"), NULL, NULL, 0, NULL},
383 {N_("/_Tools/Export v_Card"), NULL, NULL, 0, NULL},
386 static GtkItemFactoryEntry addressbook_tree_popup_entries[] =
388 {N_("/New _Address"), NULL, addressbook_new_address_cb, 0, NULL},
389 {N_("/New _Group"), NULL, addressbook_new_group_cb, 0, NULL},
390 {N_("/New _Folder"), NULL, addressbook_new_folder_cb, 0, NULL},
391 {N_("/---"), NULL, NULL, 0, "<Separator>"},
392 {N_("/_Edit"), NULL, addressbook_treenode_edit_cb, 0, NULL},
393 {N_("/_Delete"), NULL, addressbook_treenode_delete_cb, 0, NULL}
396 static GtkItemFactoryEntry addressbook_list_popup_entries[] =
398 {N_("/New _Address"), NULL, addressbook_new_address_cb, 0, NULL},
399 {N_("/New _Group"), NULL, addressbook_new_group_cb, 0, NULL},
400 {N_("/New _Folder"), NULL, addressbook_new_folder_cb, 0, NULL},
401 {N_("/---"), NULL, NULL, 0, "<Separator>"},
402 {N_("/_Edit"), NULL, addressbook_edit_address_cb, 0, NULL},
403 {N_("/_Delete"), NULL, addressbook_delete_address_cb, 0, NULL}
406 void addressbook_open(Compose *target)
408 if (!addrbook.window) {
409 addressbook_read_file();
410 addressbook_create();
411 addressbook_load_tree();
412 gtk_ctree_select(GTK_CTREE(addrbook.ctree),
413 GTK_CTREE_NODE(GTK_CLIST(addrbook.ctree)->row_list));
415 gtk_widget_hide(addrbook.window);
417 gtk_widget_show_all(addrbook.window);
419 addressbook_set_target_compose(target);
422 void addressbook_set_target_compose(Compose *target)
424 addrbook.target_compose = target;
426 addressbook_button_set_sensitive();
429 Compose *addressbook_get_target_compose(void)
431 return addrbook.target_compose;
434 void addressbook_refresh(void)
436 if (addrbook.window) {
437 if (addrbook.treeSelected) {
438 gtk_ctree_select(GTK_CTREE(addrbook.ctree),
439 addrbook.treeSelected);
442 addressbook_export_to_file();
446 * Create the address book widgets. The address book contains two CTree widgets: the
447 * address index tree on the left and the address list on the right.
449 * The address index tree displays a hierarchy of interfaces and groups. Each node in
450 * this tree is linked to an address Adapter. Adapters have been created for interfaces,
451 * data sources and folder objects.
453 * The address list displays group, person and email objects. These items are linked
454 * directly to ItemGroup, ItemPerson and ItemEMail objects inside the address book data
457 * In the tradition of MVC architecture, the data stores have been separated from the
458 * GUI components. The addrindex.c file provides the interface to all data stores.
460 static void addressbook_create(void)
466 GtkWidget *ctree_swin;
468 GtkWidget *clist_vbox;
469 GtkWidget *clist_swin;
475 GtkWidget *statusbar;
484 GtkWidget *tree_popup;
485 GtkWidget *list_popup;
486 GtkItemFactory *tree_factory;
487 GtkItemFactory *list_factory;
488 GtkItemFactory *menu_factory;
492 gchar *titles[N_COLS] = {_("Name"), _("E-Mail address"), _("Remarks")};
496 debug_print("Creating addressbook window...\n");
498 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
499 gtk_window_set_title(GTK_WINDOW(window), _("Address book"));
500 gtk_widget_set_usize(window, ADDRESSBOOK_WIDTH, ADDRESSBOOK_HEIGHT);
501 gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);
502 gtk_widget_realize(window);
504 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
505 GTK_SIGNAL_FUNC(addressbook_close), NULL);
506 gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
507 GTK_SIGNAL_FUNC(key_pressed), NULL);
508 gtk_signal_connect(GTK_OBJECT(window), "focus_in_event",
509 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
510 gtk_signal_connect(GTK_OBJECT(window), "focus_out_event",
511 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
513 vbox = gtk_vbox_new(FALSE, 0);
514 gtk_container_add(GTK_CONTAINER(window), vbox);
516 n_entries = sizeof(addressbook_entries) /
517 sizeof(addressbook_entries[0]);
518 menubar = menubar_create(window, addressbook_entries, n_entries,
519 "<AddressBook>", NULL);
520 gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
521 menu_factory = gtk_item_factory_from_widget(menubar);
523 vbox2 = gtk_vbox_new(FALSE, 4);
524 gtk_container_set_border_width(GTK_CONTAINER(vbox2), BORDER_WIDTH);
525 gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);
527 ctree_swin = gtk_scrolled_window_new(NULL, NULL);
528 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ctree_swin),
529 GTK_POLICY_AUTOMATIC,
531 gtk_widget_set_usize(ctree_swin, COL_FOLDER_WIDTH + 40, -1);
534 ctree = gtk_ctree_new(1, 0);
535 gtk_container_add(GTK_CONTAINER(ctree_swin), ctree);
536 gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
537 gtk_clist_set_column_width(GTK_CLIST(ctree), 0, COL_FOLDER_WIDTH);
538 gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_DOTTED);
539 gtk_ctree_set_expander_style(GTK_CTREE(ctree),
540 GTK_CTREE_EXPANDER_SQUARE);
541 gtk_ctree_set_indent(GTK_CTREE(ctree), CTREE_INDENT);
542 gtk_clist_set_compare_func(GTK_CLIST(ctree),
543 addressbook_list_compare_func);
545 gtk_signal_connect(GTK_OBJECT(ctree), "tree_select_row",
546 GTK_SIGNAL_FUNC(addressbook_tree_selected), NULL);
547 gtk_signal_connect(GTK_OBJECT(ctree), "button_press_event",
548 GTK_SIGNAL_FUNC(addressbook_tree_button_pressed),
550 gtk_signal_connect(GTK_OBJECT(ctree), "button_release_event",
551 GTK_SIGNAL_FUNC(addressbook_tree_button_released),
554 clist_vbox = gtk_vbox_new(FALSE, 4);
556 clist_swin = gtk_scrolled_window_new(NULL, NULL);
557 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
558 GTK_POLICY_AUTOMATIC,
560 gtk_box_pack_start(GTK_BOX(clist_vbox), clist_swin, TRUE, TRUE, 0);
563 clist = gtk_ctree_new_with_titles(N_COLS, 0, titles);
564 gtk_container_add(GTK_CONTAINER(clist_swin), clist);
565 gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_EXTENDED);
566 gtk_ctree_set_line_style(GTK_CTREE(clist), GTK_CTREE_LINES_NONE);
567 gtk_ctree_set_expander_style(GTK_CTREE(clist), GTK_CTREE_EXPANDER_SQUARE);
568 gtk_ctree_set_indent(GTK_CTREE(clist), CTREE_INDENT);
569 gtk_clist_set_column_width(GTK_CLIST(clist), COL_NAME,
571 gtk_clist_set_column_width(GTK_CLIST(clist), COL_ADDRESS,
573 gtk_clist_set_compare_func(GTK_CLIST(clist),
574 addressbook_list_compare_func);
576 for (i = 0; i < N_COLS; i++)
577 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[i].button,
580 gtk_signal_connect(GTK_OBJECT(clist), "tree_select_row",
581 GTK_SIGNAL_FUNC(addressbook_list_row_selected), NULL);
582 gtk_signal_connect(GTK_OBJECT(clist), "tree_unselect_row",
583 GTK_SIGNAL_FUNC(addressbook_list_row_unselected), NULL);
584 gtk_signal_connect(GTK_OBJECT(clist), "button_press_event",
585 GTK_SIGNAL_FUNC(addressbook_list_button_pressed),
587 gtk_signal_connect(GTK_OBJECT(clist), "button_release_event",
588 GTK_SIGNAL_FUNC(addressbook_list_button_released),
590 gtk_signal_connect(GTK_OBJECT(clist), "select_row",
591 GTK_SIGNAL_FUNC(addressbook_list_selected), NULL);
592 gtk_signal_connect(GTK_OBJECT(clist), "tree_expand",
593 GTK_SIGNAL_FUNC(addressbook_person_expand_node), NULL );
594 gtk_signal_connect(GTK_OBJECT(clist), "tree_collapse",
595 GTK_SIGNAL_FUNC(addressbook_person_collapse_node), NULL );
597 hbox = gtk_hbox_new(FALSE, 4);
598 gtk_box_pack_start(GTK_BOX(clist_vbox), hbox, FALSE, FALSE, 0);
600 label = gtk_label_new(_("Name:"));
601 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
603 entry = gtk_entry_new();
604 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
606 address_completion_register_entry(GTK_ENTRY(entry));
607 gtk_signal_connect(GTK_OBJECT(entry), "focus_in_event",
608 GTK_SIGNAL_FUNC(addressbook_entry_gotfocus), NULL);
611 gtk_signal_connect(GTK_OBJECT(entry), "changed",
612 GTK_SIGNAL_FUNC(addressbook_entry_changed), NULL);
615 paned = gtk_hpaned_new();
616 gtk_box_pack_start(GTK_BOX(vbox2), paned, TRUE, TRUE, 0);
617 gtk_paned_add1(GTK_PANED(paned), ctree_swin);
618 gtk_paned_add2(GTK_PANED(paned), clist_vbox);
621 hsbox = gtk_hbox_new(FALSE, 0);
622 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
623 statusbar = gtk_statusbar_new();
624 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
627 hbbox = gtk_hbutton_box_new();
628 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_END);
629 gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbbox), 2);
630 gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
632 del_btn = gtk_button_new_with_label(_("Delete"));
633 GTK_WIDGET_SET_FLAGS(del_btn, GTK_CAN_DEFAULT);
634 gtk_box_pack_start(GTK_BOX(hbbox), del_btn, TRUE, TRUE, 0);
635 reg_btn = gtk_button_new_with_label(_("Add"));
636 GTK_WIDGET_SET_FLAGS(reg_btn, GTK_CAN_DEFAULT);
637 gtk_box_pack_start(GTK_BOX(hbbox), reg_btn, TRUE, TRUE, 0);
638 lup_btn = gtk_button_new_with_label(_("Lookup"));
639 GTK_WIDGET_SET_FLAGS(lup_btn, GTK_CAN_DEFAULT);
640 gtk_box_pack_start(GTK_BOX(hbbox), lup_btn, TRUE, TRUE, 0);
642 gtk_signal_connect(GTK_OBJECT(del_btn), "clicked",
643 GTK_SIGNAL_FUNC(addressbook_del_clicked), NULL);
644 gtk_signal_connect(GTK_OBJECT(reg_btn), "clicked",
645 GTK_SIGNAL_FUNC(addressbook_reg_clicked), NULL);
646 gtk_signal_connect(GTK_OBJECT(lup_btn), "clicked",
647 GTK_SIGNAL_FUNC(addressbook_lup_clicked), NULL);
649 to_btn = gtk_button_new_with_label
650 (prefs_common.trans_hdr ? _("To:") : "To:");
651 GTK_WIDGET_SET_FLAGS(to_btn, GTK_CAN_DEFAULT);
652 gtk_box_pack_start(GTK_BOX(hbbox), to_btn, TRUE, TRUE, 0);
653 cc_btn = gtk_button_new_with_label
654 (prefs_common.trans_hdr ? _("Cc:") : "Cc:");
655 GTK_WIDGET_SET_FLAGS(cc_btn, GTK_CAN_DEFAULT);
656 gtk_box_pack_start(GTK_BOX(hbbox), cc_btn, TRUE, TRUE, 0);
657 bcc_btn = gtk_button_new_with_label
658 (prefs_common.trans_hdr ? _("Bcc:") : "Bcc:");
659 GTK_WIDGET_SET_FLAGS(bcc_btn, GTK_CAN_DEFAULT);
660 gtk_box_pack_start(GTK_BOX(hbbox), bcc_btn, TRUE, TRUE, 0);
662 gtk_signal_connect(GTK_OBJECT(to_btn), "clicked",
663 GTK_SIGNAL_FUNC(addressbook_to_clicked),
664 GINT_TO_POINTER(COMPOSE_TO));
665 gtk_signal_connect(GTK_OBJECT(cc_btn), "clicked",
666 GTK_SIGNAL_FUNC(addressbook_to_clicked),
667 GINT_TO_POINTER(COMPOSE_CC));
668 gtk_signal_connect(GTK_OBJECT(bcc_btn), "clicked",
669 GTK_SIGNAL_FUNC(addressbook_to_clicked),
670 GINT_TO_POINTER(COMPOSE_BCC));
672 /* Build icons for interface */
673 PIXMAP_CREATE( window, interfacexpm, interfacexpmmask, interface_xpm );
675 /* Build control tables */
676 addrbookctl_build_map(window);
677 addrbookctl_build_iflist();
678 addrbookctl_build_ifselect();
680 /* Add each interface into the tree as a root level folder */
681 nodeIf = _addressInterfaceList_;
683 AdapterInterface *adapter = nodeIf->data;
684 AddressInterface *iface = adapter->interface;
685 nodeIf = g_list_next(nodeIf);
687 if(iface->useInterface) {
688 AddressTypeControlItem *atci = adapter->atci;
689 text = atci->displayName;
691 gtk_ctree_insert_node( GTK_CTREE(ctree),
692 NULL, NULL, &text, FOLDER_SPACING,
693 interfacexpm, interfacexpmmask,
694 interfacexpm, interfacexpmmask,
696 menu_set_sensitive( menu_factory, atci->menuCommand, adapter->haveLibrary );
697 gtk_ctree_node_set_row_data( GTK_CTREE(ctree), adapter->treeNode, adapter );
702 n_entries = sizeof(addressbook_tree_popup_entries) /
703 sizeof(addressbook_tree_popup_entries[0]);
704 tree_popup = menu_create_items(addressbook_tree_popup_entries,
706 "<AddressBookTree>", &tree_factory,
708 gtk_signal_connect(GTK_OBJECT(tree_popup), "selection_done",
709 GTK_SIGNAL_FUNC(addressbook_popup_close), NULL);
710 n_entries = sizeof(addressbook_list_popup_entries) /
711 sizeof(addressbook_list_popup_entries[0]);
712 list_popup = menu_create_items(addressbook_list_popup_entries,
714 "<AddressBookList>", &list_factory,
717 addrbook.window = window;
718 addrbook.menubar = menubar;
719 addrbook.ctree = ctree;
720 addrbook.clist = clist;
721 addrbook.entry = entry;
722 addrbook.statusbar = statusbar;
723 addrbook.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Addressbook Window" );
725 addrbook.del_btn = del_btn;
726 addrbook.reg_btn = reg_btn;
727 addrbook.lup_btn = lup_btn;
728 addrbook.to_btn = to_btn;
729 addrbook.cc_btn = cc_btn;
730 addrbook.bcc_btn = bcc_btn;
732 addrbook.tree_popup = tree_popup;
733 addrbook.list_popup = list_popup;
734 addrbook.tree_factory = tree_factory;
735 addrbook.list_factory = list_factory;
736 addrbook.menu_factory = menu_factory;
738 addrbook.listSelected = NULL;
739 address_completion_start(window);
740 gtk_widget_show_all(window);
744 static gint addressbook_close(void)
746 gtk_widget_hide(addrbook.window);
747 addressbook_export_to_file();
751 static void addressbook_status_show( gchar *msg ) {
752 if( addrbook.statusbar != NULL ) {
753 gtk_statusbar_pop( GTK_STATUSBAR(addrbook.statusbar), addrbook.status_cid );
755 gtk_statusbar_push( GTK_STATUSBAR(addrbook.statusbar), addrbook.status_cid, msg );
760 static void addressbook_ds_show_message( AddressDataSource *ds ) {
763 *addressbook_msgbuf = '\0';
765 name = addrindex_ds_get_name( ds );
766 retVal = addrindex_ds_get_status_code( ds );
767 if( retVal == MGU_SUCCESS ) {
769 sprintf( addressbook_msgbuf, "%s", name );
774 sprintf( addressbook_msgbuf, "%s", mgu_error2string( retVal ) );
777 sprintf( addressbook_msgbuf, "%s: %s", name, mgu_error2string( retVal ) );
781 addressbook_status_show( addressbook_msgbuf );
784 static void addressbook_button_set_sensitive(void)
786 gboolean to_sens = FALSE;
787 gboolean cc_sens = FALSE;
788 gboolean bcc_sens = FALSE;
790 if (!addrbook.window) return;
792 if (addrbook.target_compose) {
795 if (addrbook.target_compose->use_bcc)
799 gtk_widget_set_sensitive(addrbook.to_btn, to_sens);
800 gtk_widget_set_sensitive(addrbook.cc_btn, cc_sens);
801 gtk_widget_set_sensitive(addrbook.bcc_btn, bcc_sens);
805 * Delete one or more objects from address list.
807 static void addressbook_del_clicked(GtkButton *button, gpointer data)
809 GtkCTree *clist = GTK_CTREE(addrbook.clist);
810 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
811 AddressObject *pobj, *obj;
812 AdapterDSource *ads = NULL;
813 GtkCTreeNode *nodeList;
816 AddressBookFile *abf = NULL;
817 AddressDataSource *ds = NULL;
819 pobj = gtk_ctree_node_get_row_data(ctree, addrbook.opened );
820 g_return_if_fail(pobj != NULL);
822 nodeList = addrbook.listSelected;
823 obj = gtk_ctree_node_get_row_data( clist, nodeList );
824 if( obj == NULL) return;
825 ds = addressbook_find_datasource( addrbook.treeSelected );
826 if( ds == NULL ) return;
829 if( pobj->type == ADDR_DATASOURCE ) {
830 ads = ADAPTER_DSOURCE(pobj);
831 if( ads->subType == ADDR_BOOK ) procFlag = TRUE;
833 else if( pobj->type == ADDR_ITEM_FOLDER ) {
836 else if( pobj->type == ADDR_ITEM_GROUP ) {
839 if( ! procFlag ) return;
840 abf = ds->rawDataSource;
841 if( abf == NULL ) return;
843 /* Confirm deletion */
844 aval = alertpanel( _("Delete address(es)"),
845 _("Really delete the address(es)?"),
846 _("Yes"), _("No"), NULL );
847 if( aval != G_ALERTDEFAULT ) return;
849 /* Process deletions */
850 if( pobj->type == ADDR_DATASOURCE || pobj->type == ADDR_ITEM_FOLDER ) {
851 /* Items inside folders */
853 node = _addressListSelection_;
855 AddrItemObject *aio = node->data;
856 node = g_list_next( node );
857 if( aio->type == ADDR_ITEM_GROUP ) {
858 ItemGroup *item = ( ItemGroup * ) aio;
859 GtkCTreeNode *nd = NULL;
861 nd = addressbook_find_group_node( addrbook.opened, item );
862 item = addrbook_remove_group( abf, item );
864 addritem_free_item_group( item );
867 /* Remove group from parent node */
868 gtk_ctree_remove_node( ctree, nd );
870 else if( aio->type == ADDR_ITEM_PERSON ) {
871 ItemPerson *item = ( ItemPerson * ) aio;
872 item = addrbook_remove_person( abf, item );
874 addritem_free_item_person( item );
878 else if( aio->type == ADDR_ITEM_EMAIL ) {
879 ItemEMail *item = ( ItemEMail * ) aio;
880 ItemPerson *person = ( ItemPerson * ) ADDRITEM_PARENT(item);
881 item = addrbook_person_remove_email( abf, person, item );
883 addritem_free_item_email( item );
888 addressbook_list_select_clear();
889 gtk_ctree_select( ctree, addrbook.opened);
892 else if( pobj->type == ADDR_ITEM_GROUP ) {
893 /* Items inside groups */
895 node = _addressListSelection_;
897 AddrItemObject *aio = node->data;
898 node = g_list_next( node );
899 if( aio->type == ADDR_ITEM_EMAIL ) {
900 ItemEMail *item = ( ItemEMail * ) aio;
901 ItemPerson *person = ( ItemPerson * ) ADDRITEM_PARENT(item);
902 item = addrbook_person_remove_email( abf, person, item );
904 addritem_print_item_email( item, stdout );
905 addritem_free_item_email( item );
910 addressbook_list_select_clear();
911 gtk_ctree_select( ctree, addrbook.opened);
915 gtk_ctree_node_set_row_data( clist, nodeList, NULL );
916 gtk_ctree_remove_node( clist, nodeList );
917 addressbook_list_select_remove( obj );
921 static void addressbook_reg_clicked(GtkButton *button, gpointer data)
923 addressbook_new_address_cb( NULL, 0, NULL );
926 gchar *addressbook_format_address( AddressObject * obj ) {
929 gchar *address = NULL;
931 if( obj->type == ADDR_ITEM_EMAIL ) {
932 ItemPerson *person = NULL;
933 ItemEMail *email = ( ItemEMail * ) obj;
935 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
936 if( email->address ) {
937 if( ADDRITEM_NAME(email) ) {
938 name = ADDRITEM_NAME(email);
939 if( *name == '\0' ) {
940 name = ADDRITEM_NAME(person);
943 else if( ADDRITEM_NAME(person) ) {
944 name = ADDRITEM_NAME(person);
947 buf = g_strdup( email->address );
949 address = email->address;
952 else if( obj->type == ADDR_ITEM_PERSON ) {
953 ItemPerson *person = ( ItemPerson * ) obj;
954 GList *node = person->listEMail;
956 name = ADDRITEM_NAME(person);
958 ItemEMail *email = ( ItemEMail * ) node->data;
959 address = email->address;
964 buf = g_strdup_printf( "%s <%s>", name, address );
967 buf = g_strdup( address );
974 static void addressbook_to_clicked(GtkButton *button, gpointer data)
976 GList *node = _addressListSelection_;
977 if (!addrbook.target_compose) return;
979 AddressObject *obj = node->data;
980 Compose *compose = addrbook.target_compose;
981 node = g_list_next( node );
982 if( obj->type == ADDR_ITEM_PERSON || obj->type == ADDR_ITEM_EMAIL ) {
983 gchar *addr = addressbook_format_address( obj );
984 compose_entry_append( compose, addr, (ComposeEntryType) data );
988 else if( obj->type == ADDR_ITEM_GROUP ) {
989 ItemGroup *group = ( ItemGroup * ) obj;
990 GList *nodeMail = group->listEMail;
992 ItemEMail *email = nodeMail->data;
993 gchar *addr = addressbook_format_address( ( AddressObject * ) email );
994 compose_entry_append( compose, addr, (ComposeEntryType) data );
996 nodeMail = g_list_next( nodeMail );
1002 static void addressbook_menubar_set_sensitive( gboolean sensitive ) {
1003 menu_set_sensitive( addrbook.menu_factory, "/File/New Book", sensitive );
1004 menu_set_sensitive( addrbook.menu_factory, "/File/New vCard", sensitive );
1006 menu_set_sensitive( addrbook.menu_factory, "/File/New J-Pilot", sensitive );
1009 menu_set_sensitive( addrbook.menu_factory, "/File/New Server", sensitive );
1011 menu_set_sensitive( addrbook.menu_factory, "/File/Edit", sensitive );
1012 menu_set_sensitive( addrbook.menu_factory, "/File/Delete", sensitive );
1014 menu_set_sensitive( addrbook.menu_factory, "/Address/New Address", sensitive );
1015 menu_set_sensitive( addrbook.menu_factory, "/Address/New Group", sensitive );
1016 menu_set_sensitive( addrbook.menu_factory, "/Address/New Folder", sensitive );
1017 gtk_widget_set_sensitive( addrbook.reg_btn, sensitive );
1018 gtk_widget_set_sensitive( addrbook.del_btn, sensitive );
1021 static void addressbook_menuitem_set_sensitive( AddressObject *obj, GtkCTreeNode *node ) {
1022 gboolean canEdit = FALSE;
1023 gboolean canAdd = FALSE;
1024 gboolean canEditTr = TRUE;
1025 gboolean editAddress = FALSE;
1026 AddressTypeControlItem *atci = NULL;
1027 AddressDataSource *ds = NULL;
1028 AddressInterface *iface = NULL;
1030 if( obj == NULL ) return;
1031 if( obj->type == ADDR_INTERFACE ) {
1032 AdapterInterface *adapter = ADAPTER_INTERFACE(obj);
1033 iface = adapter->interface;
1035 if( iface->haveLibrary ) {
1036 /* Enable appropriate File / New command */
1037 atci = adapter->atci;
1038 menu_set_sensitive( addrbook.menu_factory, atci->menuCommand, TRUE );
1043 else if( obj->type == ADDR_DATASOURCE ) {
1044 AdapterDSource *ads = ADAPTER_DSOURCE(obj);
1045 ds = ads->dataSource;
1046 iface = ds->interface;
1047 if( ! iface->readOnly ) {
1048 canAdd = canEdit = editAddress = TRUE;
1050 if( ! iface->haveLibrary ) {
1051 canAdd = canEdit = editAddress = FALSE;
1054 else if( obj->type == ADDR_ITEM_FOLDER ) {
1055 ds = addressbook_find_datasource( addrbook.treeSelected );
1057 iface = ds->interface;
1058 if( ! iface->readOnly ) {
1059 canAdd = editAddress = TRUE;
1063 else if( obj->type == ADDR_ITEM_GROUP ) {
1064 ds = addressbook_find_datasource( addrbook.treeSelected );
1066 iface = ds->interface;
1067 if( ! iface->readOnly ) {
1073 if( addrbook.listSelected == NULL ) canEdit = FALSE;
1076 menu_set_sensitive( addrbook.menu_factory, "/Address/New Address", editAddress );
1077 menu_set_sensitive( addrbook.menu_factory, "/Address/New Group", canAdd );
1078 menu_set_sensitive( addrbook.menu_factory, "/Address/New Folder", canAdd );
1079 gtk_widget_set_sensitive( addrbook.reg_btn, editAddress );
1082 menu_set_sensitive( addrbook.menu_factory, "/Address/Edit", canEdit );
1083 menu_set_sensitive( addrbook.menu_factory, "/Address/Delete", canEdit );
1084 gtk_widget_set_sensitive( addrbook.del_btn, canEdit );
1086 menu_set_sensitive( addrbook.menu_factory, "/File/Edit", canEditTr );
1087 menu_set_sensitive( addrbook.menu_factory, "/File/Delete", canEditTr );
1090 static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node,
1091 gint column, gpointer data)
1093 AddressObject *obj = NULL;
1094 AdapterDSource *ads = NULL;
1095 AddressDataSource *ds = NULL;
1096 ItemFolder *rootFolder = NULL;
1098 addrbook.treeSelected = node;
1099 addrbook.listSelected = NULL;
1100 addressbook_status_show( "" );
1101 if( addrbook.entry != NULL ) gtk_entry_set_text(GTK_ENTRY(addrbook.entry), "");
1103 if( addrbook.clist ) gtk_clist_clear( GTK_CLIST(addrbook.clist) );
1104 if( node ) obj = gtk_ctree_node_get_row_data( ctree, node );
1105 if( obj == NULL ) return;
1107 addrbook.opened = node;
1109 if( obj->type == ADDR_DATASOURCE ) {
1110 /* Read from file */
1111 static gboolean tVal = TRUE;
1113 ads = ADAPTER_DSOURCE(obj);
1114 if( ads == NULL ) return;
1115 ds = ads->dataSource;
1116 if( ds == NULL ) return;
1118 if( addrindex_ds_get_modify_flag( ds ) ) {
1119 addrindex_ds_read_data( ds );
1122 if( ! addrindex_ds_get_read_flag( ds ) ) {
1123 addrindex_ds_read_data( ds );
1125 addressbook_ds_show_message( ds );
1127 if( ! addrindex_ds_get_access_flag( ds ) ) {
1128 /* Remove existing folders and groups */
1129 gtk_clist_freeze( GTK_CLIST(ctree) );
1130 addressbook_tree_remove_children( ctree, node );
1131 gtk_clist_thaw( GTK_CLIST(ctree) );
1133 /* Load folders into the tree */
1134 rootFolder = addrindex_ds_get_root_folder( ds );
1135 if( ds->type == ADDR_IF_JPILOT ) {
1136 addressbook_node_add_folder( node, ds, rootFolder, ADDR_CATEGORY );
1139 addressbook_node_add_folder( node, ds, rootFolder, ADDR_ITEM_FOLDER );
1141 addrindex_ds_set_access_flag( ds, &tVal );
1142 gtk_ctree_expand( ctree, node );
1146 /* Update address list */
1147 addressbook_set_clist( obj );
1149 /* Setup main menu selections */
1150 addressbook_menubar_set_sensitive( FALSE );
1151 addressbook_menuitem_set_sensitive( obj, node );
1153 addressbook_list_select_clear();
1157 static void addressbook_list_selected(GtkCList *clist, gint row, gint column,
1158 GdkEvent *event, gpointer data)
1160 if (event && event->type == GDK_2BUTTON_PRESS) {
1161 /* Handle double click */
1162 if (prefs_common.add_address_by_click &&
1163 addrbook.target_compose)
1164 addressbook_to_clicked(NULL, NULL);
1166 addressbook_edit_address_cb(NULL, 0, NULL);
1171 static void addressbook_list_select_show() {
1172 GList *node = _addressListSelection_;
1174 printf( "show selection...>>>\n" );
1175 while( node != NULL ) {
1176 AddressObject *obj = ( AddressObject * ) node->data;
1178 printf( "- %d : '%s'\n", obj->type, obj->name );
1179 if( obj->type == ADDR_ITEM_GROUP ) {
1180 ItemGroup *group = ( ItemGroup * ) obj;
1181 GList *node = group->listEMail;
1183 ItemEMail *email = node->data;
1184 addr = addressbook_format_address( ( AddressObject * ) email );
1186 printf( "\tgrp >%s<\n", addr );
1189 node = g_list_next( node );
1193 addr = addressbook_format_address( obj );
1195 printf( "\t>%s<\n", addr );
1203 node = g_list_next( node );
1205 printf( "show selection...<<<\n" );
1209 static void addressbook_list_select_clear() {
1210 if( _addressListSelection_ ) {
1211 g_list_free( _addressListSelection_ );
1213 _addressListSelection_ = NULL;
1216 static void addressbook_list_select_add( AddressObject *obj ) {
1218 if( obj->type == ADDR_ITEM_PERSON ||
1219 obj->type == ADDR_ITEM_EMAIL ||
1220 obj->type == ADDR_ITEM_GROUP ) {
1221 if( ! g_list_find( _addressListSelection_, obj ) ) {
1222 _addressListSelection_ = g_list_append( _addressListSelection_, obj );
1226 /* addressbook_list_select_show(); */
1229 static void addressbook_list_select_remove( AddressObject *obj ) {
1230 if( obj == NULL ) return;
1231 if( _addressListSelection_ ) {
1232 _addressListSelection_ = g_list_remove( _addressListSelection_, obj );
1234 /* addressbook_list_select_show(); */
1237 static void addressbook_list_row_selected( GtkCTree *clist, GtkCTreeNode *node, gint column, gpointer data ) {
1238 GtkEntry *entry = GTK_ENTRY(addrbook.entry);
1239 AddressObject *obj = NULL;
1240 AddressObject *pobj = NULL;
1241 AdapterDSource *ads = NULL;
1242 AddressInterface *iface = NULL;
1243 AddressDataSource *ds = NULL;
1244 gboolean canEdit = FALSE;
1245 gboolean canDelete = FALSE;
1247 gtk_entry_set_text( entry, "" );
1248 addrbook.listSelected = node;
1249 obj = gtk_ctree_node_get_row_data( clist, node );
1251 /* printf( "list select: %d : '%s'\n", obj->type, obj->name ); */
1252 addressbook_list_select_add( obj );
1255 pobj = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), addrbook.treeSelected );
1256 if( pobj == NULL ) return;
1258 menu_set_insensitive_all( GTK_MENU_SHELL(addrbook.list_popup) );
1260 if( pobj->type == ADDR_DATASOURCE ) {
1261 ads = ADAPTER_DSOURCE(pobj);
1262 ds = ads->dataSource;
1263 iface = ds->interface;
1264 if( ! iface->readOnly ) {
1266 menu_set_sensitive( addrbook.list_factory, "/New Address", TRUE );
1267 menu_set_sensitive( addrbook.list_factory, "/New Folder", TRUE );
1268 menu_set_sensitive( addrbook.list_factory, "/New Group", TRUE );
1269 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1272 else if( pobj->type != ADDR_INTERFACE ) {
1273 ds = addressbook_find_datasource( addrbook.treeSelected );
1274 iface = ds->interface;
1275 if( ! iface->readOnly ) {
1276 if( pobj->type == ADDR_ITEM_FOLDER || pobj->type == ADDR_ITEM_GROUP ) {
1278 menu_set_sensitive( addrbook.list_factory, "/New Address", TRUE );
1279 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1281 if( pobj->type == ADDR_ITEM_FOLDER ) {
1283 menu_set_sensitive( addrbook.list_factory, "/New Folder", TRUE );
1284 menu_set_sensitive( addrbook.list_factory, "/New Group", TRUE );
1288 if( obj == NULL ) canEdit = FALSE;
1289 canDelete = canEdit;
1290 if( GTK_CLIST(clist)->selection && GTK_CLIST(clist)->selection->next ) canEdit = FALSE;
1292 menu_set_sensitive( addrbook.list_factory, "/Edit", canEdit );
1293 menu_set_sensitive( addrbook.list_factory, "/Delete", canDelete );
1295 menu_set_sensitive( addrbook.menu_factory, "/Address/Edit", canEdit );
1296 menu_set_sensitive( addrbook.menu_factory, "/Address/Delete", canDelete );
1298 gtk_widget_set_sensitive( addrbook.del_btn, canDelete );
1302 static void addressbook_list_row_unselected( GtkCTree *ctree, GtkCTreeNode *node, gint column, gpointer data ) {
1305 obj = gtk_ctree_node_get_row_data( ctree, node );
1307 /* g_print( "list unselect: %d : '%s'\n", obj->type, obj->name ); */
1308 addressbook_list_select_remove( obj );
1312 static void addressbook_entry_gotfocus( GtkWidget *widget ) {
1313 gtk_editable_select_region( GTK_EDITABLE(addrbook.entry), 0, -1 );
1316 static void addressbook_list_button_pressed(GtkWidget *widget,
1317 GdkEventButton *event,
1320 if( ! event ) return;
1321 if( event->button == 3 ) {
1322 gtk_menu_popup( GTK_MENU(addrbook.list_popup), NULL, NULL, NULL, NULL,
1323 event->button, event->time );
1327 static void addressbook_list_button_released(GtkWidget *widget,
1328 GdkEventButton *event,
1333 static void addressbook_tree_button_pressed(GtkWidget *ctree,
1334 GdkEventButton *event,
1337 GtkCList *clist = GTK_CLIST(ctree);
1339 AddressObject *obj = NULL;
1340 /* GtkCTreeNode *node; */
1341 AdapterDSource *ads = NULL;
1342 AddressInterface *iface = NULL;
1343 AddressDataSource *ds = NULL;
1344 /* AddressTypeControlItem *atci = NULL; */
1345 gboolean canEdit = FALSE;
1347 if( ! event ) return;
1348 addressbook_menubar_set_sensitive( FALSE );
1350 if( gtk_clist_get_selection_info( clist, event->x, event->y, &row, &column ) ) {
1351 gtk_clist_select_row( clist, row, column );
1352 gtkut_clist_set_focus_row(clist, row);
1353 obj = gtk_clist_get_row_data( clist, row );
1356 menu_set_insensitive_all(GTK_MENU_SHELL(addrbook.tree_popup));
1358 if( obj == NULL ) return;
1359 if (obj->type == ADDR_DATASOURCE) {
1360 ads = ADAPTER_DSOURCE(obj);
1361 ds = ads->dataSource;
1362 iface = ds->interface;
1364 if( ! iface->readOnly ) {
1365 menu_set_sensitive( addrbook.tree_factory, "/New Address", TRUE );
1366 menu_set_sensitive( addrbook.tree_factory, "/New Folder", TRUE );
1367 menu_set_sensitive( addrbook.tree_factory, "/New Group", TRUE );
1368 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1371 else if (obj->type == ADDR_ITEM_FOLDER) {
1372 ds = addressbook_find_datasource( addrbook.treeSelected );
1373 iface = ds->interface;
1374 if( ! iface->readOnly ) {
1376 menu_set_sensitive( addrbook.tree_factory, "/New Address", TRUE );
1377 menu_set_sensitive( addrbook.tree_factory, "/New Folder", TRUE );
1378 menu_set_sensitive( addrbook.tree_factory, "/New Group", TRUE );
1379 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1382 else if (obj->type == ADDR_ITEM_GROUP) {
1383 ds = addressbook_find_datasource( addrbook.treeSelected );
1384 iface = ds->interface;
1385 if( ! iface->readOnly ) {
1387 menu_set_sensitive( addrbook.tree_factory, "/New Address", TRUE );
1388 gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
1393 menu_set_sensitive( addrbook.tree_factory, "/Edit", canEdit );
1394 menu_set_sensitive( addrbook.tree_factory, "/Delete", canEdit );
1395 menu_set_sensitive( addrbook.menu_factory, "/File/Edit", canEdit );
1396 menu_set_sensitive( addrbook.menu_factory, "/File/Delete", canEdit );
1398 if( event->button == 3 ) {
1399 gtk_menu_popup(GTK_MENU(addrbook.tree_popup), NULL, NULL, NULL, NULL,
1400 event->button, event->time);
1405 static void addressbook_tree_button_released(GtkWidget *ctree,
1406 GdkEventButton *event,
1409 gtk_ctree_select(GTK_CTREE(addrbook.ctree), addrbook.opened);
1410 gtkut_ctree_set_focus_row(GTK_CTREE(addrbook.ctree), addrbook.opened);
1413 static void addressbook_popup_close(GtkMenuShell *menu_shell, gpointer data)
1415 if (!addrbook.opened) return;
1417 gtk_ctree_select(GTK_CTREE(addrbook.ctree), addrbook.opened);
1418 gtkut_ctree_set_focus_row(GTK_CTREE(addrbook.ctree),
1422 static void addressbook_new_folder_cb(gpointer data, guint action,
1425 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1426 AddressObject *obj = NULL;
1427 AddressDataSource *ds = NULL;
1428 AddressBookFile *abf = NULL;
1429 ItemFolder *parentFolder = NULL;
1430 ItemFolder *folder = NULL;
1432 if( ! addrbook.treeSelected ) return;
1433 obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
1434 if( obj == NULL ) return;
1435 ds = addressbook_find_datasource( addrbook.treeSelected );
1436 if( ds == NULL ) return;
1438 if( obj->type == ADDR_DATASOURCE ) {
1439 if( ADAPTER_DSOURCE(obj)->subType != ADDR_BOOK ) return;
1441 else if( obj->type == ADDR_ITEM_FOLDER ) {
1442 parentFolder = ADAPTER_FOLDER(obj)->itemFolder;
1448 abf = ds->rawDataSource;
1449 if( abf == NULL ) return;
1450 folder = addressbook_edit_folder( abf, parentFolder, NULL );
1453 nn = addressbook_node_add_folder( addrbook.treeSelected, ds, folder, ADDR_ITEM_FOLDER );
1454 gtk_ctree_expand( ctree, addrbook.treeSelected );
1455 if( addrbook.treeSelected == addrbook.opened ) addressbook_set_clist(obj);
1460 static void addressbook_new_group_cb(gpointer data, guint action,
1463 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1464 AddressObject *obj = NULL;
1465 AddressDataSource *ds = NULL;
1466 AddressBookFile *abf = NULL;
1467 ItemFolder *parentFolder = NULL;
1468 ItemGroup *group = NULL;
1470 if( ! addrbook.treeSelected ) return;
1471 obj = gtk_ctree_node_get_row_data(ctree, addrbook.treeSelected);
1472 if( obj == NULL ) return;
1473 ds = addressbook_find_datasource( addrbook.treeSelected );
1474 if( ds == NULL ) return;
1476 if( obj->type == ADDR_DATASOURCE ) {
1477 if( ADAPTER_DSOURCE(obj)->subType != ADDR_BOOK ) return;
1479 else if( obj->type == ADDR_ITEM_FOLDER ) {
1480 parentFolder = ADAPTER_FOLDER(obj)->itemFolder;
1486 abf = ds->rawDataSource;
1487 if( abf == NULL ) return;
1488 group = addressbook_edit_group( abf, parentFolder, NULL );
1491 nn = addressbook_node_add_group( addrbook.treeSelected, ds, group );
1492 gtk_ctree_expand( ctree, addrbook.treeSelected );
1493 if( addrbook.treeSelected == addrbook.opened ) addressbook_set_clist(obj);
1498 static void addressbook_change_node_name(GtkCTreeNode *node, const gchar *name)
1500 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1503 GdkPixmap *pix_cl, *pix_op;
1504 GdkBitmap *mask_cl, *mask_op;
1505 gboolean is_leaf, expanded;
1507 gtk_ctree_get_node_info(ctree, node, text, &spacing,
1508 &pix_cl, &mask_cl, &pix_op, &mask_op,
1509 &is_leaf, &expanded);
1510 gtk_ctree_set_node_info(ctree, node, name, spacing,
1511 pix_cl, mask_cl, pix_op, mask_op,
1517 * Enter: obj Address object to edit.
1518 * node Node in tree.
1519 * Return: New name of data source.
1521 static gchar *addressbook_edit_datasource( AddressObject *obj, GtkCTreeNode *node ) {
1522 gchar *newName = NULL;
1523 AddressDataSource *ds = NULL;
1524 AddressInterface *iface = NULL;
1525 AdapterDSource *ads = NULL;
1527 ds = addressbook_find_datasource( node );
1528 if( ds == NULL ) return NULL;
1529 iface = ds->interface;
1530 if( ! iface->haveLibrary ) return NULL;
1532 /* Read data from data source */
1533 if( ! addrindex_ds_get_read_flag( ds ) ) {
1534 addrindex_ds_read_data( ds );
1538 ads = ADAPTER_DSOURCE(obj);
1539 if( ads->subType == ADDR_BOOK ) {
1540 if( addressbook_edit_book( _addressIndex_, ads ) == NULL ) return NULL;
1542 else if( ads->subType == ADDR_VCARD ) {
1543 if( addressbook_edit_vcard( _addressIndex_, ads ) == NULL ) return NULL;
1546 else if( ads->subType == ADDR_JPILOT ) {
1547 if( addressbook_edit_jpilot( _addressIndex_, ads ) == NULL ) return NULL;
1551 else if( ads->subType == ADDR_LDAP ) {
1552 if( addressbook_edit_ldap( _addressIndex_, ads ) == NULL ) return NULL;
1558 newName = obj->name;
1563 * Edit an object that is in the address tree area.
1565 static void addressbook_treenode_edit_cb(gpointer data, guint action,
1568 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1570 AddressDataSource *ds = NULL;
1571 AddressBookFile *abf = NULL;
1572 GtkCTreeNode *node = NULL, *parentNode = NULL;
1575 if( ! addrbook.treeSelected ) return;
1576 node = addrbook.treeSelected;
1577 if( GTK_CTREE_ROW(node)->level == 1 ) return;
1578 obj = gtk_ctree_node_get_row_data( ctree, node );
1579 if( obj == NULL ) return;
1580 parentNode = GTK_CTREE_ROW(node)->parent;
1582 ds = addressbook_find_datasource( node );
1583 if( ds == NULL ) return;
1585 if( obj->type == ADDR_DATASOURCE ) {
1586 name = addressbook_edit_datasource( obj, node );
1587 if( name == NULL ) return;
1590 abf = ds->rawDataSource;
1591 if( abf == NULL ) return;
1592 if( obj->type == ADDR_ITEM_FOLDER ) {
1593 AdapterFolder *adapter = ADAPTER_FOLDER(obj);
1594 ItemFolder *item = adapter->itemFolder;
1595 ItemFolder *parentFolder = NULL;
1596 parentFolder = ( ItemFolder * ) ADDRITEM_PARENT(item);
1597 if( addressbook_edit_folder( abf, parentFolder, item ) == NULL ) return;
1598 name = ADDRITEM_NAME(item);
1600 else if( obj->type == ADDR_ITEM_GROUP ) {
1601 AdapterGroup *adapter = ADAPTER_GROUP(obj);
1602 ItemGroup *item = adapter->itemGroup;
1603 ItemFolder *parentFolder = NULL;
1604 parentFolder = ( ItemFolder * ) ADDRITEM_PARENT(item);
1605 if( addressbook_edit_group( abf, parentFolder, item ) == NULL ) return;
1606 name = ADDRITEM_NAME(item);
1609 if( name && parentNode ) {
1610 /* Update node in tree view */
1611 addressbook_change_node_name( node, name );
1612 gtk_ctree_sort_node(ctree, parentNode);
1613 gtk_ctree_expand( ctree, node );
1614 gtk_ctree_select( ctree, node );
1619 * Delete an item from the tree widget.
1621 static void addressbook_treenode_delete_cb(gpointer data, guint action,
1624 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
1625 GtkCTreeNode *node = NULL;
1629 AddressBookFile *abf = NULL;
1630 AdapterDSource *ads = NULL;
1631 AddressInterface *iface = NULL;
1632 AddressDataSource *ds = NULL;
1633 gboolean remFlag = FALSE;
1635 if( ! addrbook.treeSelected ) return;
1636 node = addrbook.treeSelected;
1637 if( GTK_CTREE_ROW(node)->level == 1 ) return;
1639 obj = gtk_ctree_node_get_row_data( ctree, node );
1640 g_return_if_fail(obj != NULL);
1642 if( obj->type == ADDR_DATASOURCE ) {
1643 ads = ADAPTER_DSOURCE(obj);
1644 if( ads == NULL ) return;
1645 ds = ads->dataSource;
1646 if( ds == NULL ) return;
1649 /* Must be folder or something else */
1650 ds = addressbook_find_datasource( node );
1651 if( ds == NULL ) return;
1653 /* Only allow deletion from non-readOnly data sources */
1654 iface = ds->interface;
1655 if( iface->readOnly ) return;
1658 /* Confirm deletion */
1659 if( obj->type == ADDR_ITEM_FOLDER ) {
1660 message = g_strdup_printf( _(
1661 "Do you want to delete the folder AND all addresses in `%s' ? \n" \
1662 "If deleting the folder only, addresses will be moved into parent folder." ),
1664 aval = alertpanel( _("Delete"), message, _("Folder only"), _("Folder and Addresses"), _("Cancel") );
1666 if( aval == G_ALERTOTHER ) return;
1669 message = g_strdup_printf(_("Really delete `%s' ?"), obj->name);
1670 aval = alertpanel(_("Delete"), message, _("Yes"), _("No"), NULL);
1672 if (aval != G_ALERTDEFAULT) return;
1675 /* Proceed with deletion */
1676 if( obj->type == ADDR_DATASOURCE ) {
1677 /* Remove data source. */
1678 if( addrindex_index_remove_datasource( _addressIndex_, ds ) ) {
1679 addressbook_free_child_adapters( node );
1684 abf = addressbook_get_book_file();
1685 if( abf == NULL ) return;
1688 if( obj->type == ADDR_ITEM_FOLDER ) {
1689 AdapterFolder *adapter = ADAPTER_FOLDER(obj);
1690 ItemFolder *item = adapter->itemFolder;
1691 if( aval == G_ALERTDEFAULT ) {
1692 /* Remove folder only */
1693 item = addrbook_remove_folder( abf, item );
1695 addritem_free_item_folder( item );
1696 addressbook_move_nodes_up( ctree, node );
1700 else if( aval == G_ALERTALTERNATE ) {
1701 /* Remove folder and addresses */
1702 item = addrbook_remove_folder_delete( abf, item );
1704 addritem_free_item_folder( item );
1705 addressbook_free_child_adapters( node );
1710 else if( obj->type == ADDR_ITEM_GROUP ) {
1711 AdapterGroup *adapter = ADAPTER_GROUP(obj);
1712 ItemGroup *item = adapter->itemGroup;
1714 item = addrbook_remove_group( abf, item );
1716 addritem_free_item_group( item );
1722 /* Free up adapter and remove node. */
1723 addressbook_free_adapter( node );
1724 gtk_ctree_remove_node(ctree, node );
1728 static void addressbook_new_address_cb( gpointer data, guint action, GtkWidget *widget ) {
1729 AddressObject *pobj = NULL;
1730 AddressDataSource *ds = NULL;
1731 AddressBookFile *abf = NULL;
1733 pobj = gtk_ctree_node_get_row_data(GTK_CTREE(addrbook.ctree), addrbook.treeSelected);
1734 if( pobj == NULL ) return;
1735 ds = addressbook_find_datasource( GTK_CTREE_NODE(addrbook.treeSelected) );
1736 if( ds == NULL ) return;
1738 abf = ds->rawDataSource;
1739 if( abf == NULL ) return;
1741 if( pobj->type == ADDR_DATASOURCE ) {
1742 if( ADAPTER_DSOURCE(pobj)->subType == ADDR_BOOK ) {
1744 ItemPerson *person = addressbook_edit_person( abf, NULL, NULL, FALSE );
1746 if( addrbook.treeSelected == addrbook.opened ) {
1747 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
1752 else if( pobj->type == ADDR_ITEM_FOLDER ) {
1754 ItemFolder *folder = ADAPTER_FOLDER(pobj)->itemFolder;
1755 ItemPerson *person = addressbook_edit_person( abf, folder, NULL, FALSE );
1757 if (addrbook.treeSelected == addrbook.opened) {
1758 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
1762 else if( pobj->type == ADDR_ITEM_GROUP ) {
1763 /* New address in group */
1764 ItemGroup *group = ADAPTER_GROUP(pobj)->itemGroup;
1765 if( addressbook_edit_group( abf, NULL, group ) == NULL ) return;
1766 if (addrbook.treeSelected == addrbook.opened) {
1767 /* Change node name in tree. */
1768 addressbook_change_node_name( addrbook.treeSelected, ADDRITEM_NAME(group) );
1769 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
1775 * Search for specified group in address index tree.
1777 static GtkCTreeNode *addressbook_find_group_node( GtkCTreeNode *parent, ItemGroup *group ) {
1778 GtkCTreeNode *node = NULL;
1779 GtkCTreeRow *currRow;
1781 currRow = GTK_CTREE_ROW( parent );
1783 node = currRow->children;
1785 AddressObject *obj = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), node );
1786 if( obj->type == ADDR_ITEM_GROUP ) {
1787 ItemGroup *g = ADAPTER_GROUP(obj)->itemGroup;
1788 if( g == group ) return node;
1790 currRow = GTK_CTREE_ROW(node);
1791 node = currRow->sibling;
1797 static AddressBookFile *addressbook_get_book_file() {
1798 AddressBookFile *abf = NULL;
1799 AddressDataSource *ds = NULL;
1801 ds = addressbook_find_datasource( addrbook.treeSelected );
1802 if( ds == NULL ) return NULL;
1803 if( ds->type == ADDR_IF_BOOK ) abf = ds->rawDataSource;
1807 static void addressbook_tree_remove_children( GtkCTree *ctree, GtkCTreeNode *parent ) {
1811 /* Remove existing folders and groups */
1812 row = GTK_CTREE_ROW( parent );
1814 while( (node = row->children) ) {
1815 gtk_ctree_remove_node( ctree, node );
1820 static void addressbook_move_nodes_up( GtkCTree *ctree, GtkCTreeNode *node ) {
1821 GtkCTreeNode *parent, *child;
1822 GtkCTreeRow *currRow;
1823 currRow = GTK_CTREE_ROW( node );
1825 parent = currRow->parent;
1826 while( (child = currRow->children) ) {
1827 gtk_ctree_move( ctree, child, parent, node );
1829 gtk_ctree_sort_node( ctree, parent );
1833 static void addressbook_edit_address_cb( gpointer data, guint action, GtkWidget *widget ) {
1834 GtkCTree *clist = GTK_CTREE(addrbook.clist);
1836 AddressObject *obj = NULL, *pobj = NULL;
1837 AddressDataSource *ds = NULL;
1838 GtkCTreeNode *node = NULL, *parentNode = NULL;
1840 AddressBookFile *abf = NULL;
1842 if( addrbook.listSelected == NULL ) return;
1843 obj = gtk_ctree_node_get_row_data( clist, addrbook.listSelected );
1844 g_return_if_fail(obj != NULL);
1846 ctree = GTK_CTREE( addrbook.ctree );
1847 pobj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
1848 node = gtk_ctree_find_by_row_data( ctree, addrbook.treeSelected, obj );
1850 ds = addressbook_find_datasource( GTK_CTREE_NODE(addrbook.treeSelected) );
1851 if( ds == NULL ) return;
1853 abf = addressbook_get_book_file();
1854 if( abf == NULL ) return;
1855 if( obj->type == ADDR_ITEM_EMAIL ) {
1856 ItemEMail *email = ( ItemEMail * ) obj;
1858 if( email == NULL ) return;
1859 if( pobj && pobj->type == ADDR_ITEM_GROUP ) {
1860 /* Edit parent group */
1861 AdapterGroup *adapter = ADAPTER_GROUP(pobj);
1862 ItemGroup *itemGrp = adapter->itemGroup;
1863 if( addressbook_edit_group( abf, NULL, itemGrp ) == NULL ) return;
1864 name = ADDRITEM_NAME(itemGrp);
1865 node = addrbook.treeSelected;
1866 parentNode = GTK_CTREE_ROW(node)->parent;
1869 /* Edit person - email page */
1870 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
1871 if( addressbook_edit_person( abf, NULL, person, TRUE ) == NULL ) return;
1872 gtk_ctree_select( ctree, addrbook.opened );
1873 invalidate_address_completion();
1877 else if( obj->type == ADDR_ITEM_PERSON ) {
1878 /* Edit person - basic page */
1879 ItemPerson *person = ( ItemPerson * ) obj;
1880 if( addressbook_edit_person( abf, NULL, person, FALSE ) == NULL ) return;
1881 gtk_ctree_select( ctree, addrbook.opened );
1882 invalidate_address_completion();
1885 else if( obj->type == ADDR_ITEM_GROUP ) {
1886 ItemGroup *itemGrp = ( ItemGroup * ) obj;
1887 if( addressbook_edit_group( abf, NULL, itemGrp ) == NULL ) return;
1888 parentNode = addrbook.treeSelected;
1889 node = addressbook_find_group_node( parentNode, itemGrp );
1890 name = ADDRITEM_NAME(itemGrp);
1896 /* Update tree node with node name */
1897 if( node == NULL ) return;
1898 addressbook_change_node_name( node, name );
1899 gtk_ctree_sort_node( ctree, parentNode );
1900 gtk_ctree_select( ctree, addrbook.opened );
1903 static void addressbook_delete_address_cb(gpointer data, guint action,
1906 addressbook_del_clicked(NULL, NULL);
1909 static void close_cb(gpointer data, guint action, GtkWidget *widget)
1911 addressbook_close();
1914 static void addressbook_file_save_cb( gpointer data, guint action, GtkWidget *widget ) {
1915 addressbook_export_to_file();
1918 static void addressbook_person_expand_node( GtkCTree *ctree, GList *node, gpointer *data ) {
1920 ItemPerson *person = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
1921 if( person ) addritem_person_set_opened( person, TRUE );
1925 static void addressbook_person_collapse_node( GtkCTree *ctree, GList *node, gpointer *data ) {
1927 ItemPerson *person = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
1928 if( person ) addritem_person_set_opened( person, FALSE );
1932 static gchar *addressbook_format_item_clist( ItemPerson *person, ItemEMail *email ) {
1934 gchar *eMailAlias = ADDRITEM_NAME(email);
1935 if( eMailAlias && *eMailAlias != '\0' ) {
1937 str = g_strdup_printf( "%s - %s", ADDRITEM_NAME(person), eMailAlias );
1940 str = g_strdup( eMailAlias );
1946 static void addressbook_load_group( GtkCTree *clist, ItemGroup *itemGroup ) {
1947 GList *items = itemGroup->listEMail;
1948 AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_EMAIL );
1949 for( ; items != NULL; items = g_list_next( items ) ) {
1950 GtkCTreeNode *nodeEMail = NULL;
1951 gchar *text[N_COLS];
1952 ItemEMail *email = items->data;
1956 if( ! email ) continue;
1958 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
1959 str = addressbook_format_item_clist( person, email );
1961 text[COL_NAME] = str;
1964 text[COL_NAME] = ADDRITEM_NAME(person);
1966 text[COL_ADDRESS] = email->address;
1967 text[COL_REMARKS] = email->remarks;
1968 nodeEMail = gtk_ctree_insert_node(
1970 text, FOLDER_SPACING,
1971 atci->iconXpm, atci->maskXpm,
1972 atci->iconXpmOpen, atci->maskXpmOpen,
1974 gtk_ctree_node_set_row_data( clist, nodeEMail, email );
1980 static void addressbook_folder_load_person( GtkCTree *clist, ItemFolder *itemFolder ) {
1982 AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_PERSON );
1983 AddressTypeControlItem *atciMail = addrbookctl_lookup( ADDR_ITEM_EMAIL );
1985 if( atci == NULL ) return;
1986 if( atciMail == NULL ) return;
1988 /* Load email addresses */
1989 items = addritem_folder_get_person_list( itemFolder );
1990 for( ; items != NULL; items = g_list_next( items ) ) {
1991 GtkCTreeNode *nodePerson = NULL;
1992 GtkCTreeNode *nodeEMail = NULL;
1993 gchar *text[N_COLS];
1994 gboolean flgFirst = TRUE, haveAddr = FALSE;
1999 person = ( ItemPerson * ) items->data;
2000 if( person == NULL ) continue;
2002 text[COL_NAME] = NULL;
2003 node = person->listEMail;
2005 ItemEMail *email = node->data;
2006 gchar *eMailAddr = NULL;
2007 node = g_list_next( node );
2009 text[COL_ADDRESS] = email->address;
2010 text[COL_REMARKS] = email->remarks;
2011 eMailAddr = ADDRITEM_NAME(email);
2012 if( eMailAddr && *eMailAddr == '\0' ) eMailAddr = NULL;
2014 /* First email belongs with person */
2015 gchar *str = addressbook_format_item_clist( person, email );
2017 text[COL_NAME] = str;
2020 text[COL_NAME] = ADDRITEM_NAME(person);
2022 nodePerson = gtk_ctree_insert_node(
2024 text, FOLDER_SPACING,
2025 atci->iconXpm, atci->maskXpm,
2026 atci->iconXpmOpen, atci->maskXpmOpen,
2027 FALSE, person->isOpened );
2030 gtk_ctree_node_set_row_data(clist, nodePerson, person );
2033 /* Subsequent email is a child node of person */
2034 text[COL_NAME] = ADDRITEM_NAME(email);
2035 nodeEMail = gtk_ctree_insert_node(
2036 clist, nodePerson, NULL,
2037 text, FOLDER_SPACING,
2038 atciMail->iconXpm, atciMail->maskXpm,
2039 atciMail->iconXpmOpen, atciMail->maskXpmOpen,
2041 gtk_ctree_node_set_row_data(clist, nodeEMail, email );
2047 /* Have name without EMail */
2048 text[COL_NAME] = ADDRITEM_NAME(person);
2049 text[COL_ADDRESS] = NULL;
2050 text[COL_REMARKS] = NULL;
2051 nodePerson = gtk_ctree_insert_node(
2053 text, FOLDER_SPACING,
2054 atci->iconXpm, atci->maskXpm,
2055 atci->iconXpmOpen, atci->maskXpmOpen,
2056 FALSE, person->isOpened );
2057 gtk_ctree_node_set_row_data(clist, nodePerson, person );
2059 gtk_ctree_sort_node(GTK_CTREE(clist), NULL);
2061 /* Free up the list */
2062 mgu_clear_list( items );
2063 g_list_free( items );
2066 static void addressbook_folder_load_group( GtkCTree *clist, ItemFolder *itemFolder ) {
2068 AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_GROUP );
2070 /* Load any groups */
2071 if( ! atci ) return;
2072 items = addritem_folder_get_group_list( itemFolder );
2073 for( ; items != NULL; items = g_list_next( items ) ) {
2074 GtkCTreeNode *nodeGroup = NULL;
2075 gchar *text[N_COLS];
2076 ItemGroup *group = items->data;
2077 if( group == NULL ) continue;
2078 text[COL_NAME] = ADDRITEM_NAME(group);
2079 text[COL_ADDRESS] = NULL;
2080 text[COL_REMARKS] = NULL;
2081 nodeGroup = gtk_ctree_insert_node(clist, NULL, NULL,
2082 text, FOLDER_SPACING,
2083 atci->iconXpm, atci->maskXpm,
2084 atci->iconXpmOpen, atci->maskXpmOpen,
2086 gtk_ctree_node_set_row_data(clist, nodeGroup, group );
2087 gtk_ctree_sort_node(clist, NULL);
2089 /* Free up the list */
2090 mgu_clear_list( items );
2091 g_list_free( items );
2095 * Load data sources into list.
2097 static void addressbook_node_load_datasource( GtkCTree *clist, AddressObject *obj ) {
2098 AdapterInterface *adapter;
2099 AddressInterface *iface;
2100 AddressTypeControlItem *atci = NULL;
2101 /* AddressDataSource *ds; */
2102 GtkCTreeNode *newNode, *node;
2104 GtkCell *cell = NULL;
2105 gchar *text[N_COLS];
2107 adapter = ADAPTER_INTERFACE(obj);
2108 if( adapter == NULL ) return;
2109 iface = adapter->interface;
2110 atci = adapter->atci;
2111 if( atci == NULL ) return;
2113 /* Create nodes in list copying values for data sources in tree */
2114 row = GTK_CTREE_ROW( adapter->treeNode );
2116 node = row->children;
2118 gpointer data = gtk_ctree_node_get_row_data( clist, node );
2119 row = GTK_CTREE_ROW( node );
2120 cell = ( ( GtkCListRow * )row )->cell;
2121 text[COL_NAME] = cell->u.text;
2122 text[COL_ADDRESS] = NULL;
2123 text[COL_REMARKS] = NULL;
2124 newNode = gtk_ctree_insert_node( clist, NULL, NULL,
2125 text, FOLDER_SPACING,
2126 atci->iconXpm, atci->maskXpm,
2127 atci->iconXpmOpen, atci->maskXpmOpen,
2129 gtk_ctree_node_set_row_data( clist, newNode, data );
2130 node = row->sibling;
2134 gtk_ctree_sort_node( clist, NULL );
2137 static AddressDataSource *addressbook_find_datasource( GtkCTreeNode *node ) {
2138 AddressDataSource *ds = NULL;
2141 g_return_val_if_fail(addrbook.ctree != NULL, NULL);
2144 if( GTK_CTREE_ROW(node)->level < 2 ) return NULL;
2145 ao = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), node );
2147 /* printf( "ao->type = %d\n", ao->type ); */
2148 if( ao->type == ADDR_DATASOURCE ) {
2149 AdapterDSource *ads = ADAPTER_DSOURCE(ao);
2150 /* printf( "found it\n" ); */
2151 ds = ads->dataSource;
2155 node = GTK_CTREE_ROW(node)->parent;
2161 * Load address list widget with children of specified object.
2162 * Enter: obj Parent object to be loaded.
2164 static void addressbook_set_clist( AddressObject *obj ) {
2165 GtkCTree *ctreelist = GTK_CTREE(addrbook.clist);
2166 GtkCList *clist = GTK_CLIST(addrbook.clist);
2167 AddressDataSource *ds = NULL;
2168 AdapterDSource *ads = NULL;
2171 gtk_clist_clear(clist);
2175 if( obj->type == ADDR_INTERFACE ) {
2176 /* printf( "set_clist: loading datasource...\n" ); */
2177 /* addressbook_node_load_datasource( clist, obj ); */
2181 gtk_clist_freeze(clist);
2182 gtk_clist_clear(clist);
2184 if( obj->type == ADDR_DATASOURCE ) {
2185 ads = ADAPTER_DSOURCE(obj);
2186 ds = ADAPTER_DSOURCE(obj)->dataSource;
2188 /* Load root folder */
2189 ItemFolder *rootFolder = NULL;
2190 rootFolder = addrindex_ds_get_root_folder( ds );
2191 addressbook_folder_load_person( ctreelist, addrindex_ds_get_root_folder( ds ) );
2192 addressbook_folder_load_group( ctreelist, addrindex_ds_get_root_folder( ds ) );
2196 if( obj->type == ADDR_ITEM_GROUP ) {
2198 ItemGroup *itemGroup = ADAPTER_GROUP(obj)->itemGroup;
2199 addressbook_load_group( ctreelist, itemGroup );
2201 else if( obj->type == ADDR_ITEM_FOLDER ) {
2203 ItemFolder *itemFolder = ADAPTER_FOLDER(obj)->itemFolder;
2204 addressbook_folder_load_person( ctreelist, itemFolder );
2205 addressbook_folder_load_group( ctreelist, itemFolder );
2209 gtk_clist_sort(clist);
2210 gtk_clist_thaw(clist);
2214 * Free adaptor for specified node.
2216 static void addressbook_free_adapter( GtkCTreeNode *node ) {
2219 g_return_if_fail(addrbook.ctree != NULL);
2222 if( GTK_CTREE_ROW(node)->level < 2 ) return;
2223 ao = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), node );
2224 if( ao == NULL ) return;
2225 if( ao->type == ADDR_INTERFACE ) {
2226 AdapterInterface *ai = ADAPTER_INTERFACE(ao);
2227 addrbookctl_free_interface( ai );
2229 else if( ao->type == ADDR_DATASOURCE ) {
2230 AdapterDSource *ads = ADAPTER_DSOURCE(ao);
2231 addrbookctl_free_datasource( ads );
2233 else if( ao->type == ADDR_ITEM_FOLDER ) {
2234 AdapterFolder *af = ADAPTER_FOLDER(ao);
2235 addrbookctl_free_folder( af );
2237 else if( ao->type == ADDR_ITEM_GROUP ) {
2238 AdapterGroup *ag = ADAPTER_GROUP(ao);
2239 addrbookctl_free_group( ag );
2241 gtk_ctree_node_set_row_data( GTK_CTREE(addrbook.ctree), node, NULL );
2246 * Free all children adapters.
2248 static void addressbook_free_child_adapters( GtkCTreeNode *node ) {
2249 GtkCTreeNode *parent, *child;
2250 GtkCTreeRow *currRow;
2252 if( node == NULL ) return;
2253 currRow = GTK_CTREE_ROW( node );
2255 parent = currRow->parent;
2256 child = currRow->children;
2258 addressbook_free_child_adapters( child );
2259 addressbook_free_adapter( child );
2260 currRow = GTK_CTREE_ROW( child );
2261 child = currRow->sibling;
2266 AdapterDSource *addressbook_create_ds_adapter( AddressDataSource *ds,
2267 AddressObjectType otype, gchar *name )
2269 AdapterDSource *adapter = g_new0( AdapterDSource, 1 );
2270 ADDRESS_OBJECT(adapter)->type = ADDR_DATASOURCE;
2271 ADDRESS_OBJECT_NAME(adapter) = g_strdup( name );
2272 adapter->dataSource = ds;
2273 adapter->subType = otype;
2277 void addressbook_ads_set_name( AdapterDSource *adapter, gchar *value ) {
2278 ADDRESS_OBJECT_NAME(adapter) = mgu_replace_string( ADDRESS_OBJECT_NAME(adapter), value );
2282 * Load tree from address index with the initial data.
2284 static void addressbook_load_tree( void ) {
2285 GtkCTree *ctree = GTK_CTREE( addrbook.ctree );
2286 GList *nodeIf, *nodeDS;
2287 AdapterInterface *adapter;
2288 AddressInterface *iface;
2289 AddressTypeControlItem *atci;
2290 AddressDataSource *ds;
2291 AdapterDSource *ads;
2292 GtkCTreeNode *node, *newNode;
2295 nodeIf = _addressInterfaceList_;
2297 adapter = nodeIf->data;
2298 node = adapter->treeNode;
2299 iface = adapter->interface;
2300 atci = adapter->atci;
2302 if( iface->useInterface ) {
2303 /* Load data sources below interface node */
2304 nodeDS = iface->listSource;
2308 name = addrindex_ds_get_name( ds );
2309 ads = addressbook_create_ds_adapter( ds, atci->objectType, name );
2310 newNode = addressbook_add_object( node, ADDRESS_OBJECT(ads) );
2311 nodeDS = g_list_next( nodeDS );
2313 gtk_ctree_expand( ctree, node );
2316 nodeIf = g_list_next( nodeIf );
2321 * Convert the old address book to new format.
2323 static gboolean addressbook_convert( AddressIndex *addrIndex ) {
2324 gboolean retVal = FALSE;
2325 gboolean errFlag = TRUE;
2328 /* Read old address book, performing conversion */
2329 debug_print( "Reading and converting old address book...\n" );
2330 addrindex_set_file_name( addrIndex, ADDRESSBOOK_OLD_FILE );
2331 addrindex_read_data( addrIndex );
2332 if( addrIndex->retVal == MGU_NO_FILE ) {
2333 /* We do not have a file - new user */
2334 debug_print( "New user... create new books...\n" );
2335 addrindex_create_new_books( addrIndex );
2336 if( addrIndex->retVal == MGU_SUCCESS ) {
2337 /* Save index file */
2338 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2339 addrindex_save_data( addrIndex );
2340 if( addrIndex->retVal == MGU_SUCCESS ) {
2345 msg = _( "New user, could not save index file." );
2349 msg = _( "New user, could not save address book files." );
2353 /* We have an old file */
2354 if( addrIndex->wasConverted ) {
2355 /* Converted successfully - save address index */
2356 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2357 addrindex_save_data( addrIndex );
2358 if( addrIndex->retVal == MGU_SUCCESS ) {
2359 msg = _( "Old address book converted successfully." );
2364 msg = _("Old address book converted,\n"
2365 "could not save new address index file" );
2369 /* File conversion failed - just create new books */
2370 debug_print( "File conversion failed... just create new books...\n" );
2371 addrindex_create_new_books( addrIndex );
2372 if( addrIndex->retVal == MGU_SUCCESS ) {
2374 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2375 addrindex_save_data( addrIndex );
2376 if( addrIndex->retVal == MGU_SUCCESS ) {
2377 msg = _("Could not convert address book,\n"
2378 "but created empty new address book files." );
2383 msg = _("Could not convert address book,\n"
2384 "could not create new address book files." );
2388 msg = _("Could not convert address book\n"
2389 "and could not create new address book files." );
2394 debug_print( "Error\n%s\n", msg );
2395 alertpanel( _( "Addressbook conversion error" ), msg, _( "Close" ), NULL, NULL );
2398 debug_print( "Warning\n%s\n", msg );
2399 alertpanel( _( "Addressbook conversion" ), msg, _( "Close" ), NULL, NULL );
2405 void addressbook_read_file( void ) {
2406 AddressIndex *addrIndex = NULL;
2408 debug_print( "Reading address index...\n" );
2409 if( _addressIndex_ ) {
2410 debug_print( "address book already read!!!\n" );
2414 addrIndex = addrindex_create_index();
2416 /* Use new address book index. */
2417 addrindex_set_file_path( addrIndex, get_rc_dir() );
2418 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2419 addrindex_read_data( addrIndex );
2420 if( addrIndex->retVal == MGU_NO_FILE ) {
2421 /* Conversion required */
2422 debug_print( "Converting...\n" );
2423 if( addressbook_convert( addrIndex ) ) {
2424 _addressIndex_ = addrIndex;
2427 else if( addrIndex->retVal == MGU_SUCCESS ) {
2428 _addressIndex_ = addrIndex;
2431 /* Error reading address book */
2432 debug_print( "Could not read address index.\n" );
2433 addrindex_print_index( addrIndex, stdout );
2434 alertpanel( _( "Addressbook Error" ),
2435 _( "Could not read address index" ),
2436 _( "Close" ), NULL, NULL );
2438 debug_print( "done.\n" );
2442 void addressbook_read_file_old( void ) {
2443 AddressIndex *addrIndex = NULL;
2444 gboolean errFlag = TRUE;
2447 if( _addressIndex_ ) {
2448 debug_print( "address book already read!!!\n" );
2452 addrIndex = addrindex_create_index();
2454 /* Use use new address book. */
2455 /* addrindex_set_file_path( addrIndex, "/home/match/tmp/empty-dir" ); */
2456 addrindex_set_file_path( addrIndex, get_rc_dir() );
2457 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2459 debug_print( "Reading address index...\n" );
2460 addrindex_read_data( addrIndex );
2461 if( addrIndex->retVal == MGU_NO_FILE ) {
2462 /* Read old address book, performing conversion */
2463 debug_print( "Reading and converting old address book...\n" );
2464 addrindex_set_file_name( addrIndex, ADDRESSBOOK_OLD_FILE );
2465 addrindex_read_data( addrIndex );
2466 if( addrIndex->retVal == MGU_NO_FILE ) {
2467 /* We do not have a file - new user */
2468 debug_print( "New user... create new books...\n" );
2469 addrindex_create_new_books( addrIndex );
2470 if( addrIndex->retVal == MGU_SUCCESS ) {
2471 /* Save index file */
2472 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2473 addrindex_save_data( addrIndex );
2474 if( addrIndex->retVal == MGU_SUCCESS ) {
2478 msg = g_strdup( _( "New user, could not save index file." ) );
2482 msg = g_strdup( _( "New user, could not save address book files." ) );
2486 /* We have an old file */
2487 if( addrIndex->wasConverted ) {
2488 /* Converted successfully - save address index */
2489 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2490 addrindex_save_data( addrIndex );
2491 if( addrIndex->retVal == MGU_SUCCESS ) {
2492 msg = g_strdup( _( "Old address book converted successfully." ) );
2497 "Old address book converted, " \
2498 "could not save new address index file" ) );
2502 /* File conversion failed - just create new books */
2503 debug_print( "File conversion failed... just create new books...\n" );
2504 addrindex_create_new_books( addrIndex );
2505 if( addrIndex->retVal == MGU_SUCCESS ) {
2507 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
2508 addrindex_save_data( addrIndex );
2509 if( addrIndex->retVal == MGU_SUCCESS ) {
2511 "Could not convert address book, " \
2512 "but created empty new address book files." ) );
2517 "Could not convert address book, " \
2518 "could not create new address book files." ) );
2523 "Could not convert address book " \
2524 "and could not create new address book files." ) );
2529 else if( addrIndex->retVal == MGU_SUCCESS ) {
2533 debug_print( "Could not read address index.\n" );
2534 addrindex_print_index( addrIndex, stdout );
2535 msg = g_strdup( _( "Could not read address index" ) );
2537 _addressIndex_ = addrIndex;
2540 debug_print( "Error\n%s\n", msg );
2541 alertpanel( _( "Addressbook Conversion Error" ), msg,
2542 _( "Close" ), NULL, NULL );
2546 debug_print( "Warning\n%s\n", msg );
2547 alertpanel( _( "Addressbook Conversion" ), msg,
2548 _( "Close" ), NULL, NULL );
2551 if( msg ) g_free( msg );
2552 debug_print( "done.\n" );
2557 * Add object into the address index tree widget.
2558 * Enter: node Parent node.
2559 * obj Object to add.
2560 * Return: Node that was added, or NULL if object not added.
2562 static GtkCTreeNode *addressbook_add_object(GtkCTreeNode *node,
2565 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2566 GtkCTreeNode *added;
2567 AddressObject *pobj;
2568 AddressObjectType otype;
2569 AddressTypeControlItem *atci = NULL;
2571 g_return_val_if_fail(node != NULL, NULL);
2572 g_return_val_if_fail(obj != NULL, NULL);
2574 pobj = gtk_ctree_node_get_row_data(ctree, node);
2575 g_return_val_if_fail(pobj != NULL, NULL);
2577 /* Determine object type to be displayed */
2578 if( obj->type == ADDR_DATASOURCE ) {
2579 otype = ADAPTER_DSOURCE(obj)->subType;
2585 /* Handle any special conditions. */
2587 atci = addrbookctl_lookup( otype );
2589 if( atci->showInTree ) {
2590 /* Add object to tree */
2593 added = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
2594 atci->iconXpm, atci->maskXpm, atci->iconXpmOpen, atci->maskXpmOpen,
2595 atci->treeLeaf, atci->treeExpand );
2596 gtk_ctree_node_set_row_data(ctree, added, obj);
2600 gtk_ctree_sort_node(ctree, node);
2606 * Add group into the address index tree.
2607 * Enter: node Parent node.
2609 * itemGroup Group to add.
2610 * Return: Inserted node.
2612 static GtkCTreeNode *addressbook_node_add_group( GtkCTreeNode *node, AddressDataSource *ds, ItemGroup *itemGroup ) {
2613 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2614 GtkCTreeNode *newNode;
2615 AdapterGroup *adapter;
2616 AddressTypeControlItem *atci = NULL;
2619 if( ds == NULL ) return NULL;
2620 if( node == NULL || itemGroup == NULL ) return NULL;
2622 name = &itemGroup->obj.name;
2624 atci = addrbookctl_lookup( ADDR_ITEM_GROUP );
2626 adapter = g_new0( AdapterGroup, 1 );
2627 ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_GROUP;
2628 ADDRESS_OBJECT_NAME(adapter) = g_strdup( ADDRITEM_NAME(itemGroup) );
2629 adapter->itemGroup = itemGroup;
2631 newNode = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
2632 atci->iconXpm, atci->maskXpm, atci->iconXpm, atci->maskXpm,
2633 atci->treeLeaf, atci->treeExpand );
2634 gtk_ctree_node_set_row_data( ctree, newNode, adapter );
2635 gtk_ctree_sort_node( ctree, node );
2640 * Add folder into the address index tree.
2641 * Enter: node Parent node.
2643 * itemFolder Folder to add.
2644 * otype Object type to display.
2645 * Return: Inserted node.
2647 static GtkCTreeNode *addressbook_node_add_folder(
2648 GtkCTreeNode *node, AddressDataSource *ds, ItemFolder *itemFolder, AddressObjectType otype )
2650 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2651 GtkCTreeNode *newNode = NULL;
2652 AdapterFolder *adapter;
2653 AddressTypeControlItem *atci = NULL;
2654 GList *listItems = NULL;
2656 ItemFolder *rootFolder;
2658 if( ds == NULL ) return NULL;
2659 if( node == NULL || itemFolder == NULL ) return NULL;
2661 /* Determine object type */
2662 atci = addrbookctl_lookup( otype );
2663 if( atci == NULL ) return NULL;
2665 rootFolder = addrindex_ds_get_root_folder( ds );
2666 if( itemFolder == rootFolder ) {
2670 name = &itemFolder->obj.name;
2672 adapter = g_new0( AdapterFolder, 1 );
2673 ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_FOLDER;
2674 ADDRESS_OBJECT_NAME(adapter) = g_strdup( ADDRITEM_NAME(itemFolder) );
2675 adapter->itemFolder = itemFolder;
2677 newNode = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
2678 atci->iconXpm, atci->maskXpm, atci->iconXpm, atci->maskXpm,
2679 atci->treeLeaf, atci->treeExpand );
2680 gtk_ctree_node_set_row_data( ctree, newNode, adapter );
2683 listItems = itemFolder->listFolder;
2684 while( listItems ) {
2685 ItemFolder *item = listItems->data;
2686 addressbook_node_add_folder( newNode, ds, item, otype );
2687 listItems = g_list_next( listItems );
2689 listItems = itemFolder->listGroup;
2690 while( listItems ) {
2691 ItemGroup *item = listItems->data;
2692 addressbook_node_add_group( newNode, ds, item );
2693 listItems = g_list_next( listItems );
2695 gtk_ctree_sort_node( ctree, node );
2699 static void addressbook_delete_object(AddressObject *obj) {
2700 AdapterDSource *ads = NULL;
2701 AddressDataSource *ds = NULL;
2704 /* Remove data source. */
2705 printf( "Delete obj type : %d\n", obj->type );
2707 ads = ADAPTER_DSOURCE(obj);
2708 if( ads == NULL ) return;
2709 ds = ads->dataSource;
2710 if( ds == NULL ) return;
2712 /* Remove data source */
2713 if( addrindex_index_remove_datasource( _addressIndex_, ds ) ) {
2714 addrindex_free_datasource( _addressIndex_, ds );
2716 /* Free up Adapter object */
2717 g_free( ADAPTER_DSOURCE(obj) );
2720 void addressbook_export_to_file( void ) {
2721 if( _addressIndex_ ) {
2722 /* Save all new address book data */
2723 debug_print( "Saving address books...\n" );
2724 addrindex_save_all_books( _addressIndex_ );
2726 debug_print( "Exporting addressbook to file...\n" );
2727 addrindex_save_data( _addressIndex_ );
2728 if( _addressIndex_->retVal != MGU_SUCCESS ) {
2729 addrindex_print_index( _addressIndex_, stdout );
2732 /* Notify address completion of new data */
2733 invalidate_address_completion();
2737 static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
2739 if (event && event->keyval == GDK_Escape)
2740 addressbook_close();
2744 * Comparsion using names of AddressItem objects.
2747 static gint addressbook_list_compare_func(GtkCList *clist,
2751 AddressObject *obj1 = ((GtkCListRow *)ptr1)->data;
2752 AddressObject *obj2 = ((GtkCListRow *)ptr2)->data;
2753 gchar *name1 = NULL, *name2 = NULL;
2754 if( obj1 ) name1 = obj1->name;
2755 if( obj2 ) name2 = obj2->name;
2756 if( ! name1 ) return ( name2 != NULL );
2757 if( ! name2 ) return -1;
2758 return strcasecmp(name1, name2);
2763 * Comparison using cell contents (text in first column).
2765 static gint addressbook_list_compare_func( GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2 ) {
2766 GtkCell *cell1 = ((GtkCListRow *)ptr1)->cell;
2767 GtkCell *cell2 = ((GtkCListRow *)ptr2)->cell;
2768 gchar *name1 = NULL, *name2 = NULL;
2769 if( cell1 ) name1 = cell1->u.text;
2770 if( cell2 ) name2 = cell2->u.text;
2771 if( ! name1 ) return ( name2 != NULL );
2772 if( ! name2 ) return -1;
2773 return strcasecmp( name1, name2 );
2777 gint addressbook_obj_name_compare(gconstpointer a, gconstpointer b)
2779 const AddressObject *obj = a;
2780 const gchar *name = b;
2781 AddressTypeControlItem *atci = NULL;
2783 if (!obj || !name) return -1;
2785 atci = addrbookctl_lookup( obj->type );
2786 if( ! atci ) return -1;
2787 if( ! obj->name ) return -1;
2788 return strcasecmp(obj->name, name);
2791 static void addressbook_book_show_message( AddressBookFile *abf ) {
2792 *addressbook_msgbuf = '\0';
2794 if( abf->retVal == MGU_SUCCESS ) {
2795 sprintf( addressbook_msgbuf, "%s", abf->name );
2798 sprintf( addressbook_msgbuf, "%s: %s", abf->name, mgu_error2string( abf->retVal ) );
2801 addressbook_status_show( addressbook_msgbuf );
2804 static void addressbook_new_book_cb( gpointer data, guint action, GtkWidget *widget ) {
2805 AdapterDSource *ads;
2806 AdapterInterface *adapter;
2808 adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
2809 if( adapter == NULL ) return;
2810 if( addrbook.treeSelected == NULL ) return;
2811 if( addrbook.treeSelected != adapter->treeNode ) return;
2812 ads = addressbook_edit_book( _addressIndex_, NULL );
2814 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2815 if( addrbook.treeSelected == addrbook.opened ) {
2816 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2821 static void addressbook_new_vcard_cb( gpointer data, guint action, GtkWidget *widget ) {
2822 AdapterDSource *ads;
2823 AdapterInterface *adapter;
2825 adapter = addrbookctl_find_interface( ADDR_IF_VCARD );
2826 if( adapter == NULL ) return;
2827 if( addrbook.treeSelected != adapter->treeNode ) return;
2828 ads = addressbook_edit_vcard( _addressIndex_, NULL );
2830 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2831 if( addrbook.treeSelected == addrbook.opened ) {
2832 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2837 static void addressbook_vcard_show_message( VCardFile *vcf ) {
2838 *addressbook_msgbuf = '\0';
2840 if( vcf->retVal == MGU_SUCCESS ) {
2841 sprintf( addressbook_msgbuf, "%s", vcf->name );
2844 sprintf( addressbook_msgbuf, "%s: %s", vcf->name, mgu_error2string( vcf->retVal ) );
2847 addressbook_status_show( addressbook_msgbuf );
2851 static void addressbook_new_jpilot_cb( gpointer data, guint action, GtkWidget *widget ) {
2852 AdapterDSource *ads;
2853 AdapterInterface *adapter;
2854 AddressInterface *iface;
2856 adapter = addrbookctl_find_interface( ADDR_IF_JPILOT );
2857 if( adapter == NULL ) return;
2858 if( addrbook.treeSelected != adapter->treeNode ) return;
2859 iface = adapter->interface;
2860 if( ! iface->haveLibrary ) return;
2861 ads = addressbook_edit_jpilot( _addressIndex_, NULL );
2863 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2864 if( addrbook.treeSelected == addrbook.opened ) {
2865 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2870 static void addressbook_jpilot_show_message( JPilotFile *jpf ) {
2871 *addressbook_msgbuf = '\0';
2873 if( jpf->retVal == MGU_SUCCESS ) {
2874 sprintf( addressbook_msgbuf, "%s", jpf->name );
2877 sprintf( addressbook_msgbuf, "%s: %s", jpf->name, mgu_error2string( jpf->retVal ) );
2880 addressbook_status_show( addressbook_msgbuf );
2886 static void addressbook_new_ldap_cb( gpointer data, guint action, GtkWidget *widget ) {
2887 AdapterDSource *ads;
2888 AdapterInterface *adapter;
2889 AddressInterface *iface;
2891 adapter = addrbookctl_find_interface( ADDR_IF_LDAP );
2892 if( adapter == NULL ) return;
2893 if( addrbook.treeSelected != adapter->treeNode ) return;
2894 iface = adapter->interface;
2895 if( ! iface->haveLibrary ) return;
2896 ads = addressbook_edit_ldap( _addressIndex_, NULL );
2898 addressbook_add_object( addrbook.treeSelected, ADDRESS_OBJECT(ads) );
2899 if( addrbook.treeSelected == addrbook.opened ) {
2900 gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened );
2905 static void addressbook_ldap_show_message( SyldapServer *svr ) {
2906 *addressbook_msgbuf = '\0';
2908 if( svr->busyFlag ) {
2909 sprintf( addressbook_msgbuf, "%s: %s", svr->name, ADDRESSBOOK_LDAP_BUSYMSG );
2912 if( svr->retVal == MGU_SUCCESS ) {
2913 sprintf( addressbook_msgbuf, "%s", svr->name );
2916 sprintf( addressbook_msgbuf, "%s: %s", svr->name, mgu_error2string( svr->retVal ) );
2920 addressbook_status_show( addressbook_msgbuf );
2923 static void ldapsearch_callback( SyldapServer *sls ) {
2924 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2926 AdapterDSource *ads = NULL;
2927 AddressDataSource *ds = NULL;
2928 AddressInterface *iface = NULL;
2930 if( sls == NULL ) return;
2931 if( ! addrbook.treeSelected ) return;
2932 if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
2934 obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
2935 if( obj == NULL ) return;
2936 if( obj->type == ADDR_DATASOURCE ) {
2937 ads = ADAPTER_DSOURCE(obj);
2938 if( ads->subType == ADDR_LDAP ) {
2939 SyldapServer *server;
2941 ds = ads->dataSource;
2942 if( ds == NULL ) return;
2943 iface = ds->interface;
2944 if( ! iface->haveLibrary ) return;
2945 server = ds->rawDataSource;
2946 if( server == sls ) {
2947 /* Read from cache */
2948 gtk_widget_show_all(addrbook.window);
2949 addressbook_set_clist( obj );
2950 addressbook_ldap_show_message( sls );
2951 gtk_widget_show_all(addrbook.window);
2952 gtk_entry_set_text( GTK_ENTRY(addrbook.entry), "" );
2960 * Lookup button handler.
2962 static void addressbook_lup_clicked( GtkButton *button, gpointer data ) {
2963 GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
2966 AdapterDSource *ads = NULL;
2967 AddressDataSource *ds = NULL;
2968 AddressInterface *iface = NULL;
2972 sLookup = gtk_editable_get_chars( GTK_EDITABLE(addrbook.entry), 0, -1 );
2973 g_strchomp( sLookup );
2975 if( ! addrbook.treeSelected ) return;
2976 if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
2978 obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
2979 if( obj == NULL ) return;
2982 if( obj->type == ADDR_DATASOURCE ) {
2983 ads = ADAPTER_DSOURCE(obj);
2984 if( ads->subType == ADDR_LDAP ) {
2985 SyldapServer *server;
2987 ds = ads->dataSource;
2988 if( ds == NULL ) return;
2989 iface = ds->interface;
2990 if( ! iface->haveLibrary ) return;
2991 server = ds->rawDataSource;
2993 syldap_cancel_read( server );
2994 if( *sLookup == '\0' || strlen( sLookup ) < 1 ) return;
2995 syldap_set_search_value( server, sLookup );
2996 syldap_set_callback( server, ldapsearch_callback );
2997 syldap_read_data_th( server );
2998 addressbook_ldap_show_message( server );
3006 /* **********************************************************************
3007 * Build lookup tables.
3008 * ***********************************************************************
3012 * Build table that controls the rendering of object types.
3014 void addrbookctl_build_map( GtkWidget *window ) {
3015 AddressTypeControlItem *atci;
3018 PIXMAP_CREATE(window, folderxpm, folderxpmmask, dir_close_xpm);
3019 PIXMAP_CREATE(window, folderopenxpm, folderopenxpmmask, dir_open_xpm);
3020 PIXMAP_CREATE(window, groupxpm, groupxpmmask, group_xpm);
3021 PIXMAP_CREATE(window, vcardxpm, vcardxpmmask, vcard_xpm);
3022 PIXMAP_CREATE(window, bookxpm, bookxpmmask, book_xpm);
3023 PIXMAP_CREATE(window, addressxpm, addressxpmmask, address_xpm);
3024 PIXMAP_CREATE(window, jpilotxpm, jpilotxpmmask, jpilot_xpm);
3025 PIXMAP_CREATE(window, categoryxpm, categoryxpmmask, category_xpm);
3026 PIXMAP_CREATE(window, ldapxpm, ldapxpmmask, ldap_xpm);
3028 _addressBookTypeHash_ = g_hash_table_new( g_int_hash, g_int_equal );
3029 _addressBookTypeList_ = NULL;
3032 atci = g_new0( AddressTypeControlItem, 1 );
3033 atci->objectType = ADDR_INTERFACE;
3034 atci->interfaceType = ADDR_IF_NONE;
3035 atci->showInTree = TRUE;
3036 atci->treeExpand = TRUE;
3037 atci->treeLeaf = FALSE;
3038 atci->displayName = _( "Interface" );
3039 atci->iconXpm = folderxpm;
3040 atci->maskXpm = folderxpmmask;
3041 atci->iconXpmOpen = folderopenxpm;
3042 atci->maskXpmOpen = folderopenxpmmask;
3043 atci->menuCommand = NULL;
3044 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3045 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3048 atci = g_new0( AddressTypeControlItem, 1 );
3049 atci->objectType = ADDR_BOOK;
3050 atci->interfaceType = ADDR_IF_BOOK;
3051 atci->showInTree = TRUE;
3052 atci->treeExpand = TRUE;
3053 atci->treeLeaf = FALSE;
3054 atci->displayName = _( "Address Book" );
3055 atci->iconXpm = bookxpm;
3056 atci->maskXpm = bookxpmmask;
3057 atci->iconXpmOpen = bookxpm;
3058 atci->maskXpmOpen = bookxpmmask;
3059 atci->menuCommand = "/File/New Book";
3060 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3061 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3064 atci = g_new0( AddressTypeControlItem, 1 );
3065 atci->objectType = ADDR_ITEM_PERSON;
3066 atci->interfaceType = ADDR_IF_NONE;
3067 atci->showInTree = FALSE;
3068 atci->treeExpand = FALSE;
3069 atci->treeLeaf = FALSE;
3070 atci->displayName = _( "Person" );
3071 atci->iconXpm = NULL;
3072 atci->maskXpm = NULL;
3073 atci->iconXpmOpen = NULL;
3074 atci->maskXpmOpen = NULL;
3075 atci->menuCommand = NULL;
3076 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3077 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3080 atci = g_new0( AddressTypeControlItem, 1 );
3081 atci->objectType = ADDR_ITEM_EMAIL;
3082 atci->interfaceType = ADDR_IF_NONE;
3083 atci->showInTree = FALSE;
3084 atci->treeExpand = FALSE;
3085 atci->treeLeaf = TRUE;
3086 atci->displayName = _( "EMail Address" );
3087 atci->iconXpm = addressxpm;
3088 atci->maskXpm = addressxpmmask;
3089 atci->iconXpmOpen = addressxpm;
3090 atci->maskXpmOpen = addressxpmmask;
3091 atci->menuCommand = NULL;
3092 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3093 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3096 atci = g_new0( AddressTypeControlItem, 1 );
3097 atci->objectType = ADDR_ITEM_GROUP;
3098 atci->interfaceType = ADDR_IF_BOOK;
3099 atci->showInTree = TRUE;
3100 atci->treeExpand = FALSE;
3101 atci->treeLeaf = FALSE;
3102 atci->displayName = _( "Group" );
3103 atci->iconXpm = groupxpm;
3104 atci->maskXpm = groupxpmmask;
3105 atci->iconXpmOpen = groupxpm;
3106 atci->maskXpmOpen = groupxpmmask;
3107 atci->menuCommand = NULL;
3108 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3109 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3112 atci = g_new0( AddressTypeControlItem, 1 );
3113 atci->objectType = ADDR_ITEM_FOLDER;
3114 atci->interfaceType = ADDR_IF_BOOK;
3115 atci->showInTree = TRUE;
3116 atci->treeExpand = FALSE;
3117 atci->treeLeaf = FALSE;
3118 atci->displayName = _( "Folder" );
3119 atci->iconXpm = folderxpm;
3120 atci->maskXpm = folderxpmmask;
3121 atci->iconXpmOpen = folderopenxpm;
3122 atci->maskXpmOpen = folderopenxpmmask;
3123 atci->menuCommand = NULL;
3124 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3125 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3128 atci = g_new0( AddressTypeControlItem, 1 );
3129 atci->objectType = ADDR_VCARD;
3130 atci->interfaceType = ADDR_IF_VCARD;
3131 atci->showInTree = TRUE;
3132 atci->treeExpand = TRUE;
3133 atci->treeLeaf = TRUE;
3134 atci->displayName = _( "vCard" );
3135 atci->iconXpm = vcardxpm;
3136 atci->maskXpm = vcardxpmmask;
3137 atci->iconXpmOpen = vcardxpm;
3138 atci->maskXpmOpen = vcardxpmmask;
3139 atci->menuCommand = "/File/New vCard";
3140 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3141 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3144 atci = g_new0( AddressTypeControlItem, 1 );
3145 atci->objectType = ADDR_JPILOT;
3146 atci->interfaceType = ADDR_IF_JPILOT;
3147 atci->showInTree = TRUE;
3148 atci->treeExpand = TRUE;
3149 atci->treeLeaf = FALSE;
3150 atci->displayName = _( "J-Pilot" );
3151 atci->iconXpm = jpilotxpm;
3152 atci->maskXpm = jpilotxpmmask;
3153 atci->iconXpmOpen = jpilotxpm;
3154 atci->maskXpmOpen = jpilotxpmmask;
3155 atci->menuCommand = "/File/New J-Pilot";
3156 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3157 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3160 atci = g_new0( AddressTypeControlItem, 1 );
3161 atci->objectType = ADDR_CATEGORY;
3162 atci->interfaceType = ADDR_IF_JPILOT;
3163 atci->showInTree = TRUE;
3164 atci->treeExpand = TRUE;
3165 atci->treeLeaf = TRUE;
3166 atci->displayName = _( "J-Pilot" );
3167 atci->iconXpm = categoryxpm;
3168 atci->maskXpm = categoryxpmmask;
3169 atci->iconXpmOpen = categoryxpm;
3170 atci->maskXpmOpen = categoryxpmmask;
3171 atci->menuCommand = NULL;
3172 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3173 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3176 atci = g_new0( AddressTypeControlItem, 1 );
3177 atci->objectType = ADDR_LDAP;
3178 atci->interfaceType = ADDR_IF_LDAP;
3179 atci->showInTree = TRUE;
3180 atci->treeExpand = TRUE;
3181 atci->treeLeaf = TRUE;
3182 atci->displayName = _( "LDAP Server" );
3183 atci->iconXpm = ldapxpm;
3184 atci->maskXpm = ldapxpmmask;
3185 atci->iconXpmOpen = ldapxpm;
3186 atci->maskXpmOpen = ldapxpmmask;
3187 atci->menuCommand = "/File/New Server";
3188 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
3189 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
3194 * Search for specified object type.
3196 AddressTypeControlItem *addrbookctl_lookup( gint ot ) {
3198 return ( AddressTypeControlItem * ) g_hash_table_lookup( _addressBookTypeHash_, &objType );
3202 * Search for specified interface type.
3204 AddressTypeControlItem *addrbookctl_lookup_iface( AddressIfType ifType ) {
3205 GList *node = _addressBookTypeList_;
3207 AddressTypeControlItem *atci = node->data;
3208 if( atci->interfaceType == ifType ) return atci;
3209 node = g_list_next( node );
3214 static void addrbookctl_free_address( AddressObject *obj ) {
3215 g_free( obj->name );
3216 obj->type = ADDR_NONE;
3220 static void addrbookctl_free_interface( AdapterInterface *adapter ) {
3221 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3222 adapter->interface = NULL;
3223 adapter->interfaceType = ADDR_IF_NONE;
3224 adapter->atci = NULL;
3225 adapter->enabled = FALSE;
3226 adapter->haveLibrary = FALSE;
3227 adapter->treeNode = NULL;
3231 static void addrbookctl_free_datasource( AdapterDSource *adapter ) {
3232 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3233 adapter->dataSource = NULL;
3234 adapter->subType = ADDR_NONE;
3238 static void addrbookctl_free_folder( AdapterFolder *adapter ) {
3239 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3240 adapter->itemFolder = NULL;
3244 static void addrbookctl_free_group( AdapterGroup *adapter ) {
3245 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
3246 adapter->itemGroup = NULL;
3251 * Build GUI interface list.
3253 void addrbookctl_build_iflist() {
3254 AddressTypeControlItem *atci;
3255 AdapterInterface *adapter;
3258 if( _addressIndex_ == NULL ) {
3259 _addressIndex_ = addrindex_create_index();
3261 _addressInterfaceList_ = NULL;
3262 list = addrindex_get_interface_list( _addressIndex_ );
3264 AddressInterface *interface = list->data;
3265 atci = addrbookctl_lookup_iface( interface->type );
3267 adapter = g_new0( AdapterInterface, 1 );
3268 adapter->interfaceType = interface->type;
3269 adapter->atci = atci;
3270 adapter->interface = interface;
3271 adapter->treeNode = NULL;
3272 adapter->enabled = TRUE;
3273 adapter->haveLibrary = interface->haveLibrary;
3274 ADDRESS_OBJECT(adapter)->type = ADDR_INTERFACE;
3275 ADDRESS_OBJECT_NAME(adapter) = g_strdup( atci->displayName );
3276 _addressInterfaceList_ = g_list_append( _addressInterfaceList_, adapter );
3278 list = g_list_next( list );
3282 void addrbookctl_free_selection( GList *list ) {
3285 AdapterInterface *adapter = node->data;
3287 node = g_list_next( node );
3289 g_list_free( list );
3293 * Find GUI interface type specified interface type.
3294 * Return: Interface item, or NULL if not found.
3296 AdapterInterface *addrbookctl_find_interface( AddressIfType ifType ) {
3297 GList *node = _addressInterfaceList_;
3299 AdapterInterface *adapter = node->data;
3300 if( adapter->interfaceType == ifType ) return adapter;
3301 node = g_list_next( node );
3307 * Build interface list selection.
3309 void addrbookctl_build_ifselect() {
3310 GList *newList = NULL;
3315 gchar *endptr = NULL;
3317 AdapterInterface *adapter;
3320 selectStr = g_strdup( ADDRESSBOOK_IFACE_SELECTION );
3323 splitStr = g_strsplit( selectStr, ",", -1 );
3324 for( i = 0; i < ADDRESSBOOK_MAX_IFACE; i++ ) {
3326 /* printf( "%d : %s\n", i, splitStr[i] ); */
3327 ifType = strtol( splitStr[i], &endptr, 10 );
3330 if( strcmp( endptr, "/n" ) == 0 ) {
3334 /* printf( "\t%d : %s\n", ifType, enabled ? "yes" : "no" ); */
3335 adapter = addrbookctl_find_interface( ifType );
3337 newList = g_list_append( newList, adapter );
3344 /* printf( "i=%d\n", i ); */
3345 g_strfreev( splitStr );
3346 g_free( selectStr );
3348 /* Replace existing list */
3349 mgu_clear_list( _addressIFaceSelection_ );
3350 g_list_free( _addressIFaceSelection_ );
3351 _addressIFaceSelection_ = newList;
3356 /* **********************************************************************
3357 * Add sender to address book.
3358 * ***********************************************************************
3362 * This function is used by the Add sender to address book function.
3364 gboolean addressbook_add_contact( const gchar *name, const gchar *address, const gchar *remarks ) {
3365 debug_print( "addressbook_add_contact: name/address: %s - %s\n", name, address );
3366 if( addressadd_selection( _addressIndex_, name, address, remarks ) ) {
3367 debug_print( "addressbook_add_contact - added\n" );
3368 addressbook_refresh();
3373 /* **********************************************************************
3374 * Address completion support.
3375 * ***********************************************************************
3379 * This function is used by the address completion function to load
3381 * Enter: callBackFunc Function to be called when an address is
3383 * Return: TRUE if data loaded, FALSE if address index not loaded.
3385 gboolean addressbook_load_completion( gint (*callBackFunc) ( const gchar *, const gchar * ) ) {
3386 /* AddressInterface *interface; */
3387 AddressDataSource *ds;
3388 GList *nodeIf, *nodeDS;
3389 GList *listP, *nodeP;
3391 gchar *sName, *sAddress, *sAlias, *sFriendly;
3393 debug_print( "addressbook_load_completion\n" );
3395 if( _addressIndex_ == NULL ) return FALSE;
3397 nodeIf = addrindex_get_interface_list( _addressIndex_ );
3399 AddressInterface *interface = nodeIf->data;
3400 nodeDS = interface->listSource;
3404 /* Read address book */
3405 if( ! addrindex_ds_get_read_flag( ds ) ) {
3406 addrindex_ds_read_data( ds );
3409 /* Get all persons */
3410 listP = addrindex_ds_get_all_persons( ds );
3413 ItemPerson *person = nodeP->data;
3414 nodeM = person->listEMail;
3416 /* Figure out name to use */
3417 sName = person->nickName;
3418 if( sName == NULL || *sName == '\0' ) {
3419 sName = ADDRITEM_NAME(person);
3422 /* Process each E-Mail address */
3424 ItemEMail *email = nodeM->data;
3427 sAddress = email->address;
3428 if( sAddress || *sAddress != '\0' ) {
3429 sAlias = ADDRITEM_NAME(email);
3430 if( sAlias && *sAlias != '\0' ) {
3433 ( callBackFunc ) ( sFriendly, sAddress );
3436 nodeM = g_list_next( nodeM );
3438 nodeP = g_list_next( nodeP );
3440 /* Free up the list */
3441 g_list_free( listP );
3443 nodeDS = g_list_next( nodeDS );
3445 nodeIf = g_list_next( nodeIf );
3447 debug_print( "addressbook_load_completion... done\n" );
3452 /* **********************************************************************
3454 * ***********************************************************************
3460 static void addressbook_import_ldif_cb() {
3461 AddressDataSource *ds = NULL;
3462 AdapterDSource *ads = NULL;
3463 AddressBookFile *abf = NULL;
3464 AdapterInterface *adapter;
3465 GtkCTreeNode *newNode;
3467 adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
3468 if ( !adapter || !adapter->treeNode ) return;
3470 abf = addressbook_imp_ldif( _addressIndex_ );
3473 ds = addrindex_index_add_datasource( _addressIndex_, ADDR_IF_BOOK, abf );
3474 ads = addressbook_create_ds_adapter( ds, ADDR_BOOK, NULL );
3475 addressbook_ads_set_name( ads, abf->name );
3476 newNode = addressbook_add_object( adapter->treeNode, ADDRESS_OBJECT(ads) );
3478 gtk_ctree_select( GTK_CTREE(addrbook.ctree), newNode );
3479 addrbook.treeSelected = newNode;
3482 /* Notify address completion */
3483 invalidate_address_completion();