[evolution] Simplify clipboard handling in calendar.



commit 425d49ebe1a6243d41984a87268353170e728187
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Nov 11 20:40:24 2009 -0500

    Simplify clipboard handling in calendar.

 calendar/gui/Makefile.am                    |    3 +
 calendar/gui/e-cal-selection.c              |  323 +++++++++++++++++++++++++++
 calendar/gui/e-cal-selection.h              |   75 ++++++
 calendar/gui/e-calendar-table.c             |  111 +++-------
 calendar/gui/e-calendar-view.c              |  105 ++-------
 calendar/gui/e-memo-table.c                 |  111 +++-------
 doc/reference/shell/tmpl/e-util.sgml        |   17 --
 doc/reference/shell/tmpl/eshell-unused.sgml |   15 ++
 modules/calendar/e-cal-shell-content.c      |   18 +-
 modules/calendar/e-cal-shell-view-private.h |    1 +
 modules/calendar/e-cal-shell-view.c         |    7 +-
 11 files changed, 520 insertions(+), 266 deletions(-)
---
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index dd1357c..fc9c910 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -18,6 +18,7 @@ ecalendarinclude_HEADERS =			\
 	e-cal-event.h				\
 	e-cal-model-calendar.h			\
 	e-cal-model.h				\
+	e-cal-selection.h			\
 	e-calendar-view.h			\
 	e-cell-date-edit-text.h			\
 	e-date-time-list.h                      \
@@ -112,6 +113,8 @@ libevolution_calendar_la_SOURCES = \
 	e-cal-model-memos.h			\
 	e-cal-model-tasks.c			\
 	e-cal-model-tasks.h			\
+	e-cal-selection.c			\
+	e-cal-selection.h			\
 	e-calendar-selector.c			\
 	e-calendar-selector.h			\
 	e-calendar-table.c			\
