diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2009-11-12 12:52:08 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2009-11-12 23:44:52 +0800 |
commit | c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d (patch) | |
tree | 4cbdb439735c9a1406e9294a152996e7c10cf49c /e-util | |
parent | 7a2a0d05a9ba46c1d6c6f43f1a2d00c0ad93479a (diff) | |
download | gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar.gz gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar.zst gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.zip |
Simplify clipboard handling in addressbook.
Diffstat (limited to 'e-util')
-rw-r--r-- | e-util/Makefile.am | 6 | ||||
-rw-r--r-- | e-util/e-selection.c | 536 | ||||
-rw-r--r-- | e-util/e-selection.h | 96 |
3 files changed, 636 insertions, 2 deletions
diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 688c7e73ec..3014458f28 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -15,6 +15,7 @@ eutilinclude_HEADERS = \ e-alert-activity.h \ e-bconf-map.h \ e-binding.h \ + e-bit-array.h \ e-categories-config.h \ e-charset.h \ e-config.h \ @@ -38,10 +39,10 @@ eutilinclude_HEADERS = \ e-plugin.h \ e-plugin-ui.h \ e-profile-event.h \ + e-selection.h \ e-signature.h \ e-signature-list.h \ e-signature-utils.h \ - e-bit-array.h \ e-sorter.h \ e-sorter-array.h \ e-text-event-processor-emacs-like.h \ @@ -88,6 +89,7 @@ libeutil_la_SOURCES = \ e-alert-activity.c \ e-bconf-map.c \ e-binding.c \ + e-bit-array.c \ e-categories-config.c \ e-charset.c \ e-config.c \ @@ -111,10 +113,10 @@ libeutil_la_SOURCES = \ e-plugin.c \ e-print.c \ e-profile-event.c \ + e-selection.c \ e-signature.c \ e-signature-list.c \ e-signature-utils.c \ - e-bit-array.c \ e-sorter.c \ e-sorter-array.c \ e-text-event-processor-emacs-like.c \ diff --git a/e-util/e-selection.c b/e-util/e-selection.c new file mode 100644 index 0000000000..8d2efff764 --- /dev/null +++ b/e-util/e-selection.c @@ -0,0 +1,536 @@ +/* + * e-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-selection.h" + +#include <string.h> + +typedef struct _RequestTextInfo RequestTextInfo; +typedef struct _WaitForDataResults WaitForDataResults; + +struct _RequestTextInfo { + GtkClipboardTextReceivedFunc callback; + gpointer user_data; +}; + +struct _WaitForDataResults { + GMainLoop *loop; + gpointer data; +}; + +enum { + ATOM_CALENDAR, + ATOM_X_VCALENDAR, + NUM_CALENDAR_ATOMS +}; + +enum { + ATOM_DIRECTORY, + ATOM_X_VCARD, + NUM_DIRECTORY_ATOMS +}; + +static GdkAtom calendar_atoms[NUM_CALENDAR_ATOMS]; +static GdkAtom directory_atoms[NUM_DIRECTORY_ATOMS]; + +static void +init_atoms (void) +{ + static gboolean initialized = FALSE; + + if (initialized) + return; + + /* Calendar Atoms */ + + calendar_atoms[ATOM_CALENDAR] = + gdk_atom_intern_static_string ("text/calendar"); + + calendar_atoms[ATOM_X_VCALENDAR] = + gdk_atom_intern_static_string ("text/x-vcalendar"); + + /* Directory Atoms */ + + directory_atoms[ATOM_DIRECTORY] = + gdk_atom_intern_static_string ("text/directory"); + + directory_atoms[ATOM_X_VCARD] = + gdk_atom_intern_static_string ("text/x-vcard"); + + initialized = TRUE; +} + +static void +clipboard_wait_for_text_cb (GtkClipboard *clipboard, + const gchar *source, + WaitForDataResults *results) +{ + results->data = g_strdup (source); + g_main_loop_quit (results->loop); +} + +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); +} + +void +e_target_list_add_directory_targets (GtkTargetList *list, + guint info) +{ + gint ii; + + g_return_if_fail (list != NULL); + + init_atoms (); + + for (ii = 0; ii < NUM_DIRECTORY_ATOMS; ii++) + gtk_target_list_add (list, directory_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; +} + +gboolean +e_selection_data_set_directory (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 directory atoms are treated the same. */ + for (ii = 0; ii < NUM_DIRECTORY_ATOMS; ii++) { + if (atom == directory_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; +} + +gchar * +e_selection_data_get_directory (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 directory atoms are treated the same. */ + for (ii = 0; ii < NUM_DIRECTORY_ATOMS; ii++) + if (data_type == directory_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_selection_data_targets_include_directory (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_directory (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; +} + +gboolean +e_targets_include_directory (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_DIRECTORY_ATOMS; jj++) + if (targets[ii] == directory_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_get_directory (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + guint info, + gchar *source) +{ + e_selection_data_set_directory (selection_data, source, -1); +} + +static void +clipboard_clear_directory (GtkClipboard *clipboard, + gchar *source) +{ + g_free (source); +} + +void +e_clipboard_set_directory (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_directory_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_directory, + (GtkClipboardClearFunc) clipboard_clear_directory, + 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, + RequestTextInfo *info) +{ + gchar *source; + + source = e_selection_data_get_calendar (selection_data); + info->callback (clipboard, source, info->user_data); + g_free (source); + + g_slice_free (RequestTextInfo, info); +} + +void +e_clipboard_request_calendar (GtkClipboard *clipboard, + GtkClipboardTextReceivedFunc callback, + gpointer user_data) +{ + RequestTextInfo *info; + + g_return_if_fail (clipboard != NULL); + g_return_if_fail (callback != NULL); + + info = g_slice_new (RequestTextInfo); + 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_request_directory_cb (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + RequestTextInfo *info) +{ + gchar *source; + + source = e_selection_data_get_directory (selection_data); + info->callback (clipboard, source, info->user_data); + g_free (source); + + g_slice_free (RequestTextInfo, info); +} + +void +e_clipboard_request_directory (GtkClipboard *clipboard, + GtkClipboardTextReceivedFunc callback, + gpointer user_data) +{ + RequestTextInfo *info; + + g_return_if_fail (clipboard != NULL); + g_return_if_fail (callback != NULL); + + info = g_slice_new (RequestTextInfo); + info->callback = callback; + info->user_data = user_data; + + gtk_clipboard_request_contents ( + clipboard, directory_atoms[ATOM_DIRECTORY], + (GtkClipboardReceivedFunc) + clipboard_request_directory_cb, info); +} + +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_text_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; +} + +gchar * +e_clipboard_wait_for_directory (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_directory ( + clipboard, (GtkClipboardTextReceivedFunc) + clipboard_wait_for_text_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; +} + +gboolean +e_clipboard_wait_is_directory_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_directory (targets, n_targets); + g_free (targets); + } + + return result; +} diff --git a/e-util/e-selection.h b/e-util/e-selection.h new file mode 100644 index 0000000000..b0b2d1f3b6 --- /dev/null +++ b/e-util/e-selection.h @@ -0,0 +1,96 @@ +/* + * 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-selection + * @short_description: selection and clipboard utilities + * @include: e-util/e-selection.h + **/ + +#ifndef E_SELECTION_H +#define E_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); +void e_target_list_add_directory_targets + (GtkTargetList *list, + guint info); +gboolean e_selection_data_set_calendar + (GtkSelectionData *selection_data, + const gchar *source, + gint length); +gboolean e_selection_data_set_directory + (GtkSelectionData *selection_data, + const gchar *source, + gint length); +gchar * e_selection_data_get_calendar + (GtkSelectionData *selection_data); +gchar * e_selection_data_get_directory + (GtkSelectionData *selection_data); +gboolean e_selection_data_targets_include_calendar + (GtkSelectionData *selection_data); +gboolean e_selection_data_targets_include_directory + (GtkSelectionData *selection_data); +gboolean e_targets_include_calendar + (GdkAtom *targets, + gint n_targets); +gboolean e_targets_include_directory + (GdkAtom *targets, + gint n_targets); + +/* Clipboard Functions */ + +void e_clipboard_set_calendar(GtkClipboard *clipboard, + const gchar *source, + gint length); +void e_clipboard_set_directory + (GtkClipboard *clipboard, + const gchar *source, + gint length); +void e_clipboard_request_calendar + (GtkClipboard *clipboard, + GtkClipboardTextReceivedFunc callback, + gpointer user_data); +void e_clipboard_request_directory + (GtkClipboard *clipboard, + GtkClipboardTextReceivedFunc callback, + gpointer user_data); +gchar * e_clipboard_wait_for_calendar + (GtkClipboard *clipboard); +gchar * e_clipboard_wait_for_directory + (GtkClipboard *clipboard); +gboolean e_clipboard_wait_is_calendar_available + (GtkClipboard *clipboard); +gboolean e_clipboard_wait_is_directory_available + (GtkClipboard *clipboard); + +G_END_DECLS + +#endif /* E_SELECTION_H */ |