]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/textctrl.cpp
Warning fix.
[wxWidgets.git] / src / gtk / textctrl.cpp
index 1443e5777904aa768abd5e7c4a15dc004f7bf2a0..1c599667a9ac6ece15be13356aa5735e60904aa3 100644 (file)
@@ -787,7 +787,7 @@ wxString wxTextCtrl::GetValue() const
     wxCHECK_MSG( m_text != NULL, wxEmptyString, wxT("invalid text ctrl") );
 
     wxString tmp;
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter start;
         gtk_text_buffer_get_start_iter( m_buffer, &start );
@@ -812,6 +812,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") );
@@ -823,9 +841,9 @@ void wxTextCtrl::SetValue( const wxString &value )
     m_modified = false;
     DontMarkDirtyOnNextChange();
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    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...
@@ -860,17 +878,31 @@ 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;
     }
 
     // we're changing the text programmatically
     DontMarkDirtyOnNextChange();
 
-    if ( m_windowStyle & wxTE_MULTILINE )
+    if ( IsMultiLine() )
     {
         // First remove the selection if there is one
         // TODO:  Is there an easier GTK specific way to do this?
@@ -913,7 +945,7 @@ void wxTextCtrl::AppendText( const wxString &text )
 
 wxString wxTextCtrl::GetLineText( long lineNo ) const
 {
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter line;
         gtk_text_buffer_get_iter_at_line(m_buffer,&line,lineNo);
@@ -940,9 +972,13 @@ void wxTextCtrl::OnDropFiles( wxDropFilesEvent &WXUNUSED(event) )
 
 bool wxTextCtrl::PositionToXY(long pos, long *x, long *y ) const
 {
-    if ( m_windowStyle & wxTE_MULTILINE )
+    if ( IsMultiLine() )
     {
         GtkTextIter iter;
+
+        if (pos > GetLastPosition())
+            return false;
+
         gtk_text_buffer_get_iter_at_offset(m_buffer, &iter, pos);
 
         if ( y )
@@ -971,7 +1007,8 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y ) const
 
 long wxTextCtrl::XYToPosition(long x, long y ) const
 {
-    if (!(m_windowStyle & wxTE_MULTILINE)) return 0;
+    if ( IsSingleLine() )
+        return 0;
 
     GtkTextIter iter;
     if (y >= gtk_text_buffer_get_line_count (m_buffer))
@@ -986,7 +1023,7 @@ long wxTextCtrl::XYToPosition(long x, long y ) const
 
 int wxTextCtrl::GetLineLength(long lineNo) const
 {
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         int last_line = gtk_text_buffer_get_line_count( m_buffer ) - 1;
         if (lineNo > last_line)
@@ -1006,7 +1043,7 @@ int wxTextCtrl::GetLineLength(long lineNo) const
 
 int wxTextCtrl::GetNumberOfLines() const
 {
-    if ( m_windowStyle & wxTE_MULTILINE )
+    if ( IsMultiLine() )
     {
         GtkTextIter iter;
         gtk_text_buffer_get_iter_at_offset( m_buffer, &iter, 0 );
@@ -1066,7 +1103,7 @@ void wxTextCtrl::SetInsertionPointEnd()
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter end;
         gtk_text_buffer_get_end_iter( m_buffer, &end );
@@ -1082,7 +1119,7 @@ void wxTextCtrl::SetEditable( bool editable )
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         gtk_text_view_set_editable( GTK_TEXT_VIEW(m_text), editable );
     }
@@ -1100,7 +1137,7 @@ bool wxTextCtrl::Enable( bool enable )
         return false;
     }
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         SetEditable( enable );
     }
@@ -1208,7 +1245,7 @@ void wxTextCtrl::SetSelection( long from, long to )
         to = GetValue().length();
     }
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter fromi, toi;
         gtk_text_buffer_get_iter_at_offset( m_buffer, &fromi, from );
@@ -1225,7 +1262,7 @@ void wxTextCtrl::SetSelection( long from, long to )
 
 void wxTextCtrl::ShowPosition( long pos )
 {
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter iter;
         gtk_text_buffer_get_start_iter( m_buffer, &iter );
@@ -1265,7 +1302,7 @@ long wxTextCtrl::GetInsertionPoint() const
 {
     wxCHECK_MSG( m_text != NULL, 0, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         // There is no direct accessor for the cursor, but
         // internally, the cursor is the "mark" called
@@ -1289,7 +1326,7 @@ wxTextPos wxTextCtrl::GetLastPosition() const
 
     int pos = 0;
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter end;
         gtk_text_buffer_get_end_iter( m_buffer, &end );
@@ -1308,7 +1345,7 @@ void wxTextCtrl::Remove( long from, long to )
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         GtkTextIter fromi, toi;
         gtk_text_buffer_get_iter_at_offset( m_buffer, &fromi, from );
@@ -1337,7 +1374,7 @@ void wxTextCtrl::Cut()
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
         g_signal_emit_by_name (m_text, "cut-clipboard");
     else
         gtk_editable_cut_clipboard(GTK_EDITABLE(m_text));
@@ -1347,7 +1384,7 @@ void wxTextCtrl::Copy()
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
         g_signal_emit_by_name (m_text, "copy-clipboard");
     else
         gtk_editable_copy_clipboard(GTK_EDITABLE(m_text));
@@ -1357,7 +1394,7 @@ void wxTextCtrl::Paste()
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
         g_signal_emit_by_name (m_text, "paste-clipboard");
     else
         gtk_editable_paste_clipboard(GTK_EDITABLE(m_text));
@@ -1400,7 +1437,7 @@ void wxTextCtrl::GetSelection(long* fromOut, long* toOut) const
     gint to = -1;
     bool haveSelection = false;
 
-     if (m_windowStyle & wxTE_MULTILINE)
+     if ( IsMultiLine() )
      {
          GtkTextIter ifrom, ito;
          if ( gtk_text_buffer_get_selection_bounds(m_buffer, &ifrom, &ito) )
@@ -1441,7 +1478,7 @@ bool wxTextCtrl::IsEditable() const
 {
     wxCHECK_MSG( m_text != NULL, false, wxT("invalid text ctrl") );
 
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         return gtk_text_view_get_editable(GTK_TEXT_VIEW(m_text));
     }
@@ -1465,31 +1502,37 @@ void wxTextCtrl::OnChar( wxKeyEvent &key_event )
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if ((key_event.GetKeyCode() == WXK_RETURN) && (m_windowStyle & wxTE_PROCESS_ENTER))
-    {
-        wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
-        event.SetEventObject(this);
-        event.SetString(GetValue());
-        if (GetEventHandler()->ProcessEvent(event)) return;
-    }
-
-    if ((key_event.GetKeyCode() == WXK_RETURN) && !(m_windowStyle & wxTE_MULTILINE))
+    if ( key_event.GetKeyCode() == WXK_RETURN )
     {
-        // This will invoke the dialog default action, such
-        // as the clicking the default button.
-
-        wxWindow *top_frame = m_parent;
-        while (top_frame->GetParent() && !(top_frame->IsTopLevel()))
-            top_frame = top_frame->GetParent();
+        if ( HasFlag(wxTE_PROCESS_ENTER) )
+        {
+            wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+            event.SetEventObject(this);
+            event.SetString(GetValue());
+            if ( GetEventHandler()->ProcessEvent(event) )
+                return;
+        }
 
-        if (top_frame && GTK_IS_WINDOW(top_frame->m_widget))
+        // FIXME: this is not the right place to do it, wxDialog::OnCharHook()
+        //        probably is
+        if ( IsSingleLine() )
         {
-            GtkWindow *window = GTK_WINDOW(top_frame->m_widget);
+            // This will invoke the dialog default action, such
+            // as the clicking the default button.
 
-            if (window->default_widget)
+            wxWindow *top_frame = m_parent;
+            while (top_frame->GetParent() && !(top_frame->IsTopLevel()))
+                top_frame = top_frame->GetParent();
+
+            if (top_frame && GTK_IS_WINDOW(top_frame->m_widget))
             {
-                gtk_widget_activate (window->default_widget);
-                return;
+                GtkWindow *window = GTK_WINDOW(top_frame->m_widget);
+
+                if (window->default_widget)
+                {
+                    gtk_widget_activate (window->default_widget);
+                    return;
+                }
             }
         }
     }
@@ -1504,7 +1547,7 @@ GtkWidget* wxTextCtrl::GetConnectWidget()
 
 bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window )
 {
-    if (m_windowStyle & wxTE_MULTILINE)
+    if ( IsMultiLine() )
     {
         return window == gtk_text_view_get_window( GTK_TEXT_VIEW( m_text ), GTK_TEXT_WINDOW_TEXT );  // pure guesswork
     }
@@ -1525,7 +1568,7 @@ bool wxTextCtrl::SetFont( const wxFont &font )
         return false;
     }
 
-    if ( m_windowStyle & wxTE_MULTILINE )
+    if ( IsMultiLine() )
     {
         SetUpdateFont(true);
 
@@ -1543,7 +1586,7 @@ void wxTextCtrl::ChangeFontGlobally()
     // possible!
     //
     // TODO: it can be implemented much more efficiently for GTK2
-    wxASSERT_MSG( (m_windowStyle & wxTE_MULTILINE),
+    wxASSERT_MSG( IsMultiLine(),
                   _T("shouldn't be called for single line controls") );
 
     wxString value = GetValue();
@@ -1585,7 +1628,7 @@ bool wxTextCtrl::SetBackgroundColour( const wxColour &colour )
 
 bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style )
 {
-    if ( m_windowStyle & wxTE_MULTILINE )
+    if ( IsMultiLine() )
     {
         if ( style.IsDefault() )
         {
@@ -1674,6 +1717,9 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
 
 void wxTextCtrl::OnInternalIdle()
 {
+    // Check if we have to show window now
+    if (GtkShowFromOnIdle()) return;
+
     if (g_delayedFocus == this)
     {
         if (GTK_WIDGET_REALIZED(m_widget))
@@ -1682,7 +1728,7 @@ void wxTextCtrl::OnInternalIdle()
             g_delayedFocus = NULL;
         }
     }
-
+    
     if (wxUpdateUIEvent::CanUpdate(this))
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
@@ -1748,7 +1794,7 @@ void wxTextCtrl::Thaw()
 void wxTextCtrl::OnUrlMouseEvent(wxMouseEvent& event)
 {
     event.Skip();
-    if(!(m_windowStyle & wxTE_AUTO_URL))
+    if( !HasFlag(wxTE_AUTO_URL) )
         return;
 
     gint x, y;