[dia] Improve clipboard handling for OS X



commit c235547ad70d33de05cafd85f332f8160269d9db
Author: Hans Breuer <hans breuer org>
Date:   Sun Sep 14 13:15:14 2014 +0200

    Improve clipboard handling for OS X
    
     - Use gtk_clipboard_wait_for_targets() and select based on that to paste
       either SVG or fallback to image
     - Add TIFF and PNG to the supported formats
     - Use the global clipboard as with win32. Only X11 uses the "selection"
       keyboard
     - try to treat UTF8_STRING as SVG (works with iDraw/Copy/SVG)

 app/commands.c |   99 +++++++++++++++++++++++++++++++-------------------------
 1 files changed, 55 insertions(+), 44 deletions(-)
---
diff --git a/app/commands.c b/app/commands.c
index 99f2994..d9f933f 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -311,9 +311,9 @@ received_clipboard_image_handler(GtkClipboard *clipboard,
 static void
 received_clipboard_content_handler (GtkClipboard     *clipboard,
                                    GtkSelectionData *selection_data,
-                                   gpointer          data)
+                                   gpointer          user_data)
 {
-  DDisplay *ddisp = (DDisplay *)data;
+  DDisplay *ddisp = (DDisplay *)user_data;
   GdkAtom type_atom;
   gchar *type_name;
   gint len;
@@ -322,44 +322,39 @@ received_clipboard_content_handler (GtkClipboard     *clipboard,
     const guchar *data = gtk_selection_data_get_data (selection_data);
     type_atom = gtk_selection_data_get_data_type (selection_data);
     type_name = gdk_atom_name (type_atom);
-    if (type_name && strcmp (type_name, "image/svg+xml") == 0) {
+    if (type_name && (   strcmp (type_name, "image/svg") == 0
+                     || strcmp (type_name, "image/svg+xml") == 0
+                     || strcmp (type_name, "UTF8_STRING") == 0)) {
       DiaImportFilter *ifilter = filter_import_get_by_name ("dia-svg");
       DiaContext *ctx = dia_context_new (_("Clipboard Paste"));
 
       if (ifilter->import_mem_func) {
-        Change *change = undo_import_change_setup (ddisp->diagram);
+       Change *change = undo_import_change_setup (ddisp->diagram);
 
        if (!ifilter->import_mem_func (data, len, DIA_DIAGRAM_DATA (ddisp->diagram),
                                      ctx, ifilter->user_data)) {
          /* might become more right some day ;) */
-         message_error (_("No clipboard handler for '%s'"), type_name);
+         dia_context_add_message (ctx, _("Failed to import '%s' as SVG."), type_name);
+         dia_context_release (ctx);
        }
        if (undo_import_change_done (ddisp->diagram, change)) {
-          undo_set_transactionpoint(ddisp->diagram->undo);
-          diagram_modified(ddisp->diagram);
-          diagram_flush(ddisp->diagram);
+         undo_set_transactionpoint(ddisp->diagram->undo);
+         diagram_modified(ddisp->diagram);
+         diagram_flush(ddisp->diagram);
        }
       }
+    } else {
+      /* fallback to pixbuf loader */
+      GdkPixbuf *pixbuf = gtk_selection_data_get_pixbuf (selection_data);
+      if (pixbuf) {
+       received_clipboard_image_handler (clipboard, pixbuf, ddisp);
+       g_object_unref (pixbuf);
+      } else {
+        message_error (_("Paste failed: %s"), type_name);
+      }
     }
     dia_log_message ("Content is %s (size=%d)", type_name, len);
     g_free (type_name);
-
-  }
-}
-
-static void
-_targets_receive (GtkClipboard *clipboard,
-                 GdkAtom      *atom,
-                 gint          n_atoms,
-                 gpointer      data)
-{
-  gint i;
-  gchar *aname;
-
-  for (i = 0; i < n_atoms; ++i) {
-    aname = gdk_atom_name (atom[i]);
-    dia_log_message ("clipboard-targets %d: %s", i, aname);
-    g_free (aname);
   }
 }
 
@@ -368,21 +363,33 @@ edit_paste_image_callback (GtkAction *action)
 {
   GtkClipboard *clipboard = gtk_clipboard_get(GDK_NONE);
   DDisplay *ddisp;
-  GdkAtom  svg_atom = gdk_atom_intern_static_string ("image/svg+xml");
+  GdkAtom *targets;
+  gint n_targets;
+  gboolean done = FALSE;
 
   ddisp = ddisplay_active();
   if (!ddisp) return;
 
-  gtk_clipboard_request_targets (clipboard, _targets_receive, ddisp);
-  /* a second request call is asynchronuously to the above. I've found no reliable
-   * way to make the latter use information generted by the former
-   */
-  if (gtk_clipboard_wait_for_contents (clipboard, svg_atom))
-    gtk_clipboard_request_contents (clipboard, svg_atom,
-                                   received_clipboard_content_handler, ddisp);
-  else
-    gtk_clipboard_request_image (clipboard,
-                                received_clipboard_image_handler, ddisp);
+  if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) {
+    int i;
+    for (i = 0; i < n_targets; ++i) {
+      gchar *aname = gdk_atom_name (targets[i]);
+      if (   strcmp (aname, "image/svg") == 0
+         || strcmp (aname, "image/svg+xml") == 0
+         || strcmp (aname, "UTF8_STRING") == 0) {
+       gtk_clipboard_request_contents (clipboard, targets[i],
+                                       received_clipboard_content_handler, ddisp);
+       done = TRUE;
+      }
+      dia_log_message ("clipboard-targets %d: %s", i, aname);
+      g_free (aname);
+      if (done)
+       break;
+    }
+    if (!done)
+      gtk_clipboard_request_image (clipboard, received_clipboard_image_handler, ddisp);
+    g_free (targets);
+  }
 }
 
 static PropDescription text_prop_singleton_desc[] = {
@@ -405,12 +412,13 @@ static GtkTargetEntry target_entries[] = {
   { "image/svg+xml", GTK_TARGET_OTHER_APP, 2 },
   { "image/png", GTK_TARGET_OTHER_APP, 3 },
   { "image/bmp", GTK_TARGET_OTHER_APP, 4 },
+  { "image/tiff", GTK_TARGET_OTHER_APP, 5 },
 #ifdef G_OS_WIN32
   /* this is not working on win32 either, maybe we need to register it with
    * CF_ENHMETAFILE in Gtk+? Change order? Direct use of SetClipboardData()?
    */
-  { "image/emf", GTK_TARGET_OTHER_APP, 5 },
-  { "image/wmf", GTK_TARGET_OTHER_APP, 6 },
+  { "image/emf", GTK_TARGET_OTHER_APP, 6 },
+  { "image/wmf", GTK_TARGET_OTHER_APP, 7 },
 #endif
 };
 
@@ -437,6 +445,9 @@ _clipboard_get_data_callback (GtkClipboard     *clipboard,
    * convert from png on demand ... */
   if (strcmp (ext, "bmp") == 0) {
     tmplate = g_strdup ("dia-cb-XXXXXX.png"); 
+  } else if (strcmp (ext, "tiff") == 0) {
+    /* pixbuf on OS X offers qtif and qif - both look like a mistake to me ;) */
+    tmplate = g_strdup ("dia-cb-XXXXXX.png");
   } else if (g_str_has_suffix (ext, "+xml")) {
     gchar *ext2 = g_strndup (ext, strlen (ext) - 4);
     tmplate = g_strdup_printf ("dia-cb-XXXXXX.%s", ext2);
@@ -466,7 +477,7 @@ _clipboard_get_data_callback (GtkClipboard     *clipboard,
      * Or even better: only use pixbuf transport when asked
      * for 'OS native bitmaps' BMP (win32), TIFF(osx), ...?
      */
-    if (strcmp (ext, "bmp") == 0 || strcmp (ext, "tif") == 0) {
+    if (strcmp (ext, "bmp") == 0 || strcmp (ext, "tiff") == 0) {
       GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(outfname, &error);
       if (pixbuf) {
        gtk_selection_data_set_pixbuf (selection_data, pixbuf);
@@ -537,7 +548,7 @@ edit_copy_callback (GtkAction *action)
      * Nowadays the notation of one system global clipboard is common
      * for many programs on Linux, too.
      */
-#ifdef G_OS_WIN32
+#ifndef GDK_WINDOWING_X11
     gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE),
                           prop->text_data, -1);
 #else
@@ -613,7 +624,7 @@ edit_paste_callback (GtkAction *action)
   ddisp = ddisplay_active();
   if (!ddisp) return;
   if (textedit_mode(ddisp)) {
-#ifdef G_OS_WIN32
+#ifndef GDK_WINDOWING_X11
     gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE), 
                               received_clipboard_text_handler, ddisp);
 #else
@@ -768,7 +779,7 @@ edit_copy_text_callback (GtkAction *action)
   /* GTK docs claim the selection clipboard is ignored on Win32.
    * The "clipboard" clipboard is mostly ignored in Unix
    */
-#ifdef G_OS_WIN32
+#ifndef GDK_WINDOWING_X11
   gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE),
                         prop->text_data, -1);
 #else
@@ -806,7 +817,7 @@ edit_cut_text_callback (GtkAction *action)
   /* GTK docs claim the selection clipboard is ignored on Win32.
    * The "clipboard" clipboard is mostly ignored in Unix
    */
-#ifdef G_OS_WIN32
+#ifndef GDK_WINDOWING_X11
   gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE),
                         prop->text_data, -1);
 #else
@@ -833,7 +844,7 @@ edit_paste_text_callback (GtkAction *action)
   ddisp = ddisplay_active();
   if (!ddisp) return;
 
-#ifdef G_OS_WIN32
+#ifndef GDK_WINDOWING_X11
   gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE), 
                             received_clipboard_text_handler, ddisp);
 #else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]