diff --git a/calendar/gui/e-cal-selection.c b/calendar/gui/e-cal-selection.c
new file mode 100644
index 0000000..27da752
--- /dev/null
+++ b/calendar/gui/e-cal-selection.c
@@ -0,0 +1,323 @@
+/*
+ * e-cal-selection.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-selection.h"
+
+#include <string.h>
+
+typedef struct _RequestCalendarInfo RequestCalendarInfo;
+typedef struct _WaitForDataResults WaitForDataResults;
+
+struct _RequestCalendarInfo {
+	GtkClipboardTextReceivedFunc callback;
+	gpointer user_data;
+};
+
+struct _WaitForDataResults {
+	GMainLoop *loop;
+	gpointer data;
+};
+
+enum {
+	ATOM_CALENDAR,
+	ATOM_X_CALENDAR,
+	ATOM_X_VCALENDAR,
+	NUM_CALENDAR_ATOMS
+};
+
+static GdkAtom calendar_atoms[NUM_CALENDAR_ATOMS];
+
+static void
+init_atoms (void)
+{
+	static gboolean initialized = FALSE;
+
+	if (initialized)
+		return;
+
+	calendar_atoms[ATOM_CALENDAR] =
+		gdk_atom_intern_static_string ("text/calendar");
+
+	calendar_atoms[ATOM_X_CALENDAR] =
+		gdk_atom_intern_static_string ("text/x-calendar");
+
+	calendar_atoms[ATOM_X_VCALENDAR] =
+		gdk_atom_intern_static_string ("text/x-vcalendar");
+
+	initialized = TRUE;
+}
+
+void
+e_target_list_add_calendar_targets (GtkTargetList *list,
+                                    guint info)
+{
+	gint ii;
+
+	g_return_if_fail (list != NULL);
+
+	init_atoms ();
+
+	for (ii = 0; ii < NUM_CALENDAR_ATOMS; ii++)
+		gtk_target_list_add (list, calendar_atoms[ii], 0, info);
+}
+
+gboolean
+e_selection_data_set_calendar (GtkSelectionData *selection_data,
+                               const gchar *source,
+                               gint length)
+{
+	GdkAtom atom;
+	gint ii;
+
+	g_return_val_if_fail (selection_data != NULL, FALSE);
+
+	if (length < 0)
+		length = strlen (source);
+
+	init_atoms ();
+
+	atom = gtk_selection_data_get_target (selection_data);
+
+	/* All calendar atoms are treated the same. */
+	for (ii = 0; ii < NUM_CALENDAR_ATOMS; ii++) {
+		if (atom == calendar_atoms[ii]) {
+			gtk_selection_data_set (
+				selection_data, atom, 8,
+				(guchar *) source, length);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+gchar *
+e_selection_data_get_calendar (GtkSelectionData *selection_data)
+{
+	GdkAtom data_type;
+	const guchar *data = NULL;
+	gint ii;
+
+	/* XXX May need to do encoding and line ending conversions
+	 *     here.  Not worrying about it for now. */
+
+	g_return_val_if_fail (selection_data != NULL, NULL);
+
+	data = gtk_selection_data_get_data (selection_data);
+	data_type = gtk_selection_data_get_data_type (selection_data);
+
+	/* All calendar atoms are treated the same. */
+	for (ii = 0; ii < NUM_CALENDAR_ATOMS; ii++)
+		if (data_type == calendar_atoms[ii])
+			return g_strdup ((gchar *) data);
+
+	return NULL;
+}
+
+gboolean
+e_selection_data_targets_include_calendar (GtkSelectionData *selection_data)
+{
+	GdkAtom *targets;
+	gint n_targets;
+	gboolean result = FALSE;
+
+	g_return_val_if_fail (selection_data != NULL, FALSE);
+
+	if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets)) {
+		result = e_targets_include_calendar (targets, n_targets);
+		g_free (targets);
+	}
+
+	return result;
+}
+
+gboolean
+e_targets_include_calendar (GdkAtom *targets,
+                            gint n_targets)
+{
+	gint ii, jj;
+
+	g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
+
+	init_atoms ();
+
+	for (ii = 0; ii < n_targets; ii++)
+		for (jj = 0; jj < NUM_CALENDAR_ATOMS; jj++)
+			if (targets[ii] == calendar_atoms[jj])
+				return TRUE;
+
+	return FALSE;
+}
+
+static void
+clipboard_get_calendar (GtkClipboard *clipboard,
+                        GtkSelectionData *selection_data,
+                        guint info,
+                        gchar *source)
+{
+	e_selection_data_set_calendar (selection_data, source, -1);
+}
+
+static void
+clipboard_clear_calendar (GtkClipboard *clipboard,
+                          gchar *source)
+{
+	g_free (source);
+}
+
+void
+e_clipboard_set_calendar (GtkClipboard *clipboard,
+                          const gchar *source,
+                          gint length)
+{
+	GtkTargetList *list;
+	GtkTargetEntry *targets;
+	gint n_targets;
+
+	g_return_if_fail (clipboard != NULL);
+	g_return_if_fail (source != NULL);
+
+	list = gtk_target_list_new (NULL, 0);
+	e_target_list_add_calendar_targets (list, 0);
+
+	targets = gtk_target_table_new_from_list (list, &n_targets);
+
+	if (length < 0)
+		length = strlen (source);
+
+	gtk_clipboard_set_with_data (
+		clipboard, targets, n_targets,
+		(GtkClipboardGetFunc) clipboard_get_calendar,
+		(GtkClipboardClearFunc) clipboard_clear_calendar,
+		g_strndup (source, length));
+
+	gtk_clipboard_set_can_store (clipboard, NULL, 0);
+
+	gtk_target_table_free (targets, n_targets);
+	gtk_target_list_unref (list);
+}
+
+static void
+clipboard_request_calendar_cb (GtkClipboard *clipboard,
+                               GtkSelectionData *selection_data,
+                               RequestCalendarInfo *info)
+{
+	gchar *source;
+
+	source = e_selection_data_get_calendar (selection_data);
+	info->callback (clipboard, source, info->user_data);
+	g_free (source);
+
+	g_slice_free (RequestCalendarInfo, info);
+}
+
+void
+e_clipboard_request_calendar (GtkClipboard *clipboard,
+                              GtkClipboardTextReceivedFunc callback,
+                              gpointer user_data)
+{
+	RequestCalendarInfo *info;
+
+	g_return_if_fail (clipboard != NULL);
+	g_return_if_fail (callback != NULL);
+
+	info = g_slice_new (RequestCalendarInfo);
+	info->callback = callback;
+	info->user_data = user_data;
+
+	gtk_clipboard_request_contents (
+		clipboard, calendar_atoms[ATOM_CALENDAR],
+		(GtkClipboardReceivedFunc)
+		clipboard_request_calendar_cb, info);
+}
+
+static void
+clipboard_wait_for_calendar_cb (GtkClipboard *clipboard,
+                                const gchar *source,
+                                WaitForDataResults *results)
+{
+	results->data = g_strdup (source);
+	g_main_loop_quit (results->loop);
+}
+
+gchar *
+e_clipboard_wait_for_calendar (GtkClipboard *clipboard)
+{
+	WaitForDataResults results;
+
+	g_return_val_if_fail (clipboard != NULL, NULL);
+
+	results.data = NULL;
+	results.loop = g_main_loop_new (NULL, TRUE);
+
+	e_clipboard_request_calendar (
+		clipboard, (GtkClipboardTextReceivedFunc)
+		clipboard_wait_for_calendar_cb, &results);
+
+	if (g_main_loop_is_running (results.loop)) {
+		GDK_THREADS_LEAVE ();
+		g_main_loop_run (results.loop);
+		GDK_THREADS_ENTER ();
+	}
+
+	g_main_loop_unref (results.loop);
+
+	return results.data;
+}
+
+gboolean
+e_clipboard_wait_is_calendar_available (GtkClipboard *clipboard)
+{
+	GdkAtom *targets;
+	gint n_targets;
+	gboolean result = FALSE;
+
+	if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) {
+		result = e_targets_include_calendar (targets, n_targets);
+		g_free (targets);
+	}
+
+	return result;
+}
+
+void
+e_clipboard_print_targets (GtkClipboard *clipboard)
+{
+	GdkAtom *targets;
+	gchar *target_name;
+	gint n_targets, ii;
+
+	g_return_if_fail (clipboard != NULL);
+
+	gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets);
+
+	g_print ("Clipboard Targets:\n");
+
+	if (n_targets == 0)
+		g_print ("  (none)\n");
+	else for (ii = 0; ii < n_targets; ii++) {
+		target_name = gdk_atom_name (targets[ii]);
+		g_print ("  %s\n", target_name);
+		g_free (target_name);
+	}
+
+	g_free (targets);
+}
diff --git a/calendar/gui/e-cal-selection.h b/calendar/gui/e-cal-selection.h
new file mode 100644
index 0000000..c79f1d6
--- /dev/null
+++ b/calendar/gui/e-cal-selection.h
@@ -0,0 +1,75 @@
+/*
+ * e-cal-selection.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-cal-selection
+ * @short_description: calendar selection utilities
+ * @include: calendar/gui/e-cal-selection.h
+ **/
+
+#ifndef E_CAL_SELECTION_H
+#define E_CAL_SELECTION_H
+
+#include <gtk/gtk.h>
+
+/* This API mimics GTK's API for dealing with text, image and URI data. */
+
+G_BEGIN_DECLS
+
+/* Selection Functions */
+
+void		e_target_list_add_calendar_targets
+					(GtkTargetList *list,
+					 guint info);
+gboolean	e_selection_data_set_calendar
+					(GtkSelectionData *selection_data,
+					 const gchar *source,
+					 gint length);
+gchar *		e_selection_data_get_calendar
+					(GtkSelectionData *selection_data);
+gboolean	e_selection_data_targets_include_calendar
+					(GtkSelectionData *selection_data);
+gboolean	e_targets_include_calendar
+					(GdkAtom *targets,
+					 gint n_targets);
+
+/* Clipboard Functions */
+
+void		e_clipboard_set_calendar(GtkClipboard *clipboard,
+					 const gchar *source,
+					 gint length);
+void		e_clipboard_request_calendar
+					(GtkClipboard *clipboard,
+					 GtkClipboardTextReceivedFunc callback,
+					 gpointer user_data);
+gchar *		e_clipboard_wait_for_calendar
+					(GtkClipboard *clipboard);
+gboolean	e_clipboard_wait_is_calendar_available
+					(GtkClipboard *clipboard);
+
+/* Debugging Functions */
+
+void		e_clipboard_print_targets
+					(GtkClipboard *clipboard);
+
+G_END_DECLS
+
+#endif /* E_CAL_SELECTION_H */
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 483c032..3903c58 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -55,6 +55,7 @@
 #include "dialogs/delete-error.h"
 #include "dialogs/task-editor.h"
 #include "e-cal-model-tasks.h"
