After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 324177 - Copy and paste of rich text
Copy and paste of rich text
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkTextView
2.8.x
Other All
: Normal enhancement
: ---
Assigned To: gtk-bugs
gtk-bugs
: 328660 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2005-12-15 14:05 UTC by Michael Natterer
Modified: 2006-03-07 13:50 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch against HEAD implementing the above (20.74 KB, patch)
2005-12-15 14:07 UTC, Michael Natterer
needs-work Details | Review
gtktextbufferserialize.c (41.95 KB, text/plain)
2005-12-15 14:07 UTC, Michael Natterer
  Details
gtktextbufferserialize.h (1.65 KB, text/plain)
2005-12-15 14:08 UTC, Michael Natterer
  Details
Next version of the patch (36.02 KB, patch)
2006-01-19 15:12 UTC, Michael Natterer
none Details | Review
Next version of gtktextbufferserialize.c (42.17 KB, text/x-csrc)
2006-01-19 15:13 UTC, Michael Natterer
  Details
Next version of gtktextbufferserialize.h (1.69 KB, text/x-chdr)
2006-01-19 15:13 UTC, Michael Natterer
  Details
API proposal: gtkrichtext.h registry (4.27 KB, text/x-chdr)
2006-01-24 17:21 UTC, Michael Natterer
  Details
Next patch version for review (66.94 KB, patch)
2006-01-26 16:55 UTC, Michael Natterer
none Details | Review
gtkrichtext.c (9.52 KB, text/x-csrc)
2006-01-26 16:56 UTC, Michael Natterer
  Details
gtkrichtext.h (4.29 KB, text/x-chdr)
2006-01-26 16:56 UTC, Michael Natterer
  Details
gtktextbufferserialize.c (42.33 KB, text/x-csrc)
2006-01-26 16:57 UTC, Michael Natterer
  Details
gtktextbufferserialize.h (1.85 KB, text/x-chdr)
2006-01-26 16:58 UTC, Michael Natterer
  Details
Rename property: s/rich-text-format/rich-text-tag-set-name/ (67.10 KB, patch)
2006-01-27 13:50 UTC, Michael Natterer
none Details | Review
Next patch version (72.09 KB, patch)
2006-01-31 15:48 UTC, Michael Natterer
none Details | Review
Fix dropping between different buffers in the same process (76.71 KB, patch)
2006-02-03 15:15 UTC, Michael Natterer
none Details | Review
patch (7.64 KB, patch)
2006-02-03 21:42 UTC, Matthias Clasen
none Details | Review
Adds rich text DND icon (85.32 KB, patch)
2006-02-06 16:55 UTC, Michael Natterer
none Details | Review
gtkrichtext.c (13.33 KB, text/x-csrc)
2006-02-28 10:51 UTC, Michael Natterer
  Details
gtkrichtext.h (5.07 KB, text/x-chdr)
2006-02-28 10:52 UTC, Michael Natterer
  Details
new patch to be used with above new gtkrichtext.[ch] (76.28 KB, patch)
2006-02-28 10:59 UTC, Michael Natterer
none Details | Review
gtktextbufferrichtext.c (13.95 KB, text/x-csrc)
2006-03-01 14:13 UTC, Michael Natterer
  Details
gtktextbufferrichtext.h (5.47 KB, text/x-chdr)
2006-03-01 14:14 UTC, Michael Natterer
  Details
And another iteration (88.71 KB, patch)
2006-03-01 14:19 UTC, Michael Natterer
none Details | Review
gtktextbufferrichtext.c (16.53 KB, text/x-csrc)
2006-03-03 19:09 UTC, Michael Natterer
  Details
gtktextbufferrichtext.h (5.85 KB, text/x-chdr)
2006-03-03 19:09 UTC, Michael Natterer
  Details
gtktextbufferserialize.c (42.50 KB, text/x-csrc)
2006-03-03 19:10 UTC, Michael Natterer
  Details
gtktextbufferserialize.h (2.04 KB, text/x-chdr)
2006-03-03 19:11 UTC, Michael Natterer
  Details
Next patch version (84.47 KB, patch)
2006-03-03 19:15 UTC, Michael Natterer
none Details | Review
For the records: final patch as comitted to cvs (85.33 KB, patch)
2006-03-07 13:49 UTC, Michael Natterer
committed Details | Review

