aboutsummaryrefslogtreecommitdiffstats
path: root/e-util
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-11-12 12:52:08 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-11-12 23:44:52 +0800
commitc12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d (patch)
tree4cbdb439735c9a1406e9294a152996e7c10cf49c /e-util
parent7a2a0d05a9ba46c1d6c6f43f1a2d00c0ad93479a (diff)
downloadgsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar
gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar.gz
gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar.bz2
gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar.lz
gsoc2013-evolution-c12e485e47f5ac99f0ddd7f7e90b9ab28b077c3d.tar.xz
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.am6
-rw-r--r--e-util/e-selection.c536
-rw-r--r--e-util/e-selection.h96
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 */