1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "textctrl.h"
14 #include "wx/textctrl.h"
18 //-----------------------------------------------------------------------------
20 //-----------------------------------------------------------------------------
22 static void gtk_text_changed_callback( GtkWidget
*WXUNUSED(widget
), wxTextCtrl
*win
)
26 wxCommandEvent
event( wxEVT_COMMAND_TEXT_UPDATED
, win
->m_windowId
);
27 wxString
val( win
->GetValue() );
28 if (!val
.IsNull()) event
.m_commandString
= WXSTRINGCAST val
;
29 event
.SetEventObject( win
);
30 win
->GetEventHandler()->ProcessEvent( event
);
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
37 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
39 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
40 EVT_CHAR(wxTextCtrl::OnChar
)
43 wxTextCtrl::wxTextCtrl() : streambuf()
45 if (allocate()) setp(base(),ebuf());
50 wxTextCtrl::wxTextCtrl( wxWindow
*parent
, wxWindowID id
, const wxString
&value
,
51 const wxPoint
&pos
, const wxSize
&size
,
52 int style
, const wxValidator
& validator
, const wxString
&name
) : streambuf()
54 if (allocate()) setp(base(),ebuf());
57 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
60 bool wxTextCtrl::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&value
,
61 const wxPoint
&pos
, const wxSize
&size
,
62 int style
, const wxValidator
& validator
, const wxString
&name
)
66 PreCreation( parent
, id
, pos
, size
, style
, name
);
68 SetValidator( validator
);
70 bool bMultiLine
= (style
& wxTE_MULTILINE
) != 0;
73 // a multi-line edit control: create a vertical scrollbar by default and
74 // horizontal if requested
75 bool bHasHScrollbar
= (style
& wxHSCROLL
) != 0;
77 // create our control...
78 m_text
= gtk_text_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
80 // ... and put into the upper left hand corner of the table
81 m_widget
= gtk_table_new(bHasHScrollbar
? 2 : 1, 2, FALSE
);
82 gtk_table_attach(GTK_TABLE(m_widget
), m_text
, 0, 1, 0, 1,
83 GTK_FILL
| GTK_EXPAND
,
84 GTK_FILL
| GTK_EXPAND
| GTK_SHRINK
,
87 // put the horizontal scrollbar in the lower left hand corner
90 GtkWidget
*hscrollbar
= gtk_hscrollbar_new(GTK_TEXT(m_text
)->hadj
);
91 gtk_table_attach(GTK_TABLE(m_widget
), hscrollbar
, 0, 1, 1, 2,
92 GTK_EXPAND
| GTK_FILL
,
95 gtk_widget_show(hscrollbar
);
98 // finally, put the vertical scrollbar in the upper right corner
99 GtkWidget
*vscrollbar
= gtk_vscrollbar_new(GTK_TEXT(m_text
)->vadj
);
100 gtk_table_attach(GTK_TABLE(m_widget
), vscrollbar
, 1, 2, 0, 1,
102 GTK_EXPAND
| GTK_FILL
| GTK_SHRINK
,
104 gtk_widget_show( vscrollbar
);
108 // a single-line text control: no need for scrollbars
110 m_text
= gtk_entry_new();
113 wxSize newSize
= size
;
114 if (newSize
.x
== -1) newSize
.x
= 80;
115 if (newSize
.y
== -1) newSize
.y
= 26;
116 SetSize( newSize
.x
, newSize
.y
);
122 gtk_widget_realize(m_text
);
123 gtk_widget_show(m_text
);
126 // we want to be notified about text changes
127 gtk_signal_connect(GTK_OBJECT(m_text
), "changed",
128 GTK_SIGNAL_FUNC(gtk_text_changed_callback
),
134 gtk_editable_insert_text( GTK_EDITABLE(m_text
), value
, value
.Length(), &tmp
);
137 if (style
& wxTE_READONLY
)
143 gtk_text_set_editable( GTK_TEXT(m_text
), 1 );
148 SetBackgroundColour( parent
->GetBackgroundColour() );
153 wxString
wxTextCtrl::GetValue() const
156 if (m_windowStyle
& wxTE_MULTILINE
)
158 gint len
= gtk_text_get_length( GTK_TEXT(m_text
) );
159 tmp
= gtk_editable_get_chars( GTK_EDITABLE(m_text
), 0, len
);
163 tmp
= gtk_entry_get_text( GTK_ENTRY(m_text
) );
168 void wxTextCtrl::SetValue( const wxString
&value
)
170 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
173 if (!value
.IsNull()) tmp
= value
;
174 if (m_windowStyle
& wxTE_MULTILINE
)
176 gint len
= gtk_text_get_length( GTK_TEXT(m_text
) );
177 gtk_editable_delete_text( GTK_EDITABLE(m_text
), 0, len
);
179 gtk_editable_insert_text( GTK_EDITABLE(m_text
), tmp
, tmp
.Length(), &len
);
183 gtk_entry_set_text( GTK_ENTRY(m_text
), tmp
);
187 void wxTextCtrl::WriteText( const wxString
&text
)
189 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
191 if (text
.IsNull()) return;
193 if (m_windowStyle
& wxTE_MULTILINE
)
195 gint len
= gtk_text_get_length( GTK_TEXT(m_text
) );
196 gtk_editable_insert_text( GTK_EDITABLE(m_text
), text
, text
.Length(), &len
);
200 gtk_entry_append_text( GTK_ENTRY(m_text
), text
);
204 bool wxTextCtrl::LoadFile( const wxString
&WXUNUSED(file
) )
206 wxFAIL_MSG( "wxTextCtrl::LoadFile not implemented" );
211 bool wxTextCtrl::SaveFile( const wxString
&WXUNUSED(file
) )
213 wxFAIL_MSG( "wxTextCtrl::SaveFile not implemented" );
219 wxString wxTextCtrl::GetLineText( long lineNo ) const
224 void wxTextCtrl::OnDropFiles( wxDropFilesEvent &event )
228 long wxTextCtrl::PositionToXY( long pos, long *x, long *y ) const
232 long wxTextCtrl::XYToPosition( long x, long y )
236 int wxTextCtrl::GetNumberOfLines()
241 void wxTextCtrl::SetInsertionPoint( long pos
)
244 if (m_windowStyle
& wxTE_MULTILINE
)
245 gtk_text_set_point( GTK_TEXT(m_text
), tmp
);
247 gtk_entry_set_position( GTK_ENTRY(m_text
), tmp
);
250 void wxTextCtrl::SetInsertionPointEnd()
252 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
255 if (m_windowStyle
& wxTE_MULTILINE
)
256 pos
= gtk_text_get_length( GTK_TEXT(m_text
) );
258 pos
= GTK_ENTRY(m_text
)->text_length
;
259 SetInsertionPoint( pos
-1 );
262 void wxTextCtrl::SetEditable( bool editable
)
264 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
266 if (m_windowStyle
& wxTE_MULTILINE
)
267 gtk_text_set_editable( GTK_TEXT(m_text
), editable
);
269 gtk_entry_set_editable( GTK_ENTRY(m_text
), editable
);
272 void wxTextCtrl::SetSelection( long from
, long to
)
274 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
276 gtk_editable_select_region( GTK_EDITABLE(m_text
), (gint
)from
, (gint
)to
);
279 void wxTextCtrl::ShowPosition( long WXUNUSED(pos
) )
281 wxFAIL_MSG( "wxTextCtrl::ShowPosition not implemented" );
284 long wxTextCtrl::GetInsertionPoint() const
286 wxCHECK_MSG( m_text
!= NULL
, 0, "invalid text ctrl" );
288 return (long) GTK_EDITABLE(m_text
)->current_pos
;
291 long wxTextCtrl::GetLastPosition() const
293 wxCHECK_MSG( m_text
!= NULL
, 0, "invalid text ctrl" );
296 if (m_windowStyle
& wxTE_MULTILINE
)
297 pos
= gtk_text_get_length( GTK_TEXT(m_text
) );
299 pos
= GTK_ENTRY(m_text
)->text_length
;
303 void wxTextCtrl::Remove( long from
, long to
)
305 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
307 gtk_editable_delete_text( GTK_EDITABLE(m_text
), (gint
)from
, (gint
)to
);
310 void wxTextCtrl::Replace( long from
, long to
, const wxString
&value
)
312 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
314 gtk_editable_delete_text( GTK_EDITABLE(m_text
), (gint
)from
, (gint
)to
);
315 if (value
.IsNull()) return;
317 gtk_editable_insert_text( GTK_EDITABLE(m_text
), value
, value
.Length(), &pos
);
320 void wxTextCtrl::Cut()
322 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
324 #if (GTK_MINOR_VERSION == 1)
325 gtk_editable_cut_clipboard( GTK_EDITABLE(m_text
) );
327 gtk_editable_cut_clipboard( GTK_EDITABLE(m_text
), 0 );
331 void wxTextCtrl::Copy()
333 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
335 #if (GTK_MINOR_VERSION == 1)
336 gtk_editable_copy_clipboard( GTK_EDITABLE(m_text
) );
338 gtk_editable_copy_clipboard( GTK_EDITABLE(m_text
), 0 );
342 void wxTextCtrl::Paste()
344 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
346 #if (GTK_MINOR_VERSION == 1)
347 gtk_editable_paste_clipboard( GTK_EDITABLE(m_text
) );
349 gtk_editable_paste_clipboard( GTK_EDITABLE(m_text
), 0 );
353 void wxTextCtrl::Clear()
358 void wxTextCtrl::OnChar( wxKeyEvent
&key_event
)
360 if ((key_event
.KeyCode() == WXK_RETURN
) && (m_windowStyle
& wxPROCESS_ENTER
))
362 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
363 event
.SetEventObject(this);
364 if (GetEventHandler()->ProcessEvent(event
)) return;
366 else if (key_event
.KeyCode() == WXK_TAB
)
368 wxNavigationKeyEvent event
;
369 event
.SetDirection( key_event
.m_shiftDown
);
370 event
.SetWindowChange(FALSE
);
371 event
.SetEventObject(this);
373 if (GetEventHandler()->ProcessEvent(event
)) return;
378 int wxTextCtrl::overflow( int WXUNUSED(c
) )
380 int len
= pptr() - pbase();
381 char *txt
= new char[len
+1];
382 strncpy(txt
, pbase(), len
);
385 setp(pbase(), epptr());
390 int wxTextCtrl::sync()
392 int len
= pptr() - pbase();
393 char *txt
= new char[len
+1];
394 strncpy(txt
, pbase(), len
);
397 setp(pbase(), epptr());
402 int wxTextCtrl::underflow()
407 wxTextCtrl
& wxTextCtrl::operator<<(const wxString
& s
)
413 wxTextCtrl
& wxTextCtrl::operator<<(float f
)
415 static char buf
[100];
416 sprintf(buf
, "%.2f", f
);
421 wxTextCtrl
& wxTextCtrl::operator<<(double d
)
423 static char buf
[100];
424 sprintf(buf
, "%.2f", d
);
429 wxTextCtrl
& wxTextCtrl::operator<<(int i
)
431 static char buf
[100];
432 sprintf(buf
, "%i", i
);
437 wxTextCtrl
& wxTextCtrl::operator<<(long i
)
439 static char buf
[100];
440 sprintf(buf
, "%ld", i
);
445 wxTextCtrl
& wxTextCtrl::operator<<(const char c
)
455 GtkWidget
* wxTextCtrl::GetConnectWidget()
457 return GTK_WIDGET(m_text
);
460 bool wxTextCtrl::IsOwnGtkWindow( GdkWindow
*window
)
462 if (m_windowStyle
& wxTE_MULTILINE
)
463 return (window
== GTK_TEXT(m_text
)->text_area
);
465 return (window
== GTK_ENTRY(m_text
)->text_area
);
468 void wxTextCtrl::SetFont( const wxFont
&font
)
470 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
472 if (((wxFont
*)&font
)->Ok())
475 m_font
= *wxSWISS_FONT
;
477 GtkStyle
*style
= gtk_widget_get_style( m_text
);
480 m_hasOwnStyle
= TRUE
;
481 style
= gtk_style_copy( gtk_widget_get_style( m_text
) );
484 gdk_font_unref( style
->font
);
485 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
487 gtk_widget_set_style( m_text
, style
);
490 void wxTextCtrl::SetBackgroundColour( const wxColour
&colour
)
494 wxCHECK_RET( m_text
!= NULL
, "invalid text ctrl" );
496 m_backgroundColour
= colour
;
497 if (!m_backgroundColour
.Ok()) return;
499 if (m_windowStyle
& wxTE_MULTILINE
)
501 GdkWindow
*window
= GTK_TEXT(m_text
)->text_area
;
502 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
503 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
504 gdk_window_clear( window
);
508 GtkStyle
*style
= gtk_widget_get_style( m_text
);
511 m_hasOwnStyle
= TRUE
;
512 style
= gtk_style_copy( gtk_widget_get_style( m_text
) );
515 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_text
->window
) );
516 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
517 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
519 gtk_widget_set_style( m_text
, style
);