Re: paste in GtkTextBuffer



Darin Adler <darin bentspoon com> writes:
> on 10/5/01 4:14 PM, Havoc Pennington at hp redhat com wrote:
> 
> > vishnu pobox com writes:
> >> Examining the GtkTextBuffer source code, i see that paste_from_buffer
> >> calls gtk_text_buffer_real_insert_range which appears impossible
> >> to customize for my purposes.
> >> 
> >> If i could disable the paste function from copying tags then i
> >> would be happy.  Any other suggestions?
> > 
> > Sure, I don't promise I know how to fix this by 2.0, but at least
> > we'll have an open issue.
> 
> Just using a signal or virtual function here for the insert_range call done
> for pasting would do the trick. It doesn't seem to require much deep
> thought, except maybe for the name of the function. Maybe I'm missing what
> makes it hard.
> 

There are already some possible hacks, for example you can connect to
apply_tag and simply stop_by_name that signal. You can even
distinguish apply_tags resulting from a user operation and those you
are doing yourself, using begin_user_action/end_user_action. So I do
think there are workarounds for now.

The reason I think it's hard to know what else to add to make this
nicer is that I don't want to just virtualize everything in
gtktextbuffer.c and gtktextview.c, without having some kind of general
idea what is going on and which use-cases I'm trying to
handle. Because virtualizing everything will mean supporting a lot of
internal details in the future.

The general issue here is how you override what happens in response to
various user actions (paste, various keybindings, dnd on mouse events,
etc.) In this case it's paste, but there are lots of them. Josh
himself has a couple open bugs in bugzilla for other ones.

The reason this issue is hard is that the code in gtktextview.c is all
interrelated and it's not very clear (to me at least) where people
need to hook in and how we can present a sane API for doing so.  For
example the button release handler can only work if it knows what
happend in button press, there's persistent state that has to be
consistent.



On the insert_range virtual function specifically, I'm not sure it
makes sense. insert_range is just a convenience function, not a
fundamental operation. "Inserting a range" just means you insert some
text, and then you apply some tags to it. All instances of inserting
some text then applying tags would not be forced to go through an
insert_range virtual function. The insert_range implementation doesn't
use any private methods on text buffer, I don't think, in any case it
shouldn't have to.

So, unlike insert_text and apply_tag, which are primitive operations
and ALL insertions of text or applications of tags go through there,
overriding insert_range is like overriding the keybinding signals on
GtkTextView; it doesn't catch all the things you might be intending to
catch.

I can't even come up with a definition of the semantics of
insert_range; when is it OK to insert text and apply tags without
using insert_range? If never, how the heck do you enforce that? And
how long do you have to wait after inserting text before you apply
tags, to have it not count as an insert_range? And how do you use
insert_range when your text/tags aren't already in some other buffer
to be copied? (Because insert_range means to insert text and apply
tags using another buffer as source.)


Upshot, any use of the insert_range virtual function would be broken
because it would be totally legitimate for someone (for example the
GtkTextView implementation) to have a function that did exactly the
same thing as insert_range, but didn't go through the insert_range
function.



So one brute-force way to address all this is to have a collection of
functions like:

 gtk_text_view_set_has_selection_dnd()
 gtk_text_view_set_paste_includes_tags()
 gtk_text_view_set_double_click_selects_word()
 gtk_text_view_set_triple_click_selects_line()

My problems with this solution are:

 - it's a lot of API bloat

 - it's quite fragile for application code; say you disable selection
   DND, but forget to disable paste, or disable paste, but forget to
   disable the paste keybindings, or disable everything, but then in
   the future GTK adds new keybindings or mouse handling - i.e. it
   binds application correctness to the text widget UI details, which 
   makes it hard for us to improve the UI

 - it breaks model-view if you are having to intercept things on 
   the GtkTextView widget level



In any case, since GtkTextBuffer/GtkTextView are already more
elaborate than pretty much any other GUI toolkit text widget (except
the Swing text widget, which is practically a word processor), I'm not
sure it makes sense to toss in a half-baked API to make it still more
flexible at the last minute. Gathering use-case data during the 2.2
cycle might give us a much better idea what to do.


Which isn't to say I wouldn't like to discuss this issue now, I am
happy to hear more thoughts from people on what to do.

Havoc





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]