+#include "e-cal-selection.h"
 #include "e-calendar-table.h"
 #include "e-calendar-view.h"
 #include "e-cell-date-edit-text.h"
@@ -85,20 +86,10 @@ enum {
 	LAST_SIGNAL
 };
 
-enum {
-	TARGET_TYPE_VCALENDAR
-};
-
-static GtkTargetEntry target_types[] = {
-	{ (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR },
-	{ (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR }
-};
-
 static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data);
 
 static gpointer parent_class;
 static guint signals[LAST_SIGNAL];
-static GdkAtom clipboard_atom;
 
 /* The icons to represent the task. */
 #define NUM_ICONS 4
@@ -938,8 +929,6 @@ calendar_table_class_init (ECalendarTableClass *class)
 		NULL, NULL,
 		g_cclosure_marshal_VOID__VOID,
 		G_TYPE_NONE, 0);
-
-	clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
 }
 
 static void
@@ -1277,26 +1266,6 @@ e_calendar_table_cut_clipboard (ECalendarTable *cal_table)
 	delete_selected_components (cal_table);
 }
 
-static void
-clipboard_get_calendar_cb (GtkClipboard *clipboard,
-			   GtkSelectionData *selection_data,
-			   guint info,
-			   gpointer data)
-{
-	gchar *comp_str = (gchar *) data;
-
-	switch (info) {
-	case TARGET_TYPE_VCALENDAR:
-		gtk_selection_data_set (selection_data,
-					gdk_atom_intern (target_types[info].target, FALSE), 8,
-					(const guchar *) comp_str,
-					(gint) strlen (comp_str));
-		break;
-	default:
-		break;
-	}
-}
-
 /* callback for e_table_selected_row_foreach */
 static void
 copy_row_cb (gint model_row, gpointer data)
