summaryrefslogtreecommitdiff
path: root/src/eom-clipboard-handler.c
diff options
context:
space:
mode:
authorinfirit <[email protected]>2014-07-26 12:15:01 +0200
committerinfirit <[email protected]>2014-07-26 12:48:21 +0200
commite4177ed4c0de5eaa4294c756a43e072f1373cb0f (patch)
treee220bf77c549f6a8579d9751c543de3e2a27aa62 /src/eom-clipboard-handler.c
parentc35741c224cdbb67e05229aaafaa96373e4e7947 (diff)
downloadeom-e4177ed4c0de5eaa4294c756a43e072f1373cb0f.tar.bz2
eom-e4177ed4c0de5eaa4294c756a43e072f1373cb0f.tar.xz
Allow handling multiple clipboard data formats from one menu entry
The new class "snapshots" the required data from the given EomImage and keeps it around for clipboard usage until the clipboard gets reset. Based on eog commit dcb56b03e9c9282138b9da94eddcedfc401ab750 From Felix Riemann <[email protected]>
Diffstat (limited to 'src/eom-clipboard-handler.c')
-rw-r--r--src/eom-clipboard-handler.c324
1 files changed, 324 insertions, 0 deletions
diff --git a/src/eom-clipboard-handler.c b/src/eom-clipboard-handler.c
new file mode 100644
index 0000000..6d7cd4f
--- /dev/null
+++ b/src/eom-clipboard-handler.c
@@ -0,0 +1,324 @@
+/*
+ * eom-clipboard-handler.c
+ * This file is part of eom
+ *
+ * Author: Felix Riemann <[email protected]>
+ *
+ * Copyright (C) 2010 GNOME Foundation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
+#include "eom-clipboard-handler.h"
+
+enum {
+ PROP_0,
+ PROP_PIXBUF,
+ PROP_URI
+};
+
+enum {
+ TARGET_PIXBUF,
+ TARGET_TEXT,
+ TARGET_URI
+};
+
+struct _EomClipboardHandlerPrivate {
+ GdkPixbuf *pixbuf;
+ gchar *uri;
+};
+
+#define EOM_CLIPBOARD_HANDLER_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EOM_TYPE_CLIPBOARD_HANDLER, EomClipboardHandlerPrivate))
+
+G_DEFINE_TYPE(EomClipboardHandler, eom_clipboard_handler, G_TYPE_INITIALLY_UNOWNED)
+
+static GdkPixbuf*
+eom_clipboard_handler_get_pixbuf (EomClipboardHandler *handler)
+{
+ g_return_val_if_fail (EOM_IS_CLIPBOARD_HANDLER (handler), NULL);
+
+ return handler->priv->pixbuf;
+}
+
+static const gchar *
+eom_clipboard_handler_get_uri (EomClipboardHandler *handler)
+{
+ g_return_val_if_fail (EOM_IS_CLIPBOARD_HANDLER (handler), NULL);
+
+ return handler->priv->uri;
+}
+
+static void
+eom_clipboard_handler_set_pixbuf (EomClipboardHandler *handler, GdkPixbuf *pixbuf)
+{
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (handler));
+ g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
+
+ if (handler->priv->pixbuf == pixbuf)
+ return;
+
+ if (handler->priv->pixbuf)
+ g_object_unref (handler->priv->pixbuf);
+
+ handler->priv->pixbuf = g_object_ref (pixbuf);
+
+ g_object_notify (G_OBJECT (handler), "pixbuf");
+}
+
+static void
+eom_clipboard_handler_set_uri (EomClipboardHandler *handler, const gchar *uri)
+{
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (handler));
+
+ if (handler->priv->uri != NULL)
+ g_free (handler->priv->uri);
+
+ handler->priv->uri = g_strdup (uri);
+ g_object_notify (G_OBJECT (handler), "uri");
+}
+
+static void
+eom_clipboard_handler_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ EomClipboardHandler *handler;
+
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (object));
+
+ handler = EOM_CLIPBOARD_HANDLER (object);
+
+ switch (property_id) {
+ case PROP_PIXBUF:
+ g_value_set_object (value,
+ eom_clipboard_handler_get_pixbuf (handler));
+ break;
+ case PROP_URI:
+ g_value_set_string (value,
+ eom_clipboard_handler_get_uri (handler));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+eom_clipboard_handler_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ EomClipboardHandler *handler;
+
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (object));
+
+ handler = EOM_CLIPBOARD_HANDLER (object);
+
+ switch (property_id) {
+ case PROP_PIXBUF:
+ {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = g_value_get_object (value);
+ eom_clipboard_handler_set_pixbuf (handler, pixbuf);
+ break;
+ }
+ case PROP_URI:
+ {
+ const gchar *uri;
+
+ uri = g_value_get_string (value);
+ eom_clipboard_handler_set_uri (handler, uri);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+
+}
+
+static void
+eom_clipboard_handler_dispose (GObject *obj)
+{
+ EomClipboardHandlerPrivate *priv;
+
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (obj));
+
+ priv = EOM_CLIPBOARD_HANDLER (obj)->priv;
+
+ if (priv->pixbuf != NULL) {
+ g_object_unref (priv->pixbuf);
+ priv->pixbuf = NULL;
+ }
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ G_OBJECT_CLASS (eom_clipboard_handler_parent_class)->dispose (obj);
+}
+
+static void
+eom_clipboard_handler_init (EomClipboardHandler *handler)
+{
+ handler->priv = EOM_CLIPBOARD_HANDLER_GET_PRIVATE (handler);
+}
+
+static void
+eom_clipboard_handler_class_init (EomClipboardHandlerClass *klass)
+{
+ GObjectClass *g_obj_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (EomClipboardHandlerPrivate));
+
+ g_obj_class->get_property = eom_clipboard_handler_get_property;
+ g_obj_class->set_property = eom_clipboard_handler_set_property;
+ g_obj_class->dispose = eom_clipboard_handler_dispose;
+
+ g_object_class_install_property (
+ g_obj_class, PROP_PIXBUF,
+ g_param_spec_object ("pixbuf", NULL, NULL, GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ g_obj_class, PROP_URI,
+ g_param_spec_string ("uri", NULL, NULL, NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+EomClipboardHandler*
+eom_clipboard_handler_new (EomImage *img)
+{
+ GObject *obj;
+ GFile *file;
+ GdkPixbuf *pbuf;
+ gchar *uri;
+
+ g_object_ref (img);
+ pbuf = eom_image_get_pixbuf (img);
+ file = eom_image_get_file (img);
+ uri = g_file_get_uri (file);
+ obj = g_object_new (EOM_TYPE_CLIPBOARD_HANDLER,
+ "pixbuf", pbuf,
+ "uri", uri,
+ NULL);
+ g_free (uri);
+ g_object_unref (file);
+ g_object_unref (pbuf);
+ g_object_unref (img);
+
+ return EOM_CLIPBOARD_HANDLER (obj);
+
+}
+
+static void
+eom_clipboard_handler_get_func (GtkClipboard *clipboard,
+ GtkSelectionData *selection,
+ guint info, gpointer owner)
+{
+ EomClipboardHandler *handler;
+
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (owner));
+
+ handler = EOM_CLIPBOARD_HANDLER (owner);
+
+ switch (info) {
+ case TARGET_PIXBUF:
+ {
+ GdkPixbuf *pixbuf = eom_clipboard_handler_get_pixbuf (handler);
+ g_object_ref (pixbuf);
+ gtk_selection_data_set_pixbuf (selection, pixbuf);
+ g_object_unref (pixbuf);
+ break;
+ }
+ case TARGET_TEXT:
+ {
+ gtk_selection_data_set_text (selection,
+ eom_clipboard_handler_get_uri (handler),
+ -1);
+ break;
+ }
+ case TARGET_URI:
+ {
+ gchar *uris[2];
+ uris[0] = g_strdup (eom_clipboard_handler_get_uri (handler));
+ uris[1] = NULL;
+
+ gtk_selection_data_set_uris (selection, uris);
+ g_free (uris[0]);
+ break;
+ }
+ default:
+ g_return_if_reached ();
+ }
+
+}
+
+static void
+eom_clipboard_handler_clear_func (GtkClipboard *clipboard, gpointer owner)
+{
+ g_return_if_fail (EOM_IS_CLIPBOARD_HANDLER (owner));
+
+ g_object_unref (G_OBJECT (owner));
+}
+
+void
+eom_clipboard_handler_copy_to_clipboard (EomClipboardHandler *handler,
+ GtkClipboard *clipboard)
+{
+ GtkTargetList *tlist;
+ GtkTargetEntry *targets;
+ gint n_targets = 0;
+ gboolean set = FALSE;
+
+ tlist = gtk_target_list_new (NULL, 0);
+
+ if (handler->priv->pixbuf != NULL)
+ gtk_target_list_add_image_targets (tlist, TARGET_PIXBUF, TRUE);
+
+ if (handler->priv->uri != NULL) {
+ gtk_target_list_add_text_targets (tlist, TARGET_TEXT);
+ gtk_target_list_add_uri_targets (tlist, TARGET_URI);
+ }
+
+ targets = gtk_target_table_new_from_list (tlist, &n_targets);
+
+ // We need to take ownership here if nobody else did
+ g_object_ref_sink (handler);
+
+ if (n_targets > 0) {
+ set = gtk_clipboard_set_with_owner (clipboard,
+ targets, n_targets,
+ eom_clipboard_handler_get_func,
+ eom_clipboard_handler_clear_func,
+ G_OBJECT (handler));
+
+ }
+
+ if (!set) {
+ gtk_clipboard_clear (clipboard);
+ g_object_unref (handler);
+ }
+
+ gtk_target_table_free (targets, n_targets);
+ gtk_target_list_unref (tlist);
+}