summaryrefslogtreecommitdiff
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
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]>
-rw-r--r--src/Makefile.am2
-rw-r--r--src/eom-clipboard-handler.c324
-rw-r--r--src/eom-clipboard-handler.h63
-rw-r--r--src/eom-window.c11
4 files changed, 395 insertions, 5 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8d9e15f..91002f9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,7 @@ NOINST_H_FILES = \
eom-plugin-engine.h \
uta.h \
eom-close-confirmation-dialog.h \
+ eom-clipboard-handler.h \
zoom.h
if ENABLE_PYTHON
@@ -107,6 +108,7 @@ libeom_la_SOURCES = \
eom-plugin.c \
eom-plugin-manager.c \
eom-plugin-engine.c \
+ eom-clipboard-handler.c \
uta.c \
zoom.c \
$(BUILT_SOURCES) \
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);
+}
diff --git a/src/eom-clipboard-handler.h b/src/eom-clipboard-handler.h
new file mode 100644
index 0000000..8bb52de
--- /dev/null
+++ b/src/eom-clipboard-handler.h
@@ -0,0 +1,63 @@
+/*
+ * eom-clipboard-handler.h
+ * 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.
+ */
+
+#ifndef __EOM_CLIPBOARD_HANDLER_H__
+#define __EOM_CLIPBOARD_HANDLER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "eom-image.h"
+
+G_BEGIN_DECLS
+
+#define EOM_TYPE_CLIPBOARD_HANDLER (eom_clipboard_handler_get_type ())
+#define EOM_CLIPBOARD_HANDLER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EOM_TYPE_CLIPBOARD_HANDLER, EomClipboardHandler))
+#define EOM_CLIPBOARD_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EOM_TYPE_CLIPBOARD_HANDLER, EomClipboardHandlerClass))
+#define EOM_IS_CLIPBOARD_HANDLER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EOM_TYPE_CLIPBOARD_HANDLER))
+#define EOM_IS_CLIPBOARD_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EOM_TYPE_CLIPBOARD_HANDLER))
+#define EOM_CLIPBOARD_HANDLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EOM_TYPE_CLIPBOARD_HANDLER, EomClipboardHandlerClass))
+
+typedef struct _EomClipboardHandler EomClipboardHandler;
+typedef struct _EomClipboardHandlerClass EomClipboardHandlerClass;
+typedef struct _EomClipboardHandlerPrivate EomClipboardHandlerPrivate;
+
+struct _EomClipboardHandler {
+ GObject parent;
+
+ EomClipboardHandlerPrivate *priv;
+};
+
+struct _EomClipboardHandlerClass {
+ GObjectClass parent_klass;
+};
+
+GType eom_clipboard_handler_get_type (void) G_GNUC_CONST;
+
+EomClipboardHandler* eom_clipboard_handler_new (EomImage *img);
+
+void eom_clipboard_handler_copy_to_clipboard (EomClipboardHandler *handler,
+ GtkClipboard *clipboard);
+
+G_END_DECLS
+#endif /* __EOM_CLIPBOARD_HANDLER_H__ */
diff --git a/src/eom-window.c b/src/eom-window.c
index 5b4f59d..8be70e4 100644
--- a/src/eom-window.c
+++ b/src/eom-window.c
@@ -52,6 +52,7 @@
#include "eom-save-as-dialog-helper.h"
#include "eom-plugin-engine.h"
#include "eom-close-confirmation-dialog.h"
+#include "eom-clipboard-handler.h"
#include "eom-enum-types.h"
@@ -3546,10 +3547,10 @@ static void
eom_window_cmd_copy_image (GtkAction *action, gpointer user_data)
{
GtkClipboard *clipboard;
- GdkPixbuf *pix;
EomWindow *window;
EomWindowPrivate *priv;
EomImage *image;
+ EomClipboardHandler *cbhandler;
g_return_if_fail (EOM_IS_WINDOW (user_data));
@@ -3560,12 +3561,12 @@ eom_window_cmd_copy_image (GtkAction *action, gpointer user_data)
g_return_if_fail (EOM_IS_IMAGE (image));
- pix = eom_image_get_pixbuf (image);
-
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_image (clipboard, pix);
- g_object_unref (pix);
+ cbhandler = eom_clipboard_handler_new (image);
+ // cbhandler will self-destruct when it's not needed anymore
+ eom_clipboard_handler_copy_to_clipboard (cbhandler, clipboard);
+
}
static void