作図ソフト dia の改良版
Revision | c235547ad70d33de05cafd85f332f8160269d9db (tree) |
---|---|
Zeit | 2014-09-14 21:12:38 |
Autor | Hans Breuer <hans@breu...> |
Commiter | Hans Breuer |
Improve clipboard handling for OS X
@@ -311,9 +311,9 @@ received_clipboard_image_handler(GtkClipboard *clipboard, | ||
311 | 311 | static void |
312 | 312 | received_clipboard_content_handler (GtkClipboard *clipboard, |
313 | 313 | GtkSelectionData *selection_data, |
314 | - gpointer data) | |
314 | + gpointer user_data) | |
315 | 315 | { |
316 | - DDisplay *ddisp = (DDisplay *)data; | |
316 | + DDisplay *ddisp = (DDisplay *)user_data; | |
317 | 317 | GdkAtom type_atom; |
318 | 318 | gchar *type_name; |
319 | 319 | gint len; |
@@ -322,44 +322,39 @@ received_clipboard_content_handler (GtkClipboard *clipboard, | ||
322 | 322 | const guchar *data = gtk_selection_data_get_data (selection_data); |
323 | 323 | type_atom = gtk_selection_data_get_data_type (selection_data); |
324 | 324 | type_name = gdk_atom_name (type_atom); |
325 | - if (type_name && strcmp (type_name, "image/svg+xml") == 0) { | |
325 | + if (type_name && ( strcmp (type_name, "image/svg") == 0 | |
326 | + || strcmp (type_name, "image/svg+xml") == 0 | |
327 | + || strcmp (type_name, "UTF8_STRING") == 0)) { | |
326 | 328 | DiaImportFilter *ifilter = filter_import_get_by_name ("dia-svg"); |
327 | 329 | DiaContext *ctx = dia_context_new (_("Clipboard Paste")); |
328 | 330 | |
329 | 331 | if (ifilter->import_mem_func) { |
330 | - Change *change = undo_import_change_setup (ddisp->diagram); | |
332 | + Change *change = undo_import_change_setup (ddisp->diagram); | |
331 | 333 | |
332 | 334 | if (!ifilter->import_mem_func (data, len, DIA_DIAGRAM_DATA (ddisp->diagram), |
333 | 335 | ctx, ifilter->user_data)) { |
334 | 336 | /* might become more right some day ;) */ |
335 | - message_error (_("No clipboard handler for '%s'"), type_name); | |
337 | + dia_context_add_message (ctx, _("Failed to import '%s' as SVG."), type_name); | |
338 | + dia_context_release (ctx); | |
336 | 339 | } |
337 | 340 | if (undo_import_change_done (ddisp->diagram, change)) { |
338 | - undo_set_transactionpoint(ddisp->diagram->undo); | |
339 | - diagram_modified(ddisp->diagram); | |
340 | - diagram_flush(ddisp->diagram); | |
341 | + undo_set_transactionpoint(ddisp->diagram->undo); | |
342 | + diagram_modified(ddisp->diagram); | |
343 | + diagram_flush(ddisp->diagram); | |
341 | 344 | } |
342 | 345 | } |
346 | + } else { | |
347 | + /* fallback to pixbuf loader */ | |
348 | + GdkPixbuf *pixbuf = gtk_selection_data_get_pixbuf (selection_data); | |
349 | + if (pixbuf) { | |
350 | + received_clipboard_image_handler (clipboard, pixbuf, ddisp); | |
351 | + g_object_unref (pixbuf); | |
352 | + } else { | |
353 | + message_error (_("Paste failed: %s"), type_name); | |
354 | + } | |
343 | 355 | } |
344 | 356 | dia_log_message ("Content is %s (size=%d)", type_name, len); |
345 | 357 | g_free (type_name); |
346 | - | |
347 | - } | |
348 | -} | |
349 | - | |
350 | -static void | |
351 | -_targets_receive (GtkClipboard *clipboard, | |
352 | - GdkAtom *atom, | |
353 | - gint n_atoms, | |
354 | - gpointer data) | |
355 | -{ | |
356 | - gint i; | |
357 | - gchar *aname; | |
358 | - | |
359 | - for (i = 0; i < n_atoms; ++i) { | |
360 | - aname = gdk_atom_name (atom[i]); | |
361 | - dia_log_message ("clipboard-targets %d: %s", i, aname); | |
362 | - g_free (aname); | |
363 | 358 | } |
364 | 359 | } |
365 | 360 |
@@ -368,21 +363,33 @@ edit_paste_image_callback (GtkAction *action) | ||
368 | 363 | { |
369 | 364 | GtkClipboard *clipboard = gtk_clipboard_get(GDK_NONE); |
370 | 365 | DDisplay *ddisp; |
371 | - GdkAtom svg_atom = gdk_atom_intern_static_string ("image/svg+xml"); | |
366 | + GdkAtom *targets; | |
367 | + gint n_targets; | |
368 | + gboolean done = FALSE; | |
372 | 369 | |
373 | 370 | ddisp = ddisplay_active(); |
374 | 371 | if (!ddisp) return; |
375 | 372 | |
376 | - gtk_clipboard_request_targets (clipboard, _targets_receive, ddisp); | |
377 | - /* a second request call is asynchronuously to the above. I've found no reliable | |
378 | - * way to make the latter use information generted by the former | |
379 | - */ | |
380 | - if (gtk_clipboard_wait_for_contents (clipboard, svg_atom)) | |
381 | - gtk_clipboard_request_contents (clipboard, svg_atom, | |
382 | - received_clipboard_content_handler, ddisp); | |
383 | - else | |
384 | - gtk_clipboard_request_image (clipboard, | |
385 | - received_clipboard_image_handler, ddisp); | |
373 | + if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) { | |
374 | + int i; | |
375 | + for (i = 0; i < n_targets; ++i) { | |
376 | + gchar *aname = gdk_atom_name (targets[i]); | |
377 | + if ( strcmp (aname, "image/svg") == 0 | |
378 | + || strcmp (aname, "image/svg+xml") == 0 | |
379 | + || strcmp (aname, "UTF8_STRING") == 0) { | |
380 | + gtk_clipboard_request_contents (clipboard, targets[i], | |
381 | + received_clipboard_content_handler, ddisp); | |
382 | + done = TRUE; | |
383 | + } | |
384 | + dia_log_message ("clipboard-targets %d: %s", i, aname); | |
385 | + g_free (aname); | |
386 | + if (done) | |
387 | + break; | |
388 | + } | |
389 | + if (!done) | |
390 | + gtk_clipboard_request_image (clipboard, received_clipboard_image_handler, ddisp); | |
391 | + g_free (targets); | |
392 | + } | |
386 | 393 | } |
387 | 394 | |
388 | 395 | static PropDescription text_prop_singleton_desc[] = { |
@@ -405,12 +412,13 @@ static GtkTargetEntry target_entries[] = { | ||
405 | 412 | { "image/svg+xml", GTK_TARGET_OTHER_APP, 2 }, |
406 | 413 | { "image/png", GTK_TARGET_OTHER_APP, 3 }, |
407 | 414 | { "image/bmp", GTK_TARGET_OTHER_APP, 4 }, |
415 | + { "image/tiff", GTK_TARGET_OTHER_APP, 5 }, | |
408 | 416 | #ifdef G_OS_WIN32 |
409 | 417 | /* this is not working on win32 either, maybe we need to register it with |
410 | 418 | * CF_ENHMETAFILE in Gtk+? Change order? Direct use of SetClipboardData()? |
411 | 419 | */ |
412 | - { "image/emf", GTK_TARGET_OTHER_APP, 5 }, | |
413 | - { "image/wmf", GTK_TARGET_OTHER_APP, 6 }, | |
420 | + { "image/emf", GTK_TARGET_OTHER_APP, 6 }, | |
421 | + { "image/wmf", GTK_TARGET_OTHER_APP, 7 }, | |
414 | 422 | #endif |
415 | 423 | }; |
416 | 424 |
@@ -437,6 +445,9 @@ _clipboard_get_data_callback (GtkClipboard *clipboard, | ||
437 | 445 | * convert from png on demand ... */ |
438 | 446 | if (strcmp (ext, "bmp") == 0) { |
439 | 447 | tmplate = g_strdup ("dia-cb-XXXXXX.png"); |
448 | + } else if (strcmp (ext, "tiff") == 0) { | |
449 | + /* pixbuf on OS X offers qtif and qif - both look like a mistake to me ;) */ | |
450 | + tmplate = g_strdup ("dia-cb-XXXXXX.png"); | |
440 | 451 | } else if (g_str_has_suffix (ext, "+xml")) { |
441 | 452 | gchar *ext2 = g_strndup (ext, strlen (ext) - 4); |
442 | 453 | tmplate = g_strdup_printf ("dia-cb-XXXXXX.%s", ext2); |
@@ -466,7 +477,7 @@ _clipboard_get_data_callback (GtkClipboard *clipboard, | ||
466 | 477 | * Or even better: only use pixbuf transport when asked |
467 | 478 | * for 'OS native bitmaps' BMP (win32), TIFF(osx), ...? |
468 | 479 | */ |
469 | - if (strcmp (ext, "bmp") == 0 || strcmp (ext, "tif") == 0) { | |
480 | + if (strcmp (ext, "bmp") == 0 || strcmp (ext, "tiff") == 0) { | |
470 | 481 | GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(outfname, &error); |
471 | 482 | if (pixbuf) { |
472 | 483 | gtk_selection_data_set_pixbuf (selection_data, pixbuf); |
@@ -537,7 +548,7 @@ edit_copy_callback (GtkAction *action) | ||
537 | 548 | * Nowadays the notation of one system global clipboard is common |
538 | 549 | * for many programs on Linux, too. |
539 | 550 | */ |
540 | -#ifdef G_OS_WIN32 | |
551 | +#ifndef GDK_WINDOWING_X11 | |
541 | 552 | gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE), |
542 | 553 | prop->text_data, -1); |
543 | 554 | #else |
@@ -613,7 +624,7 @@ edit_paste_callback (GtkAction *action) | ||
613 | 624 | ddisp = ddisplay_active(); |
614 | 625 | if (!ddisp) return; |
615 | 626 | if (textedit_mode(ddisp)) { |
616 | -#ifdef G_OS_WIN32 | |
627 | +#ifndef GDK_WINDOWING_X11 | |
617 | 628 | gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE), |
618 | 629 | received_clipboard_text_handler, ddisp); |
619 | 630 | #else |
@@ -768,7 +779,7 @@ edit_copy_text_callback (GtkAction *action) | ||
768 | 779 | /* GTK docs claim the selection clipboard is ignored on Win32. |
769 | 780 | * The "clipboard" clipboard is mostly ignored in Unix |
770 | 781 | */ |
771 | -#ifdef G_OS_WIN32 | |
782 | +#ifndef GDK_WINDOWING_X11 | |
772 | 783 | gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE), |
773 | 784 | prop->text_data, -1); |
774 | 785 | #else |
@@ -806,7 +817,7 @@ edit_cut_text_callback (GtkAction *action) | ||
806 | 817 | /* GTK docs claim the selection clipboard is ignored on Win32. |
807 | 818 | * The "clipboard" clipboard is mostly ignored in Unix |
808 | 819 | */ |
809 | -#ifdef G_OS_WIN32 | |
820 | +#ifndef GDK_WINDOWING_X11 | |
810 | 821 | gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE), |
811 | 822 | prop->text_data, -1); |
812 | 823 | #else |
@@ -833,7 +844,7 @@ edit_paste_text_callback (GtkAction *action) | ||
833 | 844 | ddisp = ddisplay_active(); |
834 | 845 | if (!ddisp) return; |
835 | 846 | |
836 | -#ifdef G_OS_WIN32 | |
847 | +#ifndef GDK_WINDOWING_X11 | |
837 | 848 | gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE), |
838 | 849 | received_clipboard_text_handler, ddisp); |
839 | 850 | #else |