1 /*
2  * e-mail-signature-combo-box.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 <glib/gi18n-lib.h>
21 
22 #include "e-mail-signature-combo-box.h"
23 
24 #define E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE(obj) \
25 	(G_TYPE_INSTANCE_GET_PRIVATE \
26 	((obj), E_TYPE_MAIL_SIGNATURE_COMBO_BOX, EMailSignatureComboBoxPrivate))
27 
28 #define SOURCE_IS_MAIL_SIGNATURE(source) \
29 	(e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_SIGNATURE))
30 
31 struct _EMailSignatureComboBoxPrivate {
32 	ESourceRegistry *registry;
33 	guint refresh_idle_id;
34 	gchar *identity_uid;
35 	gchar *identity_name;
36 	gchar *identity_address;
37 };
38 
39 enum {
40 	PROP_0,
41 	PROP_IDENTITY_UID,
42 	PROP_IDENTITY_NAME,
43 	PROP_IDENTITY_ADDRESS,
44 	PROP_REGISTRY
45 };
46 
47 enum {
48 	COLUMN_DISPLAY_NAME,
49 	COLUMN_UID
50 };
51 
G_DEFINE_TYPE(EMailSignatureComboBox,e_mail_signature_combo_box,GTK_TYPE_COMBO_BOX)52 G_DEFINE_TYPE (
53 	EMailSignatureComboBox,
54 	e_mail_signature_combo_box,
55 	GTK_TYPE_COMBO_BOX)
56 
57 static gboolean
58 mail_signature_combo_box_refresh_idle_cb (EMailSignatureComboBox *combo_box)
59 {
60 	/* The refresh function will clear the idle ID. */
61 	e_mail_signature_combo_box_refresh (combo_box);
62 
63 	return FALSE;
64 }
65 
66 static void
mail_signature_combo_box_registry_changed(ESourceRegistry * registry,ESource * source,EMailSignatureComboBox * combo_box)67 mail_signature_combo_box_registry_changed (ESourceRegistry *registry,
68                                            ESource *source,
69                                            EMailSignatureComboBox *combo_box)
70 {
71 	/* If the ESource in question has a "Mail Signature" extension,
72 	 * schedule a refresh of the tree model.  Otherwise ignore it.
73 	 * We use an idle callback to limit how frequently we refresh
74 	 * the tree model, in case the registry is emitting lots of
75 	 * signals at once. */
76 
77 	if (!SOURCE_IS_MAIL_SIGNATURE (source))
78 		return;
79 
80 	if (combo_box->priv->refresh_idle_id > 0)
81 		return;
82 
83 	combo_box->priv->refresh_idle_id = g_idle_add (
84 		(GSourceFunc) mail_signature_combo_box_refresh_idle_cb,
85 		combo_box);
86 }
87 
88 static gboolean
mail_signature_combo_box_identity_to_signature(GBinding * binding,const GValue * source_value,GValue * target_value,gpointer user_data)89 mail_signature_combo_box_identity_to_signature (GBinding *binding,
90                                                 const GValue *source_value,
91                                                 GValue *target_value,
92                                                 gpointer user_data)
93 {
94 	EMailSignatureComboBox *combo_box;
95 	ESourceRegistry *registry;
96 	GObject *source_object;
97 	ESource *source;
98 	ESourceMailIdentity *extension;
99 	const gchar *identity_uid;
100 	const gchar *signature_uid = "none";
101 	const gchar *extension_name;
102 
103 	/* Source and target are the same object. */
104 	source_object = g_binding_get_source (binding);
105 	combo_box = E_MAIL_SIGNATURE_COMBO_BOX (source_object);
106 	registry = e_mail_signature_combo_box_get_registry (combo_box);
107 
108 	identity_uid = g_value_get_string (source_value);
109 	if (identity_uid == NULL)
110 		return FALSE;
111 
112 	source = e_source_registry_ref_source (registry, identity_uid);
113 	if (source == NULL)
114 		return FALSE;
115 
116 	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
117 	if (!e_source_has_extension (source, extension_name)) {
118 		g_object_unref (source);
119 		return FALSE;
120 	}
121 
122 	extension = e_source_get_extension (source, extension_name);
123 	signature_uid = e_source_mail_identity_get_signature_uid (extension);
124 	g_value_set_string (target_value, signature_uid);
125 
126 	g_object_unref (source);
127 
128 	return TRUE;
129 }
130 
131 static void
mail_signature_combo_box_set_registry(EMailSignatureComboBox * combo_box,ESourceRegistry * registry)132 mail_signature_combo_box_set_registry (EMailSignatureComboBox *combo_box,
133                                        ESourceRegistry *registry)
134 {
135 	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
136 	g_return_if_fail (combo_box->priv->registry == NULL);
137 
138 	combo_box->priv->registry = g_object_ref (registry);
139 
140 	g_signal_connect (
141 		registry, "source-added",
142 		G_CALLBACK (mail_signature_combo_box_registry_changed),
143 		combo_box);
144 
145 	g_signal_connect (
146 		registry, "source-changed",
147 		G_CALLBACK (mail_signature_combo_box_registry_changed),
148 		combo_box);
149 
150 	g_signal_connect (
151 		registry, "source-removed",
152 		G_CALLBACK (mail_signature_combo_box_registry_changed),
153 		combo_box);
154 }
155 
156 static void
mail_signature_combo_box_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)157 mail_signature_combo_box_set_property (GObject *object,
158                                        guint property_id,
159                                        const GValue *value,
160                                        GParamSpec *pspec)
161 {
162 	switch (property_id) {
163 		case PROP_IDENTITY_UID:
164 			e_mail_signature_combo_box_set_identity_uid (
165 				E_MAIL_SIGNATURE_COMBO_BOX (object),
166 				g_value_get_string (value));
167 			return;
168 
169 		case PROP_IDENTITY_NAME:
170 			e_mail_signature_combo_box_set_identity_name (
171 				E_MAIL_SIGNATURE_COMBO_BOX (object),
172 				g_value_get_string (value));
173 			return;
174 
175 		case PROP_IDENTITY_ADDRESS:
176 			e_mail_signature_combo_box_set_identity_address (
177 				E_MAIL_SIGNATURE_COMBO_BOX (object),
178 				g_value_get_string (value));
179 			return;
180 
181 		case PROP_REGISTRY:
182 			mail_signature_combo_box_set_registry (
183 				E_MAIL_SIGNATURE_COMBO_BOX (object),
184 				g_value_get_object (value));
185 			return;
186 	}
187 
188 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
189 }
190 
191 static void
mail_signature_combo_box_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)192 mail_signature_combo_box_get_property (GObject *object,
193                                        guint property_id,
194                                        GValue *value,
195                                        GParamSpec *pspec)
196 {
197 	switch (property_id) {
198 		case PROP_IDENTITY_UID:
199 			g_value_set_string (
200 				value,
201 				e_mail_signature_combo_box_get_identity_uid (
202 				E_MAIL_SIGNATURE_COMBO_BOX (object)));
203 			return;
204 
205 		case PROP_IDENTITY_NAME:
206 			g_value_set_string (
207 				value,
208 				e_mail_signature_combo_box_get_identity_name (
209 				E_MAIL_SIGNATURE_COMBO_BOX (object)));
210 			return;
211 
212 		case PROP_IDENTITY_ADDRESS:
213 			g_value_set_string (
214 				value,
215 				e_mail_signature_combo_box_get_identity_address (
216 				E_MAIL_SIGNATURE_COMBO_BOX (object)));
217 			return;
218 
219 		case PROP_REGISTRY:
220 			g_value_set_object (
221 				value,
222 				e_mail_signature_combo_box_get_registry (
223 				E_MAIL_SIGNATURE_COMBO_BOX (object)));
224 			return;
225 	}
226 
227 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
228 }
229 
230 static void
mail_signature_combo_box_dispose(GObject * object)231 mail_signature_combo_box_dispose (GObject *object)
232 {
233 	EMailSignatureComboBoxPrivate *priv;
234 
235 	priv = E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE (object);
236 
237 	if (priv->registry != NULL) {
238 		g_signal_handlers_disconnect_matched (
239 			priv->registry, G_SIGNAL_MATCH_DATA,
240 			0, 0, NULL, NULL, object);
241 		g_object_unref (priv->registry);
242 		priv->registry = NULL;
243 	}
244 
245 	if (priv->refresh_idle_id > 0) {
246 		g_source_remove (priv->refresh_idle_id);
247 		priv->refresh_idle_id = 0;
248 	}
249 
250 	/* Chain up to parent's dispose() method. */
251 	G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)->
252 		dispose (object);
253 }
254 
255 static void
mail_signature_combo_box_finalize(GObject * object)256 mail_signature_combo_box_finalize (GObject *object)
257 {
258 	EMailSignatureComboBoxPrivate *priv;
259 
260 	priv = E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE (object);
261 
262 	g_free (priv->identity_uid);
263 	g_free (priv->identity_name);
264 	g_free (priv->identity_address);
265 
266 	/* Chain up to parent's finalize() method. */
267 	G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)->
268 		finalize (object);
269 }
270 
271 static void
mail_signature_combo_box_constructed(GObject * object)272 mail_signature_combo_box_constructed (GObject *object)
273 {
274 	GtkListStore *list_store;
275 	GtkComboBox *combo_box;
276 	GtkCellLayout *cell_layout;
277 	GtkCellRenderer *cell_renderer;
278 
279 	/* Chain up to parent's constructed() method. */
280 	G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)->constructed (object);
281 
282 	combo_box = GTK_COMBO_BOX (object);
283 	cell_layout = GTK_CELL_LAYOUT (object);
284 
285 	list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
286 	gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store));
287 	gtk_combo_box_set_id_column (combo_box, COLUMN_UID);
288 	g_object_unref (list_store);
289 
290 	cell_renderer = gtk_cell_renderer_text_new ();
291 	gtk_cell_layout_pack_start (cell_layout, cell_renderer, TRUE);
292 	gtk_cell_layout_add_attribute (
293 		cell_layout, cell_renderer, "text", COLUMN_DISPLAY_NAME);
294 
295 	e_binding_bind_property_full (
296 		combo_box, "identity-uid",
297 		combo_box, "active-id",
298 		G_BINDING_DEFAULT,
299 		mail_signature_combo_box_identity_to_signature,
300 		NULL,
301 		NULL, (GDestroyNotify) NULL);
302 
303 	e_mail_signature_combo_box_refresh (
304 		E_MAIL_SIGNATURE_COMBO_BOX (object));
305 }
306 
307 static void
e_mail_signature_combo_box_class_init(EMailSignatureComboBoxClass * class)308 e_mail_signature_combo_box_class_init (EMailSignatureComboBoxClass *class)
309 {
310 	GObjectClass *object_class;
311 
312 	g_type_class_add_private (
313 		class, sizeof (EMailSignatureComboBoxPrivate));
314 
315 	object_class = G_OBJECT_CLASS (class);
316 	object_class->set_property = mail_signature_combo_box_set_property;
317 	object_class->get_property = mail_signature_combo_box_get_property;
318 	object_class->dispose = mail_signature_combo_box_dispose;
319 	object_class->finalize = mail_signature_combo_box_finalize;
320 	object_class->constructed = mail_signature_combo_box_constructed;
321 
322 	g_object_class_install_property (
323 		object_class,
324 		PROP_IDENTITY_UID,
325 		g_param_spec_string (
326 			"identity-uid",
327 			"Identity UID",
328 			NULL,
329 			NULL,
330 			G_PARAM_READWRITE |
331 			G_PARAM_STATIC_STRINGS));
332 
333 	g_object_class_install_property (
334 		object_class,
335 		PROP_IDENTITY_NAME,
336 		g_param_spec_string (
337 			"identity-name",
338 			"Identity Name",
339 			NULL,
340 			NULL,
341 			G_PARAM_READWRITE |
342 			G_PARAM_STATIC_STRINGS));
343 
344 	g_object_class_install_property (
345 		object_class,
346 		PROP_IDENTITY_ADDRESS,
347 		g_param_spec_string (
348 			"identity-address",
349 			"Identity Address",
350 			NULL,
351 			NULL,
352 			G_PARAM_READWRITE |
353 			G_PARAM_STATIC_STRINGS));
354 
355 	g_object_class_install_property (
356 		object_class,
357 		PROP_REGISTRY,
358 		g_param_spec_object (
359 			"registry",
360 			"Registry",
361 			NULL,
362 			E_TYPE_SOURCE_REGISTRY,
363 			G_PARAM_READWRITE |
364 			G_PARAM_CONSTRUCT_ONLY |
365 			G_PARAM_STATIC_STRINGS));
366 }
367 
368 static void
e_mail_signature_combo_box_init(EMailSignatureComboBox * combo_box)369 e_mail_signature_combo_box_init (EMailSignatureComboBox *combo_box)
370 {
371 	combo_box->priv = E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE (combo_box);
372 }
373 
374 GtkWidget *
e_mail_signature_combo_box_new(ESourceRegistry * registry)375 e_mail_signature_combo_box_new (ESourceRegistry *registry)
376 {
377 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
378 
379 	return g_object_new (
380 		E_TYPE_MAIL_SIGNATURE_COMBO_BOX,
381 		"registry", registry, NULL);
382 }
383 
384 void
e_mail_signature_combo_box_refresh(EMailSignatureComboBox * combo_box)385 e_mail_signature_combo_box_refresh (EMailSignatureComboBox *combo_box)
386 {
387 	ESourceRegistry *registry;
388 	GtkComboBox *gtk_combo_box;
389 	GtkTreeModel *tree_model;
390 	GtkTreeIter iter;
391 	ESource *source;
392 	GList *list, *link;
393 	const gchar *extension_name;
394 	const gchar *saved_uid;
395 
396 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
397 
398 	if (combo_box->priv->refresh_idle_id > 0) {
399 		g_source_remove (combo_box->priv->refresh_idle_id);
400 		combo_box->priv->refresh_idle_id = 0;
401 	}
402 
403 	gtk_combo_box = GTK_COMBO_BOX (combo_box);
404 	tree_model = gtk_combo_box_get_model (gtk_combo_box);
405 
406 	/* This is an interned string, which means it's safe
407 	 * to use even after clearing the combo box model. */
408 	saved_uid = gtk_combo_box_get_active_id (gtk_combo_box);
409 
410 	gtk_list_store_clear (GTK_LIST_STORE (tree_model));
411 
412 	extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
413 	registry = e_mail_signature_combo_box_get_registry (combo_box);
414 	list = e_source_registry_list_sources (registry, extension_name);
415 
416 	/* The "None" option always comes first. */
417 
418 	gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
419 
420 	gtk_list_store_set (
421 		GTK_LIST_STORE (tree_model), &iter,
422 		COLUMN_DISPLAY_NAME, _("None"),
423 		COLUMN_UID, "none", -1);
424 
425 	/* The "autogenerated" UID has special meaning. */
426 
427 	gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
428 
429 	gtk_list_store_set (
430 		GTK_LIST_STORE (tree_model), &iter,
431 		COLUMN_DISPLAY_NAME, _("Autogenerated"),
432 		COLUMN_UID, E_MAIL_SIGNATURE_AUTOGENERATED_UID, -1);
433 
434 	/* Followed by the other mail signatures, alphabetized. */
435 
436 	for (link = list; link != NULL; link = g_list_next (link)) {
437 		GtkTreeIter iter;
438 		const gchar *display_name;
439 		const gchar *uid;
440 
441 		source = E_SOURCE (link->data);
442 		display_name = e_source_get_display_name (source);
443 		uid = e_source_get_uid (source);
444 
445 		gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
446 
447 		gtk_list_store_set (
448 			GTK_LIST_STORE (tree_model), &iter,
449 			COLUMN_DISPLAY_NAME, display_name,
450 			COLUMN_UID, uid, -1);
451 	}
452 
453 	g_list_free_full (list, (GDestroyNotify) g_object_unref);
454 
455 	/* Try and restore the previous selected source, or else "None". */
456 
457 	if (saved_uid != NULL)
458 		gtk_combo_box_set_active_id (gtk_combo_box, saved_uid);
459 
460 	if (gtk_combo_box_get_active_id (gtk_combo_box) == NULL)
461 		gtk_combo_box_set_active (gtk_combo_box, 0);
462 }
463 
464 ESourceRegistry *
e_mail_signature_combo_box_get_registry(EMailSignatureComboBox * combo_box)465 e_mail_signature_combo_box_get_registry (EMailSignatureComboBox *combo_box)
466 {
467 	g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL);
468 
469 	return combo_box->priv->registry;
470 }
471 
472 const gchar *
e_mail_signature_combo_box_get_identity_uid(EMailSignatureComboBox * combo_box)473 e_mail_signature_combo_box_get_identity_uid (EMailSignatureComboBox *combo_box)
474 {
475 	g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL);
476 
477 	return combo_box->priv->identity_uid;
478 }
479 
480 static void
mail_signature_combo_box_emit_changed_for_autogenerated(EMailSignatureComboBox * combo_box)481 mail_signature_combo_box_emit_changed_for_autogenerated (EMailSignatureComboBox *combo_box)
482 {
483 	const gchar *active_id;
484 
485 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
486 
487 	/* If "Autogenerated" is selected, emit a "changed" signal as
488 	 * a hint to whomever is listening to reload the signature. */
489 	active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
490 	if (g_strcmp0 (active_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0)
491 		g_signal_emit_by_name (combo_box, "changed");
492 }
493 
494 static void
mail_signature_combo_box_set_identity_uid(EMailSignatureComboBox * combo_box,const gchar * identity_uid,gboolean can_emit_changed)495 mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box,
496 					   const gchar *identity_uid,
497 					   gboolean can_emit_changed)
498 {
499 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
500 
501 	if (g_strcmp0 (combo_box->priv->identity_uid, identity_uid) == 0)
502 		return;
503 
504 	g_free (combo_box->priv->identity_uid);
505 	combo_box->priv->identity_uid = g_strdup (identity_uid);
506 
507 	g_object_notify (G_OBJECT (combo_box), "identity-uid");
508 
509 	if (can_emit_changed)
510 		mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
511 }
512 
513 void
e_mail_signature_combo_box_set_identity_uid(EMailSignatureComboBox * combo_box,const gchar * identity_uid)514 e_mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box,
515                                              const gchar *identity_uid)
516 {
517 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
518 
519 	mail_signature_combo_box_set_identity_uid (combo_box, identity_uid, TRUE);
520 }
521 
522 const gchar *
e_mail_signature_combo_box_get_identity_name(EMailSignatureComboBox * combo_box)523 e_mail_signature_combo_box_get_identity_name (EMailSignatureComboBox *combo_box)
524 {
525 	g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL);
526 
527 	return combo_box->priv->identity_name;
528 }
529 
530 static void
mail_signature_combo_box_set_identity_name(EMailSignatureComboBox * combo_box,const gchar * identity_name,gboolean can_emit_changed)531 mail_signature_combo_box_set_identity_name (EMailSignatureComboBox *combo_box,
532 					    const gchar *identity_name,
533 					    gboolean can_emit_changed)
534 {
535 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
536 
537 	if (g_strcmp0 (combo_box->priv->identity_name, identity_name) == 0)
538 		return;
539 
540 	g_free (combo_box->priv->identity_name);
541 	combo_box->priv->identity_name = g_strdup (identity_name);
542 
543 	g_object_notify (G_OBJECT (combo_box), "identity-name");
544 
545 	if (can_emit_changed)
546 		mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
547 }
548 
549 void
e_mail_signature_combo_box_set_identity_name(EMailSignatureComboBox * combo_box,const gchar * identity_name)550 e_mail_signature_combo_box_set_identity_name (EMailSignatureComboBox *combo_box,
551 					      const gchar *identity_name)
552 {
553 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
554 
555 	mail_signature_combo_box_set_identity_name (combo_box, identity_name, TRUE);
556 }
557 
558 const gchar *
e_mail_signature_combo_box_get_identity_address(EMailSignatureComboBox * combo_box)559 e_mail_signature_combo_box_get_identity_address (EMailSignatureComboBox *combo_box)
560 {
561 	g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL);
562 
563 	return combo_box->priv->identity_address;
564 }
565 
566 static void
mail_signature_combo_box_set_identity_address(EMailSignatureComboBox * combo_box,const gchar * identity_address,gboolean can_emit_changed)567 mail_signature_combo_box_set_identity_address (EMailSignatureComboBox *combo_box,
568 					       const gchar *identity_address,
569 					       gboolean can_emit_changed)
570 {
571 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
572 
573 	if (g_strcmp0 (combo_box->priv->identity_address, identity_address) == 0)
574 		return;
575 
576 	g_free (combo_box->priv->identity_address);
577 	combo_box->priv->identity_address = g_strdup (identity_address);
578 
579 	g_object_notify (G_OBJECT (combo_box), "identity-address");
580 
581 	if (can_emit_changed)
582 		mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
583 }
584 
585 void
e_mail_signature_combo_box_set_identity_address(EMailSignatureComboBox * combo_box,const gchar * identity_address)586 e_mail_signature_combo_box_set_identity_address (EMailSignatureComboBox *combo_box,
587 						 const gchar *identity_address)
588 {
589 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
590 
591 	mail_signature_combo_box_set_identity_address (combo_box, identity_address, TRUE);
592 }
593 
594 void
e_mail_signature_combo_box_set_identity(EMailSignatureComboBox * combo_box,const gchar * identity_uid,const gchar * identity_name,const gchar * identity_address)595 e_mail_signature_combo_box_set_identity (EMailSignatureComboBox *combo_box,
596 					 const gchar *identity_uid,
597 					 const gchar *identity_name,
598 					 const gchar *identity_address)
599 {
600 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
601 
602 	g_object_freeze_notify (G_OBJECT (combo_box));
603 
604 	mail_signature_combo_box_set_identity_uid (combo_box, identity_uid, FALSE);
605 	mail_signature_combo_box_set_identity_name (combo_box, identity_name, FALSE);
606 	mail_signature_combo_box_set_identity_address (combo_box, identity_address, FALSE);
607 
608 	g_object_thaw_notify (G_OBJECT (combo_box));
609 
610 	mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
611 }
612 
613 /**************** e_mail_signature_combo_box_load_selected() *****************/
614 
615 typedef struct _LoadContext LoadContext;
616 
617 struct _LoadContext {
618 	GCancellable *cancellable;
619 	gchar *contents;
620 	gsize length;
621 	gboolean is_html;
622 };
623 
624 static void
load_context_free(LoadContext * context)625 load_context_free (LoadContext *context)
626 {
627 	g_clear_object (&context->cancellable);
628 	g_free (context->contents);
629 	g_slice_free (LoadContext, context);
630 }
631 
632 static void
mail_signature_combo_box_autogenerate(EMailSignatureComboBox * combo_box,LoadContext * context)633 mail_signature_combo_box_autogenerate (EMailSignatureComboBox *combo_box,
634                                        LoadContext *context)
635 {
636 	ESourceMailIdentity *extension;
637 	ESourceRegistry *registry;
638 	ESource *source;
639 	GString *buffer;
640 	const gchar *extension_name;
641 	const gchar *identity_uid;
642 	const gchar *identity_name;
643 	const gchar *identity_address;
644 	const gchar *text;
645 	gchar *escaped;
646 
647 	identity_uid = e_mail_signature_combo_box_get_identity_uid (combo_box);
648 
649 	/* If we have no mail identity UID, handle it as though
650 	 * "None" were selected.  No need to report an error. */
651 	if (identity_uid == NULL)
652 		return;
653 
654 	registry = e_mail_signature_combo_box_get_registry (combo_box);
655 	source = e_source_registry_ref_source (registry, identity_uid);
656 
657 	/* If the mail identity lookup fails, handle it as though
658 	 * "None" were selected.  No need to report an error. */
659 	if (source == NULL)
660 		return;
661 
662 	/* If the source is not actually a mail identity, handle it as
663 	 * though "None" were selected.  No need to report an error. */
664 	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
665 	if (!e_source_has_extension (source, extension_name)) {
666 		g_object_unref (source);
667 		return;
668 	}
669 
670 	extension = e_source_get_extension (source, extension_name);
671 
672 	/* The autogenerated signature format is:
673 	 *
674 	 *   <NAME> <ADDRESS>
675 	 *   <ORGANIZATION>
676 	 *
677 	 * The <ADDRESS> is a mailto link and
678 	 * the <ORGANIZATION> line is optional.
679 	 */
680 
681 	buffer = g_string_sized_new (512);
682 
683 	identity_name = e_mail_signature_combo_box_get_identity_name (combo_box);
684 	identity_address = e_mail_signature_combo_box_get_identity_address (combo_box);
685 
686 	if (identity_address && !*identity_address)
687 		identity_address = NULL;
688 
689 	text = (identity_address && identity_name && *identity_name) ? identity_name : e_source_mail_identity_get_name (extension);
690 	escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL;
691 	if (escaped != NULL && *escaped != '\0')
692 		g_string_append (buffer, escaped);
693 	g_free (escaped);
694 
695 	text = identity_address ? identity_address : e_source_mail_identity_get_address (extension);
696 	escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL;
697 	if (escaped != NULL && *escaped != '\0')
698 		g_string_append_printf (
699 			buffer, " &lt;<a href=\"mailto:%s\">%s</a>&gt;",
700 			escaped, escaped);
701 	g_free (escaped);
702 
703 	text = e_source_mail_identity_get_organization (extension);
704 	escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL;
705 	if (escaped != NULL && *escaped != '\0')
706 		g_string_append_printf (buffer, "<br>%s", escaped);
707 	g_free (escaped);
708 
709 	context->length = buffer->len;
710 	context->contents = g_string_free (buffer, FALSE);
711 	context->is_html = TRUE;
712 
713 	g_object_unref (source);
714 }
715 
716 static void
mail_signature_combo_box_load_cb(ESource * source,GAsyncResult * result,GSimpleAsyncResult * simple)717 mail_signature_combo_box_load_cb (ESource *source,
718                                   GAsyncResult *result,
719                                   GSimpleAsyncResult *simple)
720 {
721 	ESourceMailSignature *extension;
722 	LoadContext *context;
723 	const gchar *extension_name;
724 	const gchar *mime_type;
725 	GError *error = NULL;
726 
727 	context = g_simple_async_result_get_op_res_gpointer (simple);
728 
729 	e_source_mail_signature_load_finish (
730 		source, result, &context->contents, &context->length, &error);
731 
732 	if (error != NULL) {
733 		g_simple_async_result_set_from_error (simple, error);
734 		g_simple_async_result_complete (simple);
735 		g_object_unref (simple);
736 		g_error_free (error);
737 		return;
738 	}
739 
740 	extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
741 	extension = e_source_get_extension (source, extension_name);
742 	mime_type = e_source_mail_signature_get_mime_type (extension);
743 	context->is_html = (g_strcmp0 (mime_type, "text/html") == 0);
744 
745 	g_simple_async_result_complete (simple);
746 
747 	g_object_unref (simple);
748 }
749 
750 void
e_mail_signature_combo_box_load_selected(EMailSignatureComboBox * combo_box,gint io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)751 e_mail_signature_combo_box_load_selected (EMailSignatureComboBox *combo_box,
752                                           gint io_priority,
753                                           GCancellable *cancellable,
754                                           GAsyncReadyCallback callback,
755                                           gpointer user_data)
756 {
757 	GSimpleAsyncResult *simple;
758 	ESourceRegistry *registry;
759 	LoadContext *context;
760 	ESource *source;
761 	const gchar *active_id;
762 
763 	g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
764 
765 	context = g_slice_new0 (LoadContext);
766 	context->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
767 
768 	simple = g_simple_async_result_new (
769 		G_OBJECT (combo_box), callback, user_data,
770 		e_mail_signature_combo_box_load_selected);
771 
772 	g_simple_async_result_set_op_res_gpointer (
773 		simple, context, (GDestroyNotify) load_context_free);
774 
775 	active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
776 
777 	if (active_id == NULL) {
778 		g_simple_async_result_complete_in_idle (simple);
779 		g_object_unref (simple);
780 		return;
781 	}
782 
783 	if (g_strcmp0 (active_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0) {
784 		mail_signature_combo_box_autogenerate (combo_box, context);
785 		g_simple_async_result_complete_in_idle (simple);
786 		g_object_unref (simple);
787 		return;
788 	}
789 
790 	registry = e_mail_signature_combo_box_get_registry (combo_box);
791 	source = e_source_registry_ref_source (registry, active_id);
792 
793 	/* If for some reason the ESource lookup fails, handle it as
794 	 * though "None" were selected.  No need to report an error. */
795 	if (source == NULL) {
796 		g_simple_async_result_complete_in_idle (simple);
797 		g_object_unref (simple);
798 		return;
799 	}
800 
801 	e_source_mail_signature_load (
802 		source, io_priority, cancellable, (GAsyncReadyCallback)
803 		mail_signature_combo_box_load_cb, simple);
804 
805 	g_object_unref (source);
806 }
807 
808 gboolean
e_mail_signature_combo_box_load_selected_finish(EMailSignatureComboBox * combo_box,GAsyncResult * result,gchar ** contents,gsize * length,gboolean * is_html,GError ** error)809 e_mail_signature_combo_box_load_selected_finish (EMailSignatureComboBox *combo_box,
810                                                  GAsyncResult *result,
811                                                  gchar **contents,
812                                                  gsize *length,
813                                                  gboolean *is_html,
814                                                  GError **error)
815 {
816 	GSimpleAsyncResult *simple;
817 	LoadContext *context;
818 
819 	g_return_val_if_fail (
820 		g_simple_async_result_is_valid (
821 		result, G_OBJECT (combo_box),
822 		e_mail_signature_combo_box_load_selected), FALSE);
823 
824 	simple = G_SIMPLE_ASYNC_RESULT (result);
825 	context = g_simple_async_result_get_op_res_gpointer (simple);
826 
827 	if (g_simple_async_result_propagate_error (simple, error))
828 		return FALSE;
829 
830 	if (g_cancellable_set_error_if_cancelled (context->cancellable, error))
831 		return FALSE;
832 
833 	if (contents != NULL) {
834 		*contents = context->contents;
835 		context->contents = NULL;
836 	}
837 
838 	if (length != NULL)
839 		*length = context->length;
840 
841 	if (is_html != NULL)
842 		*is_html = context->is_html;
843 
844 	return TRUE;
845 }
846