1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Vadim Zeitlin 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "textctrl.h" 
  14 #include "wx/textctrl.h" 
  17 #include "wx/settings.h" 
  19 #include <sys/types.h> 
  25 #include "gdk/gdkkeysyms.h" 
  27 //----------------------------------------------------------------------------- 
  29 //----------------------------------------------------------------------------- 
  31 extern void wxapp_install_idle_handler(); 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 extern bool   g_blockEventsOnDrag
; 
  40 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  45 gtk_text_changed_callback( GtkWidget 
*WXUNUSED(widget
), wxTextCtrl 
*win 
) 
  47     if (g_isIdle
) wxapp_install_idle_handler(); 
  49     if (!win
->m_hasVMT
) return; 
  53     wxCommandEvent 
event( wxEVT_COMMAND_TEXT_UPDATED
, win
->m_windowId 
); 
  54     event
.SetString( win
->GetValue() ); 
  55     event
.SetEventObject( win 
); 
  56     win
->GetEventHandler()->ProcessEvent( event 
); 
  59 //----------------------------------------------------------------------------- 
  60 // "changed" from vertical scrollbar 
  61 //----------------------------------------------------------------------------- 
  64 gtk_scrollbar_changed_callback( GtkWidget 
*WXUNUSED(widget
), wxTextCtrl 
*win 
) 
  66     if (g_isIdle
) wxapp_install_idle_handler(); 
  68     if (!win
->m_hasVMT
) return; 
  70     win
->CalculateScrollbar(); 
  73 //----------------------------------------------------------------------------- 
  75 //----------------------------------------------------------------------------- 
  77 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
) 
  79 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
) 
  80     EVT_CHAR(wxTextCtrl::OnChar
) 
  82     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
  83     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
  84     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
  85     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
  86     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
  88     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
  89     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
  90     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
  91     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
  92     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
  95 #ifndef NO_TEXT_WINDOW_STREAM 
  96 wxTextCtrl::wxTextCtrl() : streambuf() 
  98     if (allocate()) setp(base(),ebuf()); 
 103 wxTextCtrl::wxTextCtrl() 
 109 #ifndef NO_TEXT_WINDOW_STREAM 
 110 wxTextCtrl::wxTextCtrl( wxWindow 
*parent
, wxWindowID id
, const wxString 
&value
, 
 111       const wxPoint 
&pos
, const wxSize 
&size
, 
 112       int style
, const wxValidator
& validator
, const wxString 
&name 
) : streambuf() 
 114     if (allocate()) setp(base(),ebuf()); 
 117     Create( parent
, id
, value
, pos
, size
, style
, validator
, name 
); 
 120 wxTextCtrl::wxTextCtrl( wxWindow 
*parent
, wxWindowID id
, const wxString 
&value
, 
 121       const wxPoint 
&pos
, const wxSize 
&size
, 
 122       int style
, const wxValidator
& validator
, const wxString 
&name 
) 
 125     Create( parent
, id
, value
, pos
, size
, style
, validator
, name 
); 
 129 bool wxTextCtrl::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&value
, 
 130       const wxPoint 
&pos
, const wxSize 
&size
, 
 131       int style
, const wxValidator
& validator
, const wxString 
&name 
) 
 134     m_acceptsFocus 
= TRUE
; 
 136     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 138     SetValidator( validator 
); 
 140     m_vScrollbarVisible 
= FALSE
; 
 142     bool multi_line 
= (style 
& wxTE_MULTILINE
) != 0; 
 145         /* a multi-line edit control: create a vertical scrollbar by default and 
 146            horizontal if requested */ 
 147         bool bHasHScrollbar 
= (style 
& wxHSCROLL
) != 0; 
 149         /* create our control ... */ 
 150         m_text 
= gtk_text_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
 152         /* ... and put into the upper left hand corner of the table */ 
 153         m_widget 
