The rounded corners look really dumb at this size.
[wxWidgets.git] / src / osx / iphone / textctrl.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/iphone/textctrl.mm
3 // Purpose:     wxTextCtrl
4 // Author:      Stefan Csomor
5 // Modified by: Ryan Norton (MLTE GetLineLength and GetLineText)
6 // Created:     1998-01-01
7 // Copyright:   (c) Stefan Csomor
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #include "wx/wxprec.h"
12
13 #if wxUSE_TEXTCTRL
14
15 #include "wx/textctrl.h"
16
17 #ifndef WX_PRECOMP
18     #include "wx/intl.h"
19     #include "wx/app.h"
20     #include "wx/utils.h"
21     #include "wx/dc.h"
22     #include "wx/button.h"
23     #include "wx/menu.h"
24     #include "wx/settings.h"
25     #include "wx/msgdlg.h"
26     #include "wx/toplevel.h"
27 #endif
28
29 #ifdef __DARWIN__
30     #include <sys/types.h>
31     #include <sys/stat.h>
32 #else
33     #include <stat.h>
34 #endif
35
36 #if wxUSE_STD_IOSTREAM
37     #if wxUSE_IOSTREAMH
38         #include <fstream.h>
39     #else
40         #include <fstream>
41     #endif
42 #endif
43
44 #include "wx/filefn.h"
45 #include "wx/sysopt.h"
46 #include "wx/thread.h"
47
48 #include "wx/osx/private.h"
49 #include "wx/osx/iphone/private/textimpl.h"
50
51 // currently for some reasong the UITextField leads to a recursion when the keyboard should be shown, so let's leave the code
52 // in case this gets resolved...
53
54 #define wxOSX_IPHONE_USE_TEXTFIELD 1
55
56 class wxMacEditHelper
57 {
58 public :
59     wxMacEditHelper( UITextView* textView )
60     {
61         m_textView = textView;
62         m_formerState = YES;
63         if ( textView )
64         {
65             m_formerState = [textView isEditable];
66             [textView setEditable:YES];
67         }
68     }
69
70     ~wxMacEditHelper()
71     {
72         if ( m_textView )
73             [m_textView setEditable:m_formerState];
74     }
75
76 protected :
77     BOOL m_formerState ;
78     UITextView* m_textView;
79 } ;
80
81 #if wxOSX_IPHONE_USE_TEXTFIELD
82
83 @interface  wxUITextFieldDelegate : NSObject<UITextFieldDelegate>
84 {
85 }
86
87 @end
88
89
90 @interface wxUITextField : UITextField
91 {
92 }
93
94 @end
95
96 @interface wxNSSecureTextField : UITextField<UITextFieldDelegate>
97 {
98 }
99
100 @end
101
102 @implementation wxNSSecureTextField
103
104 + (void)initialize
105 {
106     static BOOL initialized = NO;
107     if (!initialized)
108     {
109         initialized = YES;
110         wxOSXIPhoneClassAddWXMethods( self );
111     }
112 }
113
114 - (void)controlTextDidChange:(NSNotification *)aNotification
115 {
116     wxUnusedVar(aNotification);
117     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( self );
118     if ( impl )
119         impl->controlTextDidChange();
120 }
121
122 - (void)controlTextDidEndEditing:(NSNotification *)aNotification
123 {
124     wxUnusedVar(aNotification);
125     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( self );
126     if ( impl )
127     {
128         impl->DoNotifyFocusEvent( false, NULL );
129     }
130 }
131
132 @end
133
134 #if 0 
135 @implementation wxUITextFieldEditor
136
137 - (void) keyDown:(NSEvent*) event
138 {
139     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( (WXWidget) [self delegate] );
140     lastKeyDownEvent = event;
141     if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
142         [super keyDown:event];
143     lastKeyDownEvent = nil;
144 }
145
146 - (void) keyUp:(NSEvent*) event
147 {
148     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( (WXWidget) [self delegate] );
149     if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
150         [super keyUp:event];
151 }
152
153 - (void) flagsChanged:(NSEvent*) event
154 {
155     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( (WXWidget) [self delegate] );
156     if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
157         [super flagsChanged:event];
158 }
159
160 - (BOOL) performKeyEquivalent:(NSEvent*) event
161 {
162     BOOL retval = [super performKeyEquivalent:event];
163     return retval;
164 }
165
166 - (void) insertText:(id) str
167 {
168     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( (WXWidget) [self delegate] );
169     if ( impl == NULL || lastKeyDownEvent==nil || !impl->DoHandleCharEvent(lastKeyDownEvent, str) )
170     {
171         [super insertText:str];
172     }
173 }
174
175 @end
176
177 #endif
178
179
180 @implementation wxUITextFieldDelegate
181
182 - (BOOL)textFieldShouldReturn:(UITextField *)textField
183 {
184     // the user pressed the "Done" button, so dismiss the keyboard
185     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( textField );
186     if ( impl  )
187     {
188         wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
189         if ( wxpeer && wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER )
190         {
191             wxCommandEvent event(wxEVT_TEXT_ENTER, wxpeer->GetId());
192             event.SetEventObject( wxpeer );
193             event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
194             wxpeer->HandleWindowEvent( event );
195         }
196     }
197
198     [textField resignFirstResponder];
199     return YES;
200 }
201
202 /*
203 - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;        // return NO to disallow editing.
204 - (void)textFieldDidBeginEditing:(UITextField *)textField;           // became first responder
205 - (BOOL)textFieldShouldEndEditing:(UITextField *)textField;          // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
206 - (void)textFieldDidEndEditing:(UITextField *)textField;             // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
207
208 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;   // return NO to not change text
209
210 - (BOOL)textFieldShouldClear:(UITextField *)textField;               // called when clear button pressed. return NO to ignore (no notifications)
211 */
212
213 @end
214
215
216 @implementation wxUITextField
217
218 + (void)initialize
219 {
220     static BOOL initialized = NO;
221     if (!initialized)
222     {
223         initialized = YES;
224         wxOSXIPhoneClassAddWXMethods( self );
225     }
226 }
227
228 #if 0
229 - (void)controlTextDidChange:(NSNotification *)aNotification
230 {
231     wxUnusedVar(aNotification);
232     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( self );
233     if ( impl )
234         impl->controlTextDidChange();
235 }
236 #endif
237
238 - (BOOL)textFieldShouldReturn:(UITextField *)textField
239 {
240     wxUnusedVar(textField);
241     
242     
243     return NO;
244 }
245
246 - (void)controlTextDidEndEditing:(NSNotification *)aNotification
247 {
248     wxUnusedVar(aNotification);
249     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( self );
250     if ( impl )
251     {
252         impl->DoNotifyFocusEvent( false, NULL );
253     }
254 }
255 @end
256
257 #endif
258
259 @interface wxUITextViewDelegate : NSObject<UITextViewDelegate>
260 {
261 }
262
263 - (void)textViewDidChange:(UITextView *)textView;
264 - (void)textViewDidBeginEditing:(UITextView *)textView;
265 - (void)textViewDidEndEditing:(UITextView *)textView;
266 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
267
268 @end
269
270 @implementation wxUITextViewDelegate
271
272 - (void)textViewDidChange:(UITextView *)textView
273 {
274     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( textView );
275     if ( impl )
276         impl->controlTextDidChange();
277 }
278
279 - (void)textViewDidBeginEditing:(UITextView *)textView
280 {
281     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( textView );
282     if ( impl )
283         impl->DoNotifyFocusEvent(true, NULL);
284 }
285
286 - (void)textViewDidEndEditing:(UITextView *)textView
287 {
288     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( textView );
289     if ( impl )
290         impl->DoNotifyFocusEvent(false, NULL);
291 }
292
293 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
294 {
295     wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( textView );
296     if ( impl )
297     {
298         if ( !impl->GetWXPeer()->HasFlag(wxTE_MULTILINE) && [text isEqualToString:@"\n"])
299         {
300             [textView resignFirstResponder];
301             return NO;
302         }
303     }
304     return YES;
305 }
306
307
308 @end
309
310 //
311 // wxUITextViewControl
312 //
313
314 wxUITextViewControl::wxUITextViewControl( wxTextCtrl *wxPeer, UITextView* v) : 
315     wxWidgetIPhoneImpl(wxPeer, v),
316     wxTextWidgetImpl(wxPeer)
317 {
318     m_textView = v;
319     m_delegate= [[wxUITextViewDelegate alloc] init];
320     
321     [m_textView setDelegate:m_delegate];
322 }
323
324 wxUITextViewControl::~wxUITextViewControl()
325 {
326     if (m_textView)
327     {
328         [m_textView setDelegate: nil];
329     }
330     [m_delegate release];
331 }
332
333 bool wxUITextViewControl::CanFocus() const
334 {
335     return true;
336 }
337
338 wxString wxUITextViewControl::GetStringValue() const
339 {
340     if (m_textView)
341     {
342         wxString result = wxCFStringRef::AsString([m_textView text], m_wxPeer->GetFont().GetEncoding());
343         wxMacConvertNewlines13To10( &result ) ;
344         return result;
345     }
346     return wxEmptyString;
347 }
348
349 void wxUITextViewControl::SetStringValue( const wxString &str)
350 {
351     wxString st = str;
352     wxMacConvertNewlines10To13( &st );
353     wxMacEditHelper helper(m_textView);
354
355     if (m_textView)
356         [m_textView setText: wxCFStringRef( st , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
357 }
358
359 void wxUITextViewControl::Copy()
360 {
361     if (m_textView)
362         [m_textView copy:nil];
363
364 }
365
366 void wxUITextViewControl::Cut()
367 {
368     if (m_textView)
369         [m_textView cut:nil];
370 }
371
372 void wxUITextViewControl::Paste()
373 {
374     if (m_textView)
375         [m_textView paste:nil];
376 }
377
378 bool wxUITextViewControl::CanPaste() const
379 {
380     return true;
381 }
382
383 void wxUITextViewControl::SetEditable(bool editable)
384 {
385     if (m_textView)
386         [m_textView setEditable: editable];
387 }
388
389 void wxUITextViewControl::GetSelection( long* from, long* to) const
390 {
391     if (m_textView)
392     {
393         NSRange range = [m_textView selectedRange];
394         *from = range.location;
395         *to = range.location + range.length;
396     }
397 }
398
399 void wxUITextViewControl::SetSelection( long from , long to )
400 {
401     long textLength = [[m_textView text] length];
402     if ((from == -1) && (to == -1))
403     {
404         from = 0 ;
405         to = textLength ;
406     }
407     else
408     {
409         from = wxMin(textLength,wxMax(from,0)) ;
410         if ( to == -1 )
411             to = textLength;
412         else
413             to = wxMax(0,wxMin(textLength,to)) ;
414     }
415
416     NSRange selrange = NSMakeRange(from, to-from);
417     [m_textView setSelectedRange:selrange];
418     [m_textView scrollRangeToVisible:selrange];
419 }
420
421 void wxUITextViewControl::WriteText(const wxString& str)
422 {
423     wxString st = str;
424     wxMacConvertNewlines10To13( &st );
425     wxMacEditHelper helper(m_textView);
426     
427     wxCFStringRef insert( st , m_wxPeer->GetFont().GetEncoding() );
428     NSMutableString* subst = [NSMutableString stringWithString:[m_textView text]];
429     [subst replaceCharactersInRange:[m_textView selectedRange] withString:insert.AsNSString()];
430
431     [m_textView setText:subst];
432 }
433
434 void wxUITextViewControl::SetFont( const wxFont & font , const wxColour& WXUNUSED(foreground) , long WXUNUSED(windowStyle), bool WXUNUSED(ignoreBlack) )
435 {
436     if ([m_textView respondsToSelector:@selector(setFont:)])
437         [m_textView setFont: font.OSXGetUIFont()];
438 }
439
440 bool wxUITextViewControl::GetStyle(long position, wxTextAttr& style)
441 {
442     if (m_textView && position >=0)
443     {   
444         // UIFont* font = NULL;
445         // NSColor* bgcolor = NULL;
446         // NSColor* fgcolor = NULL;
447         // NOTE: It appears that other platforms accept GetStyle with the position == length
448         // but that UITextStorage does not accept length as a valid position.
449         // Therefore we return the default control style in that case.
450         /*
451         if (position < [[m_textView string] length]) 
452         {
453             UITextStorage* storage = [m_textView textStorage];
454             font = [[storage attribute:NSFontAttributeName atIndex:position effectiveRange:NULL] autorelease];
455             bgcolor = [[storage attribute:NSBackgroundColorAttributeName atIndex:position effectiveRange:NULL] autorelease];
456             fgcolor = [[storage attribute:NSForegroundColorAttributeName atIndex:position effectiveRange:NULL] autorelease];
457         }
458         else
459         {
460             NSDictionary* attrs = [m_textView typingAttributes];
461             font = [[attrs objectForKey:NSFontAttributeName] autorelease];
462             bgcolor = [[attrs objectForKey:NSBackgroundColorAttributeName] autorelease];
463             fgcolor = [[attrs objectForKey:NSForegroundColorAttributeName] autorelease];
464         }
465         */
466         /*
467         if (font)
468             style.SetFont(wxFont(font));
469         
470         if (bgcolor)
471             style.SetBackgroundColour(wxColour(bgcolor));
472             
473         if (fgcolor)
474             style.SetTextColour(wxColour(fgcolor));
475         */
476         return true;
477     }
478
479     return false;
480 }
481
482 void wxUITextViewControl::SetStyle(long start,
483                                 long end,
484                                 const wxTextAttr& style)
485 {
486     if (m_textView) {
487         NSRange range = NSMakeRange(start, end-start);
488         if (start == -1 && end == -1)
489             range = [m_textView selectedRange];
490 /*
491         UITextStorage* storage = [m_textView textStorage];
492         
493         wxFont font = style.GetFont();
494         if (style.HasFont() && font.IsOk())
495             [storage addAttribute:NSFontAttributeName value:font.OSXGetNSFont() range:range];
496         
497         wxColour bgcolor = style.GetBackgroundColour();
498         if (style.HasBackgroundColour() && bgcolor.IsOk())
499             [storage addAttribute:NSBackgroundColorAttributeName value:bgcolor.OSXGetNSColor() range:range];
500         
501         wxColour fgcolor = style.GetTextColour();
502         if (style.HasTextColour() && fgcolor.IsOk())
503             [storage addAttribute:NSForegroundColorAttributeName value:fgcolor.OSXGetNSColor() range:range];
504 */
505     }
506 }
507
508 void wxUITextViewControl::CheckSpelling(bool check)
509 {
510 }
511
512 wxSize wxUITextViewControl::GetBestSize() const
513 {
514     wxRect r;
515     
516     GetBestRect(&r);
517     
518     /*
519     if (m_textView && [m_textView layoutManager])
520     {
521         NSRect rect = [[m_textView layoutManager] usedRectForTextContainer: [m_textView textContainer]];
522         wxSize size = wxSize(rect.size.width, rect.size.height);
523         size.x += [m_textView textContainerInset].width;
524         size.y += [m_textView textContainerInset].height;
525         return size;
526     }
527     return wxSize(0,0);
528     */
529     
530     wxSize sz = r.GetSize();
531     if ( sz.y < 31 )
532         sz.y = 31;
533
534     return sz;
535 }
536
537 #if wxOSX_IPHONE_USE_TEXTFIELD
538
539 //
540 // wxUITextFieldControl
541 //
542
543 wxUITextFieldControl::wxUITextFieldControl( wxTextCtrl *wxPeer, UITextField* w ) : 
544     wxWidgetIPhoneImpl(wxPeer, w),
545     wxTextWidgetImpl(wxPeer)
546 {
547     m_textField = w;
548     m_delegate = [[wxUITextFieldDelegate alloc] init];
549     [m_textField setDelegate: m_delegate];
550     m_selStart = m_selEnd = 0;
551 }
552
553 wxUITextFieldControl::~wxUITextFieldControl()
554 {
555     if (m_textField)
556         [m_textField setDelegate: nil];
557     [m_delegate release];
558 }
559
560 wxString wxUITextFieldControl::GetStringValue() const
561 {
562     return wxCFStringRef::AsString([m_textField text], m_wxPeer->GetFont().GetEncoding());
563 }
564
565 void wxUITextFieldControl::SetStringValue( const wxString &str)
566 {
567 //    wxMacEditHelper helper(m_textField);
568     [m_textField setText: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
569 }
570
571 wxSize wxUITextFieldControl::GetBestSize() const
572 {
573     wxRect r;
574     
575     GetBestRect(&r);
576     wxSize sz = r.GetSize();
577     if ( sz.y < 31 )
578         sz.y = 31;
579     return sz;
580 }
581
582 void wxUITextFieldControl::Copy()
583 {
584     [m_textField copy:nil];
585 }
586
587 void wxUITextFieldControl::Cut()
588 {
589     [m_textField cut:nil];
590 }
591
592 void wxUITextFieldControl::Paste()
593 {
594     [m_textField paste:nil];
595 }
596
597 bool wxUITextFieldControl::CanPaste() const
598 {
599     return true;
600 }
601
602 void wxUITextFieldControl::SetEditable(bool editable)
603 {
604 }
605
606 void wxUITextFieldControl::GetSelection( long* from, long* to) const
607 {
608     *from = m_selStart;
609     *to = m_selEnd;
610 }
611
612 void wxUITextFieldControl::SetSelection( long from , long to )
613 {
614     long textLength = [[m_textField text] length];
615     if ((from == -1) && (to == -1))
616     {
617         from = 0 ;
618         to = textLength ;
619     }
620     else
621     {
622         from = wxMin(textLength,wxMax(from,0)) ;
623         if ( to == -1 )
624             to = textLength;
625         else
626             to = wxMax(0,wxMin(textLength,to)) ;
627     }
628
629     m_selStart = from;
630     m_selEnd = to;
631 }
632
633 void wxUITextFieldControl::WriteText(const wxString& str)
634 {
635 #if 0
636     NSEvent* formerEvent = m_lastKeyDownEvent;
637         UIText* editor = [m_textField currentEditor];
638     if ( editor )
639     {
640         wxMacEditHelper helper(m_textField);
641         [editor insertText:wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
642     }
643     else
644 #endif
645     {
646         wxString val = GetStringValue() ;
647         long start , end ;
648         GetSelection( &start , &end ) ;
649         val.Remove( start , end - start ) ;
650         val.insert( start , str ) ;
651         SetStringValue( val ) ;
652         SetSelection( start + str.length() , start + str.length() ) ;
653     }
654 #if 0
655     m_lastKeyDownEvent = formerEvent;
656 #endif
657 }
658
659 void wxUITextFieldControl::controlAction(WXWidget WXUNUSED(slf),
660     void* WXUNUSED(_cmd), void *WXUNUSED(sender))
661 {
662     wxWindow* wxpeer = (wxWindow*) GetWXPeer();
663     if ( wxpeer && (wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER) )
664     {
665         wxCommandEvent event(wxEVT_TEXT_ENTER, wxpeer->GetId());
666         event.SetEventObject( wxpeer );
667         event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
668         wxpeer->HandleWindowEvent( event );
669     }
670 }
671
672 bool wxUITextFieldControl::SetHint(const wxString& hint)
673 {
674     wxCFStringRef hintstring(hint);
675     [m_textField setPlaceholder:hintstring.AsNSString()];
676     return true;
677 }
678
679 #endif
680
681 //
682 //
683 //
684
685 wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
686                                     wxWindowMac* WXUNUSED(parent),
687                                     wxWindowID WXUNUSED(id),
688                                     const wxString& str,
689                                     const wxPoint& pos,
690                                     const wxSize& size,
691                                     long style,
692                                     long WXUNUSED(extraStyle))
693 {
694     CGRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
695     wxWidgetIPhoneImpl* c = NULL;
696     wxTextWidgetImpl* t = NULL;
697     id<UITextInputTraits> tv = nil;
698
699 #if wxOSX_IPHONE_USE_TEXTFIELD
700     if ( style & wxTE_MULTILINE || style & wxTE_RICH || style & wxTE_RICH2 )
701 #endif
702     {
703         UITextView * v = nil;
704         v = [[UITextView alloc] initWithFrame:r];
705         tv = v;
706         
707         wxUITextViewControl* tc = new wxUITextViewControl( wxpeer, v );
708         c = tc;
709         t = tc;
710     }
711 #if wxOSX_IPHONE_USE_TEXTFIELD
712     else
713     {
714         wxUITextField* v = [[wxUITextField alloc] initWithFrame:r];
715         tv = v;
716
717                 v.textColor = [UIColor blackColor];
718                 v.font = [UIFont systemFontOfSize:17.0];
719                 v.backgroundColor = [UIColor whiteColor];
720                 
721                 v.clearButtonMode = UITextFieldViewModeNever;
722                 
723         [v setBorderStyle:UITextBorderStyleBezel];
724         if ( style & wxNO_BORDER )
725             v.borderStyle = UITextBorderStyleNone;
726          
727         wxUITextFieldControl* tc = new wxUITextFieldControl( wxpeer, v );
728         c = tc;
729         t = tc;
730     }
731 #endif
732     
733     if ( style & wxTE_PASSWORD )
734         [tv setSecureTextEntry:YES];
735     
736     if ( !(style & wxTE_MULTILINE) )
737     {
738         [tv setAutocorrectionType:UITextAutocorrectionTypeNo];
739                 [tv setReturnKeyType:UIReturnKeyDone];
740     }
741     [tv setKeyboardType:UIKeyboardTypeDefault];
742     
743     t->SetStringValue(str);
744     
745     return c;
746 }
747
748
749 #endif // wxUSE_TEXTCTRL