aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-calendar-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/e-calendar-table.c')
-rw-r--r--calendar/gui/e-calendar-table.c88
1 files changed, 80 insertions, 8 deletions
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 826075fe72..c3f9dbb2c7 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -62,6 +62,17 @@
#include "e-tasks.h"
#include "misc.h"
+enum TargetType{
+ TARGET_TYPE_VCALENDAR
+};
+
+static GtkTargetEntry target_types[] = {
+ { "text/x-calendar", 0, TARGET_TYPE_VCALENDAR },
+ { "text/calendar", 0, TARGET_TYPE_VCALENDAR }
+};
+
+static guint n_target_types = G_N_ELEMENTS (target_types);
+
extern ECompEditorRegistry *comp_editor_registry;
static void e_calendar_table_class_init (ECalendarTableClass *class);
@@ -867,6 +878,26 @@ 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 (int model_row, gpointer data)
@@ -907,6 +938,7 @@ void
e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
{
ETable *etable;
+ GtkClipboard *clipboard;
char *comp_str;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
@@ -917,9 +949,14 @@ e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
e_table_selected_row_foreach (etable, copy_row_cb, cal_table);
comp_str = icalcomponent_as_ical_string (cal_table->tmp_vcal);
- gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom),
- (const char *) comp_str,
- g_utf8_strlen (comp_str, -1));
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom);
+ if (!gtk_clipboard_set_with_data(clipboard, target_types, n_target_types,
+ clipboard_get_calendar_cb,
+ NULL, comp_str)) {
+ g_free (comp_str);
+ } else {
+ gtk_clipboard_set_can_store (clipboard, target_types + 1, n_target_types - 1);
+ }
/* free memory */
icalcomponent_free (cal_table->tmp_vcal);
@@ -927,7 +964,7 @@ e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
}
static void
-clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarTable *cal_table)
+clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
{
icalcomponent *icalcomp;
char *uid;
@@ -988,8 +1025,7 @@ clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarTabl
subcomp = icalcomponent_get_next_component (
vcal_comp, ICAL_ANY_COMPONENT);
}
- }
- else {
+ } else {
comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (comp, icalcomp);
uid = e_cal_component_gen_uid ();
@@ -1004,6 +1040,37 @@ clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarTabl
e_calendar_table_set_status_message (cal_table, NULL, -1);
}
+static void
+clipboard_paste_received_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
+{
+ ECalendarTable *cal_table = E_CALENDAR_TABLE (data);
+ ETable *e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
+ 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.
@@ -1013,10 +1080,15 @@ clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarTabl
void
e_calendar_table_paste_clipboard (ECalendarTable *cal_table)
{
+ GtkClipboard *clipboard;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
- gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom),
- (GtkClipboardTextReceivedFunc) clipboard_get_text_cb, cal_table);
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom);
+ g_object_ref (cal_table);
+
+ gtk_clipboard_request_contents (clipboard,
+ gdk_atom_intern (target_types[0].target, FALSE),
+ clipboard_paste_received_cb, cal_table);
}
/* Opens a task in the task editor */