1 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
2 /* Balsa E-Mail Client
3  *
4  * Copyright (C) 1997-2013 Stuart Parmenter and others,
5  *                         See the file AUTHORS for a list.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20  * 02111-1307, USA.
21  */
22 
23 #if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
24 # include "config.h"
25 #endif                          /* HAVE_CONFIG_H */
26 #include "address-book.h"
27 
28 #include <gtk/gtk.h>
29 #include <glib/gi18n.h>
30 
31 #include "libbalsa-marshal.h"
32 #include "libbalsa-conf.h"
33 
34 static GObjectClass *parent_class = NULL;
35 
36 static void libbalsa_address_book_class_init(LibBalsaAddressBookClass *
37 					     klass);
38 static void libbalsa_address_book_init(LibBalsaAddressBook * ab);
39 static void libbalsa_address_book_finalize(GObject * object);
40 
41 static void libbalsa_address_book_real_save_config(LibBalsaAddressBook *
42 						   ab,
43 						   const gchar * group);
44 static void libbalsa_address_book_real_load_config(LibBalsaAddressBook *
45 						   ab,
46 						   const gchar * group);
47 
libbalsa_address_book_get_type(void)48 GType libbalsa_address_book_get_type(void)
49 {
50     static GType address_book_type = 0;
51 
52     if (!address_book_type) {
53 	static const GTypeInfo address_book_info = {
54 	    sizeof(LibBalsaAddressBookClass),
55             NULL,               /* base_init */
56             NULL,               /* base_finalize */
57 	    (GClassInitFunc) libbalsa_address_book_class_init,
58             NULL,               /* class_finalize */
59             NULL,               /* class_data */
60 	    sizeof(LibBalsaAddressBook),
61             0,                  /* n_preallocs */
62 	    (GInstanceInitFunc) libbalsa_address_book_init
63 	};
64 
65 	address_book_type =
66 	    g_type_register_static(G_TYPE_OBJECT,
67                                    "LibBalsaAddressBook",
68                                    &address_book_info, 0);
69     }
70 
71     return address_book_type;
72 }
73 
74 static void
libbalsa_address_book_class_init(LibBalsaAddressBookClass * klass)75 libbalsa_address_book_class_init(LibBalsaAddressBookClass * klass)
76 {
77     GObjectClass *object_class;
78 
79     parent_class = g_type_class_peek_parent(klass);
80 
81     object_class = G_OBJECT_CLASS(klass);
82 
83     klass->load = NULL;
84     klass->add_address = NULL;
85     klass->remove_address = NULL;
86     klass->modify_address = NULL;
87     klass->save_config = libbalsa_address_book_real_save_config;
88     klass->load_config = libbalsa_address_book_real_load_config;
89     klass->alias_complete = NULL;
90 
91     object_class->finalize = libbalsa_address_book_finalize;
92 }
93 
94 static void
libbalsa_address_book_init(LibBalsaAddressBook * ab)95 libbalsa_address_book_init(LibBalsaAddressBook * ab)
96 {
97     ab->config_prefix = NULL;
98 
99     ab->name = NULL;
100     ab->expand_aliases = TRUE;
101     ab->dist_list_mode = FALSE;
102     ab->is_expensive   = FALSE;
103 }
104 
105 static void
libbalsa_address_book_finalize(GObject * object)106 libbalsa_address_book_finalize(GObject * object)
107 {
108     LibBalsaAddressBook *ab;
109 
110     ab = LIBBALSA_ADDRESS_BOOK(object);
111 
112     g_free(ab->config_prefix);
113     ab->config_prefix = NULL;
114 
115     g_free(ab->name);
116     ab->name = NULL;
117 
118     G_OBJECT_CLASS(parent_class)->finalize(object);
119 }
120 
121 LibBalsaAddressBook *
libbalsa_address_book_new_from_config(const gchar * group)122 libbalsa_address_book_new_from_config(const gchar * group)
123 {
124     gchar *type_str;
125     GType type;
126     gboolean got_default;
127     LibBalsaAddressBook *address_book = NULL;
128 
129     libbalsa_conf_push_group(group);
130     type_str = libbalsa_conf_get_string_with_default("Type", &got_default);
131 
132     if (got_default == TRUE) {
133         /* type entry missing, skip it */
134 	libbalsa_conf_pop_group();
135 	return NULL;
136     }
137 
138     type = g_type_from_name(type_str);
139     if (type == 0) {
140         /* type unknown, skip it */
141 	g_free(type_str);
142 	libbalsa_conf_pop_group();
143 	return NULL;
144     }
145 
146     address_book = g_object_new(type, NULL);
147     libbalsa_address_book_load_config(address_book, group);
148 
149     libbalsa_conf_pop_group();
150     g_free(type_str);
151 
152     return address_book;
153 
154 }
155 
156 LibBalsaABErr
libbalsa_address_book_load(LibBalsaAddressBook * ab,const gchar * filter,LibBalsaAddressBookLoadFunc callback,gpointer closure)157 libbalsa_address_book_load(LibBalsaAddressBook * ab,
158                            const gchar * filter,
159                            LibBalsaAddressBookLoadFunc callback,
160                            gpointer closure)
161 {
162     g_return_val_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab), LBABERR_OK);
163 
164     return LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->load(ab, filter, callback,
165                                                      closure);
166 }
167 
168 LibBalsaABErr
libbalsa_address_book_add_address(LibBalsaAddressBook * ab,LibBalsaAddress * address)169 libbalsa_address_book_add_address(LibBalsaAddressBook * ab,
170                                   LibBalsaAddress * address)
171 {
172     g_return_val_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab), LBABERR_OK);
173     g_return_val_if_fail(LIBBALSA_IS_ADDRESS(address), LBABERR_OK);
174 
175     return LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->add_address(ab, address);
176 }
177 
178 LibBalsaABErr
libbalsa_address_book_remove_address(LibBalsaAddressBook * ab,LibBalsaAddress * address)179 libbalsa_address_book_remove_address(LibBalsaAddressBook * ab,
180                                      LibBalsaAddress * address)
181 {
182     g_return_val_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab), LBABERR_OK);
183     g_return_val_if_fail(LIBBALSA_IS_ADDRESS(address), LBABERR_OK);
184 
185     return LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->remove_address(ab,
186                                                                address);
187 }
188 
189 LibBalsaABErr
libbalsa_address_book_modify_address(LibBalsaAddressBook * ab,LibBalsaAddress * address,LibBalsaAddress * newval)190 libbalsa_address_book_modify_address(LibBalsaAddressBook * ab,
191                                      LibBalsaAddress * address,
192                                      LibBalsaAddress * newval)
193 {
194     LibBalsaABErr res;
195 
196     g_return_val_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab), LBABERR_OK);
197     g_return_val_if_fail(LIBBALSA_IS_ADDRESS(address), LBABERR_OK);
198 
199     res =
200         LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->modify_address(ab, address,
201                                                             newval);
202     if (res == LBABERR_OK)
203         libbalsa_address_set_copy(address, newval);
204 
205     return res;
206 }
207 
208 /* set_status takes over the string ownership */
209 void
libbalsa_address_book_set_status(LibBalsaAddressBook * ab,gchar * str)210 libbalsa_address_book_set_status(LibBalsaAddressBook * ab, gchar *str)
211 {
212     g_return_if_fail(ab);
213     g_free(ab->ext_op_code);
214     ab->ext_op_code = str;
215 }
216 
217 void
libbalsa_address_book_save_config(LibBalsaAddressBook * ab,const gchar * group)218 libbalsa_address_book_save_config(LibBalsaAddressBook * ab,
219                                   const gchar * group)
220 {
221     g_return_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab));
222 
223     libbalsa_conf_private_remove_group(group);
224     libbalsa_conf_remove_group(group);
225 
226     libbalsa_conf_push_group(group);
227     LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->save_config(ab, group);
228     libbalsa_conf_pop_group();
229 }
230 
231 void
libbalsa_address_book_load_config(LibBalsaAddressBook * ab,const gchar * group)232 libbalsa_address_book_load_config(LibBalsaAddressBook * ab,
233 				  const gchar * group)
234 {
235     g_return_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab));
236 
237     libbalsa_conf_push_group(group);
238     LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->load_config(ab, group);
239     libbalsa_conf_pop_group();
240 
241     if (ab->is_expensive < 0)
242         ab->is_expensive = FALSE;
243 }
244 
245 GList *
libbalsa_address_book_alias_complete(LibBalsaAddressBook * ab,const gchar * prefix)246 libbalsa_address_book_alias_complete(LibBalsaAddressBook * ab,
247                                      const gchar * prefix)
248 {
249     g_return_val_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab), NULL);
250 
251     return LIBBALSA_ADDRESS_BOOK_GET_CLASS(ab)->alias_complete(ab, prefix);
252 }
253 
254 
libbalsa_address_is_dist_list(const LibBalsaAddressBook * ab,const LibBalsaAddress * address)255 gboolean libbalsa_address_is_dist_list(const LibBalsaAddressBook *ab,
256 				       const LibBalsaAddress *address)
257 {
258     return (ab->dist_list_mode && g_list_length(address->address_list)>1);
259 }
260 
261 
262 
263 static void
libbalsa_address_book_real_save_config(LibBalsaAddressBook * ab,const gchar * group)264 libbalsa_address_book_real_save_config(LibBalsaAddressBook * ab,
265 				       const gchar * group)
266 {
267     g_return_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab));
268 
269     libbalsa_conf_set_string("Type", g_type_name(G_OBJECT_TYPE(ab)));
270     libbalsa_conf_set_string("Name", ab->name);
271     libbalsa_conf_set_bool("ExpandAliases", ab->expand_aliases);
272     libbalsa_conf_set_bool("IsExpensive", ab->is_expensive);
273     libbalsa_conf_set_bool("DistListMode", ab->dist_list_mode);
274 
275     g_free(ab->config_prefix);
276     ab->config_prefix = g_strdup(group);
277 }
278 
279 static void
libbalsa_address_book_real_load_config(LibBalsaAddressBook * ab,const gchar * group)280 libbalsa_address_book_real_load_config(LibBalsaAddressBook * ab,
281 				       const gchar * group)
282 {
283     gboolean def;
284 
285     g_return_if_fail(LIBBALSA_IS_ADDRESS_BOOK(ab));
286 
287     g_free(ab->config_prefix);
288     ab->config_prefix = g_strdup(group);
289 
290     ab->expand_aliases = libbalsa_conf_get_bool("ExpandAliases=false");
291 
292     ab->is_expensive =
293         libbalsa_conf_get_bool_with_default("IsExpensive", &def);
294     if (def)
295         /* Default will be supplied by the backend, or in
296          * libbalsa_address_book_load_config. */
297         ab->is_expensive = -1;
298 
299     ab->dist_list_mode = libbalsa_conf_get_bool("DistListMode=false");
300 
301     g_free(ab->name);
302     ab->name = libbalsa_conf_get_string("Name=Address Book");
303 }
304 
305 const gchar*
libbalsa_address_book_strerror(LibBalsaAddressBook * ab,LibBalsaABErr err)306 libbalsa_address_book_strerror(LibBalsaAddressBook * ab, LibBalsaABErr err)
307 {
308     const gchar *s;
309     g_return_val_if_fail(ab, NULL);
310     if(ab->ext_op_code)
311 	return ab->ext_op_code;
312 
313     switch(err) {
314     case LBABERR_OK:             s= _("No error"); break;
315     case LBABERR_CANNOT_READ:    s= _("Cannot read from address book"); break;
316     case LBABERR_CANNOT_WRITE:   s= _("Cannot write to address book");  break;
317     case LBABERR_CANNOT_CONNECT: s= _("Cannot connect to the server");  break;
318     case LBABERR_CANNOT_SEARCH:  s= _("Cannot search in the address book");
319         break;
320     case LBABERR_DUPLICATE:      s= _("Cannot add duplicate entry");    break;
321     case LBABERR_ADDRESS_NOT_FOUND:
322         s= _("Cannot find address in address book"); break;
323     default: s= _("Unknown error"); break;
324     }
325     return s;
326 }
327 
328 
329