1 /*
2  * e-selection.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  *
17  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18  *
19  */
20 
21 /**
22  * SECTION: e-selection
23  * @short_description: selection and clipboard utilities
24  * @include: e-util/e-util.h
25  **/
26 
27 #include "evolution-config.h"
28 
29 #include "e-selection.h"
30 
31 #include <string.h>
32 
33 typedef struct _RequestTextInfo RequestTextInfo;
34 typedef struct _WaitForDataResults WaitForDataResults;
35 
36 struct _RequestTextInfo {
37 	GtkClipboardTextReceivedFunc callback;
38 	gpointer user_data;
39 };
40 
41 struct _WaitForDataResults {
42 	GMainLoop *loop;
43 	gpointer data;
44 };
45 
46 enum {
47 	ATOM_CALENDAR,
48 	ATOM_X_VCALENDAR,
49 	NUM_CALENDAR_ATOMS
50 };
51 
52 enum {
53 	ATOM_DIRECTORY,
54 	ATOM_X_VCARD,
55 	NUM_DIRECTORY_ATOMS
56 };
57 
58 enum {
59 	ATOM_HTML,
60 	NUM_HTML_ATOMS
61 };
62 
63 static GdkAtom calendar_atoms[NUM_CALENDAR_ATOMS];
64 static GdkAtom directory_atoms[NUM_DIRECTORY_ATOMS];
65 static GdkAtom html_atoms[NUM_HTML_ATOMS];
66 
67 static void
init_atoms(void)68 init_atoms (void)
69 {
70 	static gboolean initialized = FALSE;
71 
72 	if (initialized)
73 		return;
74 
75 	/* Calendar Atoms */
76 
77 	calendar_atoms[ATOM_CALENDAR] =
78 		gdk_atom_intern_static_string ("text/calendar");
79 
80 	calendar_atoms[ATOM_X_VCALENDAR] =
81 		gdk_atom_intern_static_string ("text/x-vcalendar");
82 
83 	/* Directory Atoms */
84 
85 	directory_atoms[ATOM_DIRECTORY] =
86 		gdk_atom_intern_static_string ("text/directory");
87 
88 	directory_atoms[ATOM_X_VCARD] =
89 		gdk_atom_intern_static_string ("text/x-vcard");
90 
91 	/* HTML Atoms */
92 
93 	html_atoms[ATOM_HTML] =
94 		gdk_atom_intern_static_string ("text/html");
95 
96 	initialized = TRUE;
97 }
98 
99 static void
clipboard_wait_for_text_cb(GtkClipboard * clipboard,const gchar * source,WaitForDataResults * results)100 clipboard_wait_for_text_cb (GtkClipboard *clipboard,
101                             const gchar *source,
102                             WaitForDataResults *results)
103 {
104 	results->data = g_strdup (source);
105 	g_main_loop_quit (results->loop);
106 }
107 
108 void
e_target_list_add_calendar_targets(GtkTargetList * list,guint info)109 e_target_list_add_calendar_targets (GtkTargetList *list,
110                                     guint info)
111 {
112 	gint ii;
113 
114 	g_return_if_fail (list != NULL);
115 
116 	init_atoms ();
117 
118 	for (ii = 0; ii < NUM_CALENDAR_ATOMS; ii++)
119 		gtk_target_list_add (list, calendar_atoms[ii], 0, info);
120 }
121 
122 void
e_target_list_add_directory_targets(GtkTargetList * list,guint info)123 e_target_list_add_directory_targets (GtkTargetList *list,
124                                      guint info)
125 {
126 	gint ii;
127 
128 	g_return_if_fail (list != NULL);
129 
130 	init_atoms ();
131 
132 	for (ii = 0; ii < NUM_DIRECTORY_ATOMS; ii++)
133 		gtk_target_list_add (list, directory_atoms[ii], 0, info);
134 }
135 
136 void
e_target_list_add_html_targets(GtkTargetList * list,guint info)137 e_target_list_add_html_targets (GtkTargetList *list,
138                                 guint info)
139 {
140 	gint ii;
141 
142 	g_return_if_fail (list != NULL);
143 
144 	init_atoms ();
145 
146 	for (ii = 0; ii < NUM_HTML_ATOMS; ii++)
147 		gtk_target_list_add (list, html_atoms[ii], 0, info);
148 }
149 
150 gboolean
e_selection_data_set_calendar(GtkSelectionData * selection_data,const gchar * source,gint length)151 e_selection_data_set_calendar (GtkSelectionData *selection_data,
152                                const gchar *source,
153                                gint length)
154 {
155 	GdkAtom atom;
156 	gint ii;
157 
158 	g_return_val_if_fail (selection_data != NULL, FALSE);
159 	g_return_val_if_fail (source != NULL, FALSE);
160 
161 	if (length < 0)
162 		length = strlen (source);
163 
164 	init_atoms ();
165 
166 	atom = gtk_selection_data_get_target (selection_data);
167 
168 	/* All calendar atoms are treated the same. */
169 	for (ii = 0; ii < NUM_CALENDAR_ATOMS; ii++) {
170 		if (atom == calendar_atoms[ii]) {
171 			gtk_selection_data_set (
172 				selection_data, atom, 8,
173 				(guchar *) source, length);
174 			return TRUE;
175 		}
176 	}
177 
178 	return FALSE;
179 }
180 
181 gboolean
e_selection_data_set_directory(GtkSelectionData * selection_data,const gchar * source,gint length)182 e_selection_data_set_directory (GtkSelectionData *selection_data,
183                                 const gchar *source,
184                                 gint length)
185 {
186 	GdkAtom atom;
187 	gint ii;
188 
189 	g_return_val_if_fail (selection_data != NULL, FALSE);
190 	g_return_val_if_fail (source != NULL, FALSE);
191 
192 	if (length < 0)
193 		length = strlen (source);
194 
195 	init_atoms ();
196 
197 	atom = gtk_selection_data_get_target (selection_data);
198 
199 	/* All directory atoms are treated the same. */
200 	for (ii = 0; ii < NUM_DIRECTORY_ATOMS; ii++) {
201 		if (atom == directory_atoms[ii]) {
202 			gtk_selection_data_set (
203 				selection_data, atom, 8,
204 				(guchar *) source, length);
205 			return TRUE;
206 		}
207 	}
208 
209 	return FALSE;
210 }
211 
212 gboolean
e_selection_data_set_html(GtkSelectionData * selection_data,const gchar * source,gint length)213 e_selection_data_set_html (GtkSelectionData *selection_data,
214                            const gchar *source,
215                            gint length)
216 {
217 	GdkAtom atom;
218 	gint ii;
219 
220 	g_return_val_if_fail (selection_data != NULL, FALSE);
221 	g_return_val_if_fail (source != NULL, FALSE);
222 
223 	if (length < 0)
224 		length = strlen (source);
225 
226 	init_atoms ();
227 
228 	atom = gtk_selection_data_get_target (selection_data);
229 
230 	/* All HTML atoms are treated the same. */
231 	for (ii = 0; ii < NUM_HTML_ATOMS; ii++) {
232 		if (atom == html_atoms[ii]) {
233 			gtk_selection_data_set (
234 				selection_data, atom, 8,
235 				(guchar *) source, length);
236 			return TRUE;
237 		}
238 	}
239 
240 	return FALSE;
241 }
242 
243 gchar *
e_selection_data_get_calendar(GtkSelectionData * selection_data)244 e_selection_data_get_calendar (GtkSelectionData *selection_data)
245 {
246 	GdkAtom data_type;
247 	const guchar *data = NULL;
248 	gint ii;
249 
250 	/* XXX May need to do encoding and line ending conversions
251 	 *     here.  Not worrying about it for now. */
252 
253 	g_return_val_if_fail (selection_data != NULL, NULL);
254 
255 	data = gtk_selection_data_get_data (selection_data);
256 	data_type = gtk_selection_data_get_data_type (selection_data);
257 
258 	/* All calendar atoms are treated the same. */
259 	for (ii = 0; ii < NUM_CALENDAR_ATOMS; ii++)
260 		if (data_type == calendar_atoms[ii])
261 			return g_strdup ((gchar *) data);
262 
263 	return NULL;
264 }
265 
266 gchar *
e_selection_data_get_directory(GtkSelectionData * selection_data)267 e_selection_data_get_directory (GtkSelectionData *selection_data)
268 {
269 	GdkAtom data_type;
270 	const guchar *data = NULL;
271 	gint ii;
272 
273 	/* XXX May need to do encoding and line ending conversions
274 	 *     here.  Not worrying about it for now. */
275 
276 	g_return_val_if_fail (selection_data != NULL, NULL);
277 
278 	data = gtk_selection_data_get_data (selection_data);
279 	data_type = gtk_selection_data_get_data_type (selection_data);
280 
281 	/* All directory atoms are treated the same. */
282 	for (ii = 0; ii < NUM_DIRECTORY_ATOMS; ii++)
283 		if (data_type == directory_atoms[ii])
284 			return g_strdup ((gchar *) data);
285 
286 	return NULL;
287 }
288 
289 gchar *
e_selection_data_get_html(GtkSelectionData * selection_data)290 e_selection_data_get_html (GtkSelectionData *selection_data)
291 {
292 	GdkAtom data_type;
293 	const guchar *data = NULL;
294 	gchar *utf8_text;
295 	gint length;
296 	gint ii;
297 	GError *error = NULL;
298 
299 	/* XXX May need to do encoding conversions here.
300 	 *     Not worrying about it for now. */
301 
302 	g_return_val_if_fail (selection_data != NULL, NULL);
303 
304 	data = gtk_selection_data_get_data (selection_data);
305 	length = gtk_selection_data_get_length (selection_data);
306 	data_type = gtk_selection_data_get_data_type (selection_data);
307 
308 	g_return_val_if_fail (data != NULL, NULL);
309 
310 	/* First validate the data.  Assume it's UTF-8 or UTF-16. */
311 	if (g_utf8_validate ((const gchar *) data, length - 1, NULL))
312 		utf8_text = g_strdup ((const gchar *) data);
313 	else
314 		utf8_text = g_convert (
315 			(const gchar *) data, length,
316 			"UTF-8", "UTF-16", NULL, NULL, &error);
317 
318 	if (error != NULL) {
319 		g_warning ("%s", error->message);
320 		g_error_free (error);
321 	}
322 
323 	/* All HTML atoms are treated the same. */
324 	for (ii = 0; ii < NUM_HTML_ATOMS; ii++)
325 		if (data_type == html_atoms[ii])
326 			return utf8_text;
327 
328 	g_free (utf8_text);
329 
330 	return NULL;
331 }
332 
333 gboolean
e_selection_data_targets_include_calendar(GtkSelectionData * selection_data)334 e_selection_data_targets_include_calendar (GtkSelectionData *selection_data)
335 {
336 	GdkAtom *targets;
337 	gint n_targets;
338 	gboolean result = FALSE;
339 
340 	g_return_val_if_fail (selection_data != NULL, FALSE);
341 
342 	if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets)) {
343 		result = e_targets_include_calendar (targets, n_targets);
344 		g_free (targets);
345 	}
346 
347 	return result;
348 }
349 
350 gboolean
e_selection_data_targets_include_directory(GtkSelectionData * selection_data)351 e_selection_data_targets_include_directory (GtkSelectionData *selection_data)
352 {
353 	GdkAtom *targets;
354 	gint n_targets;
355 	gboolean result = FALSE;
356 
357 	g_return_val_if_fail (selection_data != NULL, FALSE);
358 
359 	if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets)) {
360 		result = e_targets_include_directory (targets, n_targets);
361 		g_free (targets);
362 	}
363 
364 	return result;
365 }
366 
367 gboolean
e_selection_data_targets_include_html(GtkSelectionData * selection_data)368 e_selection_data_targets_include_html (GtkSelectionData *selection_data)
369 {
370 	GdkAtom *targets;
371 	gint n_targets;
372 	gboolean result = FALSE;
373 
374 	g_return_val_if_fail (selection_data != NULL, FALSE);
375 
376 	if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets)) {
377 		result = e_targets_include_html (targets, n_targets);
378 		g_free (targets);
379 	}
380 
381 	return result;
382 }
383 
384 gboolean
e_targets_include_calendar(GdkAtom * targets,gint n_targets)385 e_targets_include_calendar (GdkAtom *targets,
386                             gint n_targets)
387 {
388 	gint ii, jj;
389 
390 	g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
391 
392 	init_atoms ();
393 
394 	for (ii = 0; ii < n_targets; ii++)
395 		for (jj = 0; jj < NUM_CALENDAR_ATOMS; jj++)
396 			if (targets[ii] == calendar_atoms[jj])
397 				return TRUE;
398 
399 	return FALSE;
400 }
401 
402 gboolean
e_targets_include_directory(GdkAtom * targets,gint n_targets)403 e_targets_include_directory (GdkAtom *targets,
404                              gint n_targets)
405 {
406 	gint ii, jj;
407 
408 	g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
409 
410 	init_atoms ();
411 
412 	for (ii = 0; ii < n_targets; ii++)
413 		for (jj = 0; jj < NUM_DIRECTORY_ATOMS; jj++)
414 			if (targets[ii] == directory_atoms[jj])
415 				return TRUE;
416 
417 	return FALSE;
418 }
419 
420 gboolean
e_targets_include_html(GdkAtom * targets,gint n_targets)421 e_targets_include_html (GdkAtom *targets,
422                         gint n_targets)
423 {
424 	gint ii, jj;
425 
426 	g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
427 
428 	init_atoms ();
429 
430 	for (ii = 0; ii < n_targets; ii++)
431 		for (jj = 0; jj < NUM_HTML_ATOMS; jj++)
432 			if (targets[ii] == html_atoms[jj])
433 				return TRUE;
434 
435 	return FALSE;
436 }
437 
438 static void
clipboard_get_calendar(GtkClipboard * clipboard,GtkSelectionData * selection_data,guint info,gchar * source)439 clipboard_get_calendar (GtkClipboard *clipboard,
440                         GtkSelectionData *selection_data,
441                         guint info,
442                         gchar *source)
443 {
444 	e_selection_data_set_calendar (selection_data, source, -1);
445 }
446 
447 static void
clipboard_clear_calendar(GtkClipboard * clipboard,gchar * source)448 clipboard_clear_calendar (GtkClipboard *clipboard,
449                           gchar *source)
450 {
451 	g_free (source);
452 }
453 
454 void
e_clipboard_set_calendar(GtkClipboard * clipboard,const gchar * source,gint length)455 e_clipboard_set_calendar (GtkClipboard *clipboard,
456                           const gchar *source,
457                           gint length)
458 {
459 	GtkTargetList *list;
460 	GtkTargetEntry *targets;
461 	gint n_targets;
462 
463 	g_return_if_fail (clipboard != NULL);
464 	g_return_if_fail (source != NULL);
465 
466 	list = gtk_target_list_new (NULL, 0);
467 	e_target_list_add_calendar_targets (list, 0);
468 
469 	targets = gtk_target_table_new_from_list (list, &n_targets);
470 
471 	if (length < 0)
472 		length = strlen (source);
473 
474 	gtk_clipboard_set_with_data (
475 		clipboard, targets, n_targets,
476 		(GtkClipboardGetFunc) clipboard_get_calendar,
477 		(GtkClipboardClearFunc) clipboard_clear_calendar,
478 		g_strndup (source, length));
479 
480 	gtk_clipboard_set_can_store (clipboard, NULL, 0);
481 
482 	gtk_target_table_free (targets, n_targets);
483 	gtk_target_list_unref (list);
484 }
485 
486 static void
clipboard_get_directory(GtkClipboard * clipboard,GtkSelectionData * selection_data,guint info,gchar * source)487 clipboard_get_directory (GtkClipboard *clipboard,
488                          GtkSelectionData *selection_data,
489                          guint info,
490                          gchar *source)
491 {
492 	e_selection_data_set_directory (selection_data, source, -1);
493 }
494 
495 static void
clipboard_clear_directory(GtkClipboard * clipboard,gchar * source)496 clipboard_clear_directory (GtkClipboard *clipboard,
497                            gchar *source)
498 {
499 	g_free (source);
500 }
501 
502 void
e_clipboard_set_directory(GtkClipboard * clipboard,const gchar * source,gint length)503 e_clipboard_set_directory (GtkClipboard *clipboard,
504                            const gchar *source,
505                            gint length)
506 {
507 	GtkTargetList *list;
508 	GtkTargetEntry *targets;
509 	gint n_targets;
510 
511 	g_return_if_fail (clipboard != NULL);
512 	g_return_if_fail (source != NULL);
513 
514 	list = gtk_target_list_new (NULL, 0);
515 	e_target_list_add_directory_targets (list, 0);
516 
517 	targets = gtk_target_table_new_from_list (list, &n_targets);
518 
519 	if (length < 0)
520 		length = strlen (source);
521 
522 	gtk_clipboard_set_with_data (
523 		clipboard, targets, n_targets,
524 		(GtkClipboardGetFunc) clipboard_get_directory,
525 		(GtkClipboardClearFunc) clipboard_clear_directory,
526 		g_strndup (source, length));
527 
528 	gtk_clipboard_set_can_store (clipboard, NULL, 0);
529 
530 	gtk_target_table_free (targets, n_targets);
531 	gtk_target_list_unref (list);
532 }
533 
534 static void
clipboard_get_html(GtkClipboard * clipboard,GtkSelectionData * selection_data,guint info,gchar * source)535 clipboard_get_html (GtkClipboard *clipboard,
536                     GtkSelectionData *selection_data,
537                     guint info,
538                     gchar *source)
539 {
540 	e_selection_data_set_html (selection_data, source, -1);
541 }
542 
543 static void
clipboard_clear_html(GtkClipboard * clipboard,gchar * source)544 clipboard_clear_html (GtkClipboard *clipboard,
545                       gchar *source)
546 {
547 	g_free (source);
548 }
549 
550 void
e_clipboard_set_html(GtkClipboard * clipboard,const gchar * source,gint length)551 e_clipboard_set_html (GtkClipboard *clipboard,
552                       const gchar *source,
553                       gint length)
554 {
555 	GtkTargetList *list;
556 	GtkTargetEntry *targets;
557 	gint n_targets;
558 
559 	g_return_if_fail (clipboard != NULL);
560 	g_return_if_fail (source != NULL);
561 
562 	list = gtk_target_list_new (NULL, 0);
563 	e_target_list_add_html_targets (list, 0);
564 
565 	targets = gtk_target_table_new_from_list (list, &n_targets);
566 
567 	if (length < 0)
568 		length = strlen (source);
569 
570 	gtk_clipboard_set_with_data (
571 		clipboard, targets, n_targets,
572 		(GtkClipboardGetFunc) clipboard_get_html,
573 		(GtkClipboardClearFunc) clipboard_clear_html,
574 		g_strndup (source, length));
575 
576 	gtk_clipboard_set_can_store (clipboard, NULL, 0);
577 
578 	gtk_target_table_free (targets, n_targets);
579 	gtk_target_list_unref (list);
580 }
581 
582 static void
clipboard_request_calendar_cb(GtkClipboard * clipboard,GtkSelectionData * selection_data,RequestTextInfo * info)583 clipboard_request_calendar_cb (GtkClipboard *clipboard,
584                                GtkSelectionData *selection_data,
585                                RequestTextInfo *info)
586 {
587 	gchar *source;
588 
589 	source = e_selection_data_get_calendar (selection_data);
590 	info->callback (clipboard, source, info->user_data);
591 	g_free (source);
592 
593 	g_slice_free (RequestTextInfo, info);
594 }
595 
596 void
e_clipboard_request_calendar(GtkClipboard * clipboard,GtkClipboardTextReceivedFunc callback,gpointer user_data)597 e_clipboard_request_calendar (GtkClipboard *clipboard,
598                               GtkClipboardTextReceivedFunc callback,
599                               gpointer user_data)
600 {
601 	RequestTextInfo *info;
602 
603 	g_return_if_fail (clipboard != NULL);
604 	g_return_if_fail (callback != NULL);
605 
606 	init_atoms ();
607 
608 	info = g_slice_new (RequestTextInfo);
609 	info->callback = callback;
610 	info->user_data = user_data;
611 
612 	gtk_clipboard_request_contents (
613 		clipboard, calendar_atoms[ATOM_CALENDAR],
614 		(GtkClipboardReceivedFunc)
615 		clipboard_request_calendar_cb, info);
616 }
617 
618 static void
clipboard_request_directory_cb(GtkClipboard * clipboard,GtkSelectionData * selection_data,RequestTextInfo * info)619 clipboard_request_directory_cb (GtkClipboard *clipboard,
620                                 GtkSelectionData *selection_data,
621                                 RequestTextInfo *info)
622 {
623 	gchar *source;
624 
625 	source = e_selection_data_get_directory (selection_data);
626 	info->callback (clipboard, source, info->user_data);
627 	g_free (source);
628 
629 	g_slice_free (RequestTextInfo, info);
630 }
631 
632 void
e_clipboard_request_directory(GtkClipboard * clipboard,GtkClipboardTextReceivedFunc callback,gpointer user_data)633 e_clipboard_request_directory (GtkClipboard *clipboard,
634                                GtkClipboardTextReceivedFunc callback,
635                                gpointer user_data)
636 {
637 	RequestTextInfo *info;
638 
639 	g_return_if_fail (clipboard != NULL);
640 	g_return_if_fail (callback != NULL);
641 
642 	init_atoms ();
643 
644 	info = g_slice_new (RequestTextInfo);
645 	info->callback = callback;
646 	info->user_data = user_data;
647 
648 	gtk_clipboard_request_contents (
649 		clipboard, directory_atoms[ATOM_DIRECTORY],
650 		(GtkClipboardReceivedFunc)
651 		clipboard_request_directory_cb, info);
652 }
653 
654 static void
clipboard_request_html_cb(GtkClipboard * clipboard,GtkSelectionData * selection_data,RequestTextInfo * info)655 clipboard_request_html_cb (GtkClipboard *clipboard,
656                            GtkSelectionData *selection_data,
657                            RequestTextInfo *info)
658 {
659 	gchar *source;
660 
661 	source = e_selection_data_get_html (selection_data);
662 	info->callback (clipboard, source, info->user_data);
663 	g_free (source);
664 
665 	g_slice_free (RequestTextInfo, info);
666 }
667 
668 void
e_clipboard_request_html(GtkClipboard * clipboard,GtkClipboardTextReceivedFunc callback,gpointer user_data)669 e_clipboard_request_html (GtkClipboard *clipboard,
670                           GtkClipboardTextReceivedFunc callback,
671                           gpointer user_data)
672 {
673 	RequestTextInfo *info;
674 
675 	g_return_if_fail (clipboard != NULL);
676 	g_return_if_fail (callback != NULL);
677 
678 	init_atoms ();
679 
680 	info = g_slice_new (RequestTextInfo);
681 	info->callback = callback;
682 	info->user_data = user_data;
683 
684 	gtk_clipboard_request_contents (
685 		clipboard, html_atoms[ATOM_HTML],
686 		(GtkClipboardReceivedFunc)
687 		clipboard_request_html_cb, info);
688 }
689 
690 gchar *
e_clipboard_wait_for_calendar(GtkClipboard * clipboard)691 e_clipboard_wait_for_calendar (GtkClipboard *clipboard)
692 {
693 	WaitForDataResults results;
694 
695 	g_return_val_if_fail (clipboard != NULL, NULL);
696 
697 	results.data = NULL;
698 	results.loop = g_main_loop_new (NULL, TRUE);
699 
700 	e_clipboard_request_calendar (
701 		clipboard, (GtkClipboardTextReceivedFunc)
702 		clipboard_wait_for_text_cb, &results);
703 
704 	if (g_main_loop_is_running (results.loop))
705 		g_main_loop_run (results.loop);
706 
707 	g_main_loop_unref (results.loop);
708 
709 	return results.data;
710 }
711 
712 gchar *
e_clipboard_wait_for_directory(GtkClipboard * clipboard)713 e_clipboard_wait_for_directory (GtkClipboard *clipboard)
714 {
715 	WaitForDataResults results;
716 
717 	g_return_val_if_fail (clipboard != NULL, NULL);
718 
719 	results.data = NULL;
720 	results.loop = g_main_loop_new (NULL, TRUE);
721 
722 	e_clipboard_request_directory (
723 		clipboard, (GtkClipboardTextReceivedFunc)
724 		clipboard_wait_for_text_cb, &results);
725 
726 	if (g_main_loop_is_running (results.loop))
727 		g_main_loop_run (results.loop);
728 
729 	g_main_loop_unref (results.loop);
730 
731 	return results.data;
732 }
733 
734 gchar *
e_clipboard_wait_for_html(GtkClipboard * clipboard)735 e_clipboard_wait_for_html (GtkClipboard *clipboard)
736 {
737 	WaitForDataResults results;
738 
739 	g_return_val_if_fail (clipboard != NULL, NULL);
740 
741 	results.data = NULL;
742 	results.loop = g_main_loop_new (NULL, TRUE);
743 
744 	e_clipboard_request_html (
745 		clipboard, (GtkClipboardTextReceivedFunc)
746 		clipboard_wait_for_text_cb, &results);
747 
748 	if (g_main_loop_is_running (results.loop))
749 		g_main_loop_run (results.loop);
750 
751 	g_main_loop_unref (results.loop);
752 
753 	return results.data;
754 }
755 
756 gboolean
e_clipboard_wait_is_calendar_available(GtkClipboard * clipboard)757 e_clipboard_wait_is_calendar_available (GtkClipboard *clipboard)
758 {
759 	GdkAtom *targets;
760 	gint n_targets;
761 	gboolean result = FALSE;
762 
763 	if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) {
764 		result = e_targets_include_calendar (targets, n_targets);
765 		g_free (targets);
766 	}
767 
768 	return result;
769 }
770 
771 gboolean
e_clipboard_wait_is_directory_available(GtkClipboard * clipboard)772 e_clipboard_wait_is_directory_available (GtkClipboard *clipboard)
773 {
774 	GdkAtom *targets;
775 	gint n_targets;
776 	gboolean result = FALSE;
777 
778 	if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) {
779 		result = e_targets_include_directory (targets, n_targets);
780 		g_free (targets);
781 	}
782 
783 	return result;
784 }
785 
786 gboolean
e_clipboard_wait_is_html_available(GtkClipboard * clipboard)787 e_clipboard_wait_is_html_available (GtkClipboard *clipboard)
788 {
789 	GdkAtom *targets;
790 	gint n_targets;
791 	gboolean result = FALSE;
792 
793 	if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) {
794 		result = e_targets_include_html (targets, n_targets);
795 		g_free (targets);
796 	}
797 
798 	return result;
799 }
800 
801 void
e_drag_dest_add_calendar_targets(GtkWidget * widget)802 e_drag_dest_add_calendar_targets (GtkWidget *widget)
803 {
804 	GtkTargetList *target_list;
805 
806 	g_return_if_fail (GTK_IS_WIDGET (widget));
807 
808 	target_list = gtk_drag_dest_get_target_list (widget);
809 	if (target_list != NULL)
810 		gtk_target_list_ref (target_list);
811 	else
812 		target_list = gtk_target_list_new (NULL, 0);
813 	e_target_list_add_calendar_targets (target_list, 0);
814 	gtk_drag_dest_set_target_list (widget, target_list);
815 	gtk_target_list_unref (target_list);
816 }
817 
818 void
e_drag_dest_add_directory_targets(GtkWidget * widget)819 e_drag_dest_add_directory_targets (GtkWidget *widget)
820 {
821 	GtkTargetList *target_list;
822 
823 	g_return_if_fail (GTK_IS_WIDGET (widget));
824 
825 	target_list = gtk_drag_dest_get_target_list (widget);
826 	if (target_list != NULL)
827 		gtk_target_list_ref (target_list);
828 	else
829 		target_list = gtk_target_list_new (NULL, 0);
830 	e_target_list_add_directory_targets (target_list, 0);
831 	gtk_drag_dest_set_target_list (widget, target_list);
832 	gtk_target_list_unref (target_list);
833 }
834 
835 void
e_drag_dest_add_html_targets(GtkWidget * widget)836 e_drag_dest_add_html_targets (GtkWidget *widget)
837 {
838 	GtkTargetList *target_list;
839 
840 	g_return_if_fail (GTK_IS_WIDGET (widget));
841 
842 	target_list = gtk_drag_dest_get_target_list (widget);
843 	if (target_list != NULL)
844 		gtk_target_list_ref (target_list);
845 	else
846 		target_list = gtk_target_list_new (NULL, 0);
847 	e_target_list_add_html_targets (target_list, 0);
848 	gtk_drag_dest_set_target_list (widget, target_list);
849 	gtk_target_list_unref (target_list);
850 }
851 
852 void
e_drag_source_add_calendar_targets(GtkWidget * widget)853 e_drag_source_add_calendar_targets (GtkWidget *widget)
854 {
855 	GtkTargetList *target_list;
856 
857 	g_return_if_fail (GTK_IS_WIDGET (widget));
858 
859 	target_list = gtk_drag_source_get_target_list (widget);
860 	if (target_list != NULL)
861 		gtk_target_list_ref (target_list);
862 	else
863 		target_list = gtk_target_list_new (NULL, 0);
864 	e_target_list_add_calendar_targets (target_list, 0);
865 	gtk_drag_source_set_target_list (widget, target_list);
866 	gtk_target_list_unref (target_list);
867 }
868 
869 void
e_drag_source_add_directory_targets(GtkWidget * widget)870 e_drag_source_add_directory_targets (GtkWidget *widget)
871 {
872 	GtkTargetList *target_list;
873 
874 	g_return_if_fail (GTK_IS_WIDGET (widget));
875 
876 	target_list = gtk_drag_source_get_target_list (widget);
877 	if (target_list != NULL)
878 		gtk_target_list_ref (target_list);
879 	else
880 		target_list = gtk_target_list_new (NULL, 0);
881 	e_target_list_add_directory_targets (target_list, 0);
882 	gtk_drag_source_set_target_list (widget, target_list);
883 	gtk_target_list_unref (target_list);
884 }
885 
886 void
e_drag_source_add_html_targets(GtkWidget * widget)887 e_drag_source_add_html_targets (GtkWidget *widget)
888 {
889 	GtkTargetList *target_list;
890 
891 	g_return_if_fail (GTK_IS_WIDGET (widget));
892 
893 	target_list = gtk_drag_source_get_target_list (widget);
894 	if (target_list != NULL)
895 		gtk_target_list_ref (target_list);
896 	else
897 		target_list = gtk_target_list_new (NULL, 0);
898 	e_target_list_add_html_targets (target_list, 0);
899 	gtk_drag_source_set_target_list (widget, target_list);
900 	gtk_target_list_unref (target_list);
901 }
902