Hi,
I really need to implement "max length" in multiline wxTextCtrl on GTK.
Documentation says:
Note that in wxGTK this function may only be used with single line
text controls.
I am wondering why, i can't find any mail thread from past that discusses
why
is complex/impossible.
So i've tried to implement First try:
Bind(wxEVT_COMMAND_TEXT_UPDATED,
&eagent_messenger_message_dlg::on_text_change,
this);
(...)
void on_text_change(wxCommandEvent& ev)
{
wxString s = this->main_text_ctrl->GetValue();
if( s.size() > 100 ) {
s = s.substr(0,100);
this->main_text_ctrl->SetValue(s); HERE!!!
}
}
I've tried also with "Remove" (in same code):
this->main_text_ctrl->Remove(max,
this->main_text_ctrl->GetLastPosition());
I've tried also doing it directly via GTK in wxTextCtrl:
bool wxTextCtrl::Create( wxWindow *parent,...)
{
(...)
g_signal_connect(G_OBJECT( m_buffer ), "changed",
G_CALLBACK( textview_buffer_changed_callback ), this );
}
void textview_buffer_changed_callback (
GtkTextBuffer *buffer,
gpointer user_data)
{
(...)
if( current_buffer_length > MAX_BUFFER_LENGTH {
GtkTextIter start;
GtkTextIter end;
gtk_text_buffer_get_iter_at_offset( buffer,
&start,
MAX_BUFFER_LENGTH );
gtk_text_buffer_get_iter_at_offset( buffer,
&end,
current_buffer_length );
gtk_text_buffer_delete( buffer, &start, &end );
}
}
Everything crashes in more or less same manner:
First, GTK asserts:
(messenger:10788): Gtk-WARNING **: Invalid text buffer iterator: either the
iterator is
uninitialized, or the characters/pixbufs/widgets in the buffer have been
modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a
position
across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can
be referred to by character offset)
will invalidate all outstanding iterators
Then *au_insert_text_callback* tries to dereference invalid iterator:
Program received signal SIGSEGV, Segmentation fault.
0x003175af in ?? () from /usr/lib/libgtk-x11-2.0.so.0
(gdb) bt
#1 0x0031aa10 in gtk_text_iter_backward_chars ()
from /usr/lib/libgtk-x11-2.0.so.0
#2 0x080e5590 in au_insert_text_callback (end=0xbfffeab8, text=0x8374d10
"this->
main_text_ctrl->GetValue();", len=33, win=0x827adc0) at
./src/gtk/textctrl.cpp:477
#3 0x002668b6 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
(...)
#31 0x0095392b in g_main_loop_run () from
/lib/i386-linux-gnu/libglib-2.0.so.0
#32 0x00261c39 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
#33 0x08135e79 in wxGUIEventLoop::Run (this=0x83100f0) at
./src/gtk/evtloop.cpp:60
#34 0x080e0915 in wxDialog::ShowModal (this=0x8241018) at
./src/gtk/dialog.cpp:133
#35 0x0806a31f in eagent_messenger_app::OnInit (this=0x8206a38) at
messages/messenger.c
(full listing: http://pastebin.com/CuDMh476)
Now the issue: what i am missing here, i don't understand fully
"wxGTK event architecture" but it looks like GTK "changed" and
wxEVT_COMMAND_TEXT_UPDATED are spawned with queue full of other
signals already queued. And moreover, those signals contain gtk text
buffer iterators which are invalidated by my operation (be it SetValue,
Remove, gtk_text_buffer_delete).
Any ideas where shall continue searching for solution ?
Now i will try randomly:
1) disabling URL highliht
2) trying to fix au_insert_text_callback, so it doesn't dereference
received
iterator
3) reorder/cancel queued signals ? is this possible ?
BR,
Zbyszek