Commit 6c1d990a authored by Michael Natterer's avatar Michael Natterer Committed by Michael Natterer

Add infrastructure for copy/paste and DND of rich text for GtkTextBuffer.

2006-03-07  Michael Natterer  <mitch@imendio.com>

	Add infrastructure for copy/paste and DND of rich text for
	GtkTextBuffer. Fixes bug #324177.

	* gtk/gtktextbufferrichtext.[ch]: new files implementing a
	per-buffer registry of rich text formats.

	* gtk/gtk.h: #include gtktextbufferrichtext.h

	* gtk/gtktextbufferserialize.[ch]: new files implementing an
	internal serialization format that can handle all of a text
	buffer's tags and pixbufs. It's not useful for anything except
	tranfer between instances of GtkTextBuffer (Anders Carlsson).

	* gtk/Makefile.am: build the new files.

	* gtk/gtkclipboard.[ch]: added convenience APIs for rich text,
	just as they exist for plain text and pixbufs.

	* gtk/gtkselection.[ch]: added rich text convenience APIs here
	too.  Return the target list from gtk_target_list_ref(). Register
	GtkTargetList as boxed type. Added
	gtk_target_table_new_from_list() and gtk_target_table_free(),
	which make converting between GtkTargetList and arrays of
	GtkTargetEntry considerably easier.

	* gtk/gtktextutil.[ch]: added _gtk_text_util_create_rich_drag_icon()
	which creates a fancy rich text icon (Matthias Clasen).

	* gtk/gtktextbuffer.[ch]: use all the new stuff above and
	implement copy and paste of rich text. Added APIs for getting the
	target lists used for copy and paste. Added public enum
	GtkTextBufferTargetInfo which contains the "info" IDs associated
	with the entries of the target lists.

	* gtk/gtktextview.c: use the new rich text APIs and
	GtkTextBuffer's new target list API to enable DND of rich text
	chunks.

	* gtk/gtk.symbols: export all the new symbols added.

	* tests/testtext.c: added rich text testing stuff.
