+ if ( fromOut )
+ *fromOut = from;
+ if ( toOut )
+ *toOut = to;
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+ wxCHECK_MSG( m_text != NULL, FALSE, wxT("invalid text ctrl") );
+
+ return GTK_EDITABLE(m_text)->editable;
+}
+
+bool wxTextCtrl::IsModified() const
+{
+ return m_modified;
+}
+
+void wxTextCtrl::Clear()
+{
+ SetValue( wxT("") );
+}
+
+void wxTextCtrl::OnChar( wxKeyEvent &key_event )
+{
+ wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
+
+ if ((key_event.KeyCode() == WXK_RETURN) && (m_windowStyle & wxPROCESS_ENTER))
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+ event.SetEventObject(this);
+ event.SetString(GetValue());
+ if (GetEventHandler()->ProcessEvent(event)) return;
+ }
+
+ if ((key_event.KeyCode() == WXK_RETURN) && !(m_windowStyle & wxTE_MULTILINE))
+ {
+ wxWindow *top_frame = m_parent;
+ while (top_frame->GetParent() && !(top_frame->IsTopLevel()))
+ top_frame = top_frame->GetParent();
+ GtkWindow *window = GTK_WINDOW(top_frame->m_widget);
+
+ if (window->default_widget)
+ {
+ gtk_widget_activate (window->default_widget);
+ return;
+ }
+ }
+
+ key_event.Skip();
+}
+
+GtkWidget* wxTextCtrl::GetConnectWidget()
+{
+ return GTK_WIDGET(m_text);
+}
+
+bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window )
+{
+ if (m_windowStyle & wxTE_MULTILINE)
+ return (window == GTK_TEXT(m_text)->text_area);
+ else
+ return (window == GTK_ENTRY(m_text)->text_area);
+}
+
+// the font will change for subsequent text insertiongs
+bool wxTextCtrl::SetFont( const wxFont &font )
+{
+ wxCHECK_MSG( m_text != NULL, FALSE, wxT("invalid text ctrl") );
+
+ if ( !wxWindowBase::SetFont(font) )
+ {
+ // font didn't change, nothing to do
+ return FALSE;
+ }
+
+ if ( m_windowStyle & wxTE_MULTILINE )
+ {
+ m_updateFont = TRUE;
+
+ m_defaultStyle.SetFont(font);
+
+ ChangeFontGlobally();
+ }
+
+ return TRUE;
+}
+
+void wxTextCtrl::ChangeFontGlobally()
+{
+ // this method is very inefficient and hence should be called as rarely as
+ // possible!
+ wxASSERT_MSG( (m_windowStyle & wxTE_MULTILINE) && m_updateFont,
+ _T("shouldn't be called for single line controls") );
+
+ wxString value = GetValue();
+ if ( !value.IsEmpty() )
+ {
+ m_updateFont = FALSE;
+
+ Clear();
+ AppendText(value);
+ }
+}
+
+void wxTextCtrl::UpdateFontIfNeeded()
+{
+ if ( m_updateFont )
+ ChangeFontGlobally();
+}
+
+bool wxTextCtrl::SetForegroundColour(const wxColour& colour)
+{
+ if ( !wxControl::SetForegroundColour(colour) )
+ return FALSE;
+
+ // update default fg colour too
+ m_defaultStyle.SetTextColour(colour);
+
+ return TRUE;
+}
+
+bool wxTextCtrl::SetBackgroundColour( const wxColour &colour )
+{
+ wxCHECK_MSG( m_text != NULL, FALSE, wxT("invalid text ctrl") );
+
+ if ( !wxControl::SetBackgroundColour( colour ) )
+ return FALSE;
+
+ if (!m_widget->window)
+ return FALSE;
+
+ wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
+ if (sysbg.Red() == colour.Red() &&
+ sysbg.Green() == colour.Green() &&
+ sysbg.Blue() == colour.Blue())
+ {
+ return FALSE; // FIXME or TRUE?
+ }
+
+ if (!m_backgroundColour.Ok())
+ return FALSE;
+
+ if (m_windowStyle & wxTE_MULTILINE)
+ {
+ GdkWindow *window = GTK_TEXT(m_text)->text_area;
+ if (!window)
+ return FALSE;
+ m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) );
+ gdk_window_set_background( window, m_backgroundColour.GetColor() );
+ gdk_window_clear( window );
+ }
+
+ // change active background color too
+ m_defaultStyle.SetBackgroundColour( colour );
+
+ return TRUE;
+}
+
+bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr &style )
+{
+ /* VERY dirty way to do that - removes the required text and re-adds it
+ with styling (FIXME) */
+ if ( m_windowStyle & wxTE_MULTILINE )
+ {
+ if ( style.IsDefault() )
+ {
+ // nothing to do
+ return TRUE;
+ }
+
+ gint l = gtk_text_get_length( GTK_TEXT(m_text) );
+
+ wxCHECK_MSG( start >= 0 && end <= l, FALSE,
+ _T("invalid range in wxTextCtrl::SetStyle") );
+
+ gint old_pos = gtk_editable_get_position( GTK_EDITABLE(m_text) );
+ char *text = gtk_editable_get_chars( GTK_EDITABLE(m_text), start, end );
+ wxString tmp(text,*wxConvCurrent);
+ g_free( text );
+
+ gtk_editable_delete_text( GTK_EDITABLE(m_text), start, end );
+ gtk_editable_set_position( GTK_EDITABLE(m_text), start );
+
+#if wxUSE_UNICODE
+ wxWX2MBbuf buf = tmp.mbc_str();
+ const char *txt = buf;
+ size_t txtlen = strlen(buf);