Description Michael Natterer 2005-12-15 14:05:36 UTC
Attached patch from maemo-gtk adds rich text copy and paste
to GtkTextBuffer. I made the API private, even though it's
public in maemo. Also it might make sense to add versioning
to the serialized data.
Comment 1 Michael Natterer 2005-12-15 14:07:07 UTC
Created attachment 56027 [details] [review]
Patch against HEAD implementing the above
Comment 2 Michael Natterer 2005-12-15 14:07:57 UTC
Created attachment 56028 [details]
gtktextbufferserialize.c
Comment 3 Michael Natterer 2005-12-15 14:08:24 UTC
Created attachment 56029 [details]
gtktextbufferserialize.h
Comment 4 Matthias Clasen 2005-12-18 04:20:52 UTC
- This should probably be renamed to can-transfer-rich-text, and cover   
  drag-and-drop as well.

- While this ad-hoc xml format is probably fine for transferring data between 
  text views in multiple instances of the same application, I can see that it 
  could be much more useful to offer "rich text" in other formats, such as
  RTF or XHTML fragments. One way to enable this would be to allow registration
  of additional formats (to register a format, you would need a name or atom,
  and a pair of serialization/deserialization functions)

- What about selectable labels ? It would probably be of marginal usefulness,
  but those can also contain "rich text" and support copy-paste/drag-and-drop. 
Comment 5 Michael Natterer 2005-12-21 14:09:27 UTC
- I don't see how can-transfer-rich-text would be better, since copying
  is always allowed, the property just makes pasting configurable.

- Totally agree here, however getting RTF or XHTML done right is
  much harder. And does it hurt to support this as "internal" feature
  between different GtkTextViews?

- How can entries contain rich text?
Comment 6 Matthias Clasen 2005-12-21 14:20:33 UTC
- The proposed name change was just to make it more obvious that it
  applies to copy-and-paste and dnd (Different ways to "transfer" text...)

- I don't think there is a problem with allowing this internal format
  between different text views (you should probably document it then, though).
  And I don't want to hold this patch hostage to implementing RTF support
  in GTK+, but having hooks for other formats would be useful.

- Not entries, selectable labels
  
Comment 7 Tim Janik 2006-01-05 10:18:40 UTC
i'd like to suggest that we simply change the header from its current "RICHTEXT" to something like "GTKTEXTBUFFERSERIAL0000", i.e. do the versioning mitch suggested earlier. then we can declare the format purely internal, don't need to document it and can change it to any (documented) format in the future without problems.
Comment 8 Matthias Clasen 2006-01-06 13:48:02 UTC
Yes, something like GTKTEXTBUFFERCONTENTS-1.0 is a better name for the private serialization format. I still think my points in #4 need to be addressed.
Comment 9 Michael Natterer 2006-01-19 15:12:07 UTC
Created attachment 57645 [details] [review]
Next version of the patch

Attached patch addresses serialization format versioning and DND.
Registering of other rich text formats is not implemented, but easier
to implement now because the target lists/tables are manages dynamically
now. GtkLabel stuff is also untouched.
Comment 10 Michael Natterer 2006-01-19 15:13:05 UTC
Created attachment 57646 [details]
Next version of gtktextbufferserialize.c
Comment 11 Michael Natterer 2006-01-19 15:13:39 UTC
Created attachment 57647 [details]
Next version of gtktextbufferserialize.h
Comment 12 Matthias Clasen 2006-01-20 07:03:23 UTC
The one thing thats hampering our ability to add registration of application-defined rich text formats later is the assumption that 
a text buffer can only support a single rich text format. You will 
have to allow multiple formats.

In order to extend this to selectable labels, we need a mapping from
pango attributes to tags, and a functions to serialize/deserialize
text+pango attributes into this format.
Comment 13 Michael Natterer 2006-01-20 11:18:17 UTC
I don't consider that patch final, just a step in the right direction.
The target lists/tables are already created dynamically, so adding
registration of other formats is much easier to implement. In fact,
I'm working on an API to allow this.

The problem I see with selectable labels is that it's not exactly
trivial to create a serialization API that will handle both. Perhaps
we should simply have a utility function that makes a GtkTextBuffer
out of a label's markup?

Also, where should the serialization formats be registered? With each
buffer and label? That sounds rather weird imho. Maybe it's best to
put all that stuff into a central rich text format registry, living
in gtk/gtkrichtext.[ch], and have both GtkTextBuffer and GtkLabel use
this?
Comment 14 Tim Janik 2006-01-20 13:07:48 UTC
matthis, note that mitch's patch already supports multiple formats that are negotiated upon pasting (either you use a specific format name which then denotes a conventional set of tags, or you use a NULL format which allowes any kind of tag list to be transfered).
to avoid duplication of the logic involved, and because i consider rich-text pasting from labels far less common than plain text pasting from labels or rich-text pasting from text buffers, i think mitch's idea to -if neccessary- facilitate label->text-buffer->serialization conversion is very sound.
programatically, label markup conversion to and from text buffers can also be interesting, so having two conversion functions that accomplish this sounds desirable to me.
Comment 15 Michael Natterer 2006-01-20 13:27:01 UTC
I don't think that's the "formats" matthias means, we're talking
about optionally letting the user register functions for RTF,
XHTML etc. The set of aggreed-upon (in whatever context) tags
that are supported is a layer on top of that.
Comment 16 Matthias Clasen 2006-01-20 13:43:50 UTC
Yes.

