]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/textctrl.cpp
* added gtk_text_changed callback and implemented DiscardEdits(), so that
[wxWidgets.git] / src / gtk / textctrl.cpp
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
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "textctrl.h"
13 #endif
14
15 #include "wx/textctrl.h"
16 #include "wx/utils.h"
17
18 //-----------------------------------------------------------------------------
19 // wxTextCtrl
20 //-----------------------------------------------------------------------------
21
22 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl,wxControl)
23
24 void gtk_text_changed_callback( GtkWidget *WXUNUSED(widget), wxTextCtrl *win )
25 {
26 win->m_modified = TRUE;
27 };
28
29
30 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
31 // EVT_CHAR(wxTextCtrl::OnChar)
32 END_EVENT_TABLE()
33
34 wxTextCtrl::wxTextCtrl(void) : streambuf()
35 {
36 m_modified = FALSE;
37 };
38
39 wxTextCtrl::wxTextCtrl( wxWindow *parent, const wxWindowID id, const wxString &value,
40 const wxPoint &pos, const wxSize &size,
41 const int style, const wxString &name ) : streambuf()
42 {
43 m_modified = FALSE;
44 Create( parent, id, value, pos, size, style, name );
45 };
46
47 bool wxTextCtrl::Create( wxWindow *parent, const wxWindowID id, const wxString &value,
48 const wxPoint &pos, const wxSize &size,
49 const int style, const wxString &name )
50 {
51 m_needParent = TRUE;
52
53 PreCreation( parent, id, pos, size, style, name );
54
55 if (style & wxTE_MULTILINE)
56 m_widget = gtk_text_new( NULL, NULL );
57 else
58 m_widget = gtk_entry_new();
59
60 wxSize newSize = size;
61 if (newSize.x == -1) newSize.x = 80;
62 if (newSize.y == -1) newSize.y = 26;
63 SetSize( newSize.x, newSize.y );
64
65 PostCreation();
66
67 // we want to be notified about text changes
68 gtk_signal_connect(GTK_OBJECT(m_widget), "changed",
69 GTK_SIGNAL_FUNC(gtk_text_changed_callback),
70 (gpointer)this);
71
72 if (!value.IsNull())
73 {
74 gint tmp = 0;
75 gtk_editable_insert_text( GTK_EDITABLE(m_widget), value, value.Length(), &tmp );
76 };
77
78 if (style & wxREADONLY)
79 {
80 }
81 else
82 {
83 if (style & wxTE_MULTILINE) gtk_text_set_editable( GTK_TEXT(m_widget), 1 );
84 };
85
86 Show( TRUE );
87
88 return TRUE;
89 };
90
91 wxString wxTextCtrl::GetValue(void) const
92 {
93 wxString tmp;
94 if (m_windowStyle & wxTE_MULTILINE)
95 {
96 gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
97 tmp = gtk_editable_get_chars( GTK_EDITABLE(m_widget), 0, len );
98 }
99 else
100 {
101 tmp = gtk_entry_get_text( GTK_ENTRY(m_widget) );
102 };
103 return tmp;
104 };
105
106 void wxTextCtrl::SetValue( const wxString &value )
107 {
108 wxString tmp = "";
109 if (!value.IsNull()) tmp = value;
110 if (m_windowStyle & wxTE_MULTILINE)
111 {
112 gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
113 gtk_editable_delete_text( GTK_EDITABLE(m_widget), 0, len );
114 len = 0;
115 gtk_editable_insert_text( GTK_EDITABLE(m_widget), tmp, tmp.Length(), &len );
116 }
117 else
118 {
119 gtk_entry_set_text( GTK_ENTRY(m_widget), tmp );
120 };
121 };
122
123 void wxTextCtrl::WriteText( const wxString &text )
124 {
125 if (text.IsNull()) return;
126
127 if (m_windowStyle & wxTE_MULTILINE)
128 {
129 gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
130 gtk_editable_insert_text( GTK_EDITABLE(m_widget), text, text.Length(), &len );
131 }
132 else
133 {
134 gtk_entry_append_text( GTK_ENTRY(m_widget), text );
135 };
136 };
137
138 bool wxTextCtrl::LoadFile( const wxString &WXUNUSED(file) )
139 {
140 wxFAIL_MSG("wxTextCtrl::LoadFile not implemented");
141
142 return FALSE;
143 };
144
145 bool wxTextCtrl::SaveFile( const wxString &WXUNUSED(file) )
146 {
147 wxFAIL_MSG("wxTextCtrl::SaveFile not implemented");
148
149 return FALSE;
150 };
151
152 bool wxTextCtrl::IsModified(void)
153 {
154 return m_modified;
155 };
156
157 void wxTextCtrl::DiscardEdits(void)
158 {
159 m_modified = FALSE;
160 };
161
162 /*
163 wxString wxTextCtrl::GetLineText( const long lineNo ) const
164 {
165 };
166
167
168 void wxTextCtrl::OnDropFiles( wxDropFilesEvent &event )
169 {
170 };
171
172 long wxTextCtrl::PositionToXY( const long pos, long *x, long *y ) const
173 {
174 };
175
176 long wxTextCtrl::XYToPosition( const long x, const long y )
177 {
178 };
179
180 int wxTextCtrl::GetNumberOfLines(void)
181 {
182 };
183
184 */
185 void wxTextCtrl::SetInsertionPoint( const long pos )
186 {
187 int tmp = (int) pos;
188 if (m_windowStyle & wxTE_MULTILINE)
189 gtk_text_set_point( GTK_TEXT(m_widget), tmp );
190 else
191 gtk_entry_set_position( GTK_ENTRY(m_widget), tmp );
192 };
193
194 void wxTextCtrl::SetInsertionPointEnd(void)
195 {
196 int pos = 0;
197 if (m_windowStyle & wxTE_MULTILINE)
198 pos = gtk_text_get_length( GTK_TEXT(m_widget) );
199 else
200 pos = GTK_ENTRY(m_widget)->text_length;
201 SetInsertionPoint( pos-1 );
202 };
203
204 void wxTextCtrl::SetEditable( const bool editable )
205 {
206 if (m_windowStyle & wxTE_MULTILINE)
207 gtk_text_set_editable( GTK_TEXT(m_widget), editable );
208 else
209 gtk_entry_set_editable( GTK_ENTRY(m_widget), editable );
210 };
211
212 void wxTextCtrl::SetSelection( const long from, const long to )
213 {
214 gtk_editable_select_region( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
215 };
216
217 void wxTextCtrl::ShowPosition( const long WXUNUSED(pos) )
218 {
219 wxFAIL_MSG("wxTextCtrl::ShowPosition not implemented");
220 };
221
222 long wxTextCtrl::GetInsertionPoint(void) const
223 {
224 return (long) GTK_EDITABLE(m_widget)->current_pos;
225 };
226
227 long wxTextCtrl::GetLastPosition(void) const
228 {
229 int pos = 0;
230 if (m_windowStyle & wxTE_MULTILINE)
231 pos = gtk_text_get_length( GTK_TEXT(m_widget) );
232 else
233 pos = GTK_ENTRY(m_widget)->text_length;
234 return (long)pos-1;
235 };
236
237 void wxTextCtrl::Remove( const long from, const long to )
238 {
239 gtk_editable_delete_text( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
240 };
241
242 void wxTextCtrl::Replace( const long from, const long to, const wxString &value )
243 {
244 gtk_editable_delete_text( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
245 if (value.IsNull()) return;
246 gint pos = (gint)to;
247 gtk_editable_insert_text( GTK_EDITABLE(m_widget), value, value.Length(), &pos );
248 };
249
250 void wxTextCtrl::Cut(void)
251 {
252 gtk_editable_cut_clipboard( GTK_EDITABLE(m_widget), 0 );
253 };
254
255 void wxTextCtrl::Copy(void)
256 {
257 gtk_editable_copy_clipboard( GTK_EDITABLE(m_widget), 0 );
258 };
259
260 void wxTextCtrl::Paste(void)
261 {
262 gtk_editable_paste_clipboard( GTK_EDITABLE(m_widget), 0 );
263 };
264
265 void wxTextCtrl::Delete(void)
266 {
267 SetValue( "" );
268 };
269
270 void wxTextCtrl::OnChar( wxKeyEvent &WXUNUSED(event) )
271 {
272 };
273
274 int wxTextCtrl::overflow(int c)
275 {
276 // Make sure there is a holding area
277 if ( allocate()==EOF )
278 {
279 wxError("Streambuf allocation failed","Internal error");
280 return EOF;
281 }
282
283 // Verify that there are no characters in get area
284 if ( gptr() && gptr() < egptr() )
285 {
286 wxError("Who's trespassing my get area?","Internal error");
287 return EOF;
288 }
289
290 // Reset get area
291 setg(0,0,0);
292
293 // Make sure there is a put area
294 if ( ! pptr() )
295 {
296 /* This doesn't seem to be fatal so comment out error message */
297 // wxError("Put area not opened","Internal error");
298 setp( base(), base() );
299 }
300
301 // Determine how many characters have been inserted but no consumed
302 int plen = pptr() - pbase();
303
304 // Now Jerry relies on the fact that the buffer is at least 2 chars
305 // long, but the holding area "may be as small as 1" ???
306 // And we need an additional \0, so let's keep this inefficient but
307 // safe copy.
308
309 // If c!=EOF, it is a character that must also be comsumed
310 int xtra = c==EOF? 0 : 1;
311
312 // Write temporary C-string to wxTextWindow
313 {
314 char *txt = new char[plen+xtra+1];
315 memcpy(txt, pbase(), plen);
316 txt[plen] = (char)c; // append c
317 txt[plen+xtra] = '\0'; // append '\0' or overwrite c
318 // If the put area already contained \0, output will be truncated there
319 WriteText(txt);
320 delete[] txt;
321 }
322
323 // Reset put area
324 setp(pbase(), epptr());
325
326 #if defined(__WATCOMC__)
327 return __NOT_EOF;
328 #elif defined(zapeof) // HP-UX (all cfront based?)
329 return zapeof(c);
330 #else
331 return c!=EOF ? c : 0; // this should make everybody happy
332 #endif
333
334 /* OLD CODE
335 int len = pptr() - pbase();
336 char *txt = new char[len+1];
337 strncpy(txt, pbase(), len);
338 txt[len] = '\0';
339 (*this) << txt;
340 setp(pbase(), epptr());
341 delete[] txt;
342 return EOF;
343 */
344 };
345
346 int wxTextCtrl::sync(void)
347 {
348 // Verify that there are no characters in get area
349 if ( gptr() && gptr() < egptr() )
350 {
351 wxError("Who's trespassing my get area?","Internal error");
352 return EOF;
353 }
354
355 if ( pptr() && pptr() > pbase() ) return overflow(EOF);
356
357 return 0;
358 /* OLD CODE
359 int len = pptr() - pbase();
360 char *txt = new char[len+1];
361 strncpy(txt, pbase(), len);
362 txt[len] = '\0';
363 (*this) << txt;
364 setp(pbase(), epptr());
365 delete[] txt;
366 return 0;
367 */
368 };
369
370 int wxTextCtrl::underflow(void)
371 {
372 return EOF;
373 };
374
375 wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
376 {
377 WriteText(s);
378 return *this;
379 }
380
381 wxTextCtrl& wxTextCtrl::operator<<(const float f)
382 {
383 static char buf[100];
384 sprintf(buf, "%.2f", f);
385 WriteText(buf);
386 return *this;
387 }
388
389 wxTextCtrl& wxTextCtrl::operator<<(const double d)
390 {
391 static char buf[100];
392 sprintf(buf, "%.2f", d);
393 WriteText(buf);
394 return *this;
395 }
396
397 wxTextCtrl& wxTextCtrl::operator<<(const int i)
398 {
399 static char buf[100];
400 sprintf(buf, "%i", i);
401 WriteText(buf);
402 return *this;
403 }
404
405 wxTextCtrl& wxTextCtrl::operator<<(const long i)
406 {
407 static char buf[100];
408 sprintf(buf, "%ld", i);
409 WriteText(buf);
410 return *this;
411 }
412
413 wxTextCtrl& wxTextCtrl::operator<<(const char c)
414 {
415 char buf[2];
416
417 buf[0] = c;
418 buf[1] = 0;
419 WriteText(buf);
420 return *this;
421 }
422