@@ -1351,16 +1320,10 @@ e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
 	etable = e_calendar_table_get_table (cal_table);
 	e_table_selected_row_foreach (etable, copy_row_cb, cal_table);
 	comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
-	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom);
-	if (!gtk_clipboard_set_with_data (
-		clipboard, target_types, G_N_ELEMENTS (target_types),
-		clipboard_get_calendar_cb, NULL, comp_str)) {
-		/* no-op */
-	} else {
-		gtk_clipboard_set_can_store (
-			clipboard, target_types + 1,
-			G_N_ELEMENTS (target_types) - 1);
-	}
+
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+	e_clipboard_set_calendar (clipboard, comp_str, -1);
+	gtk_clipboard_store (clipboard);
 
 	/* free memory */
 	icalcomponent_free (cal_table->tmp_vcal);
@@ -1449,37 +1412,6 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
 	calendar_table_emit_status_message (cal_table, NULL, -1.0);
 }
 
-static void
-clipboard_paste_received_cb (GtkClipboard *clipboard,
-			     GtkSelectionData *selection_data,
-			     gpointer data)
-{
-	ECalendarTable *cal_table = E_CALENDAR_TABLE (data);
-	ETable *e_table = e_calendar_table_get_table (cal_table);
-	GnomeCanvas *canvas = e_table->table_canvas;
-	GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item;
-
-	if (gtk_clipboard_wait_is_text_available (clipboard) &&
-	    GTK_WIDGET_HAS_FOCUS (canvas) &&
-	    E_IS_TABLE_ITEM (item) &&
-	    E_TABLE_ITEM (item)->editing_col >= 0 &&
-	    E_TABLE_ITEM (item)->editing_row >= 0) {
-		ETableItem *eti = E_TABLE_ITEM (item);
-		ECellView *cell_view = eti->cell_views[eti->editing_col];
-		e_cell_text_paste_clipboard (cell_view, eti->editing_col, eti->editing_row);
-	} else {
-		GdkAtom type = selection_data->type;
-		if (type == gdk_atom_intern (target_types[TARGET_TYPE_VCALENDAR].target, TRUE)) {
-			gchar *result = NULL;
-			result = g_strndup ((const gchar *) selection_data->data,
-					    selection_data->length);
-			clipboard_get_calendar_data (cal_table, result);
-			g_free (result);
-		}
-	}
-	g_object_unref (cal_table);
-}
-
 /**
  * e_calendar_table_paste_clipboard:
  * @cal_table: A calendar table.
@@ -1490,15 +1422,38 @@ void
 e_calendar_table_paste_clipboard (ECalendarTable *cal_table)
 {
 	GtkClipboard *clipboard;
+	GnomeCanvasItem *item;
+	ETable *etable;
 
 	g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
 
-	clipboard = gtk_widget_get_clipboard (
-		GTK_WIDGET (cal_table), clipboard_atom);
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 
-	gtk_clipboard_request_contents (
-		clipboard, gdk_atom_intern (target_types[0].target, FALSE),
-		clipboard_paste_received_cb, g_object_ref (cal_table));
+	etable = e_calendar_table_get_table (cal_table);
+	item = GNOME_CANVAS (etable->table_canvas)->focused_item;
+
+	/* Paste text into a cell being edited. */
+	if (gtk_clipboard_wait_is_text_available (clipboard) &&
+		GTK_WIDGET_HAS_FOCUS (etable->table_canvas) &&
+		E_IS_TABLE_ITEM (item) &&
+		E_TABLE_ITEM (item)->editing_col >= 0 &&
+		E_TABLE_ITEM (item)->editing_row >= 0) {
+
+		ETableItem *etable_item = E_TABLE_ITEM (item);
+
+		e_cell_text_paste_clipboard (
+			etable_item->cell_views[etable_item->editing_col],
+			etable_item->editing_col,
+			etable_item->editing_row);
+
+	/* Paste iCalendar data into the table. */
+	} else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+		gchar *calendar_source;
+
+		calendar_source = e_clipboard_wait_for_calendar (clipboard);
+		clipboard_get_calendar_data (cal_table, calendar_source);
+		g_free (calendar_source);
+	}
 }
 
 static void
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index 805ec93..0ea84e1 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -45,6 +45,7 @@
 #include "comp-util.h"
 #include "ea-calendar.h"
 #include "e-cal-model-calendar.h"
