]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/textctrl.mm
Sheet support for wxMessageDialog.
[wxWidgets.git] / src / osx / cocoa / textctrl.mm
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/cocoa/private/textimpl.h"
51
52 @interface wxNSSecureTextField : NSSecureTextField
53 {
54 wxWidgetCocoaImpl* impl;
55 }
56
57 - (void) setImplementation:(wxWidgetCocoaImpl*) item;
58 - (wxWidgetCocoaImpl*) implementation;
59 @end
60
61 @implementation wxNSSecureTextField
62
63 + (void)initialize
64 {
65 static BOOL initialized = NO;
66 if (!initialized)
67 {
68 initialized = YES;
69 wxOSXCocoaClassAddWXMethods( self );
70 }
71 }
72
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
97 @end
98
99 @interface wxNSTextView : NSScrollView
100 {
101 wxWidgetCocoaImpl* impl;
102 }
103
104 - (void) setImplementation:(wxWidgetCocoaImpl*) item;
105 - (wxWidgetCocoaImpl*) implementation;
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
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 }
144 @end
145
146 @implementation wxNSTextField
147
148 + (void)initialize
149 {
150 static BOOL initialized = NO;
151 if (!initialized)
152 {
153 initialized = YES;
154 wxOSXCocoaClassAddWXMethods( self );
155 }
156 }
157
158 - (wxWidgetCocoaImpl*) implementation
159 {
160 return impl;
161 }
162
163 - (void) setImplementation:(wxWidgetCocoaImpl*) item
164 {
165 impl = item;
166 }
167
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 }
183
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 }
197
198 typedef 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 }
219 /*
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 }
233 */
234 @end
235
236 // wxNSTextViewControl
237
238 wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
239 {
240 m_scrollView = (NSScrollView*) w;
241 [(wxNSTextField*)w setImplementation: this];
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
259 wxNSTextViewControl::~wxNSTextViewControl()
260 {
261 if (m_textView)
262 [m_textView setDelegate: nil];
263 }
264
265 wxString 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 }
274 void wxNSTextViewControl::SetStringValue( const wxString &str)
275 {
276 if (m_textView)
277 [m_textView setString: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
278 }
279 void wxNSTextViewControl::Copy()
280 {
281 if (m_textView)
282 [m_textView copy:nil];
283
284 }
285
286 void wxNSTextViewControl::Cut()
287 {
288 if (m_textView)
289 [m_textView cut:nil];
290 }
291
292 void wxNSTextViewControl::Paste()
293 {
294 if (m_textView)
295 [m_textView paste:nil];
296 }
297
298 bool wxNSTextViewControl::CanPaste() const
299 {
300 return true;
301 }
302
303 void wxNSTextViewControl::SetEditable(bool editable)
304 {
305 if (m_textView)
306 [m_textView setEditable: editable];
307 }
308
309 void 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
319 void wxNSTextViewControl::SetSelection( long from , long to )
320 {
321 NSRange selrange = NSMakeRange(from, to-from);
322 [m_textView setSelectedRange:selrange];
323 [m_textView scrollRangeToVisible:selrange];
324 }
325
326 void wxNSTextViewControl::WriteText(const wxString& str)
327 {
328 // temp hack to get logging working early
329 wxString former = GetStringValue();
330 SetStringValue( former + str );
331 SetSelection(GetStringValue().length(), GetStringValue().length());
332 }
333
334 // wxNSTextFieldControl
335
336 wxNSTextFieldControl::wxNSTextFieldControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
337 {
338 m_textField = (NSTextField*) w;
339 [m_textField setDelegate: w];
340 }
341
342 wxNSTextFieldControl::~wxNSTextFieldControl()
343 {
344 if (m_textField)
345 [m_textField setDelegate: nil];
346 }
347
348 wxString wxNSTextFieldControl::GetStringValue() const
349 {
350 wxCFStringRef cf( (CFStringRef) [[m_textField stringValue] retain] );
351 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
352 }
353 void wxNSTextFieldControl::SetStringValue( const wxString &str)
354 {
355 [m_textField setStringValue: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
356 }
357 void wxNSTextFieldControl::Copy()
358 {
359 NSText* editor = [m_textField currentEditor];
360 if ( editor )
361 {
362 [editor copy:nil];
363 }
364 }
365
366 void wxNSTextFieldControl::Cut()
367 {
368 NSText* editor = [m_textField currentEditor];
369 if ( editor )
370 {
371 [editor cut:nil];
372 }
373 }
374
375 void wxNSTextFieldControl::Paste()
376 {
377 NSText* editor = [m_textField currentEditor];
378 if ( editor )
379 {
380 [editor paste:nil];
381 }
382 }
383
384 bool wxNSTextFieldControl::CanPaste() const
385 {
386 return true;
387 }
388
389 void wxNSTextFieldControl::SetEditable(bool editable)
390 {
391 [m_textField setEditable:editable];
392 }
393
394 void wxNSTextFieldControl::GetSelection( long* from, long* to) const
395 {
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 }
403 }
404
405 void wxNSTextFieldControl::SetSelection( long from , long to )
406 {
407 NSText* editor = [m_textField currentEditor];
408 if ( editor )
409 {
410 [editor setSelectedRange:NSMakeRange(from, to-from)];
411 }
412 }
413
414 void wxNSTextFieldControl::WriteText(const wxString& str)
415 {
416 // temp hack to get logging working early
417 wxString former = GetStringValue();
418 SetStringValue( former + str );
419 SetSelection(GetStringValue().length(), GetStringValue().length());
420 }
421
422 void 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
438 wxWidgetImplType* 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 {
447 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
448 NSTextField* v = nil;
449 wxWidgetCocoaImpl* c = NULL;
450
451 if ( style & wxTE_MULTILINE || style & wxTE_RICH || style & wxTE_RICH2 )
452 {
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
470 [v setBezeled:NO];
471 [v setBordered:NO];
472
473 c = new wxNSTextFieldControl( wxpeer, v );
474 [v setImplementation: c];
475 static_cast<wxNSTextFieldControl*>(c)->SetStringValue(str);
476 }
477
478 return c;
479 }
480
481
482 #endif // wxUSE_TEXTCTRL