]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/textctrl.cpp
More Motif stuff incl. beginnings of wxToolBar
[wxWidgets.git] / src / gtk1 / textctrl.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: textctrl.cpp
3// Purpose:
4// Author: Robert Roebling
5// Created: 01/02/97
6// Id:
7// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
13289f04 8// Licence: wxWindows licence
c801d85f
KB
9/////////////////////////////////////////////////////////////////////////////
10
11#ifdef __GNUG__
12#pragma implementation "textctrl.h"
13#endif
14
15#include "wx/textctrl.h"
16#include "wx/utils.h"
1a5a8367 17#include <wx/intl.h>
c801d85f
KB
18
19//-----------------------------------------------------------------------------
2f2aa628 20// "changed"
c801d85f
KB
21//-----------------------------------------------------------------------------
22
6de97a3b 23static void gtk_text_changed_callback( GtkWidget *WXUNUSED(widget), wxTextCtrl *win )
484e45bf 24{
9406d962 25 win->SetModified();
903f689b
RR
26
27 wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, win->m_windowId );
28 wxString val( win->GetValue() );
29 if (!val.IsNull()) event.m_commandString = WXSTRINGCAST val;
30 event.SetEventObject( win );
31 win->GetEventHandler()->ProcessEvent( event );
6de97a3b 32}
112892b9 33
2f2aa628
RR
34//-----------------------------------------------------------------------------
35// wxTextCtrl
36//-----------------------------------------------------------------------------
37
38IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl,wxControl)
39
c801d85f 40BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
903f689b 41 EVT_CHAR(wxTextCtrl::OnChar)
c801d85f
KB
42END_EVENT_TABLE()
43
03f38c58 44wxTextCtrl::wxTextCtrl() : streambuf()
c801d85f 45{
6de97a3b 46 if (allocate()) setp(base(),ebuf());
13289f04 47
112892b9 48 m_modified = FALSE;
6de97a3b 49}
c801d85f 50
debe6624 51wxTextCtrl::wxTextCtrl( wxWindow *parent, wxWindowID id, const wxString &value,
484e45bf 52 const wxPoint &pos, const wxSize &size,
6de97a3b 53 int style, const wxValidator& validator, const wxString &name ) : streambuf()
c801d85f 54{
6de97a3b 55 if (allocate()) setp(base(),ebuf());
13289f04 56
112892b9 57 m_modified = FALSE;
6de97a3b
RR
58 Create( parent, id, value, pos, size, style, validator, name );
59}
c801d85f 60
debe6624 61bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value,
484e45bf 62 const wxPoint &pos, const wxSize &size,
6de97a3b 63 int style, const wxValidator& validator, const wxString &name )
c801d85f
KB
64{
65 m_needParent = TRUE;
484e45bf 66
c801d85f 67 PreCreation( parent, id, pos, size, style, name );
484e45bf 68
6de97a3b
RR
69 SetValidator( validator );
70
13289f04 71 bool bMultiLine = (style & wxTE_MULTILINE) != 0;
5796ed40 72 if ( bMultiLine )
47908e25 73 {
13289f04
VZ
74 // a multi-line edit control: create a vertical scrollbar by default and
75 // horizontal if requested
76 bool bHasHScrollbar = (style & wxHSCROLL) != 0;
77
78 // create our control...
c67daf87 79 m_text = gtk_text_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
13289f04
VZ
80
81 // ... and put into the upper left hand corner of the table
82 m_widget = gtk_table_new(bHasHScrollbar ? 2 : 1, 2, FALSE);
83 gtk_table_attach(GTK_TABLE(m_widget), m_text, 0, 1, 0, 1,
84 GTK_FILL | GTK_EXPAND,
85 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
86 0, 0);
87
88 // put the horizontal scrollbar in the lower left hand corner
903f689b
RR
89 if (bHasHScrollbar)
90 {
13289f04
VZ
91 GtkWidget *hscrollbar = gtk_hscrollbar_new(GTK_TEXT(m_text)->hadj);
92 gtk_table_attach(GTK_TABLE(m_widget), hscrollbar, 0, 1, 1, 2,
93 GTK_EXPAND | GTK_FILL,
94 GTK_FILL,
95 0, 0);
96 gtk_widget_show(hscrollbar);
97 }
98
99 // finally, put the vertical scrollbar in the upper right corner
100 GtkWidget *vscrollbar = gtk_vscrollbar_new(GTK_TEXT(m_text)->vadj);
101 gtk_table_attach(GTK_TABLE(m_widget), vscrollbar, 1, 2, 0, 1,
102 GTK_FILL,
103 GTK_EXPAND | GTK_FILL | GTK_SHRINK,
104 0, 0);
903f689b 105 gtk_widget_show( vscrollbar );
13289f04 106 }
903f689b
RR
107 else
108 {
13289f04
VZ
109 // a single-line text control: no need for scrollbars
110 m_widget =
111 m_text = gtk_entry_new();
112 }
484e45bf 113
c801d85f
KB
114 wxSize newSize = size;
115 if (newSize.x == -1) newSize.x = 80;
116 if (newSize.y == -1) newSize.y = 26;
117 SetSize( newSize.x, newSize.y );
484e45bf 118
c801d85f 119 PostCreation();
484e45bf 120
903f689b
RR
121 if (bMultiLine)
122 {
13289f04
VZ
123 gtk_widget_realize(m_text);
124 gtk_widget_show(m_text);
125 }
126
484e45bf 127 // we want to be notified about text changes
13289f04 128 gtk_signal_connect(GTK_OBJECT(m_text), "changed",
484e45bf
VZ
129 GTK_SIGNAL_FUNC(gtk_text_changed_callback),
130 (gpointer)this);
131
7f4dc78d
RR
132 if (!value.IsNull())
133 {
134 gint tmp = 0;
13289f04 135 gtk_editable_insert_text( GTK_EDITABLE(m_text), value, value.Length(), &tmp );
6de97a3b 136 }
484e45bf 137
5796ed40 138 if (style & wxTE_READONLY)
112892b9
RR
139 {
140 }
141 else
142 {
903f689b 143 if (bMultiLine)
13289f04 144 gtk_text_set_editable( GTK_TEXT(m_text), 1 );
6de97a3b 145 }
484e45bf 146
c801d85f 147 Show( TRUE );
484e45bf 148
c801d85f 149 return TRUE;
6de97a3b 150}
c801d85f 151
03f38c58 152wxString wxTextCtrl::GetValue() const
c801d85f
KB
153{
154 wxString tmp;
155 if (m_windowStyle & wxTE_MULTILINE)
156 {
13289f04
VZ
157 gint len = gtk_text_get_length( GTK_TEXT(m_text) );
158 tmp = gtk_editable_get_chars( GTK_EDITABLE(m_text), 0, len );
c801d85f
KB
159 }
160 else
161 {
13289f04 162 tmp = gtk_entry_get_text( GTK_ENTRY(m_text) );
6de97a3b 163 }
c801d85f 164 return tmp;
6de97a3b 165}
c801d85f
KB
166
167void wxTextCtrl::SetValue( const wxString &value )
168{
169 wxString tmp = "";
170 if (!value.IsNull()) tmp = value;
171 if (m_windowStyle & wxTE_MULTILINE)
172 {
13289f04
VZ
173 gint len = gtk_text_get_length( GTK_TEXT(m_text) );
174 gtk_editable_delete_text( GTK_EDITABLE(m_text), 0, len );
c801d85f 175 len = 0;
13289f04 176 gtk_editable_insert_text( GTK_EDITABLE(m_text), tmp, tmp.Length(), &len );
c801d85f
KB
177 }
178 else
179 {
13289f04 180 gtk_entry_set_text( GTK_ENTRY(m_text), tmp );
6de97a3b
RR
181 }
182}
c801d85f
KB
183
184void wxTextCtrl::WriteText( const wxString &text )
185{
186 if (text.IsNull()) return;
484e45bf 187
c801d85f
KB
188 if (m_windowStyle & wxTE_MULTILINE)
189 {
13289f04
VZ
190 gint len = gtk_text_get_length( GTK_TEXT(m_text) );
191 gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
c801d85f
KB
192 }
193 else
194 {
13289f04 195 gtk_entry_append_text( GTK_ENTRY(m_text), text );
6de97a3b
RR
196 }
197}
c801d85f 198
112892b9 199bool wxTextCtrl::LoadFile( const wxString &WXUNUSED(file) )
c801d85f 200{
6de97a3b 201 wxFAIL_MSG( "wxTextCtrl::LoadFile not implemented" );
2ad3a34e 202
112892b9 203 return FALSE;
6de97a3b 204}
c801d85f 205
112892b9 206bool wxTextCtrl::SaveFile( const wxString &WXUNUSED(file) )
c801d85f 207{
6de97a3b 208 wxFAIL_MSG( "wxTextCtrl::SaveFile not implemented" );
2ad3a34e 209
112892b9 210 return FALSE;
6de97a3b 211}
c801d85f 212
112892b9 213/*
debe6624 214wxString wxTextCtrl::GetLineText( long lineNo ) const
c801d85f 215{
6de97a3b 216}
c801d85f 217
112892b9 218
c801d85f
KB
219void wxTextCtrl::OnDropFiles( wxDropFilesEvent &event )
220{
6de97a3b 221}
c801d85f 222
debe6624 223long wxTextCtrl::PositionToXY( long pos, long *x, long *y ) const
c801d85f 224{
6de97a3b 225}
c801d85f 226
debe6624 227long wxTextCtrl::XYToPosition( long x, long y )
c801d85f 228{
6de97a3b 229}
c801d85f 230
03f38c58 231int wxTextCtrl::GetNumberOfLines()
c801d85f 232{
6de97a3b 233}
c801d85f
KB
234
235*/
debe6624 236void wxTextCtrl::SetInsertionPoint( long pos )
c801d85f
KB
237{
238 int tmp = (int) pos;
239 if (m_windowStyle & wxTE_MULTILINE)
13289f04 240 gtk_text_set_point( GTK_TEXT(m_text), tmp );
c801d85f 241 else
13289f04 242 gtk_entry_set_position( GTK_ENTRY(m_text), tmp );
6de97a3b 243}
c801d85f 244
03f38c58 245void wxTextCtrl::SetInsertionPointEnd()
c801d85f
KB
246{
247 int pos = 0;
248 if (m_windowStyle & wxTE_MULTILINE)
13289f04 249 pos = gtk_text_get_length( GTK_TEXT(m_text) );
c801d85f 250 else
13289f04 251 pos = GTK_ENTRY(m_text)->text_length;
c801d85f 252 SetInsertionPoint( pos-1 );
6de97a3b 253}
c801d85f 254
debe6624 255void wxTextCtrl::SetEditable( bool editable )
c801d85f
KB
256{
257 if (m_windowStyle & wxTE_MULTILINE)
13289f04 258 gtk_text_set_editable( GTK_TEXT(m_text), editable );
c801d85f 259 else
13289f04 260 gtk_entry_set_editable( GTK_ENTRY(m_text), editable );
6de97a3b 261}
c801d85f 262
debe6624 263void wxTextCtrl::SetSelection( long from, long to )
c801d85f 264{
13289f04 265 gtk_editable_select_region( GTK_EDITABLE(m_text), (gint)from, (gint)to );
6de97a3b 266}
c801d85f 267
debe6624 268void wxTextCtrl::ShowPosition( long WXUNUSED(pos) )
c801d85f 269{
1a5a8367 270 wxFAIL_MSG(_("wxTextCtrl::ShowPosition not implemented"));
6de97a3b 271}
c801d85f 272
03f38c58 273long wxTextCtrl::GetInsertionPoint() const
c801d85f 274{
13289f04 275 return (long) GTK_EDITABLE(m_text)->current_pos;
6de97a3b 276}
c801d85f 277
03f38c58 278long wxTextCtrl::GetLastPosition() const
c801d85f
KB
279{
280 int pos = 0;
281 if (m_windowStyle & wxTE_MULTILINE)
13289f04 282 pos = gtk_text_get_length( GTK_TEXT(m_text) );
c801d85f 283 else
13289f04 284 pos = GTK_ENTRY(m_text)->text_length;
c801d85f 285 return (long)pos-1;
6de97a3b 286}
c801d85f 287
debe6624 288void wxTextCtrl::Remove( long from, long to )
c801d85f 289{
13289f04 290 gtk_editable_delete_text( GTK_EDITABLE(m_text), (gint)from, (gint)to );
6de97a3b 291}
c801d85f 292
debe6624 293void wxTextCtrl::Replace( long from, long to, const wxString &value )
c801d85f 294{
13289f04 295 gtk_editable_delete_text( GTK_EDITABLE(m_text), (gint)from, (gint)to );
c801d85f
KB
296 if (value.IsNull()) return;
297 gint pos = (gint)to;
13289f04 298 gtk_editable_insert_text( GTK_EDITABLE(m_text), value, value.Length(), &pos );
6de97a3b 299}
c801d85f 300
03f38c58 301void wxTextCtrl::Cut()
c801d85f 302{
75ed1d15
GL
303#if (GTK_MINOR_VERSION == 1)
304 gtk_editable_cut_clipboard( GTK_EDITABLE(m_text) );
305#else
13289f04 306 gtk_editable_cut_clipboard( GTK_EDITABLE(m_text), 0 );
75ed1d15 307#endif
6de97a3b 308}
c801d85f 309
03f38c58 310void wxTextCtrl::Copy()
c801d85f 311{
75ed1d15
GL
312#if (GTK_MINOR_VERSION == 1)
313 gtk_editable_copy_clipboard( GTK_EDITABLE(m_text) );
314#else
13289f04 315 gtk_editable_copy_clipboard( GTK_EDITABLE(m_text), 0 );
75ed1d15 316#endif
6de97a3b 317}
c801d85f 318
03f38c58 319void wxTextCtrl::Paste()
c801d85f 320{
75ed1d15
GL
321#if (GTK_MINOR_VERSION == 1)
322 gtk_editable_paste_clipboard( GTK_EDITABLE(m_text) );
323#else
13289f04 324 gtk_editable_paste_clipboard( GTK_EDITABLE(m_text), 0 );
75ed1d15 325#endif
6de97a3b 326}
c801d85f 327
03f38c58 328void wxTextCtrl::Clear()
c801d85f
KB
329{
330 SetValue( "" );
6de97a3b 331}
c801d85f 332
903f689b 333void wxTextCtrl::OnChar( wxKeyEvent &key_event )
c801d85f 334{
903f689b
RR
335 if ((key_event.KeyCode() == WXK_RETURN) && (m_windowStyle & wxPROCESS_ENTER))
336 {
337 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
338 event.SetEventObject(this);
903f689b
RR
339 if (GetEventHandler()->ProcessEvent(event)) return;
340 }
341 else if (key_event.KeyCode() == WXK_TAB)
342 {
343 wxNavigationKeyEvent event;
344 event.SetDirection( key_event.m_shiftDown );
345 event.SetWindowChange(FALSE);
346 event.SetEventObject(this);
347
348 if (GetEventHandler()->ProcessEvent(event)) return;
349 }
350 key_event.Skip();
6de97a3b 351}
c801d85f 352
46dc76ba 353int wxTextCtrl::overflow( int WXUNUSED(c) )
c801d85f 354{
c801d85f
KB
355 int len = pptr() - pbase();
356 char *txt = new char[len+1];
357 strncpy(txt, pbase(), len);
358 txt[len] = '\0';
359 (*this) << txt;
360 setp(pbase(), epptr());
361 delete[] txt;
362 return EOF;
6de97a3b 363}
c801d85f 364
03f38c58 365int wxTextCtrl::sync()
c801d85f 366{
c801d85f
KB
367 int len = pptr() - pbase();
368 char *txt = new char[len+1];
369 strncpy(txt, pbase(), len);
370 txt[len] = '\0';
371 (*this) << txt;
372 setp(pbase(), epptr());
373 delete[] txt;
374 return 0;
6de97a3b 375}
c801d85f 376
03f38c58 377int wxTextCtrl::underflow()
c801d85f
KB
378{
379 return EOF;
6de97a3b 380}
c801d85f
KB
381
382wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
383{
384 WriteText(s);
385 return *this;
386}
387
debe6624 388wxTextCtrl& wxTextCtrl::operator<<(float f)
c801d85f
KB
389{
390 static char buf[100];
391 sprintf(buf, "%.2f", f);
392 WriteText(buf);
393 return *this;
394}
395
debe6624 396wxTextCtrl& wxTextCtrl::operator<<(double d)
c801d85f
KB
397{
398 static char buf[100];
399 sprintf(buf, "%.2f", d);
400 WriteText(buf);
401 return *this;
402}
403
debe6624 404wxTextCtrl& wxTextCtrl::operator<<(int i)
c801d85f
KB
405{
406 static char buf[100];
407 sprintf(buf, "%i", i);
408 WriteText(buf);
409 return *this;
410}
411
debe6624 412wxTextCtrl& wxTextCtrl::operator<<(long i)
c801d85f
KB
413{
414 static char buf[100];
415 sprintf(buf, "%ld", i);
416 WriteText(buf);
417 return *this;
418}
419
420wxTextCtrl& wxTextCtrl::operator<<(const char c)
421{
422 char buf[2];
423
424 buf[0] = c;
425 buf[1] = 0;
426 WriteText(buf);
427 return *this;
428}
429
03f38c58 430GtkWidget* wxTextCtrl::GetConnectWidget()
e3e65dac
RR
431{
432 return GTK_WIDGET(m_text);
6de97a3b 433}
e3e65dac 434
903f689b
RR
435bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window )
436{
437 if (m_windowStyle & wxTE_MULTILINE)
438 return (window == GTK_TEXT(m_text)->text_area);
439 else
440 return (window == GTK_ENTRY(m_text)->text_area);
441}
e3e65dac 442
868a2826
RR
443void wxTextCtrl::SetFont( const wxFont &font )
444{
3f659fd6
RR
445 if (((wxFont*)&font)->Ok())
446 m_font = font;
447 else
448 m_font = *wxSWISS_FONT;
868a2826
RR
449
450 GtkStyle *style = (GtkStyle*) NULL;
451 if (!m_hasOwnStyle)
452 {
453 m_hasOwnStyle = TRUE;
454 style = gtk_style_copy( gtk_widget_get_style( m_text ) );
455 }
456 else
457 {
458 style = gtk_widget_get_style( m_text );
459 }
460
461 gdk_font_unref( style->font );
462 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
463
464 gtk_widget_set_style( m_text, style );
465}
e3e65dac 466
68dda785
VZ
467// as our GTK widget is m_text and not m_widget, we have to override
468// SetBackgroundColour() to make it work
469void wxTextCtrl::SetBackgroundColour( const wxColour &colour )
470{
471 wxCHECK_RET( m_text != NULL, "invalid text ctrl" );
5796ed40 472
68dda785
VZ
473 // NB: the GtkEntry and GtkText classes have text_area at the same offset
474 SetBackgroundColourHelper( colour, GTK_TEXT(m_text)->text_area );
475}