= gtk_table_new(bHasHScrollbar 
? 2 : 1, 2, FALSE
); 
 154         GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 156         gtk_table_attach( GTK_TABLE(m_widget
), m_text
, 0, 1, 0, 1, 
 157                       (GtkAttachOptions
)(GTK_FILL 
| GTK_EXPAND 
| GTK_SHRINK
), 
 158                       (GtkAttachOptions
)(GTK_FILL 
| GTK_EXPAND 
| GTK_SHRINK
), 
 161         /* put the horizontal scrollbar in the lower left hand corner */ 
 164             GtkWidget 
*hscrollbar 
= gtk_hscrollbar_new(GTK_TEXT(m_text
)->hadj
); 
 165             GTK_WIDGET_UNSET_FLAGS( hscrollbar
, GTK_CAN_FOCUS 
); 
 167             gtk_table_attach(GTK_TABLE(m_widget
), hscrollbar
, 0, 1, 1, 2, 
 168                        (GtkAttachOptions
)(GTK_EXPAND 
| GTK_FILL
), 
 171             gtk_widget_show(hscrollbar
); 
 174         /* we create the vertical scrollbar on demand */ 
 175         m_vScrollbar 
= (GtkWidget
*) NULL
; 
 180         /* a single-line text control: no need for scrollbars */ 
 182           m_text 
= gtk_entry_new(); 
 185     wxSize newSize 
= size
; 
 186     if (newSize
.x 
== -1) newSize
.x 
= 80; 
 187     if (newSize
.y 
== -1) newSize
.y 
= 26; 
 188     SetSize( newSize
.x
, newSize
.y 
); 
 190     m_parent
->AddChild( this ); 
 192     (m_parent
->m_insertCallback
)( m_parent
, this ); 
 198 //        gtk_widget_realize(m_text); 
 199         gtk_widget_show(m_text
); 
 202     /* we want to be notified about text changes */ 
 203     gtk_signal_connect( GTK_OBJECT(m_text
), "changed", 
 204       GTK_SIGNAL_FUNC(gtk_text_changed_callback
), (gpointer
)this); 
 206     if (!value
.IsEmpty()) 
 210         wxWX2MBbuf val 
= value
.mbc_str(); 
 211         gtk_editable_insert_text( GTK_EDITABLE(m_text
), val
, strlen(val
), &tmp 
); 
 213         gtk_editable_insert_text( GTK_EDITABLE(m_text
), value
, value
.Length(), &tmp 
); 
 218             /* bring editable's cursor uptodate. bug in GTK. */ 
 220             GTK_EDITABLE(m_text
)->current_pos 
= gtk_text_get_point( GTK_TEXT(m_text
) ); 
 224     if (style 
& wxTE_PASSWORD
) 
 227             gtk_entry_set_visibility( GTK_ENTRY(m_text
), FALSE 
); 
 230     if (style 
& wxTE_READONLY
) 
 233             gtk_entry_set_editable( GTK_ENTRY(m_text
), FALSE 
); 
 238             gtk_text_set_editable( GTK_TEXT(m_text
), 1 ); 
 241     SetBackgroundColour( parent
->GetBackgroundColour() ); 
 242     SetForegroundColour( parent
->GetForegroundColour() ); 
 248         gtk_signal_connect(GTK_OBJECT(GTK_TEXT(m_text
)->vadj
), "changed", 
 249           (GtkSignalFunc
) gtk_scrollbar_changed_callback
, (gpointer
) this ); 
 255 void wxTextCtrl::CalculateScrollbar() 
 257     if ((m_windowStyle 
& wxTE_MULTILINE
) == 0) return; 
 259     GtkAdjustment 
*adj 
= GTK_TEXT(m_text
)->vadj
; 
 261     if (adj
->upper 
- adj
->page_size 
< 0.8) 
 263         if (m_vScrollbarVisible
) 
 265             gtk_widget_hide( m_vScrollbar 
); 
 267             m_vScrollbarVisible 
= FALSE
; 
 272         if (!m_vScrollbarVisible
) 
 276                 /* finally, put the vertical scrollbar in the upper right corner */ 
 277                 m_vScrollbar 
= gtk_vscrollbar_new( GTK_TEXT(m_text
)->vadj 
); 
 278                 GTK_WIDGET_UNSET_FLAGS( m_vScrollbar
, GTK_CAN_FOCUS 
); 
 280                 gtk_table_attach(GTK_TABLE(m_widget
), m_vScrollbar
, 1, 2, 0, 1, 
 282                      (GtkAttachOptions
)(GTK_EXPAND 
| GTK_FILL 
| GTK_SHRINK
), 
 286             gtk_widget_show( m_vScrollbar 
); 
 288             m_vScrollbarVisible 
= TRUE
; 
 293 wxString 
wxTextCtrl::GetValue() const 
 295     wxCHECK_MSG( m_text 
!= NULL
, _T(""), _T("invalid text ctrl") ); 
 298     if (m_windowStyle 
& wxTE_MULTILINE
) 
 300         gint len 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 301         char *text 
= gtk_editable_get_chars( GTK_EDITABLE(m_text
), 0, len 
); 
 302         tmp 
= wxString(text
,*wxConv_current
); 
 307         tmp 
= wxString(gtk_entry_get_text( GTK_ENTRY(m_text
) ),*wxConv_current
); 
 312 void wxTextCtrl::SetValue( const wxString 
&value 
) 
 314     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 316     wxString tmp 
= _T(""); 
 317     if (!value
.IsNull()) tmp 
= value
; 
 318     if (m_windowStyle 
& wxTE_MULTILINE
) 
 320         gint len 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 321         gtk_editable_delete_text( GTK_EDITABLE(m_text
), 0, len 
); 
 324         wxWX2MBbuf tmpbuf 
= tmp
.mbc_str(); 
 325         gtk_editable_insert_text( GTK_EDITABLE(m_text
), tmpbuf
, strlen(tmpbuf
), &len 
); 
 327         gtk_editable_insert_text( GTK_EDITABLE(m_text
), tmp
.mbc_str(), tmp
.Length(), &len 
); 
 332         gtk_entry_set_text( GTK_ENTRY(m_text
), tmp
.mbc_str() ); 
 336 void wxTextCtrl::WriteText( const wxString 
&text 
) 
 338     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 340     if (text
.IsNull()) return; 
 342     if (m_windowStyle 
& wxTE_MULTILINE
) 
 344         /* this moves the cursor pos to behind the inserted text */ 
 345         gint len 
= GTK_EDITABLE(m_text
)->current_pos
; 
 348         wxWX2MBbuf buf 
= text
.mbc_str(); 
 349         gtk_editable_insert_text( GTK_EDITABLE(m_text
), buf
, strlen(buf
), &len 
); 
 351         gtk_editable_insert_text( GTK_EDITABLE(m_text
), text
, text
.Length(), &len 
); 
 354         /* bring editable's cursor uptodate. bug in GTK. */ 
 355         GTK_EDITABLE(m_text
)->current_pos 
= gtk_text_get_point( GTK_TEXT(m_text
) ); 
 359         /* this moves the cursor pos to behind the inserted text */ 
 360         gint len 
= GTK_EDITABLE(m_text
)->current_pos
; 
 362         wxWX2MBbuf buf 
= text
.mbc_str(); 
 363         gtk_editable_insert_text( GTK_EDITABLE(m_text
), buf
, strlen(buf
), &len 
); 
 365         gtk_editable_insert_text( GTK_EDITABLE(m_text
), text
, text
.Length(), &len 
); 
 368         /* bring editable's cursor uptodate. bug in GTK. */ 
 369         GTK_EDITABLE(m_text
)->current_pos 
+= text
.Len(); 
 371         /* bring entry's cursor uptodate. bug in GTK. */ 
 372         gtk_entry_set_position( GTK_ENTRY(m_text
), GTK_EDITABLE(m_text
)->current_pos 
); 
 376 void wxTextCtrl::AppendText( const wxString 
&text 
) 
 378     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 380     if (m_windowStyle 
& wxTE_MULTILINE
) 
 382         /* we'll insert at the last position */ 
 383         gint len 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 385         wxWX2MBbuf buf 
= text
.mbc_str(); 
 386         gtk_editable_insert_text( GTK_EDITABLE(m_text
), buf
, strlen(buf
), &len 
); 
 388         gtk_editable_insert_text( GTK_EDITABLE(m_text
), text
, text
.Length(), &len 
); 
 391         /* bring editable's cursor uptodate. bug in GTK. */ 
 392         GTK_EDITABLE(m_text
)->current_pos 
= gtk_text_get_point( GTK_TEXT(m_text
) ); 
 396         gtk_entry_append_text( GTK_ENTRY(m_text
), text
.mbc_str() ); 
 400 bool wxTextCtrl::LoadFile( const wxString 
&file 
) 
 402   wxCHECK_MSG( m_text 
!= NULL
, FALSE
, _T("invalid text ctrl") ); 
 404   if (!wxFileExists(file
)) return FALSE
; 
 408   FILE *fp 
= (FILE*) NULL
; 
 411   if ((stat (FNSTRINGCAST file
.fn_str(), &statb
) == -1) || (statb
.st_mode 
& S_IFMT
) != S_IFREG 
|| 
 412       !(fp 
= fopen (FNSTRINGCAST file
.fn_str(), "r"))) 
 418     gint len 
= statb
.st_size
; 
 420     if (!(text 
= (char*)malloc ((unsigned) (len 
+ 1)))) 
 425     if (fread (text
, sizeof (char), len
, fp
) != (size_t) len
) 
 432     if (m_windowStyle 
& wxTE_MULTILINE
) 
 435       gtk_editable_insert_text( GTK_EDITABLE(m_text
), text
, len
, &pos 
); 
 439       gtk_entry_set_text( GTK_ENTRY(m_text
), text 
); 
 449 bool wxTextCtrl::SaveFile( const wxString 
&file 
) 
 451   wxCHECK_MSG( m_text 
!= NULL
, FALSE
, _T("invalid text ctrl") ); 
 453   if (file 
== _T("")) return FALSE
; 
 457   if (!(fp 
= fopen (FNSTRINGCAST file
.fn_str(), "w"))) 
 463       char *text 
= (char*) NULL
; 
 466       if (m_windowStyle 
& wxTE_MULTILINE
) 
 468         len 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 469         text 
= gtk_editable_get_chars( GTK_EDITABLE(m_text
), 0, len 
); 
 473         text 
= gtk_entry_get_text( GTK_ENTRY(m_text
) ); 
 476       if (fwrite (text
, sizeof (char), len
, fp
) != (size_t) len
) 
 478           // Did not write whole file 
 481       // Make sure newline terminates the file 
 482       if (text
[len 
- 1] != '\n') 
 487       if (m_windowStyle 
& wxTE_MULTILINE
) g_free( text 
); 
 496 wxString 
wxTextCtrl::GetLineText( long lineNo 
) const 
 498   if (m_windowStyle 
& wxTE_MULTILINE
) 
 500     gint len 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 501     char *text 
= gtk_editable_get_chars( GTK_EDITABLE(m_text
), 0, len 
); 
 505         wxString 
buf(_T("")); 
 508         for (i 
= 0; currentLine 
!= lineNo 
&& text
[i
]; i
++ ) 
 513         for (j 
= 0; text
[i
] && text
[i
] != '\n'; i
++, j
++ ) 
 520       return wxEmptyString
; 
 524     if (lineNo 
== 0) return GetValue(); 
 525     return wxEmptyString
; 
 529 void wxTextCtrl::OnDropFiles( wxDropFilesEvent 
&WXUNUSED(event
) ) 
 531   /* If you implement this, don't forget to update the documentation! 
 532    * (file docs/latex/wx/text.tex) */ 
 533     wxFAIL_MSG( _T("wxTextCtrl::OnDropFiles not implemented") ); 
 536 long wxTextCtrl::PositionToXY(long pos
, long *x
, long *y 
) const 
 538     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
 540         wxString text 
= GetValue(); 
 542         // cast to prevent warning. But pos really should've been unsigned. 
 543         if( (unsigned long)pos 
> text
.Len()  ) 
 549         const wxChar
* stop 
= text
.c_str() + pos
; 
 550         for ( const wxChar 
*p 
= text
.c_str(); p 
< stop
; p
++ ) 
 561     else // single line control 
 563         if ( pos 
<= GTK_ENTRY(m_text
)->text_length 
) 
 570             // index out of bounds 
 578 long wxTextCtrl::XYToPosition(long x
, long y 
) const 
 580     if (!(m_windowStyle 
& wxTE_MULTILINE
)) return 0; 
 583     for( int i
=0; i
<y
; i
++ ) pos 
+= GetLineLength(i
) + 1; // one for '\n' 
 589 int wxTextCtrl::GetLineLength(long lineNo
) const 
 591     wxString str 
= GetLineText (lineNo
); 
 592     return (int) str
.Length(); 
 595 int wxTextCtrl::GetNumberOfLines() const 
 597     if (m_windowStyle 
& wxTE_MULTILINE
) 
 599         gint len 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 600         char *text 
= gtk_editable_get_chars( GTK_EDITABLE(m_text
), 0, len 
); 
 605             for (int i 
= 0; i 
< len
; i
++ ) 
 612             // currentLine is 0 based, add 1 to get number of lines 
 613             return currentLine 
+ 1; 
 626 void wxTextCtrl::SetInsertionPoint( long pos 
) 
 628     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 630     if (m_windowStyle 
& wxTE_MULTILINE
)  
 632         /* seems to be broken in GTK 1.0.X: 
 633            gtk_text_set_point( GTK_TEXT(m_text), (int)pos ); */ 
 635         gtk_signal_disconnect_by_func( GTK_OBJECT(m_text
), 
 636           GTK_SIGNAL_FUNC(gtk_text_changed_callback
), (gpointer
)this); 
 638         /* we fake a set_point by inserting and deleting. as the user 
 639            isn't supposed to get to know about thos non-sense, we 
 640            disconnect so that no events are sent to the user program. */ 
 642         gint tmp 
= (gint
)pos
; 
 643         gtk_editable_insert_text( GTK_EDITABLE(m_text
), " ", 1, &tmp 
); 
 644         gtk_editable_delete_text( GTK_EDITABLE(m_text
), tmp
-1, tmp 
); 
 646         gtk_signal_connect( GTK_OBJECT(m_text
), "changed", 
 647           GTK_SIGNAL_FUNC(gtk_text_changed_callback
), (gpointer
)this); 
 649         /* bring editable's cursor uptodate. another bug in GTK. */ 
 651         GTK_EDITABLE(m_text
)->current_pos 
= gtk_text_get_point( GTK_TEXT(m_text
) ); 
 655         gtk_entry_set_position( GTK_ENTRY(m_text
), (int)pos 
); 
 657         /* bring editable's cursor uptodate. bug in GTK. */ 
 659         GTK_EDITABLE(m_text
)->current_pos 
= pos
; 
 663 void wxTextCtrl::SetInsertionPointEnd() 
 665     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 667     if (m_windowStyle 
& wxTE_MULTILINE
) 
 668         SetInsertionPoint(gtk_text_get_length(GTK_TEXT(m_text
))); 
 670         gtk_entry_set_position( GTK_ENTRY(m_text
), -1 ); 
 673 void wxTextCtrl::SetEditable( bool editable 
) 
 675     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 677     if (m_windowStyle 
& wxTE_MULTILINE
) 
 678         gtk_text_set_editable( GTK_TEXT(m_text
), editable 
); 
 680         gtk_entry_set_editable( GTK_ENTRY(m_text
), editable 
); 
 683 void wxTextCtrl::SetSelection( long from
, long to 
) 
 685     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 687     gtk_editable_select_region( GTK_EDITABLE(m_text
), (gint
)from
, (gint
)to 
); 
 690 void wxTextCtrl::ShowPosition( long WXUNUSED(pos
) ) 
 692     wxFAIL_MSG( _T("wxTextCtrl::ShowPosition not implemented") ); 
 695 long wxTextCtrl::GetInsertionPoint() const 
 697     wxCHECK_MSG( m_text 
!= NULL
, 0, _T("invalid text ctrl") ); 
 699     return (long) GTK_EDITABLE(m_text
)->current_pos
; 
 702 long wxTextCtrl::GetLastPosition() const 
 704     wxCHECK_MSG( m_text 
!= NULL
, 0, _T("invalid text ctrl") ); 
 707     if (m_windowStyle 
& wxTE_MULTILINE
) 
 708         pos 
= gtk_text_get_length( GTK_TEXT(m_text
) ); 
 710         pos 
= GTK_ENTRY(m_text
)->text_length
; 
 715 void wxTextCtrl::Remove( long from
, long to 
) 
 717     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 719     gtk_editable_delete_text( GTK_EDITABLE(m_text
), (gint
)from
, (gint
)to 
); 
 722 void wxTextCtrl::Replace( long from
, long to
, const wxString 
&value 
) 
 724     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 726     gtk_editable_delete_text( GTK_EDITABLE(m_text
), (gint
)from
, (gint
)to 
); 
 727     if (value
.IsNull()) return; 
 728     gint pos 
= (gint
)from
; 
 730     wxWX2MBbuf buf 
= value
.mbc_str(); 
 731     gtk_editable_insert_text( GTK_EDITABLE(m_text
), buf
, strlen(buf
), &pos 
); 
 733     gtk_editable_insert_text( GTK_EDITABLE(m_text
), value
, value
.Length(), &pos 
); 
 737 void wxTextCtrl::Cut() 
 739     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 741 #if (GTK_MINOR_VERSION > 0) 
 742     gtk_editable_cut_clipboard( GTK_EDITABLE(m_text
) ); 
 744     gtk_editable_cut_clipboard( GTK_EDITABLE(m_text
), 0 ); 
 748 void wxTextCtrl::Copy() 
 750     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 752 #if (GTK_MINOR_VERSION > 0) 
 753     gtk_editable_copy_clipboard( GTK_EDITABLE(m_text
) ); 
 755     gtk_editable_copy_clipboard( GTK_EDITABLE(m_text
), 0 ); 
 759 void wxTextCtrl::Paste() 
 761     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 763 #if (GTK_MINOR_VERSION > 0) 
 764     gtk_editable_paste_clipboard( GTK_EDITABLE(m_text
) ); 
 766     gtk_editable_paste_clipboard( GTK_EDITABLE(m_text
), 0 ); 
 770 bool wxTextCtrl::CanCopy() const 
 772     // Can copy if there's a selection 
 774     GetSelection(& from
, & to
); 
 775     return (from 
!= to
) ; 
 778 bool wxTextCtrl::CanCut() const 
 780     // Can cut if there's a selection 
 782     GetSelection(& from
, & to
); 
 783     return (from 
!= to
) ; 
 786 bool wxTextCtrl::CanPaste() const 
 788     return IsEditable() ; 
 792 void wxTextCtrl::Undo() 
 795     wxFAIL_MSG( _T("wxTextCtrl::Undo not implemented") ); 
 798 void wxTextCtrl::Redo() 
 801     wxFAIL_MSG( _T("wxTextCtrl::Redo not implemented") ); 
 804 bool wxTextCtrl::CanUndo() const 
 807     wxFAIL_MSG( _T("wxTextCtrl::CanUndo not implemented") ); 
 811 bool wxTextCtrl::CanRedo() const 
 814     wxFAIL_MSG( _T("wxTextCtrl::CanRedo not implemented") ); 
 818 // If the return values from and to are the same, there is no 
 820 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 825     wxFAIL_MSG( _T("wxTextCtrl::GetSelection not implemented") ); 
 828 bool wxTextCtrl::IsEditable() const 
 831     wxFAIL_MSG( _T("wxTextCtrl::IsEditable not implemented") ); 
 835 void wxTextCtrl::Clear() 
 840 void wxTextCtrl::OnChar( wxKeyEvent 
&key_event 
) 
 842     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 844     if ((key_event
.KeyCode() == WXK_RETURN
) && (m_windowStyle 
& wxPROCESS_ENTER
)) 
 846         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
 847         event
.SetEventObject(this); 
 848         if (GetEventHandler()->ProcessEvent(event
)) return; 
 854 #ifndef NO_TEXT_WINDOW_STREAM 
 855 int wxTextCtrl::overflow( int WXUNUSED(c
) ) 
 857     int len 
= pptr() - pbase(); 
 858     char *txt 
= new char[len
+1]; 
 859     strncpy(txt
, pbase(), len
); 
 862     setp(pbase(), epptr()); 
 867 int wxTextCtrl::sync() 
 869     int len 
= pptr() - pbase(); 
 870     char *txt 
= new char[len
+1]; 
 871     strncpy(txt
, pbase(), len
); 
 874     setp(pbase(), epptr()); 
 879 int wxTextCtrl::underflow() 
 884 wxTextCtrl
& wxTextCtrl::operator<<(const wxString
& s
) 
 890 wxTextCtrl
& wxTextCtrl::operator<<(float f
) 
 892     static char buf
[100]; 
 893     sprintf(buf
, "%.2f", f
); 
 898 wxTextCtrl
& wxTextCtrl::operator<<(double d
) 
 900     static char buf
[100]; 
 901     sprintf(buf
, "%.2f", d
); 
 906 wxTextCtrl
& wxTextCtrl::operator<<(int i
) 
 908     static char buf
[100]; 
 909     sprintf(buf
, "%i", i
); 
 914 wxTextCtrl
& wxTextCtrl::operator<<(long i
) 
 916     static char buf
[100]; 
 917     sprintf(buf
, "%ld", i
); 
 922 wxTextCtrl
& wxTextCtrl::operator<<(const char c
) 
 933 GtkWidget
* wxTextCtrl::GetConnectWidget() 
 935     return GTK_WIDGET(m_text
); 
 938 bool wxTextCtrl::IsOwnGtkWindow( GdkWindow 
*window 
) 
 940     if (m_windowStyle 
& wxTE_MULTILINE
) 
 941         return (window 
== GTK_TEXT(m_text
)->text_area
); 
 943         return (window 
== GTK_ENTRY(m_text
)->text_area
); 
 946 void wxTextCtrl::SetFont( const wxFont 
&WXUNUSED(font
) ) 
 948     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 953 void wxTextCtrl::SetForegroundColour( const wxColour 
&WXUNUSED(colour
) ) 
 955     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 960 void wxTextCtrl::SetBackgroundColour( const wxColour 
&colour 
) 
 962     wxCHECK_RET( m_text 
!= NULL
, _T("invalid text ctrl") ); 
 964     wxControl::SetBackgroundColour( colour 
); 
 966     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
 967     if (sysbg
.Red() == colour
.Red() && 
 968         sysbg
.Green() == colour
.Green() && 
 969         sysbg
.Blue() == colour
.Blue()) 
 974     if (!m_backgroundColour
.Ok()) return; 
 976     if (m_windowStyle 
& wxTE_MULTILINE
) 
 978         GdkWindow 
*window 
= GTK_TEXT(m_text
)->text_area
; 
 979         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window 
) ); 
 980         gdk_window_set_background( window
, m_backgroundColour
.GetColor() ); 
 981         gdk_window_clear( window 
); 
 985 void wxTextCtrl::ApplyWidgetStyle() 
 987     if (m_windowStyle 
& wxTE_MULTILINE
) 
 994         gtk_widget_set_style( m_text
, m_widgetStyle 
); 
 998 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
1003 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
1008 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
1013 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
1018 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
1023 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
1025     event
.Enable( CanCut() ); 
1028 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
1030     event
.Enable( CanCopy() ); 
1033 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
1035     event
.Enable( CanPaste() ); 
1038 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
1040     event
.Enable( CanUndo() ); 
1043 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
1045     event
.Enable( CanRedo() );