added new public function gimp_clipboard_set_svg() and internal stuff to

2005-09-19  Michael Natterer  <mitch@gimp.org>

	* app/widgets/gimpclipboard.[ch]: added new public function
	gimp_clipboard_set_svg() and internal stuff to offer and transfer
	the svg data to the clipboard.

	* app/actions/vectors-commands.c (vectors_copy_cmd_callback)
	(vectors_paste_cmd_callback): implement copy/paste of vectors as
	SVG. Fixes bug #316547.

	* app/widgets/gimpvectorstreeview.c
	(gimp_vectors_tree_view_drag_svg): don't add the terminating
	nul-byte of the svg string to svg_data_length, it confuses the XML
	parser.

	* app/actions/vectors-actions.c
	* app/actions/vectors-commands.[ch]
	* menus/vectors-menu.xml: reordered export/import so they are in
	the same order as copy/paste.
This commit is contained in:
Michael Natterer 2005-09-19 21:33:03 +00:00 committed by Michael Natterer
parent de5ee6c44c
commit c7998a1855
8 changed files with 188 additions and 39 deletions

View File

@ -1,3 +1,23 @@
2005-09-19 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpclipboard.[ch]: added new public function
gimp_clipboard_set_svg() and internal stuff to offer and transfer
the svg data to the clipboard.
* app/actions/vectors-commands.c (vectors_copy_cmd_callback)
(vectors_paste_cmd_callback): implement copy/paste of vectors as
SVG. Fixes bug #316547.
* app/widgets/gimpvectorstreeview.c
(gimp_vectors_tree_view_drag_svg): don't add the terminating
nul-byte of the svg string to svg_data_length, it confuses the XML
parser.
* app/actions/vectors-actions.c
* app/actions/vectors-commands.[ch]
* menus/vectors-menu.xml: reordered export/import so they are in
the same order as copy/paste.
2005-09-19 Sven Neumann <sven@gimp.org>
* plug-ins/common/animationplay.c: moved toolbar out of main vbox.

View File

@ -130,15 +130,15 @@ static GimpActionEntry vectors_actions[] =
G_CALLBACK (vectors_paste_cmd_callback),
GIMP_HELP_PATH_PASTE },
{ "vectors-import", GTK_STOCK_OPEN,
N_("I_mport Path..."), "", NULL,
G_CALLBACK (vectors_import_cmd_callback),
GIMP_HELP_PATH_IMPORT },
{ "vectors-export", GTK_STOCK_SAVE,
N_("E_xport Path..."), "", NULL,
G_CALLBACK (vectors_export_cmd_callback),
GIMP_HELP_PATH_EXPORT }
GIMP_HELP_PATH_EXPORT },
{ "vectors-import", GTK_STOCK_OPEN,
N_("I_mport Path..."), "", NULL,
G_CALLBACK (vectors_import_cmd_callback),
GIMP_HELP_PATH_IMPORT }
};
static GimpToggleActionEntry vectors_toggle_actions[] =
@ -291,9 +291,9 @@ vectors_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("vectors-lower-to-bottom", vectors && next);
SET_SENSITIVE ("vectors-copy", vectors);
SET_SENSITIVE ("vectors-paste", global_buf);
SET_SENSITIVE ("vectors-import", gimage);
SET_SENSITIVE ("vectors-paste", gimage);
SET_SENSITIVE ("vectors-export", vectors);
SET_SENSITIVE ("vectors-import", gimage);
SET_SENSITIVE ("vectors-visible", vectors);
SET_SENSITIVE ("vectors-linked", vectors);

View File