I agree that rich text copying from labels can be treated as a separate
problem after we have text views done. And Mitch is correct that I was thinking
about scenarios where the application, might want to allow copying contents
as RTF or XHTML. I think it is quite reasonable to assume that people will 
want to allow multiple different formats to be available at the same time. 

Just like we offer plain text in multiple formats, and let the receiving side
pick the one it can handle best.

I agree with mitch that it would be cumbersome to register the RTF format for every single text view where you want to offer it. It might in fact be better
to have an extensible set of rich text targets, similar to the current
 gtk_target_list_add_text/image_targets()
The text view would then simply offer rich text in all formats which have
been registered with GtkSelection (or whereever we want to establish that registry)

Comment 17 Michael Natterer 2006-01-24 17:21:40 UTC
Created attachment 58030 [details]
API proposal: gtkrichtext.h registry

Attached API proposal for central rich text format registry.
gtkselection.c would simply use the registry to implement:

void gtk_target_list_add_image_targets (GtkTargetList  *list,
                                        guint           info,
                                        gboolean        deserializable,
                                        const gchar    *tag_set_name);
Comment 18 Michael Natterer 2006-01-24 17:23:43 UTC
Ehm, s/image/rich_text/ for the target list API of course...
Comment 19 Matthias Clasen 2006-01-24 17:27:11 UTC
Looks reasonable to me. Do you expect it to be common to only support
one way, ie only serialize, or only deserialize ? If not, it may be more
convenient to register both directions at the same time.
Comment 20 Michael Natterer 2006-01-24 17:50:50 UTC
Registering both was my first API version, but after some thinking
it turned out that not having separate internal serialize/deserialize
format lists would make certain things impossible, like overriding
just one of the functions some other part of the code has registered
before. So I went for the more complex API, instead of figuring
the lack thereof after the release ;)
Comment 21 Matthias Clasen 2006-01-24 18:24:40 UTC
hmm, when would you do that ? anyway, its not a big deal, I'm fine with 
having separate functions
Comment 22 Michael Natterer 2006-01-24 19:01:05 UTC
I have no idea :) But given the fact that each combination of mime-type
and tag-set-name (e.g. "application/my-private-foo-format;my-editor-tag-set")
makes up a new format, it's hard to forsee what weird stuff people
will do with that, so better stay generic...
Comment 23 Michael Natterer 2006-01-26 16:55:50 UTC
Created attachment 58162 [details] [review]
Next patch version for review

Attached patch makes use the rich text registration facility that
follows in the next attachments.
Comment 24 Michael Natterer 2006-01-26 16:56:27 UTC
Created attachment 58163 [details]
gtkrichtext.c
Comment 25 Michael Natterer 2006-01-26 16:56:58 UTC
Created attachment 58164 [details]
gtkrichtext.h
Comment 26 Michael Natterer 2006-01-26 16:57:31 UTC
Created attachment 58165 [details]
gtktextbufferserialize.c
Comment 27 Michael Natterer 2006-01-26 16:58:15 UTC
Created attachment 58166 [details]
gtktextbufferserialize.h

That's it.
Comment 28 Michael Natterer 2006-01-27 13:50:31 UTC
Created attachment 58207 [details] [review]
Rename property: s/rich-text-format/rich-text-tag-set-name/

Next version featuring GtkTextBuffer property name cleanup.

Matthias: Does not include the list of tag-set-names yet we
talked about on irc.
Comment 29 Michael Natterer 2006-01-31 15:48:46 UTC
Created attachment 58473 [details] [review]
Next patch version

- rename "tag set" to "tagset" globally to avoind looking like a setter
- changed tagset name APIs in GtkTextBuffer and GtkClipboard from one string
  to a GList of strings so a buffer can support multiple tagsets
- allways offer all formats when copying/dragging, and only restrict
  pasting/dropping
- changed text buffer property and API:
  can-transfer-rich-text -> can-receive-rich-text
