[gnumeric] Clipboard: fix image pasting.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Clipboard: fix image pasting.
- Date: Sat, 21 Apr 2018 18:42:30 +0000 (UTC)
commit ac9794de1e0a5fbc6c15f7e420cc17912184ea51
Author: Morten Welinder <terra gnome org>
Date: Sat Apr 21 14:41:45 2018 -0400
Clipboard: fix image pasting.
We didn't convert to the requested format. LO wasn't happy about that
and it's hard to blame it.
ChangeLog | 5 ++
NEWS | 1 +
src/gui-clipboard.c | 158 ++++++++++++++++++++++------------------------
src/sheet-object-image.c | 19 +++++-
4 files changed, 100 insertions(+), 83 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ee0bc35..cbd6c61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-04-21 Morten Welinder <terra gnome org>
+
+ * src/sheet-object-image.c (gnm_soi_write_image): If the format
+ doesn't match what is requested, convert.
+
2018-04-20 Morten Welinder <terra gnome org>
* src/ssconvert.c (merge_single): Avoid a
diff --git a/NEWS b/NEWS
index cb42ba8..7e0463b 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,7 @@ Morten:
* Fix paste to LibreOffice -- use Biff8. [#795280]
* Allow inter-process paste-special. [#346630]
* Fix ssconvert --merge-to problem with names. [#795408]
+ * Fix problem with image pasting.
--------------------------------------------------------------------------
Gnumeric 1.12.39
diff --git a/src/gui-clipboard.c b/src/gui-clipboard.c
index 66fb0f4..56cd855 100644
--- a/src/gui-clipboard.c
+++ b/src/gui-clipboard.c
@@ -128,7 +128,6 @@ typedef enum {
INFO_HTML,
INFO_OBJECT,
INFO_IMAGE,
- INFO_STRING
} AtomInfoType;
static GtkTargetList *generic_text_targets;
@@ -552,7 +551,7 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
}
}
- if (gnm_debug_flag ("clipboard-dump")) {
+ if (debug_clipboard_dump) {
g_file_set_contents ("paste-to-gnumeric.dat",
buffer, sel_len < 0 ? 0 : sel_len, NULL);
}
@@ -727,7 +726,7 @@ table_cellregion_write (GOCmdContext *ctx, GnmCellRegion *cr,
GnmPasteTarget pt;
GnmRange r;
- if (gnm_debug_flag ("clipboard-undump")) {
+ if (debug_clipboard_undump) {
gsize siz;
gchar *contents;
if (g_file_get_contents ("paste-from-gnumeric.dat", &contents,
@@ -775,11 +774,6 @@ table_cellregion_write (GOCmdContext *ctx, GnmCellRegion *cr,
gsf_off_t osize = gsf_output_size (output);
const guint8 *data = gsf_output_memory_get_bytes (omem);
- if (gnm_debug_flag ("clipboard-dump")) {
- g_file_set_contents ("paste-from-gnumeric.dat",
- data, osize, NULL);
- }
-
*size = osize;
if (*size == osize) {
ret = g_memdup (data, *size);
@@ -831,9 +825,9 @@ image_write (GnmCellRegion *cr, gchar const *mime_type, int *size)
format = go_mime_to_image_format (mime_type);
if (!format) {
g_warning ("No image format for %s\n", mime_type);
- g_free (format);
return ret;
}
+
output = gsf_output_memory_new ();
omem = GSF_OUTPUT_MEMORY (output);
sheet_object_write_image (so, format, 150.0, output, NULL);
@@ -896,6 +890,29 @@ object_write (GnmCellRegion *cr, gchar const *mime_type, int *size)
return ret;
}
+static void
+paste_from_gnumeric (GtkSelectionData *selection_data, GdkAtom target,
+ gconstpointer data, gssize size)
+{
+ if (size < 0)
+ size = 0;
+
+ if (debug_clipboard_dump) {
+ g_file_set_contents ("paste-from-gnumeric.dat",
+ data, size, NULL);
+ }
+
+ if (debug_clipboard) {
+ char *target_name = gdk_atom_name (target);
+ g_printerr ("clipboard %s of %d bytes\n",
+ target_name, (int)size);
+ g_free (target_name);
+ }
+
+ gtk_selection_data_set (selection_data, target, 8, data, size);
+}
+
+
/*
* x_clipboard_get_cb
*
@@ -943,74 +960,44 @@ x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
if (output) {
gsf_off_t size = gsf_output_size (GSF_OUTPUT (output));
gconstpointer data = gsf_output_memory_get_bytes (output);
- if (gnm_debug_flag ("clipboard-dump")) {
- g_file_set_contents ("paste-from-gnumeric.dat",
- data, size, NULL);
- }
- if (debug_clipboard)
- g_printerr ("clipboard .gnumeric of %d bytes\n",
- (int)size);
- gtk_selection_data_set
- (selection_data, target, 8,
- data,
- size);
+
+ paste_from_gnumeric (selection_data, target,
+ data, size);
g_object_unref (output);
to_gnumeric = TRUE;
}
} else if (info == INFO_HTML) {
const char *saver_id = "Gnumeric_html:xhtml_range";
- int buffer_size;
+ int size;
guchar *buffer = table_cellregion_write (ctx, clipboard,
saver_id,
- &buffer_size);
- if (debug_clipboard)
- g_message ("clipboard html of %d bytes",
- buffer_size);
- gtk_selection_data_set (selection_data,
- target, 8,
- buffer, buffer_size);
+ &size);
+ paste_from_gnumeric (selection_data, target, buffer, size);
g_free (buffer);
} else if (info == INFO_EXCEL) {
const char *saver_id = "Gnumeric_Excel:excel_biff8";
- int buffer_size;
+ int size;
guchar *buffer = table_cellregion_write (ctx, clipboard,
saver_id,
- &buffer_size);
- if (debug_clipboard)
- g_message ("clipboard biff8 of %d bytes",
- buffer_size);
- gtk_selection_data_set (selection_data,
- target, 8,
- buffer, buffer_size);
+ &size);
+ paste_from_gnumeric (selection_data, target, buffer, size);
g_free (buffer);
} else if (target == atoms[ATOM_GOFFICE_GRAPH] ||
g_slist_find_custom (go_components_get_mime_types (), target_name, (GCompareFunc) strcmp)
!= NULL) {
- int buffer_size;
- guchar *buffer = object_write (clipboard, target_name,
- &buffer_size);
- if (debug_clipboard)
- g_message ("clipboard graph of %d bytes",
- buffer_size);
- gtk_selection_data_set (selection_data,
- target, 8,
- buffer, buffer_size);
+ int size;
+ guchar *buffer = object_write (clipboard, target_name, &size);
+ paste_from_gnumeric (selection_data, target, buffer, size);
g_free (buffer);
} else if (info == INFO_IMAGE) {
- int buffer_size;
- guchar *buffer = image_write (clipboard, target_name,
- &buffer_size);
- if (debug_clipboard)
- g_message ("clipboard image of %d bytes",
- buffer_size);
- gtk_selection_data_set (selection_data,
- target, 8,
- buffer, buffer_size);
+ int size;
+ guchar *buffer = image_write (clipboard, target_name, &size);
+ paste_from_gnumeric (selection_data, target, buffer, size);
g_free (buffer);
} else if (target == atoms[ATOM_SAVE_TARGETS]) {
/* We implicitly registered this when calling
* gtk_clipboard_set_can_store. We're supposed to
* ignore it. */
- } else if (info == INFO_STRING) {
+ } else if (info == INFO_GENERIC_TEXT) {
Workbook *wb = clipboard->origin_sheet->workbook;
GString *res = cellregion_to_string (clipboard,
TRUE, workbook_date_conv (wb));
@@ -1101,9 +1088,22 @@ gnm_x_request_clipboard (WBCGtk *wbcg, GnmPasteTarget const *pt)
x_targets_received, ctxt);
}
-/* Restrict the set of formats offered to clipboard manager. */
-/* We include bmp in the whitelist because that's the only image format
- * we share with OOo over clipboard (!) */
+static void
+cb_clear_target_entry (gpointer te_)
+{
+ GtkTargetEntry *te = te_;
+ g_free (te->target);
+}
+
+static void
+add_target (GArray *targets, const char *target, int flags, AtomInfoType info)
+{
+ GtkTargetEntry t;
+ t.target = g_strdup (target);
+ t.flags = flags;
+ t.info = info;
+ g_array_append_val (targets, t);
+}
static gboolean
is_clipman_target (const char *target)
@@ -1117,20 +1117,22 @@ is_clipman_target (const char *target)
g_str_equal (target, atom_names[ATOM_IMAGE_XWMF]) ||
g_str_equal (target, atom_names[ATOM_IMAGE_XEMF]) ||
g_str_equal (target, atom_names[ATOM_IMAGE_PNG]) ||
- g_str_equal (target, atom_names[ATOM_IMAGE_JPEG]) ||
- g_str_equal (target, atom_names[ATOM_IMAGE_BMP]));
+ g_str_equal (target, atom_names[ATOM_IMAGE_JPEG]));
}
+/* Restrict the set of formats offered to clipboard manager. */
static void
set_clipman_targets (GdkDisplay *disp, GArray *targets)
{
GArray *allowed = g_array_new (FALSE, FALSE, sizeof (GtkTargetEntry));
unsigned ui;
+ g_array_set_clear_func (allowed, cb_clear_target_entry);
+
for (ui = 0; ui < targets->len; ui++) {
GtkTargetEntry *te = &g_array_index (targets, GtkTargetEntry, ui);
if (is_clipman_target (te->target))
- g_array_append_val (allowed, *te);
+ add_target (allowed, te->target, te->flags, te->info);
}
gtk_clipboard_set_can_store
@@ -1143,27 +1145,17 @@ set_clipman_targets (GdkDisplay *disp, GArray *targets)
}
static void
-add_target (GArray *targets, const char *target, int flags, AtomInfoType info)
-{
- GtkTargetEntry t;
- t.target = (char *)target;
- t.flags = flags;
- t.info = info;
- g_array_append_val (targets, t);
-}
-
-
-static void
add_target_list (GArray *targets, GtkTargetList *src, AtomInfoType info)
{
- int n;
+ int i, n;
GtkTargetEntry *entries = gtk_target_table_new_from_list (src, &n);
- unsigned ui = targets->len;
- g_array_append_vals (targets, entries, n);
- if (info != INFO_UNKNOWN) {
- for (; ui < targets->len; ui++)
- g_array_index (targets, GtkTargetEntry, ui).info = info;
+
+ for (i = 0; i < n; i++) {
+ GtkTargetEntry *te = entries + i;
+ add_target (targets, te->target, te->flags,
+ info == INFO_UNKNOWN ? te->info : info);
}
+
gtk_target_table_free (entries, n);
}
@@ -1177,6 +1169,8 @@ gnm_x_claim_clipboard (GdkDisplay *display)
GObject *app = gnm_app_get_app ();
gboolean no_cells = (!content) || (content->cols <= 0 || content->rows <= 0);
+ g_array_set_clear_func (targets, cb_clear_target_entry);
+
if (no_cells) {
GSList *ptr = content ? content->objects : NULL;
@@ -1199,9 +1193,9 @@ gnm_x_claim_clipboard (GdkDisplay *display)
#else
add_target (targets, atom_names[ATOM_TEXT_HTML], 0, INFO_HTML);
#endif
- add_target (targets, atom_names[ATOM_UTF8_STRING], 0, INFO_STRING);
- add_target (targets, atom_names[ATOM_COMPOUND_TEXT], 0, INFO_STRING);
- add_target (targets, atom_names[ATOM_STRING], 0, INFO_STRING);
+ add_target (targets, atom_names[ATOM_UTF8_STRING], 0, INFO_GENERIC_TEXT);
+ add_target (targets, atom_names[ATOM_COMPOUND_TEXT], 0, INFO_GENERIC_TEXT);
+ add_target (targets, atom_names[ATOM_STRING], 0, INFO_GENERIC_TEXT);
}
if (exportable) {
@@ -1329,7 +1323,7 @@ gui_clipboard_init (void)
atoms[ui] = gdk_atom_intern_static_string (atom_names[ui]);
generic_text_targets = gtk_target_list_new (NULL, 0);
- gtk_target_list_add_text_targets (generic_text_targets, INFO_STRING);
+ gtk_target_list_add_text_targets (generic_text_targets, INFO_GENERIC_TEXT);
image_targets = gtk_target_list_new (NULL, 0);
gtk_target_list_add_image_targets (image_targets, 0, FALSE);
diff --git a/src/sheet-object-image.c b/src/sheet-object-image.c
index 8e0ff3a..a9f5312 100644
--- a/src/sheet-object-image.c
+++ b/src/sheet-object-image.c
@@ -263,15 +263,32 @@ gnm_soi_write_image (SheetObject const *so, char const *format,
gboolean res;
gsize length;
guint8 const *data;
+ GOImage *image = NULL;
+ GOImageFormatInfo const *src_info;
+ GOImageFormatInfo const *dst_info;
g_return_if_fail (soi->image != NULL);
- data = go_image_get_data (soi->image, &length);
+ src_info = go_image_get_info (soi->image);
+ dst_info = format
+ ? go_image_get_format_info (go_image_get_format_from_name (format))
+ : src_info;
+
+ if (src_info != dst_info) {
+ GdkPixbuf *pixbuf = go_image_get_pixbuf (soi->image);
+ image = go_pixbuf_new_from_pixbuf (pixbuf);
+ g_object_set (image, "image-type", format, NULL);
+ g_object_unref (pixbuf);
+ }
+
+ data = go_image_get_data (image ? image : soi->image, &length);
res = gsf_output_write (output, length, data);
if (!res && err && *err == NULL)
*err = g_error_new (gsf_output_error_id (), 0,
_("Unknown failure while saving image"));
+
+ if (image) g_object_unref (image);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]