]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/textctrl.cpp
added wxWindow::IsFrozen() (only existed in wxMSW and wxDFB before)
[wxWidgets.git] / src / gtk / textctrl.cpp
index 07b729c9cddc27fe428a76db9cdb6b9fbac28fa9..703ceccd9c7b18bb529d1ba1ec6712a73dc436c7 100644 (file)
 #include "wx/gtk/private.h"
 #include <gdk/gdkkeysyms.h>
 
-//-----------------------------------------------------------------------------
-// data
-//-----------------------------------------------------------------------------
-
-extern wxWindowGTK *g_delayedFocus;
-
 // ----------------------------------------------------------------------------
 // helpers
 // ----------------------------------------------------------------------------
@@ -812,6 +806,24 @@ wxString wxTextCtrl::GetValue() const
     return tmp;
 }
 
+wxFontEncoding wxTextCtrl::GetTextEncoding() const
+{
+    // GTK+ uses UTF-8 internally, we need to convert to it but from which
+    // encoding?
+
+    // first check the default text style (we intentionally don't check the
+    // style for the current position as it doesn't make sense for SetValue())
+    const wxTextAttr& style = GetDefaultStyle();
+    wxFontEncoding enc = style.HasFont() ? style.GetFont().GetEncoding()
+                                         : wxFONTENCODING_SYSTEM;
+
+    // fall back to the controls font if no style
+    if ( enc == wxFONTENCODING_SYSTEM && m_hasFont )
+        enc = GetFont().GetEncoding();
+
+    return enc;
+}
+
 void wxTextCtrl::SetValue( const wxString &value )
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
@@ -825,10 +837,12 @@ void wxTextCtrl::SetValue( const wxString &value )
 
     if ( IsMultiLine() )
     {
-        const wxCharBuffer buffer(wxGTK_CONV(value));
+        const wxCharBuffer buffer(wxGTK_CONV_ENC(value, GetTextEncoding()));
         if ( !buffer )
         {
-            // what else can we do? at least don't crash...
+            // see comment in WriteText() as to why we must warn the user about
+            // this
+            wxLogWarning(_("Failed to set text in the text control."));
             return;
         }
 
@@ -839,10 +853,11 @@ void wxTextCtrl::SetValue( const wxString &value )
     }
     else // single line
     {
-        // gtk_entry_set_text() emits two "changed" signals because internally
-        // it calls gtk_editable_delete_text() and gtk_editable_insert_text()
-        // but we want to have only one event
-        IgnoreNextTextUpdate();
+        // gtk_entry_set_text() emits two "changed" signals if the control is
+        // not empty because internally it calls gtk_editable_delete_text() and
+        // gtk_editable_insert_text() but we want to have only one event
+        if ( !GetValue().empty() )
+            IgnoreNextTextUpdate();
 
         gtk_entry_set_text( GTK_ENTRY(m_text), wxGTK_CONV(value) );
     }
@@ -860,10 +875,24 @@ void wxTextCtrl::WriteText( const wxString &text )
     if ( text.empty() )
         return;
 
-    const wxCharBuffer buffer(wxGTK_CONV(text));
+    // check if we have a specific style for the current position
+    wxFontEncoding enc = wxFONTENCODING_SYSTEM;
+    wxTextAttr style;
+    if ( GetStyle(GetInsertionPoint(), style) && style.HasFont() )
+    {
+        enc = style.GetFont().GetEncoding();
+    }
+
+    if ( enc == wxFONTENCODING_SYSTEM )
+        enc = GetTextEncoding();
+
+    const wxCharBuffer buffer(wxGTK_CONV_ENC(text, enc));
     if ( !buffer )
     {
-        // what else can we do? at least don't crash...
+        // we must log an error here as losing the text like this can be a
+        // serious problem (e.g. imagine the document edited by user being
+        // empty instead of containing the correct text)
+        wxLogWarning(_("Failed to insert text in the control."));
         return;
     }
 
@@ -1513,15 +1542,16 @@ GtkWidget* wxTextCtrl::GetConnectWidget()
     return GTK_WIDGET(m_text);
 }
 
-bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxTextCtrl::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
     if ( IsMultiLine() )
     {
-        return window == gtk_text_view_get_window( GTK_TEXT_VIEW( m_text ), GTK_TEXT_WINDOW_TEXT );  // pure guesswork
+        return gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
+                                        GTK_TEXT_WINDOW_TEXT );
     }
     else
     {
-        return (window == GTK_ENTRY(m_text)->text_area);
+        return GTK_ENTRY(m_text)->text_area;
     }
 }
 
@@ -1683,24 +1713,6 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
     event.Enable( CanRedo() );
 }
 
-void wxTextCtrl::OnInternalIdle()
-{
-    // Check if we have to show window now
-    if (GtkShowFromOnIdle()) return;
-
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            gtk_widget_grab_focus( m_widget );
-            g_delayedFocus = NULL;
-        }
-    }
-    
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
 wxSize wxTextCtrl::DoGetBestSize() const
 {
     // FIXME should be different for multi-line controls...
@@ -1805,6 +1817,18 @@ void wxTextCtrl::OnUrlMouseEvent(wxMouseEvent& event)
     GetEventHandler()->ProcessEvent(url_event);
 }
 
+bool wxTextCtrl::GTKProcessEvent(wxEvent& event) const
+{
+    bool rc = wxTextCtrlBase::GTKProcessEvent(event);
+
+    // GtkTextView starts a drag operation when left mouse button is pressed
+    // and ends it when it is released and if it doesn't get the release event
+    // the next click on a control results in an assertion failure inside
+    // gtk_text_view_start_selection_drag() which simply *kills* the program
+    // without anything we can do about it, so always let GTK+ have this event
+    return rc && (IsSingleLine() || event.GetEventType() != wxEVT_LEFT_UP);
+}
+
 // static
 wxVisualAttributes
 wxTextCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))