evolution-3.6.4/modules/prefer-plain/e-mail-display-popup-prefer-plain.c

No issues found

Incomplete coverage

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
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  * 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 }