+#include "e-cal-selection.h"
 #include "e-calendar-view.h"
 #include "itip-utils.h"
 #include "dialogs/comp-editor-util.h"
@@ -97,15 +98,6 @@ static guint signals[LAST_SIGNAL];
 
 G_DEFINE_TYPE (ECalendarView, e_calendar_view, GTK_TYPE_TABLE)
 
-enum TargetType{
-	TARGET_TYPE_VCALENDAR
-};
-
-static GtkTargetEntry target_types[] = {
-	{ (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR },
-	{ (gchar *) "text/calendar",   0, TARGET_TYPE_VCALENDAR }
-};
-
 static void
 calendar_view_set_model (ECalendarView *calendar_view,
                          ECalModel *model)
@@ -661,34 +653,6 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view)
 }
 
 static void
-clipboard_clear_calendar_cb (GtkClipboard *clipboard,
-			     gpointer data)
-{
-	g_free (data);
-}
-
-static void
-clipboard_get_calendar_cb (GtkClipboard *clipboard,
-			   GtkSelectionData *selection_data,
-			   guint info,
-			   gpointer data)
-{
-	gchar *comp_str = (gchar *) data;
-
-	switch (info) {
-	case TARGET_TYPE_VCALENDAR:
-		gtk_selection_data_set (selection_data,
-					selection_data->target,
-					8,
-					(const guchar *) comp_str,
-					(gint) strlen (comp_str));
-		break;
-	default:
-		break;
-	}
-}
-
-static void
 add_related_timezones (icalcomponent *des_icalcomp, icalcomponent *src_icalcomp, ECal *client)
 {
 	icalproperty_kind look_in[] = {
@@ -778,21 +742,16 @@ e_calendar_view_copy_clipboard (ECalendarView *cal_view)
 		icalcomponent_add_component (vcal_comp, new_icalcomp);
 	}
 
-	/* copy the VCALENDAR to the clipboard */
-	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_view), GDK_SELECTION_CLIPBOARD);
 	comp_str = icalcomponent_as_ical_string_r (vcal_comp);
 
-	if (!gtk_clipboard_set_with_data (clipboard, target_types, G_N_ELEMENTS (target_types),
-					  clipboard_get_calendar_cb,
-					  clipboard_clear_calendar_cb,
-					  comp_str)) {
-		g_free (comp_str);
-	} else {
-		gtk_clipboard_set_can_store (clipboard, target_types + 1, G_N_ELEMENTS (target_types) - 1);
-	}
+	/* copy the VCALENDAR to the clipboard */
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+	e_clipboard_set_calendar (clipboard, comp_str, -1);
+	gtk_clipboard_store (clipboard);
 
 	/* free memory */
 	icalcomponent_free (vcal_comp);
+	g_free (comp_str);
 	g_list_free (selected);
 }
 
@@ -879,52 +838,32 @@ clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text)
 #endif
 }
 
-static void
-e_calendar_view_paste_text (ECalendarView *cal_view)
+void
+e_calendar_view_paste_clipboard (ECalendarView *cal_view)
 {
-	ECalendarViewClass *class;
+	GtkClipboard *clipboard;
 
 	g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
 
-	class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
-	g_return_if_fail (class->paste_text != NULL);
-
-	class->paste_text (cal_view);
-}
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 
-static void
-clipboard_paste_received_cb (GtkClipboard *clipboard,
-			     GtkSelectionData *selection_data,
-			     gpointer data)
-{
+	/* Paste text into an event being edited. */
 	if (gtk_clipboard_wait_is_text_available (clipboard)) {
-		e_calendar_view_paste_text (E_CALENDAR_VIEW (data));
-	} else {
-		GdkAtom type = selection_data->type;
-		if (type == gdk_atom_intern (target_types[TARGET_TYPE_VCALENDAR].target, TRUE)) {
-			gchar *result = NULL;
-			result = g_strndup ((const gchar *) selection_data->data,
-					    selection_data->length);
-			clipboard_get_calendar_data (E_CALENDAR_VIEW (data), result);
-			g_free (result);
-		}
-	}
-	g_object_unref (data);
-}
+		ECalendarViewClass *class;
 