parent 1f5c2948
2006-03-07 Michael Natterer <mitch@imendio.com>
Add infrastructure for copy/paste and DND of rich text for
GtkTextBuffer. Fixes bug #324177.
* gtk/gtktextbufferrichtext.[ch]: new files implementing a
per-buffer registry of rich text formats.
* gtk/gtk.h: #include gtktextbufferrichtext.h
* gtk/gtktextbufferserialize.[ch]: new files implementing an
internal serialization format that can handle all of a text
buffer's tags and pixbufs. It's not useful for anything except
tranfer between instances of GtkTextBuffer (Anders Carlsson).
* gtk/Makefile.am: build the new files.
* gtk/gtkclipboard.[ch]: added convenience APIs for rich text,
just as they exist for plain text and pixbufs.
* gtk/gtkselection.[ch]: added rich text convenience APIs here
too. Return the target list from gtk_target_list_ref(). Register
GtkTargetList as boxed type. Added
gtk_target_table_new_from_list() and gtk_target_table_free(),
which make converting between GtkTargetList and arrays of
GtkTargetEntry considerably easier.
* gtk/gtktextutil.[ch]: added _gtk_text_util_create_rich_drag_icon()
which creates a fancy rich text icon (Matthias Clasen).
* gtk/gtktextbuffer.[ch]: use all the new stuff above and
implement copy and paste of rich text. Added APIs for getting the
target lists used for copy and paste. Added public enum
GtkTextBufferTargetInfo which contains the "info" IDs associated
with the entries of the target lists.
* gtk/gtktextview.c: use the new rich text APIs and
GtkTextBuffer's new target list API to enable DND of rich text
chunks.
* gtk/gtk.symbols: export all the new symbols added.
* tests/testtext.c: added rich text testing stuff.
2006-03-06 Matthias Clasen <mclasen@redhat.com>
* gtk/gtktextview.c (text_window_invalidate_cursors): Take
......
2006-03-07 Michael Natterer <mitch@imendio.com>
Add infrastructure for copy/paste and DND of rich text for
GtkTextBuffer. Fixes bug #324177.
* gtk/gtktextbufferrichtext.[ch]: new files implementing a
per-buffer registry of rich text formats.
* gtk/gtk.h: #include gtktextbufferrichtext.h
* gtk/gtktextbufferserialize.[ch]: new files implementing an
internal serialization format that can handle all of a text
buffer's tags and pixbufs. It's not useful for anything except
tranfer between instances of GtkTextBuffer (Anders Carlsson).
* gtk/Makefile.am: build the new files.
* gtk/gtkclipboard.[ch]: added convenience APIs for rich text,
just as they exist for plain text and pixbufs.
* gtk/gtkselection.[ch]: added rich text convenience APIs here
too. Return the target list from gtk_target_list_ref(). Register
GtkTargetList as boxed type. Added
gtk_target_table_new_from_list() and gtk_target_table_free(),
which make converting between GtkTargetList and arrays of
GtkTargetEntry considerably easier.
* gtk/gtktextutil.[ch]: added _gtk_text_util_create_rich_drag_icon()
which creates a fancy rich text icon (Matthias Clasen).
* gtk/gtktextbuffer.[ch]: use all the new stuff above and
implement copy and paste of rich text. Added APIs for getting the
target lists used for copy and paste. Added public enum
GtkTextBufferTargetInfo which contains the "info" IDs associated
with the entries of the target lists.
* gtk/gtktextview.c: use the new rich text APIs and
GtkTextBuffer's new target list API to enable DND of rich text
chunks.
* gtk/gtk.symbols: export all the new symbols added.
* tests/testtext.c: added rich text testing stuff.
2006-03-06 Matthias Clasen <mclasen@redhat.com>
* gtk/gtktextview.c (text_window_invalidate_cursors): Take
......
......@@ -248,6 +248,7 @@ gtk_public_h_sources = \
gtktearoffmenuitem.h \
gtktext.h \
gtktextbuffer.h \
gtktextbufferrichtext.h \
gtktextchild.h \
gtktextdisplay.h \
gtktextiter.h \
......@@ -481,6 +482,9 @@ gtk_c_sources = \
gtktext.c \
gtktextbtree.c \
gtktextbuffer.c \
gtktextbufferrichtext.c \
gtktextbufferserialize.c\
gtktextbufferserialize.h\
gtktextchild.c \
gtktextdisplay.c \
gtktextiter.c \
......
......@@ -160,6 +160,7 @@
#include <gtk/gtktearoffmenuitem.h>
#include <gtk/gtktext.h>
#include <gtk/gtktextbuffer.h>
#include <gtk/gtktextbufferrichtext.h>
#include <gtk/gtktextview.h>
#include <gtk/gtktipsquery.h>
#include <gtk/gtktoggleaction.h>
......
......@@ -600,6 +600,7 @@ gtk_clipboard_get_owner
gtk_clipboard_get_type G_GNUC_CONST
gtk_clipboard_request_contents
gtk_clipboard_request_image
gtk_clipboard_request_rich_text
gtk_clipboard_request_targets
gtk_clipboard_request_text
gtk_clipboard_set_can_store
......@@ -610,9 +611,11 @@ gtk_clipboard_set_with_owner
gtk_clipboard_store
gtk_clipboard_wait_for_contents
gtk_clipboard_wait_for_image
gtk_clipboard_wait_for_rich_text
gtk_clipboard_wait_for_targets
gtk_clipboard_wait_for_text
gtk_clipboard_wait_is_image_available
gtk_clipboard_wait_is_rich_text_available
gtk_clipboard_wait_is_text_available
gtk_clipboard_wait_is_target_available
#endif
......@@ -2607,6 +2610,23 @@ gtk_rc_style_unref
#endif
#endif
#if IN_HEADER(__GTK_TEXT_BUFFER_RICH_TEXT_H__)
#if IN_FILE(__GTK_TEXT_BUFFER_RICH_TEXT_C__)
gtk_text_buffer_deserialize
gtk_text_buffer_deserialize_get_can_create_tags
gtk_text_buffer_deserialize_set_can_create_tags
gtk_text_buffer_get_deserialize_formats
gtk_text_buffer_get_serialize_formats
gtk_text_buffer_register_deserialize_format
gtk_text_buffer_register_deserialize_tagset
gtk_text_buffer_register_serialize_format
gtk_text_buffer_register_serialize_tagset
gtk_text_buffer_serialize
gtk_text_buffer_unregister_deserialize_format
gtk_text_buffer_unregister_serialize_format
#endif
#endif
#if IN_HEADER(__GTK_RULER_H__)
#if IN_FILE(__GTK_RULER_C__)
gtk_ruler_draw_pos
......@@ -2678,9 +2698,11 @@ gtk_selection_data_set_pixbuf
gtk_selection_data_set_text
gtk_selection_data_set_uris
gtk_selection_data_targets_include_image
gtk_selection_data_targets_include_rich_text
gtk_selection_data_targets_include_text
gtk_selection_data_targets_include_uri
gtk_targets_include_image
gtk_targets_include_rich_text
gtk_targets_include_text
gtk_targets_include_uri
gtk_selection_owner_set
......@@ -2688,14 +2710,18 @@ gtk_selection_owner_set_for_display
gtk_selection_remove_all
gtk_target_list_add
gtk_target_list_add_image_targets
gtk_target_list_add_rich_text_targets
gtk_target_list_add_table
gtk_target_list_add_text_targets
gtk_target_list_add_uri_targets
gtk_target_list_find
gtk_target_list_get_type G_GNUC_CONST
gtk_target_list_new
gtk_target_list_ref
gtk_target_list_remove
gtk_target_list_unref
gtk_target_table_new_from_list
gtk_target_table_free
#endif
#endif
......@@ -2934,6 +2960,7 @@ gtk_text_buffer_delete_selection
gtk_text_buffer_end_user_action
gtk_text_buffer_get_bounds
gtk_text_buffer_get_char_count
gtk_text_buffer_get_copy_target_list
gtk_text_buffer_get_end_iter
gtk_text_buffer_get_has_selection
gtk_text_buffer_get_insert
......@@ -2946,6 +2973,7 @@ gtk_text_buffer_get_iter_at_offset
gtk_text_buffer_get_line_count
gtk_text_buffer_get_mark
gtk_text_buffer_get_modified
gtk_text_buffer_get_paste_target_list
gtk_text_buffer_get_selection_bound
gtk_text_buffer_get_selection_bounds
gtk_text_buffer_get_slice
......
......@@ -27,6 +27,7 @@
#include "gtkinvisible.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtktextbufferrichtext.h"
#include "gtkintl.h"
#include "gtkalias.h"
......@@ -47,6 +48,7 @@ typedef struct _GtkClipboardClass GtkClipboardClass;
typedef struct _RequestContentsInfo RequestContentsInfo;
typedef struct _RequestTextInfo RequestTextInfo;
typedef struct _RequestRichTextInfo RequestRichTextInfo;
typedef struct _RequestImageInfo RequestImageInfo;
typedef struct _RequestTargetsInfo RequestTargetsInfo;
......@@ -97,6 +99,15 @@ struct _RequestTextInfo
gpointer user_data;
};
struct _RequestRichTextInfo
{
GtkClipboardRichTextReceivedFunc callback;
GdkAtom *atoms;
gint n_atoms;
gint current_atom;
gpointer user_data;
};
struct _RequestImageInfo
{
GtkClipboardImageReceivedFunc callback;
......@@ -927,7 +938,7 @@ request_text_received_func (GtkClipboard *clipboard,
RequestTextInfo *info = data;
gchar *result = NULL;
result = gtk_selection_data_get_text (selection_data);
result = (gchar *) gtk_selection_data_get_text (selection_data);
if (!result)
{
......@@ -992,6 +1003,80 @@ gtk_clipboard_request_text (GtkClipboard *clipboard,
info);
}
static void
request_rich_text_received_func (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
gpointer data)
{
RequestRichTextInfo *info = data;
guint8 *result = NULL;
gsize length = 0;
result = selection_data->data;
length = selection_data->length;
info->current_atom++;
if ((!result || length < 1) && (info->current_atom < info->n_atoms))
{
gtk_clipboard_request_contents (clipboard, info->atoms[info->current_atom],
request_rich_text_received_func,
info);
return;
}
info->callback (clipboard, selection_data->target, result, length,
info->user_data);
g_free (info->atoms);
g_free (info);
}
/**
* gtk_clipboard_request_rich_text:
* @clipboard: a #GtkClipboard
* @buffer: a #GtkTextBuffer
* @callback: a function to call when the text is received,
* or the retrieval fails. (It will always be called
* one way or the other.)
* @user_data: user data to pass to @callback.
*
* Requests the contents of the clipboard as rich text. When the rich
* text is later received, @callback will be called.
*
* The @text parameter to @callback will contain the resulting rich
* text if the request succeeded, or %NULL if it failed. The @length
* parameter will contain @text's length. This function can fail for
* various reasons, in particular if the clipboard was empty or if the
* contents of the clipboard could not be converted into rich text form.
*
* Since: 2.10
**/
void
gtk_clipboard_request_rich_text (GtkClipboard *clipboard,
GtkTextBuffer *buffer,
GtkClipboardRichTextReceivedFunc callback,
gpointer user_data)
{
RequestRichTextInfo *info;
g_return_if_fail (clipboard != NULL);
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
g_return_if_fail (callback != NULL);
info = g_new (RequestRichTextInfo, 1);
info->callback = callback;
info->atoms = NULL;
info->n_atoms = 0;
info->current_atom = 0;
info->user_data = user_data;
info->atoms = gtk_text_buffer_get_deserialize_formats (buffer, &info->n_atoms);
gtk_clipboard_request_contents (clipboard, info->atoms[info->current_atom],
request_rich_text_received_func,
info);
}
static void
request_image_received_func (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
......@@ -1143,6 +1228,8 @@ typedef struct
{
GMainLoop *loop;
gpointer data;
GdkAtom format; /* used by rich text */
gsize length; /* used by rich text */
} WaitResults;
static void
......@@ -1254,6 +1341,75 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
return results.data;
}
static void
clipboard_rich_text_received_func (GtkClipboard *clipboard,
GdkAtom format,
const guint8 *text,
gsize length,
gpointer data)
{
WaitResults *results = data;
results->data = g_memdup (text, length);
results->format = format;
results->length = length;
g_main_loop_quit (results->loop);
}
/**
* gtk_clipboard_wait_for_rich_text:
* @clipboard: a #GtkClipboard
* @buffer: a #GtkTextBuffer
* @length: return location for the length of the returned data
*
* Requests the contents of the clipboard as rich text. This function
* waits for the data to be received using the main loop, so events,
* timeouts, etc, may be dispatched during the wait.
*
* Return value: a newly-allocated binary block of data which must
* be freed with g_free(), or %NULL if retrieving
* the selection data failed. (This could happen
* for various reasons, in particular if the
* clipboard was empty or if the contents of the
* clipboard could not be converted into text form.)
*
* Since: 2.10
**/
guint8 *
gtk_clipboard_wait_for_rich_text (GtkClipboard *clipboard,
GtkTextBuffer *buffer,
GdkAtom *format,
gsize *length)
{
WaitResults results;
g_return_val_if_fail (clipboard != NULL, NULL);
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (length != NULL, NULL);
results.data = NULL;
results.loop = g_main_loop_new (NULL, TRUE);
gtk_clipboard_request_rich_text (clipboard, buffer,
clipboard_rich_text_received_func,
&results);
if (g_main_loop_is_running (results.loop))
{
GDK_THREADS_LEAVE ();
g_main_loop_run (results.loop);
GDK_THREADS_ENTER ();
}
g_main_loop_unref (results.loop);
*format = results.format;
*length = results.length;
return results.data;
}
static void
clipboard_image_received_func (GtkClipboard *clipboard,
GdkPixbuf *pixbuf,
......@@ -1361,6 +1517,45 @@ gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
return result;
}
/**
* gtk_clipboard_wait_is_rich_text_available:
* @clipboard: a #GtkClipboard
* @buffer: a #GtkTextBuffer
*
* Test to see if there is rich text available to be pasted
* This is done by requesting the TARGETS atom and checking
* if it contains any of the supported rich text targets. This function
* waits for the data to be received using the main loop, so events,
* timeouts, etc, may be dispatched during the wait.
*
* This function is a little faster than calling
* gtk_clipboard_wait_for_rich_text() since it doesn't need to retrieve
* the actual text.
*
* Return value: %TRUE is there is rich text available, %FALSE otherwise.
*
* Since: 2.10
**/
gboolean
gtk_clipboard_wait_is_rich_text_available (GtkClipboard *clipboard,
GtkTextBuffer *buffer)
{
GtkSelectionData *data;
gboolean result = FALSE;
g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
if (data)
{
result = gtk_selection_data_targets_include_rich_text (data, buffer);
gtk_selection_data_free (data);
}
return result;
}
/**
* gtk_clipboard_wait_is_image_available:
* @clipboard: a #GtkClipboard
......
......@@ -30,19 +30,24 @@ G_BEGIN_DECLS
#define GTK_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CLIPBOARD, GtkClipboard))
#define GTK_IS_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CLIPBOARD))
typedef void (* GtkClipboardReceivedFunc) (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
gpointer data);
typedef void (* GtkClipboardTextReceivedFunc) (GtkClipboard *clipboard,
const gchar *text,
gpointer data);
typedef void (* GtkClipboardImageReceivedFunc) (GtkClipboard *clipboard,
GdkPixbuf *pixbuf,
gpointer data);
typedef void (* GtkClipboardTargetsReceivedFunc) (GtkClipboard *clipboard,
GdkAtom *atoms,
gint n_atoms,
gpointer data);
typedef void (* GtkClipboardReceivedFunc) (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
gpointer data);
typedef void (* GtkClipboardTextReceivedFunc) (GtkClipboard *clipboard,
const gchar *text,
gpointer data);
typedef void (* GtkClipboardRichTextReceivedFunc) (GtkClipboard *clipboard,
GdkAtom format,
const guint8 *text,
gsize length,
gpointer data);
typedef void (* GtkClipboardImageReceivedFunc) (GtkClipboard *clipboard,
GdkPixbuf *pixbuf,
gpointer data);
typedef void (* GtkClipboardTargetsReceivedFunc) (GtkClipboard *clipboard,
GdkAtom *atoms,
gint n_atoms,
gpointer data);
/* Should these functions have GtkClipboard *clipboard as the first argument?
* right now for ClearFunc, you may have trouble determining _which_ clipboard
......@@ -86,32 +91,42 @@ void gtk_clipboard_set_text (GtkClipboard *clipboard,
void gtk_clipboard_set_image (GtkClipboard *clipboard,
GdkPixbuf *pixbuf);
void gtk_clipboard_request_contents (GtkClipboard *clipboard,
GdkAtom target,
GtkClipboardReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_text (GtkClipboard *clipboard,
GtkClipboardTextReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_image (GtkClipboard *clipboard,
GtkClipboardImageReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_targets (GtkClipboard *clipboard,
GtkClipboardTargetsReceivedFunc callback,
gpointer user_data);
GtkSelectionData *gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
GdkAtom target);
gchar * gtk_clipboard_wait_for_text (GtkClipboard *clipboard);
GdkPixbuf * gtk_clipboard_wait_for_image (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
GdkAtom **targets,
gint *n_targets);
gboolean gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
GdkAtom target);
void gtk_clipboard_request_contents (GtkClipboard *clipboard,
GdkAtom target,
GtkClipboardReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_text (GtkClipboard *clipboard,
GtkClipboardTextReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_rich_text (GtkClipboard *clipboard,
GtkTextBuffer *buffer,
GtkClipboardRichTextReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_image (GtkClipboard *clipboard,
GtkClipboardImageReceivedFunc callback,
gpointer user_data);
void gtk_clipboard_request_targets (GtkClipboard *clipboard,
GtkClipboardTargetsReceivedFunc callback,
gpointer user_data);
GtkSelectionData *gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
GdkAtom target);
gchar * gtk_clipboard_wait_for_text (GtkClipboard *clipboard);
guint8 * gtk_clipboard_wait_for_rich_text (GtkClipboard *clipboard,
GtkTextBuffer *buffer,
GdkAtom *format,
gsize *size);
GdkPixbuf * gtk_clipboard_wait_for_image (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
GdkAtom **targets,
gint *n_targets);
gboolean gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_is_rich_text_available (GtkClipboard *clipboard,
GtkTextBuffer *buffer);
gboolean gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
GdkAtom target);
void gtk_clipboard_set_can_store (GtkClipboard *clipboard,
......
......@@ -58,6 +58,7 @@
#include "gtkmain.h"
#include "gtkselection.h"
#include "gtktextbufferrichtext.h"
#include "gtkintl.h"
#include "gdk-pixbuf/gdk-pixbuf.h"
......@@ -213,13 +214,16 @@ gtk_target_list_new (const GtkTargetEntry *targets,
*
* Increases the reference count of a #GtkTargetList by one.
*
* Return value: the passed in #GtkTargetList.
**/
void
GtkTargetList *
gtk_target_list_ref (GtkTargetList *list)
{
g_return_if_fail (list != NULL);
g_return_val_if_fail (list != NULL, NULL);
list->ref_count++;
return list;
}
/**
......@@ -338,6 +342,45 @@ gtk_target_list_add_text_targets (GtkTargetList *list,
gtk_target_list_add (list, text_plain_atom, 0, info);
}
/**
* gtk_target_list_add_rich_text_targets:
* @list: a #GtkTargetList
* @info: an ID that will be passed back to the application
* @deserializable: if %TRUE, then deserializable rich text formats
* will be added, serializable formats otherwise.
* @buffer: a #GtkTextBuffer.
*
* Appends the rich text targets registered with
* gtk_text_buffer_register_serialize_format() or
* gtk_text_buffer_register_deserialize_format() to the target list. All
* targets are added with the same @info.
*
* Since: 2.10
**/
void
gtk_target_list_add_rich_text_targets (GtkTargetList *list,
guint info,
gboolean deserializable,
GtkTextBuffer *buffer)
{
GdkAtom *atoms;
gint n_atoms;
gint i;
g_return_if_fail (list != NULL);
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
if (deserializable)
atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
else
atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_atoms);
for (i = 0; i < n_atoms; i++)
gtk_target_list_add (list, atoms[i], 0, info);
g_free (atoms);
}
/**
* gtk_target_list_add_image_targets:
* @list: a #GtkTargetList
......@@ -514,6 +557,72 @@ gtk_target_list_find (GtkTargetList *list,
return FALSE;
}
/**
* gtk_target_table_new_from_list:
* @list: a #GtkTargetList
* @n_targets: return location for the number ot targets in the table
*
* This function creates an #GtkTargetEntry array that contains the
* same targets as the passed %list. The returned table is newly
* allocated and should be freed using gtk_target_table_free() when no
* longer needed.
*
* Return value: the new table.
*
* Since: 2.10
**/
GtkTargetEntry *
gtk_target_table_new_from_list (GtkTargetList *list,
gint *n_targets)
{
GtkTargetEntry *targets;
GList *tmp_list;
gint i;
g_return_val_if_fail (list != NULL, NULL);
g_return_val_if_fail (n_targets != NULL, NULL);
*n_targets = g_list_length (list->list);
targets = g_new0 (GtkTargetEntry, *n_targets);
for (i = 0, tmp_list = list->list;
i < *n_targets;
i++, tmp_list = g_list_next (tmp_list))
{
GtkTargetPair *pair = tmp_list->data;
targets[i].target = gdk_atom_name (pair->target);
targets[i].flags = pair->flags;
targets[i].info = pair->info;
}
return targets;
}
/**
* gtk_target_table_free:
* @targets: a #GtkTargetEntry array
* @n_targets: the number of entries in the array
*
* This function frees a target table as returned by
* gtk_target_table_new_from_list()
*
* Since: 2.10
**/
void
gtk_target_table_free (GtkTargetEntry *targets,
gint n_targets)
{
gint i;
g_return_if_fail (targets == NULL || n_targets > 0);
for (i = 0; i < n_targets; i++)
g_free (targets[i].target);
g_free (targets);
}
/**
* gtk_selection_owner_set_for_display:
* @display: the #Gdkdisplay where the selection is set
......@@ -1608,7 +1717,54 @@ gtk_targets_include_text (GdkAtom *targets,
return result;
}
/**
* gtk_targets_include_rich_text:
* @targets: an array of #GdkAtom<!-- -->s
* @n_targets: the length of @targets
* @buffer: a #GtkTextBuffer
*
* Determines if any of the targets in @targets can be used to
* provide rich text.
*
* Return value: %TRUE if @targets include a suitable target for rich text,
* otherwise %FALSE.
*
* Since: 2.10
**/
gboolean
gtk_targets_include_rich_text (GdkAtom *targets,
gint n_targets,
GtkTextBuffer *buffer)
{
GdkAtom *rich_targets;
gint n_rich_targets;
gint i, j;
gboolean result = FALSE;
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
&n_rich_targets);
for (i = 0; i < n_targets; i++)
{
for (j = 0; j < n_rich_targets; j++)
{
if (targets[i] == rich_targets[j])
{
result = TRUE;
goto done;
}
}
}