evolution-3.6.4/em-format/e-mail-formatter-attachment.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-formatter-attachment.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-formatter-attachment.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * e-mail-formatter-attachment.c
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  */
 18 
 19 #ifdef HAVE_CONFIG_H
 20 #include <config.h>
 21 #endif
 22 
 23 #include "e-mail-format-extensions.h"
 24 #include "e-mail-part-attachment.h"
 25 #include "e-mail-part-attachment-bar.h"
 26 
 27 #include <em-format/e-mail-formatter-extension.h>
 28 #include <em-format/e-mail-formatter.h>
 29 #include <em-format/e-mail-part-utils.h>
 30 #include <em-format/e-mail-inline-filter.h>
 31 #include <e-util/e-util.h>
 32 
 33 #include <shell/e-shell.h>
 34 #include <shell/e-shell-window.h>
 35 
 36 #include <widgets/misc/e-attachment-button.h>
 37 
 38 #include <glib/gi18n-lib.h>
 39 #include <camel/camel.h>
 40 
 41 #define d(x)
 42 
 43 typedef struct _EMailFormatterAttachment {
 44 	GObject parent;
 45 } EMailFormatterAttachment;
 46 
 47 typedef struct _EMailFormatterAttachmentClass {
 48 	GObjectClass parent_class;
 49 } EMailFormatterAttachmentClass;
 50 
 51 static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
 52 static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
 53 
 54 G_DEFINE_TYPE_EXTENDED (
 55 	EMailFormatterAttachment,
 56 	e_mail_formatter_attachment,
 57 	G_TYPE_OBJECT,
 58 	0,
 59 	G_IMPLEMENT_INTERFACE (
 60 		E_TYPE_MAIL_EXTENSION,
 61 		e_mail_formatter_mail_extension_interface_init)
 62 	G_IMPLEMENT_INTERFACE (
 63 		E_TYPE_MAIL_FORMATTER_EXTENSION,
 64 		e_mail_formatter_formatter_extension_interface_init)
 65 )
 66 
 67 static const gchar *formatter_mime_types[] = { "application/vnd.evolution.attachment",
 68 					       "application/vnd.evolution.widget.attachment-button",
 69 					       NULL };
 70 
 71 static EAttachmentStore *
 72 find_attachment_store (GSList *parts,
 73                        const gchar *start_id)
 74 {
 75 	gchar *tmp, *pos;
 76 	EMailPart *part;
 77 	gchar *id;
 78 
 79 	id = g_strconcat (start_id, ".attachment-bar", NULL);
 80 	tmp = g_strdup (id);
 81 	part = NULL;
 82 	do {
 83 		GSList *iter;
 84 
 85 		d (printf ("Looking up attachment bar as %s\n", id));
 86 
 87 		for (iter = parts; iter; iter = iter->next) {
 88 			EMailPart *p = iter->data;
 89 
 90 			if (!p)
 91 				continue;
 92 
 93 			if (g_strcmp0 (p->id, id) == 0) {
 94 				part = p;
 95 				break;
 96 			}
 97 		}
 98 
 99 		pos = g_strrstr (tmp, ".");
100 		if (!pos)
101 			break;
102 
103 		g_free (id);
104 		g_free (tmp);
105 		tmp = g_strndup (start_id, pos - tmp);
106 		id = g_strdup_printf ("%s.attachment-bar", tmp);
107 
108 	} while (pos && !part);
109 
110 	g_free (id);
111 	g_free (tmp);
112 
113 	if (part) {
114 		return ((EMailPartAttachmentBar *) part)->store;
115 	}
116 
117 	return NULL;
118 }
119 
120 static gboolean
121 emfe_attachment_format (EMailFormatterExtension *extension,
122                         EMailFormatter *formatter,
123                         EMailFormatterContext *context,
124                         EMailPart *part,
125                         CamelStream *stream,
126                         GCancellable *cancellable)
127 {
128 	gchar *str, *text, *html;
129 	gchar *button_id;
130 	EAttachmentStore *store;
131 	EMailExtensionRegistry *reg;
132 	GQueue *extensions;
133 	EMailPartAttachment *empa;
134 	gchar *attachment_part_id;
135 
136 	g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartAttachment), FALSE);
137 
138 	empa = (EMailPartAttachment *) part;
139 
140 	if ((context->mode == E_MAIL_FORMATTER_MODE_NORMAL) ||
141 	    (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) ||
142 	    (context->mode == E_MAIL_FORMATTER_MODE_ALL_HEADERS)) {
143 		if (part->validity) {
144 			e_attachment_set_signed (
145 				empa->attachment, part->validity->sign.status);
146 			e_attachment_set_encrypted (
147 				empa->attachment, part->validity->encrypt.status);
148 		}
149 
150 		store = find_attachment_store (context->parts, part->id);
151 		if (store) {
152 			GList *attachments = e_attachment_store_get_attachments (store);
153 			if (!g_list_find (attachments, empa->attachment)) {
154 				e_attachment_store_add_attachment (
155 					store, empa->attachment);
156 			}
157 			g_list_free (attachments);
158 		} else {
159 			g_warning ("Failed to locate attachment-bar for %s", part->id);
160 		}
161 	}
162 
163         /* If the attachment is requested as RAW, then call the handler directly
164          * and do not append any other code. */
165 	if ((context->mode == E_MAIL_FORMATTER_MODE_RAW) ||
166 	    (context->mode == E_MAIL_FORMATTER_MODE_PRINTING)) {
167 		EMailExtensionRegistry *reg;
168 		GQueue *extensions;
169 		GList *iter;
170 		reg = e_mail_formatter_get_extension_registry (formatter);
171 
172 		extensions = e_mail_extension_registry_get_for_mime_type (
173 					reg, empa->snoop_mime_type);
174 		if (!extensions) {
175 			extensions = e_mail_extension_registry_get_fallback (
176 					reg, empa->snoop_mime_type);
177 		}
178 
179 		if (!extensions)
180 			return FALSE;
181 
182 		if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
183 			gchar *name;
184 			EAttachment *attachment;
185 			GFileInfo *fi;
186 			const gchar *description;
187 
188 			attachment = empa->attachment;
189 			fi = e_attachment_get_file_info (attachment);
190 
191 			description = e_attachment_get_description (attachment);
192 			if (description && *description) {
193 				name = g_strdup_printf (
194 					"<h2>Attachment: %s (%s)</h2>\n",
195 					description, g_file_info_get_display_name (fi));
196 			} else {
197 				name = g_strdup_printf (
198 					"<h2>Attachment: %s</h2>\n",
199 					g_file_info_get_display_name (fi));
200 			}
201 
202 			camel_stream_write_string (stream, name, cancellable, NULL);
203 			g_free (name);
204 		}
205 
206 		for (iter = g_queue_peek_head_link (extensions); iter; iter = iter->next) {
207 
208 			EMailFormatterExtension *ext;
209 			ext = iter->data;
210 			if (!ext)
211 				continue;
212 
213 			if (e_mail_formatter_extension_format (ext, formatter,
214 				context, part, stream, cancellable)) {
215 				return TRUE;
216 			}
217 		}
218 
219 		return FALSE;
220 	}
221 
222 	/* E_MAIL_FORMATTER_MODE_NORMAL: */
223 
224 	reg = e_mail_formatter_get_extension_registry (formatter);
225 	extensions = e_mail_extension_registry_get_for_mime_type (
226 				reg, empa->snoop_mime_type);
227 
228 	if (!extensions) {
229 		extensions = e_mail_extension_registry_get_fallback (
230 				reg, empa->snoop_mime_type);
231 	}
232 
233 	text = e_mail_part_describe (part->part, empa->snoop_mime_type);
234 	html = camel_text_to_html (
235 		text, e_mail_formatter_get_text_format_flags (formatter) &
236 		CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
237 	g_free (text);
238 
239 	if (empa->attachment_view_part_id)
240 		attachment_part_id = empa->attachment_view_part_id;
241 	else
242 		attachment_part_id = part->id;
243 
244 	button_id = g_strconcat (attachment_part_id, ".attachment_button", NULL);
245 
246 	str = g_strdup_printf (
247 		"<div class=\"attachment\">"
248 		"<table width=\"100%%\" border=\"0\">"
249 		"<tr valign=\"middle\">"
250 		"<td align=\"left\" width=\"100\">"
251 		"<object type=\"application/vnd.evolution.widget.attachment-button\" "
252 		"height=\"20\" width=\"100\" data=\"%s\" id=\"%s\"></object>"
253 		"</td>"
254 		"<td align=\"left\">%s</td>"
255 		"</tr>", part->id, button_id, html);
256 
257 	camel_stream_write_string (stream, str, cancellable, NULL);
258 	g_free (button_id);
259 	g_free (str);
260 	g_free (html);
261 
262 	if (extensions) {
263 		GList *iter;
264 		CamelStream *content_stream;
265 		gboolean ok;
266 
267 		content_stream = camel_stream_mem_new ();
268 		ok = FALSE;
269 		if (empa->attachment_view_part_id != NULL) {
270 			EMailPart *attachment_view_part = NULL;
271 			GSList *att_parts;
272 
273 			att_parts = e_mail_part_list_get_iter (
274 				context->parts,
275 				empa->attachment_view_part_id);
276 
277 			if (att_parts != NULL && att_parts->data != NULL) {
278 				attachment_view_part = att_parts->data;
279 
280 				/* Avoid recursion. */
281 				if (attachment_view_part == part)
282 					attachment_view_part = NULL;
283 			}
284 
285 			if (attachment_view_part != NULL) {
286 				ok = e_mail_formatter_format_as (
287 					formatter, context,
288 					attachment_view_part,
289 					content_stream, NULL,
290 					cancellable);
291 			}
292 
293 		} else {
294 
295 			for (iter = g_queue_peek_head_link (extensions); iter; iter = iter->next) {
296 
297 				EMailFormatterExtension *ext;
298 
299 				ext = iter->data;
300 				if (!ext)
301 					continue;
302 
303 				if (e_mail_formatter_extension_format (
304 						ext, formatter, context,
305 						part, content_stream,
306 						cancellable)) {
307 					ok = TRUE;
308 					break;
309 				}
310 			}
311 		}
312 
313 		if (ok) {
314 			str = g_strdup_printf (
315 				"<tr><td colspan=\"2\">"
316 				"<div class=\"attachment-wrapper\" id=\"%s\">",
317 				attachment_part_id);
318 
319 			camel_stream_write_string (
320 				stream, str, cancellable, NULL);
321 			g_free (str);
322 
323 			g_seekable_seek (
324 				G_SEEKABLE (content_stream), 0,
325 				G_SEEK_SET, cancellable, NULL);
326 			camel_stream_write_to_stream (
327 					content_stream, stream,
328 					cancellable, NULL);
329 
330 			camel_stream_write_string (
331 				stream, "</div></td></tr>", cancellable, NULL);
332 		}
333 
334 		g_object_unref (content_stream);
335 	}
336 
337 	camel_stream_write_string (stream, "</table></div>", cancellable, NULL);
338 
339 	return TRUE;
340 }
341 
342 static GtkWidget *
343 emfe_attachment_get_widget (EMailFormatterExtension *extension,
344                             EMailPartList *context,
345                             EMailPart *part,
346                             GHashTable *params)
347 {
348 	EMailPartAttachment *empa;
349 	EAttachmentStore *store;
350 	EAttachmentView *view;
351 	GtkWidget *widget;
352 
353 	g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartAttachment), NULL);
354 	empa = (EMailPartAttachment *) part;
355 
356 	store = find_attachment_store (context->list, part->id);
357 	widget = e_attachment_button_new ();
358 	g_object_set_data (G_OBJECT (widget), "uri", part->id);
359 	e_attachment_button_set_attachment (
360 		E_ATTACHMENT_BUTTON (widget), empa->attachment);
361 	view = g_object_get_data (G_OBJECT (store), "attachment-bar");
362 	if (view) {
363 		e_attachment_button_set_view (
364 			E_ATTACHMENT_BUTTON (widget), view);
365 	}
366 
367 	gtk_widget_set_can_focus (widget, TRUE);
368 	gtk_widget_show (widget);
369 
370 	return widget;
371 }
372 
373 static const gchar *
374 emfe_attachment_get_display_name (EMailFormatterExtension *extension)
375 {
376 	return _("Attachment");
377 }
378 
379 static const gchar *
380 emfe_attachment_get_description (EMailFormatterExtension *extension)
381 {
382 	return _("Display as attachment");
383 }
384 
385 static const gchar **
386 emfe_attachment_mime_types (EMailExtension *extension)
387 {
388 	return formatter_mime_types;
389 }
390 
391 static void
392 e_mail_formatter_attachment_class_init (EMailFormatterAttachmentClass *class)
393 {
394 }
395 
396 static void
397 e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
398 {
399 	iface->format = emfe_attachment_format;
400 	iface->get_widget = emfe_attachment_get_widget;
401 	iface->get_display_name = emfe_attachment_get_display_name;
402 	iface->get_description = emfe_attachment_get_description;
403 }
404 
405 static void
406 e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
407 {
408 	iface->mime_types = emfe_attachment_mime_types;
409 }
410 
411 static void
412 e_mail_formatter_attachment_init (EMailFormatterAttachment *formatter)
413 {
414 
415 }