1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/textctrl.mm
4 // Author: Stefan Csomor
5 // Modified by: Ryan Norton (MLTE GetLineLength and GetLineText)
7 // RCS-ID: $Id: textctrl.cpp 54820 2008-07-29 20:04:11Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #include "wx/textctrl.h"
23 #include "wx/button.h"
25 #include "wx/settings.h"
26 #include "wx/msgdlg.h"
27 #include "wx/toplevel.h"
31 #include <sys/types.h>
37 #if wxUSE_STD_IOSTREAM
45 #include "wx/filefn.h"
46 #include "wx/sysopt.h"
47 #include "wx/thread.h"
49 #include "wx/osx/private.h"
50 #include "wx/osx/cocoa/private/textimpl.h"
52 @interface wxNSSecureTextField : NSSecureTextField
54 wxWidgetCocoaImpl* impl;
57 - (void) setImplementation:(wxWidgetCocoaImpl*) item;
58 - (wxWidgetCocoaImpl*) implementation;
61 @implementation wxNSSecureTextField
65 static BOOL initialized = NO;
69 wxOSXCocoaClassAddWXMethods( self );
73 - (wxWidgetCocoaImpl*) implementation
78 - (void) setImplementation:(wxWidgetCocoaImpl*) item
83 - (void)controlTextDidChange:(NSNotification *)aNotification
87 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
89 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
90 event.SetEventObject( wxpeer );
91 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
92 wxpeer->HandleWindowEvent( event );
99 @interface wxNSTextView : NSScrollView
101 wxWidgetCocoaImpl* impl;
104 - (void) setImplementation:(wxWidgetCocoaImpl*) item;
105 - (wxWidgetCocoaImpl*) implementation;
108 @implementation wxNSTextView
112 static BOOL initialized = NO;
116 wxOSXCocoaClassAddWXMethods( self );
120 - (wxWidgetCocoaImpl*) implementation
125 - (void) setImplementation:(wxWidgetCocoaImpl*) item
131 - (void)textDidChange:(NSNotification *)aNotification
135 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
137 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
138 event.SetEventObject( wxpeer );
139 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
140 wxpeer->HandleWindowEvent( event );
145 - (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)commandSelector
149 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
150 if (commandSelector == @selector(insertNewline:))
152 if ( wxpeer && wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER )
154 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
155 event.SetEventObject( wxpeer );
156 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
157 wxpeer->HandleWindowEvent( event );
166 @implementation wxNSTextField
170 static BOOL initialized = NO;
174 wxOSXCocoaClassAddWXMethods( self );
178 - (wxWidgetCocoaImpl*) implementation
183 - (void) setImplementation:(wxWidgetCocoaImpl*) item
188 - (void) setEnabled:(BOOL) flag
190 [super setEnabled: flag];
192 if (![self drawsBackground]) {
193 // Static text is drawn incorrectly when disabled.
194 // For an explanation, see
195 // http://www.cocoabuilder.com/archive/message/cocoa/2006/7/21/168028
197 [self setTextColor: [NSColor controlTextColor]];
199 [self setTextColor: [NSColor secondarySelectedControlColor]];
204 - (void)controlTextDidChange:(NSNotification *)aNotification
208 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
210 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
211 event.SetEventObject( wxpeer );
212 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
213 wxpeer->HandleWindowEvent( event );
218 typedef BOOL (*wxOSX_insertNewlineHandlerPtr)(NSView* self, SEL _cmd, NSControl *control, NSTextView* textView, SEL commandSelector);
220 - (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
222 if (commandSelector == @selector(insertNewline:))
226 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
227 if ( wxpeer && wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER )
229 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
230 event.SetEventObject( wxpeer );
231 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
232 wxpeer->HandleWindowEvent( event );
240 - (void)controlTextDidEndEditing:(NSNotification *)aNotification
244 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
246 wxFocusEvent event(wxEVT_KILL_FOCUS, wxpeer->GetId());
247 event.SetEventObject( wxpeer );
248 event.SetWindow( wxpeer );
249 wxpeer->HandleWindowEvent( event );
256 // wxNSTextViewControl
258 wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
260 m_scrollView = (NSScrollView*) w;
261 [(wxNSTextField*)w setImplementation: this];
263 [m_scrollView setHasVerticalScroller:YES];
264 [m_scrollView setHasHorizontalScroller:NO];
265 [m_scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
266 NSSize contentSize = [m_scrollView contentSize];
268 m_textView = [[NSTextView alloc] initWithFrame: NSMakeRect(0, 0,
269 contentSize.width, contentSize.height)];
270 [m_textView setVerticallyResizable:YES];
271 [m_textView setHorizontallyResizable:NO];
272 [m_textView setAutoresizingMask:NSViewWidthSizable];
274 [m_scrollView setDocumentView: m_textView];
276 [m_textView setDelegate: w];
279 wxNSTextViewControl::~wxNSTextViewControl()
282 [m_textView setDelegate: nil];
285 wxString wxNSTextViewControl::GetStringValue() const
289 wxCFStringRef cf( (CFStringRef) [[m_textView string] retain] );
290 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
292 return wxEmptyString;
294 void wxNSTextViewControl::SetStringValue( const wxString &str)
297 [m_textView setString: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
299 void wxNSTextViewControl::Copy()
302 [m_textView copy:nil];
306 void wxNSTextViewControl::Cut()
309 [m_textView cut:nil];
312 void wxNSTextViewControl::Paste()
315 [m_textView paste:nil];
318 bool wxNSTextViewControl::CanPaste() const
323 void wxNSTextViewControl::SetEditable(bool editable)
326 [m_textView setEditable: editable];
329 void wxNSTextViewControl::GetSelection( long* from, long* to) const
333 NSRange range = [m_textView selectedRange];
334 *from = range.location;
335 *to = range.location + range.length;
339 void wxNSTextViewControl::SetSelection( long from , long to )
341 NSRange selrange = NSMakeRange(from, to-from);
342 [m_textView setSelectedRange:selrange];
343 [m_textView scrollRangeToVisible:selrange];
346 void wxNSTextViewControl::WriteText(const wxString& str)
348 // temp hack to get logging working early
349 wxString former = GetStringValue();
350 SetStringValue( former + str );
351 SetSelection(GetStringValue().length(), GetStringValue().length());
354 // wxNSTextFieldControl
356 wxNSTextFieldControl::wxNSTextFieldControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
358 m_textField = (NSTextField*) w;
359 [m_textField setDelegate: w];
362 wxNSTextFieldControl::~wxNSTextFieldControl()
365 [m_textField setDelegate: nil];
368 wxString wxNSTextFieldControl::GetStringValue() const
370 wxCFStringRef cf( (CFStringRef) [[m_textField stringValue] retain] );
371 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
373 void wxNSTextFieldControl::SetStringValue( const wxString &str)
375 [m_textField setStringValue: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
377 void wxNSTextFieldControl::Copy()
379 NSText* editor = [m_textField currentEditor];
386 void wxNSTextFieldControl::Cut()
388 NSText* editor = [m_textField currentEditor];
395 void wxNSTextFieldControl::Paste()
397 NSText* editor = [m_textField currentEditor];
404 bool wxNSTextFieldControl::CanPaste() const
409 void wxNSTextFieldControl::SetEditable(bool editable)
411 [m_textField setEditable:editable];
414 void wxNSTextFieldControl::GetSelection( long* from, long* to) const
416 NSText* editor = [m_textField currentEditor];
419 NSRange range = [editor selectedRange];
420 *from = range.location;
421 *to = range.location + range.length;
425 void wxNSTextFieldControl::SetSelection( long from , long to )
427 NSText* editor = [m_textField currentEditor];
430 [editor setSelectedRange:NSMakeRange(from, to-from)];
434 void wxNSTextFieldControl::WriteText(const wxString& str)
436 // temp hack to get logging working early
437 wxString former = GetStringValue();
438 SetStringValue( former + str );
439 SetSelection(GetStringValue().length(), GetStringValue().length());
442 void wxNSTextFieldControl::controlAction(WXWidget slf, void* _cmd, void *sender)
444 wxWindow* wxpeer = (wxWindow*) GetWXPeer();
445 if ( wxpeer && (wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER) )
447 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
448 event.SetEventObject( wxpeer );
449 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
450 wxpeer->HandleWindowEvent( event );
458 wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
467 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
468 NSTextField* v = nil;
469 wxWidgetCocoaImpl* c = NULL;
471 if ( style & wxTE_MULTILINE || style & wxTE_RICH || style & wxTE_RICH2 )
473 v = [[wxNSTextView alloc] initWithFrame:r];
474 c = new wxNSTextViewControl( wxpeer, v );
475 static_cast<wxNSTextViewControl*>(c)->SetStringValue(str);
479 if ( style & wxTE_PASSWORD )
480 v = [[wxNSSecureTextField alloc] initWithFrame:r];
482 v = [[wxNSTextField alloc] initWithFrame:r];
484 if ( style & wxNO_BORDER )
486 // FIXME: How can we remove the native control's border?
487 // setBordered is separate from the text ctrl's border.
493 c = new wxNSTextFieldControl( wxpeer, v );
494 [v setImplementation: c];
495 static_cast<wxNSTextFieldControl*>(c)->SetStringValue(str);
502 #endif // wxUSE_TEXTCTRL