diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2009-11-12 09:40:24 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2009-11-12 09:41:46 +0800 |
commit | 425d49ebe1a6243d41984a87268353170e728187 (patch) | |
tree | c55b13c3702b9aa271e419e8c00c56d785363a47 /calendar/gui/e-cal-selection.c | |
parent | 623d0541ee69f1dfd37bd6e80d4afe15bba57c13 (diff) | |
download | gsoc2013-evolution-425d49ebe1a6243d41984a87268353170e728187.tar.gz gsoc2013-evolution-425d49ebe1a6243d41984a87268353170e728187.tar.zst gsoc2013-evolution-425d49ebe1a6243d41984a87268353170e728187.zip |
Simplify clipboard handling in calendar.
Diffstat (limited to 'calendar/gui/e-cal-selection.c')
-rw-r--r-- | calendar/gui/e-cal-selection.c | 323 |
1 files changed, 323 insertions, 0 deletions
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 <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); +} |