No issues found
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 |
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 }