1 /*
2  * e-book-source-config.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17 
18 #include "evolution-config.h"
19 
20 #include "e-book-source-config.h"
21 
22 #include <glib/gi18n-lib.h>
23 
24 #define E_BOOK_SOURCE_CONFIG_GET_PRIVATE(obj) \
25 	(G_TYPE_INSTANCE_GET_PRIVATE \
26 	((obj), E_TYPE_BOOK_SOURCE_CONFIG, EBookSourceConfigPrivate))
27 
28 struct _EBookSourceConfigPrivate {
29 	GtkWidget *default_button;
30 	GtkWidget *autocomplete_button;
31 };
32 
G_DEFINE_TYPE(EBookSourceConfig,e_book_source_config,E_TYPE_SOURCE_CONFIG)33 G_DEFINE_TYPE (
34 	EBookSourceConfig,
35 	e_book_source_config,
36 	E_TYPE_SOURCE_CONFIG)
37 
38 static ESource *
39 book_source_config_ref_default (ESourceConfig *config)
40 {
41 	ESourceRegistry *registry;
42 
43 	registry = e_source_config_get_registry (config);
44 
45 	return e_source_registry_ref_default_address_book (registry);
46 }
47 
48 static void
book_source_config_set_default(ESourceConfig * config,ESource * source)49 book_source_config_set_default (ESourceConfig *config,
50                                 ESource *source)
51 {
52 	ESourceRegistry *registry;
53 
54 	registry = e_source_config_get_registry (config);
55 
56 	e_source_registry_set_default_address_book (registry, source);
57 }
58 
59 static void
book_source_config_dispose(GObject * object)60 book_source_config_dispose (GObject *object)
61 {
62 	EBookSourceConfigPrivate *priv;
63 
64 	priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (object);
65 	g_clear_object (&priv->default_button);
66 	g_clear_object (&priv->autocomplete_button);
67 
68 	/* Chain up to parent's dispose() method. */
69 	G_OBJECT_CLASS (e_book_source_config_parent_class)->dispose (object);
70 }
71 
72 static void
book_source_config_constructed(GObject * object)73 book_source_config_constructed (GObject *object)
74 {
75 	EBookSourceConfigPrivate *priv;
76 	ESource *default_source;
77 	ESource *original_source;
78 	ESourceConfig *config;
79 	GObjectClass *class;
80 	GtkWidget *widget;
81 	const gchar *label;
82 
83 	/* Chain up to parent's constructed() method. */
84 	class = G_OBJECT_CLASS (e_book_source_config_parent_class);
85 	class->constructed (object);
86 
87 	config = E_SOURCE_CONFIG (object);
88 	priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (object);
89 
90 	label = _("Mark as default address book");
91 	widget = gtk_check_button_new_with_label (label);
92 	priv->default_button = g_object_ref_sink (widget);
93 	gtk_widget_show (widget);
94 
95 	label = _("Autocomplete with this address book");
96 	widget = gtk_check_button_new_with_label (label);
97 	priv->autocomplete_button = g_object_ref_sink (widget);
98 	gtk_widget_show (widget);
99 
100 	default_source = book_source_config_ref_default (config);
101 	original_source = e_source_config_get_original_source (config);
102 
103 	if (original_source != NULL) {
104 		gboolean active;
105 
106 		active = e_source_equal (original_source, default_source);
107 		g_object_set (priv->default_button, "active", active, NULL);
108 	}
109 
110 	g_object_unref (default_source);
111 
112 	e_source_config_insert_widget (
113 		config, NULL, NULL, priv->default_button);
114 
115 	e_source_config_insert_widget (
116 		config, NULL, NULL, priv->autocomplete_button);
117 }
118 
119 static const gchar *
book_source_config_get_backend_extension_name(ESourceConfig * config)120 book_source_config_get_backend_extension_name (ESourceConfig *config)
121 {
122 	return E_SOURCE_EXTENSION_ADDRESS_BOOK;
123 }
124 
125 static GList *
book_source_config_list_eligible_collections(ESourceConfig * config)126 book_source_config_list_eligible_collections (ESourceConfig *config)
127 {
128 	GQueue trash = G_QUEUE_INIT;
129 	GList *list, *link;
130 
131 	/* Chain up to parent's list_eligible_collections() method. */
132 	list = E_SOURCE_CONFIG_CLASS (e_book_source_config_parent_class)->
133 		list_eligible_collections (config);
134 
135 	for (link = list; link != NULL; link = g_list_next (link)) {
136 		ESource *source = E_SOURCE (link->data);
137 		ESourceCollection *extension;
138 		const gchar *extension_name;
139 
140 		extension_name = E_SOURCE_EXTENSION_COLLECTION;
141 		extension = e_source_get_extension (source, extension_name);
142 
143 		if (!e_source_collection_get_contacts_enabled (extension))
144 			g_queue_push_tail (&trash, link);
145 	}
146 
147 	/* Remove ineligible collections from the list. */
148 	while ((link = g_queue_pop_head (&trash)) != NULL) {
149 		g_object_unref (link->data);
150 		list = g_list_delete_link (list, link);
151 	}
152 
153 	return list;
154 }
155 
156 static void
book_source_config_init_candidate(ESourceConfig * config,ESource * scratch_source)157 book_source_config_init_candidate (ESourceConfig *config,
158                                    ESource *scratch_source)
159 {
160 	EBookSourceConfigPrivate *priv;
161 	ESourceConfigClass *class;
162 	ESourceExtension *extension;
163 	const gchar *extension_name;
164 
165 	/* Chain up to parent's init_candidate() method. */
166 	class = E_SOURCE_CONFIG_CLASS (e_book_source_config_parent_class);
167 	class->init_candidate (config, scratch_source);
168 
169 	priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (config);
170 
171 	extension_name = E_SOURCE_EXTENSION_AUTOCOMPLETE;
172 	extension = e_source_get_extension (scratch_source, extension_name);
173 
174 	e_binding_bind_property (
175 		extension, "include-me",
176 		priv->autocomplete_button, "active",
177 		G_BINDING_BIDIRECTIONAL |
178 		G_BINDING_SYNC_CREATE);
179 }
180 
181 static void
book_source_config_commit_changes(ESourceConfig * config,ESource * scratch_source)182 book_source_config_commit_changes (ESourceConfig *config,
183                                    ESource *scratch_source)
184 {
185 	EBookSourceConfigPrivate *priv;
186 	ESourceConfigClass *class;
187 	ESource *default_source;
188 	GtkToggleButton *toggle_button;
189 
190 	priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (config);
191 	toggle_button = GTK_TOGGLE_BUTTON (priv->default_button);
192 
193 	/* Chain up to parent's commit_changes() method. */
194 	class = E_SOURCE_CONFIG_CLASS (e_book_source_config_parent_class);
195 	class->commit_changes (config, scratch_source);
196 
197 	default_source = book_source_config_ref_default (config);
198 
199 	/* The default setting is a little tricky to get right.  If
200 	 * the toggle button is active, this ESource is now the default.
201 	 * That much is simple.  But if the toggle button is NOT active,
202 	 * then we have to inspect the old default.  If this ESource WAS
203 	 * the default, reset the default to 'system'.  If this ESource
204 	 * WAS NOT the old default, leave it alone. */
205 	if (gtk_toggle_button_get_active (toggle_button))
206 		book_source_config_set_default (config, scratch_source);
207 	else if (e_source_equal (scratch_source, default_source))
208 		book_source_config_set_default (config, NULL);
209 
210 	g_object_unref (default_source);
211 }
212 
213 static void
e_book_source_config_class_init(EBookSourceConfigClass * class)214 e_book_source_config_class_init (EBookSourceConfigClass *class)
215 {
216 	GObjectClass *object_class;
217 	ESourceConfigClass *source_config_class;
218 
219 	g_type_class_add_private (class, sizeof (EBookSourceConfigPrivate));
220 
221 	object_class = G_OBJECT_CLASS (class);
222 	object_class->dispose = book_source_config_dispose;
223 	object_class->constructed = book_source_config_constructed;
224 
225 	source_config_class = E_SOURCE_CONFIG_CLASS (class);
226 	source_config_class->get_backend_extension_name =
227 		book_source_config_get_backend_extension_name;
228 	source_config_class->list_eligible_collections =
229 		book_source_config_list_eligible_collections;
230 	source_config_class->init_candidate = book_source_config_init_candidate;
231 	source_config_class->commit_changes = book_source_config_commit_changes;
232 }
233 
234 static void
e_book_source_config_init(EBookSourceConfig * config)235 e_book_source_config_init (EBookSourceConfig *config)
236 {
237 	config->priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (config);
238 }
239 
240 GtkWidget *
e_book_source_config_new(ESourceRegistry * registry,ESource * original_source)241 e_book_source_config_new (ESourceRegistry *registry,
242                           ESource *original_source)
243 {
244 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
245 
246 	if (original_source != NULL)
247 		g_return_val_if_fail (E_IS_SOURCE (original_source), NULL);
248 
249 	return g_object_new (
250 		E_TYPE_BOOK_SOURCE_CONFIG, "registry", registry,
251 		"original-source", original_source, NULL);
252 }
253 
254 void
e_book_source_config_add_offline_toggle(EBookSourceConfig * config,ESource * scratch_source)255 e_book_source_config_add_offline_toggle (EBookSourceConfig *config,
256                                          ESource *scratch_source)
257 {
258 	GtkWidget *widget;
259 	ESourceExtension *extension;
260 	const gchar *extension_name;
261 
262 	g_return_if_fail (E_IS_BOOK_SOURCE_CONFIG (config));
263 	g_return_if_fail (E_IS_SOURCE (scratch_source));
264 
265 	extension_name = E_SOURCE_EXTENSION_OFFLINE;
266 	extension = e_source_get_extension (scratch_source, extension_name);
267 
268 	widget = gtk_check_button_new_with_label (
269 		_("Copy book content locally for offline operation"));
270 	e_source_config_insert_widget (
271 		E_SOURCE_CONFIG (config), scratch_source, NULL, widget);
272 	gtk_widget_show (widget);
273 
274 	e_binding_bind_property (
275 		extension, "stay-synchronized",
276 		widget, "active",
277 		G_BINDING_BIDIRECTIONAL |
278 		G_BINDING_SYNC_CREATE);
279 }
280