Comment 30 Matthias Clasen 2006-02-01 05:41:33 UTC
ok, first feedback after playing around with it for 5 minutes:

+ I was able to copy and paste formatted text including a pixbuf from
  one testtext instance to another, very nice

+ application/x-gtk-text-buffer-rich-text shows up in the list of targets
  offered when pasting and when dragging.

- DND between the two testtext instances only transfers poor text, even
  though application/x-gtk-text-buffer-rich-text is among the offered
  formats

- The DND icon needs to show rich text when we are dragging rich text
Comment 31 Matthias Clasen 2006-02-01 21:48:28 UTC
*** Bug 328660 has been marked as a duplicate of this bug. ***
Comment 32 Michael Natterer 2006-02-03 15:15:26 UTC
Created attachment 58655 [details] [review]
Fix dropping between different buffers in the same process
Comment 33 Matthias Clasen 2006-02-03 19:32:47 UTC
  g_free (priv->rich_text_tagsets);

in gtk_text_buffer_finalize should be 

  g_list_free (priv->rich_text_tagsets);
Comment 34 Matthias Clasen 2006-02-03 19:48:44 UTC
Mitch, "fix dropping between different buffers in the same process"
means don't drop rich text when can-reveive-rich-text is off ?
can-receive-rich-text is still ignored for copy-paste or dnd inside a single buffer, afaics. But it works between different buffers.
Comment 35 Matthias Clasen 2006-02-03 21:42:26 UTC
Created attachment 58674 [details] [review]
patch
Comment 36 Matthias Clasen 2006-02-03 21:50:52 UTC
things to fix:

- hide cursor
- make text fade out towards the right/bottom
- don't serialize/deserialize for this, probably add a separate function
  to create a  rich text drag icon from a buffer slice
- reinstate the simple text drag icon function for entries.
Comment 37 Michael Natterer 2006-02-06 16:55:12 UTC
Created attachment 58816 [details] [review]
Adds rich text DND icon
Comment 38 Yevgen Muntyan 2006-02-08 12:51:25 UTC
In some cases (e.g. syntax highlighting) copying/dragging text with formatting is not desired. At the moment when copying/pasting in one buffer, it also copies tags, and workaround for this is using some flag in apply_tags handler (ugly but works). Please make sure it doesn't break (Mitch said he didn't change intra-buffer copying, so it should be okay).
Also, dragging colored text from a buffer with syntax highlighting inside might not make much sense, so it would be good to have some property to disable it (source targets can't be just changed without code for dnd, right?).
And same thing applies to pixbufs - e.g. placeholders which denote certain positions in text but are not part of the text.
Comment 39 Thomas Folz-Donahue 2006-02-08 14:36:56 UTC
> In some cases (e.g. syntax highlighting) copying/dragging
> text with formatting is not desired.

On the contrary, I think that it is desirable to copy some code from your text editor to your email or im client, and send it to your buddy with full syntax highlighting.

When I send people code snippets, I sometimes even manually syntax highlight them.  Syntax highlighting lets people see the structure of code easier.

When the code gets put in another text editor or gets fed to an interpreter, that's when the syntax highlighting information needs to get stripped.  Coincidentially, interpreters and code editors don't accept rich text.

Part of my motivation for filing a duplicate of this feature request was that I wanted to be able to copy and paste syntax-highlighted code.
Comment 40 Michael Natterer 2006-02-28 10:51:53 UTC
Created attachment 60309 [details]
gtkrichtext.c
Comment 41 Michael Natterer 2006-02-28 10:52:34 UTC
Created attachment 60310 [details]
gtkrichtext.h
Comment 42 Michael Natterer 2006-02-28 10:59:44 UTC
Created attachment 60311 [details] [review]
new patch to be used with above new gtkrichtext.[ch]

New rich text patch:

- the serialize/deserialize registries are now per-textbuffer. I didn't
  change the namespace yet, comments are welcome
  (probably gtk_text_buffer_[de]desialize_foo_bar())
- tagset names are gone from the public API, except for the rich text
  register functions. They are meant to be used with either the internal
  format (mime_type and functions == NULL), or with any externally provided
  format that is capable of holding any of a text buffer's features.
- creating new tags upon deserialization is now configurable for each
  deserialize function, it didn't make any sense to configure this on
  the text buffer.
- the rich text functions in gtkclipboard and gtkselection now take
  GtkTextBuffer arguments, since they need to query the rich text formats
  registered with the buffer.
- the internal format is not registered by default any more.
- a text case is still missing, testing by simply setting some text
  buffer properties is not possible any longer.
Comment 43 Michael Natterer 2006-03-01 14:13:41 UTC
Created attachment 60399 [details]
gtktextbufferrichtext.c
Comment 44 Michael Natterer 2006-03-01 14:14:21 UTC
Created attachment 60400 [details]
gtktextbufferrichtext.h
Comment 45 Michael Natterer 2006-03-01 14:19:15 UTC
Created attachment 60401 [details] [review]
And another iteration

We're getting close:

- renamed rich text registry files to gtktextbufferrichtext.[ch]
  and its functions to gtk_text_buffer_foo_bar()
- added testing stuff to tests/testtext.c
- added "content_buffer" parameter to the main serialize() and
  deserialize() functions, because now that the registry is attached
  to the buffer, it's no longer possible to create temporary buffers
  and serialize/deserialize them, they simply lack the registered
  rich text formats. With the new API, a text buffer can (de)serialize
  another one. The patch uses this feature to serialize the temporary
  clipboard contents buffer that is created internally.
- the only thing that's missing is some API docs.
Comment 46 Matthias Clasen 2006-03-02 05:44:52 UTC
The api changes look good to me.

When I tried testtext, I could not get rich text dragged from one
buffer to the other, although I had registered application/x-gtk-text-buffer-rich-text on both sides, and checked the
can create tags column.

Copying inside a single buffer, on the other hand copied the tags
even though no rich text target was registered.
Comment 47 Matthias Clasen 2006-03-02 05:52:16 UTC
Ah, the failure to copy rich text between buffers was due to the
can-receive-rich-text property not being set.
Comment 48 Michael Natterer 2006-03-02 10:07:58 UTC
Copying inside a text buffer does not go through rich text.
And I wonder if we still need the can-receive-rich-text property
now that rich text has to be registered for each buffer.
Comment 49 Matthias Clasen 2006-03-02 13:29:42 UTC
I was about to ask the same, but you said the version was final...
Comment 50 Michael Natterer 2006-03-03 19:09:16 UTC
Created attachment 60595 [details]
gtktextbufferrichtext.c
Comment 51 Michael Natterer 2006-03-03 19:09:56 UTC
Created attachment 60596 [details]
gtktextbufferrichtext.h
Comment 52 Michael Natterer 2006-03-03 19:10:32 UTC
Created attachment 60597 [details]
gtktextbufferserialize.c
Comment 53 Michael Natterer 2006-03-03 19:11:12 UTC
Created attachment 60598 [details]
gtktextbufferserialize.h
Comment 54 Michael Natterer 2006-03-03 19:15:53 UTC
Created attachment 60599 [details] [review]
Next patch version

Apparently, nothing is ever final :)