-void
-e_calendar_view_paste_clipboard (ECalendarView *cal_view)
-{
-	GtkClipboard *clipboard;
+		class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+		g_return_if_fail (class->paste_text != NULL);
 
-	g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
+		class->paste_text (cal_view);
 
-	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_view), GDK_SELECTION_CLIPBOARD);
-	g_object_ref (cal_view);
+	/* Paste iCalendar data into the view. */
+	} else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+		gchar *calendar_source;
 
-	gtk_clipboard_request_contents (clipboard,
-					gdk_atom_intern (target_types[TARGET_TYPE_VCALENDAR].target, FALSE),
-					clipboard_paste_received_cb, cal_view);
+		calendar_source = e_clipboard_wait_for_calendar (clipboard);
+		clipboard_get_calendar_data (cal_view, calendar_source);
+		g_free (calendar_source);
+	}
 }
 
 static void
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 9a73680..c111bd6 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -53,6 +53,7 @@
 #include "dialogs/delete-error.h"
 #include "dialogs/memo-editor.h"
 #include "e-cal-model-memos.h"
+#include "e-cal-selection.h"
 #include "e-memo-table.h"
 #include "e-calendar-view.h"
 #include "e-cell-date-edit-text.h"
@@ -83,20 +84,10 @@ enum {
 	LAST_SIGNAL
 };
 
-enum {
-	TARGET_TYPE_VCALENDAR
-};
-
-static GtkTargetEntry target_types[] = {
-	{ (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR },
-	{ (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR }
-};
-
 static struct tm e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data);
 
 static gpointer parent_class;
 static guint signals[LAST_SIGNAL];
-static GdkAtom clipboard_atom;
 
 /* The icons to represent the task. */
 #define NUM_ICONS 2
@@ -721,8 +712,6 @@ memo_table_class_init (EMemoTableClass *class)
 		NULL, NULL,
 		g_cclosure_marshal_VOID__VOID,
 		G_TYPE_NONE, 0);
-
-	clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
 }
 
 static void
@@ -992,26 +981,6 @@ e_memo_table_cut_clipboard (EMemoTable *memo_table)
 	delete_selected_components (memo_table);
 }
 
-static void
-clipboard_get_calendar_cb (GtkClipboard *clipboard,
-			   GtkSelectionData *selection_data,
-			   guint info,
-			   gpointer data)
-{
-	gchar *comp_str = (gchar *) data;
-
-	switch (info) {
-	case TARGET_TYPE_VCALENDAR:
-		gtk_selection_data_set (selection_data,
-					gdk_atom_intern (target_types[info].target, FALSE), 8,
-					(const guchar *) comp_str,
-					(gint) strlen (comp_str));
-		break;
-	default:
-		break;
-	}
-}
-
 /* callback for e_table_selected_row_foreach */
 static void
 copy_row_cb (gint model_row, gpointer data)
@@ -1066,16 +1035,10 @@ e_memo_table_copy_clipboard (EMemoTable *memo_table)
 	etable = e_memo_table_get_table (memo_table);
 	e_table_selected_row_foreach (etable, copy_row_cb, memo_table);
 	comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal);
-	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom);
-	if (!gtk_clipboard_set_with_data (
-		clipboard, target_types, G_N_ELEMENTS (target_types),
-		clipboard_get_calendar_cb, NULL, comp_str)) {
-		/* no-op */
-	} else {
-		gtk_clipboard_set_can_store (
-			clipboard, target_types + 1,
-			G_N_ELEMENTS (target_types) - 1);
-	}
+
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+	e_clipboard_set_calendar (clipboard, comp_str, -1);
+	gtk_clipboard_store (clipboard);
 
 	/* free memory */
 	icalcomponent_free (memo_table->tmp_vcal);
@@ -1164,37 +1127,6 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
 	memo_table_emit_status_message (memo_table, NULL, -1.0);
 }
 
