]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/textctrl.cpp
check for wxInputStream::Read errors
[wxWidgets.git] / src / gtk / textctrl.cpp
index e511ce39c31121edc0e3f637449b66c4d44f366b..11d4eab71665d5e419edc733098c6fe0077b3a65 100644 (file)
@@ -149,7 +149,7 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text,
                                           gtk_text_iter_get_line(start) );
         gtk_text_iter_forward_line(&para_end);
 
-        wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXALIGNMENT", start, end);
+        wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXALIGNMENT", &para_start, &para_end);
 
         GtkJustification align;
         switch (attr.GetAlignment())
@@ -195,7 +195,7 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text,
                                           gtk_text_iter_get_line(start) );
         gtk_text_iter_forward_line(&para_end);
 
-        wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXINDENT", start, end);
+        wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXINDENT", &para_start, &para_end);
 
         // Convert indent from 1/10th of a mm into pixels
         float factor =
@@ -239,7 +239,7 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text,
                                           gtk_text_iter_get_line(start) );
         gtk_text_iter_forward_line(&para_end);
 
-        wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXTABS", start, end);
+        wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXTABS", &para_start, &para_end);
 
         const wxArrayInt& tabs = attr.GetTabs();
 
@@ -494,6 +494,27 @@ au_delete_range_callback(GtkTextBuffer * WXUNUSED(buffer),
 }
 }
 
+//-----------------------------------------------------------------------------
+//  "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"
@@ -501,7 +522,7 @@ au_delete_range_callback(GtkTextBuffer * WXUNUSED(buffer),
 
 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;
@@ -557,21 +578,6 @@ gtk_paste_clipboard_callback( GtkWidget *widget, wxTextCtrl *win )
 }
 }
 
-//-----------------------------------------------------------------------------
-// "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
 //-----------------------------------------------------------------------------
@@ -614,7 +620,6 @@ void wxTextCtrl::Init()
     SetUpdateFont(false);
 
     m_text = NULL;
-    m_freezeCount = 0;
     m_showPositionOnThaw = NULL;
     m_gdkHandCursor = NULL;
     m_gdkXTermCursor = NULL;
@@ -701,7 +706,9 @@ bool wxTextCtrl::Create( wxWindow *parent,
 
         if (style & wxNO_BORDER)
             g_object_set (m_text, "has-frame", FALSE, NULL);
+
     }
+    g_object_ref(m_widget);
 
     m_parent->DoAddChild( this );
 
@@ -726,6 +733,11 @@ bool wxTextCtrl::Create( wxWindow *parent,
                           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 );
@@ -970,6 +982,22 @@ void wxTextCtrl::DoSetValue( const wxString &value, int flags )
         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;
@@ -984,6 +1012,7 @@ void wxTextCtrl::DoSetValue( const wxString &value, int flags )
         wxLogWarning(_("Failed to set text in the text control."));
         return;
     }
+#endif
 
     if ( !(flags & SetValue_SendEvent) )
     {
@@ -1004,9 +1033,6 @@ void wxTextCtrl::DoSetValue( const wxString &value, int flags )
     {
         EnableTextChangedEvents(true);
     }
-
-    // This was added after discussion on the list
-    SetInsertionPoint(0);
 }
 
 void wxTextCtrl::WriteText( const wxString &text )
@@ -1022,6 +1048,9 @@ 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;
@@ -1042,6 +1071,7 @@ void wxTextCtrl::WriteText( const wxString &text )
         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?
@@ -1222,6 +1252,7 @@ bool wxTextCtrl::Enable( bool enable )
     }
 
     gtk_widget_set_sensitive( m_text, enable );
+    SetCursor(enable ? wxCursor(wxCURSOR_IBEAM) : wxCursor());
 
     return true;
 }
@@ -1314,8 +1345,7 @@ void wxTextCtrl::SetSelection( long from, long to )
         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_move_mark_by_name( m_buffer, "selection_bound", &fromi );
+        gtk_text_buffer_select_range( m_buffer, &fromi, &toi );
     }
     else // single line
     {
@@ -1718,60 +1748,52 @@ wxSize wxTextCtrl::DoGetBestSize() const
 // 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();
 }
 
 // ----------------------------------------------------------------------------