Changes in this version:

- the can-receive-rich-text property and API is gone
- the actual serialize and deserialize functions have two GtkTextBuffer
  parameters too, so they have access to the buffer they were registered
  with
- there is now a separate, very easy API for registering tagset names
  for the internal rich text format. This also makes the main registering
  functions easier to understand and document
- there are some API docs to ease review, more to come
Comment 55 Matthias Clasen 2006-03-05 04:03:14 UTC
Looks good to me. 
GtkTextBufferSelectionInfo does not really need to become public API, does it ?
Comment 56 Tim Janik 2006-03-06 13:36:07 UTC
ok, i think the API is ok now, and this can go into CVS.

i do think that text buffers in general should support copying of the unconstrained rich-text format, by adding:
  gtk_text_buffer_register_serialize_tagset (buffer, NULL);
to gtk_text_buffer_init().

since tags need to be handled by the user, pastage couldn't be enabled by default. but this way, at least every text buffer can serve as a source for target buffers that are setup with:
  atom = gtk_text_buffer_register_deserialize_tagset (buffer, NULL);
  gtk_text_buffer_deserialize_set_can_create_tags (buffer, atom, TRUE);
Comment 57 Michael Natterer 2006-03-06 14:50:53 UTC
GtkTextBufferSelectionInfo contains the "info" values used in the
target lists returned by gtk_text_buffer_get_copy,paste_target_list(),
i don't see a way to avoid them being public.

Will add gtk_text_buffer_register_serialize_tagset (buffer, NULL);
to gtk_text_buffer_init() plus the missing api docs and commit the
patch otherwise as-is.
Comment 58 Michael Natterer 2006-03-06 14:59:47 UTC
argh, mis-clicked
Comment 59 Michael Natterer 2006-03-07 13:47:59 UTC
Fixed in CVS with the final changes discussed above:

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.
Comment 60 Michael Natterer 2006-03-07 13:49:09 UTC
Created attachment 60832 [details] [review]
For the records: final patch as comitted to cvs