-static void
-clipboard_paste_received_cb (GtkClipboard *clipboard,
-			     GtkSelectionData *selection_data,
-			     gpointer data)
-{
-	EMemoTable *memo_table = E_MEMO_TABLE (data);
-	ETable *e_table = e_memo_table_get_table (memo_table);
-	GnomeCanvas *canvas = e_table->table_canvas;
-	GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item;
-
-	if (gtk_clipboard_wait_is_text_available (clipboard) &&
-	    GTK_WIDGET_HAS_FOCUS (canvas) &&
-	    E_IS_TABLE_ITEM (item) &&
-	    E_TABLE_ITEM (item)->editing_col >= 0 &&
-	    E_TABLE_ITEM (item)->editing_row >= 0) {
-		ETableItem *eti = E_TABLE_ITEM (item);
-		ECellView *cell_view = eti->cell_views[eti->editing_col];
-		e_cell_text_paste_clipboard (cell_view, eti->editing_col, eti->editing_row);
-	} else {
-		GdkAtom type = selection_data->type;
-		if (type == gdk_atom_intern (target_types[TARGET_TYPE_VCALENDAR].target, TRUE)) {
-			gchar *result = NULL;
-			result = g_strndup ((const gchar *) selection_data->data,
-					    selection_data->length);
-			clipboard_get_calendar_data (memo_table, result);
-			g_free (result);
-		}
-	}
-	g_object_unref (memo_table);
-}
-
 /**
  * e_memo_table_paste_clipboard:
  * @memo_table: A calendar table.
@@ -1205,15 +1137,38 @@ void
 e_memo_table_paste_clipboard (EMemoTable *memo_table)
 {
 	GtkClipboard *clipboard;
+	GnomeCanvasItem *item;
+	ETable *etable;
 
 	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
 
-	clipboard = gtk_widget_get_clipboard (
-		GTK_WIDGET (memo_table), clipboard_atom);
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 
-	gtk_clipboard_request_contents (
-		clipboard, gdk_atom_intern (target_types[0].target, FALSE),
-		clipboard_paste_received_cb, g_object_ref (memo_table));
+	etable = e_memo_table_get_table (memo_table);
+	item = GNOME_CANVAS (etable->table_canvas)->focused_item;
+
+	/* Paste text into a cell being edited. */
+	if (gtk_clipboard_wait_is_text_available (clipboard) &&
+		GTK_WIDGET_HAS_FOCUS (etable->table_canvas) &&
+		E_IS_TABLE_ITEM (item) &&
+		E_TABLE_ITEM (item)->editing_col >= 0 &&
+		E_TABLE_ITEM (item)->editing_row >= 0) {
+
+		ETableItem *etable_item = E_TABLE_ITEM (item);
+
+		e_cell_text_paste_clipboard (
+			etable_item->cell_views[etable_item->editing_col],
+			etable_item->editing_col,
+			etable_item->editing_row);
+
+	/* Paste iCalendar data into the table. */
+	} else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+		gchar *calendar_source;
+
+		calendar_source = e_clipboard_wait_for_calendar (clipboard);
+		clipboard_get_calendar_data (memo_table, calendar_source);
+		g_free (calendar_source);
+	}
 }
 
 /* Loads the state of the table (headers shown etc.) from the given file. */
diff --git a/doc/reference/shell/tmpl/e-util.sgml b/doc/reference/shell/tmpl/e-util.sgml
index b58fb3d..6a7f354 100644
--- a/doc/reference/shell/tmpl/e-util.sgml
+++ b/doc/reference/shell/tmpl/e-util.sgml
@@ -294,23 +294,6 @@ Miscellaneous Utility Functions
 @Returns: 
 
 
-<!-- ##### FUNCTION e_file_update_save_path ##### -->
-<para>
-
-</para>
-
- uri: 
- free: 
-
-
-<!-- ##### FUNCTION e_file_get_save_path ##### -->
-<para>
-
-</para>
-
- Returns: 
-
-
 <!-- ##### FUNCTION e_file_lock_create ##### -->
 <para>
 
diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml
index 8c8bcbd..9533427 100644
--- a/doc/reference/shell/tmpl/eshell-unused.sgml
+++ b/doc/reference/shell/tmpl/eshell-unused.sgml
@@ -1904,6 +1904,21 @@ intelligent
 @action: 
 @Returns: 
 
+<!-- ##### FUNCTION e_file_get_save_path ##### -->
+<para>
+
+</para>
+
+ Returns: 
+
+<!-- ##### FUNCTION e_file_update_save_path ##### -->
+<para>
+
+</para>
+
+ uri: 
+ free: 
+
 <!-- ##### FUNCTION e_shell_backend_get_filename ##### -->
 <para>
 
diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c
index d784ce7..e797c0c 100644
--- a/modules/calendar/e-cal-shell-content.c
+++ b/modules/calendar/e-cal-shell-content.c
@@ -160,51 +160,51 @@ cal_shell_content_get_focus_location (ECalShellContent *cal_shell_content)
 	task_table = E_CALENDAR_TABLE (cal_shell_content->priv->task_table);
 
 	table = e_memo_table_get_table (memo_table);
-	if (GTK_WIDGET_HAS_FOCUS (table->table_canvas))
+	if (gtk_widget_is_focus (GTK_WIDGET (table->table_canvas)))
 		return FOCUS_MEMO_TABLE;
 
 	table = e_calendar_table_get_table (task_table);
