/////////////////////////////////////////////////////////////////////////////
-// Name: textctrl.cpp
+// Name: src/gtk1/textctrl.cpp
// Purpose:
// Author: Robert Roebling
// Id: $Id$
#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/evtloop.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>
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;
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)
// we should only be called if we have a max len limit at all
GtkEntry *entry = GTK_ENTRY (editable);
- wxCHECK_RET( entry->text_max_length, _T("shouldn't be called") );
+ wxCHECK_RET( entry->text_max_length, wxT("shouldn't be called") );
// check that we don't overflow the max length limit
//
wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, win->GetId());
event.SetEventObject(win);
event.SetString(win->GetValue());
- win->GetEventHandler()->ProcessEvent( event );
+ win->HandleWindowEvent( event );
}
}
}
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;
wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, win->GetId() );
event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
+ win->HandleWindowEvent( event );
}
}
// 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" {
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") );
+ wxT("infinite recursion in wxgtk_text_draw aborted") );
gs_gtk_text_draw(widget, rect);
}
// 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)
m_modified = false;
SetUpdateFont(false);
m_text =
- m_vScrollbar = (GtkWidget *)NULL;
+ m_vScrollbar = NULL;
}
wxTextCtrl::~wxTextCtrl()
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;
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)
}
}
-wxString wxTextCtrl::GetValue() const
+wxString wxTextCtrl::DoGetValue() const
{
wxCHECK_MSG( m_text != NULL, wxEmptyString, wxT("invalid text ctrl") );
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") );
+ 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;
- 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
{
// 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
// 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 );
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
int wxTextCtrl::GetLineLength(long lineNo) const
{
wxString str = GetLineText (lineNo);
- return (int) str.Length();
+ return (int) str.length();
}
int wxTextCtrl::GetNumberOfLines() const
}
}
-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 );
- OnParentEnable(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
-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 (from == -1 && to == -1)
{
from = 0;
- to = GetValue().Length();
+ to = GetValue().length();
}
if ( (m_windowStyle & wxTE_MULTILINE) &&
!GTK_TEXT(m_text)->line_start_cache )
{
// tell the programmer that it didn't work
- wxLogDebug(_T("Can't call SetSelection() before realizing the control"));
+ wxLogDebug(wxT("Can't call SetSelection() before realizing the control"));
return;
}
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
}
}
{
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());
- if (GetEventHandler()->ProcessEvent(event)) return;
+ if (HandleWindowEvent(event)) return;
}
if ((key_event.GetKeyCode() == WXK_RETURN) && !(m_windowStyle & wxTE_MULTILINE))
// possible!
wxASSERT_MSG( (m_windowStyle & wxTE_MULTILINE) && m_updateFont,
- _T("shouldn't be called for single line controls") );
+ wxT("shouldn't be called for single line controls") );
wxString value = GetValue();
if ( !value.empty() )
gint l = gtk_text_get_length( GTK_TEXT(m_text) );
wxCHECK_MSG( start >= 0 && end <= l, false,
- _T("invalid range in wxTextCtrl::SetStyle") );
+ wxT("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 );
if (cursor.Ok())
{
- GdkWindow *window = (GdkWindow*) NULL;
+ GdkWindow *window = NULL;
if (HasFlag(wxTE_MULTILINE))
window = GTK_TEXT(m_text)->text_area;
else
// freeze/thaw
// ----------------------------------------------------------------------------
-void wxTextCtrl::Freeze()
+void wxTextCtrl::DoFreeze()
{
if ( HasFlag(wxTE_MULTILINE) )
{
}
}
-void wxTextCtrl::Thaw()
+void wxTextCtrl::DoThaw()
{
if ( HasFlag(wxTE_MULTILINE) )
{