]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/textctrl.mm
conforming to new naming convention of starting all port specific methods with the...
[wxWidgets.git] / src / osx / cocoa / textctrl.mm
CommitLineData
dbeddfb9
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"
1e181c7a 50#include "wx/osx/cocoa/private/textimpl.h"
dbeddfb9 51
e32090ba 52@interface wxNSSecureTextField : NSSecureTextField
4d23a0d3 53{
4d23a0d3 54}
e32090ba
SC
55@end
56
57@implementation wxNSSecureTextField
dbeddfb9 58
4dd9fdf8
SC
59+ (void)initialize
60{
61 static BOOL initialized = NO;
62 if (!initialized)
63 {
64 initialized = YES;
65 wxOSXCocoaClassAddWXMethods( self );
66 }
67}
dbeddfb9 68
4d23a0d3
KO
69- (void)controlTextDidChange:(NSNotification *)aNotification
70{
6331c8c0
SC
71 wxUnusedVar(aNotification);
72 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
4d23a0d3
KO
73 if ( impl )
74 {
75 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
76 if ( wxpeer ) {
77 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
78 event.SetEventObject( wxpeer );
79 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
80 wxpeer->HandleWindowEvent( event );
81 }
82 }
83}
84
e32090ba
SC
85@end
86
c824c165 87@interface wxNSTextView : NSScrollView
4d23a0d3 88{
4d23a0d3 89}
c824c165
KO
90
91@end
92
93@implementation wxNSTextView
94
95+ (void)initialize
96{
97 static BOOL initialized = NO;
98 if (!initialized)
99 {
100 initialized = YES;
101 wxOSXCocoaClassAddWXMethods( self );
102 }
103}
104
533e2ae1 105- (void)textDidChange:(NSNotification *)aNotification
4d23a0d3 106{
6331c8c0
SC
107 wxUnusedVar(aNotification);
108 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
4d23a0d3
KO
109 if ( impl )
110 {
111 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
112 if ( wxpeer ) {
113 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
114 event.SetEventObject( wxpeer );
115 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
116 wxpeer->HandleWindowEvent( event );
117 }
118 }
119}
533e2ae1
KO
120
121- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)commandSelector
122{
6331c8c0
SC
123 wxUnusedVar(aTextView);
124 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
533e2ae1
KO
125 if ( impl )
126 {
127 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
128 if (commandSelector == @selector(insertNewline:))
129 {
130 if ( wxpeer && wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER )
131 {
132 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
133 event.SetEventObject( wxpeer );
134 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
135 wxpeer->HandleWindowEvent( event );
136 }
137 }
138 }
139
140 return NO;
141}
c824c165
KO
142@end
143
e32090ba 144@implementation wxNSTextField
ffad7b0d 145
e32090ba 146+ (void)initialize
dbeddfb9 147{
e32090ba
SC
148 static BOOL initialized = NO;
149 if (!initialized)
150 {
151 initialized = YES;
152 wxOSXCocoaClassAddWXMethods( self );
153 }
dbeddfb9 154}
e32090ba 155
c3e433b1
SC
156- (void) setEnabled:(BOOL) flag
157{
158 [super setEnabled: flag];
159
160 if (![self drawsBackground]) {
161 // Static text is drawn incorrectly when disabled.
162 // For an explanation, see
163 // http://www.cocoabuilder.com/archive/message/cocoa/2006/7/21/168028
164 if (flag) {
165 [self setTextColor: [NSColor controlTextColor]];
166 } else {
167 [self setTextColor: [NSColor secondarySelectedControlColor]];
168 }
169 }
170}
4d23a0d3 171
ffad7b0d
SC
172- (void)controlTextDidChange:(NSNotification *)aNotification
173{
6331c8c0
SC
174 wxUnusedVar(aNotification);
175 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
ffad7b0d
SC
176 if ( impl )
177 {
178 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
179 if ( wxpeer ) {
180 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
181 event.SetEventObject( wxpeer );
182 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
183 wxpeer->HandleWindowEvent( event );
184 }
185 }
186}
dbeddfb9 187
2d6aa919
KO
188typedef BOOL (*wxOSX_insertNewlineHandlerPtr)(NSView* self, SEL _cmd, NSControl *control, NSTextView* textView, SEL commandSelector);
189
190- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
191{
6331c8c0
SC
192 wxUnusedVar(textView);
193 wxUnusedVar(control);
2d6aa919
KO
194 if (commandSelector == @selector(insertNewline:))
195 {
6331c8c0 196 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
2d6aa919
KO
197 if ( impl )
198 {
199 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
200 if ( wxpeer && wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER )
201 {
202 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
203 event.SetEventObject( wxpeer );
204 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
205 wxpeer->HandleWindowEvent( event );
206 }
207 }
208 }
209
210 return NO;
211}
4d23a0d3 212/*
ffad7b0d
SC
213- (void)controlTextDidEndEditing:(NSNotification *)aNotification
214{
215 if ( impl )
216 {
217 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
218 if ( wxpeer ) {
219 wxFocusEvent event(wxEVT_KILL_FOCUS, wxpeer->GetId());
220 event.SetEventObject( wxpeer );
221 event.SetWindow( wxpeer );
222 wxpeer->HandleWindowEvent( event );
223 }
224 }
225}
ffad7b0d 226*/
dbeddfb9
SC
227@end
228
c824c165
KO
229// wxNSTextViewControl
230
231wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
232{
233 m_scrollView = (NSScrollView*) w;
234
235 [m_scrollView setHasVerticalScroller:YES];
236 [m_scrollView setHasHorizontalScroller:NO];
237 [m_scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
238 NSSize contentSize = [m_scrollView contentSize];
239
240 m_textView = [[NSTextView alloc] initWithFrame: NSMakeRect(0, 0,
241 contentSize.width, contentSize.height)];
242 [m_textView setVerticallyResizable:YES];
243 [m_textView setHorizontallyResizable:NO];
244 [m_textView setAutoresizingMask:NSViewWidthSizable];
245
246 [m_scrollView setDocumentView: m_textView];
247
248 [m_textView setDelegate: w];
249}
250
251wxNSTextViewControl::~wxNSTextViewControl()
252{
253 if (m_textView)
254 [m_textView setDelegate: nil];
255}
256
257wxString wxNSTextViewControl::GetStringValue() const
258{
259 if (m_textView)
260 {
261 wxCFStringRef cf( (CFStringRef) [[m_textView string] retain] );
262 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
263 }
264 return wxEmptyString;
265}
266void wxNSTextViewControl::SetStringValue( const wxString &str)
267{
268 if (m_textView)
269 [m_textView setString: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
270}
271void wxNSTextViewControl::Copy()
272{
273 if (m_textView)
274 [m_textView copy:nil];
275
276}
277
278void wxNSTextViewControl::Cut()
279{
280 if (m_textView)
281 [m_textView cut:nil];
282}
283
284void wxNSTextViewControl::Paste()
285{
286 if (m_textView)
287 [m_textView paste:nil];
288}
289
290bool wxNSTextViewControl::CanPaste() const
291{
292 return true;
293}
294
295void wxNSTextViewControl::SetEditable(bool editable)
296{
297 if (m_textView)
298 [m_textView setEditable: editable];
299}
300
301void wxNSTextViewControl::GetSelection( long* from, long* to) const
302{
303 if (m_textView)
304 {
305 NSRange range = [m_textView selectedRange];
306 *from = range.location;
307 *to = range.location + range.length;
308 }
309}
310
311void wxNSTextViewControl::SetSelection( long from , long to )
312{
2d6aa919
KO
313 NSRange selrange = NSMakeRange(from, to-from);
314 [m_textView setSelectedRange:selrange];
315 [m_textView scrollRangeToVisible:selrange];
c824c165
KO
316}
317
318void wxNSTextViewControl::WriteText(const wxString& str)
319{
320 // temp hack to get logging working early
321 wxString former = GetStringValue();
322 SetStringValue( former + str );
2d6aa919 323 SetSelection(GetStringValue().length(), GetStringValue().length());
c824c165
KO
324}
325
326// wxNSTextFieldControl
327
1e181c7a
SC
328wxNSTextFieldControl::wxNSTextFieldControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
329{
e32090ba
SC
330 m_textField = (NSTextField*) w;
331 [m_textField setDelegate: w];
1e181c7a
SC
332}
333
334wxNSTextFieldControl::~wxNSTextFieldControl()
335{
c824c165
KO
336 if (m_textField)
337 [m_textField setDelegate: nil];
1e181c7a
SC
338}
339
340wxString wxNSTextFieldControl::GetStringValue() const
341{
e32090ba 342 wxCFStringRef cf( (CFStringRef) [[m_textField stringValue] retain] );
1e181c7a
SC
343 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
344}
345void wxNSTextFieldControl::SetStringValue( const wxString &str)
346{
e32090ba 347 [m_textField setStringValue: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
1e181c7a
SC
348}
349void wxNSTextFieldControl::Copy()
350{
e32090ba
SC
351 NSText* editor = [m_textField currentEditor];
352 if ( editor )
353 {
354 [editor copy:nil];
355 }
1e181c7a
SC
356}
357
358void wxNSTextFieldControl::Cut()
359{
e32090ba
SC
360 NSText* editor = [m_textField currentEditor];
361 if ( editor )
362 {
363 [editor cut:nil];
364 }
1e181c7a
SC
365}
366
367void wxNSTextFieldControl::Paste()
368{
e32090ba
SC
369 NSText* editor = [m_textField currentEditor];
370 if ( editor )
371 {
372 [editor paste:nil];
373 }
1e181c7a
SC
374}
375
376bool wxNSTextFieldControl::CanPaste() const
377{
e32090ba 378 return true;
1e181c7a
SC
379}
380
381void wxNSTextFieldControl::SetEditable(bool editable)
382{
e32090ba 383 [m_textField setEditable:editable];
1e181c7a
SC
384}
385
386void wxNSTextFieldControl::GetSelection( long* from, long* to) const
387{
e32090ba
SC
388 NSText* editor = [m_textField currentEditor];
389 if ( editor )
390 {
391 NSRange range = [editor selectedRange];
392 *from = range.location;
393 *to = range.location + range.length;
394 }
1e181c7a
SC
395}
396
397void wxNSTextFieldControl::SetSelection( long from , long to )
398{
e32090ba
SC
399 NSText* editor = [m_textField currentEditor];
400 if ( editor )
401 {
402 [editor setSelectedRange:NSMakeRange(from, to-from)];
403 }
1e181c7a
SC
404}
405
406void wxNSTextFieldControl::WriteText(const wxString& str)
407{
408 // temp hack to get logging working early
409 wxString former = GetStringValue();
410 SetStringValue( former + str );
2d6aa919 411 SetSelection(GetStringValue().length(), GetStringValue().length());
1e181c7a 412}
dbeddfb9 413
6331c8c0
SC
414void wxNSTextFieldControl::controlAction(WXWidget WXUNUSED(slf),
415 void* WXUNUSED(_cmd), void *WXUNUSED(sender))
e32090ba
SC
416{
417 wxWindow* wxpeer = (wxWindow*) GetWXPeer();
418 if ( wxpeer && (wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER) )
419 {
420 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
421 event.SetEventObject( wxpeer );
422 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
423 wxpeer->HandleWindowEvent( event );
424 }
425}
426
427//
428//
429//
430
dbeddfb9 431wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
6331c8c0
SC
432 wxWindowMac* WXUNUSED(parent),
433 wxWindowID WXUNUSED(id),
dbeddfb9
SC
434 const wxString& str,
435 const wxPoint& pos,
436 const wxSize& size,
437 long style,
6331c8c0 438 long WXUNUSED(extraStyle))
dbeddfb9 439{
dbeddfb9 440 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
c824c165 441 wxWidgetCocoaImpl* c = NULL;
e32090ba 442
c824c165 443 if ( style & wxTE_MULTILINE || style & wxTE_RICH || style & wxTE_RICH2 )
b15f9375 444 {
6331c8c0 445 wxNSTextView* v = nil;
c824c165
KO
446 v = [[wxNSTextView alloc] initWithFrame:r];
447 c = new wxNSTextViewControl( wxpeer, v );
448 static_cast<wxNSTextViewControl*>(c)->SetStringValue(str);
449 }
450 else
451 {
6331c8c0 452 NSTextField* v = nil;
c824c165
KO
453 if ( style & wxTE_PASSWORD )
454 v = [[wxNSSecureTextField alloc] initWithFrame:r];
455 else
456 v = [[wxNSTextField alloc] initWithFrame:r];
457
458 if ( style & wxNO_BORDER )
459 {
460 // FIXME: How can we remove the native control's border?
461 // setBordered is separate from the text ctrl's border.
462 }
463
b15f9375
SC
464 [v setBezeled:NO];
465 [v setBordered:NO];
c824c165
KO
466
467 c = new wxNSTextFieldControl( wxpeer, v );
468 static_cast<wxNSTextFieldControl*>(c)->SetStringValue(str);
b15f9375 469 }
dbeddfb9 470
dbeddfb9
SC
471 return c;
472}
473
474
475#endif // wxUSE_TEXTCTRL