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