]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/textctrl.cpp
fixing modal dialog quit after nested message box problem
[wxWidgets.git] / src / gtk1 / textctrl.cpp
index e7117ec992340c7521204c1d717536e7cb5629cb..547c804242fe26610d2eabcae1ec81c78246a1d0 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        textctrl.cpp
+// Name:        src/gtk1/textctrl.cpp
 // Purpose:
 // Author:      Robert Roebling
 // Id:          $Id$
 // Purpose:
 // Author:      Robert Roebling
 // Id:          $Id$
 #include "wx/wxprec.h"
 
 #include "wx/textctrl.h"
 #include "wx/wxprec.h"
 
 #include "wx/textctrl.h"
-#include "wx/utils.h"
-#include "wx/intl.h"
-#include "wx/log.h"
-#include "wx/math.h"
-#include "wx/settings.h"
-#include "wx/panel.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
+    #include "wx/utils.h"
+    #include "wx/panel.h"
+    #include "wx/settings.h"
+    #include "wx/math.h"
+#endif
+
 #include "wx/strconv.h"
 #include "wx/fontutil.h"        // for wxNativeFontInfo (GetNativeFontInfo())
 #include "wx/strconv.h"
 #include "wx/fontutil.h"        // for wxNativeFontInfo (GetNativeFontInfo())
+#include "wx/evtloop.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <ctype.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <ctype.h>
-#include "wx/math.h"
 
 #include "wx/gtk1/private.h"
 #include <gdk/gdkkeysyms.h>
 
 #include "wx/gtk1/private.h"
 #include <gdk/gdkkeysyms.h>
@@ -52,8 +57,21 @@ static void wxGtkTextInsert(GtkWidget *text,
                             const char *txt,
                             size_t len)
 {
                             const char *txt,
                             size_t len)
 {
-    GdkFont *font = attr.HasFont() ? attr.GetFont().GetInternalFont()
-                                   : NULL;
+    wxFont tmpFont;
+    GdkFont *font;
+    if (attr.HasFont())
+    {
+        tmpFont = attr.GetFont();
+
+        // FIXME: if this crashes because tmpFont goes out of scope and the GdkFont is
+        // deleted, then we need to call gdk_font_ref on font.
+        // This is because attr.GetFont() now returns a temporary font since wxTextAttr
+        // no longer stores a wxFont object, for efficiency.
+
+        font = tmpFont.GetInternalFont();
+    }
+    else
+        font  = NULL;
 
     GdkColor *colFg = attr.HasTextColour() ? attr.GetTextColour().GetColor()
                                            : NULL;
 
     GdkColor *colFg = attr.HasTextColour() ? attr.GetTextColour().GetColor()
                                            : NULL;
@@ -73,9 +91,9 @@ static void wxGtkTextInsert(GtkWidget *text,
 extern "C" {
 static void
 gtk_insert_text_callback(GtkEditable *editable,
 extern "C" {
 static void
 gtk_insert_text_callback(GtkEditable *editable,
-                         const gchar *new_text,
-                         gint new_text_length,
-                         gint *position,
+                         const gchar *WXUNUSED(new_text),
+                         gint WXUNUSED(new_text_length),
+                         gint *WXUNUSED(position),
                          wxTextCtrl *win)
 {
     if (g_isIdle)
                          wxTextCtrl *win)
 {
     if (g_isIdle)
@@ -103,7 +121,7 @@ gtk_insert_text_callback(GtkEditable *editable,
         wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, win->GetId());
         event.SetEventObject(win);
         event.SetString(win->GetValue());
         wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, win->GetId());
         event.SetEventObject(win);
         event.SetString(win->GetValue());
-        win->GetEventHandler()->ProcessEvent( event );
+        win->HandleWindowEvent( event );
     }
 }
 }
     }
 }
 }
@@ -114,7 +132,7 @@ gtk_insert_text_callback(GtkEditable *editable,
 
 extern "C" {
 static void
 
 extern "C" {
 static void
-gtk_text_changed_callback( GtkWidget *widget, wxTextCtrl *win )
+gtk_text_changed_callback( GtkWidget *WXUNUSED(widget), wxTextCtrl *win )
 {
     if ( win->IgnoreTextUpdate() )
         return;
 {
     if ( win->IgnoreTextUpdate() )
         return;
@@ -129,7 +147,7 @@ gtk_text_changed_callback( GtkWidget *widget, wxTextCtrl *win )
 
     wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, win->GetId() );
     event.SetEventObject( win );
 
     wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, win->GetId() );
     event.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent( event );
+    win->HandleWindowEvent( event );
 }
 }
 
 }
 }
 
