From 425d49ebe1a6243d41984a87268353170e728187 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 11 Nov 2009 20:40:24 -0500 Subject: 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 ++++---------- 6 files changed, 489 insertions(+), 239 deletions(-) create mode 100644 calendar/gui/e-cal-selection.c create mode 100644 calendar/gui/e-cal-selection.h (limited to 'calendar') diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index dd1357c6c5..fc9c91047a 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 0000000000..27da752c98 --- /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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-selection.h" + +#include + +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 0000000000..c79f1d608d --- /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 + * + * + * 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 + +/* 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 483c032438..3903c58888 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 805ec939f8..0ea84e1268 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) @@ -660,34 +652,6 @@ 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; - } -} - static void add_related_timezones (icalcomponent *des_icalcomp, icalcomponent *src_icalcomp, ECal *client) { @@ -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 9a736801b6..c111bd668d 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. */ -- cgit v1.2.3