No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-display-popup-prefer-plain.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-display-popup-prefer-plain.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
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 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include "e-mail-display-popup-prefer-plain.h"
21 #include "mail/e-mail-display-popup-extension.h"
22 #include "mail/e-mail-display.h"
23 #include <shell/e-shell.h>
24 #include <shell/e-shell-window.h>
25 #include "mail/e-mail-browser.h"
26
27 #include <libebackend/libebackend.h>
28
29 #include <glib/gi18n-lib.h>
30
31 #define d(x)
32
33 typedef struct _EMailDisplayPopupPreferPlain EMailDisplayPopupPreferPlain;
34 typedef struct _EMailDisplayPopupPreferPlainClass EMailDisplayPopupPreferPlainClass;
35
36 struct _EMailDisplayPopupPreferPlain {
37 EExtension parent;
38
39 WebKitDOMDocument *document;
40 gchar *text_plain_id;
41 gchar *text_html_id;
42
43 GtkActionGroup *action_group;
44
45 };
46
47 struct _EMailDisplayPopupPreferPlainClass {
48 EExtensionClass parent_class;
49 };
50
51 #define E_TYPE_MAIL_DISPLAY_POPUP_PREFER_PLAIN \
52 (e_mail_display_popup_prefer_plain_get_type ())
53 #define E_MAIL_DISPLAY_POPUP_PREFER_PLAIN(obj) \
54 (G_TYPE_CHECK_INSTANCE_CAST \
55 ((obj), E_TYPE_MAIL_DISPLAY_POPUP_PREFER_PLAIN, EMailDisplayPopupPreferPlain))
56
57 GType e_mail_display_popup_prefer_plain_get_type (void);
58 static void e_mail_display_popup_extension_interface_init (EMailDisplayPopupExtensionInterface *iface);
59
60 G_DEFINE_DYNAMIC_TYPE_EXTENDED (
61 EMailDisplayPopupPreferPlain,
62 e_mail_display_popup_prefer_plain,
63 E_TYPE_EXTENSION,
64 0,
65 G_IMPLEMENT_INTERFACE_DYNAMIC (
66 E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION,
67 e_mail_display_popup_extension_interface_init));
68
69 static const gchar *ui_webview =
70 "<ui>"
71 " <popup name='context'>"
72 " <placeholder name='custom-actions-2'>"
73 " <separator/>"
74 " <menuitem action='show-plain-text-part'/>"
75 " <menuitem action='show-text-html-part'/>"
76 " <separator/>"
77 " </placeholder>"
78 " </popup>"
79 "</ui>";
80
81 static const gchar *ui_reader =
82 "<ui>"
83 " <popup name='mail-preview-popup'>"
84 " <placeholder name='mail-preview-popup-actions'>"
85 " <separator/>"
86 " <menuitem action='show-plain-text-part'/>"
87 " <menuitem action='show-text-html-part'/>"
88 " <separator/>"
89 " </placeholder>"
90 " </popup>"
91 "</ui>";
92
93 static void
94 toggle_part (GtkAction *action,
95 EMailDisplayPopupExtension *extension)
96 {
97 EMailDisplayPopupPreferPlain *pp_extension = (EMailDisplayPopupPreferPlain *) extension;
98 WebKitDOMDocument *doc = pp_extension->document;
99 WebKitDOMDOMWindow *window;
100 WebKitDOMElement *frame_element;
101 SoupURI *soup_uri;
102 GHashTable *query;
103 gchar *uri;
104
105 uri = webkit_dom_document_get_document_uri (doc);
106 soup_uri = soup_uri_new (uri);
107 g_free (uri);
108
109 query = soup_form_decode (soup_uri->query);
110 g_hash_table_replace (
111 query, g_strdup ("part_id"),
112 pp_extension->text_html_id ?
113 pp_extension->text_html_id :
114 pp_extension->text_plain_id);
115 g_hash_table_replace (
116 query, g_strdup ("mime_type"),
117 pp_extension->text_html_id ?
118 (gpointer) "text/html" :
119 (gpointer) "text/plain");
120
121 soup_uri_set_query_from_form (soup_uri, query);
122 g_hash_table_destroy (query);
123
124 uri = soup_uri_to_string (soup_uri, FALSE);
125 soup_uri_free (soup_uri);
126
127 /* Get frame's window and from the window the actual <iframe> element */
128 window = webkit_dom_document_get_default_view (doc);
129 frame_element = webkit_dom_dom_window_get_frame_element (window);
130 webkit_dom_html_iframe_element_set_src (
131 WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), uri);
132
133 g_free (uri);
134 }
135
136 GtkActionEntry entries[] = {
137
138 { "show-plain-text-part",
139 NULL,
140 N_("Display plain text version"),
141 NULL,
142 N_("Display plain text version of multipart/alternative message"),
143 NULL
144 },
145
146 { "show-text-html-part",
147 NULL,
148 N_("Display HTML version"),
149 NULL,
150 N_("Display HTML version of multipart/alternative message"),
151 NULL
152 }
153 };
154
155 const gint ID_LEN = G_N_ELEMENTS (".alternative-prefer-plain.");
156
157 static void
158 set_text_plain_id (EMailDisplayPopupPreferPlain *extension,
159 const gchar *id)
160 {
161 g_free (extension->text_plain_id);
162 extension->text_plain_id = g_strdup (id);
163 }
164
165 static void
166 set_text_html_id (EMailDisplayPopupPreferPlain *extension,
167 const gchar *id)
168 {
169 g_free (extension->text_html_id);
170 extension->text_html_id = g_strdup (id);
171 }
172
173 static GtkActionGroup *
174 create_group (EMailDisplayPopupExtension *extension)
175 {
176 EExtensible *extensible;
177 EWebView *web_view;
178 GtkUIManager *ui_manager;
179 GtkActionGroup *group;
180 GtkAction *action;
181 EShell *shell;
182 GtkWindow *shell_window;
183
184 extensible = e_extension_get_extensible (E_EXTENSION (extension));
185 web_view = E_WEB_VIEW (extensible);
186
187 group = gtk_action_group_new ("prefer-plain");
188 gtk_action_group_add_actions (group, entries, G_N_ELEMENTS (entries), NULL);
189
190 ui_manager = e_web_view_get_ui_manager (web_view);
191 gtk_ui_manager_insert_action_group (ui_manager, group, 0);
192 gtk_ui_manager_add_ui_from_string (ui_manager, ui_webview, -1, NULL);
193
194 action = gtk_action_group_get_action (group, "show-plain-text-part");
195 g_signal_connect (
196 action, "activate",
197 G_CALLBACK (toggle_part), extension);
198
199 action = gtk_action_group_get_action (group, "show-text-html-part");
200 g_signal_connect (
201 action, "activate",
202 G_CALLBACK (toggle_part), extension);
203
204 shell = e_shell_get_default ();
205 shell_window = e_shell_get_active_window (shell);
206 if (E_IS_SHELL_WINDOW (shell_window)) {
207 ui_manager = e_shell_window_get_ui_manager (E_SHELL_WINDOW (shell_window));
208 } else if (E_IS_MAIL_BROWSER (shell_window)) {
209 ui_manager = e_mail_browser_get_ui_manager (E_MAIL_BROWSER (shell_window));
210 } else {
211 return NULL;
212 }
213
214 gtk_ui_manager_insert_action_group (ui_manager, group, 0);
215 gtk_ui_manager_add_ui_from_string (ui_manager, ui_reader, -1, NULL);
216
217 return group;
218 }
219
220 static void
221 mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *extension,
222 WebKitHitTestResult *context)
223 {
224 EMailDisplay *display;
225 GtkAction *action;
226 WebKitDOMNode *node;
227 gchar *uri, *part_id, *pos, *prefix;
228 SoupURI *soup_uri;
229 GHashTable *query;
230 EMailPartList *part_list;
231 GSList *iter;
232 gboolean is_text_plain;
233 const gchar *action_name;
234 EMailDisplayPopupPreferPlain *pp_extension;
235
236 display = E_MAIL_DISPLAY (e_extension_get_extensible (
237 E_EXTENSION (extension)));
238
239 pp_extension = E_MAIL_DISPLAY_POPUP_PREFER_PLAIN (extension);
240
241 if (!pp_extension->action_group)
242 pp_extension->action_group = create_group (extension);
243
244 g_object_get (context, "inner-node", &node, NULL);
245
246 if (!node) {
247 gtk_action_group_set_visible (pp_extension->action_group, FALSE);
248 return;
249 }
250
251 pp_extension->document = webkit_dom_node_get_owner_document (node);
252 uri = webkit_dom_document_get_document_uri (pp_extension->document);
253
254 soup_uri = soup_uri_new (uri);
255 if (!soup_uri || !soup_uri->query) {
256 gtk_action_group_set_visible (pp_extension->action_group, FALSE);
257 if (soup_uri)
258 soup_uri_free (soup_uri);
259 g_free (uri);
260 return;
261 }
262
263 query = soup_form_decode (soup_uri->query);
264 part_id = g_hash_table_lookup (query, "part_id");
265 if (part_id == NULL) {
266 gtk_action_group_set_visible (pp_extension->action_group, FALSE);
267 g_hash_table_destroy (query);
268 soup_uri_free (soup_uri);
269 g_free (uri);
270 return;
271 }
272
273 pos = strstr (part_id, ".alternative-prefer-plain.");
274 if (!pos) {
275 gtk_action_group_set_visible (pp_extension->action_group, FALSE);
276 g_hash_table_destroy (query);
277 soup_uri_free (soup_uri);
278 g_free (uri);
279 return;
280 }
281
282 /* Don't display the actions on any other than text/plain or text/html parts */
283 if (!strstr (pos, "plain_text") && !strstr (pos, "text_html")) {
284 gtk_action_group_set_visible (pp_extension->action_group, FALSE);
285 g_hash_table_destroy (query);
286 soup_uri_free (soup_uri);
287 g_free (uri);
288 return;
289 }
290
291 /* Check whether the displayed part is text_plain */
292 is_text_plain = (strstr (pos + ID_LEN, "plain_text") != NULL);
293
294 /* It is! Hide the menu action */
295 if (is_text_plain) {
296 action = gtk_action_group_get_action (
297 pp_extension->action_group, "show-plain-text-part");
298 gtk_action_set_visible (action, FALSE);
299 } else {
300 action = gtk_action_group_get_action (
301 pp_extension->action_group, "show-text-html-part");
302 gtk_action_set_visible (action, FALSE);
303 }
304
305 /* Now check whether HTML version exists, if it does enable the action */
306 prefix = g_strndup (part_id, (pos - part_id) + ID_LEN - 1);
307
308 action_name = NULL;
309 part_list = e_mail_display_get_parts_list (display);
310 for (iter = part_list->list; iter; iter = g_slist_next (iter)) {
311 EMailPart *p = iter->data;
312 if (!p)
313 continue;
314
315 if (g_str_has_prefix (p->id, prefix) &&
316 (strstr (p->id, "text_html") || strstr (p->id, "plain_text"))) {
317
318 pos = strstr (p->id, ".alternative-prefer-plain.");
319
320 if (is_text_plain) {
321 if (strstr (pos + ID_LEN, "text_html") != NULL) {
322 action_name = "show-text-html-part";
323 set_text_html_id (pp_extension, p->id);
324 set_text_plain_id (pp_extension, NULL);
325 break;
326 }
327 } else {
328 if (strstr (pos + ID_LEN, "plain_text") != NULL) {
329 action_name = "show-plain-text-part";
330 set_text_html_id (pp_extension, NULL);
331 set_text_plain_id (pp_extension, p->id);
332 break;
333 }
334 }
335 }
336 }
337
338 if (action_name) {
339 action = gtk_action_group_get_action (
340 pp_extension->action_group, action_name);
341 gtk_action_group_set_visible (pp_extension->action_group, TRUE);
342 gtk_action_set_visible (action, TRUE);
343 } else {
344 gtk_action_group_set_visible (pp_extension->action_group, FALSE);
345 }
346
347 g_free (prefix);
348 g_hash_table_destroy (query);
349 soup_uri_free (soup_uri);
350 g_free (uri);
351 }
352
353 void
354 e_mail_display_popup_prefer_plain_type_register (GTypeModule *type_module)
355 {
356 e_mail_display_popup_prefer_plain_register_type (type_module);
357 }
358
359 static void
360 e_mail_display_popup_prefer_plain_dispose (GObject *object)
361 {
362 EMailDisplayPopupPreferPlain *extension;
363
364 extension = E_MAIL_DISPLAY_POPUP_PREFER_PLAIN (object);
365
366 if (extension->action_group != NULL) {
367 g_object_unref (extension->action_group);
368 extension->action_group = NULL;
369 }
370
371 /* Chain up to parent's dispose() method. */
372 G_OBJECT_CLASS (e_mail_display_popup_prefer_plain_parent_class)->
373 dispose (object);
374 }
375
376 static void
377 e_mail_display_popup_prefer_plain_finalize (GObject *object)
378 {
379 EMailDisplayPopupPreferPlain *extension;
380
381 extension = E_MAIL_DISPLAY_POPUP_PREFER_PLAIN (object);
382
383 g_free (extension->text_html_id);
384 g_free (extension->text_plain_id);
385
386 /* Chain up to parent's finalize() method. */
387 G_OBJECT_CLASS (e_mail_display_popup_prefer_plain_parent_class)->
388 finalize (object);
389 }
390
391 static void
392 e_mail_display_popup_prefer_plain_class_init (EMailDisplayPopupPreferPlainClass *class)
393 {
394 EExtensionClass *extension_class;
395 GObjectClass *object_class;
396
397 extension_class = E_EXTENSION_CLASS (class);
398 extension_class->extensible_type = E_TYPE_MAIL_DISPLAY;
399
400 object_class = G_OBJECT_CLASS (class);
401 object_class->dispose = e_mail_display_popup_prefer_plain_dispose;
402 object_class->finalize = e_mail_display_popup_prefer_plain_finalize;
403 }
404
405 static void
406 e_mail_display_popup_extension_interface_init (EMailDisplayPopupExtensionInterface *iface)
407 {
408 iface->update_actions = mail_display_popup_prefer_plain_update_actions;
409 }
410
411 void
412 e_mail_display_popup_prefer_plain_class_finalize (EMailDisplayPopupPreferPlainClass *class)
413 {
414
415 }
416
417 static void
418 e_mail_display_popup_prefer_plain_init (EMailDisplayPopupPreferPlain *extension)
419 {
420 extension->action_group = NULL;
421 extension->text_html_id = NULL;
422 extension->text_plain_id = NULL;
423 extension->document = NULL;
424 }