}
}
+//-----------------------------------------------------------------------------
+// "populate_popup" from text control and "unmap" from its poup menu
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static void
+gtk_textctrl_popup_unmap( GtkMenu *WXUNUSED(menu), wxTextCtrl* win )
+{
+ win->GTKEnableFocusOutEvent();
+}
+}
+
+extern "C" {
+static void
+gtk_textctrl_populate_popup( GtkEntry *WXUNUSED(entry), GtkMenu *menu, wxTextCtrl *win )
+{
+ win->GTKDisableFocusOutEvent();
+
+ g_signal_connect (menu, "unmap", G_CALLBACK (gtk_textctrl_popup_unmap), win );
+}
+}
//-----------------------------------------------------------------------------
// "changed"
extern "C" {
static void
-gtk_text_changed_callback( GtkWidget * WXUNUSED(widget), wxTextCtrl *win )
+gtk_text_changed_callback( GtkWidget *WXUNUSED(widget), wxTextCtrl *win )
{
if ( win->IgnoreTextUpdate() )
return;
{
wxClipboardTextEvent event( eventType, win->GetId() );
event.SetEventObject( win );
- if ( win->GetEventHandler()->ProcessEvent( event ) )
+ if ( win->HandleWindowEvent( event ) )
{
// don't let the default processing to take place if we did something
// ourselves in the event handler
}
}
-//-----------------------------------------------------------------------------
-// "expose_event" from scrolled window and textview
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static gboolean
-gtk_text_exposed_callback( GtkWidget * WXUNUSED(widget),
- GdkEventExpose * WXUNUSED(event),
- wxTextCtrl * WXUNUSED(win) )
-{
- return TRUE;
-}
-}
-
-
//-----------------------------------------------------------------------------
// wxTextCtrl
//-----------------------------------------------------------------------------
SetUpdateFont(false);
m_text = NULL;
- m_freezeCount = 0;
m_showPositionOnThaw = NULL;
m_gdkHandCursor = NULL;
m_gdkXTermCursor = NULL;
if (style & wxNO_BORDER)
g_object_set (m_text, "has-frame", FALSE, NULL);
+
}
+ g_object_ref(m_widget);
m_parent->DoAddChild( this );
G_CALLBACK (gtk_text_changed_callback), this);
}
+ // Catch to disable focus out handling
+ g_signal_connect (m_text, "populate_popup",
+ G_CALLBACK (gtk_textctrl_populate_popup),
+ this);
+
if (!value.empty())
{
SetValue( value );
if (style & wxTE_READONLY)
GTKSetEditable();
- if (style & wxTE_PROCESS_ENTER)
- GTKSetActivatesDefault();
-
// left justification (alignment) is the default anyhow
if ( style & (wxTE_RIGHT | wxTE_CENTRE) )
GTKSetJustification();
au_check_range(&start, &end);
}
}
+ else // single line
+ {
+ // do the right thing with Enter presses depending on whether we have
+ // wxTE_PROCESS_ENTER or not
+ GTKSetActivatesDefault();
+ }
+
g_signal_connect (m_text, "copy-clipboard",
G_CALLBACK (gtk_copy_clipboard_callback), this);
return;
}
+ if (value.IsEmpty())
+ {
+ if ( !(flags & SetValue_SendEvent) )
+ EnableTextChangedEvents(false);
+
+ gtk_text_buffer_set_text( m_buffer, "", 0 );
+
+ if ( !(flags & SetValue_SendEvent) )
+ EnableTextChangedEvents(true);
+
+ return;
+ }
+
+#if wxUSE_UNICODE
+ const wxCharBuffer buffer(value.utf8_str());
+#else
wxFontEncoding enc = m_defaultStyle.HasFont()
? m_defaultStyle.GetFont().GetEncoding()
: wxFONTENCODING_SYSTEM;
wxLogWarning(_("Failed to set text in the text control."));
return;
}
+#endif
if ( !(flags & SetValue_SendEvent) )
{
{
EnableTextChangedEvents(true);
}
-
- // This was added after discussion on the list
- SetInsertionPoint(0);
}
void wxTextCtrl::WriteText( const wxString &text )
return;
}
+#if wxUSE_UNICODE
+ const wxCharBuffer buffer(text.utf8_str());
+#else
// check if we have a specific style for the current position
wxFontEncoding enc = wxFONTENCODING_SYSTEM;
wxTextAttr style;
wxLogWarning(_("Failed to insert text in the control."));
return;
}
+#endif
// First remove the selection if there is one
// TODO: Is there an easier GTK specific way to do this?
gtk_text_buffer_get_iter_at_offset( m_buffer, &fromi, from );
gtk_text_buffer_get_iter_at_offset( m_buffer, &toi, to );
- gtk_text_buffer_place_cursor( m_buffer, &toi );
+ gtk_text_buffer_place_cursor( m_buffer, &fromi );
gtk_text_buffer_move_mark_by_name( m_buffer, "selection_bound", &fromi );
}
else // single line
wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
event.SetEventObject(this);
event.SetString(GetValue());
- if ( GetEventHandler()->ProcessEvent(event) )
+ if ( HandleWindowEvent(event) )
return;
}
}
// freeze/thaw
// ----------------------------------------------------------------------------
-void wxTextCtrl::Freeze()
+void wxTextCtrl::DoFreeze()
{
wxCHECK_RET(m_text != NULL, wxT("invalid text ctrl"));
+ wxWindow::DoFreeze();
+
if ( HasFlag(wxTE_MULTILINE) )
{
- if (m_freezeCount++ == 0)
- {
- // freeze textview updates and remove buffer
- g_signal_connect (m_text, "expose_event",
- G_CALLBACK (gtk_text_exposed_callback), this);
- g_signal_connect (m_widget, "expose_event",
- G_CALLBACK (gtk_text_exposed_callback), this);
- gtk_widget_set_sensitive(m_widget, false);
- g_object_ref(m_buffer);
- GtkTextBuffer* buf_new = gtk_text_buffer_new(NULL);
- GtkTextMark* mark = GTK_TEXT_VIEW(m_text)->first_para_mark;
- gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_text), buf_new);
- // gtk_text_view_set_buffer adds its own reference
- g_object_unref(buf_new);
- // This mark should be deleted when the buffer is changed,
- // but it's not (in GTK+ up to at least 2.10.6).
- // Otherwise these anonymous marks start to build up in the buffer,
- // and Freeze takes longer and longer each time it is called.
- if (GTK_IS_TEXT_MARK(mark) && !gtk_text_mark_get_deleted(mark))
- gtk_text_buffer_delete_mark(m_buffer, mark);
- }
+ GTKFreezeWidget(m_text);
+
+ // removing buffer dramatically speeds up insertion:
+ g_object_ref(m_buffer);
+ GtkTextBuffer* buf_new = gtk_text_buffer_new(NULL);
+ GtkTextMark* mark = GTK_TEXT_VIEW(m_text)->first_para_mark;
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_text), buf_new);
+ // gtk_text_view_set_buffer adds its own reference
+ g_object_unref(buf_new);
+ // This mark should be deleted when the buffer is changed,
+ // but it's not (in GTK+ up to at least 2.10.6).
+ // Otherwise these anonymous marks start to build up in the buffer,
+ // and Freeze takes longer and longer each time it is called.
+ if (GTK_IS_TEXT_MARK(mark) && !gtk_text_mark_get_deleted(mark))
+ gtk_text_buffer_delete_mark(m_buffer, mark);
}
}
-void wxTextCtrl::Thaw()
+void wxTextCtrl::DoThaw()
{
if ( HasFlag(wxTE_MULTILINE) )
{
- wxCHECK_RET(m_freezeCount != 0, _T("Thaw() without matching Freeze()"));
+ // reattach buffer:
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_text), m_buffer);
+ g_object_unref(m_buffer);
- if (--m_freezeCount == 0)
+ if (m_showPositionOnThaw != NULL)
{
- // Reattach buffer and thaw textview updates
- gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_text), m_buffer);
- g_object_unref(m_buffer);
- gtk_widget_set_sensitive(m_widget, true);
- g_signal_handlers_disconnect_by_func (m_widget,
- (gpointer) gtk_text_exposed_callback, this);
- g_signal_handlers_disconnect_by_func (m_text,
- (gpointer) gtk_text_exposed_callback, this);
- if (m_showPositionOnThaw != NULL)
- {
- gtk_text_view_scroll_mark_onscreen(
- GTK_TEXT_VIEW(m_text), m_showPositionOnThaw);
- m_showPositionOnThaw = NULL;
- }
+ gtk_text_view_scroll_mark_onscreen(
+ GTK_TEXT_VIEW(m_text), m_showPositionOnThaw);
+ m_showPositionOnThaw = NULL;
}
+
+ // and thaw the window
+ GTKThawWidget(m_text);
}
+
+ wxWindow::DoThaw();
}
// ----------------------------------------------------------------------------
InitCommandEvent(url_event);
// Is that a good idea? Seems not (pleasure with gtk_text_view_start_selection_drag)
- //event.Skip(!GetEventHandler()->ProcessEvent(url_event));
- GetEventHandler()->ProcessEvent(url_event);
+ //event.Skip(!HandleWindowEvent(url_event));
+ HandleWindowEvent(url_event);
}
bool wxTextCtrl::GTKProcessEvent(wxEvent& event) const