1 --- gtk+-2.6.4/gtk/gtktextbuffer.c 2004-11-01 21:57:13.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtktextbuffer.c 2005-04-06 16:19:38.023757872 +0300
4 /* GTK - The GIMP Toolkit
5 * gtktextbuffer.c Copyright (C) 2000 Red Hat, Inc.
6 + * Copyright (C) 2004 Nokia Corporation
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
11 #include "gtktextbtree.h"
12 #include "gtktextiterprivate.h"
14 +#include "gtktextbufferserialize.h"
16 +#define GTK_TEXT_BUFFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TEXT_BUFFER, GtkTextBufferPrivate))
18 +typedef struct _GtkTextBufferPrivate GtkTextBufferPrivate;
20 +struct _GtkTextBufferPrivate
22 + gboolean can_paste_rich_text;
23 + gchar *rich_text_format;
26 typedef struct _ClipboardRequest ClipboardRequest;
35 + PROP_CAN_PASTE_RICH_TEXT,
36 + PROP_RICH_TEXT_FORMAT
44 + TARGET_TEXT_VIEW_MARKUP,
45 + TARGET_TEXT_VIEW_RICH_TEXT_FORMAT,
46 TARGET_TEXT_BUFFER_CONTENTS
51 GTK_TYPE_TEXT_TAG_TABLE,
52 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
53 + g_object_class_install_property (object_class,
54 + PROP_CAN_PASTE_RICH_TEXT,
55 + g_param_spec_boolean ("can_paste_rich_text",
56 + P_("Can paste rich text"),
57 + P_("Whether it should be possible to paste rich text to the buffer"),
58 + FALSE, G_PARAM_READWRITE));
59 + g_object_class_install_property (object_class,
60 + PROP_RICH_TEXT_FORMAT,
61 + g_param_spec_string ("rich_text_format",
62 + P_("Rich Text Format"),
63 + P_("Name of a collection of tags that the text view supports"),
64 + NULL, G_PARAM_READWRITE));
67 signals[INSERT_TEXT] =
68 g_signal_new ("insert_text",
69 G_OBJECT_CLASS_TYPE (object_class),
72 _gtk_marshal_VOID__VOID,
77 + g_type_class_add_private (object_class, sizeof (GtkTextBufferPrivate));
83 set_table (text_buffer, g_value_get_object (value));
86 + case PROP_CAN_PASTE_RICH_TEXT:
87 + gtk_text_buffer_set_can_paste_rich_text (text_buffer, g_value_get_boolean (value));
89 + case PROP_RICH_TEXT_FORMAT:
90 + gtk_text_buffer_set_rich_text_format (text_buffer, g_value_get_string (value));
97 g_value_set_object (value, get_table (text_buffer));
100 + case PROP_CAN_PASTE_RICH_TEXT:
101 + g_value_set_boolean (value,
102 + gtk_text_buffer_get_can_paste_rich_text (text_buffer));
104 + case PROP_RICH_TEXT_FORMAT:
105 + g_value_set_string (value,
106 + gtk_text_buffer_get_rich_text_format (text_buffer));
111 @@ -434,11 +478,14 @@
112 gtk_text_buffer_finalize (GObject *object)
114 GtkTextBuffer *buffer;
115 + GtkTextBufferPrivate *priv;
117 buffer = GTK_TEXT_BUFFER (object);
119 remove_all_selection_clipboards (buffer);
121 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (buffer);
123 if (buffer->tag_table)
125 _gtk_text_tag_table_remove_buffer (buffer->tag_table, buffer);
127 free_log_attr_cache (buffer->log_attr_cache);
129 buffer->log_attr_cache = NULL;
132 + g_free (priv->rich_text_format);
134 G_OBJECT_CLASS (parent_class)->finalize (object);
137 @@ -2738,8 +2787,7 @@
139 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
141 - if (selection_data->target ==
142 - gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
143 + if (info == TARGET_TEXT_BUFFER_CONTENTS)
145 /* Provide the address of the buffer; this will only be
146 * used within-process
147 @@ -2750,6 +2798,32 @@
151 + else if (info == TARGET_TEXT_VIEW_MARKUP)
156 + str = gtk_text_buffer_serialize_rich_text (buffer, &start, &end, &len);
158 + gtk_selection_data_set (selection_data,
159 + gdk_atom_intern ("application/x-gtk-text-view-markup", FALSE),
164 + else if (info == TARGET_TEXT_VIEW_RICH_TEXT_FORMAT)
169 + format = g_object_get_data (G_OBJECT (buffer), "gtk-text-buffer-clipboard-format");
170 + len = format ? strlen (format) : -1;
172 + gtk_selection_data_set (selection_data,
173 + gdk_atom_intern ("application/x-gtk-text-view-rich-text-format", FALSE),
180 @@ -2765,10 +2839,16 @@
181 create_clipboard_contents_buffer (GtkTextBuffer *buffer)
183 GtkTextBuffer *contents;
186 contents = gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
188 + format = GTK_TEXT_BUFFER_GET_PRIVATE (buffer)->rich_text_format;
190 g_object_set_data (G_OBJECT (contents), "gtk-text-buffer-clipboard", GINT_TO_POINTER (1));
192 + g_object_set_data_full (G_OBJECT (contents), "gtk-text-buffer-clipboard-format",
193 + format ? g_strdup (format) : NULL, g_free);
197 @@ -2786,8 +2866,7 @@
199 g_assert (contents); /* This should never be called unless we own the clipboard */
201 - if (selection_data->target ==
202 - gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
203 + if (info == TARGET_TEXT_BUFFER_CONTENTS)
205 /* Provide the address of the clipboard buffer; this will only
206 * be used within-process. OK to supply a NULL value for contents.
207 @@ -2798,6 +2877,35 @@
211 + else if (info == TARGET_TEXT_VIEW_MARKUP)
215 + GtkTextIter start, end;
217 + gtk_text_buffer_get_bounds (contents, &start, &end);
219 + str = gtk_text_buffer_serialize_rich_text (contents, &start, &end, &len);
221 + gtk_selection_data_set (selection_data,
222 + gdk_atom_intern ("application/x-gtk-text-view-markup", FALSE),
227 + else if (info == TARGET_TEXT_VIEW_RICH_TEXT_FORMAT)
232 + format = g_object_get_data (G_OBJECT (contents), "gtk-text-buffer-clipboard-format");
233 + len = format ? strlen (format) : -1;
235 + gtk_selection_data_set (selection_data,
236 + gdk_atom_intern ("application/x-gtk-text-view-rich-text-format", FALSE),
243 @@ -2992,6 +3100,54 @@
247 +clipboard_text_view_markup_received (GtkClipboard *clipboard,
248 + GtkSelectionData *selection_data,
251 + ClipboardRequest *request_data = data;
252 + GtkTextIter insert_point;
253 + gboolean retval = TRUE;
254 + GError *error = NULL;
255 + GtkTextBufferPrivate *priv;
257 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (request_data->buffer);
259 + if (selection_data->target ==
260 + gdk_atom_intern ("application/x-gtk-text-view-markup", FALSE))
262 + pre_paste_prep (request_data, &insert_point);
264 + if (request_data->interactive)
265 + gtk_text_buffer_begin_user_action (request_data->buffer);
267 + if (!request_data->interactive ||
268 + gtk_text_iter_can_insert (&insert_point, request_data->default_editable))
269 + retval = gtk_text_buffer_deserialize_rich_text (request_data->buffer,
271 + selection_data->data, selection_data->length,
272 + priv->rich_text_format == NULL, &error);
276 + g_warning ("error pasting: %s\n", error->message);
279 + if (request_data->interactive)
280 + gtk_text_buffer_end_user_action (request_data->buffer);
283 + post_paste_cleanup (request_data);
288 + /* Request the text selection instead */
289 + gtk_clipboard_request_text (clipboard,
290 + clipboard_text_received,
295 paste_from_buffer (ClipboardRequest *request_data,
296 GtkTextBuffer *src_buffer,
297 const GtkTextIter *start,
298 @@ -3029,6 +3185,35 @@
299 g_free (request_data);
303 +formats_match (GtkClipboard *clipboard, const gchar *format)
305 + GtkSelectionData *data;
312 + data = gtk_clipboard_wait_for_contents (clipboard,
313 + gdk_atom_intern ("application/x-gtk-text-view-rich-text-format", FALSE));
315 + if (data->length <= 0)
319 + tmp = g_strndup (data->data, data->length);
321 + retval = (strcmp (tmp, format) == 0);
326 + gtk_selection_data_free (data);
332 clipboard_clipboard_buffer_received (GtkClipboard *clipboard,
333 GtkSelectionData *selection_data,
334 @@ -3036,6 +3221,7 @@
336 ClipboardRequest *request_data = data;
337 GtkTextBuffer *src_buffer;
338 + GtkTextBufferPrivate *priv;
340 src_buffer = selection_data_get_buffer (selection_data, request_data);
342 @@ -3059,10 +3245,19 @@
346 - /* Request the text selection instead */
347 - gtk_clipboard_request_text (clipboard,
348 - clipboard_text_received,
350 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (request_data->buffer);
352 + if (priv->can_paste_rich_text &&
353 + formats_match (clipboard, priv->rich_text_format))
354 + /* Request markup */
355 + gtk_clipboard_request_contents (clipboard,
356 + gdk_atom_intern ("application/x-gtk-text-view-markup", FALSE),
357 + clipboard_text_view_markup_received, data);
359 + /* Request the text selection instead */
360 + gtk_clipboard_request_text (clipboard,
361 + clipboard_text_received,
366 @@ -3071,6 +3266,8 @@
367 { "TEXT", 0, TARGET_TEXT },
368 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
369 { "UTF8_STRING", 0, TARGET_UTF8_STRING },
370 + { "application/x-gtk-text-view-markup", 0, TARGET_TEXT_VIEW_MARKUP },
371 + { "application/x-gtk-text-view-rich-text-format", 0, TARGET_TEXT_VIEW_RICH_TEXT_FORMAT },
372 { "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
375 @@ -3591,6 +3788,68 @@
380 +gtk_text_buffer_set_can_paste_rich_text (GtkTextBuffer *buffer,
381 + gboolean can_paste_rich_text)
383 + GtkTextBufferPrivate *priv;
385 + g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
387 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (buffer);
389 + can_paste_rich_text = (can_paste_rich_text != FALSE);
391 + if (priv->can_paste_rich_text != can_paste_rich_text)
393 + priv->can_paste_rich_text = can_paste_rich_text;
395 + g_object_notify (G_OBJECT (buffer), "can_paste_rich_text");
400 +gtk_text_buffer_get_can_paste_rich_text (GtkTextBuffer *buffer)
402 + GtkTextBufferPrivate *priv;
404 + g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
406 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (buffer);
408 + return priv->can_paste_rich_text;
412 +gtk_text_buffer_set_rich_text_format (GtkTextBuffer *buffer,
413 + const gchar *format)
416 + GtkTextBufferPrivate *priv;
418 + g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
420 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (buffer);
422 + new_format = g_strdup (format);
423 + g_free (priv->rich_text_format);
425 + priv->rich_text_format = new_format;
426 + g_object_notify (G_OBJECT (buffer), "rich_text_format");
429 +G_CONST_RETURN gchar *
430 +gtk_text_buffer_get_rich_text_format (GtkTextBuffer *buffer)
432 + GtkTextBufferPrivate *priv;
434 + g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
436 + priv = GTK_TEXT_BUFFER_GET_PRIVATE (buffer);
438 + return priv->rich_text_format;
442 * Logical attribute cache