@@ -159,8 +177,6 @@ gtk_scrollbar_changed_callback( GtkWidget *WXUNUSED(widget), wxTextCtrl *win )
 // which implicitly calls wxYield()) so we override GtkText::draw() and simply
 // don't do anything if we're inside wxYield()
 
 // which implicitly calls wxYield()) so we override GtkText::draw() and simply
 // don't do anything if we're inside wxYield()
 
-extern bool wxIsInsideYield;
-
 extern "C" {
     typedef void (*GtkDrawCallback)(GtkWidget *widget, GdkRectangle *rect);
 }
 extern "C" {
     typedef void (*GtkDrawCallback)(GtkWidget *widget, GdkRectangle *rect);
 }
@@ -170,7 +186,8 @@ static GtkDrawCallback gs_gtk_text_draw = NULL;
 extern "C" {
 static void wxgtk_text_draw( GtkWidget *widget, GdkRectangle *rect)
 {
 extern "C" {
 static void wxgtk_text_draw( GtkWidget *widget, GdkRectangle *rect)
 {
-    if ( !wxIsInsideYield )
+    wxEventLoopBase* loop = wxEventLoopBase::GetActive();
+    if ( loop && !loop->IsYielding() )
     {
         wxCHECK_RET( gs_gtk_text_draw != wxgtk_text_draw,
                      _T("infinite recursion in wxgtk_text_draw aborted") );
     {
         wxCHECK_RET( gs_gtk_text_draw != wxgtk_text_draw,
                      _T("infinite recursion in wxgtk_text_draw aborted") );
@@ -184,9 +201,9 @@ static void wxgtk_text_draw( GtkWidget *widget, GdkRectangle *rect)
 //  wxTextCtrl
 //-----------------------------------------------------------------------------
 
 //  wxTextCtrl
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl,wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
 
 
-BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
     EVT_CHAR(wxTextCtrl::OnChar)
 
     EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
     EVT_CHAR(wxTextCtrl::OnChar)
 
     EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
@@ -208,7 +225,7 @@ void wxTextCtrl::Init()
     m_modified = false;
     SetUpdateFont(false);
     m_text =
     m_modified = false;
     SetUpdateFont(false);
     m_text =
-    m_vScrollbar = (GtkWidget *)NULL;
+    m_vScrollbar = NULL;
 }
 
 wxTextCtrl::~wxTextCtrl()
 }
 
 wxTextCtrl::~wxTextCtrl()
@@ -256,7 +273,7 @@ bool wxTextCtrl::Create( wxWindow *parent,
     if (multi_line)
     {
         // create our control ...
     if (multi_line)
     {
         // create our control ...
-        m_text = gtk_text_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
+        m_text = gtk_text_new( NULL, NULL );
 
         // ... and put into the upper left hand corner of the table
         bool bHasHScrollbar = false;
 
         // ... and put into the upper left hand corner of the table
         bool bHasHScrollbar = false;
@@ -325,7 +342,7 @@ bool wxTextCtrl::Create( wxWindow *parent,
         wxWX2MBbuf val = value.mbc_str();
         gtk_editable_insert_text( GTK_EDITABLE(m_text), val, strlen(val), &tmp );
 #else
         wxWX2MBbuf val = value.mbc_str();
         gtk_editable_insert_text( GTK_EDITABLE(m_text), val, strlen(val), &tmp );
 #else
-        gtk_editable_insert_text( GTK_EDITABLE(m_text), value, value.Length(), &tmp );
+        gtk_editable_insert_text( GTK_EDITABLE(m_text), value, value.length(), &tmp );
 #endif
 
         if (multi_line)
 #endif
 
         if (multi_line)
@@ -389,7 +406,7 @@ void wxTextCtrl::CalculateScrollbar()
     }
 }
 
     }
 }
 
-wxString wxTextCtrl::GetValue() const
+wxString wxTextCtrl::DoGetValue() const
 {
     wxCHECK_MSG( m_text != NULL, wxEmptyString, wxT("invalid text ctrl") );
 
 {
     wxCHECK_MSG( m_text != NULL, wxEmptyString, wxT("invalid text ctrl") );
 
@@ -409,16 +426,22 @@ wxString wxTextCtrl::GetValue() const
     return tmp;
 }
 
     return tmp;
 }
 
-void wxTextCtrl::SetValue( const wxString &value )
+void wxTextCtrl::DoSetValue( const wxString &value, int flags )
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
+    if ( !(flags & SetValue_SendEvent) )
+    {
+        // do not generate events
+        IgnoreNextTextUpdate();
+    }
+
     if (m_windowStyle & wxTE_MULTILINE)
     {
         gint len = gtk_text_get_length( GTK_TEXT(m_text) );
         gtk_editable_delete_text( GTK_EDITABLE(m_text), 0, len );
         len = 0;
     if (m_windowStyle & wxTE_MULTILINE)
     {
         gint len = gtk_text_get_length( GTK_TEXT(m_text) );
         gtk_editable_delete_text( GTK_EDITABLE(m_text), 0, len );
         len = 0;
-        gtk_editable_insert_text( GTK_EDITABLE(m_text), value.mbc_str(), value.Length(), &len );
+        gtk_editable_insert_text( GTK_EDITABLE(m_text), value.mbc_str(), value.length(), &len );
     }
     else
     {
     }
     else
     {
@@ -454,7 +477,7 @@ void wxTextCtrl::WriteText( const wxString &text )
         // resetting the style and appending some more text wouldn't work: if
         // we don't specify the style explicitly, the old style would be used
         gtk_editable_delete_selection( GTK_EDITABLE(m_text) );
         // resetting the style and appending some more text wouldn't work: if
         // we don't specify the style explicitly, the old style would be used
         gtk_editable_delete_selection( GTK_EDITABLE(m_text) );
-        wxGtkTextInsert(m_text, m_defaultStyle, text.c_str(), text.Len());
+        wxGtkTextInsert(m_text, m_defaultStyle, text.c_str(), text.length());
 
         // we called wxGtkTextInsert with correct font, no need to do anything
         // in UpdateFontIfNeeded() any longer
 
         // we called wxGtkTextInsert with correct font, no need to do anything
         // in UpdateFontIfNeeded() any longer
@@ -474,7 +497,7 @@ void wxTextCtrl::WriteText( const wxString &text )
         // This moves the cursor pos to behind the inserted text.
         gint len = GET_EDITABLE_POS(m_text);
 
         // This moves the cursor pos to behind the inserted text.
         gint len = GET_EDITABLE_POS(m_text);
 
-        gtk_editable_insert_text( GTK_EDITABLE(m_text), text.c_str(), text.Len(), &len );
+        gtk_editable_insert_text( GTK_EDITABLE(m_text), text.c_str(), text.length(), &len );
 
         // Bring entry's cursor uptodate.
         gtk_entry_set_position( GTK_ENTRY(m_text), len );
 
         // Bring entry's cursor uptodate.
         gtk_entry_set_position( GTK_ENTRY(m_text), len );
@@ -538,7 +561,7 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y ) const
         wxString text = GetValue();
 
         // cast to prevent warning. But pos really should've been unsigned.
         wxString text = GetValue();
 
         // cast to prevent warning. But pos really should've been unsigned.
-        if( (unsigned long)pos > text.Len()  )
+        if( (unsigned long)pos > text.length()  )
             return false;
 
         *x=0;   // First Col
             return false;
 
         *x=0;   // First Col
@@ -587,7 +610,7 @@ long wxTextCtrl::XYToPosition(long x, long y ) const
 int wxTextCtrl::GetLineLength(long lineNo) const
 {
     wxString str = GetLineText (lineNo);
 int wxTextCtrl::GetLineLength(long lineNo) const
 {
     wxString str = GetLineText (lineNo);
-    return (int) str.Length();
+    return (int) str.length();
 }
 
 int wxTextCtrl::GetNumberOfLines() const
 }
 
 int wxTextCtrl::GetNumberOfLines() const
@@ -681,32 +704,26 @@ void wxTextCtrl::SetEditable( bool editable )
     }
 }
 
     }
 }
 
-bool wxTextCtrl::Enable( bool enable )
+void wxTextCtrl::DoEnable( bool enable )
 {
 {
-    if (!wxWindowBase::Enable(enable))
-    {
-        // nothing to do
-        return false;
-    }
-
     if (m_windowStyle & wxTE_MULTILINE)
     {
         gtk_text_set_editable( GTK_TEXT(m_text), enable );
     if (m_windowStyle & wxTE_MULTILINE)
     {
         gtk_text_set_editable( GTK_TEXT(m_text), enable );
-        OnParentEnable(enable);
     }
     else
     {
         gtk_widget_set_sensitive( m_text, enable );
     }
     }
     else
     {
         gtk_widget_set_sensitive( m_text, enable );
     }
-
-    return true;
 }
 
 // wxGTK-specific: called recursively by Enable,
 // to give widgets an oppprtunity to correct their colours after they
 // have been changed by Enable
 }
 
 // wxGTK-specific: called recursively by Enable,
 // to give widgets an oppprtunity to correct their colours after they
 // have been changed by Enable
-void wxTextCtrl::OnParentEnable( bool enable )
+void wxTextCtrl::OnEnabled( bool WXUNUSED(enable) )
 {
 {
+    if ( IsSingleLine() )
+        return;
+
     // If we have a custom background colour, we use this colour in both
     // disabled and enabled mode, or we end up with a different colour under the
     // text.
     // If we have a custom background colour, we use this colour in both
     // disabled and enabled mode, or we end up with a different colour under the
     // text.
@@ -794,7 +811,7 @@ void wxTextCtrl::SetSelection( long from, long to )
     if (from == -1 && to == -1)
     {
         from = 0;
     if (from == -1 && to == -1)
     {
         from = 0;
-        to = GetValue().Length();
+        to = GetValue().length();
     }
 
     if ( (m_windowStyle & wxTE_MULTILINE) &&
     }
 
     if ( (m_windowStyle & wxTE_MULTILINE) &&
@@ -873,7 +890,7 @@ void wxTextCtrl::Replace( long from, long to, const wxString &value )
         wxWX2MBbuf buf = value.mbc_str();
         gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &pos );
 #else
         wxWX2MBbuf buf = value.mbc_str();
         gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &pos );
 #else
-        gtk_editable_insert_text( GTK_EDITABLE(m_text), value, value.Length(), &pos );
+        gtk_editable_insert_text( GTK_EDITABLE(m_text), value, value.length(), &pos );
 #endif // wxUSE_UNICODE
     }
 }
 #endif // wxUSE_UNICODE
     }
 }
