1 /*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2017 Hiroyuki Yamamoto
4 *
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.
9 *
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.
14 *
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.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include "defs.h"
25
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <gtk/gtk.h>
30 #include <string.h>
31 #include <setjmp.h>
32
33 #include "main.h"
34 #include "addressbook.h"
35 #include "manage_window.h"
36 #include "prefs_common.h"
37 #include "alertpanel.h"
38 #include "inputdialog.h"
39 #include "menu.h"
40 #include "stock_pixmap.h"
41 #include "xml.h"
42 #include "prefs.h"
43 #include "procmime.h"
44 #include "utils.h"
45 #include "gtkutils.h"
46 #include "codeconv.h"
47 #include "about.h"
48 #include "addr_compl.h"
49
50 #include "mgutils.h"
51 #include "addressitem.h"
52 #include "addritem.h"
53 #include "addrcache.h"
54 #include "addrbook.h"
55 #include "addrindex.h"
56 #include "addressadd.h"
57 #include "vcard.h"
58 #include "editvcard.h"
59 #include "editgroup.h"
60 #include "editaddress.h"
61 #include "editbook.h"
62 #include "ldif.h"
63 #include "importldif.h"
64 #include "importcsv.h"
65 #include "exportcsv.h"
66
67 #ifdef USE_JPILOT
68 #include "jpilot.h"
69 #include "editjpilot.h"
70 #endif
71
72 #ifdef USE_LDAP
73 #include <pthread.h>
74 #include "syldap.h"
75 #include "editldap.h"
76
77 #define ADDRESSBOOK_LDAP_BUSYMSG "Busy"
78 #endif
79
80 typedef enum
81 {
82 COL_FOLDER_NAME,
83 COL_OBJ,
84 COL_PIXBUF,
85 COL_PIXBUF_OPEN,
86
87 N_TREE_COLS
88 } AddressBookTreeColumnPos;
89
90 typedef enum
91 {
92 COL_NAME,
93 COL_ADDRESS,
94 COL_NICKNAME,
95 COL_REMARKS,
96 COL_L_OBJ,
97 COL_L_PIXBUF,
98
99 N_LIST_COLS
100 } AddressBookListColumnPos;
101
102 enum
103 {
104 DRAG_TYPE_OBJ,
105
106 N_DRAG_TYPES
107 };
108
109 #define COL_NAME_WIDTH 164
110 #define COL_ADDRESS_WIDTH 156
111
112 #define COL_FOLDER_WIDTH 170
113
114 #define ADDRESSBOOK_MSGBUF_SIZE 2048
115
116 static GdkPixbuf *folderpix;
117 static GdkPixbuf *folderopenpix;
118 static GdkPixbuf *grouppix;
119 static GdkPixbuf *interfacepix;
120 static GdkPixbuf *bookpix;
121 static GdkPixbuf *personpix;
122 static GdkPixbuf *addresspix;
123 static GdkPixbuf *vcardpix;
124 static GdkPixbuf *jpilotpix;
125 static GdkPixbuf *categorypix;
126 static GdkPixbuf *ldappix;
127
128 /* Address list selection */
129 static GList *_addressListSelection_ = NULL;
130
131 static gboolean can_toggle_list_selection = TRUE;
132 static gboolean list_on_drag = FALSE;
133
134 /* Address index file and interfaces */
135 static AddressIndex *_addressIndex_ = NULL;
136 static GList *_addressInterfaceList_ = NULL;
137 static GList *_addressIFaceSelection_ = NULL;
138 #define ADDRESSBOOK_IFACE_SELECTION "1/y,3/y,4/y,2/n"
139
140 /* Address clipboard */
141 static GList *_clipObjectList_ = NULL;
142
143 static AddressBook_win addrbook;
144
145 static GHashTable *_addressBookTypeHash_ = NULL;
146 static GList *_addressBookTypeList_ = NULL;
147
148 static void addressbook_refresh (void);
149 static void addressbook_reopen (void);
150
151 static void addressbook_create (void);
152 static gint addressbook_close (void);
153
154 static void addressbook_menuitem_set_sensitive (void);
155
156 /* callback functions */
157 static void addressbook_del_clicked (GtkButton *button,
158 gpointer data);
159 static void addressbook_reg_clicked (GtkButton *button,
160 gpointer data);
161 static void addressbook_to_clicked (GtkButton *button,
162 gpointer data);
163 static void addressbook_lup_clicked (GtkButton *button,
164 gpointer data);
165 static void addressbook_close_clicked (GtkButton *button,
166 gpointer data);
167
168 static void addressbook_tree_selection_changed (GtkTreeSelection *selection,
169 gpointer data);
170 static void addressbook_list_selection_changed (GtkTreeSelection *selection,
171 gpointer data);
172 static void addressbook_person_expand_node (GtkTreeView *treeview,
173 GtkTreeIter *iter,
174 GtkTreePath *path,
175 gpointer *data);
176 static void addressbook_person_collapse_node (GtkTreeView *treeview,
177 GtkTreeIter *iter,
178 GtkTreePath *path,
179 gpointer *data);
180
181 static void addressbook_drag_begin (GtkWidget *widget,
182 GdkDragContext *drag_context,
183 gpointer data);
184 static void addressbook_drag_end (GtkWidget *widget,
185 GdkDragContext *drag_context,
186 gpointer data);
187 static void addressbook_drag_data_get (GtkWidget *widget,
188 GdkDragContext *drag_context,
189 GtkSelectionData *selection_data,
190 guint info,
191 guint time,
192 gpointer data);
193
194 #if 0
195 static void addressbook_entry_changed (GtkWidget *widget);
196 #endif
197 static void addressbook_entry_activated (GtkWidget *widget,
198 gpointer data);
199
200 static gboolean addressbook_list_button_pressed (GtkWidget *widget,
201 GdkEventButton *event,
202 gpointer data);
203 static gboolean addressbook_list_button_released(GtkWidget *widget,
204 GdkEventButton *event,
205 gpointer data);
206 static gboolean addressbook_tree_button_pressed (GtkWidget *ctree,
207 GdkEventButton *event,
208 gpointer data);
209 static gboolean addressbook_tree_button_released(GtkWidget *ctree,
210 GdkEventButton *event,
211 gpointer data);
212
213 static gboolean addressbook_drag_motion (GtkWidget *widget,
214 GdkDragContext *context,
215 gint x,
216 gint y,
217 guint time,
218 gpointer data);
219 static void addressbook_drag_leave (GtkWidget *widget,
220 GdkDragContext *context,
221 guint time,
222 gpointer data);
223 static void addressbook_drag_received (GtkWidget *widget,
224 GdkDragContext *context,
225 gint x,
226 gint y,
227 GtkSelectionData *data,
228 guint info,
229 guint time,
230 gpointer user_data);
231
232 static void addressbook_folder_resized (GtkWidget *widget,
233 GtkAllocation *allocation,
234 gpointer data);
235 static void addressbook_col_resized (GtkWidget *widget,
236 GtkAllocation *allocation,
237 gpointer data);
238
239 static void addressbook_popup_close (GtkMenuShell *menu_shell,
240 gpointer data);
241
242 static void addressbook_new_folder_cb (gpointer data,
243 guint action,
244 GtkWidget *widget);
245 static void addressbook_new_group_cb (gpointer data,
246 guint action,
247 GtkWidget *widget);
248 static void addressbook_treenode_edit_cb (gpointer data,
249 guint action,
250 GtkWidget *widget);
251 static void addressbook_treenode_delete_cb (gpointer data,
252 guint action,
253 GtkWidget *widget);
254
255 static void addressbook_change_node_name (GtkTreeIter *iter,
256 const gchar *name);
257
258 static void addressbook_new_address_cb (gpointer data,
259 guint action,
260 GtkWidget *widget);
261 static void addressbook_compose_to_cb (gpointer data,
262 guint action,
263 GtkWidget *widget);
264 static void addressbook_edit_address_cb (gpointer data,
265 guint action,
266 GtkWidget *widget);
267 static void addressbook_delete_address_cb (gpointer data,
268 guint action,
269 GtkWidget *widget);
270 static void addressbook_copy_address_cb (gpointer data,
271 guint action,
272 GtkWidget *widget);
273 static void addressbook_paste_address_cb (gpointer data,
274 guint action,
275 GtkWidget *widget);
276
277 static void close_cb (gpointer data,
278 guint action,
279 GtkWidget *widget);
280 static void addressbook_file_save_cb (gpointer data,
281 guint action,
282 GtkWidget *widget);
283
284 /* Data source edit stuff */
285 static void addressbook_new_book_cb (gpointer data,
286 guint action,
287 GtkWidget *widget);
288 static void addressbook_new_vcard_cb (gpointer data,
289 guint action,
290 GtkWidget *widget);
291
292 #ifdef USE_JPILOT
293 static void addressbook_new_jpilot_cb (gpointer data,
294 guint action,
295 GtkWidget *widget);
296 #endif
297
298 #ifdef USE_LDAP
299 static void addressbook_new_ldap_cb (gpointer data,
300 guint action,
301 GtkWidget *widget);
302 #endif
303
304 static void addressbook_set_list (AddressObject *obj);
305
306 static void addressbook_load_tree (void);
307 void addressbook_read_file (void);
308
309 static gboolean addressbook_add_object (GtkTreeIter *iter,
310 GtkTreeIter *new_iter,
311 AddressObject *obj);
312 static AddressDataSource *addressbook_find_datasource
313 (GtkTreeIter *iter);
314
315 static AddressBookFile *addressbook_get_book_file();
316
317 static gboolean addressbook_node_add_folder (GtkTreeIter *iter,
318 AddressDataSource *ds,
319 ItemFolder *itemFolder,
320 AddressObjectType otype,
321 GtkTreeIter *new_iter);
322 static gboolean addressbook_node_add_group (GtkTreeIter *iter,
323 AddressDataSource *ds,
324 ItemGroup *itemGroup,
325 GtkTreeIter *new_iter);
326 static void addressbook_tree_remove_children (GtkTreeModel *model,
327 GtkTreeIter *parent);
328 static void addressbook_move_nodes_up (GtkTreeIter *iter);
329 static gboolean addressbook_find_group_node (GtkTreeIter *parent,
330 GtkTreeIter *iter,
331 ItemGroup *group);
332
333 /* static void addressbook_delete_object (AddressObject *obj); */
334
335 static gboolean key_pressed (GtkWidget *widget,
336 GdkEventKey *event,
337 gpointer data);
338 static void size_allocated (GtkWidget *widget,
339 GtkAllocation *allocation,
340 gpointer data);
341
342 static gint addressbook_tree_compare (GtkTreeModel *model,
343 GtkTreeIter *a,
344 GtkTreeIter *b,
345 gpointer data);
346 static gint addressbook_list_name_compare (GtkTreeModel *model,
347 GtkTreeIter *a,
348 GtkTreeIter *b,
349 gpointer data);
350 static gint addressbook_list_address_compare (GtkTreeModel *model,
351 GtkTreeIter *a,
352 GtkTreeIter *b,
353 gpointer data);
354 static gint addressbook_list_nickname_compare (GtkTreeModel *model,
355 GtkTreeIter *a,
356 GtkTreeIter *b,
357 gpointer data);
358 static gint addressbook_list_remarks_compare (GtkTreeModel *model,
359 GtkTreeIter *a,
360 GtkTreeIter *b,
361 gpointer data);
362
363 static gboolean addressbook_list_select_func (GtkTreeSelection *selection,
364 GtkTreeModel *model,
365 GtkTreePath *path,
366 gboolean cur_selected,
367 gpointer data);
368
369 /* static void addressbook_book_show_message (AddressBookFile *book); */
370 /* static void addressbook_vcard_show_message (VCardFile *vcf); */
371 #ifdef USE_JPILOT
372 /* static void addressbook_jpilot_show_message (JPilotFile *jpf); */
373 #endif
374 #ifdef USE_LDAP
375 static void addressbook_ldap_show_message (SyldapServer *server);
376 #endif
377
378 /* LUT's and IF stuff */
379 static void addressbook_free_adapter (GtkTreeIter *iter);
380 static void addressbook_free_child_adapters (GtkTreeIter *iter);
381 AddressTypeControlItem *addrbookctl_lookup (gint ot);
382 AddressTypeControlItem *addrbookctl_lookup_iface(AddressIfType ifType);
383
384 void addrbookctl_build_map (GtkWidget *window);
385 void addrbookctl_build_iflist (void);
386 AdapterInterface *addrbookctl_find_interface (AddressIfType ifType);
387 void addrbookctl_build_ifselect (void);
388
389 static void addrbookctl_free_interface (AdapterInterface *adapter);
390 static void addrbookctl_free_datasource (AdapterDSource *adapter);
391 static void addrbookctl_free_folder (AdapterFolder *adapter);
392 static void addrbookctl_free_group (AdapterGroup *adapter);
393
394 static void addressbook_list_select_clear (void);
395 static void addressbook_list_select_remove (AddressObject *obj);
396 static void addressbook_list_select_set (GList *row_list);
397
398 static void addressbook_import_ldif_cb (void);
399 static void addressbook_import_csv_cb (void);
400
401 static void addressbook_export_csv_cb (void);
402
403 static void addressbook_modified (void);
404
405
406 static GtkTargetEntry addressbook_drag_types[] =
407 {
408 {"application/octet-stream", GTK_TARGET_SAME_APP, DRAG_TYPE_OBJ}
409 };
410
411 static GtkItemFactoryEntry addressbook_entries[] =
412 {
413 {N_("/_File"), NULL, NULL, 0, "<Branch>"},
414 {N_("/_File/New _Book"), NULL, addressbook_new_book_cb, 0, NULL},
415 {N_("/_File/New _vCard"), NULL, addressbook_new_vcard_cb, 0, NULL},
416 #ifdef USE_JPILOT
417 {N_("/_File/New _JPilot"), NULL, addressbook_new_jpilot_cb, 0, NULL},
418 #endif
419 #ifdef USE_LDAP
420 {N_("/_File/New _LDAP Server"), NULL, addressbook_new_ldap_cb, 0, NULL},
421 #endif
422 {N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
423 {N_("/_File/_Edit"), NULL, addressbook_treenode_edit_cb, 0, NULL},
424 {N_("/_File/_Delete"), NULL, addressbook_treenode_delete_cb, 0, NULL},
425 {N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
426 {N_("/_File/_Save"), "<control>S", addressbook_file_save_cb, 0, NULL},
427 {N_("/_File/_Close"), "<control>W", close_cb, 0, NULL},
428
429 {N_("/_Edit"), NULL, NULL, 0, "<Branch>"},
430 {N_("/_Edit/_Copy"), "<control>C", addressbook_copy_address_cb, 0, NULL},
431 {N_("/_Edit/_Paste"), "<control>V", addressbook_paste_address_cb, 0, NULL},
432
433 {N_("/_Address"), NULL, NULL, 0, "<Branch>"},
434 {N_("/_Address/New _Address"), "<control>N", addressbook_new_address_cb, 0, NULL},
435 {N_("/_Address/New _Group"), "<control>G", addressbook_new_group_cb, 0, NULL},
436 {N_("/_Address/New _Folder"), "<control>F", addressbook_new_folder_cb, 0, NULL},
437 {N_("/_Address/---"), NULL, NULL, 0, "<Separator>"},
438 {N_("/_Address/Add _to recipient"),
439 "<control>M", addressbook_compose_to_cb, COMPOSE_ENTRY_TO, NULL},
440 {N_("/_Address/Add to _Cc"),
441 NULL, addressbook_compose_to_cb, COMPOSE_ENTRY_CC, NULL},
442 {N_("/_Address/Add to _Bcc"),
443 NULL, addressbook_compose_to_cb, COMPOSE_ENTRY_BCC, NULL},
444 {N_("/_Address/---"), NULL, NULL, 0, "<Separator>"},
445 {N_("/_Address/_Edit"), "<control>Return", addressbook_edit_address_cb, 0, NULL},
446 {N_("/_Address/_Delete"), "Delete", addressbook_delete_address_cb, 0, NULL},
447
448 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
449 {N_("/_Tools/Import _LDIF file"), NULL, addressbook_import_ldif_cb, 0, NULL},
450 {N_("/_Tools/Import _CSV file"), NULL, addressbook_import_csv_cb, 0, NULL},
451 {N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
452 {N_("/_Tools/Export to C_SV file"), NULL, addressbook_export_csv_cb, 0, NULL},
453 {N_("/_Help"), NULL, NULL, 0, "<Branch>"},
454 {N_("/_Help/_About"), NULL, about_show, 0, NULL}
455 };
456
457 /* New options to be added. */
458 /*
459 {N_("/_Edit"), NULL, NULL, 0, "<Branch>"},
460 {N_("/_Edit/C_ut"), "<control>X", NULL, 0, NULL},
461 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
462 {N_("/_Tools/Import _Mozilla"), NULL, NULL, 0, NULL},
463 {N_("/_Tools/Import _vCard"), NULL, NULL, 0, NULL},
464 {N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
465 {N_("/_Tools/Export _LDIF file"), NULL, NULL, 0, NULL},
466 {N_("/_Tools/Export v_Card"), NULL, NULL, 0, NULL},
467 */
468
469 static GtkItemFactoryEntry addressbook_tree_popup_entries[] =
470 {
471 {N_("/New _Address"), NULL, addressbook_new_address_cb, 0, NULL},
472 {N_("/New _Group"), NULL, addressbook_new_group_cb, 0, NULL},
473 {N_("/New _Folder"), NULL, addressbook_new_folder_cb, 0, NULL},
474 {N_("/---"), NULL, NULL, 0, "<Separator>"},
475 {N_("/_Edit"), NULL, addressbook_treenode_edit_cb, 0, NULL},
476 {N_("/_Delete"), NULL, addressbook_treenode_delete_cb, 0, NULL}
477 };
478
479 static GtkItemFactoryEntry addressbook_list_popup_entries[] =
480 {
481 {N_("/New _Address"), NULL, addressbook_new_address_cb, 0, NULL},
482 {N_("/New _Group"), NULL, addressbook_new_group_cb, 0, NULL},
483 {N_("/New _Folder"), NULL, addressbook_new_folder_cb, 0, NULL},
484 {N_("/---"), NULL, NULL, 0, "<Separator>"},
485 {N_("/Add _to recipient"),
486 NULL, addressbook_compose_to_cb, COMPOSE_ENTRY_TO, NULL},
487 {N_("/Add t_o Cc"),
488 NULL, addressbook_compose_to_cb, COMPOSE_ENTRY_CC, NULL},
489 {N_("/Add to _Bcc"),
490 NULL, addressbook_compose_to_cb, COMPOSE_ENTRY_BCC, NULL},
491 {N_("/---"), NULL, NULL, 0, "<Separator>"},
492 {N_("/_Edit"), NULL, addressbook_edit_address_cb, 0, NULL},
493 {N_("/_Delete"), NULL, addressbook_delete_address_cb, 0, NULL},
494 {N_("/---"), NULL, NULL, 0, "<Separator>"},
495 {N_("/_Copy"), NULL, addressbook_copy_address_cb, 0, NULL},
496 {N_("/_Paste"), NULL, addressbook_paste_address_cb, 0, NULL}
497 };
498
499
addressbook_open(Compose * target)500 void addressbook_open(Compose *target)
501 {
502 if (!addrbook.window) {
503 GtkTreeView *treeview;
504 GtkTreeModel *model;
505 GtkTreeIter iter;
506 GtkTreePath *path;
507
508 addressbook_read_file();
509 addressbook_create();
510 addressbook_load_tree();
511 treeview = GTK_TREE_VIEW(addrbook.treeview);
512 model = gtk_tree_view_get_model(treeview);
513 if (gtk_tree_model_get_iter_first(model, &iter)) {
514 path = gtk_tree_model_get_path(model, &iter);
515 gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
516 gtk_tree_path_free(path);
517 }
518 addressbook_menuitem_set_sensitive();
519 gtk_widget_show(addrbook.window);
520 }
521
522 gtk_window_present(GTK_WINDOW(addrbook.window));
523
524 addressbook_set_target_compose(target);
525 }
526
addressbook_set_target_compose(Compose * target)527 void addressbook_set_target_compose(Compose *target)
528 {
529 addrbook.target_compose = target;
530 }
531
addressbook_get_target_compose(void)532 Compose *addressbook_get_target_compose(void)
533 {
534 return addrbook.target_compose;
535 }
536
addressbook_refresh(void)537 static void addressbook_refresh(void)
538 {
539 if (addrbook.window) {
540 if (addrbook.tree_opened) {
541 addressbook_reopen();
542 }
543 }
544 addressbook_export_to_file();
545 }
546
addressbook_reopen(void)547 static void addressbook_reopen(void)
548 {
549 GtkTreePath *path;
550
551 if (addrbook.tree_selected) {
552 gtk_tree_row_reference_free(addrbook.tree_selected);
553 addrbook.tree_selected = NULL;
554 }
555 if (addrbook.tree_opened) {
556 path = gtk_tree_row_reference_get_path(addrbook.tree_opened);
557 gtk_tree_view_set_cursor(GTK_TREE_VIEW(addrbook.treeview), path, NULL, FALSE);
558 gtk_tree_path_free(path);
559 }
560 }
561
562 /*
563 * Create the address book widgets. The address book contains two CTree widgets: the
564 * address index tree on the left and the address list on the right.
565 *
566 * The address index tree displays a hierarchy of interfaces and groups. Each node in
567 * this tree is linked to an address Adapter. Adapters have been created for interfaces,
568 * data sources and folder objects.
569 *
570 * The address list displays group, person and email objects. These items are linked
571 * directly to ItemGroup, ItemPerson and ItemEMail objects inside the address book data
572 * sources.
573 *
574 * In the tradition of MVC architecture, the data stores have been separated from the
575 * GUI components. The addrindex.c file provides the interface to all data stores.
576 */
addressbook_create(void)577 static void addressbook_create(void)
578 {
579 GtkWidget *window;
580 GtkWidget *vbox;
581 GtkWidget *menubar;
582 GtkWidget *spc_hbox;
583 GtkWidget *vbox2;
584 GtkWidget *tree_swin;
585 GtkWidget *treeview;
586 GtkTreeStore *tree_store;
587 GtkTreeSelection *selection;
588 GtkTreeViewColumn *column;
589 GtkCellRenderer *renderer;
590 GtkWidget *list_vbox;
591 GtkWidget *list_swin;
592 GtkWidget *listview;
593 GtkTreeStore *list_store;
594 GtkWidget *paned;
595 GtkWidget *hbox;
596 GtkWidget *label;
597 GtkWidget *entry;
598 GtkWidget *statusbar;
599 GtkWidget *hbbox;
600 GtkWidget *hbbox1;
601 GtkWidget *hbbox2;
602 GtkWidget *hsbox;
603 GtkWidget *to_btn;
604 GtkWidget *cc_btn;
605 GtkWidget *bcc_btn;
606 GtkWidget *del_btn;
607 GtkWidget *reg_btn;
608 GtkWidget *lup_btn;
609 GtkWidget *close_btn;
610 GtkWidget *tree_popup;
611 GtkWidget *list_popup;
612 GtkItemFactory *tree_factory;
613 GtkItemFactory *list_factory;
614 GtkItemFactory *menu_factory;
615 gint n_entries;
616 GList *nodeIf;
617
618 debug_print("Creating addressbook window...\n");
619
620 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
621 gtk_window_set_title(GTK_WINDOW(window), _("Address book"));
622 gtk_window_set_wmclass(GTK_WINDOW(window), "addressbook", "Sylpheed");
623 gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, TRUE);
624 gtk_widget_set_size_request(window, 620 * gtkut_get_dpi_multiplier(), 360 * gtkut_get_dpi_multiplier());
625 gtk_window_set_default_size(GTK_WINDOW(window),
626 prefs_common.addressbook_width,
627 prefs_common.addressbook_height);
628 gtkut_window_move(GTK_WINDOW(window), prefs_common.addressbook_x,
629 prefs_common.addressbook_y);
630 gtk_widget_realize(window);
631
632 g_signal_connect(G_OBJECT(window), "delete_event",
633 G_CALLBACK(addressbook_close), NULL);
634 g_signal_connect(G_OBJECT(window), "key_press_event",
635 G_CALLBACK(key_pressed), NULL);
636 g_signal_connect(G_OBJECT(window), "size_allocate",
637 G_CALLBACK(size_allocated), NULL);
638 MANAGE_WINDOW_SIGNALS_CONNECT(window);
639
640 vbox = gtk_vbox_new(FALSE, 0);
641 gtk_container_add(GTK_CONTAINER(window), vbox);
642
643 n_entries = sizeof(addressbook_entries) /
644 sizeof(addressbook_entries[0]);
645 menubar = menubar_create(window, addressbook_entries, n_entries,
646 "<AddressBook>", NULL);
647 gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
648 menu_factory = gtk_item_factory_from_widget(menubar);
649
650 spc_hbox = gtk_hbox_new(FALSE, 0);
651 gtk_widget_set_size_request(spc_hbox, -1, BORDER_WIDTH);
652 gtk_box_pack_start(GTK_BOX(vbox), spc_hbox, FALSE, FALSE, 0);
653
654 vbox2 = gtk_vbox_new(FALSE, 4);
655 gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);
656
657 tree_swin = gtk_scrolled_window_new(NULL, NULL);
658 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tree_swin),
659 GTK_POLICY_AUTOMATIC,
660 GTK_POLICY_AUTOMATIC);
661 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tree_swin),
662 GTK_SHADOW_IN);
663 gtk_widget_set_size_request(tree_swin, prefs_common.addressbook_folder_width, -1);
664
665 /* Address index */
666 tree_store = gtk_tree_store_new(N_TREE_COLS, G_TYPE_STRING,
667 G_TYPE_POINTER, GDK_TYPE_PIXBUF,
668 GDK_TYPE_PIXBUF);
669 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tree_store),
670 COL_FOLDER_NAME,
671 addressbook_tree_compare,
672 NULL, NULL);
673
674 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_store));
675 g_object_unref(G_OBJECT(tree_store));
676 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
677 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
678 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
679 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), FALSE);
680 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview),
681 COL_FOLDER_NAME);
682 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), FALSE);
683
684 gtk_container_add(GTK_CONTAINER(tree_swin), treeview);
685
686 column = gtk_tree_view_column_new();
687 gtk_tree_view_column_set_spacing(column, 1);
688 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
689 gtk_tree_view_column_set_resizable(column, TRUE);
690
691 renderer = gtk_cell_renderer_pixbuf_new();
692 g_object_set(renderer, "ypad", 0, NULL);
693 gtk_tree_view_column_pack_start(column, renderer, FALSE);
694 gtk_tree_view_column_set_title(column, _("Folder"));
695 gtk_tree_view_column_set_attributes
696 (column, renderer, "pixbuf", COL_PIXBUF,
697 "pixbuf-expander-open", COL_PIXBUF_OPEN,
698 "pixbuf-expander-closed", COL_PIXBUF, NULL);
699
700 renderer = gtk_cell_renderer_text_new();
701 g_object_set(renderer,
702 #if GTK_CHECK_VERSION(2, 6, 0)
703 "ellipsize", PANGO_ELLIPSIZE_END,
704 #endif
705 "ypad", 0, NULL);
706 gtk_tree_view_column_pack_start(column, renderer, TRUE);
707 gtk_tree_view_column_set_attributes(column, renderer,
708 "text", COL_FOLDER_NAME, NULL);
709
710 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
711 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);
712
713 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tree_store),
714 COL_FOLDER_NAME,
715 GTK_SORT_ASCENDING);
716
717 g_signal_connect(G_OBJECT(tree_swin), "size-allocate",
718 G_CALLBACK(addressbook_folder_resized), NULL);
719
720 g_signal_connect(G_OBJECT(selection), "changed",
721 G_CALLBACK(addressbook_tree_selection_changed), NULL);
722 g_signal_connect(G_OBJECT(treeview), "button_press_event",
723 G_CALLBACK(addressbook_tree_button_pressed),
724 NULL);
725 g_signal_connect(G_OBJECT(treeview), "button_release_event",
726 G_CALLBACK(addressbook_tree_button_released),
727 NULL);
728
729 gtk_drag_dest_set(treeview, GTK_DEST_DEFAULT_ALL,
730 addressbook_drag_types, N_DRAG_TYPES,
731 GDK_ACTION_MOVE | GDK_ACTION_COPY);
732 g_signal_connect(G_OBJECT(treeview), "drag-motion",
733 G_CALLBACK(addressbook_drag_motion), NULL);
734 g_signal_connect(G_OBJECT(treeview), "drag-leave",
735 G_CALLBACK(addressbook_drag_leave), NULL);
736 g_signal_connect(G_OBJECT(treeview), "drag-data-received",
737 G_CALLBACK(addressbook_drag_received), NULL);
738
739 list_vbox = gtk_vbox_new(FALSE, 4);
740
741 list_swin = gtk_scrolled_window_new(NULL, NULL);
742 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(list_swin),
743 GTK_POLICY_AUTOMATIC,
744 GTK_POLICY_AUTOMATIC);
745 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(list_swin),
746 GTK_SHADOW_IN);
747 gtk_box_pack_start(GTK_BOX(list_vbox), list_swin, TRUE, TRUE, 0);
748
749 /* Address list */
750 list_store = gtk_tree_store_new(N_LIST_COLS, G_TYPE_STRING,
751 G_TYPE_STRING, G_TYPE_STRING,
752 G_TYPE_STRING, G_TYPE_POINTER,
753 GDK_TYPE_PIXBUF);
754 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list_store),
755 COL_NAME,
756 addressbook_list_name_compare,
757 NULL, NULL);
758 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list_store),
759 COL_ADDRESS,
760 addressbook_list_address_compare,
761 NULL, NULL);
762 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list_store),
763 COL_NICKNAME,
764 addressbook_list_nickname_compare,
765 NULL, NULL);
766 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list_store),
767 COL_REMARKS,
768 addressbook_list_remarks_compare,
769 NULL, NULL);
770
771 listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
772 g_object_unref(G_OBJECT(list_store));
773 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(listview));
774 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
775 gtk_tree_selection_set_select_function
776 (selection, addressbook_list_select_func, NULL, NULL);
777 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(listview), TRUE);
778 gtk_tree_view_set_search_column(GTK_TREE_VIEW(listview), COL_NAME);
779 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(listview), FALSE);
780 gtk_container_add(GTK_CONTAINER(list_swin), listview);
781
782 column = gtk_tree_view_column_new();
783 gtk_tree_view_column_set_spacing(column, 1);
784 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
785 gtk_tree_view_column_set_fixed_width
786 (column, prefs_common.addressbook_col_name);
787 gtk_tree_view_column_set_resizable(column, TRUE);
788 gtk_tree_view_column_set_title(column, _("Name"));
789 #if GTK_CHECK_VERSION(2, 14, 0)
790 /* gtk_tree_view_column_set_expand(column, TRUE); */
791 #endif
792
793 renderer = gtk_cell_renderer_pixbuf_new();
794 g_object_set(renderer, "ypad", 0, NULL);
795 gtk_tree_view_column_pack_start(column, renderer, FALSE);
796 gtk_tree_view_column_set_attributes(column, renderer,
797 "pixbuf", COL_L_PIXBUF, NULL);
798
799 renderer = gtk_cell_renderer_text_new();
800 g_object_set(renderer,
801 #if GTK_CHECK_VERSION(2, 6, 0)
802 "ellipsize", PANGO_ELLIPSIZE_END,
803 #endif
804 "ypad", 0, NULL);
805 gtk_tree_view_column_pack_start(column, renderer, TRUE);
806 gtk_tree_view_column_set_attributes(column, renderer,
807 "text", COL_NAME, NULL);
808
809 gtk_tree_view_column_set_sort_column_id(column, COL_NAME);
810 gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
811 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(listview), column);
812 g_signal_connect(G_OBJECT(column->button), "size-allocate",
813 G_CALLBACK(addressbook_col_resized),
814 GINT_TO_POINTER(COL_NAME));
815
816 renderer = gtk_cell_renderer_text_new();
817 g_object_set(renderer,
818 #if GTK_CHECK_VERSION(2, 6, 0)
819 "ellipsize", PANGO_ELLIPSIZE_END,
820 #endif
821 "ypad", 0, NULL);
822 column = gtk_tree_view_column_new_with_attributes
823 (_("E-Mail address"), renderer, "text", COL_ADDRESS, NULL);
824 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
825 gtk_tree_view_column_set_fixed_width
826 (column, prefs_common.addressbook_col_addr);
827 gtk_tree_view_column_set_resizable(column, TRUE);
828 #if GTK_CHECK_VERSION(2, 14, 0)
829 /* gtk_tree_view_column_set_expand(column, TRUE); */
830 #endif
831 gtk_tree_view_column_set_sort_column_id(column, COL_ADDRESS);
832 gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
833 g_signal_connect(G_OBJECT(column->button), "size-allocate",
834 G_CALLBACK(addressbook_col_resized),
835 GINT_TO_POINTER(COL_ADDRESS));
836
837 renderer = gtk_cell_renderer_text_new();
838 g_object_set(renderer,
839 #if GTK_CHECK_VERSION(2, 6, 0)
840 "ellipsize", PANGO_ELLIPSIZE_END,
841 #endif
842 "ypad", 0, NULL);
843 column = gtk_tree_view_column_new_with_attributes
844 (_("Nick Name"), renderer, "text", COL_NICKNAME, NULL);
845 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
846 gtk_tree_view_column_set_fixed_width
847 (column, prefs_common.addressbook_col_nickname);
848 gtk_tree_view_column_set_resizable(column, TRUE);
849 #if GTK_CHECK_VERSION(2, 14, 0)
850 /* gtk_tree_view_column_set_expand(column, TRUE); */
851 #endif
852 gtk_tree_view_column_set_sort_column_id(column, COL_NICKNAME);
853 gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
854 g_signal_connect(G_OBJECT(column->button), "size-allocate",
855 G_CALLBACK(addressbook_col_resized),
856 GINT_TO_POINTER(COL_NICKNAME));
857
858 renderer = gtk_cell_renderer_text_new();
859 g_object_set(renderer,
860 #if GTK_CHECK_VERSION(2, 6, 0)
861 "ellipsize", PANGO_ELLIPSIZE_END,
862 #endif
863 "ypad", 0, NULL);
864 column = gtk_tree_view_column_new_with_attributes
865 (_("Remarks"), renderer, "text", COL_REMARKS, NULL);
866 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
867 gtk_tree_view_column_set_resizable(column, TRUE);
868 #if GTK_CHECK_VERSION(2, 14, 0)
869 /* gtk_tree_view_column_set_expand(column, TRUE); */
870 #endif
871 gtk_tree_view_column_set_sort_column_id(column, COL_REMARKS);
872 gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
873 g_signal_connect(G_OBJECT(column->button), "size-allocate",
874 G_CALLBACK(addressbook_col_resized),
875 GINT_TO_POINTER(COL_REMARKS));
876
877 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list_store),
878 COL_NAME, GTK_SORT_ASCENDING);
879
880 g_signal_connect(G_OBJECT(selection), "changed",
881 G_CALLBACK(addressbook_list_selection_changed), NULL);
882 g_signal_connect(G_OBJECT(listview), "button_press_event",
883 G_CALLBACK(addressbook_list_button_pressed),
884 NULL);
885 g_signal_connect(G_OBJECT(listview), "button_release_event",
886 G_CALLBACK(addressbook_list_button_released),
887 NULL);
888 g_signal_connect(G_OBJECT(listview), "row_expanded",
889 G_CALLBACK(addressbook_person_expand_node), NULL);
890 g_signal_connect(G_OBJECT(listview), "row_collapsed",
891 G_CALLBACK(addressbook_person_collapse_node), NULL);
892
893 gtk_tree_view_enable_model_drag_source
894 (GTK_TREE_VIEW(listview), GDK_BUTTON1_MASK,
895 addressbook_drag_types, N_DRAG_TYPES,
896 GDK_ACTION_MOVE | GDK_ACTION_COPY);
897
898 g_signal_connect_after(G_OBJECT(listview), "drag-begin",
899 G_CALLBACK(addressbook_drag_begin), NULL);
900 g_signal_connect_after(G_OBJECT(listview), "drag-end",
901 G_CALLBACK(addressbook_drag_end), NULL);
902 g_signal_connect(G_OBJECT(listview), "drag-data-get",
903 G_CALLBACK(addressbook_drag_data_get), NULL);
904
905 hbox = gtk_hbox_new(FALSE, 4);
906 gtk_box_pack_start(GTK_BOX(list_vbox), hbox, FALSE, FALSE, 0);
907
908 label = gtk_label_new(_("Search:"));
909 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
910
911 entry = gtk_entry_new();
912 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
913
914 address_completion_register_entry(GTK_ENTRY(entry));
915
916 #if 0
917 g_signal_connect(G_OBJECT(entry), "changed",
918 G_CALLBACK(addressbook_entry_changed), NULL);
919 #endif
920 g_signal_connect(G_OBJECT(entry), "activate",
921 G_CALLBACK(addressbook_entry_activated), NULL);
922
923 paned = gtk_hpaned_new();
924 gtk_box_pack_start(GTK_BOX(vbox2), paned, TRUE, TRUE, 0);
925 gtk_paned_add1(GTK_PANED(paned), tree_swin);
926 gtk_paned_add2(GTK_PANED(paned), list_vbox);
927
928 /* Status bar */
929 hsbox = gtk_hbox_new(FALSE, 0);
930 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, 0);
931 statusbar = gtk_statusbar_new();
932 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, 0);
933
934 hbbox = gtk_hbox_new(FALSE, 4);
935 gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
936
937 /* Button panel */
938 hbbox1 = gtk_hbutton_box_new();
939 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox1), GTK_BUTTONBOX_END);
940 gtk_box_set_spacing(GTK_BOX(hbbox1), 4);
941 gtk_container_set_border_width(GTK_CONTAINER(hbbox1), 4);
942 gtk_button_box_set_child_size(GTK_BUTTON_BOX(hbbox1), 64, -1);
943 gtk_box_pack_end(GTK_BOX(hbbox), hbbox1, FALSE, FALSE, 0);
944
945 to_btn = gtk_button_new_with_label
946 (prefs_common.trans_hdr ? _("To:") : "To:");
947 GTK_WIDGET_SET_FLAGS(to_btn, GTK_CAN_DEFAULT);
948 gtk_box_pack_start(GTK_BOX(hbbox1), to_btn, TRUE, TRUE, 0);
949 cc_btn = gtk_button_new_with_label
950 (prefs_common.trans_hdr ? _("Cc:") : "Cc:");
951 GTK_WIDGET_SET_FLAGS(cc_btn, GTK_CAN_DEFAULT);
952 gtk_box_pack_start(GTK_BOX(hbbox1), cc_btn, TRUE, TRUE, 0);
953 bcc_btn = gtk_button_new_with_label
954 (prefs_common.trans_hdr ? _("Bcc:") : "Bcc:");
955 GTK_WIDGET_SET_FLAGS(bcc_btn, GTK_CAN_DEFAULT);
956 gtk_box_pack_start(GTK_BOX(hbbox1), bcc_btn, TRUE, TRUE, 0);
957
958 g_signal_connect(G_OBJECT(to_btn), "clicked",
959 G_CALLBACK(addressbook_to_clicked),
960 GINT_TO_POINTER(COMPOSE_ENTRY_TO));
961 g_signal_connect(G_OBJECT(cc_btn), "clicked",
962 G_CALLBACK(addressbook_to_clicked),
963 GINT_TO_POINTER(COMPOSE_ENTRY_CC));
964 g_signal_connect(G_OBJECT(bcc_btn), "clicked",
965 G_CALLBACK(addressbook_to_clicked),
966 GINT_TO_POINTER(COMPOSE_ENTRY_BCC));
967
968 hbbox2 = gtk_hbutton_box_new();
969 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox2), GTK_BUTTONBOX_END);
970 gtk_box_set_spacing(GTK_BOX(hbbox2), 4);
971 gtk_container_set_border_width(GTK_CONTAINER(hbbox2), 4);
972 gtk_button_box_set_child_size(GTK_BUTTON_BOX(hbbox2), 64, -1);
973 gtk_box_pack_end(GTK_BOX(hbbox), hbbox2, TRUE, TRUE, 0);
974
975 del_btn = gtk_button_new_with_label(_("Delete"));
976 GTK_WIDGET_SET_FLAGS(del_btn, GTK_CAN_DEFAULT);
977 gtk_box_pack_start(GTK_BOX(hbbox2), del_btn, TRUE, TRUE, 0);
978 reg_btn = gtk_button_new_with_label(_("Add"));
979 GTK_WIDGET_SET_FLAGS(reg_btn, GTK_CAN_DEFAULT);
980 gtk_box_pack_start(GTK_BOX(hbbox2), reg_btn, TRUE, TRUE, 0);
981 lup_btn = gtk_button_new_with_label(_("Search"));
982 GTK_WIDGET_SET_FLAGS(lup_btn, GTK_CAN_DEFAULT);
983 gtk_box_pack_start(GTK_BOX(hbbox2), lup_btn, TRUE, TRUE, 0);
984 close_btn = gtk_button_new_with_mnemonic(_("_Close"));
985 GTK_WIDGET_SET_FLAGS(close_btn, GTK_CAN_DEFAULT);
986 gtk_box_pack_start(GTK_BOX(hbbox2), close_btn, TRUE, TRUE, 0);
987 gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(hbbox2), close_btn,
988 TRUE);
989
990 g_signal_connect(G_OBJECT(del_btn), "clicked",
991 G_CALLBACK(addressbook_del_clicked), NULL);
992 g_signal_connect(G_OBJECT(reg_btn), "clicked",
993 G_CALLBACK(addressbook_reg_clicked), NULL);
994 g_signal_connect(G_OBJECT(lup_btn), "clicked",
995 G_CALLBACK(addressbook_lup_clicked), NULL);
996 g_signal_connect(G_OBJECT(close_btn), "clicked",
997 G_CALLBACK(addressbook_close_clicked), NULL);
998
999 /* Build icons for interface */
1000 stock_pixbuf_gdk(window, STOCK_PIXMAP_INTERFACE, &interfacepix);
1001 /* Build control tables */
1002 addrbookctl_build_map(window);
1003 addrbookctl_build_iflist();
1004 addrbookctl_build_ifselect();
1005
1006 /* Add each interface into the tree as a root level folder */
1007 nodeIf = _addressInterfaceList_;
1008 while( nodeIf ) {
1009 AdapterInterface *adapter = nodeIf->data;
1010 AddressInterface *iface = adapter->iface;
1011
1012 nodeIf = g_list_next(nodeIf);
1013
1014 if(iface->useInterface) {
1015 AddressTypeControlItem *atci = adapter->atci;
1016 gchar *text = atci->displayName;
1017 GtkTreeIter iter;
1018 GtkTreePath *path;
1019
1020 debug_print("addressbook_create: adapter: %s\n", text);
1021 gtk_tree_store_append(tree_store, &iter, NULL);
1022 gtk_tree_store_set(tree_store, &iter,
1023 COL_FOLDER_NAME, text,
1024 COL_OBJ, adapter,
1025 COL_PIXBUF, interfacepix,
1026 COL_PIXBUF_OPEN, interfacepix, -1);
1027 path = gtk_tree_model_get_path(GTK_TREE_MODEL(tree_store), &iter);
1028 adapter->tree_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(tree_store), path);
1029 gtk_tree_path_free(path);
1030 }
1031 }
1032
1033 /* Popup menu */
1034 n_entries = sizeof(addressbook_tree_popup_entries) /
1035 sizeof(addressbook_tree_popup_entries[0]);
1036 tree_popup = menu_create_items(addressbook_tree_popup_entries,
1037 n_entries,
1038 "<AddressBookTree>", &tree_factory,
1039 NULL);
1040 g_signal_connect(G_OBJECT(tree_popup), "selection_done",
1041 G_CALLBACK(addressbook_popup_close), NULL);
1042 n_entries = sizeof(addressbook_list_popup_entries) /
1043 sizeof(addressbook_list_popup_entries[0]);
1044 list_popup = menu_create_items(addressbook_list_popup_entries,
1045 n_entries,
1046 "<AddressBookList>", &list_factory,
1047 NULL);
1048
1049 addrbook.window = window;
1050 addrbook.menubar = menubar;
1051 addrbook.treeview = treeview;
1052 addrbook.listview = listview;
1053 addrbook.entry = entry;
1054 addrbook.statusbar = statusbar;
1055 addrbook.status_cid = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "Address Book Window");
1056
1057 addrbook.to_btn = to_btn;
1058 addrbook.cc_btn = cc_btn;
1059 addrbook.bcc_btn = bcc_btn;
1060 addrbook.del_btn = del_btn;
1061 addrbook.reg_btn = reg_btn;
1062 addrbook.lup_btn = lup_btn;
1063 addrbook.close_btn = close_btn;
1064
1065 addrbook.tree_popup = tree_popup;
1066 addrbook.list_popup = list_popup;
1067 addrbook.tree_factory = tree_factory;
1068 addrbook.list_factory = list_factory;
1069 addrbook.menu_factory = menu_factory;
1070
1071 addrbook.tree_selected = NULL;
1072 addrbook.list_selected = NULL;
1073 address_completion_start(window);
1074 gtk_widget_show_all(window);
1075 }
1076
addressbook_close(void)1077 static gint addressbook_close(void)
1078 {
1079 gtkut_widget_get_uposition(addrbook.window,
1080 &prefs_common.addressbook_x,
1081 &prefs_common.addressbook_y);
1082 gtk_widget_hide(addrbook.window);
1083 addressbook_export_to_file();
1084 return TRUE;
1085 }
1086
addressbook_status_show(const gchar * msg)1087 static void addressbook_status_show(const gchar *msg)
1088 {
1089 if (addrbook.statusbar != NULL) {
1090 gtk_statusbar_pop(GTK_STATUSBAR(addrbook.statusbar), addrbook.status_cid);
1091 if (msg) {
1092 gtk_statusbar_push(GTK_STATUSBAR(addrbook.statusbar), addrbook.status_cid, msg);
1093 }
1094 }
1095 }
1096
addressbook_ds_show_message(AddressDataSource * ds)1097 static void addressbook_ds_show_message(AddressDataSource *ds)
1098 {
1099 gint retVal;
1100 gchar *name;
1101 gchar msgbuf[ADDRESSBOOK_MSGBUF_SIZE] = "";
1102
1103 if (ds) {
1104 name = addrindex_ds_get_name(ds);
1105 if (ds->type == ADDR_IF_BOOK && name &&
1106 !strcmp(name, ADDR_DS_AUTOREG))
1107 name = _("Auto-registered address");
1108 retVal = addrindex_ds_get_status_code(ds);
1109 if (retVal == MGU_SUCCESS) {
1110 g_snprintf(msgbuf, sizeof(msgbuf), "%s", name);
1111 } else {
1112 g_snprintf(msgbuf, sizeof(msgbuf), "%s: %s",
1113 name, mgu_error2string(retVal));
1114 }
1115 }
1116
1117 addressbook_status_show(msgbuf);
1118 }
1119
1120 /*
1121 * Delete one or more objects from address list.
1122 */
addressbook_del_clicked(GtkButton * button,gpointer data)1123 static void addressbook_del_clicked(GtkButton *button, gpointer data)
1124 {
1125 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
1126 GtkTreeSelection *selection;
1127 GtkTreeModel *model;
1128 GtkTreeIter iter;
1129 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
1130 GtkTreeModel *lmodel;
1131 GtkTreeIter list_sel;
1132 AddressObject *pobj = NULL;
1133 AddressObject *obj = NULL;
1134 AdapterDSource *ads = NULL;
1135 gboolean procFlag;
1136 AlertValue aval;
1137 AddressBookFile *abf = NULL;
1138 AddressDataSource *ds = NULL;
1139
1140 if (!addrbook.tree_opened)
1141 return;
1142
1143 model = gtk_tree_view_get_model(treeview);
1144 lmodel = gtk_tree_view_get_model(listview);
1145 selection = gtk_tree_view_get_selection(treeview);
1146
1147 gtkut_tree_row_reference_get_iter(model, addrbook.tree_opened, &iter);
1148 gtk_tree_model_get(model, &iter, COL_OBJ, &pobj, -1);
1149 g_return_if_fail(pobj != NULL);
1150
1151 gtkut_tree_row_reference_get_iter(lmodel, addrbook.list_selected,
1152 &list_sel);
1153 gtk_tree_model_get(lmodel, &list_sel, COL_L_OBJ, &obj, -1);
1154 if (obj == NULL)
1155 return;
1156 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
1157 return;
1158 ds = addressbook_find_datasource(&iter);
1159 if (ds == NULL)
1160 return;
1161
1162 procFlag = FALSE;
1163 if (pobj->type == ADDR_DATASOURCE) {
1164 ads = ADAPTER_DSOURCE(pobj);
1165 if(ads->subType == ADDR_BOOK)
1166 procFlag = TRUE;
1167 }
1168 else if (pobj->type == ADDR_ITEM_FOLDER) {
1169 procFlag = TRUE;
1170 } else if (pobj->type == ADDR_ITEM_GROUP) {
1171 procFlag = TRUE;
1172 }
1173 if (!procFlag)
1174 return;
1175 abf = ds->rawDataSource;
1176 if (abf == NULL)
1177 return;
1178
1179 /* Confirm deletion */
1180 aval = alertpanel(_("Delete address(es)"),
1181 _("Really delete the address(es)?"),
1182 GTK_STOCK_YES, GTK_STOCK_NO, NULL);
1183 if (aval != G_ALERTDEFAULT)
1184 return;
1185
1186 /* Process deletions */
1187 if (pobj->type == ADDR_DATASOURCE || pobj->type == ADDR_ITEM_FOLDER) {
1188 /* Items inside folders */
1189 GList *node;
1190
1191 node = _addressListSelection_;
1192 while (node) {
1193 AddrItemObject *aio = node->data;
1194 node = g_list_next(node);
1195 if (aio->type == ADDR_ITEM_GROUP) {
1196 ItemGroup *item = (ItemGroup *)aio;
1197 GtkTreeIter giter;
1198
1199 addressbook_find_group_node(&iter, &giter, item);
1200 item = addrbook_remove_group(abf, item);
1201 if (item) {
1202 addritem_free_item_group(item);
1203 item = NULL;
1204 }
1205 /* Remove group from parent node */
1206 gtk_tree_store_remove(GTK_TREE_STORE(model), &giter);
1207 } else if (aio->type == ADDR_ITEM_PERSON) {
1208 ItemPerson *item = (ItemPerson *)aio;
1209
1210 if (_clipObjectList_) {
1211 _clipObjectList_ = g_list_remove(_clipObjectList_, item);
1212 }
1213 item = addrbook_remove_person(abf, item);
1214 if (item) {
1215 addritem_free_item_person(item);
1216 item = NULL;
1217 }
1218 } else if (aio->type == ADDR_ITEM_EMAIL) {
1219 ItemEMail *item = (ItemEMail *)aio;
1220 ItemPerson *person = (ItemPerson *)ADDRITEM_PARENT(item);
1221
1222 item = addrbook_person_remove_email(abf, person, item);
1223 if (item) {
1224 addritem_free_item_email(item);
1225 item = NULL;
1226 }
1227 }
1228 }
1229 addressbook_list_select_clear();
1230 addressbook_reopen();
1231 addressbook_modified();
1232 return;
1233 } else if (pobj->type == ADDR_ITEM_GROUP) {
1234 /* Items inside groups */
1235 GList *node;
1236 ItemGroup *group = ADAPTER_GROUP(pobj)->itemGroup;
1237
1238 node = _addressListSelection_;
1239 while (node) {
1240 AddrItemObject *aio = node->data;
1241 node = g_list_next(node);
1242 if (aio->type == ADDR_ITEM_EMAIL) {
1243 ItemEMail *item = (ItemEMail *)aio;
1244 item = addrbook_group_remove_email(abf, group, item);
1245 }
1246 }
1247 addressbook_list_select_clear();
1248 addressbook_reopen();
1249 return;
1250 }
1251
1252 gtk_tree_store_remove(GTK_TREE_STORE(lmodel), &list_sel);
1253 addressbook_list_select_remove(obj);
1254 }
1255
addressbook_reg_clicked(GtkButton * button,gpointer data)1256 static void addressbook_reg_clicked(GtkButton *button, gpointer data)
1257 {
1258 addressbook_new_address_cb(NULL, 0, NULL);
1259 }
1260
addressbook_format_address(AddressObject * obj)1261 gchar *addressbook_format_address(AddressObject *obj)
1262 {
1263 gchar *buf = NULL;
1264 gchar *name = NULL;
1265 gchar *address = NULL;
1266
1267 if( obj->type == ADDR_ITEM_EMAIL ) {
1268 ItemPerson *person = NULL;
1269 ItemEMail *email = ( ItemEMail * ) obj;
1270
1271 person = ( ItemPerson * ) ADDRITEM_PARENT(email);
1272 if( email->address ) {
1273 if( ADDRITEM_NAME(email) ) {
1274 name = ADDRITEM_NAME(email);
1275 if( *name == '\0' ) {
1276 name = ADDRITEM_NAME(person);
1277 }
1278 }
1279 else if( person && ADDRITEM_NAME(person) ) {
1280 name = ADDRITEM_NAME(person);
1281 }
1282 else {
1283 buf = g_strdup( email->address );
1284 }
1285 address = email->address;
1286 }
1287 }
1288 else if( obj->type == ADDR_ITEM_PERSON ) {
1289 ItemPerson *person = ( ItemPerson * ) obj;
1290 GList *node = person->listEMail;
1291
1292 name = ADDRITEM_NAME(person);
1293 if( node ) {
1294 ItemEMail *email = ( ItemEMail * ) node->data;
1295 address = email->address;
1296 }
1297 }
1298 if( address ) {
1299 if( !prefs_common.always_add_address_only &&
1300 name && name[0] != '\0' ) {
1301 if( name[0] != '"' && strpbrk( name, ",.[]<>" ) != NULL )
1302 buf = g_strdup_printf( "\"%s\" <%s>", name, address );
1303 else
1304 buf = g_strdup_printf( "%s <%s>", name, address );
1305 }
1306 else {
1307 buf = g_strdup( address );
1308 }
1309 }
1310
1311 return buf;
1312 }
1313
addressbook_to_clicked(GtkButton * button,gpointer data)1314 static void addressbook_to_clicked(GtkButton *button, gpointer data)
1315 {
1316 GList *node = _addressListSelection_;
1317 gboolean new_compose = FALSE;
1318
1319 if (!addrbook.target_compose) {
1320 new_compose = TRUE;
1321 addrbook.target_compose = compose_new(NULL, NULL, NULL, NULL);
1322 if (!addrbook.target_compose)
1323 return;
1324 }
1325
1326 if (new_compose)
1327 compose_block_modified(addrbook.target_compose);
1328
1329 while( node ) {
1330 AddressObject *obj = node->data;
1331 Compose *compose = addrbook.target_compose;
1332
1333 node = g_list_next( node );
1334 if( obj->type == ADDR_ITEM_PERSON || obj->type == ADDR_ITEM_EMAIL ) {
1335 gchar *addr = addressbook_format_address( obj );
1336 compose_entry_append( compose, addr, (ComposeEntryType) data );
1337 g_free( addr );
1338 addr = NULL;
1339 }
1340 else if( obj->type == ADDR_ITEM_GROUP ) {
1341 ItemGroup *group = ( ItemGroup * ) obj;
1342 GList *nodeMail = group->listEMail;
1343 while( nodeMail ) {
1344 ItemEMail *email = nodeMail->data;
1345 gchar *addr = addressbook_format_address( ( AddressObject * ) email );
1346 compose_entry_append( compose, addr, (ComposeEntryType) data );
1347 g_free( addr );
1348 nodeMail = g_list_next( nodeMail );
1349 }
1350 }
1351 }
1352
1353 if (new_compose)
1354 compose_unblock_modified(addrbook.target_compose);
1355 }
1356
addressbook_menuitem_set_sensitive(void)1357 static void addressbook_menuitem_set_sensitive(void)
1358 {
1359 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
1360 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
1361 GtkTreeSelection *selection;
1362 GtkTreeSelection *lselection;
1363 GtkTreeModel *model;
1364 GtkTreeModel *lmodel;
1365 GtkTreeIter iter;
1366 GtkTreeIter liter;
1367 gboolean canAdd = FALSE;
1368 gboolean canEditTree = TRUE;
1369 gboolean canEditAddress = FALSE;
1370 gboolean canDelete = FALSE;
1371 gboolean canLookup = FALSE;
1372 gboolean canCopy = FALSE;
1373 gboolean canPaste = FALSE;
1374 gboolean hasListSelection = _addressListSelection_ != NULL;
1375 AddressTypeControlItem *atci = NULL;
1376 AddressDataSource *ds = NULL;
1377 AddressInterface *iface = NULL;
1378 AddressObject *pobj = NULL;
1379 AddressObject *obj = NULL;
1380
1381 menu_set_sensitive(addrbook.menu_factory, "/File/New Book", FALSE);
1382 menu_set_sensitive(addrbook.menu_factory, "/File/New vCard", FALSE);
1383 #ifdef USE_JPILOT
1384 menu_set_sensitive(addrbook.menu_factory, "/File/New JPilot", FALSE);
1385 #endif
1386 #ifdef USE_LDAP
1387 menu_set_sensitive(addrbook.menu_factory, "/File/New LDAP Server", FALSE);
1388 #endif
1389 menu_set_insensitive_all(GTK_MENU_SHELL(addrbook.tree_popup));
1390 menu_set_insensitive_all(GTK_MENU_SHELL(addrbook.list_popup));
1391
1392 selection = gtk_tree_view_get_selection(treeview);
1393 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1394 return;
1395
1396 gtk_tree_model_get(model, &iter, COL_OBJ, &pobj, -1);
1397 if (pobj == NULL)
1398 return;
1399
1400 lmodel = gtk_tree_view_get_model(listview);
1401 lselection = gtk_tree_view_get_selection(listview);
1402
1403 if (addrbook.list_selected) {
1404 if (gtkut_tree_row_reference_get_iter(lmodel, addrbook.list_selected, &liter))
1405 gtk_tree_model_get(lmodel, &liter, COL_L_OBJ, &obj, -1);
1406 }
1407
1408 if (pobj->type == ADDR_INTERFACE) {
1409 AdapterInterface *adapter = ADAPTER_INTERFACE(pobj);
1410
1411 iface = adapter->iface;
1412 if (iface && iface->haveLibrary) {
1413 /* Enable appropriate File / New command */
1414 atci = adapter->atci;
1415 menu_set_sensitive(addrbook.menu_factory, atci->menuCommand, TRUE);
1416 }
1417 canEditTree = FALSE;
1418 } else if (pobj->type == ADDR_DATASOURCE) {
1419 AdapterDSource *ads = ADAPTER_DSOURCE(pobj);
1420
1421 ds = ads->dataSource;
1422 iface = ds->iface;
1423 if (!iface->readOnly) {
1424 canAdd = canEditAddress = TRUE;
1425 }
1426 if (!iface->haveLibrary) {
1427 canAdd = canEditAddress = FALSE;
1428 }
1429 #ifdef USE_LDAP
1430 if (ads->subType == ADDR_LDAP) {
1431 if (iface->haveLibrary && ds->rawDataSource)
1432 canLookup = TRUE;
1433 } else
1434 #endif
1435 canLookup = TRUE;
1436 if (ads->subType == ADDR_BOOK && pobj->name &&
1437 !strcmp(pobj->name, ADDR_DS_AUTOREG))
1438 canEditTree = FALSE;
1439 } else if (pobj->type == ADDR_ITEM_FOLDER) {
1440 ds = addressbook_find_datasource(&iter);
1441 if (ds) {
1442 iface = ds->iface;
1443 if (!iface->readOnly) {
1444 canAdd = canEditAddress = TRUE;
1445 }
1446 canLookup = TRUE;
1447 }
1448 } else if (pobj->type == ADDR_ITEM_GROUP) {
1449 ds = addressbook_find_datasource(&iter);
1450 if (ds) {
1451 iface = ds->iface;
1452 if (!iface->readOnly) {
1453 canEditAddress = TRUE;
1454 }
1455 canLookup = TRUE;
1456 }
1457 }
1458
1459 if (obj == NULL)
1460 canEditAddress = FALSE;
1461 canDelete = canEditAddress;
1462 if (gtk_tree_selection_count_selected_rows(lselection) > 1)
1463 canEditAddress = FALSE;
1464 if (_addressListSelection_) {
1465 GList *cur;
1466 AddressObject *item;
1467
1468 for (cur = _addressListSelection_; cur != NULL; cur = cur->next) {
1469 item = cur->data;
1470 if (item->type == ADDR_ITEM_PERSON) {
1471 canCopy = TRUE;
1472 break;
1473 }
1474 }
1475 }
1476 if (_clipObjectList_ && canAdd)
1477 canPaste = TRUE;
1478
1479 /* Enable add */
1480 menu_set_sensitive(addrbook.menu_factory, "/Address/New Address", canAdd);
1481 menu_set_sensitive(addrbook.menu_factory, "/Address/New Folder", canAdd);
1482 menu_set_sensitive(addrbook.menu_factory, "/Address/New Group", canAdd);
1483
1484 menu_set_sensitive(addrbook.menu_factory, "/Address/Add to recipient", hasListSelection);
1485 menu_set_sensitive(addrbook.menu_factory, "/Address/Add to Cc", hasListSelection);
1486 menu_set_sensitive(addrbook.menu_factory, "/Address/Add to Bcc", hasListSelection);
1487
1488 /* Enable edit */
1489 menu_set_sensitive(addrbook.menu_factory, "/Address/Edit", canEditAddress);
1490 menu_set_sensitive(addrbook.menu_factory, "/Address/Delete", canDelete);
1491
1492 menu_set_sensitive(addrbook.menu_factory, "/File/Edit", canEditTree);
1493 menu_set_sensitive(addrbook.menu_factory, "/File/Delete", canEditTree);
1494
1495 menu_set_sensitive(addrbook.menu_factory, "/Edit/Copy", canCopy);
1496 menu_set_sensitive(addrbook.menu_factory, "/Edit/Paste", canPaste);
1497
1498 menu_set_sensitive(addrbook.menu_factory, "/Tools/Export to CSV file", canEditTree);
1499
1500 /* Popup menu */
1501 menu_set_sensitive(addrbook.tree_factory, "/New Address", canAdd);
1502 menu_set_sensitive(addrbook.tree_factory, "/New Folder", canAdd);
1503 menu_set_sensitive(addrbook.tree_factory, "/New Group", canAdd);
1504 menu_set_sensitive(addrbook.tree_factory, "/Edit", canEditTree);
1505 menu_set_sensitive(addrbook.tree_factory, "/Delete", canEditTree);
1506
1507 menu_set_sensitive(addrbook.list_factory, "/New Address", canAdd);
1508 menu_set_sensitive(addrbook.list_factory, "/New Folder", canAdd);
1509 menu_set_sensitive(addrbook.list_factory, "/New Group", canAdd);
1510 menu_set_sensitive(addrbook.list_factory, "/Add to recipient", hasListSelection);
1511 menu_set_sensitive(addrbook.list_factory, "/Add to Cc", hasListSelection);
1512 menu_set_sensitive(addrbook.list_factory, "/Add to Bcc", hasListSelection);
1513 menu_set_sensitive(addrbook.list_factory, "/Edit", canEditAddress);
1514 menu_set_sensitive(addrbook.list_factory, "/Delete", canDelete);
1515 menu_set_sensitive(addrbook.list_factory, "/Copy", canCopy);
1516 menu_set_sensitive(addrbook.list_factory, "/Paste", canPaste);
1517
1518 /* Buttons */
1519 gtk_widget_set_sensitive(addrbook.to_btn, hasListSelection);
1520 gtk_widget_set_sensitive(addrbook.cc_btn, hasListSelection);
1521 gtk_widget_set_sensitive(addrbook.bcc_btn, hasListSelection);
1522 gtk_widget_set_sensitive(addrbook.reg_btn, canAdd);
1523 gtk_widget_set_sensitive(addrbook.del_btn, canDelete);
1524 gtk_widget_set_sensitive(addrbook.lup_btn, canLookup);
1525 }
1526
addressbook_tree_selection_changed(GtkTreeSelection * selection,gpointer data)1527 static void addressbook_tree_selection_changed(GtkTreeSelection *selection,
1528 gpointer data)
1529 {
1530 GtkTreeModel *model;
1531 GtkTreeModel *lmodel;
1532 GtkTreeIter iter;
1533 GtkTreePath *path;
1534 AddressObject *obj = NULL;
1535 AdapterDSource *ads = NULL;
1536 AddressDataSource *ds = NULL;
1537 ItemFolder *rootFolder = NULL;
1538
1539 debug_print("addressbook_tree_selection_changed\n");
1540
1541 if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
1542 debug_print("addressbook_tree_selection_changed: no selection\n");
1543 gtk_tree_row_reference_free(addrbook.tree_selected);
1544 addrbook.tree_selected = NULL;
1545 gtk_tree_row_reference_free(addrbook.tree_opened);
1546 addrbook.tree_opened = NULL;
1547 addressbook_status_show("");
1548 if (addrbook.entry)
1549 gtk_entry_set_text(GTK_ENTRY(addrbook.entry), "");
1550 if (addrbook.listview) {
1551 lmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.listview));
1552 gtk_tree_store_clear(GTK_TREE_STORE(lmodel));
1553 }
1554 return;
1555 }
1556
1557 path = gtk_tree_model_get_path(model, &iter);
1558 gtk_tree_row_reference_free(addrbook.tree_selected);
1559 addrbook.tree_selected = gtk_tree_row_reference_new(model, path);
1560 gtk_tree_row_reference_free(addrbook.list_selected);
1561 addrbook.list_selected = NULL;
1562 addressbook_status_show("");
1563 if (addrbook.entry)
1564 gtk_entry_set_text(GTK_ENTRY(addrbook.entry), "");
1565 if (addrbook.listview) {
1566 lmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.listview));
1567 gtk_tree_store_clear(GTK_TREE_STORE(lmodel));
1568 }
1569 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
1570 if (obj == NULL) {
1571 gtk_tree_path_free(path);
1572 return;
1573 }
1574
1575 gtk_tree_row_reference_free(addrbook.tree_opened);
1576 addrbook.tree_opened = gtk_tree_row_reference_new(model, path);
1577
1578 if (obj->type == ADDR_DATASOURCE) {
1579 /* Read from file */
1580 static gboolean tVal = TRUE;
1581
1582 ads = ADAPTER_DSOURCE(obj);
1583 if (ads == NULL) return;
1584 ds = ads->dataSource;
1585 if (ds == NULL) return;
1586
1587 if (addrindex_ds_get_modify_flag(ds)) {
1588 addrindex_ds_read_data(ds);
1589 }
1590
1591 if (!addrindex_ds_get_read_flag(ds)) {
1592 addrindex_ds_read_data(ds);
1593 }
1594 addressbook_ds_show_message(ds);
1595
1596 if (!addrindex_ds_get_access_flag(ds)) {
1597 /* Remove existing folders and groups */
1598 addressbook_tree_remove_children(model, &iter);
1599
1600 /* Load folders into the tree */
1601 rootFolder = addrindex_ds_get_root_folder(ds);
1602 if (ds->type == ADDR_IF_JPILOT) {
1603 addressbook_node_add_folder(&iter, ds, rootFolder, ADDR_CATEGORY, NULL);
1604 } else {
1605 addressbook_node_add_folder(&iter, ds, rootFolder, ADDR_ITEM_FOLDER, NULL);
1606 }
1607 addrindex_ds_set_access_flag(ds, &tVal);
1608 gtk_tree_view_expand_row(GTK_TREE_VIEW(addrbook.treeview), path, TRUE);
1609 }
1610 }
1611
1612 gtk_tree_path_free(path);
1613
1614 /* Update address list */
1615 addressbook_set_list(obj);
1616 addressbook_menuitem_set_sensitive();
1617 addressbook_list_select_clear();
1618 }
1619
addressbook_list_selection_changed(GtkTreeSelection * selection,gpointer data)1620 static void addressbook_list_selection_changed(GtkTreeSelection *selection,
1621 gpointer data)
1622 {
1623 GtkTreeModel *lmodel;
1624 GtkTreePath *path;
1625 GList *selected;
1626
1627 debug_print("addressbook_list_selection_changed\n");
1628
1629 selected = gtk_tree_selection_get_selected_rows(selection, &lmodel);
1630 addressbook_list_select_set(selected);
1631 gtk_tree_row_reference_free(addrbook.list_selected);
1632 if (selected) {
1633 path = (GtkTreePath *)selected->data;
1634 addrbook.list_selected = gtk_tree_row_reference_new(lmodel, path);
1635 g_list_foreach(selected, (GFunc)gtk_tree_path_free, NULL);
1636 g_list_free(selected);
1637 } else
1638 addrbook.list_selected = NULL;
1639
1640 addressbook_menuitem_set_sensitive();
1641 }
1642
addressbook_list_select_clear(void)1643 static void addressbook_list_select_clear(void)
1644 {
1645 if (_addressListSelection_) {
1646 g_list_free(_addressListSelection_);
1647 }
1648 _addressListSelection_ = NULL;
1649 }
1650
addressbook_list_select_remove(AddressObject * obj)1651 static void addressbook_list_select_remove(AddressObject *obj)
1652 {
1653 if (!obj)
1654 return;
1655 if (_addressListSelection_) {
1656 _addressListSelection_ = g_list_remove(_addressListSelection_, obj);
1657 }
1658 }
1659
addressbook_list_select_set(GList * row_list)1660 static void addressbook_list_select_set(GList *row_list)
1661 {
1662 GtkTreeModel *model;
1663 GtkTreeIter iter;
1664 GList *cur;
1665 AddressObject *obj;
1666
1667 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.listview));
1668
1669 addressbook_list_select_clear();
1670 for (cur = row_list; cur != NULL; cur = cur->next) {
1671 obj = NULL;
1672 gtk_tree_model_get_iter(model, &iter, (GtkTreePath *)cur->data);
1673 gtk_tree_model_get(model, &iter, COL_L_OBJ, &obj, -1);
1674 if (obj && (obj->type == ADDR_ITEM_PERSON ||
1675 obj->type == ADDR_ITEM_EMAIL ||
1676 obj->type == ADDR_ITEM_GROUP)) {
1677 _addressListSelection_ = g_list_prepend(_addressListSelection_, obj);
1678 }
1679 }
1680 _addressListSelection_ = g_list_reverse(_addressListSelection_);
1681 }
1682
addressbook_entry_activated(GtkWidget * widget,gpointer data)1683 static void addressbook_entry_activated(GtkWidget *widget, gpointer data)
1684 {
1685 addressbook_lup_clicked(NULL, NULL);
1686 }
1687
addressbook_list_button_pressed(GtkWidget * widget,GdkEventButton * event,gpointer data)1688 static gboolean addressbook_list_button_pressed(GtkWidget *widget,
1689 GdkEventButton *event,
1690 gpointer data)
1691 {
1692 GtkTreePath *path = NULL;
1693 GtkTreeSelection *selection;
1694 gboolean is_selected = FALSE;
1695 gboolean mod_pressed = FALSE;
1696
1697 if (!event)
1698 return FALSE;
1699
1700 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), event->x, event->y,
1701 &path, NULL, NULL, NULL);
1702 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
1703 if (path)
1704 is_selected = gtk_tree_selection_path_is_selected
1705 (selection, path);
1706 mod_pressed = ((event->state &
1707 (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0);
1708
1709 if (event->button == 1) {
1710 if (is_selected && !mod_pressed) {
1711 can_toggle_list_selection = FALSE;
1712 }
1713
1714 if (is_selected && event->type == GDK_2BUTTON_PRESS) {
1715 debug_print("addressbook_list_button_pressed: GDK_2BUTTON_PRESS\n");
1716 /* Handle double click */
1717 if (prefs_common.add_address_by_click &&
1718 addrbook.target_compose)
1719 addressbook_to_clicked
1720 (NULL, GINT_TO_POINTER(COMPOSE_ENTRY_TO));
1721 else
1722 addressbook_edit_address_cb(NULL, 0, NULL);
1723 return TRUE;
1724 }
1725 } else if (event->button == 3) {
1726 gtk_menu_popup(GTK_MENU(addrbook.list_popup), NULL, NULL,
1727 NULL, NULL, event->button, event->time);
1728 gtk_tree_path_free(path);
1729 if (is_selected)
1730 return TRUE;
1731 }
1732
1733 return FALSE;
1734 }
1735
addressbook_list_button_released(GtkWidget * widget,GdkEventButton * event,gpointer data)1736 static gboolean addressbook_list_button_released(GtkWidget *widget,
1737 GdkEventButton *event,
1738 gpointer data)
1739 {
1740 if (!can_toggle_list_selection && !list_on_drag) {
1741 GtkTreePath *path;
1742
1743 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), event->x, event->y, &path, NULL, NULL, NULL)) {
1744 can_toggle_list_selection = TRUE;
1745 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), path, NULL, FALSE);
1746 gtk_tree_path_free(path);
1747 }
1748 }
1749 can_toggle_list_selection = TRUE;
1750 list_on_drag = FALSE;
1751 return FALSE;
1752 }
1753
addressbook_tree_button_pressed(GtkWidget * widget,GdkEventButton * event,gpointer data)1754 static gboolean addressbook_tree_button_pressed(GtkWidget *widget,
1755 GdkEventButton *event,
1756 gpointer data)
1757 {
1758 GtkTreeView *treeview = GTK_TREE_VIEW(widget);
1759 GtkTreeSelection *selection;
1760 GtkTreePath *path;
1761
1762 if (!event)
1763 return FALSE;
1764
1765 if (!gtk_tree_view_get_path_at_pos(treeview, event->x, event->y,
1766 &path, NULL, NULL, NULL))
1767 return TRUE;
1768 selection = gtk_tree_view_get_selection(treeview);
1769
1770 addressbook_menuitem_set_sensitive();
1771
1772 if (event->button == 3) {
1773 gtk_tree_selection_select_path(selection, path);
1774 gtk_menu_popup(GTK_MENU(addrbook.tree_popup),
1775 NULL, NULL, NULL, NULL,
1776 event->button, event->time);
1777 } else if (event->type == GDK_2BUTTON_PRESS) {
1778 gtk_tree_view_expand_row(treeview, path, FALSE);
1779 }
1780
1781 gtk_tree_path_free(path);
1782 return FALSE;
1783 }
1784
addressbook_tree_button_released(GtkWidget * widget,GdkEventButton * event,gpointer data)1785 static gboolean addressbook_tree_button_released(GtkWidget *widget,
1786 GdkEventButton *event,
1787 gpointer data)
1788 {
1789 return FALSE;
1790 }
1791
addressbook_obj_is_droppable(GtkTreeModel * model,AddressObject * obj)1792 static gboolean addressbook_obj_is_droppable(GtkTreeModel *model,
1793 AddressObject *obj)
1794 {
1795 gboolean acceptable = FALSE;
1796
1797 if (!model || !obj)
1798 return FALSE;
1799 if (!_addressListSelection_)
1800 return FALSE;
1801
1802 if (obj->type == ADDR_DATASOURCE) {
1803 AdapterDSource *ads;
1804 AddressDataSource *ds;
1805 AddressInterface *iface;
1806
1807 ads = ADAPTER_DSOURCE(obj);
1808 ds = ads ? ads->dataSource : NULL;
1809 iface = ds ? ds->iface : NULL;
1810 if (ads && ads->subType == ADDR_BOOK &&
1811 iface && !iface->readOnly)
1812 acceptable = TRUE;
1813 } else if (obj->type == ADDR_ITEM_FOLDER) {
1814 acceptable = TRUE;
1815 }
1816
1817 if (acceptable && addrbook.tree_opened) {
1818 AddressObject *open_obj;
1819 GtkTreeIter opened;
1820
1821 gtkut_tree_row_reference_get_iter(model, addrbook.tree_opened,
1822 &opened);
1823 gtk_tree_model_get(model, &opened, COL_OBJ, &open_obj, -1);
1824 if (open_obj == obj)
1825 acceptable = FALSE;
1826 }
1827
1828 if (acceptable) {
1829 GList *node;
1830 for (node = _addressListSelection_; node != NULL; node = node->next) {
1831 AddressObject *obj = node->data;
1832 if (obj && obj->type == ADDR_ITEM_PERSON)
1833 break;
1834 }
1835 if (!node)
1836 acceptable = FALSE;
1837 }
1838
1839 return acceptable;
1840 }
1841
addressbook_drag_motion(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time,gpointer data)1842 static gboolean addressbook_drag_motion(GtkWidget *widget,
1843 GdkDragContext *context,
1844 gint x, gint y,
1845 guint time, gpointer data)
1846 {
1847 GtkTreeModel *model;
1848 GtkTreePath *path = NULL;
1849 GtkTreeIter iter;
1850 AddressObject *obj, *src_obj;
1851 AddressDataSource *src_ds;
1852 AddressBookFile *src_abf;
1853 gboolean acceptable;
1854
1855 if (!gtk_tree_view_get_dest_row_at_pos
1856 (GTK_TREE_VIEW(widget), x, y, &path, NULL)) {
1857 gtk_tree_view_set_drag_dest_row
1858 (GTK_TREE_VIEW(widget), NULL,
1859 GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
1860 gdk_drag_status(context, 0, time);
1861 return FALSE;
1862 }
1863
1864 model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
1865 gtk_tree_model_get_iter(model, &iter, path);
1866 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
1867 g_return_val_if_fail(obj != NULL, FALSE);
1868
1869 /* source */
1870 gtkut_tree_row_reference_get_iter(model, addrbook.tree_opened, &iter);
1871 gtk_tree_model_get(model, &iter, COL_OBJ, &src_obj, -1);
1872 g_return_val_if_fail(src_obj != NULL, FALSE);
1873 src_ds = addressbook_find_datasource(&iter);
1874 g_return_val_if_fail(src_ds != NULL, FALSE);
1875 src_abf = src_ds->rawDataSource;
1876 g_return_val_if_fail(src_abf != NULL, FALSE);
1877
1878 #ifdef G_OS_WIN32
1879 {
1880 GdkModifierType state = 0;
1881
1882 gdk_window_get_pointer(widget->window, NULL, NULL, &state);
1883 if ((state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) == 0)
1884 context->actions = GDK_ACTION_MOVE | GDK_ACTION_COPY;
1885 }
1886 #endif
1887
1888 if (!src_ds->iface ||
1889 (src_ds->iface->readOnly || !src_ds->iface->haveLibrary))
1890 context->actions &= ~GDK_ACTION_MOVE;
1891
1892 acceptable = addressbook_obj_is_droppable(model, obj);
1893 if ((context->actions & (GDK_ACTION_MOVE | GDK_ACTION_COPY)) == 0)
1894 acceptable = FALSE;
1895
1896 if (!acceptable) {
1897 gtk_tree_view_set_drag_dest_row
1898 (GTK_TREE_VIEW(widget), NULL,
1899 GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
1900 gdk_drag_status(context, 0, time);
1901 } else {
1902 GdkDragAction action = 0;
1903
1904 if ((context->actions & GDK_ACTION_MOVE) != 0)
1905 action = GDK_ACTION_MOVE;
1906 else if ((context->actions & GDK_ACTION_COPY) != 0)
1907 action = GDK_ACTION_COPY;
1908 gtk_tree_view_set_drag_dest_row
1909 (GTK_TREE_VIEW(widget), path,
1910 GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
1911 gdk_drag_status(context, action, time);
1912 }
1913
1914 gtk_tree_path_free(path);
1915
1916 return TRUE;
1917 }
1918
addressbook_drag_leave(GtkWidget * widget,GdkDragContext * context,guint time,gpointer data)1919 static void addressbook_drag_leave(GtkWidget *widget, GdkDragContext *context,
1920 guint time, gpointer data)
1921 {
1922 gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(widget), NULL,
1923 GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
1924 }
1925
addressbook_drag_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * data,guint info,guint time,gpointer user_data)1926 static void addressbook_drag_received(GtkWidget *widget,
1927 GdkDragContext *context,
1928 gint x, gint y,
1929 GtkSelectionData *data,
1930 guint info, guint time,
1931 gpointer user_data)
1932 {
1933 GtkTreeModel *model;
1934 GtkTreePath *path = NULL;
1935 GtkTreeIter iter;
1936 AddressObject *obj, *pobj, *src_obj;
1937 AddressDataSource *ds, *src_ds;
1938 AddressBookFile *abf, *src_abf;
1939 gboolean acceptable;
1940 gboolean is_move;
1941 GList *node;
1942 ItemFolder *folder = NULL;
1943 ItemPerson *person, *new_person;
1944
1945 if (!gtk_tree_view_get_dest_row_at_pos
1946 (GTK_TREE_VIEW(widget), x, y, &path, NULL))
1947 return;
1948
1949 debug_print("addressbook_drag_received_cb: received data\n");
1950
1951 /* dest */
1952 model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
1953 gtk_tree_model_get_iter(model, &iter, path);
1954 gtk_tree_model_get(model, &iter, COL_OBJ, &pobj, -1);
1955 g_return_if_fail(pobj != NULL);
1956 ds = addressbook_find_datasource(&iter);
1957 g_return_if_fail(ds != NULL);
1958
1959 /* source */
1960 gtkut_tree_row_reference_get_iter(model, addrbook.tree_opened, &iter);
1961 gtk_tree_model_get(model, &iter, COL_OBJ, &src_obj, -1);
1962 g_return_if_fail(src_obj != NULL);
1963 src_ds = addressbook_find_datasource(&iter);
1964 g_return_if_fail(src_ds != NULL);
1965 src_abf = src_ds->rawDataSource;
1966 g_return_if_fail(src_abf != NULL);
1967
1968 acceptable = addressbook_obj_is_droppable(model, pobj);
1969 abf = ds->rawDataSource;
1970 if (!abf)
1971 acceptable = FALSE;
1972
1973 if ((context->actions & (GDK_ACTION_MOVE | GDK_ACTION_COPY)) == 0)
1974 acceptable = FALSE;
1975 is_move = (context->actions & GDK_ACTION_MOVE) != 0;
1976
1977 if (!src_ds->iface ||
1978 (src_ds->iface->readOnly || !src_ds->iface->haveLibrary))
1979 is_move = FALSE;
1980
1981 if (!_addressListSelection_ || !acceptable) {
1982 context->action = 0;
1983 gtk_drag_finish(context, FALSE, FALSE, time);
1984 gtk_tree_path_free(path);
1985 return;
1986 }
1987
1988 if (pobj->type == ADDR_ITEM_FOLDER)
1989 folder = ADAPTER_FOLDER(pobj)->itemFolder;
1990
1991 node = _addressListSelection_;
1992 while (node) {
1993 GList *cur;
1994
1995 obj = node->data;
1996 node = g_list_next(node);
1997 if (obj->type != ADDR_ITEM_PERSON)
1998 continue;
1999
2000 person = (ItemPerson *)obj;
2001 new_person = addrbook_add_address_list(abf, folder, NULL);
2002 ADDRITEM_NAME(new_person) = g_strdup(ADDRITEM_NAME(person));
2003 new_person->firstName = g_strdup(person->firstName);
2004 new_person->lastName = g_strdup(person->lastName);
2005 new_person->nickName = g_strdup(person->nickName);
2006 for (cur = person->listEMail; cur != NULL; cur = cur->next) {
2007 ItemEMail *email = cur->data;
2008 addritem_person_add_email(new_person, addritem_copy_item_email(email));
2009 }
2010 for (cur = person->listAttrib; cur != NULL; cur = cur->next) {
2011 UserAttribute *attr = cur->data;
2012 addritem_person_add_attribute(new_person, addritem_copy_attribute(attr));
2013 }
2014
2015 if (is_move) {
2016 if (_clipObjectList_)
2017 _clipObjectList_ = g_list_remove(_clipObjectList_, person);
2018 person = addrbook_remove_person(src_abf, person);
2019 if (person)
2020 addritem_free_item_person(person);
2021 }
2022 }
2023
2024 if (is_move) {
2025 addressbook_list_select_clear();
2026 addressbook_reopen();
2027 }
2028
2029 context->action = 0;
2030 gtk_drag_finish(context, TRUE, FALSE, time);
2031
2032 gtk_tree_path_free(path);
2033
2034 addressbook_modified();
2035 }
2036
addressbook_folder_resized(GtkWidget * widget,GtkAllocation * allocation,gpointer data)2037 static void addressbook_folder_resized(GtkWidget *widget,
2038 GtkAllocation *allocation,
2039 gpointer data)
2040 {
2041 gint width = allocation->width;
2042
2043 if (width < 8)
2044 return;
2045
2046 prefs_common.addressbook_folder_width = width;
2047 }
2048
addressbook_col_resized(GtkWidget * widget,GtkAllocation * allocation,gpointer data)2049 static void addressbook_col_resized(GtkWidget *widget,
2050 GtkAllocation *allocation, gpointer data)
2051 {
2052 AddressBookListColumnPos type = (gint)data;
2053 gint width = allocation->width;
2054
2055 if (width < 8)
2056 return;
2057
2058 switch (type) {
2059 case COL_NAME:
2060 prefs_common.addressbook_col_name = width;
2061 break;
2062 case COL_ADDRESS:
2063 prefs_common.addressbook_col_addr = width;
2064 break;
2065 case COL_NICKNAME:
2066 prefs_common.addressbook_col_nickname = width;
2067 break;
2068 case COL_REMARKS:
2069 prefs_common.addressbook_col_rem = width;
2070 break;
2071 default:
2072 break;
2073 }
2074 }
2075
addressbook_popup_close(GtkMenuShell * menu_shell,gpointer data)2076 static void addressbook_popup_close(GtkMenuShell *menu_shell, gpointer data)
2077 {
2078 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2079 GtkTreeSelection *selection;
2080 GtkTreePath *path;
2081
2082 if (!addrbook.tree_opened)
2083 return;
2084
2085 selection = gtk_tree_view_get_selection(treeview);
2086 path = gtk_tree_row_reference_get_path(addrbook.tree_opened);
2087 if (path) {
2088 gtk_tree_selection_select_path(selection, path);
2089 gtk_tree_path_free(path);
2090 }
2091 }
2092
addressbook_new_folder_cb(gpointer data,guint action,GtkWidget * widget)2093 static void addressbook_new_folder_cb(gpointer data, guint action,
2094 GtkWidget *widget)
2095 {
2096 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2097 GtkTreeSelection *selection;
2098 GtkTreeModel *model;
2099 GtkTreeIter iter;
2100 AddressObject *obj = NULL;
2101 AddressDataSource *ds = NULL;
2102 AddressBookFile *abf = NULL;
2103 ItemFolder *parentFolder = NULL;
2104 ItemFolder *folder = NULL;
2105
2106 selection = gtk_tree_view_get_selection(treeview);
2107 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2108 return;
2109
2110 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
2111 if (obj == NULL)
2112 return;
2113 ds = addressbook_find_datasource(&iter);
2114 if (ds == NULL)
2115 return;
2116
2117 if (obj->type == ADDR_DATASOURCE) {
2118 if (ADAPTER_DSOURCE(obj)->subType != ADDR_BOOK) return;
2119 } else if (obj->type == ADDR_ITEM_FOLDER) {
2120 parentFolder = ADAPTER_FOLDER(obj)->itemFolder;
2121 } else {
2122 return;
2123 }
2124
2125 abf = ds->rawDataSource;
2126 if (abf == NULL) return;
2127 folder = addressbook_edit_folder(abf, parentFolder, NULL);
2128 if (folder) {
2129 GtkTreeIter new_iter;
2130 GtkTreePath *path;
2131 addressbook_node_add_folder(&iter, ds, folder, ADDR_ITEM_FOLDER, &new_iter);
2132 path = gtk_tree_model_get_path(model, &iter);
2133 gtk_tree_view_expand_row(treeview, path, TRUE);
2134 gtk_tree_path_free(path);
2135 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened))
2136 addressbook_set_list(obj);
2137 }
2138
2139 }
2140
addressbook_new_group_cb(gpointer data,guint action,GtkWidget * widget)2141 static void addressbook_new_group_cb(gpointer data, guint action,
2142 GtkWidget *widget)
2143 {
2144 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2145 GtkTreeSelection *selection;
2146 GtkTreeModel *model;
2147 GtkTreeIter iter;
2148 AddressObject *obj = NULL;
2149 AddressDataSource *ds = NULL;
2150 AddressBookFile *abf = NULL;
2151 ItemFolder *parentFolder = NULL;
2152 ItemGroup *group = NULL;
2153
2154 selection = gtk_tree_view_get_selection(treeview);
2155 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2156 return;
2157
2158 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
2159 if (obj == NULL)
2160 return;
2161 ds = addressbook_find_datasource(&iter);
2162 if (ds == NULL)
2163 return;
2164
2165 if (obj->type == ADDR_DATASOURCE) {
2166 if (ADAPTER_DSOURCE(obj)->subType != ADDR_BOOK) return;
2167 } else if (obj->type == ADDR_ITEM_FOLDER) {
2168 parentFolder = ADAPTER_FOLDER(obj)->itemFolder;
2169 } else {
2170 return;
2171 }
2172
2173 abf = ds->rawDataSource;
2174 if (abf == NULL) return;
2175 group = addressbook_edit_group(abf, parentFolder, NULL);
2176 if (group) {
2177 GtkTreeIter new_iter;
2178 GtkTreePath *path;
2179 addressbook_node_add_group(&iter, ds, group, &new_iter);
2180 path = gtk_tree_model_get_path(model, &iter);
2181 gtk_tree_view_expand_row(treeview, path, TRUE);
2182 gtk_tree_path_free(path);
2183 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened))
2184 addressbook_set_list(obj);
2185 }
2186
2187 }
2188
addressbook_change_node_name(GtkTreeIter * iter,const gchar * name)2189 static void addressbook_change_node_name(GtkTreeIter *iter, const gchar *name)
2190 {
2191 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2192 GtkTreeStore *store;
2193
2194 store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
2195 gtk_tree_store_set(store, iter, COL_FOLDER_NAME, name, -1);
2196 }
2197
2198 /*
2199 * Edit data source.
2200 * Enter: obj Address object to edit.
2201 * node Node in tree.
2202 * Return: New name of data source.
2203 */
addressbook_edit_datasource(AddressObject * obj,GtkTreeIter * iter)2204 static gchar *addressbook_edit_datasource(AddressObject *obj, GtkTreeIter *iter)
2205 {
2206 gchar *newName = NULL;
2207 AddressDataSource *ds = NULL;
2208 AddressInterface *iface = NULL;
2209 AdapterDSource *ads = NULL;
2210
2211 ds = addressbook_find_datasource(iter);
2212 if (ds == NULL)
2213 return NULL;
2214 iface = ds->iface;
2215 if (!iface->haveLibrary)
2216 return NULL;
2217
2218 /* Read data from data source */
2219 if (!addrindex_ds_get_read_flag(ds)) {
2220 addrindex_ds_read_data(ds);
2221 }
2222
2223 /* Handle edit */
2224 ads = ADAPTER_DSOURCE(obj);
2225 if (ads->subType == ADDR_BOOK) {
2226 if (addressbook_edit_book(_addressIndex_, ads) == NULL)
2227 return NULL;
2228 } else if (ads->subType == ADDR_VCARD) {
2229 if (addressbook_edit_vcard(_addressIndex_, ads) == NULL)
2230 return NULL;
2231 #ifdef USE_JPILOT
2232 } else if (ads->subType == ADDR_JPILOT) {
2233 if (addressbook_edit_jpilot(_addressIndex_, ads) == NULL)
2234 return NULL;
2235 #endif
2236 #ifdef USE_LDAP
2237 } else if (ads->subType == ADDR_LDAP) {
2238 if (addressbook_edit_ldap(_addressIndex_, ads) == NULL)
2239 return NULL;
2240 #endif
2241 } else {
2242 return NULL;
2243 }
2244 newName = obj->name;
2245 return newName;
2246 }
2247
2248 /*
2249 * Edit an object that is in the address tree area.
2250 */
addressbook_treenode_edit_cb(gpointer data,guint action,GtkWidget * widget)2251 static void addressbook_treenode_edit_cb(gpointer data, guint action,
2252 GtkWidget *widget)
2253 {
2254 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2255 GtkTreeSelection *selection;
2256 GtkTreeModel *model;
2257 GtkTreeIter iter, parent;
2258 AddressObject *obj = NULL;
2259 AddressDataSource *ds = NULL;
2260 AddressBookFile *abf = NULL;
2261 gchar *name = NULL;
2262
2263 selection = gtk_tree_view_get_selection(treeview);
2264 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2265 return;
2266
2267 if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), &iter) == 0)
2268 return;
2269 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
2270 if (obj == NULL)
2271 return;
2272 if (!gtk_tree_model_iter_parent(model, &parent, &iter))
2273 return;
2274
2275 ds = addressbook_find_datasource(&iter);
2276 if (ds == NULL)
2277 return;
2278
2279 if (obj->type == ADDR_DATASOURCE) {
2280 name = addressbook_edit_datasource(obj, &iter);
2281 if (name == NULL)
2282 return;
2283 } else {
2284 abf = ds->rawDataSource;
2285 if (abf == NULL)
2286 return;
2287 if (obj->type == ADDR_ITEM_FOLDER) {
2288 AdapterFolder *adapter = ADAPTER_FOLDER(obj);
2289 ItemFolder *item = adapter->itemFolder;
2290 ItemFolder *parentFolder = NULL;
2291 parentFolder = (ItemFolder *)ADDRITEM_PARENT(item);
2292 if (addressbook_edit_folder(abf, parentFolder, item) == NULL)
2293 return;
2294 name = ADDRITEM_NAME(item);
2295 } else if (obj->type == ADDR_ITEM_GROUP) {
2296 AdapterGroup *adapter = ADAPTER_GROUP(obj);
2297 ItemGroup *item = adapter->itemGroup;
2298 ItemFolder *parentFolder = NULL;
2299 parentFolder = (ItemFolder *)ADDRITEM_PARENT(item);
2300 if (addressbook_edit_group(abf, parentFolder, item) == NULL)
2301 return;
2302 name = ADDRITEM_NAME(item);
2303 }
2304 }
2305
2306 if (name) {
2307 GtkTreePath *path;
2308
2309 /* Update node in tree view */
2310 addressbook_change_node_name(&iter, name);
2311 path = gtk_tree_model_get_path(model, &iter);
2312 gtk_tree_view_expand_row(treeview, path, TRUE);
2313 gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
2314 gtk_tree_path_free(path);
2315 }
2316 }
2317
2318 /*
2319 * Delete an item from the tree widget.
2320 */
addressbook_treenode_delete_cb(gpointer data,guint action,GtkWidget * widget)2321 static void addressbook_treenode_delete_cb(gpointer data, guint action,
2322 GtkWidget *widget)
2323 {
2324 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2325 GtkTreeSelection *selection;
2326 GtkTreeModel *model;
2327 GtkTreeIter iter, parent;
2328 AddressObject *obj;
2329 gchar *message;
2330 AlertValue aval;
2331 AddressBookFile *abf = NULL;
2332 AdapterDSource *ads = NULL;
2333 AddressInterface *iface = NULL;
2334 AddressDataSource *ds = NULL;
2335 gboolean remFlag = FALSE;
2336
2337 selection = gtk_tree_view_get_selection(treeview);
2338 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2339 return;
2340
2341 if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), &iter) == 0)
2342 return;
2343 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
2344 g_return_if_fail(obj != NULL);
2345
2346 if (obj->type == ADDR_DATASOURCE) {
2347 ads = ADAPTER_DSOURCE(obj);
2348 if (ads == NULL)
2349 return;
2350 ds = ads->dataSource;
2351 if (ds == NULL)
2352 return;
2353 } else {
2354 /* Must be folder or something else */
2355 ds = addressbook_find_datasource(&iter);
2356 if (ds == NULL)
2357 return;
2358
2359 /* Only allow deletion from non-readOnly data sources */
2360 iface = ds->iface;
2361 if (iface->readOnly)
2362 return;
2363 }
2364
2365 /* Confirm deletion */
2366 if (obj->type == ADDR_ITEM_FOLDER) {
2367 message = g_strdup_printf
2368 (_("Do you want to delete the folder AND all addresses in `%s' ?\n"
2369 "If deleting the folder only, addresses will be moved into parent folder."),
2370 obj->name);
2371 aval = alertpanel(_("Delete folder"), message, _("_Folder only"), _("Folder and _addresses"), GTK_STOCK_CANCEL);
2372 g_free(message);
2373 if (aval != G_ALERTDEFAULT && aval != G_ALERTALTERNATE)
2374 return;
2375 } else {
2376 message = g_strdup_printf(_("Really delete `%s' ?"), obj->name);
2377 aval = alertpanel(_("Delete"), message, GTK_STOCK_YES, GTK_STOCK_NO, NULL);
2378 g_free(message);
2379 if (aval != G_ALERTDEFAULT)
2380 return;
2381 }
2382
2383 /* Proceed with deletion */
2384 if (obj->type == ADDR_DATASOURCE) {
2385 /* Remove data source. */
2386 if (addrindex_index_remove_datasource(_addressIndex_, ds)) {
2387 addressbook_free_child_adapters(&iter);
2388 abf = addressbook_get_book_file();
2389 if (abf) {
2390 gchar *bookFile;
2391 bookFile = g_strconcat(abf->path, G_DIR_SEPARATOR_S, abf->fileName, NULL);
2392 debug_print("removing %s\n", bookFile);
2393 g_unlink(bookFile);
2394 g_free(bookFile);
2395 }
2396 remFlag = TRUE;
2397 }
2398 } else {
2399 abf = addressbook_get_book_file();
2400 if (abf == NULL)
2401 return;
2402 }
2403
2404 if (obj->type == ADDR_ITEM_FOLDER) {
2405 AdapterFolder *adapter = ADAPTER_FOLDER(obj);
2406 ItemFolder *item = adapter->itemFolder;
2407
2408 if (aval == G_ALERTDEFAULT) {
2409 /* Remove folder only */
2410 item = addrbook_remove_folder(abf, item);
2411 if (item) {
2412 addritem_free_item_folder(item);
2413 addressbook_move_nodes_up(&iter);
2414 remFlag = TRUE;
2415 }
2416 } else if (aval == G_ALERTALTERNATE) {
2417 /* Remove folder and addresses */
2418 item = addrbook_remove_folder_delete(abf, item);
2419 if (item) {
2420 addritem_free_item_folder(item);
2421 addressbook_free_child_adapters(&iter);
2422 remFlag = TRUE;
2423 }
2424 }
2425 } else if (obj->type == ADDR_ITEM_GROUP) {
2426 AdapterGroup *adapter = ADAPTER_GROUP(obj);
2427 ItemGroup *item = adapter->itemGroup;
2428
2429 item = addrbook_remove_group(abf, item);
2430 if (item) {
2431 addritem_free_item_group(item);
2432 remFlag = TRUE;
2433 }
2434 }
2435
2436 if (remFlag) {
2437 /* Free up adapter and remove node. */
2438 addressbook_free_adapter(&iter);
2439 gtk_tree_model_iter_parent(model, &parent, &iter);
2440 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2441 gtk_tree_selection_select_iter(selection, &parent);
2442 }
2443 }
2444
addressbook_new_address_cb(gpointer data,guint action,GtkWidget * widget)2445 static void addressbook_new_address_cb(gpointer data, guint action, GtkWidget *widget)
2446 {
2447 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2448 GtkTreeSelection *selection;
2449 GtkTreeModel *model;
2450 GtkTreeIter iter;
2451 AddressObject *pobj = NULL;
2452 AddressDataSource *ds = NULL;
2453 AddressBookFile *abf = NULL;
2454
2455 selection = gtk_tree_view_get_selection(treeview);
2456 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2457 return;
2458
2459 gtk_tree_model_get(model, &iter, COL_OBJ, &pobj, -1);
2460 if (pobj == NULL)
2461 return;
2462 ds = addressbook_find_datasource(&iter);
2463 if (ds == NULL)
2464 return;
2465
2466 abf = ds->rawDataSource;
2467 if (abf == NULL)
2468 return;
2469
2470 if (pobj->type == ADDR_DATASOURCE) {
2471 if (ADAPTER_DSOURCE(pobj)->subType == ADDR_BOOK) {
2472 /* New address */
2473 ItemPerson *person = addressbook_edit_person(abf, NULL, NULL, FALSE);
2474 if (person) {
2475 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened)) {
2476 addressbook_reopen();
2477 }
2478 addressbook_modified();
2479 }
2480 }
2481 }
2482 else if( pobj->type == ADDR_ITEM_FOLDER ) {
2483 /* New address */
2484 ItemFolder *folder = ADAPTER_FOLDER(pobj)->itemFolder;
2485 ItemPerson *person = addressbook_edit_person(abf, folder, NULL, FALSE);
2486 if (person) {
2487 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened)) {
2488 addressbook_reopen();
2489 }
2490 addressbook_modified();
2491 }
2492 }
2493 else if( pobj->type == ADDR_ITEM_GROUP ) {
2494 /* New address in group */
2495 ItemGroup *group = ADAPTER_GROUP(pobj)->itemGroup;
2496
2497 if (addressbook_edit_group(abf, NULL, group) == NULL)
2498 return;
2499 if (gtkut_tree_row_reference_equal
2500 (addrbook.tree_selected, addrbook.tree_opened)) {
2501 /* Change node name in tree. */
2502 addressbook_change_node_name(&iter, ADDRITEM_NAME(group));
2503 addressbook_reopen();
2504 }
2505 }
2506 }
2507
addressbook_compose_to_cb(gpointer data,guint action,GtkWidget * widget)2508 static void addressbook_compose_to_cb(gpointer data, guint action, GtkWidget *widget)
2509 {
2510 addressbook_to_clicked(NULL, GINT_TO_POINTER(action));
2511 }
2512
2513 /*
2514 * Search for specified group in address index tree.
2515 */
addressbook_find_group_node(GtkTreeIter * parent,GtkTreeIter * iter,ItemGroup * group)2516 static gboolean addressbook_find_group_node(GtkTreeIter *parent, GtkTreeIter *iter, ItemGroup *group)
2517 {
2518 GtkTreeModel *model;
2519 GtkTreeIter iter_;
2520 gboolean valid = TRUE;
2521
2522 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
2523 valid = gtk_tree_model_iter_children(model, &iter_, parent);
2524 while (valid) {
2525 AddressObject *obj = NULL;
2526
2527 gtk_tree_model_get(model, &iter_, COL_OBJ, &obj, -1);
2528 if (obj && obj->type == ADDR_ITEM_GROUP) {
2529 ItemGroup *g = ADAPTER_GROUP(obj)->itemGroup;
2530 if (g == group) {
2531 *iter = iter_;
2532 return TRUE;
2533 }
2534 }
2535 valid = gtk_tree_model_iter_next(model, &iter_);
2536 }
2537
2538 return FALSE;
2539 }
2540
addressbook_get_book_file(void)2541 static AddressBookFile *addressbook_get_book_file(void)
2542 {
2543 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2544 GtkTreeSelection *selection;
2545 GtkTreeIter iter;
2546 AddressBookFile *abf = NULL;
2547 AddressDataSource *ds = NULL;
2548
2549 selection = gtk_tree_view_get_selection(treeview);
2550 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
2551 return NULL;
2552 ds = addressbook_find_datasource(&iter);
2553 if (ds == NULL)
2554 return NULL;
2555 if (ds->type == ADDR_IF_BOOK)
2556 abf = ds->rawDataSource;
2557 return abf;
2558 }
2559
addressbook_tree_remove_children(GtkTreeModel * model,GtkTreeIter * parent)2560 static void addressbook_tree_remove_children(GtkTreeModel *model,
2561 GtkTreeIter *parent)
2562 {
2563 GtkTreeIter iter;
2564
2565 /* Remove existing folders and groups */
2566 while (gtk_tree_model_iter_children(model, &iter, parent)) {
2567 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2568 }
2569 }
2570
addressbook_move_nodes_recursive(GtkTreeIter * iter,GtkTreeIter * parent)2571 static void addressbook_move_nodes_recursive(GtkTreeIter *iter,
2572 GtkTreeIter *parent)
2573 {
2574 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2575 GtkTreeModel *model;
2576 GtkTreeIter child, new_iter;
2577 gboolean valid;
2578
2579 model = gtk_tree_view_get_model(treeview);
2580
2581 valid = gtk_tree_model_iter_children(model, &child, iter);
2582 while (valid) {
2583 gchar *name = NULL;
2584 AddressObject *obj = NULL;
2585 GdkPixbuf *pixbuf = NULL;
2586 GdkPixbuf *pixbuf_open = NULL;
2587
2588 gtk_tree_model_get(model, &child, COL_FOLDER_NAME, &name,
2589 COL_OBJ, &obj, COL_PIXBUF, &pixbuf,
2590 COL_PIXBUF_OPEN, &pixbuf_open, -1);
2591 gtk_tree_store_append(GTK_TREE_STORE(model), &new_iter, parent);
2592 gtk_tree_store_set(GTK_TREE_STORE(model), &new_iter,
2593 COL_FOLDER_NAME, name,
2594 COL_OBJ, obj,
2595 COL_PIXBUF, pixbuf,
2596 COL_PIXBUF_OPEN, pixbuf_open, -1);
2597 g_free(name);
2598 addressbook_move_nodes_recursive(&child, &new_iter);
2599 valid = gtk_tree_model_iter_next(model, &child);
2600 }
2601 }
2602
addressbook_move_nodes_up(GtkTreeIter * iter)2603 static void addressbook_move_nodes_up(GtkTreeIter *iter)
2604 {
2605 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2606 GtkTreeModel *model;
2607 GtkTreeIter parent;
2608
2609 model = gtk_tree_view_get_model(treeview);
2610 if (!gtk_tree_model_iter_parent(model, &parent, iter))
2611 return;
2612
2613 addressbook_move_nodes_recursive(iter, &parent);
2614 }
2615
addressbook_edit_address_cb(gpointer data,guint action,GtkWidget * widget)2616 static void addressbook_edit_address_cb(gpointer data, guint action, GtkWidget *widget)
2617 {
2618 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2619 GtkTreeSelection *selection;
2620 GtkTreeModel *model;
2621 GtkTreeIter liter, iter, node, parent;
2622 gboolean node_found;
2623 gboolean parent_found = FALSE;
2624 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
2625 GtkTreeModel *lmodel;
2626 AddressObject *obj = NULL, *pobj = NULL;
2627 AddressDataSource *ds = NULL;
2628 gchar *name = NULL;
2629 AddressBookFile *abf = NULL;
2630
2631 if (addrbook.list_selected == NULL)
2632 return;
2633
2634 lmodel = gtk_tree_view_get_model(listview);
2635 if (!gtkut_tree_row_reference_get_iter(lmodel, addrbook.list_selected,
2636 &liter))
2637 return;
2638 gtk_tree_model_get(lmodel, &liter, COL_L_OBJ, &obj, -1);
2639 g_return_if_fail(obj != NULL);
2640
2641 selection = gtk_tree_view_get_selection(treeview);
2642 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2643 return;
2644 gtk_tree_model_get(model, &iter, COL_OBJ, &pobj, -1);
2645 node_found = gtkut_tree_model_find_by_column_data
2646 (model, &node, &iter, COL_OBJ, obj);
2647
2648 ds = addressbook_find_datasource(&iter);
2649 if (ds == NULL)
2650 return;
2651
2652 abf = addressbook_get_book_file();
2653 if (abf == NULL)
2654 return;
2655
2656 if (obj->type == ADDR_ITEM_EMAIL) {
2657 ItemEMail *email = (ItemEMail *)obj;
2658 ItemPerson *person;
2659
2660 if (email == NULL)
2661 return;
2662 if (pobj && pobj->type == ADDR_ITEM_GROUP) {
2663 /* Edit parent group */
2664 AdapterGroup *adapter = ADAPTER_GROUP(pobj);
2665 ItemGroup *itemGrp = adapter->itemGroup;
2666
2667 if (addressbook_edit_group(abf, NULL, itemGrp) == NULL)
2668 return;
2669 name = ADDRITEM_NAME(itemGrp);
2670 node = iter;
2671 node_found = TRUE;
2672 parent_found = gtk_tree_model_iter_parent(model, &parent, &node);
2673 } else {
2674 /* Edit person - email page */
2675 person = (ItemPerson *)ADDRITEM_PARENT(email);
2676 if (addressbook_edit_person(abf, NULL, person, TRUE) == NULL)
2677 return;
2678 addressbook_reopen();
2679 addressbook_modified();
2680 return;
2681 }
2682 } else if (obj->type == ADDR_ITEM_PERSON) {
2683 /* Edit person - basic page */
2684 ItemPerson *person = (ItemPerson *)obj;
2685
2686 if (addressbook_edit_person(abf, NULL, person, FALSE) == NULL)
2687 return;
2688 addressbook_reopen();
2689 addressbook_modified();
2690 return;
2691 } else if (obj->type == ADDR_ITEM_GROUP) {
2692 ItemGroup *itemGrp = (ItemGroup *)obj;
2693
2694 if (addressbook_edit_group(abf, NULL, itemGrp) == NULL)
2695 return;
2696 parent = iter;
2697 parent_found = TRUE;
2698 node_found = addressbook_find_group_node(&parent, &node, itemGrp);
2699 name = ADDRITEM_NAME(itemGrp);
2700 } else {
2701 return;
2702 }
2703
2704 /* Update tree node with node name */
2705 if (node_found) {
2706 addressbook_change_node_name(&node, name);
2707 addressbook_reopen();
2708 }
2709 }
2710
addressbook_delete_address_cb(gpointer data,guint action,GtkWidget * widget)2711 static void addressbook_delete_address_cb(gpointer data, guint action,
2712 GtkWidget *widget)
2713 {
2714 addressbook_del_clicked(NULL, NULL);
2715 }
2716
addressbook_copy_address_cb(gpointer data,guint action,GtkWidget * widget)2717 static void addressbook_copy_address_cb(gpointer data, guint action,
2718 GtkWidget *widget)
2719 {
2720 AddressObject *obj;
2721 GList *node;
2722
2723 if (_addressListSelection_ == NULL)
2724 return;
2725
2726 g_list_free(_clipObjectList_);
2727 _clipObjectList_ = NULL;
2728
2729 node = _addressListSelection_;
2730 while (node) {
2731 obj = node->data;
2732 if (obj->type == ADDR_ITEM_PERSON) {
2733 _clipObjectList_ = g_list_append(_clipObjectList_, obj);
2734 }
2735 node = g_list_next(node);
2736 }
2737
2738 addressbook_menuitem_set_sensitive();
2739 }
2740
addressbook_paste_address_cb(gpointer data,guint action,GtkWidget * widget)2741 static void addressbook_paste_address_cb(gpointer data, guint action,
2742 GtkWidget *widget)
2743 {
2744 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
2745 GtkTreeSelection *selection;
2746 GtkTreeModel *model;
2747 GtkTreeIter iter;
2748 AddressObject *obj = NULL, *pobj = NULL;
2749 AddressDataSource *ds = NULL;
2750 AddressBookFile *abf = NULL;
2751 ItemFolder *folder = NULL;
2752 ItemPerson *clipPerson, *person;
2753 GList *cur;
2754 GList *node;
2755
2756 if (!_clipObjectList_)
2757 return;
2758
2759 selection = gtk_tree_view_get_selection(treeview);
2760 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2761 return;
2762 gtk_tree_model_get(model, &iter, COL_OBJ, &pobj, -1);
2763 if (pobj->type == ADDR_ITEM_FOLDER)
2764 folder = ADAPTER_FOLDER(pobj)->itemFolder;
2765 else if (pobj->type == ADDR_DATASOURCE)
2766 folder = NULL;
2767 else
2768 return;
2769
2770 ds = addressbook_find_datasource(&iter);
2771 if (ds == NULL)
2772 return;
2773
2774 abf = ds->rawDataSource;
2775 if (abf == NULL)
2776 return;
2777
2778 node = _clipObjectList_;
2779 while (node) {
2780 obj = node->data;
2781 node = g_list_next(node);
2782 if (obj->type != ADDR_ITEM_PERSON)
2783 continue;
2784 clipPerson = (ItemPerson *)obj;
2785
2786 person = addrbook_add_address_list(abf, folder, NULL);
2787 ADDRITEM_NAME(person) = g_strdup(ADDRITEM_NAME(clipPerson));
2788 person->firstName = g_strdup(clipPerson->firstName);
2789 person->lastName = g_strdup(clipPerson->lastName);
2790 person->nickName = g_strdup(clipPerson->nickName);
2791 for (cur = clipPerson->listEMail; cur != NULL; cur = cur->next) {
2792 ItemEMail *email = cur->data;
2793 addritem_person_add_email(person, addritem_copy_item_email(email));
2794 }
2795 for (cur = clipPerson->listAttrib; cur != NULL; cur = cur->next) {
2796 UserAttribute *attr = cur->data;
2797 addritem_person_add_attribute(person, addritem_copy_attribute(attr));
2798 }
2799 }
2800
2801 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened))
2802 addressbook_reopen();
2803 addressbook_modified();
2804 }
2805
close_cb(gpointer data,guint action,GtkWidget * widget)2806 static void close_cb(gpointer data, guint action, GtkWidget *widget)
2807 {
2808 addressbook_close();
2809 }
2810
addressbook_file_save_cb(gpointer data,guint action,GtkWidget * widget)2811 static void addressbook_file_save_cb(gpointer data, guint action, GtkWidget *widget)
2812 {
2813 addressbook_export_to_file();
2814 }
2815
addressbook_person_expand_node(GtkTreeView * treeview,GtkTreeIter * iter,GtkTreePath * path,gpointer * data)2816 static void addressbook_person_expand_node(GtkTreeView *treeview,
2817 GtkTreeIter *iter, GtkTreePath *path,
2818 gpointer *data)
2819 {
2820 GtkTreeModel *model;
2821 ItemPerson *person = NULL;
2822
2823 model = gtk_tree_view_get_model(treeview);
2824 gtk_tree_model_get(model, iter, COL_L_OBJ, &person, -1);
2825 if (person)
2826 addritem_person_set_opened(person, TRUE);
2827 }
2828
addressbook_person_collapse_node(GtkTreeView * treeview,GtkTreeIter * iter,GtkTreePath * path,gpointer * data)2829 static void addressbook_person_collapse_node(GtkTreeView *treeview,
2830 GtkTreeIter *iter,
2831 GtkTreePath *path, gpointer *data)
2832 {
2833 GtkTreeModel *model;
2834 ItemPerson *person = NULL;
2835
2836 model = gtk_tree_view_get_model(treeview);
2837 gtk_tree_model_get(model, iter, COL_L_OBJ, &person, -1);
2838 if (person)
2839 addritem_person_set_opened(person, FALSE);
2840 }
2841
addressbook_drag_begin(GtkWidget * widget,GdkDragContext * drag_context,gpointer data)2842 static void addressbook_drag_begin(GtkWidget *widget,
2843 GdkDragContext *drag_context, gpointer data)
2844 {
2845 list_on_drag = TRUE;
2846 /* gtk_drag_set_icon_default(drag_context); */
2847 }
2848
addressbook_drag_end(GtkWidget * widget,GdkDragContext * drag_context,gpointer data)2849 static void addressbook_drag_end(GtkWidget *widget,
2850 GdkDragContext *drag_context, gpointer data)
2851 {
2852 }
2853
addressbook_drag_data_get(GtkWidget * widget,GdkDragContext * drag_context,GtkSelectionData * selection_data,guint info,guint time,gpointer data)2854 static void addressbook_drag_data_get(GtkWidget *widget,
2855 GdkDragContext *drag_context,
2856 GtkSelectionData *selection_data,
2857 guint info, guint time, gpointer data)
2858 {
2859 if (info == DRAG_TYPE_OBJ) {
2860 gtk_selection_data_set(selection_data, selection_data->target,
2861 8, (guchar *)"drag-from-list", 14);
2862 }
2863 }
2864
addressbook_format_item_list(ItemPerson * person,ItemEMail * email)2865 static gchar *addressbook_format_item_list(ItemPerson *person, ItemEMail *email)
2866 {
2867 gchar *str = NULL;
2868 gchar *eMailAlias = ADDRITEM_NAME(email);
2869
2870 if (eMailAlias && *eMailAlias != '\0') {
2871 if (person) {
2872 str = g_strdup_printf("%s - %s", ADDRITEM_NAME(person), eMailAlias);
2873 } else {
2874 str = g_strdup(eMailAlias);
2875 }
2876 }
2877 return str;
2878 }
2879
addressbook_match_item(const gchar * name,const gchar * email_alias,const gchar * addr,const gchar * remarks,const gchar * str)2880 static gboolean addressbook_match_item(const gchar *name,
2881 const gchar *email_alias,
2882 const gchar *addr,
2883 const gchar *remarks,
2884 const gchar *str)
2885 {
2886 if (!name)
2887 return FALSE;
2888 if (!str || str[0] == '\0')
2889 return TRUE;
2890 if (strcasestr(name, str))
2891 return TRUE;
2892 else if (email_alias && strcasestr(email_alias, str))
2893 return TRUE;
2894 else if (addr && strcasestr(addr, str))
2895 return TRUE;
2896 else if (remarks && strcasestr(remarks, str))
2897 return TRUE;
2898
2899 return FALSE;
2900 }
2901
addressbook_load_group(ItemGroup * itemGroup)2902 static void addressbook_load_group(ItemGroup *itemGroup)
2903 {
2904 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
2905 GtkTreeModel *model;
2906 GtkTreeIter iter;
2907 GList *items = itemGroup->listEMail;
2908 AddressTypeControlItem *atci = addrbookctl_lookup(ADDR_ITEM_EMAIL);
2909 const gchar *search_str;
2910
2911 model = gtk_tree_view_get_model(listview);
2912 search_str = gtk_entry_get_text(GTK_ENTRY(addrbook.entry));
2913
2914 for (; items != NULL; items = g_list_next(items)) {
2915 ItemEMail *email = items->data;
2916 ItemPerson *person;
2917 const gchar *name;
2918 gchar *str;
2919
2920 if (!email) continue;
2921
2922 person = (ItemPerson *)ADDRITEM_PARENT(email);
2923 if (!person) {
2924 g_warning("email %p (%s) don't have parent\n", email, email->address);
2925 continue;
2926 }
2927 if (!addressbook_match_item(ADDRITEM_NAME(person),
2928 ADDRITEM_NAME(email),
2929 email->address, email->remarks,
2930 search_str))
2931 continue;
2932
2933 str = addressbook_format_item_list(person, email);
2934 if (str) {
2935 name = str;
2936 } else {
2937 name = ADDRITEM_NAME(person);
2938 }
2939 gtk_tree_store_append(GTK_TREE_STORE(model), &iter, NULL);
2940 gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
2941 COL_NAME, name,
2942 COL_ADDRESS, email->address ? email->address : "",
2943 COL_NICKNAME, person->nickName ? person->nickName : "",
2944 COL_REMARKS, email->remarks ? email->remarks : "",
2945 COL_L_OBJ, email,
2946 COL_L_PIXBUF, atci->icon_pixbuf,
2947 -1);
2948 g_free(str);
2949 }
2950 }
2951
addressbook_folder_load_person(ItemFolder * itemFolder)2952 static void addressbook_folder_load_person(ItemFolder *itemFolder)
2953 {
2954 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
2955 GtkTreeModel *model;
2956 GList *items;
2957 AddressTypeControlItem *atci = addrbookctl_lookup(ADDR_ITEM_PERSON);
2958 AddressTypeControlItem *atciMail = addrbookctl_lookup(ADDR_ITEM_EMAIL);
2959 const gchar *search_str;
2960
2961 if (atci == NULL)
2962 return;
2963 if (atciMail == NULL)
2964 return;
2965
2966 model = gtk_tree_view_get_model(listview);
2967 search_str = gtk_entry_get_text(GTK_ENTRY(addrbook.entry));
2968
2969 /* Load email addresses */
2970 items = addritem_folder_get_person_list(itemFolder);
2971 for (; items != NULL; items = g_list_next(items)) {
2972 GtkTreeIter iperson, iemail;
2973 gboolean flgFirst = TRUE, haveAddr = FALSE;
2974 ItemPerson *person;
2975 ItemEMail *email;
2976 GList *node;
2977
2978 person = (ItemPerson *)items->data;
2979 if (!person)
2980 continue;
2981
2982 node = person->listEMail;
2983 if (node && node->data) {
2984 email = node->data;
2985 if (!addressbook_match_item(ADDRITEM_NAME(person), ADDRITEM_NAME(email), email->address, email->remarks, search_str))
2986 continue;
2987 } else {
2988 if (!addressbook_match_item(ADDRITEM_NAME(person), NULL, NULL, NULL, search_str))
2989 continue;
2990 }
2991
2992 while (node) {
2993 const gchar *name;
2994
2995 email = node->data;
2996 node = g_list_next(node);
2997
2998 if (flgFirst) {
2999 /* First email belongs with person */
3000 gchar *str = addressbook_format_item_list(person, email);
3001 if (str) {
3002 name = str;
3003 } else {
3004 name = ADDRITEM_NAME(person);
3005 }
3006
3007 gtk_tree_store_append(GTK_TREE_STORE(model),
3008 &iperson, NULL);
3009 gtk_tree_store_set(GTK_TREE_STORE(model),
3010 &iperson,
3011 COL_NAME, name,
3012 COL_ADDRESS, email->address ? email->address : "",
3013 COL_NICKNAME, person->nickName ? person->nickName : "",
3014 COL_REMARKS, email->remarks ? email->remarks : "",
3015 COL_L_OBJ, person,
3016 COL_L_PIXBUF, atci->icon_pixbuf,
3017 -1);
3018 g_free(str);
3019 } else {
3020 /* Subsequent email is a child node of person */
3021 name = ADDRITEM_NAME(email);
3022 gtk_tree_store_append(GTK_TREE_STORE(model),
3023 &iemail, &iperson);
3024 gtk_tree_store_set(GTK_TREE_STORE(model),
3025 &iemail,
3026 COL_NAME, name,
3027 COL_ADDRESS, email->address ? email->address : "",
3028 COL_NICKNAME, "",
3029 COL_REMARKS, email->remarks ? email->remarks : "",
3030 COL_L_OBJ, email,
3031 COL_L_PIXBUF, atciMail->icon_pixbuf,
3032 -1);
3033 }
3034 flgFirst = FALSE;
3035 haveAddr = TRUE;
3036 }
3037 if (!haveAddr) {
3038 /* Have name without EMail */
3039 gtk_tree_store_append(GTK_TREE_STORE(model),
3040 &iperson, NULL);
3041 gtk_tree_store_set(GTK_TREE_STORE(model),
3042 &iperson,
3043 COL_NAME, ADDRITEM_NAME(person),
3044 COL_ADDRESS, "",
3045 COL_NICKNAME, person->nickName ? person->nickName : "",
3046 COL_REMARKS, "",
3047 COL_L_OBJ, person,
3048 COL_L_PIXBUF, atci->icon_pixbuf,
3049 -1);
3050 }
3051 if (person->isOpened) {
3052 GtkTreePath *path;
3053 path = gtk_tree_model_get_path(model, &iperson);
3054 gtk_tree_view_expand_row(listview, path, TRUE);
3055 gtk_tree_path_free(path);
3056 }
3057 }
3058
3059 /* Free up the list */
3060 mgu_clear_list(items);
3061 g_list_free(items);
3062 }
3063
addressbook_folder_load_group(ItemFolder * itemFolder)3064 static void addressbook_folder_load_group(ItemFolder *itemFolder)
3065 {
3066 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
3067 GtkTreeModel *model;
3068 GList *items;
3069 AddressTypeControlItem *atci = addrbookctl_lookup(ADDR_ITEM_GROUP);
3070 const gchar *search_str;
3071
3072 if (!atci)
3073 return;
3074
3075 model = gtk_tree_view_get_model(listview);
3076 search_str = gtk_entry_get_text(GTK_ENTRY(addrbook.entry));
3077
3078 /* Load any groups */
3079 items = addritem_folder_get_group_list(itemFolder);
3080 for (; items != NULL; items = g_list_next(items)) {
3081 GtkTreeIter iter;
3082 ItemGroup *group = items->data;
3083
3084 if (!group)
3085 continue;
3086 if (!addressbook_match_item(ADDRITEM_NAME(group),
3087 NULL, NULL, NULL, search_str))
3088 continue;
3089
3090 gtk_tree_store_append(GTK_TREE_STORE(model), &iter, NULL);
3091 gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
3092 COL_NAME, ADDRITEM_NAME(group),
3093 COL_ADDRESS, "",
3094 COL_NICKNAME, "",
3095 COL_REMARKS, "",
3096 COL_L_OBJ, group,
3097 COL_L_PIXBUF, atci->icon_pixbuf,
3098 -1);
3099 }
3100
3101 /* Free up the list */
3102 mgu_clear_list(items);
3103 g_list_free(items);
3104 }
3105
addressbook_find_datasource(GtkTreeIter * iter)3106 static AddressDataSource *addressbook_find_datasource(GtkTreeIter *iter)
3107 {
3108 GtkTreeModel *model;
3109 GtkTreeIter iter_, parent;
3110 AddressDataSource *ds = NULL;
3111 AddressObject *ao;
3112
3113 g_return_val_if_fail(addrbook.treeview != NULL, NULL);
3114
3115 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
3116 parent = *iter;
3117
3118 do {
3119 iter_ = parent;
3120 if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), &iter_) < 1)
3121 return NULL;
3122 ao = NULL;
3123 gtk_tree_model_get(model, &iter_, COL_OBJ, &ao, -1);
3124 if (ao) {
3125 /* g_print("ao->type = %d\n", ao->type); */
3126 if (ao->type == ADDR_DATASOURCE) {
3127 AdapterDSource *ads = ADAPTER_DSOURCE(ao);
3128 /* g_print("found it\n"); */
3129 ds = ads->dataSource;
3130 break;
3131 }
3132 }
3133 } while (gtk_tree_model_iter_parent(model, &parent, &iter_));
3134
3135 return ds;
3136 }
3137
3138 /*
3139 * Load address list widget with children of specified object.
3140 * Enter: obj Parent object to be loaded.
3141 */
addressbook_set_list(AddressObject * obj)3142 static void addressbook_set_list(AddressObject *obj)
3143 {
3144 GtkTreeView *listview = GTK_TREE_VIEW(addrbook.listview);
3145 GtkTreeModel *model;
3146 AddressDataSource *ds = NULL;
3147 AdapterDSource *ads = NULL;
3148 gboolean sorted;
3149 gint address_list_sort_id = COL_NAME;
3150 GtkSortType order = GTK_SORT_ASCENDING;
3151
3152 debug_print("addressbook_set_list\n");
3153
3154 model = gtk_tree_view_get_model(listview);
3155
3156 if (obj == NULL) {
3157 gtk_tree_store_clear(GTK_TREE_STORE(model));
3158 return;
3159 }
3160
3161 if (obj->type == ADDR_INTERFACE) {
3162 return;
3163 }
3164
3165 gtk_tree_store_clear(GTK_TREE_STORE(model));
3166 sorted = gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(model),
3167 &address_list_sort_id,
3168 &order);
3169 if (!sorted) {
3170 address_list_sort_id = COL_NAME;
3171 order = GTK_SORT_ASCENDING;
3172 }
3173 gtkut_tree_sortable_unset_sort_column_id(GTK_TREE_SORTABLE(model));
3174
3175 if (obj->type == ADDR_DATASOURCE) {
3176 ads = ADAPTER_DSOURCE(obj);
3177 ds = ADAPTER_DSOURCE(obj)->dataSource;
3178 if (ds) {
3179 /* Load root folder */
3180 ItemFolder *rootFolder = NULL;
3181 rootFolder = addrindex_ds_get_root_folder(ds);
3182 addressbook_folder_load_person(addrindex_ds_get_root_folder(ds));
3183 addressbook_folder_load_group(addrindex_ds_get_root_folder(ds));
3184 }
3185 } else if (obj->type == ADDR_ITEM_GROUP) {
3186 /* Load groups */
3187 ItemGroup *itemGroup = ADAPTER_GROUP(obj)->itemGroup;
3188 addressbook_load_group(itemGroup);
3189 } else if (obj->type == ADDR_ITEM_FOLDER) {
3190 /* Load folders */
3191 ItemFolder *itemFolder = ADAPTER_FOLDER(obj)->itemFolder;
3192 addressbook_folder_load_person(itemFolder);
3193 addressbook_folder_load_group(itemFolder);
3194 }
3195
3196 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
3197 address_list_sort_id, order);
3198 }
3199
3200 /*
3201 * Free adaptor for specified node.
3202 */
addressbook_free_adapter(GtkTreeIter * iter)3203 static void addressbook_free_adapter(GtkTreeIter *iter)
3204 {
3205 GtkTreeModel *model;
3206 AddressObject *ao = NULL;
3207
3208 g_return_if_fail(addrbook.treeview != NULL);
3209 g_return_if_fail(iter != NULL);
3210
3211 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
3212 if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), iter) < 1)
3213 return;
3214 gtk_tree_model_get(model, iter, COL_OBJ, &ao, -1);
3215 if (ao == NULL)
3216 return;
3217
3218 if (ao->type == ADDR_INTERFACE) {
3219 AdapterInterface *ai = ADAPTER_INTERFACE(ao);
3220 addrbookctl_free_interface(ai);
3221 } else if (ao->type == ADDR_DATASOURCE) {
3222 AdapterDSource *ads = ADAPTER_DSOURCE(ao);
3223 addrbookctl_free_datasource(ads);
3224 } else if (ao->type == ADDR_ITEM_FOLDER) {
3225 AdapterFolder *af = ADAPTER_FOLDER(ao);
3226 addrbookctl_free_folder(af);
3227 } else if (ao->type == ADDR_ITEM_GROUP) {
3228 AdapterGroup *ag = ADAPTER_GROUP(ao);
3229 addrbookctl_free_group(ag);
3230 }
3231
3232 gtk_tree_store_set(GTK_TREE_STORE(model), iter, COL_OBJ, NULL, -1);
3233 }
3234
3235 /*
3236 * Free all children adapters.
3237 */
addressbook_free_child_adapters(GtkTreeIter * iter)3238 static void addressbook_free_child_adapters(GtkTreeIter *iter)
3239 {
3240 GtkTreeModel *model;
3241 GtkTreeIter child;
3242 gboolean valid;
3243
3244 g_return_if_fail(iter != NULL);
3245
3246 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
3247 valid = gtk_tree_model_iter_children(model, &child, iter);
3248 while (valid) {
3249 addressbook_free_child_adapters(&child);
3250 addressbook_free_adapter(&child);
3251 valid = gtk_tree_model_iter_next(model, &child);
3252 }
3253 }
3254
addressbook_create_ds_adapter(AddressDataSource * ds,AddressObjectType otype,gchar * name)3255 AdapterDSource *addressbook_create_ds_adapter(AddressDataSource *ds,
3256 AddressObjectType otype,
3257 gchar *name)
3258 {
3259 AdapterDSource *adapter = g_new0(AdapterDSource, 1);
3260 ADDRESS_OBJECT(adapter)->type = ADDR_DATASOURCE;
3261 ADDRESS_OBJECT_NAME(adapter) = g_strdup(name);
3262 adapter->dataSource = ds;
3263 adapter->subType = otype;
3264 return adapter;
3265 }
3266
addressbook_ads_set_name(AdapterDSource * adapter,gchar * value)3267 void addressbook_ads_set_name(AdapterDSource *adapter, gchar *value)
3268 {
3269 ADDRESS_OBJECT_NAME(adapter) =
3270 mgu_replace_string(ADDRESS_OBJECT_NAME(adapter), value);
3271 }
3272
3273 /*
3274 * Load tree from address index with the initial data.
3275 */
addressbook_load_tree(void)3276 static void addressbook_load_tree(void)
3277 {
3278 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
3279 GtkTreeModel *model;
3280 GtkTreeIter iter, new_iter;
3281 GtkTreePath *path;
3282 GList *nodeIf, *nodeDS;
3283 AdapterInterface *adapter;
3284 AddressInterface *iface;
3285 AddressTypeControlItem *atci;
3286 AddressDataSource *ds;
3287 AdapterDSource *ads;
3288 gchar *name;
3289
3290 model = gtk_tree_view_get_model(treeview);
3291
3292 nodeIf = _addressInterfaceList_;
3293 while (nodeIf) {
3294 adapter = nodeIf->data;
3295 gtkut_tree_row_reference_get_iter(model, adapter->tree_row, &iter);
3296 iface = adapter->iface;
3297 atci = adapter->atci;
3298 if (iface) {
3299 if (iface->useInterface) {
3300 /* Load data sources below interface node */
3301 nodeDS = iface->listSource;
3302 while (nodeDS) {
3303 ds = nodeDS->data;
3304 name = addrindex_ds_get_name(ds);
3305 ads = addressbook_create_ds_adapter(ds, atci->objectType, name);
3306 addressbook_add_object(&iter, &new_iter, ADDRESS_OBJECT(ads));
3307 nodeDS = g_list_next( nodeDS );
3308 }
3309 path = gtk_tree_model_get_path(model, &iter);
3310 gtk_tree_view_expand_row(treeview, path, TRUE);
3311 gtk_tree_path_free(path);
3312 }
3313 }
3314 nodeIf = g_list_next(nodeIf);
3315 }
3316 }
3317
3318 /*
3319 * Convert the old address book to new format.
3320 */
addressbook_convert(AddressIndex * addrIndex)3321 static gboolean addressbook_convert(AddressIndex *addrIndex)
3322 {
3323 gboolean retVal = FALSE;
3324 gboolean errFlag = TRUE;
3325 gchar *msg = NULL;
3326
3327 /* Read old address book, performing conversion */
3328 debug_print( "Reading and converting old address book...\n" );
3329 addrindex_set_file_name( addrIndex, ADDRESSBOOK_OLD_FILE );
3330 addrindex_read_data( addrIndex );
3331 if( addrIndex->retVal == MGU_NO_FILE ) {
3332 /* We do not have a file - new user */
3333 debug_print( "New user... create new books...\n" );
3334 addrindex_create_new_books( addrIndex );
3335 if( addrIndex->retVal == MGU_SUCCESS ) {
3336 /* Save index file */
3337 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3338 addrindex_save_data( addrIndex );
3339 if( addrIndex->retVal == MGU_SUCCESS ) {
3340 retVal = TRUE;
3341 errFlag = FALSE;
3342 }
3343 else {
3344 msg = _( "New user, could not save index file." );
3345 }
3346 }
3347 else {
3348 msg = _( "New user, could not save address book files." );
3349 }
3350 }
3351 else {
3352 /* We have an old file */
3353 if( addrIndex->wasConverted ) {
3354 /* Converted successfully - save address index */
3355 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3356 addrindex_save_data( addrIndex );
3357 if( addrIndex->retVal == MGU_SUCCESS ) {
3358 msg = _( "Old address book converted successfully." );
3359 retVal = TRUE;
3360 errFlag = FALSE;
3361 }
3362 else {
3363 msg = _("Old address book converted,\n"
3364 "could not save new address index file" );
3365 }
3366 }
3367 else {
3368 /* File conversion failed - just create new books */
3369 debug_print( "File conversion failed... just create new books...\n" );
3370 addrindex_create_new_books( addrIndex );
3371 if( addrIndex->retVal == MGU_SUCCESS ) {
3372 /* Save index */
3373 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3374 addrindex_save_data( addrIndex );
3375 if( addrIndex->retVal == MGU_SUCCESS ) {
3376 msg = _("Could not convert address book,\n"
3377 "but created empty new address book files." );
3378 retVal = TRUE;
3379 errFlag = FALSE;
3380 }
3381 else {
3382 msg = _("Could not convert address book,\n"
3383 "could not create new address book files." );
3384 }
3385 }
3386 else {
3387 msg = _("Could not convert address book\n"
3388 "and could not create new address book files." );
3389 }
3390 }
3391 }
3392 if( errFlag ) {
3393 debug_print( "Error\n%s\n", msg );
3394 alertpanel( _( "Address book conversion error" ), msg, GTK_STOCK_CLOSE, NULL, NULL );
3395 }
3396 else if( msg ) {
3397 debug_print( "Warning\n%s\n", msg );
3398 alertpanel( _( "Address book conversion" ), msg, GTK_STOCK_CLOSE, NULL, NULL );
3399 }
3400
3401 return retVal;
3402 }
3403
addressbook_read_file(void)3404 void addressbook_read_file(void)
3405 {
3406 AddressIndex *addrIndex = NULL;
3407
3408 debug_print( "Reading address index...\n" );
3409 if (_addressIndex_) {
3410 debug_print("address book already read!\n");
3411 return;
3412 }
3413
3414 addrIndex = addrindex_create_index();
3415
3416 /* Use new address book index. */
3417 addrindex_set_file_path(addrIndex, get_rc_dir());
3418 addrindex_set_file_name(addrIndex, ADDRESSBOOK_INDEX_FILE);
3419 addrindex_read_data(addrIndex);
3420 if (addrIndex->retVal == MGU_NO_FILE) {
3421 /* Conversion required */
3422 debug_print("Converting...\n");
3423 if (addressbook_convert(addrIndex)) {
3424 addrindex_create_extra_books(addrIndex);
3425 _addressIndex_ = addrIndex;
3426 }
3427 } else if (addrIndex->retVal == MGU_SUCCESS) {
3428 addrindex_create_extra_books(addrIndex);
3429 _addressIndex_ = addrIndex;
3430 } else {
3431 gchar msg[1024];
3432
3433 /* Error reading address book */
3434 debug_print("Could not read address index.\n");
3435 addrindex_print_index(addrIndex, stdout);
3436 g_snprintf(msg, sizeof(msg),
3437 _("Could not read address index:\n\n%s%c%s"),
3438 addrIndex->filePath, G_DIR_SEPARATOR,
3439 addrIndex->fileName);
3440 alertpanel_message(_("Address Book Error"), msg, ALERT_ERROR);
3441 }
3442 debug_print( "done.\n" );
3443 }
3444
3445 #if 0
3446 void addressbook_read_file_old( void ) {
3447 AddressIndex *addrIndex = NULL;
3448 gboolean errFlag = TRUE;
3449 gchar *msg = NULL;
3450
3451 if( _addressIndex_ ) {
3452 debug_print( "address book already read!!!\n" );
3453 return;
3454 }
3455
3456 addrIndex = addrindex_create_index();
3457
3458 /* Use use new address book. */
3459 /* addrindex_set_file_path( addrIndex, "/home/match/tmp/empty-dir" ); */
3460 addrindex_set_file_path( addrIndex, get_rc_dir() );
3461 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3462
3463 debug_print( "Reading address index...\n" );
3464 addrindex_read_data( addrIndex );
3465 if( addrIndex->retVal == MGU_NO_FILE ) {
3466 /* Read old address book, performing conversion */
3467 debug_print( "Reading and converting old address book...\n" );
3468 addrindex_set_file_name( addrIndex, ADDRESSBOOK_OLD_FILE );
3469 addrindex_read_data( addrIndex );
3470 if( addrIndex->retVal == MGU_NO_FILE ) {
3471 /* We do not have a file - new user */
3472 debug_print( "New user... create new books...\n" );
3473 addrindex_create_new_books( addrIndex );
3474 if( addrIndex->retVal == MGU_SUCCESS ) {
3475 /* Save index file */
3476 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3477 addrindex_save_data( addrIndex );
3478 if( addrIndex->retVal == MGU_SUCCESS ) {
3479 errFlag = FALSE;
3480 }
3481 else {
3482 msg = g_strdup( _( "New user, could not save index file." ) );
3483 }
3484 }
3485 else {
3486 msg = g_strdup( _( "New user, could not save address book files." ) );
3487 }
3488 }
3489 else {
3490 /* We have an old file */
3491 if( addrIndex->wasConverted ) {
3492 /* Converted successfully - save address index */
3493 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3494 addrindex_save_data( addrIndex );
3495 if( addrIndex->retVal == MGU_SUCCESS ) {
3496 msg = g_strdup( _( "Old address book converted successfully." ) );
3497 errFlag = FALSE;
3498 }
3499 else {
3500 msg = g_strdup( _(
3501 "Old address book converted, " \
3502 "could not save new address index file" ) );
3503 }
3504 }
3505 else {
3506 /* File conversion failed - just create new books */
3507 debug_print( "File conversion failed... just create new books...\n" );
3508 addrindex_create_new_books( addrIndex );
3509 if( addrIndex->retVal == MGU_SUCCESS ) {
3510 /* Save index */
3511 addrindex_set_file_name( addrIndex, ADDRESSBOOK_INDEX_FILE );
3512 addrindex_save_data( addrIndex );
3513 if( addrIndex->retVal == MGU_SUCCESS ) {
3514 msg = g_strdup( _(
3515 "Could not convert address book, " \
3516 "but created empty new address book files." ) );
3517 errFlag = FALSE;
3518 }
3519 else {
3520 msg = g_strdup( _(
3521 "Could not convert address book, " \
3522 "could not create new address book files." ) );
3523 }
3524 }
3525 else {
3526 msg = g_strdup( _(
3527 "Could not convert address book " \
3528 "and could not create new address book files." ) );
3529 }
3530 }
3531 }
3532 }
3533 else if( addrIndex->retVal == MGU_SUCCESS ) {
3534 errFlag = FALSE;
3535 }
3536 else {
3537 debug_print( "Could not read address index.\n" );
3538 addrindex_print_index( addrIndex, stdout );
3539 msg = g_strdup( _( "Could not read address index" ) );
3540 }
3541 _addressIndex_ = addrIndex;
3542
3543 if( errFlag ) {
3544 debug_print( "Error\n%s\n", msg );
3545 alertpanel( _( "Address Book Conversion Error" ), msg,
3546 GTK_STOCK_CLOSE, NULL, NULL );
3547 }
3548 else {
3549 if( msg ) {
3550 debug_print( "Warning\n%s\n", msg );
3551 alertpanel( _( "Address Book Conversion" ), msg,
3552 GTK_STOCK_CLOSE, NULL, NULL );
3553 }
3554 }
3555 if( msg ) g_free( msg );
3556 debug_print( "done.\n" );
3557 }
3558 #endif
3559
3560 /*
3561 * Add object into the address index tree widget.
3562 * Enter: node Parent node.
3563 * obj Object to add.
3564 * Return: Node that was added, or NULL if object not added.
3565 */
addressbook_add_object(GtkTreeIter * iter,GtkTreeIter * new_iter,AddressObject * obj)3566 static gboolean addressbook_add_object(GtkTreeIter *iter, GtkTreeIter *new_iter,
3567 AddressObject *obj)
3568 {
3569 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
3570 GtkTreeModel *model;
3571 GtkTreeIter added;
3572 AddressObject *pobj;
3573 AddressObjectType otype;
3574 AddressTypeControlItem *atci = NULL;
3575 const gchar *name;
3576
3577 g_return_val_if_fail(iter != NULL, FALSE);
3578 g_return_val_if_fail(obj != NULL, FALSE);
3579
3580 model = gtk_tree_view_get_model(treeview);
3581 gtk_tree_model_get(model, iter, COL_OBJ, &pobj, -1);
3582 g_return_val_if_fail(pobj != NULL, FALSE);
3583
3584 /* Determine object type to be displayed */
3585 if (obj->type == ADDR_DATASOURCE) {
3586 otype = ADAPTER_DSOURCE(obj)->subType;
3587 } else {
3588 otype = obj->type;
3589 }
3590
3591 /* Handle any special conditions. */
3592 atci = addrbookctl_lookup(otype);
3593 if (atci && atci->showInTree) {
3594 /* Add object to tree */
3595 debug_print("addressbook_add_object: obj: %s\n", obj->name);
3596 if (otype == ADDR_BOOK && obj->name &&
3597 !strcmp(obj->name, ADDR_DS_AUTOREG))
3598 name = _("Auto-registered address");
3599 else
3600 name = obj->name;
3601 gtk_tree_store_append(GTK_TREE_STORE(model), &added, iter);
3602 gtk_tree_store_set(GTK_TREE_STORE(model), &added,
3603 COL_FOLDER_NAME, name,
3604 COL_OBJ, obj,
3605 COL_PIXBUF, atci->icon_pixbuf,
3606 COL_PIXBUF_OPEN, atci->icon_open_pixbuf,
3607 -1);
3608 if (new_iter)
3609 *new_iter = added;
3610 return TRUE;
3611 }
3612
3613 return FALSE;
3614 }
3615
3616 /*
3617 * Add group into the address index tree.
3618 * Enter: node Parent node.
3619 * ds Data source.
3620 * itemGroup Group to add.
3621 * Return: Inserted node.
3622 */
addressbook_node_add_group(GtkTreeIter * iter,AddressDataSource * ds,ItemGroup * itemGroup,GtkTreeIter * new_iter)3623 static gboolean addressbook_node_add_group(GtkTreeIter *iter, AddressDataSource *ds, ItemGroup *itemGroup, GtkTreeIter *new_iter)
3624 {
3625 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
3626 GtkTreeStore *store;
3627 GtkTreeIter new_iter_;
3628 AdapterGroup *adapter;
3629 AddressTypeControlItem *atci = NULL;
3630 gchar *name;
3631
3632 if(ds == NULL) return FALSE;
3633 if(iter == NULL || itemGroup == NULL) return FALSE;
3634
3635 name = itemGroup->obj.name;
3636
3637 atci = addrbookctl_lookup(ADDR_ITEM_GROUP);
3638
3639 adapter = g_new0(AdapterGroup, 1);
3640 ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_GROUP;
3641 ADDRESS_OBJECT_NAME(adapter) = g_strdup(ADDRITEM_NAME(itemGroup));
3642 adapter->itemGroup = itemGroup;
3643
3644 debug_print("addressbook_node_add_group: name: %s\n", name);
3645 store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
3646 gtk_tree_store_append(store, &new_iter_, iter);
3647 gtk_tree_store_set(store, &new_iter_,
3648 COL_FOLDER_NAME, name,
3649 COL_OBJ, adapter,
3650 COL_PIXBUF, atci->icon_pixbuf,
3651 COL_PIXBUF_OPEN, atci->icon_open_pixbuf,
3652 -1);
3653 if (new_iter)
3654 *new_iter = new_iter_;
3655 return TRUE;
3656 }
3657
3658 /*
3659 * Add folder into the address index tree.
3660 * Enter: iter Parent node.
3661 * ds Data source.
3662 * itemFolder Folder to add.
3663 * otype Object type to display.
3664 * new_iter Inserted node.
3665 * Return: TRUE if inserted.
3666 */
addressbook_node_add_folder(GtkTreeIter * iter,AddressDataSource * ds,ItemFolder * itemFolder,AddressObjectType otype,GtkTreeIter * new_iter)3667 static gboolean addressbook_node_add_folder(GtkTreeIter *iter, AddressDataSource *ds, ItemFolder *itemFolder, AddressObjectType otype, GtkTreeIter *new_iter)
3668 {
3669 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
3670 GtkTreeStore *store;
3671 GtkTreeIter new_iter_;
3672 AdapterFolder *adapter;
3673 AddressTypeControlItem *atci = NULL;
3674 GList *listItems = NULL;
3675 gchar *name;
3676 ItemFolder *rootFolder;
3677
3678 if (ds == NULL)
3679 return FALSE;
3680 if (iter == NULL || itemFolder == NULL)
3681 return FALSE;
3682
3683 /* Determine object type */
3684 atci = addrbookctl_lookup(otype);
3685 if (atci == NULL)
3686 return FALSE;
3687
3688 store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
3689
3690 rootFolder = addrindex_ds_get_root_folder(ds);
3691 if (itemFolder == rootFolder) {
3692 new_iter_ = *iter;
3693 } else {
3694 name = itemFolder->obj.name;
3695
3696 adapter = g_new0(AdapterFolder, 1);
3697 ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_FOLDER;
3698 ADDRESS_OBJECT_NAME(adapter) = g_strdup(ADDRITEM_NAME(itemFolder));
3699 adapter->itemFolder = itemFolder;
3700
3701 debug_print("addressbook_node_add_folder: name: %s\n", name);
3702 gtk_tree_store_append(store, &new_iter_, iter);
3703 gtk_tree_store_set(store, &new_iter_,
3704 COL_FOLDER_NAME, name,
3705 COL_OBJ, adapter,
3706 COL_PIXBUF, atci->icon_pixbuf,
3707 COL_PIXBUF_OPEN, atci->icon_open_pixbuf,
3708 -1);
3709 }
3710
3711 listItems = itemFolder->listFolder;
3712 while (listItems) {
3713 ItemFolder *item = listItems->data;
3714 addressbook_node_add_folder(&new_iter_, ds, item, otype, NULL);
3715 listItems = g_list_next(listItems);
3716 }
3717 listItems = itemFolder->listGroup;
3718 while (listItems) {
3719 ItemGroup *item = listItems->data;
3720 addressbook_node_add_group(&new_iter_, ds, item, NULL);
3721 listItems = g_list_next(listItems);
3722 }
3723 if (new_iter)
3724 *new_iter = new_iter_;
3725 return TRUE;
3726 }
3727
3728 #if 0
3729 static void addressbook_delete_object(AddressObject *obj) {
3730 AdapterDSource *ads = NULL;
3731 AddressDataSource *ds = NULL;
3732 if (!obj) return;
3733
3734 /* Remove data source. */
3735 /* printf( "Delete obj type : %d\n", obj->type ); */
3736
3737 ads = ADAPTER_DSOURCE(obj);
3738 if( ads == NULL ) return;
3739 ds = ads->dataSource;
3740 if( ds == NULL ) return;
3741
3742 /* Remove data source */
3743 if( addrindex_index_remove_datasource( _addressIndex_, ds ) ) {
3744 addrindex_free_datasource( _addressIndex_, ds );
3745 }
3746 /* Free up Adapter object */
3747 g_free( ADAPTER_DSOURCE(obj) );
3748 }
3749 #endif
3750
addressbook_export_to_file(void)3751 void addressbook_export_to_file( void ) {
3752 if( _addressIndex_ ) {
3753 /* Save all new address book data */
3754 debug_print( "Saving address books...\n" );
3755 addrindex_save_all_books( _addressIndex_ );
3756
3757 debug_print( "Exporting addressbook to file...\n" );
3758 addrindex_save_data( _addressIndex_ );
3759 if( _addressIndex_->retVal != MGU_SUCCESS ) {
3760 addrindex_print_index( _addressIndex_, stdout );
3761 }
3762
3763 /* Notify address completion of new data */
3764 addressbook_modified();
3765 }
3766 }
3767
key_pressed(GtkWidget * widget,GdkEventKey * event,gpointer data)3768 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
3769 gpointer data)
3770 {
3771 if (event && event->keyval == GDK_Escape)
3772 addressbook_close();
3773 return FALSE;
3774 }
3775
size_allocated(GtkWidget * widget,GtkAllocation * allocation,gpointer data)3776 static void size_allocated(GtkWidget *widget, GtkAllocation *allocation,
3777 gpointer data)
3778 {
3779 if (allocation->width <= 1 || allocation->height <= 1)
3780 return;
3781
3782 prefs_common.addressbook_width = allocation->width;
3783 prefs_common.addressbook_height = allocation->height;
3784 }
3785
3786 /*
3787 * Comparison using cell contents (text in first column).
3788 */
addressbook_tree_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)3789 static gint addressbook_tree_compare(GtkTreeModel *model, GtkTreeIter *a,
3790 GtkTreeIter *b, gpointer data)
3791 {
3792 gchar *name1 = NULL, *name2 = NULL;
3793 AddressObject *obj1 = NULL, *obj2 = NULL;
3794 gint ret;
3795
3796 gtk_tree_model_get(model, a, COL_FOLDER_NAME, &name1, COL_OBJ, &obj1,
3797 -1);
3798 gtk_tree_model_get(model, b, COL_FOLDER_NAME, &name2, COL_OBJ, &obj2,
3799 -1);
3800
3801 /* Do not sort toplevel row */
3802 if (obj1 && obj1->type == ADDR_INTERFACE)
3803 return 0;
3804
3805 if (!name1 || !name2) {
3806 if (!name1)
3807 ret = (name2 != NULL);
3808 else
3809 ret = -1;
3810 g_free(name2);
3811 g_free(name1);
3812 return ret;
3813 }
3814 ret = g_ascii_strcasecmp(name1, name2);
3815 g_free(name2);
3816 g_free(name1);
3817 return ret;
3818 }
3819
addressbook_list_col_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gint col)3820 static gint addressbook_list_col_compare(GtkTreeModel *model, GtkTreeIter *a,
3821 GtkTreeIter *b, gint col)
3822 {
3823 gchar *name1 = NULL, *name2 = NULL;
3824 gint ret;
3825
3826 gtk_tree_model_get(model, a, col, &name1, -1);
3827 gtk_tree_model_get(model, b, col, &name2, -1);
3828
3829 if (!name1)
3830 name1 = g_strdup("");
3831 if (!name2)
3832 name2 = g_strdup("");
3833 ret = g_ascii_strcasecmp(name1, name2);
3834 g_free(name2);
3835 g_free(name1);
3836 return ret;
3837 }
3838
addressbook_list_name_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)3839 static gint addressbook_list_name_compare(GtkTreeModel *model, GtkTreeIter *a,
3840 GtkTreeIter *b, gpointer data)
3841 {
3842 gint ret;
3843
3844 ret = addressbook_list_col_compare(model, a, b, COL_NAME);
3845 if (ret == 0)
3846 ret = addressbook_list_col_compare(model, a, b, COL_NICKNAME);
3847 if (ret == 0)
3848 ret = addressbook_list_col_compare(model, a, b, COL_ADDRESS);
3849 if (ret == 0)
3850 ret = addressbook_list_col_compare(model, a, b, COL_REMARKS);
3851
3852 return ret;
3853 }
3854
addressbook_list_address_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)3855 static gint addressbook_list_address_compare(GtkTreeModel *model,
3856 GtkTreeIter *a, GtkTreeIter *b,
3857 gpointer data)
3858 {
3859 gint ret;
3860
3861 ret = addressbook_list_col_compare(model, a, b, COL_ADDRESS);
3862 if (ret == 0)
3863 ret = addressbook_list_col_compare(model, a, b, COL_NAME);
3864 if (ret == 0)
3865 ret = addressbook_list_col_compare(model, a, b, COL_NICKNAME);
3866 if (ret == 0)
3867 ret = addressbook_list_col_compare(model, a, b, COL_REMARKS);
3868
3869 return ret;
3870 }
3871
addressbook_list_nickname_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)3872 static gint addressbook_list_nickname_compare(GtkTreeModel *model,
3873 GtkTreeIter *a, GtkTreeIter *b,
3874 gpointer data)
3875 {
3876 gint ret;
3877
3878 ret = addressbook_list_col_compare(model, a, b, COL_NICKNAME);
3879 if (ret == 0)
3880 ret = addressbook_list_col_compare(model, a, b, COL_NAME);
3881 if (ret == 0)
3882 ret = addressbook_list_col_compare(model, a, b, COL_ADDRESS);
3883 if (ret == 0)
3884 ret = addressbook_list_col_compare(model, a, b, COL_REMARKS);
3885
3886 return ret;
3887 }
3888
addressbook_list_remarks_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)3889 static gint addressbook_list_remarks_compare(GtkTreeModel *model,
3890 GtkTreeIter *a, GtkTreeIter *b,
3891 gpointer data)
3892 {
3893 gint ret;
3894
3895 ret = addressbook_list_col_compare(model, a, b, COL_REMARKS);
3896 if (ret == 0)
3897 ret = addressbook_list_col_compare(model, a, b, COL_NAME);
3898 if (ret == 0)
3899 ret = addressbook_list_col_compare(model, a, b, COL_NICKNAME);
3900 if (ret == 0)
3901 ret = addressbook_list_col_compare(model, a, b, COL_ADDRESS);
3902
3903 return ret;
3904 }
3905
addressbook_list_select_func(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean cur_selected,gpointer data)3906 static gboolean addressbook_list_select_func(GtkTreeSelection *selection,
3907 GtkTreeModel *model,
3908 GtkTreePath *path,
3909 gboolean cur_selected,
3910 gpointer data)
3911 {
3912 return can_toggle_list_selection;
3913 }
3914
3915 /* static */
addressbook_obj_name_compare(gconstpointer a,gconstpointer b)3916 gint addressbook_obj_name_compare(gconstpointer a, gconstpointer b)
3917 {
3918 const AddressObject *obj = a;
3919 const gchar *name = b;
3920 AddressTypeControlItem *atci = NULL;
3921
3922 if (!obj || !name) return -1;
3923
3924 atci = addrbookctl_lookup( obj->type );
3925 if( ! atci ) return -1;
3926 if( ! obj->name ) return -1;
3927 return g_ascii_strcasecmp(obj->name, name);
3928 }
3929
3930 #if 0
3931 static void addressbook_book_show_message( AddressBookFile *abf ) {
3932 gchar msgbuf[ADDRESSBOOK_MSGBUF_SIZE] = "";
3933
3934 if (abf) {
3935 if (abf->retVal == MGU_SUCCESS) {
3936 g_snprintf(msgbuf, sizeof(msgbuf), "%s", abf->name);
3937 } else {
3938 g_snprintf(msgbuf, sizeof(msgbuf), "%s: %s", abf->name, mgu_error2string(abf->retVal));
3939 }
3940 }
3941 addressbook_status_show(msgbuf);
3942 }
3943 #endif
3944
addressbook_new_book_cb(gpointer data,guint action,GtkWidget * widget)3945 static void addressbook_new_book_cb(gpointer data, guint action, GtkWidget *widget)
3946 {
3947 GtkTreeModel *model;
3948 GtkTreeIter iter;
3949 AdapterDSource *ads;
3950 AdapterInterface *adapter;
3951
3952 adapter = addrbookctl_find_interface(ADDR_IF_BOOK);
3953 if (adapter == NULL)
3954 return;
3955 if (!gtkut_tree_row_reference_equal(addrbook.tree_selected, adapter->tree_row))
3956 return;
3957
3958 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
3959 gtkut_tree_row_reference_get_iter(model, addrbook.tree_selected, &iter);
3960
3961 ads = addressbook_edit_book(_addressIndex_, NULL);
3962 if (ads) {
3963 addressbook_add_object(&iter, NULL, ADDRESS_OBJECT(ads));
3964 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened)) {
3965 addressbook_reopen();
3966 }
3967 }
3968 }
3969
addressbook_new_vcard_cb(gpointer data,guint action,GtkWidget * widget)3970 static void addressbook_new_vcard_cb(gpointer data, guint action, GtkWidget *widget)
3971 {
3972 GtkTreeModel *model;
3973 GtkTreeIter iter;
3974 AdapterDSource *ads;
3975 AdapterInterface *adapter;
3976
3977 adapter = addrbookctl_find_interface(ADDR_IF_VCARD);
3978 if (adapter == NULL)
3979 return;
3980 if (!gtkut_tree_row_reference_equal(addrbook.tree_selected, adapter->tree_row))
3981 return;
3982
3983 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
3984 gtkut_tree_row_reference_get_iter(model, addrbook.tree_selected, &iter);
3985
3986 ads = addressbook_edit_vcard(_addressIndex_, NULL);
3987 if (ads) {
3988 addressbook_add_object(&iter, NULL, ADDRESS_OBJECT(ads));
3989 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened)) {
3990 addressbook_reopen();
3991 }
3992 addressbook_modified();
3993 }
3994 }
3995
3996 #if 0
3997 static void addressbook_vcard_show_message( VCardFile *vcf ) {
3998 gchar msgbuf[ADDRESSBOOK_MSGBUF_SIZE] = "";
3999
4000 if (vcf) {
4001 if (vcf->retVal == MGU_SUCCESS) {
4002 g_snprintf(msgbuf, sizeof(msgbuf), "%s", vcf->name);
4003 } else {
4004 g_snprintf(msgbuf, sizeof(msgbuf), "%s: %s", vcf->name, mgu_error2string(vcf->retVal));
4005 }
4006 }
4007 addressbook_status_show(msgbuf);
4008 }
4009 #endif
4010
4011 #ifdef USE_JPILOT
addressbook_new_jpilot_cb(gpointer data,guint action,GtkWidget * widget)4012 static void addressbook_new_jpilot_cb(gpointer data, guint action, GtkWidget *widget)
4013 {
4014 GtkTreeModel *model;
4015 GtkTreeIter iter;
4016 AdapterDSource *ads;
4017 AdapterInterface *adapter;
4018 AddressInterface *iface;
4019
4020 adapter = addrbookctl_find_interface(ADDR_IF_JPILOT);
4021 if (adapter == NULL)
4022 return;
4023 if (!gtkut_tree_row_reference_equal(addrbook.tree_selected, adapter->tree_row))
4024 return;
4025 iface = adapter->iface;
4026 if (!iface->haveLibrary)
4027 return;
4028
4029 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
4030 gtkut_tree_row_reference_get_iter(model, addrbook.tree_selected, &iter);
4031
4032 ads = addressbook_edit_jpilot(_addressIndex_, NULL);
4033 if (ads) {
4034 addressbook_add_object(&iter, NULL, ADDRESS_OBJECT(ads));
4035 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened)) {
4036 addressbook_reopen();
4037 }
4038 }
4039 }
4040
4041 #if 0
4042 static void addressbook_jpilot_show_message( JPilotFile *jpf ) {
4043 gchar msgbuf[ADDRESSBOOK_MSGBUF_SIZE] = "";
4044
4045 if (jpf) {
4046 if (jpf->retVal == MGU_SUCCESS) {
4047 g_snprintf(msgbuf, sizeof(msgbuf), "%s", jpf->name);
4048 } else {
4049 g_snprintf(msgbuf, sizeof(msgbuf), "%s: %s", jpf->name, mgu_error2string(jpf->retVal));
4050 }
4051 }
4052 addressbook_status_show(msgbuf);
4053 }
4054 #endif
4055 #endif /* USE_JPILOT */
4056
4057 #ifdef USE_LDAP
addressbook_new_ldap_cb(gpointer data,guint action,GtkWidget * widget)4058 static void addressbook_new_ldap_cb(gpointer data, guint action, GtkWidget *widget)
4059 {
4060 GtkTreeModel *model;
4061 GtkTreeIter iter;
4062 AdapterDSource *ads;
4063 AdapterInterface *adapter;
4064 AddressInterface *iface;
4065
4066 adapter = addrbookctl_find_interface(ADDR_IF_LDAP);
4067 if (adapter == NULL)
4068 return;
4069 if (!gtkut_tree_row_reference_equal(addrbook.tree_selected, adapter->tree_row))
4070 return;
4071 iface = adapter->iface;
4072 if (!iface->haveLibrary)
4073 return;
4074
4075 model = gtk_tree_view_get_model(GTK_TREE_VIEW(addrbook.treeview));
4076 gtkut_tree_row_reference_get_iter(model, addrbook.tree_selected, &iter);
4077
4078 ads = addressbook_edit_ldap(_addressIndex_, NULL);
4079 if( ads ) {
4080 addressbook_add_object(&iter, NULL, ADDRESS_OBJECT(ads));
4081 if (gtkut_tree_row_reference_equal(addrbook.tree_selected, addrbook.tree_opened)) {
4082 addressbook_reopen();
4083 }
4084 }
4085 }
4086
addressbook_ldap_show_message(SyldapServer * svr)4087 static void addressbook_ldap_show_message(SyldapServer *svr)
4088 {
4089 gchar msgbuf[ADDRESSBOOK_MSGBUF_SIZE] = "";
4090
4091 if (svr) {
4092 if (svr->busyFlag) {
4093 g_snprintf(msgbuf, sizeof(msgbuf), "%s: %s", svr->name, ADDRESSBOOK_LDAP_BUSYMSG);
4094 } else {
4095 if (svr->retVal == MGU_SUCCESS) {
4096 g_snprintf(msgbuf, sizeof(msgbuf), "%s", svr->name);
4097 } else {
4098 g_snprintf(msgbuf, sizeof(msgbuf), "%s: %s", svr->name, mgu_error2string(svr->retVal));
4099 }
4100 }
4101 }
4102 addressbook_status_show(msgbuf);
4103 }
4104
ldapsearch_callback(SyldapServer * sls)4105 static void ldapsearch_callback(SyldapServer *sls)
4106 {
4107 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
4108 GtkTreeSelection *selection;
4109 GtkTreeModel *model;
4110 GtkTreeIter iter;
4111 AddressObject *obj;
4112 AdapterDSource *ads = NULL;
4113 AddressDataSource *ds = NULL;
4114 AddressInterface *iface = NULL;
4115
4116 if (sls == NULL)
4117 return;
4118
4119 selection = gtk_tree_view_get_selection(treeview);
4120 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
4121 return;
4122 if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), &iter) == 0)
4123 return;
4124
4125 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
4126 if (obj == NULL)
4127 return;
4128 if (obj->type == ADDR_DATASOURCE) {
4129 ads = ADAPTER_DSOURCE(obj);
4130 if (ads->subType == ADDR_LDAP) {
4131 SyldapServer *server;
4132
4133 ds = ads->dataSource;
4134 if (ds == NULL)
4135 return;
4136 iface = ds->iface;
4137 if (!iface->haveLibrary)
4138 return;
4139 server = ds->rawDataSource;
4140 if (server == sls) {
4141 /* Read from cache */
4142 gtk_widget_show(addrbook.window);
4143 addressbook_set_list(obj);
4144 addressbook_ldap_show_message(sls);
4145 gtk_widget_show(addrbook.window);
4146 gtk_entry_set_text(GTK_ENTRY(addrbook.entry), "");
4147 }
4148 }
4149 }
4150 }
4151 #endif
4152
4153 /*
4154 * Lookup button handler.
4155 */
addressbook_lup_clicked(GtkButton * button,gpointer data)4156 static void addressbook_lup_clicked(GtkButton *button, gpointer data)
4157 {
4158 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
4159 GtkTreeSelection *selection;
4160 GtkTreeModel *model;
4161 GtkTreeIter iter;
4162 AddressObject *obj;
4163 AdapterDSource *ads = NULL;
4164 #ifdef USE_LDAP
4165 AddressDataSource *ds = NULL;
4166 AddressInterface *iface = NULL;
4167 #endif /* USE_LDAP */
4168 gchar *sLookup;
4169
4170 selection = gtk_tree_view_get_selection(treeview);
4171 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
4172 return;
4173 if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), &iter) == 0)
4174 return;
4175
4176 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
4177 if (obj == NULL)
4178 return;
4179
4180 sLookup = gtk_editable_get_chars(GTK_EDITABLE(addrbook.entry), 0, -1);
4181 g_strstrip(sLookup);
4182
4183 if (obj->type == ADDR_DATASOURCE) {
4184 ads = ADAPTER_DSOURCE(obj);
4185 #ifdef USE_LDAP
4186 if (ads->subType == ADDR_LDAP) {
4187 SyldapServer *server;
4188
4189 ds = ads->dataSource;
4190 if (ds == NULL)
4191 return;
4192 iface = ds->iface;
4193 if (!iface->haveLibrary)
4194 return;
4195 server = ds->rawDataSource;
4196 if (server) {
4197 syldap_cancel_read(server);
4198 if (*sLookup == '\0' || strlen(sLookup) < 1 )
4199 return;
4200 syldap_set_search_value(server, sLookup);
4201 syldap_set_callback(server, ldapsearch_callback);
4202 syldap_read_data_th(server);
4203 addressbook_ldap_show_message(server);
4204 }
4205 } else
4206 #endif /* USE_LDAP */
4207 addressbook_set_list(obj);
4208 } else {
4209 addressbook_set_list(obj);
4210 }
4211
4212 g_free(sLookup);
4213 }
4214
addressbook_close_clicked(GtkButton * button,gpointer data)4215 static void addressbook_close_clicked(GtkButton *button, gpointer data)
4216 {
4217 addressbook_close();
4218 }
4219
4220 /* **********************************************************************
4221 * Build lookup tables.
4222 * ***********************************************************************
4223 */
4224
4225 /*
4226 * Build table that controls the rendering of object types.
4227 */
addrbookctl_build_map(GtkWidget * window)4228 void addrbookctl_build_map(GtkWidget *window)
4229 {
4230 AddressTypeControlItem *atci;
4231
4232 /* Build icons */
4233 stock_pixbuf_gdk(window, STOCK_PIXMAP_FOLDER_CLOSE, &folderpix);
4234 stock_pixbuf_gdk(window, STOCK_PIXMAP_FOLDER_OPEN, &folderopenpix);
4235 stock_pixbuf_gdk(window, STOCK_PIXMAP_GROUP, &grouppix);
4236 stock_pixbuf_gdk(window, STOCK_PIXMAP_VCARD, &vcardpix);
4237 stock_pixbuf_gdk(window, STOCK_PIXMAP_BOOK, &bookpix);
4238 stock_pixbuf_gdk(window, STOCK_PIXMAP_PERSON, &personpix);
4239 stock_pixbuf_gdk(window, STOCK_PIXMAP_ADDRESS, &addresspix);
4240 stock_pixbuf_gdk(window, STOCK_PIXMAP_JPILOT, &jpilotpix);
4241 stock_pixbuf_gdk(window, STOCK_PIXMAP_CATEGORY, &categorypix);
4242 stock_pixbuf_gdk(window, STOCK_PIXMAP_LDAP, &ldappix);
4243
4244 _addressBookTypeHash_ = g_hash_table_new(g_int_hash, g_int_equal);
4245 _addressBookTypeList_ = NULL;
4246
4247 /* Interface */
4248 atci = g_new0(AddressTypeControlItem, 1);
4249 atci->objectType = ADDR_INTERFACE;
4250 atci->interfaceType = ADDR_IF_NONE;
4251 atci->showInTree = TRUE;
4252 atci->treeExpand = TRUE;
4253 atci->treeLeaf = FALSE;
4254 atci->displayName = _("Interface");
4255 atci->icon_pixbuf = folderpix;
4256 atci->icon_open_pixbuf = folderopenpix;
4257 atci->menuCommand = NULL;
4258 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4259 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4260
4261 /* Address book */
4262 atci = g_new0(AddressTypeControlItem, 1);
4263 atci->objectType = ADDR_BOOK;
4264 atci->interfaceType = ADDR_IF_BOOK;
4265 atci->showInTree = TRUE;
4266 atci->treeExpand = TRUE;
4267 atci->treeLeaf = FALSE;
4268 atci->displayName = _("Address Book");
4269 atci->icon_pixbuf = bookpix;
4270 atci->icon_open_pixbuf = bookpix;
4271 atci->menuCommand = "/File/New Book";
4272 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
4273 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
4274
4275 /* Item person */
4276 atci = g_new0(AddressTypeControlItem, 1);
4277 atci->objectType = ADDR_ITEM_PERSON;
4278 atci->interfaceType = ADDR_IF_NONE;
4279 atci->showInTree = FALSE;
4280 atci->treeExpand = FALSE;
4281 atci->treeLeaf = FALSE;
4282 atci->displayName = _("Person");
4283 atci->icon_pixbuf = personpix;
4284 atci->icon_open_pixbuf = personpix;
4285 atci->menuCommand = NULL;
4286 g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
4287 _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
4288
4289 /* Item email */
4290 atci = g_new0(AddressTypeControlItem, 1);
4291 atci->objectType = ADDR_ITEM_EMAIL;
4292 atci->interfaceType = ADDR_IF_NONE;
4293 atci->showInTree = FALSE;
4294 atci->treeExpand = FALSE;
4295 atci->treeLeaf = TRUE;
4296 atci->displayName = _("EMail Address");
4297 atci->icon_pixbuf = addresspix;
4298 atci->icon_open_pixbuf = addresspix;
4299 atci->menuCommand = NULL;
4300 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4301 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4302
4303 /* Item group */
4304 atci = g_new0(AddressTypeControlItem, 1);
4305 atci->objectType = ADDR_ITEM_GROUP;
4306 atci->interfaceType = ADDR_IF_BOOK;
4307 atci->showInTree = TRUE;
4308 atci->treeExpand = FALSE;
4309 atci->treeLeaf = FALSE;
4310 atci->displayName = _("Group");
4311 atci->icon_pixbuf = grouppix;
4312 atci->icon_open_pixbuf = grouppix;
4313 atci->menuCommand = NULL;
4314 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4315 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4316
4317 /* Item folder */
4318 atci = g_new0(AddressTypeControlItem, 1);
4319 atci->objectType = ADDR_ITEM_FOLDER;
4320 atci->interfaceType = ADDR_IF_BOOK;
4321 atci->showInTree = TRUE;
4322 atci->treeExpand = FALSE;
4323 atci->treeLeaf = FALSE;
4324 atci->displayName = _("Folder");
4325 atci->icon_pixbuf = folderpix;
4326 atci->icon_open_pixbuf = folderopenpix;
4327 atci->menuCommand = NULL;
4328 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4329 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4330
4331 /* vCard */
4332 atci = g_new0(AddressTypeControlItem, 1);
4333 atci->objectType = ADDR_VCARD;
4334 atci->interfaceType = ADDR_IF_VCARD;
4335 atci->showInTree = TRUE;
4336 atci->treeExpand = TRUE;
4337 atci->treeLeaf = TRUE;
4338 atci->displayName = _("vCard");
4339 atci->icon_pixbuf = vcardpix;
4340 atci->icon_open_pixbuf = vcardpix;
4341 atci->menuCommand = "/File/New vCard";
4342 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4343 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4344
4345 /* JPilot */
4346 atci = g_new0(AddressTypeControlItem, 1);
4347 atci->objectType = ADDR_JPILOT;
4348 atci->interfaceType = ADDR_IF_JPILOT;
4349 atci->showInTree = TRUE;
4350 atci->treeExpand = TRUE;
4351 atci->treeLeaf = FALSE;
4352 atci->displayName = _("JPilot");
4353 atci->icon_pixbuf = jpilotpix;
4354 atci->icon_open_pixbuf = jpilotpix;
4355 atci->menuCommand = "/File/New JPilot";
4356 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4357 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4358
4359 /* Category */
4360 atci = g_new0(AddressTypeControlItem, 1);
4361 atci->objectType = ADDR_CATEGORY;
4362 atci->interfaceType = ADDR_IF_JPILOT;
4363 atci->showInTree = TRUE;
4364 atci->treeExpand = TRUE;
4365 atci->treeLeaf = TRUE;
4366 atci->displayName = _("JPilot");
4367 atci->icon_pixbuf = categorypix;
4368 atci->icon_open_pixbuf = categorypix;
4369 atci->menuCommand = NULL;
4370 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4371 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4372
4373 /* LDAP Server */
4374 atci = g_new0(AddressTypeControlItem, 1);
4375 atci->objectType = ADDR_LDAP;
4376 atci->interfaceType = ADDR_IF_LDAP;
4377 atci->showInTree = TRUE;
4378 atci->treeExpand = TRUE;
4379 atci->treeLeaf = TRUE;
4380 atci->displayName = _("LDAP Server");
4381 atci->icon_pixbuf = ldappix;
4382 atci->icon_open_pixbuf = ldappix;
4383 atci->menuCommand = "/File/New LDAP Server";
4384 g_hash_table_insert(_addressBookTypeHash_, &atci->objectType, atci);
4385 _addressBookTypeList_ = g_list_append(_addressBookTypeList_, atci);
4386 }
4387
4388 /*
4389 * Search for specified object type.
4390 */
addrbookctl_lookup(gint ot)4391 AddressTypeControlItem *addrbookctl_lookup(gint ot)
4392 {
4393 gint objType = ot;
4394 return (AddressTypeControlItem *)g_hash_table_lookup(_addressBookTypeHash_, &objType);
4395 }
4396
4397 /*
4398 * Search for specified interface type.
4399 */
addrbookctl_lookup_iface(AddressIfType ifType)4400 AddressTypeControlItem *addrbookctl_lookup_iface( AddressIfType ifType ) {
4401 GList *node = _addressBookTypeList_;
4402 while( node ) {
4403 AddressTypeControlItem *atci = node->data;
4404 if( atci->interfaceType == ifType ) return atci;
4405 node = g_list_next( node );
4406 }
4407 return NULL;
4408 }
4409
addrbookctl_free_address(AddressObject * obj)4410 static void addrbookctl_free_address( AddressObject *obj ) {
4411 g_free( obj->name );
4412 obj->type = ADDR_NONE;
4413 obj->name = NULL;
4414 }
4415
addrbookctl_free_interface(AdapterInterface * adapter)4416 static void addrbookctl_free_interface(AdapterInterface *adapter)
4417 {
4418 addrbookctl_free_address(ADDRESS_OBJECT(adapter));
4419 adapter->iface = NULL;
4420 adapter->interfaceType = ADDR_IF_NONE;
4421 adapter->atci = NULL;
4422 adapter->enabled = FALSE;
4423 adapter->haveLibrary = FALSE;
4424 if (adapter->tree_row) {
4425 gtk_tree_row_reference_free(adapter->tree_row);
4426 adapter->tree_row = NULL;
4427 }
4428 g_free(adapter);
4429 }
4430
addrbookctl_free_datasource(AdapterDSource * adapter)4431 static void addrbookctl_free_datasource( AdapterDSource *adapter ) {
4432 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
4433 adapter->dataSource = NULL;
4434 adapter->subType = ADDR_NONE;
4435 g_free( adapter );
4436 }
4437
addrbookctl_free_folder(AdapterFolder * adapter)4438 static void addrbookctl_free_folder( AdapterFolder *adapter ) {
4439 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
4440 adapter->itemFolder = NULL;
4441 g_free( adapter );
4442 }
4443
addrbookctl_free_group(AdapterGroup * adapter)4444 static void addrbookctl_free_group( AdapterGroup *adapter ) {
4445 addrbookctl_free_address( ADDRESS_OBJECT(adapter) );
4446 adapter->itemGroup = NULL;
4447 g_free( adapter );
4448 }
4449
4450 /*
4451 * Build GUI interface list.
4452 */
addrbookctl_build_iflist(void)4453 void addrbookctl_build_iflist(void)
4454 {
4455 AddressTypeControlItem *atci;
4456 AdapterInterface *adapter;
4457 GList *list = NULL;
4458
4459 if(_addressIndex_ == NULL) {
4460 _addressIndex_ = addrindex_create_index();
4461 }
4462 _addressInterfaceList_ = NULL;
4463 list = addrindex_get_interface_list(_addressIndex_);
4464 while (list) {
4465 AddressInterface *iface = list->data;
4466 atci = addrbookctl_lookup_iface(iface->type);
4467 if (atci) {
4468 adapter = g_new0(AdapterInterface, 1);
4469 adapter->interfaceType = iface->type;
4470 adapter->atci = atci;
4471 adapter->iface = iface;
4472 adapter->tree_row = NULL;
4473 adapter->enabled = TRUE;
4474 adapter->haveLibrary = iface->haveLibrary;
4475 ADDRESS_OBJECT(adapter)->type = ADDR_INTERFACE;
4476 ADDRESS_OBJECT_NAME(adapter) = g_strdup(atci->displayName);
4477 _addressInterfaceList_ = g_list_append(_addressInterfaceList_, adapter);
4478 }
4479 list = g_list_next(list);
4480 }
4481 }
4482
addrbookctl_free_selection(GList * list)4483 void addrbookctl_free_selection( GList *list ) {
4484 GList *node = list;
4485 while( node ) {
4486 AdapterInterface *adapter = node->data;
4487 adapter = NULL;
4488 node = g_list_next( node );
4489 }
4490 g_list_free( list );
4491 }
4492
4493 /*
4494 * Find GUI interface type specified interface type.
4495 * Return: Interface item, or NULL if not found.
4496 */
addrbookctl_find_interface(AddressIfType ifType)4497 AdapterInterface *addrbookctl_find_interface( AddressIfType ifType ) {
4498 GList *node = _addressInterfaceList_;
4499 while( node ) {
4500 AdapterInterface *adapter = node->data;
4501 if( adapter->interfaceType == ifType ) return adapter;
4502 node = g_list_next( node );
4503 }
4504 return NULL;
4505 }
4506
4507 /*
4508 * Build interface list selection.
4509 */
addrbookctl_build_ifselect(void)4510 void addrbookctl_build_ifselect(void)
4511 {
4512 GList *newList = NULL;
4513 gchar *selectStr;
4514 gchar **splitStr;
4515 gint ifType;
4516 gint i;
4517 gchar *endptr = NULL;
4518 gboolean enabled;
4519 AdapterInterface *adapter;
4520 /* GList *node; */
4521
4522 selectStr = g_strdup( ADDRESSBOOK_IFACE_SELECTION );
4523
4524 /* Parse string */
4525 splitStr = g_strsplit( selectStr, ",", -1 );
4526 for( i = 0; i < ADDRESSBOOK_MAX_IFACE; i++ ) {
4527 if( splitStr[i] ) {
4528 /* printf( "%d : %s\n", i, splitStr[i] ); */
4529 ifType = strtol( splitStr[i], &endptr, 10 );
4530 enabled = TRUE;
4531 if( *endptr ) {
4532 if( strcmp( endptr, "/n" ) == 0 ) {
4533 enabled = FALSE;
4534 }
4535 }
4536 /* printf( "\t%d : %s\n", ifType, enabled ? "yes" : "no" ); */
4537 adapter = addrbookctl_find_interface( ifType );
4538 if( adapter ) {
4539 newList = g_list_append( newList, adapter );
4540 }
4541 }
4542 else {
4543 break;
4544 }
4545 }
4546 /* printf( "i=%d\n", i ); */
4547 g_strfreev( splitStr );
4548 g_free( selectStr );
4549
4550 /* Replace existing list */
4551 mgu_clear_list( _addressIFaceSelection_ );
4552 g_list_free( _addressIFaceSelection_ );
4553 _addressIFaceSelection_ = newList;
4554 newList = NULL;
4555
4556 }
4557
4558 /* **********************************************************************
4559 * Add sender to address book.
4560 * ***********************************************************************
4561 */
4562
4563 /*
4564 * This function is used by the Add sender to address book function.
4565 */
addressbook_add_contact(const gchar * name,const gchar * address,const gchar * remarks)4566 gboolean addressbook_add_contact(const gchar *name, const gchar *address, const gchar *remarks)
4567 {
4568 debug_print("addressbook_add_contact: name/address: %s <%s>\n", name ? name : "", address);
4569 if (addressadd_selection(_addressIndex_, name, address, remarks)) {
4570 debug_print("addressbook_add_contact - added\n");
4571 addressbook_refresh();
4572 }
4573 return TRUE;
4574 }
4575
4576 /*
4577 * This function is used by the automatic address registration.
4578 */
addressbook_add_contact_autoreg(const gchar * name,const gchar * address,const gchar * remarks)4579 gboolean addressbook_add_contact_autoreg(const gchar *name, const gchar *address, const gchar *remarks)
4580 {
4581 debug_print("addressbook_add_contact_autoreg: name/address: %s <%s>\n", name ? name : "", address);
4582 if (addressadd_autoreg(_addressIndex_, name, address, remarks)) {
4583 addressbook_refresh();
4584 }
4585 return TRUE;
4586 }
4587
4588 /* **********************************************************************
4589 * Address completion support.
4590 * ***********************************************************************
4591 */
4592
4593 /*
4594 * This function is used by the address completion function to load
4595 * addresses.
4596 * Enter: callBackFunc Function to be called when an address is
4597 * to be loaded.
4598 * Return: TRUE if data loaded, FALSE if address index not loaded.
4599 */
addressbook_load_completion_full(AddressBookCompletionFunc func)4600 gboolean addressbook_load_completion_full(AddressBookCompletionFunc func)
4601 {
4602 /* AddressInterface *interface; */
4603 AddressDataSource *ds;
4604 GList *nodeIf, *nodeDS;
4605 GList *listP, *nodeP;
4606 GList *nodeM;
4607 gchar *sName, *sAddress, *sAlias, *sNickName;
4608 gchar *sFirstName, *sLastName;
4609
4610 debug_print( "addressbook_load_completion\n" );
4611
4612 if( _addressIndex_ == NULL ) return FALSE;
4613
4614 nodeIf = addrindex_get_interface_list( _addressIndex_ );
4615 while( nodeIf ) {
4616 AddressInterface *iface = nodeIf->data;
4617 nodeDS = iface->listSource;
4618 while( nodeDS ) {
4619 ds = nodeDS->data;
4620
4621 /* Read address book */
4622 if( ! addrindex_ds_get_read_flag( ds ) ) {
4623 addrindex_ds_read_data( ds );
4624 }
4625
4626 /* Get all persons */
4627 listP = addrindex_ds_get_all_persons( ds );
4628 nodeP = listP;
4629 while( nodeP ) {
4630 ItemPerson *person = nodeP->data;
4631 nodeM = person->listEMail;
4632
4633 /* Figure out name to use */
4634 sName = ADDRITEM_NAME(person);
4635 sNickName = person->nickName;
4636 if( sName == NULL || *sName == '\0' ) {
4637 if (sNickName)
4638 sName = sNickName;
4639 }
4640 sFirstName = person->firstName;
4641 sLastName = person->lastName;
4642
4643 /* Process each E-Mail address */
4644 while( nodeM ) {
4645 ItemEMail *email = nodeM->data;
4646 /* Have mail */
4647 sAddress = email->address;
4648 if( sAddress && *sAddress != '\0' ) {
4649 sAlias = ADDRITEM_NAME(email);
4650 if( sAlias && *sAlias != '\0' ) {
4651 func( sName, sFirstName, sLastName, sAlias, sAddress );
4652 } else {
4653 func( sName, sFirstName, sLastName, sNickName, sAddress );
4654 }
4655 }
4656 nodeM = g_list_next( nodeM );
4657 }
4658 nodeP = g_list_next( nodeP );
4659 }
4660 /* Free up the list */
4661 g_list_free( listP );
4662
4663 nodeDS = g_list_next( nodeDS );
4664 }
4665 nodeIf = g_list_next( nodeIf );
4666 }
4667 debug_print( "addressbook_load_completion... done\n" );
4668
4669 return TRUE;
4670 }
4671
4672 static gint (*real_func)(const gchar *, const gchar *, const gchar *);
4673
wrapper_func(const gchar * name,const gchar * firstname,const gchar * lastname,const gchar * nickname,const gchar * address)4674 static gint wrapper_func(const gchar *name, const gchar *firstname, const gchar *lastname, const gchar *nickname, const gchar *address)
4675 {
4676 return real_func(name, address, nickname);
4677 }
4678
addressbook_load_completion(gint (* callBackFunc)(const gchar *,const gchar *,const gchar *))4679 gboolean addressbook_load_completion(gint (*callBackFunc)(const gchar *, const gchar *, const gchar *))
4680 {
4681 gboolean ret;
4682
4683 real_func = callBackFunc;
4684 ret = addressbook_load_completion_full(wrapper_func);
4685 real_func = NULL;
4686
4687 return ret;
4688 }
4689
4690 /* **********************************************************************
4691 * Address Import.
4692 * ***********************************************************************
4693 */
4694
4695 /*
4696 * Import LDIF file.
4697 */
addressbook_import_ldif_cb(void)4698 static void addressbook_import_ldif_cb(void)
4699 {
4700 AddressDataSource *ds = NULL;
4701 AdapterDSource *ads = NULL;
4702 AddressBookFile *abf = NULL;
4703 AdapterInterface *adapter;
4704 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
4705 GtkTreeModel *model;
4706 GtkTreeIter iter, new_iter;
4707 GtkTreePath *path;
4708
4709 adapter = addrbookctl_find_interface(ADDR_IF_BOOK);
4710 if (!adapter || !adapter->tree_row)
4711 return;
4712
4713 abf = addressbook_imp_ldif(_addressIndex_);
4714 gtk_window_present(GTK_WINDOW(addrbook.window));
4715 if (!abf)
4716 return;
4717
4718 ds = addrindex_index_add_datasource(_addressIndex_, ADDR_IF_BOOK, abf);
4719 ads = addressbook_create_ds_adapter(ds, ADDR_BOOK, NULL);
4720 addressbook_ads_set_name(ads, abf->name);
4721
4722 model = gtk_tree_view_get_model(treeview);
4723 gtkut_tree_row_reference_get_iter(model, adapter->tree_row, &iter);
4724
4725 if (addressbook_add_object(&iter, &new_iter, ADDRESS_OBJECT(ads))) {
4726 path = gtk_tree_model_get_path(model, &new_iter);
4727 gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
4728 gtk_tree_path_free(path);
4729 }
4730
4731 /* Notify address completion */
4732 addressbook_modified();
4733 }
4734
addressbook_import_ldif_file(const gchar * file,const gchar * book_name)4735 gboolean addressbook_import_ldif_file(const gchar *file, const gchar *book_name)
4736 {
4737 AddressBookFile *abf;
4738
4739 g_return_val_if_fail(file != NULL, FALSE);
4740 g_return_val_if_fail(book_name != NULL, FALSE);
4741
4742 abf = addressbook_imp_ldif_file(_addressIndex_, file, book_name);
4743 if (!abf)
4744 return FALSE;
4745
4746 addrindex_index_add_datasource(_addressIndex_, ADDR_IF_BOOK, abf);
4747 addrindex_save_data(_addressIndex_);
4748 addressbook_modified();
4749
4750 return TRUE;
4751 }
4752
4753 /*
4754 * Import CSV file.
4755 */
addressbook_import_csv_cb(void)4756 static void addressbook_import_csv_cb(void)
4757 {
4758 AddressDataSource *ds = NULL;
4759 AdapterDSource *ads = NULL;
4760 AddressBookFile *abf = NULL;
4761 AdapterInterface *adapter;
4762 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
4763 GtkTreeModel *model;
4764 GtkTreeIter iter, new_iter;
4765 GtkTreePath *path;
4766
4767 adapter = addrbookctl_find_interface(ADDR_IF_BOOK);
4768 if (!adapter || !adapter->tree_row)
4769 return;
4770
4771 abf = addressbook_imp_csv(_addressIndex_);
4772 gtk_window_present(GTK_WINDOW(addrbook.window));
4773 if (!abf)
4774 return;
4775
4776 ds = addrindex_index_add_datasource(_addressIndex_, ADDR_IF_BOOK, abf);
4777 ads = addressbook_create_ds_adapter(ds, ADDR_BOOK, NULL);
4778 addressbook_ads_set_name(ads, abf->name);
4779
4780 model = gtk_tree_view_get_model(treeview);
4781 gtkut_tree_row_reference_get_iter(model, adapter->tree_row, &iter);
4782
4783 if (addressbook_add_object(&iter, &new_iter, ADDRESS_OBJECT(ads))) {
4784 path = gtk_tree_model_get_path(model, &new_iter);
4785 gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
4786 gtk_tree_path_free(path);
4787 }
4788
4789 /* Notify address completion */
4790 addressbook_modified();
4791 }
4792
4793 /*
4794 * Export CSV file.
4795 */
addressbook_export_csv_cb(void)4796 static void addressbook_export_csv_cb(void)
4797 {
4798 GtkTreeView *treeview = GTK_TREE_VIEW(addrbook.treeview);
4799 GtkTreeModel *model;
4800 GtkTreeIter iter;
4801 GtkTreePath *path;
4802 AddressObject *obj;
4803 ItemFolder *itemFolder = NULL;
4804 ItemGroup *itemGroup = NULL;
4805 GList *items;
4806 GList *cur;
4807 gchar delim = ',';
4808
4809 if (!addrbook.tree_opened) {
4810 return;
4811 }
4812
4813 model = gtk_tree_view_get_model(treeview);
4814 gtkut_tree_row_reference_get_iter(model, addrbook.tree_opened, &iter);
4815 gtk_tree_model_get(model, &iter, COL_OBJ, &obj, -1);
4816 g_return_if_fail(obj != NULL);
4817
4818 if (obj->type == ADDR_INTERFACE) {
4819 return;
4820 }
4821
4822 addressbook_exp_csv(obj);
4823 }
4824
4825 /* **********************************************************************
4826 * Address Book Fast Search.
4827 * ***********************************************************************
4828 */
4829
4830 static GHashTable *addr_table;
4831
4832 #if USE_THREADS
4833 G_LOCK_DEFINE_STATIC(addr_table);
4834 #define S_LOCK(name) G_LOCK(name)
4835 #define S_UNLOCK(name) G_UNLOCK(name)
4836 #else
4837 #define S_LOCK(name)
4838 #define S_UNLOCK(name)
4839 #endif
4840
load_address(const gchar * name,const gchar * address,const gchar * nickname)4841 static gint load_address(const gchar *name, const gchar *address,
4842 const gchar *nickname)
4843 {
4844 gchar *addr;
4845
4846 if (!address)
4847 return -1;
4848
4849 addr = g_ascii_strdown(address, -1);
4850
4851 if (g_hash_table_lookup(addr_table, addr) == NULL)
4852 g_hash_table_insert(addr_table, addr, addr);
4853 else
4854 g_free(addr);
4855
4856 return 0;
4857 }
4858
addressbook_modified(void)4859 static void addressbook_modified(void)
4860 {
4861 S_LOCK(addr_table);
4862
4863 if (addr_table) {
4864 hash_free_strings(addr_table);
4865 g_hash_table_destroy(addr_table);
4866 addr_table = NULL;
4867 }
4868
4869 S_UNLOCK(addr_table);
4870
4871 invalidate_address_completion();
4872 }
4873
addressbook_has_address(const gchar * address)4874 gboolean addressbook_has_address(const gchar *address)
4875 {
4876 GSList *list, *cur;
4877 gchar *addr;
4878 gboolean found = FALSE;
4879
4880 if (!address)
4881 return FALSE;
4882
4883 /* debug_print("addressbook_has_address: check if addressbook has address: %s\n", address); */
4884
4885 list = address_list_append(NULL, address);
4886 if (!list)
4887 return FALSE;
4888
4889 S_LOCK(addr_table);
4890
4891 if (!addr_table) {
4892 addr_table = g_hash_table_new(g_str_hash, g_str_equal);
4893 addressbook_load_completion(load_address);
4894 }
4895
4896 for (cur = list; cur != NULL; cur = cur->next) {
4897 addr = g_ascii_strdown((gchar *)cur->data, -1);
4898
4899 if (g_hash_table_lookup(addr_table, addr)) {
4900 found = TRUE;
4901 /* debug_print("<%s> is in addressbook\n", addr); */
4902 } else {
4903 found = FALSE;
4904 g_free(addr);
4905 break;
4906 }
4907 g_free(addr);
4908 }
4909
4910 S_UNLOCK(addr_table);
4911
4912 slist_free_strings(list);
4913
4914 return found;
4915 }
4916
4917 /*
4918 * End of Source.
4919 */
4920