evolution-3.6.4/mail/em-filter-source-element.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Jon Trowbridge <trow@ximian.com>
 18  *      Jeffrey Stedfast <fejj@ximian.com>
 19  *
 20  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 21  *
 22  */
 23 
 24 #ifdef HAVE_CONFIG_H
 25 #include <config.h>
 26 #endif
 27 
 28 #include <string.h>
 29 
 30 #include "em-filter-source-element.h"
 31 #include "e-mail-account-store.h"
 32 #include "e-mail-ui-session.h"
 33 
 34 #include <gtk/gtk.h>
 35 #include <camel/camel.h>
 36 
 37 #include <shell/e-shell.h>
 38 #include <filter/e-filter-part.h>
 39 
 40 #define EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE(obj) \
 41 	(G_TYPE_INSTANCE_GET_PRIVATE \
 42 	((obj), EM_TYPE_FILTER_SOURCE_ELEMENT, EMFilterSourceElementPrivate))
 43 
 44 struct _EMFilterSourceElementPrivate {
 45 	EMailSession *session;
 46 	gchar *active_id;
 47 };
 48 
 49 G_DEFINE_TYPE (
 50 	EMFilterSourceElement,
 51 	em_filter_source_element,
 52 	E_TYPE_FILTER_ELEMENT)
 53 
 54 enum {
 55 	PROP_0,
 56 	PROP_SESSION
 57 };
 58 
 59 static void
 60 filter_source_element_source_changed (GtkComboBox *combo_box,
 61                                       EMFilterSourceElement *fs)
 62 {
 63 	const gchar *active_id;
 64 
 65 	active_id = gtk_combo_box_get_active_id (combo_box);
 66 
 67 	g_free (fs->priv->active_id);
 68 	fs->priv->active_id = g_strdup (active_id);
 69 }
 70 
 71 static void
 72 filter_source_element_set_session (EMFilterSourceElement *element,
 73                                    EMailSession *session)
 74 {
 75 	g_return_if_fail (E_IS_MAIL_SESSION (session));
 76 	g_return_if_fail (element->priv->session == NULL);
 77 
 78 	element->priv->session = g_object_ref (session);
 79 }
 80 
 81 static void
 82 filter_source_element_set_property (GObject *object,
 83                                     guint property_id,
 84                                     const GValue *value,
 85                                     GParamSpec *pspec)
 86 {
 87 	switch (property_id) {
 88 		case PROP_SESSION:
 89 			filter_source_element_set_session (
 90 				EM_FILTER_SOURCE_ELEMENT (object),
 91 				g_value_get_object (value));
 92 			return;
 93 	}
 94 
 95 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 96 }
 97 
 98 static void
 99 filter_source_element_get_property (GObject *object,
100                                     guint property_id,
101                                     GValue *value,
102                                     GParamSpec *pspec)
103 {
104 	switch (property_id) {
105 		case PROP_SESSION:
106 			g_value_set_object (
107 				value,
108 				em_filter_source_element_get_session (
109 				EM_FILTER_SOURCE_ELEMENT (object)));
110 			return;
111 	}
112 
113 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
114 }
115 
116 static void
117 filter_source_element_dispose (GObject *object)
118 {
119 	EMFilterSourceElementPrivate *priv;
120 
121 	priv = EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE (object);
122 
123 	if (priv->session != NULL) {
124 		g_object_unref (priv->session);
125 		priv->session = NULL;
126 	}
127 
128 	/* Chain up to parent's dispose() method. */
129 	G_OBJECT_CLASS (em_filter_source_element_parent_class)->dispose (object);
130 }
131 
132 static void
133 filter_source_element_finalize (GObject *object)
134 {
135 	EMFilterSourceElementPrivate *priv;
136 
137 	priv = EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE (object);
138 
139 	g_free (priv->active_id);
140 
141 	/* Chain up to parent's finalize() method. */
142 	G_OBJECT_CLASS (em_filter_source_element_parent_class)->finalize (object);
143 }
144 
145 static gint
146 filter_source_element_eq (EFilterElement *fe,
147                           EFilterElement *cm)
148 {
149 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
150 	EMFilterSourceElement *cs = (EMFilterSourceElement *) cm;
151 
152 	return E_FILTER_ELEMENT_CLASS (em_filter_source_element_parent_class)->eq (fe, cm)
153 		&& g_strcmp0 (fs->priv->active_id, cs->priv->active_id) == 0;
154 }
155 
156 static xmlNodePtr
157 filter_source_element_xml_encode (EFilterElement *fe)
158 {
159 	xmlNodePtr value;
160 
161 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
162 
163 	value = xmlNewNode (NULL, (const guchar *) "value");
164 	xmlSetProp (value, (const guchar *) "name", (guchar *) fe->name);
165 	xmlSetProp (value, (const guchar *) "type", (const guchar *) "uid");
166 
167 	if (fs->priv->active_id != NULL)
168 		xmlNewTextChild (
169 			value, NULL, (const guchar *) "uid",
170 			(guchar *) fs->priv->active_id);
171 
172 	return value;
173 }
174 
175 static gint
176 filter_source_element_xml_decode (EFilterElement *fe,
177                                   xmlNodePtr node)
178 {
179 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
180 	EMailSession *session;
181 	gchar *active_id = NULL;
182 
183 	session = em_filter_source_element_get_session (fs);
184 
185 	node = node->children;
186 	while (node != NULL) {
187 
188 		if (strcmp ((gchar *) node->name, "uid") == 0) {
189 			xmlChar *content;
190 
191 			content = xmlNodeGetContent (node);
192 			active_id = g_strdup ((gchar *) content);
193 			xmlFree (content);
194 
195 			break;
196 		}
197 
198 		/* For backward-compatibility: We used to store
199 		 * sources by their URI string, which can change. */
200 		if (strcmp ((gchar *) node->name, "uri") == 0) {
201 			CamelService *service = NULL;
202 			xmlChar *content;
203 			CamelURL *url;
204 
205 			content = xmlNodeGetContent (node);
206 			url = camel_url_new ((gchar *) content, NULL);
207 			xmlFree (content);
208 
209 			if (url != NULL) {
210 				service = camel_session_ref_service_by_url (
211 					CAMEL_SESSION (session),
212 					url, CAMEL_PROVIDER_STORE);
213 				camel_url_free (url);
214 			}
215 
216 			if (service != NULL) {
217 				const gchar *uid;
218 
219 				uid = camel_service_get_uid (service);
220 				active_id = g_strdup (uid);
221 
222 				g_object_unref (service);
223 			}
224 
225 			break;
226 		}
227 
228 		node = node->next;
229 	}
230 
231 	if (active_id != NULL) {
232 		g_free (fs->priv->active_id);
233 		fs->priv->active_id = active_id;
234 	} else
235 		g_free (active_id);
236 
237 	return 0;
238 }
239 
240 static EFilterElement *
241 filter_source_element_clone (EFilterElement *fe)
242 {
243 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
244 	EMFilterSourceElement *cpy;
245 	EMailSession *session;
246 
247 	session = em_filter_source_element_get_session (fs);
248 	cpy = (EMFilterSourceElement *) em_filter_source_element_new (session);
249 	((EFilterElement *) cpy)->name = (gchar *) xmlStrdup ((guchar *) fe->name);
250 
251 	cpy->priv->active_id = g_strdup (fs->priv->active_id);
252 
253 	return (EFilterElement *) cpy;
254 }
255 
256 static void
257 filter_source_element_add_to_combo (GtkComboBox *combo_box,
258                                     CamelService *service,
259                                     ESourceRegistry *registry)
260 {
261 	ESource *source;
262 	ESourceMailIdentity *extension;
263 	const gchar *extension_name;
264 	const gchar *display_name;
265 	const gchar *address;
266 	const gchar *name;
267 	const gchar *uid;
268 	gchar *label;
269 
270 	source = e_source_registry_ref_source (
271 		registry,
272 		camel_service_get_uid (service));
273 	if (!source)
274 		return;
275 
276 	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
277 	if (e_source_has_extension (source, extension_name)) {
278 		ESource *identity_source;
279 		ESourceMailAccount *mail_account;
280 
281 		mail_account = e_source_get_extension (source, extension_name);
282 		uid = e_source_mail_account_get_identity_uid (mail_account);
283 
284 		if (!uid || !*uid) {
285 			g_object_unref (source);
286 			return;
287 		}
288 
289 		identity_source = e_source_registry_ref_source (registry, uid);
290 		g_object_unref (source);
291 		source = identity_source;
292 
293 		if (!source)
294 			return;
295 	}
296 
297 	/* use UID of the service, because that's the one used in camel-filter-driver */
298 	uid = camel_service_get_uid (service);
299 	display_name = e_source_get_display_name (source);
300 
301 	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
302 	if (!e_source_has_extension (source, extension_name)) {
303 		g_object_unref (source);
304 		return;
305 	}
306 
307 	extension = e_source_get_extension (source, extension_name);
308 
309 	name = e_source_mail_identity_get_name (extension);
310 	address = e_source_mail_identity_get_address (extension);
311 
312 	if (name == NULL || address == NULL) {
313 		if (name == NULL && address == NULL)
314 			label = g_strdup (display_name);
315 		else
316 			label = g_strdup_printf ("%s (%s)", name ? name : address, display_name);
317 
318 	} else if (g_strcmp0 (display_name, address) == 0)
319 		label = g_strdup_printf ("%s <%s>", name, address);
320 	else
321 		label = g_strdup_printf ("%s <%s> (%s)", name, address, display_name);
322 
323 	gtk_combo_box_text_append (
324 		GTK_COMBO_BOX_TEXT (combo_box), uid, label);
325 
326 	g_free (label);
327 	g_object_unref (source);
328 }
329 
330 static GtkWidget *
331 filter_source_element_get_widget (EFilterElement *fe)
332 {
333 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
334 	EMailSession *session;
335 	ESourceRegistry *registry;
336 	EMailAccountStore *account_store;
337 	GtkTreeModel *model;
338 	GtkTreeIter iter;
339 	GtkWidget *widget;
340 	GtkComboBox *combo_box;
341 
342 	widget = gtk_combo_box_text_new ();
343 	combo_box = GTK_COMBO_BOX (widget);
344 
345 	session = em_filter_source_element_get_session (fs);
346 	registry = e_mail_session_get_registry (session);
347 	account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session));
348 
349 	model = GTK_TREE_MODEL (account_store);
350 	if (gtk_tree_model_get_iter_first (model, &iter)) {
351 		CamelService *service;
352 
353 		do {
354 			gboolean enabled = FALSE, builtin = TRUE;
355 
356 			service = NULL;
357 
358 			gtk_tree_model_get (
359 				model, &iter,
360 				E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE, &service,
361 				E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED, &enabled,
362 				E_MAIL_ACCOUNT_STORE_COLUMN_BUILTIN, &builtin,
363 				-1);
364 
365 			if (CAMEL_IS_STORE (service) && enabled && !builtin)
366 				filter_source_element_add_to_combo (combo_box, service, registry);
367 
368 			if (service)
369 				g_object_unref (service);
370 		} while (gtk_tree_model_iter_next (model, &iter));
371 	}
372 
373 	if (fs->priv->active_id != NULL) {
374 		gtk_combo_box_set_active_id (combo_box, fs->priv->active_id);
375 	} else {
376 		const gchar *active_id;
377 
378 		gtk_combo_box_set_active (combo_box, 0);
379 		active_id = gtk_combo_box_get_active_id (combo_box);
380 
381 		g_free (fs->priv->active_id);
382 		fs->priv->active_id = g_strdup (active_id);
383 	}
384 
385 	g_signal_connect (
386 		widget, "changed",
387 		G_CALLBACK (filter_source_element_source_changed), fs);
388 
389 	return widget;
390 }
391 
392 static void
393 filter_source_element_build_code (EFilterElement *fe,
394                                   GString *out,
395                                   EFilterPart *ff)
396 {
397 	/* We are doing nothing on purpose. */
398 }
399 
400 static void
401 filter_source_element_format_sexp (EFilterElement *fe,
402                                    GString *out)
403 {
404 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
405 
406 	camel_sexp_encode_string (out, fs->priv->active_id);
407 }
408 
409 static void
410 em_filter_source_element_class_init (EMFilterSourceElementClass *class)
411 {
412 	GObjectClass *object_class;
413 	EFilterElementClass *filter_element_class;
414 
415 	g_type_class_add_private (class, sizeof (EMFilterSourceElementPrivate));
416 
417 	object_class = G_OBJECT_CLASS (class);
418 	object_class->set_property = filter_source_element_set_property;
419 	object_class->get_property = filter_source_element_get_property;
420 	object_class->dispose = filter_source_element_dispose;
421 	object_class->finalize = filter_source_element_finalize;
422 
423 	filter_element_class = E_FILTER_ELEMENT_CLASS (class);
424 	filter_element_class->eq = filter_source_element_eq;
425 	filter_element_class->xml_encode = filter_source_element_xml_encode;
426 	filter_element_class->xml_decode = filter_source_element_xml_decode;
427 	filter_element_class->clone = filter_source_element_clone;
428 	filter_element_class->get_widget = filter_source_element_get_widget;
429 	filter_element_class->build_code = filter_source_element_build_code;
430 	filter_element_class->format_sexp = filter_source_element_format_sexp;
431 
432 	g_object_class_install_property (
433 		object_class,
434 		PROP_SESSION,
435 		g_param_spec_object (
436 			"session",
437 			NULL,
438 			NULL,
439 			E_TYPE_MAIL_SESSION,
440 			G_PARAM_READWRITE |
441 			G_PARAM_CONSTRUCT_ONLY |
442 			G_PARAM_STATIC_STRINGS));
443 }
444 
445 static void
446 em_filter_source_element_init (EMFilterSourceElement *element)
447 {
448 	element->priv = EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE (element);
449 }
450 
451 EFilterElement *
452 em_filter_source_element_new (EMailSession *session)
453 {
454 	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
455 
456 	return g_object_new (
457 		EM_TYPE_FILTER_SOURCE_ELEMENT,
458 		"session", session, NULL);
459 }
460 
461 EMailSession *
462 em_filter_source_element_get_session (EMFilterSourceElement *element)
463 {
464 	g_return_val_if_fail (EM_IS_FILTER_SOURCE_ELEMENT (element), NULL);
465 
466 	return element->priv->session;
467 }