@@ -978,12 +995,12 @@ void wxTextCtrl::OnChar( wxKeyEvent &key_event )
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
 {
     wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
 
-    if ((key_event.GetKeyCode() == WXK_RETURN) && (m_windowStyle & wxPROCESS_ENTER))
+    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());
     {
         wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
         event.SetEventObject(this);
         event.SetString(GetValue());
-        if (GetEventHandler()->ProcessEvent(event)) return;
+        if (HandleWindowEvent(event)) return;
     }
 
     if ((key_event.GetKeyCode() == WXK_RETURN) && !(m_windowStyle & wxTE_MULTILINE))
     }
 
     if ((key_event.GetKeyCode() == WXK_RETURN) && !(m_windowStyle & wxTE_MULTILINE))
@@ -1231,7 +1248,7 @@ void wxTextCtrl::OnInternalIdle()
 
     if (cursor.Ok())
     {
 
     if (cursor.Ok())
     {
-        GdkWindow *window = (GdkWindow*) NULL;
+        GdkWindow *window = NULL;
         if (HasFlag(wxTE_MULTILINE))
             window = GTK_TEXT(m_text)->text_area;
         else
         if (HasFlag(wxTE_MULTILINE))
             window = GTK_TEXT(m_text)->text_area;
         else
@@ -1274,7 +1291,7 @@ wxSize wxTextCtrl::DoGetBestSize() const
 // freeze/thaw
 // ----------------------------------------------------------------------------
 
 // freeze/thaw
 // ----------------------------------------------------------------------------
 
-void wxTextCtrl::Freeze()
+void wxTextCtrl::DoFreeze()
 {
     if ( HasFlag(wxTE_MULTILINE) )
     {
 {
     if ( HasFlag(wxTE_MULTILINE) )
     {
@@ -1282,7 +1299,7 @@ void wxTextCtrl::Freeze()
     }
 }
 
     }
 }
 
-void wxTextCtrl::Thaw()
+void wxTextCtrl::DoThaw()
 {
     if ( HasFlag(wxTE_MULTILINE) )
     {
 {
     if ( HasFlag(wxTE_MULTILINE) )
     {