Statistics
| Revision:

root / src / addressadd.c @ 2481

History | View | Annotate | Download (13 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 2001 Match Grun
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
/*
21
 * Add address to address book dialog.
22
 */
23
24
#ifdef HAVE_CONFIG_H
25
#  include "config.h"
26
#endif
27
28
#include "defs.h"
29
30
#include <glib.h>
31
#include <glib/gi18n.h>
32
#include <gdk/gdkkeysyms.h>
33
#include <gtk/gtkwindow.h>
34
#include <gtk/gtksignal.h>
35
#include <gtk/gtkvbox.h>
36
#include <gtk/gtkhbox.h>
37
#include <gtk/gtklabel.h>
38
#include <gtk/gtkentry.h>
39
#include <gtk/gtkhbbox.h>
40
#include <gtk/gtkbutton.h>
41
#include <gtk/gtktable.h>
42
#include <gtk/gtkhseparator.h>
43
#include <gtk/gtkstock.h>
44
45
#include "gtkutils.h"
46
#include "stock_pixmap.h"
47
#include "prefs_common.h"
48
#include "addressadd.h"
49
#include "addritem.h"
50
#include "addrbook.h"
51
#include "addrindex.h"
52
#include "editaddress.h"
53
#include "manage_window.h"
54
#include "utils.h"
55
56
typedef struct {
57
        AddressBookFile        *book;
58
        ItemFolder        *folder;
59
} FolderInfo;
60
61
static struct _AddressAdd_dlg {
62
        GtkWidget *window;
63
        GtkWidget *label_name;
64
        GtkWidget *label_address;
65
        GtkWidget *label_remarks;
66
        GtkWidget *tree_folder;
67
        GtkWidget *ok_btn;
68
        GtkWidget *cancel_btn;
69
        FolderInfo *fiSelected;
70
} addressadd_dlg;
71
72
static GdkPixmap *folderXpm;
73
static GdkBitmap *folderXpmMask;
74
static GdkPixmap *bookXpm;
75
static GdkBitmap *bookXpmMask;
76
77
static gboolean addressadd_cancelled;
78
79
static FolderInfo *addressadd_create_folderinfo( AddressBookFile *abf, ItemFolder *folder )
80
{
81
        FolderInfo *fi = g_new0( FolderInfo, 1 );
82
        fi->book   = abf;
83
        fi->folder = folder;
84
        return fi;
85
}
86
87
static void addressadd_free_folderinfo( FolderInfo *fi ) {
88
        fi->book   = NULL;
89
        fi->folder = NULL;
90
        g_free( fi );
91
}
92
93
static gint addressadd_delete_event( GtkWidget *widget, GdkEventAny *event, gboolean *cancelled ) {
94
        addressadd_cancelled = TRUE;
95
        gtk_main_quit();
96
        return TRUE;
97
}
98
99
static gboolean addressadd_key_pressed( GtkWidget *widget, GdkEventKey *event, gboolean *cancelled ) {
100
        if (event && event->keyval == GDK_Escape) {
101
                addressadd_cancelled = TRUE;
102
                gtk_main_quit();
103
        }
104
        return FALSE;
105
}
106
107
static void addressadd_ok( GtkWidget *widget, gboolean *cancelled ) {
108
        addressadd_cancelled = FALSE;
109
        gtk_main_quit();
110
}
111
112
static void addressadd_cancel( GtkWidget *widget, gboolean *cancelled ) {
113
        addressadd_cancelled = TRUE;
114
        gtk_main_quit();
115
}
116
117
static void addressadd_folder_select( GtkCTree *ctree, gint row, gint column,
118
                                        GdkEvent *event, gpointer data )
119
{
120
        addressadd_dlg.fiSelected = gtk_clist_get_row_data( GTK_CLIST(ctree), row );
121
}
122
123
static gboolean addressadd_tree_button( GtkCTree *ctree, GdkEventButton *event, gpointer data ) {
124
        if( ! event ) return FALSE;
125
        if( event->button == 1 ) {
126
                /* Handle double click */
127
                if( event->type == GDK_2BUTTON_PRESS ) {
128
                        addressadd_cancelled = FALSE;
129
                        gtk_main_quit();
130
                }
131
        }
132
133
        return FALSE;
134
}
135
136
static void addressadd_create( void ) {
137
        GtkWidget *window;
138
        GtkWidget *vbox;
139
        GtkWidget *table;
140
        GtkWidget *label;
141
        GtkWidget *label_name;
142
        GtkWidget *label_addr;
143
        GtkWidget *label_rems;
144
        GtkWidget *tree_folder;
145
        GtkWidget *vlbox;
146
        GtkWidget *tree_win;
147
        GtkWidget *hbbox;
148
        GtkWidget *hsep;
149
        GtkWidget *ok_btn;
150
        GtkWidget *cancel_btn;
151
        gint top;
152
153
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
154
        gtk_widget_set_size_request(window, 300, 360);
155
        gtk_container_set_border_width(GTK_CONTAINER(window), 0);
156
        gtk_window_set_title(GTK_WINDOW(window), _("Add Address to Book"));
157
        gtk_window_set_position(GTK_WINDOW(window),
158
                                GTK_WIN_POS_CENTER_ON_PARENT);
159
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
160
        gtk_widget_realize(window);
161
        g_signal_connect(G_OBJECT(window), "delete_event",
162
                         G_CALLBACK(addressadd_delete_event), NULL);
163
        g_signal_connect(G_OBJECT(window), "key_press_event",
164
                         G_CALLBACK(addressadd_key_pressed), NULL);
165
166
        vbox = gtk_vbox_new(FALSE, 4);
167
        gtk_container_add(GTK_CONTAINER(window), vbox);
168
        gtk_container_set_border_width( GTK_CONTAINER(vbox), 0 );
169
170
        table = gtk_table_new(3, 2, FALSE);
171
        gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
172
        gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
173
        gtk_table_set_row_spacings(GTK_TABLE(table), 4);
174
        gtk_table_set_col_spacings(GTK_TABLE(table), 4);
175
176
        /* First row */
177
        top = 0;
178
        label = gtk_label_new(_("Name"));
179
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
180
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
181
182
        label_name = gtk_label_new("");
183
        gtk_table_attach(GTK_TABLE(table), label_name, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
184
        gtk_misc_set_alignment(GTK_MISC(label_name), 0, 0.5);
185
186
        /* Second row */
187
        top = 1;
188
        label = gtk_label_new(_("Address"));
189
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
190
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
191
192
        label_addr = gtk_label_new("");
193
        gtk_table_attach(GTK_TABLE(table), label_addr, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
194
        gtk_misc_set_alignment(GTK_MISC(label_addr), 0, 0.5);
195
196
        /* Third row */
197
        top = 2;
198
        label = gtk_label_new(_("Remarks"));
199
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
200
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
201
202
        label_rems = gtk_label_new("");
203
        gtk_table_attach(GTK_TABLE(table), label_rems, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
204
        gtk_misc_set_alignment(GTK_MISC(label_rems), 0, 0.5);
205
206
        /* Address book/folder tree */
207
        vlbox = gtk_vbox_new(FALSE, 4);
208
        gtk_box_pack_start(GTK_BOX(vbox), vlbox, TRUE, TRUE, 0);
209
        gtk_container_set_border_width( GTK_CONTAINER(vlbox), 4 );
210
211
        tree_win = gtk_scrolled_window_new( NULL, NULL );
212
        gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(tree_win),
213
                                        GTK_POLICY_AUTOMATIC,
214
                                        GTK_POLICY_AUTOMATIC );
215
        gtk_box_pack_start( GTK_BOX(vlbox), tree_win, TRUE, TRUE, 0 );
216
217
        tree_folder = gtk_ctree_new( 1, 0 );
218
        gtk_container_add( GTK_CONTAINER(tree_win), tree_folder );
219
        gtk_clist_column_titles_show( GTK_CLIST(tree_folder) );
220
        gtk_clist_set_column_title( GTK_CLIST(tree_folder), 0, _( "Select Address Book Folder" ) );
221
        gtk_ctree_set_line_style( GTK_CTREE(tree_folder), GTK_CTREE_LINES_DOTTED );
222
        gtk_clist_set_selection_mode( GTK_CLIST(tree_folder), GTK_SELECTION_BROWSE );
223
        gtk_ctree_set_expander_style( GTK_CTREE(tree_folder), GTK_CTREE_EXPANDER_SQUARE );
224
        gtk_ctree_set_indent( GTK_CTREE(tree_folder), CTREE_INDENT );
225
        gtk_clist_set_auto_sort( GTK_CLIST(tree_folder), TRUE );
226
        gtkut_clist_set_redraw( GTK_CLIST(tree_folder) );
227
228
        /* Button panel */
229
        gtkut_stock_button_set_create(&hbbox, &ok_btn, GTK_STOCK_OK,
230
                                      &cancel_btn, GTK_STOCK_CANCEL,
231
                                      NULL, NULL);
232
        gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
233
        gtk_container_set_border_width( GTK_CONTAINER(hbbox), 4 );
234
        gtk_widget_grab_default(ok_btn);
235
236
        hsep = gtk_hseparator_new();
237
        gtk_box_pack_end(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
238
239
        g_signal_connect(G_OBJECT(ok_btn), "clicked",
240
                         G_CALLBACK(addressadd_ok), NULL);
241
        g_signal_connect(G_OBJECT(cancel_btn), "clicked",
242
                         G_CALLBACK(addressadd_cancel), NULL);
243
        g_signal_connect(G_OBJECT(tree_folder), "select_row",
244
                         G_CALLBACK(addressadd_folder_select), NULL);
245
        g_signal_connect(G_OBJECT(tree_folder), "button_press_event",
246
                         G_CALLBACK(addressadd_tree_button), NULL);
247
248
        addressadd_dlg.window        = window;
249
        addressadd_dlg.label_name    = label_name;
250
        addressadd_dlg.label_address = label_addr;
251
        addressadd_dlg.label_remarks = label_rems;
252
        addressadd_dlg.tree_folder   = tree_folder;
253
        addressadd_dlg.ok_btn        = ok_btn;
254
        addressadd_dlg.cancel_btn    = cancel_btn;
255
256
        gtk_widget_show_all(vbox);
257
258
        stock_pixmap_gdk(window, STOCK_PIXMAP_BOOK, &bookXpm, &bookXpmMask);
259
        stock_pixmap_gdk(window, STOCK_PIXMAP_FOLDER_OPEN,
260
                         &folderXpm, &folderXpmMask);
261
}
262
263
static void addressadd_load_folder( GtkCTreeNode *parentNode, ItemFolder *parentFolder,
264
                                        FolderInfo *fiParent )
265
{
266
        GtkCTree *tree = GTK_CTREE( addressadd_dlg.tree_folder );
267
        GList *list;
268
        ItemFolder *folder;
269
        gchar *fName;
270
        gchar **name;
271
        GtkCTreeNode *node;
272
        FolderInfo *fi;
273
274
        list = parentFolder->listFolder;
275
        while( list ) {
276
                folder = list->data;
277
                fName = g_strdup( ADDRITEM_NAME(folder) );
278
                name = &fName;
279
                node = gtk_ctree_insert_node( tree, parentNode, NULL, name, FOLDER_SPACING,
280
                                folderXpm, folderXpmMask, folderXpm, folderXpmMask,
281
                                FALSE, TRUE );
282
                g_free( fName );
283
                fi = addressadd_create_folderinfo( fiParent->book, folder );
284
                gtk_ctree_node_set_row_data_full( tree, node, fi,
285
                                ( GtkDestroyNotify ) addressadd_free_folderinfo );
286
                addressadd_load_folder( node, folder, fi );
287
                list = g_list_next( list );
288
        }
289
}
290
291
static void addressadd_load_data( AddressIndex *addrIndex ) {
292
        AddressDataSource *ds;
293
        GList *list, *nodeDS;
294
        gchar **name;
295
        gchar *dsName;
296
        ItemFolder *rootFolder;
297
        AddressBookFile *abf;
298
        FolderInfo *fi;
299
        GtkCTree *tree = GTK_CTREE( addressadd_dlg.tree_folder );
300
        GtkCTreeNode *node;
301
302
        gtk_clist_clear( GTK_CLIST( tree ) );
303
        list = addrindex_get_interface_list( addrIndex );
304
        while( list ) {
305
                AddressInterface *interface = list->data;
306
                if( interface->type == ADDR_IF_BOOK ) {
307
                        nodeDS = interface->listSource;
308
                        while( nodeDS ) {
309
                                ds = nodeDS->data;
310
                                if ( !strcmp( addrindex_ds_get_name( ds ), ADDR_DS_AUTOREG ) )
311
                                        dsName = g_strdup( _("Auto-registered address") );
312
                                else
313
                                        dsName = g_strdup( addrindex_ds_get_name( ds ) );
314
315
                                /* Read address book */
316
                                if( ! addrindex_ds_get_read_flag( ds ) ) {
317
                                        addrindex_ds_read_data( ds );
318
                                }
319
320
                                /* Add node for address book */
321
                                abf = ds->rawDataSource;
322
                                name = &dsName;
323
                                node = gtk_ctree_insert_node( tree, NULL, NULL,
324
                                                name, FOLDER_SPACING, bookXpm,
325
                                                bookXpmMask, bookXpm, bookXpmMask,
326
                                                FALSE, TRUE );
327
                                g_free( dsName );
328
329
                                fi = addressadd_create_folderinfo( abf, NULL );
330
                                gtk_ctree_node_set_row_data_full( tree, node, fi,
331
                                                ( GtkDestroyNotify ) addressadd_free_folderinfo );
332
333
                                rootFolder = addrindex_ds_get_root_folder( ds );
334
                                addressadd_load_folder( node, rootFolder, fi );
335
336
                                nodeDS = g_list_next( nodeDS );
337
                        }
338
                }
339
                list = g_list_next( list );
340
        }
341
}
342
343
gboolean addressadd_selection( AddressIndex *addrIndex, const gchar *name, const gchar *address, const gchar *remarks ) {
344
        gboolean retVal = FALSE;
345
        ItemPerson *person = NULL;
346
347
        addressadd_cancelled = FALSE;
348
        if( ! addressadd_dlg.window ) addressadd_create();
349
        gtk_widget_grab_focus(addressadd_dlg.ok_btn);
350
        manage_window_set_transient(GTK_WINDOW(addressadd_dlg.window));
351
        gtk_widget_show(addressadd_dlg.window);
352
353
        addressadd_dlg.fiSelected = NULL;
354
        addressadd_load_data( addrIndex );
355
        gtk_clist_select_row( GTK_CLIST( addressadd_dlg.tree_folder ), 0, 0 );
356
        gtk_widget_show(addressadd_dlg.window);
357
358
        gtk_label_set_text( GTK_LABEL(addressadd_dlg.label_name ), "" );
359
        gtk_label_set_text( GTK_LABEL(addressadd_dlg.label_address ), "" );
360
        gtk_label_set_text( GTK_LABEL(addressadd_dlg.label_remarks ), "" );
361
        if( name )
362
                gtk_label_set_text( GTK_LABEL(addressadd_dlg.label_name ), name );
363
        if( address )
364
                gtk_label_set_text( GTK_LABEL(addressadd_dlg.label_address ), address );
365
        if( remarks )
366
                gtk_label_set_text( GTK_LABEL(addressadd_dlg.label_remarks ), remarks );
367
368
        if( ! name )
369
                name = "";
370
371
        gtk_main();
372
        gtk_widget_hide( addressadd_dlg.window );
373
374
        if( ! addressadd_cancelled ) {
375
                if( addressadd_dlg.fiSelected ) {
376
                        FolderInfo *fi = addressadd_dlg.fiSelected;
377
                        person = addrbook_add_contact( fi->book, fi->folder, name, address, remarks );
378
                        if( person ) {
379
                                if( addressbook_edit_person( fi->book, NULL, person, FALSE ) == NULL )
380
                                        addrbook_remove_person( fi->book, person );
381
                                else
382
                                        retVal = TRUE;
383
                        }
384
                }
385
        }
386
387
        gtk_clist_clear( GTK_CLIST( addressadd_dlg.tree_folder ) );
388
389
        return retVal;
390
}
391
392
gboolean addressadd_autoreg(AddressIndex *addrIndex, const gchar *name,
393
                            const gchar *address, const gchar *remarks)
394
{
395
        ItemPerson *person = NULL;
396
        AddressInterface *interface = NULL;
397
        AddressDataSource *ds = NULL;
398
        AddressBookFile *abf = NULL;
399
        GList *node_ds;
400
        const gchar *ds_name;
401
402
        g_return_val_if_fail(address != NULL, FALSE);
403
404
        if (!name)
405
                name = "";
406
407
        interface = addrindex_get_interface(addrIndex, ADDR_IF_BOOK);
408
        if (!interface)
409
                return FALSE;
410
411
        for (node_ds = interface->listSource; node_ds != NULL;
412
             node_ds = node_ds->next) {
413
                ds = node_ds->data;
414
                ds_name = addrindex_ds_get_name(ds);
415
                if (!ds_name)
416
                        continue;
417
                if (strcmp(ds_name, ADDR_DS_AUTOREG) != 0)
418
                        continue;
419
                debug_print("addressadd_autoreg: AddressDataSource: %s found\n", ds_name);
420
421
                if (!addrindex_ds_get_read_flag(ds))
422
                        addrindex_ds_read_data(ds);
423
                abf = ds->rawDataSource;
424
        }
425
426
        if (!abf)
427
                return FALSE;
428
429
        person = addrbook_add_contact(abf, NULL, name, address, remarks);
430
        if (person) {
431
                debug_print("addressadd_autoreg: person added: %s <%s>\n",
432
                            name, address);
433
                return TRUE;
434
        }
435
436
        return FALSE;
437
}
438
439
/*
440
* End of Source.
441
*/
442