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