@ -48,6 +48,7 @@
#include "vectors/gimpvectors-import.h"
#include "widgets/gimpaction.h"
#include "widgets/gimpclipboard.h"
#include "widgets/gimphelp-ids.h"
#include "display/gimpdisplay.h"
@ -415,11 +416,16 @@ vectors_copy_cmd_callback (GtkAction *action,
{
GimpImage *gimage;
GimpVectors *vectors;
gchar *svg;
return_if_no_vectors (gimage, vectors, data);
#ifdef __GNUC__
#warning FIXME: need vectors clipboard
#endif
svg = gimp_vectors_export_string (gimage, vectors);
if (svg)
{
gimp_clipboard_set_svg (gimage->gimp, svg);
g_free (svg);
}
}
void
@ -427,32 +433,29 @@ vectors_paste_cmd_callback (GtkAction *action,
gpointer data)
{
GimpImage *gimage;
gchar *svg;
gsize svg_size;
return_if_no_image (gimage, data);
#ifdef __GNUC__
#warning FIXME: need vectors clipboard
#endif
}
svg = gimp_clipboard_get_svg (gimage->gimp, &svg_size);
void
vectors_import_cmd_callback (GtkAction *action,
gpointer data)
{
VectorsImportDialog *dialog;
GimpImage *gimage;
GtkWidget *widget;
return_if_no_image (gimage, data);
return_if_no_widget (widget, data);
if (svg)
{
GError *error = NULL;
dialog = vectors_import_dialog_new (gimage, widget,
vectors_import_merge,
vectors_import_scale);
if (! gimp_vectors_import_buffer (gimage, svg, svg_size,
TRUE, TRUE, -1, &error))
{
g_message (error->message);
g_clear_error (&error);
}
else
{
gimp_image_flush (gimage);
}
g_signal_connect (dialog->dialog, "response",
G_CALLBACK (vectors_import_response),
dialog);
gtk_widget_show (dialog->dialog);
g_free (svg);
}
}
void
@ -476,6 +479,27 @@ vectors_export_cmd_callback (GtkAction *action,
gtk_widget_show (dialog->dialog);
}
void
vectors_import_cmd_callback (GtkAction *action,
gpointer data)
{
VectorsImportDialog *dialog;
GimpImage *gimage;
GtkWidget *widget;
return_if_no_image (gimage, data);
return_if_no_widget (widget, data);
dialog = vectors_import_dialog_new (gimage, widget,
vectors_import_merge,
vectors_import_scale);
g_signal_connect (dialog->dialog, "response",
G_CALLBACK (vectors_import_response),
dialog);
gtk_widget_show (dialog->dialog);
}
void
vectors_visible_cmd_callback (GtkAction *action,
gpointer data)

View File

@ -59,10 +59,10 @@ void vectors_copy_cmd_callback (GtkAction *action,
gpointer data);
void vectors_paste_cmd_callback (GtkAction *action,
gpointer data);
void vectors_import_cmd_callback (GtkAction *action,
gpointer data);
void vectors_export_cmd_callback (GtkAction *action,
gpointer data);
void vectors_import_cmd_callback (GtkAction *action,
gpointer data);
void vectors_visible_cmd_callback (GtkAction *action,
gpointer data);

View File

@ -45,6 +45,11 @@ struct _GimpClipboard
GtkTargetEntry *target_entries;
gint n_target_entries;
GtkTargetEntry *svg_target_entries;
gint n_svg_target_entries;
gchar *svg;
};
@ -59,6 +64,10 @@ static void gimp_clipboard_send_buffer (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
guint info,
Gimp *gimp);
static void gimp_clipboard_send_svg (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
guint info,
Gimp *gimp);
static GdkAtom * gimp_clipboard_wait_for_targets (gint *n_targets);
static GdkAtom gimp_clipboard_wait_for_buffer (Gimp *gimp);
@ -148,6 +157,17 @@ gimp_clipboard_init (Gimp *gimp)
}
}
}
gimp_clip->n_svg_target_entries = 2;
gimp_clip->svg_target_entries = g_new0 (GtkTargetEntry, 2);
gimp_clip->svg_target_entries[0].target = g_strdup ("image/svg");
gimp_clip->svg_target_entries[0].flags = 0;
gimp_clip->svg_target_entries[0].info = 0;
gimp_clip->svg_target_entries[1].target = g_strdup ("image/svg+xml");
gimp_clip->svg_target_entries[1].flags = 0;
gimp_clip->svg_target_entries[1].info = 1;
}
void
@ -167,6 +187,7 @@ gimp_clipboard_exit (Gimp *gimp)
G_CALLBACK (gimp_clipboard_buffer_changed),
NULL);
gimp_clipboard_set_buffer (gimp, NULL);
gimp_clipboard_set_svg (gimp, NULL);
g_object_set_data (G_OBJECT (gimp), GIMP_CLIPBOARD_KEY, NULL);
}
@ -294,8 +315,7 @@ gimp_clipboard_get_svg (Gimp *gimp,
clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
GDK_SELECTION_CLIPBOARD);
if (clipboard &&
gtk_clipboard_get_owner (clipboard) != G_OBJECT (gimp) &&
if (clipboard &&
(atom = gimp_clipboard_wait_for_svg (gimp)) != GDK_NONE)
{
GtkSelectionData *data;
@ -321,6 +341,53 @@ gimp_clipboard_get_svg (Gimp *gimp,
return NULL;
}
/**
* gimp_clipboard_set_svg:
* @gimp: pointer to #Gimp
* @svg: a string containing the SVG data
*
* Offers SVG data in %GDK_SELECTION_CLIPBOARD.
**/
void
gimp_clipboard_set_svg (Gimp *gimp,
gchar *svg)
{
GimpClipboard *gimp_clip = gimp_clipboard_get (gimp);
GtkClipboard *clipboard;
g_return_if_fail (GIMP_IS_GIMP (gimp));
clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
GDK_SELECTION_CLIPBOARD);
if (! clipboard)
return;
if (gimp_clip->svg)
{
g_free (gimp_clip->svg);
gimp_clip->svg = NULL;
}
if (svg)
{
gimp_clip->svg = g_strdup (svg);
gtk_clipboard_set_with_owner (clipboard,
gimp_clip->svg_target_entries,
gimp_clip->n_svg_target_entries,
(GtkClipboardGetFunc) gimp_clipboard_send_svg,
(GtkClipboardClearFunc) NULL,
G_OBJECT (gimp));
/* mark the first entry (image/svg) as suitable for storing */
gtk_clipboard_set_can_store (clipboard, gimp_clip->svg_target_entries, 1);
}
else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
{
gtk_clipboard_clear (clipboard);
}
}
/* private functions */
@ -341,6 +408,12 @@ gimp_clipboard_free (GimpClipboard *gimp_clip)
g_free (gimp_clip->target_entries[i].target);
g_free (gimp_clip->target_entries);
for (i = 0; i < gimp_clip->n_svg_target_entries; i++)
g_free (gimp_clip->svg_target_entries[i].target);
g_free (gimp_clip->svg_target_entries);
g_free (gimp_clip);
}
@ -362,6 +435,12 @@ gimp_clipboard_set_buffer (Gimp *gimp,
if (! clipboard)
return;
if (gimp_clip->svg)
{
g_free (gimp_clip->svg);
gimp_clip->svg = NULL;
}
if (buffer)
{
gtk_clipboard_set_with_owner (clipboard,
@ -371,7 +450,7 @@ gimp_clipboard_set_buffer (Gimp *gimp,
(GtkClipboardClearFunc) NULL,
G_OBJECT (gimp));
/* mark the first entry (PNG) as suitable for storing */
/* mark the first entry (image/png) as suitable for storing */
gtk_clipboard_set_can_store (clipboard, gimp_clip->target_entries, 1);
}
else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
@ -544,3 +623,26 @@ gimp_clipboard_send_buffer (GtkClipboard *clipboard,
gimp_unset_busy (gimp);
}
static void
gimp_clipboard_send_svg (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
guint info,
Gimp *gimp)
{
GimpClipboard *gimp_clip = gimp_clipboard_get (gimp);
gimp_set_busy (gimp);
if (gimp_clip->svg)
{
g_printerr ("sending svg data as '%s'\n",
gimp_clip->svg_target_entries[info].target);
gimp_selection_data_set_stream (selection_data,
gimp_clip->svg,
strlen (gimp_clip->svg));
}
gimp_unset_busy (gimp);
}

View File

@ -30,5 +30,8 @@ gboolean gimp_clipboard_has_svg (Gimp *gimp);
gchar * gimp_clipboard_get_svg (Gimp *gimp,
gsize *svg_length);
void gimp_clipboard_set_svg (Gimp *gimp,
gchar *svg);
#endif /* __GIMP_CLIPBOARD_H__ */

View File

@ -316,7 +316,7 @@ gimp_vectors_tree_view_drag_svg (GtkWidget *widget,
svg_data = gimp_vectors_export_string (gimage, GIMP_VECTORS (item));
if (svg_data)
*svg_data_len = strlen (svg_data) + 1;
*svg_data_len = strlen (svg_data);
}
return (guchar *) svg_data;

View File

@ -22,7 +22,7 @@
<separator />
<menuitem action="vectors-copy" />
<menuitem action="vectors-paste" />
<menuitem action="vectors-import" />
<menuitem action="vectors-export" />
<menuitem action="vectors-import" />
</popup>
</ui>