Re: Gtk::TextBuffer::signal_erase()



Hi Mr.Cashe,

This is what the GTK+ documentation says about the signals you use
(http://developer.gnome.org/gtk3/stable/GtkTextBuffer.html)

The ::insert-text signal is emitted to insert text in a GtkTextBuffer.
Insertion actually occurs in the default handler.

Note that if your handler runs before the default handler it must not
invalidate the location iter (or has to revalidate it). The default
signal handler revalidates it to point to the end of the inserted text.
-------
The ::delete-range signal is emitted to delete a range from a
GtkTextBuffer.

Note that if your handler runs before the default handler it must not
invalidate the start and end iters (or has to revalidate them). The
default signal handler revalidates the start and end iters to both point
point to the location where text was deleted. Handlers which run after
the default handler (see g_signal_connect_after()) do not have access to
the deleted text.
-------
Your C signal handlers run before the default handlers, but your C++
handlers run after the default handlers. If you change your code to

if (GtkTextBuffer * gobj = tb->gobj()) {
  g_signal_connect_after(gobj, "insert-text", G_CALLBACK(on_c_insert),
0);
  g_signal_connect_after(gobj, "delete-range", G_CALLBACK(on_c_erase),
0);
}
tb->signal_insert().connect(sigc::ptr_fun(on_cxx_insert), false);
tb->signal_erase().connect(sigc::ptr_fun(on_cxx_erase), false);

the C++ handlers run before and the C handlers after the default
handlers, and the result is

on_cxx_insert(): pos = 0
on_c_insert(): pos = 14
on_cxx_erase(): start = 5, end = 8
on_c_erase(): start = 5, end = 5
Result = This a text



fre 2011-09-09 klockan 01:10 +1100 skrev Mr.Cashe:
> Hi, Everybody!
> I found strange behaviour of signals on_erase() && on_insert() within
> Gtk::TextBuffer.
> 
> Here is a test code:
> #include <gtkmm/textbuffer.h>
> #include <gtkmm/main.h>
> #include <iostream>
> 
> static void on_cxx_insert(const Gtk::TextIter & pos, const
> Glib::ustring &, int) {
>     std::cout << "on_cxx_insert(): pos = " << pos.get_offset() <<
> std::endl;
> }
> 
> static void on_cxx_erase(const Gtk::TextIter & start, const
> Gtk::TextIter & end) {
>     std::cout << "on_cxx_erase(): start = " << start.get_offset() <<
> ", end = " << end.get_offset() << std::endl;
> }
> 
> static void on_c_insert(GtkTextBuffer *, GtkTextIter * pos, const
> gchar *, gint, void *) {
>     std::cout << "on_c_insert(): pos = " <<
> gtk_text_iter_get_offset(pos) << std::endl;
> }
> 
> static void on_c_erase(GtkTextBuffer *, GtkTextIter * start,
> GtkTextIter * end, void *) {
>     std::cout << "on_c_erase(): start = " <<
> gtk_text_iter_get_offset(start) << ", end = " <<
> gtk_text_iter_get_offset(end) << std::endl;
> }
> 
> int main(int argc, char * argv[]) {
>     Gtk::Main gtk_main(&argc, &argv);
>     Glib::RefPtr<Gtk::TextBuffer> tb = Gtk::TextBuffer::create();
>     if (GtkTextBuffer * gobj = tb->gobj()) {
>         g_signal_connect(gobj, "insert-text", G_CALLBACK(on_c_insert),
> 0);
>         g_signal_connect(gobj, "delete-range", G_CALLBACK(on_c_erase),
> 0);
>     }
> 
>     tb->signal_insert().connect(sigc::ptr_fun(on_cxx_insert));
>     tb->signal_erase().connect(sigc::ptr_fun(on_cxx_erase));
> 
>     tb->set_text("This is a text");
>     Gtk::TextIter start = tb->get_iter_at_offset(5), end =
> tb->get_iter_at_offset(8);
>     tb->erase(start, end);
>     std::cout << "Result = " << tb->get_text() << std::endl;
> 
>     return 0;
> }
> 
> And a result:
> [mrcashe@home test]$ ./test
> on_c_insert(): pos = 0
> on_cxx_insert(): pos = 14
> on_c_erase(): start = 5, end = 8
> on_cxx_erase(): start = 5, end = 5
> Result = This a text
> 
> As You can see, gtk callbacks (written in C) works properly, but
> corresponding gtkmm (C++) slots works improperly - iterator positions
> are wrong. I think, gtk backend doing actual work and changing
> iterators somehow, after that C++ slots getting that changed
> iterators. 
> Of course, it isn't too hard to wrap C callbacks that manner as in my
> above code, but it looks nasty. Have authors some ideas how to resolve
> it?
> 
> Thanks.
> 
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtkmm-list




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