diff options
Diffstat (limited to 'calendar/gui/e-calendar-view.c')
-rw-r--r-- | calendar/gui/e-calendar-view.c | 102 |
1 files changed, 89 insertions, 13 deletions
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 594527aee8..d8d517c9d9 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -74,7 +74,6 @@ static void e_calendar_view_set_property (GObject *object, guint property_id, co static void e_calendar_view_destroy (GtkObject *object); static void open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *icalcomp, guint32 flags); -static GdkAtom clipboard_atom = GDK_NONE; /* Property IDs */ enum props { @@ -99,6 +98,17 @@ static guint e_calendar_view_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (ECalendarView, e_calendar_view, GTK_TYPE_TABLE) +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); + static void e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { @@ -158,6 +168,7 @@ e_calendar_view_class_init (ECalendarViewClass *klass) klass->get_visible_time_range = NULL; klass->update_query = NULL; klass->open_event = e_calendar_view_open_event; + klass->paste_text = NULL; g_object_class_install_property (gobject_class, PROP_MODEL, g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, @@ -227,11 +238,6 @@ e_calendar_view_class_init (ECalendarViewClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); - - /* * Key bindings */ @@ -663,6 +669,34 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view) g_list_free (selected); } +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; + } +} + void e_calendar_view_copy_clipboard (ECalendarView *cal_view) { @@ -671,6 +705,7 @@ e_calendar_view_copy_clipboard (ECalendarView *cal_view) icalcomponent *vcal_comp; icalcomponent *new_icalcomp; ECalendarViewEvent *event; + GtkClipboard *clipboard; g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); @@ -704,19 +739,25 @@ e_calendar_view_copy_clipboard (ECalendarView *cal_view) } /* copy the VCALENDAR to the clipboard */ + clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_view), GDK_SELECTION_CLIPBOARD); comp_str = icalcomponent_as_ical_string (vcal_comp); - gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_view), clipboard_atom), - (const gchar *) comp_str, - strlen (comp_str)); + + if (!gtk_clipboard_set_with_data (clipboard, target_types, n_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, n_target_types - 1); + } /* free memory */ icalcomponent_free (vcal_comp); - g_free (comp_str); g_list_free (selected); } static void -clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarView *cal_view) +clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text) { icalcomponent *icalcomp; icalcomponent_kind kind; @@ -796,13 +837,48 @@ clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarView #endif } +static void +e_calendar_view_paste_text (ECalendarView *cal_view) +{ + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + + if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->paste_text) + E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->paste_text (cal_view); +} + +static void +clipboard_paste_received_cb (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + gpointer data) +{ + 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); +} + void e_calendar_view_paste_clipboard (ECalendarView *cal_view) { + GtkClipboard *clipboard; + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_view), clipboard_atom), - (GtkClipboardTextReceivedFunc) clipboard_get_text_cb, cal_view); + clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_view), GDK_SELECTION_CLIPBOARD); + g_object_ref (cal_view); + + gtk_clipboard_request_contents (clipboard, + gdk_atom_intern (target_types[TARGET_TYPE_VCALENDAR].target, FALSE), + clipboard_paste_received_cb, cal_view); } static void |