Statistics
| Revision:

root / src / addressbook.c @ 2360

History | View | Annotate | Download (120.7 kB)

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