-	if (GTK_WIDGET_HAS_FOCUS (table->table_canvas))
+	if (gtk_widget_is_focus (GTK_WIDGET (table->table_canvas)))
 		return FOCUS_TASK_TABLE;
 
 	if (E_IS_DAY_VIEW (calendar_view)) {
 		EDayView *day_view = E_DAY_VIEW (calendar_view);
 
-		if (GTK_WIDGET_HAS_FOCUS (day_view->top_canvas))
+		if (gtk_widget_is_focus (day_view->top_canvas))
 			return FOCUS_CALENDAR;
 
 		if (GNOME_CANVAS (day_view->top_canvas)->focused_item != NULL)
 			return FOCUS_CALENDAR;
 
-		if (GTK_WIDGET_HAS_FOCUS (day_view->main_canvas))
+		if (gtk_widget_is_focus (day_view->main_canvas))
 			return FOCUS_CALENDAR;
 
 		if (GNOME_CANVAS (day_view->main_canvas)->focused_item != NULL)
 			return FOCUS_CALENDAR;
 
-		if (GTK_WIDGET_HAS_FOCUS (day_view))
+		if (gtk_widget_is_focus (GTK_WIDGET (day_view)))
 			return FOCUS_CALENDAR;
 
 	} else if (E_IS_WEEK_VIEW (calendar_view)) {
 		EWeekView *week_view = E_WEEK_VIEW (calendar_view);
 
-		if (GTK_WIDGET_HAS_FOCUS (week_view->main_canvas))
+		if (gtk_widget_is_focus (week_view->main_canvas))
 			return FOCUS_CALENDAR;
 
 		if (GNOME_CANVAS (week_view->main_canvas)->focused_item != NULL)
 			return FOCUS_CALENDAR;
 
-		if (GTK_WIDGET_HAS_FOCUS (week_view))
+		if (gtk_widget_is_focus (GTK_WIDGET (week_view)))
 			return FOCUS_CALENDAR;
 
 	} else if (E_IS_CAL_LIST_VIEW (calendar_view)) {
 		ECalListView *list_view = E_CAL_LIST_VIEW (calendar_view);
 
 		table = e_table_scrolled_get_table (list_view->table_scrolled);
-		if (GTK_WIDGET_HAS_FOCUS (table))
+		if (gtk_widget_is_focus (GTK_WIDGET (table)))
 			return FOCUS_CALENDAR;
 
-		if (GTK_WIDGET_HAS_FOCUS (list_view))
+		if (gtk_widget_is_focus (GTK_WIDGET (list_view)))
 			return FOCUS_CALENDAR;
 	}
 
diff --git a/modules/calendar/e-cal-shell-view-private.h b/modules/calendar/e-cal-shell-view-private.h
index 2ee0cff..7f6413c 100644
--- a/modules/calendar/e-cal-shell-view-private.h
+++ b/modules/calendar/e-cal-shell-view-private.h
@@ -44,6 +44,7 @@
 #include "calendar/gui/comp-util.h"
 #include "calendar/gui/e-cal-list-view.h"
 #include "calendar/gui/e-cal-model-tasks.h"
+#include "calendar/gui/e-cal-selection.h"
 #include "calendar/gui/e-calendar-view.h"
 #include "calendar/gui/e-day-view.h"
 #include "calendar/gui/e-week-view.h"
diff --git a/modules/calendar/e-cal-shell-view.c b/modules/calendar/e-cal-shell-view.c
index b696660..60a2781 100644
--- a/modules/calendar/e-cal-shell-view.c
+++ b/modules/calendar/e-cal-shell-view.c
@@ -284,6 +284,7 @@ cal_shell_view_update_actions (EShellView *shell_view)
 	gboolean sensitive;
 	gboolean is_meeting = FALSE;
 	gboolean is_delegatable = FALSE;
+	gboolean clipboard_has_calendar;
 	gint n_selected;
 
 	priv = E_CAL_SHELL_VIEW_GET_PRIVATE (shell_view);
@@ -356,6 +357,10 @@ cal_shell_view_update_actions (EShellView *shell_view)
 		uri = e_source_peek_relative_uri (source);
 	user_created_source = (uri != NULL && strcmp (uri, "system") != 0);
 
+	clipboard_has_calendar =
+		e_clipboard_wait_is_calendar_available (
+		gtk_clipboard_get (GDK_SELECTION_CLIPBOARD));
+
 	action = ACTION (CALENDAR_COPY);
 	sensitive = (source != NULL);
 	gtk_action_set_sensitive (action, sensitive);
@@ -381,7 +386,7 @@ cal_shell_view_update_actions (EShellView *shell_view)
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (EVENT_CLIPBOARD_PASTE);
-	sensitive = editable;
+	sensitive = editable && clipboard_has_calendar;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (EVENT_DELEGATE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]