]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/textctrl.mm
Start on implementation for wxTE_MULTILINE / wxTE_RICH* support using NSTextView...
[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 @end
55
56 @implementation wxNSSecureTextField
57
58 + (void)initialize
59 {
60 static BOOL initialized = NO;
61 if (!initialized)
62 {
63 initialized = YES;
64 wxOSXCocoaClassAddWXMethods( self );
65 }
66 }
67
68 @end
69
70 @interface wxNSTextView : NSScrollView
71
72 @end
73
74 @implementation wxNSTextView
75
76 + (void)initialize
77 {
78 static BOOL initialized = NO;
79 if (!initialized)
80 {
81 initialized = YES;
82 wxOSXCocoaClassAddWXMethods( self );
83 }
84 }
85
86 @end
87
88 @implementation wxNSTextField
89
90 + (void)initialize
91 {
92 static BOOL initialized = NO;
93 if (!initialized)
94 {
95 initialized = YES;
96 wxOSXCocoaClassAddWXMethods( self );
97 }
98 }
99
100 /*
101 - (void)controlTextDidChange:(NSNotification *)aNotification
102 {
103 if ( impl )
104 {
105 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
106 if ( wxpeer ) {
107 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
108 event.SetEventObject( wxpeer );
109 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
110 wxpeer->HandleWindowEvent( event );
111 }
112 }
113 }
114
115 - (void)controlTextDidEndEditing:(NSNotification *)aNotification
116 {
117 if ( impl )
118 {
119 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
120 if ( wxpeer ) {
121 wxFocusEvent event(wxEVT_KILL_FOCUS, wxpeer->GetId());
122 event.SetEventObject( wxpeer );
123 event.SetWindow( wxpeer );
124 wxpeer->HandleWindowEvent( event );
125 }
126 }
127 }
128 */
129 @end
130
131 // wxNSTextViewControl
132
133 wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
134 {
135 m_scrollView = (NSScrollView*) w;
136
137 [m_scrollView setHasVerticalScroller:YES];
138 [m_scrollView setHasHorizontalScroller:NO];
139 [m_scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
140 NSSize contentSize = [m_scrollView contentSize];
141
142 m_textView = [[NSTextView alloc] initWithFrame: NSMakeRect(0, 0,
143 contentSize.width, contentSize.height)];
144 [m_textView setVerticallyResizable:YES];
145 [m_textView setHorizontallyResizable:NO];
146 [m_textView setAutoresizingMask:NSViewWidthSizable];
147
148 [m_scrollView setDocumentView: m_textView];
149
150 [m_textView setDelegate: w];
151 }
152
153 wxNSTextViewControl::~wxNSTextViewControl()
154 {
155 if (m_textView)
156 [m_textView setDelegate: nil];
157 }
158
159 wxString wxNSTextViewControl::GetStringValue() const
160 {
161 if (m_textView)
162 {
163 wxCFStringRef cf( (CFStringRef) [[m_textView string] retain] );
164 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
165 }
166 return wxEmptyString;
167 }
168 void wxNSTextViewControl::SetStringValue( const wxString &str)
169 {
170 if (m_textView)
171 [m_textView setString: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
172 }
173 void wxNSTextViewControl::Copy()
174 {
175 if (m_textView)
176 [m_textView copy:nil];
177
178 }
179
180 void wxNSTextViewControl::Cut()
181 {
182 if (m_textView)
183 [m_textView cut:nil];
184 }
185
186 void wxNSTextViewControl::Paste()
187 {
188 if (m_textView)
189 [m_textView paste:nil];
190 }
191
192 bool wxNSTextViewControl::CanPaste() const
193 {
194 return true;
195 }
196
197 void wxNSTextViewControl::SetEditable(bool editable)
198 {
199 if (m_textView)
200 [m_textView setEditable: editable];
201 }
202
203 void wxNSTextViewControl::GetSelection( long* from, long* to) const
204 {
205 if (m_textView)
206 {
207 NSRange range = [m_textView selectedRange];
208 *from = range.location;
209 *to = range.location + range.length;
210 }
211 }
212
213 void wxNSTextViewControl::SetSelection( long from , long to )
214 {
215 [m_textView setSelectedRange:NSMakeRange(from, to-from)];
216 }
217
218 void wxNSTextViewControl::WriteText(const wxString& str)
219 {
220 // temp hack to get logging working early
221 wxString former = GetStringValue();
222 SetStringValue( former + str );
223 }
224
225 // wxNSTextFieldControl
226
227 wxNSTextFieldControl::wxNSTextFieldControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w)
228 {
229 m_textField = (NSTextField*) w;
230 [m_textField setDelegate: w];
231 }
232
233 wxNSTextFieldControl::~wxNSTextFieldControl()
234 {
235 if (m_textField)
236 [m_textField setDelegate: nil];
237 }
238
239 wxString wxNSTextFieldControl::GetStringValue() const
240 {
241 wxCFStringRef cf( (CFStringRef) [[m_textField stringValue] retain] );
242 return cf.AsString(m_wxPeer->GetFont().GetEncoding());
243 }
244 void wxNSTextFieldControl::SetStringValue( const wxString &str)
245 {
246 [m_textField setStringValue: wxCFStringRef( str , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
247 }
248 void wxNSTextFieldControl::Copy()
249 {
250 NSText* editor = [m_textField currentEditor];
251 if ( editor )
252 {
253 [editor copy:nil];
254 }
255 }
256
257 void wxNSTextFieldControl::Cut()
258 {
259 NSText* editor = [m_textField currentEditor];
260 if ( editor )
261 {
262 [editor cut:nil];
263 }
264 }
265
266 void wxNSTextFieldControl::Paste()
267 {
268 NSText* editor = [m_textField currentEditor];
269 if ( editor )
270 {
271 [editor paste:nil];
272 }
273 }
274
275 bool wxNSTextFieldControl::CanPaste() const
276 {
277 return true;
278 }
279
280 void wxNSTextFieldControl::SetEditable(bool editable)
281 {
282 [m_textField setEditable:editable];
283 }
284
285 void wxNSTextFieldControl::GetSelection( long* from, long* to) const
286 {
287 NSText* editor = [m_textField currentEditor];
288 if ( editor )
289 {
290 NSRange range = [editor selectedRange];
291 *from = range.location;
292 *to = range.location + range.length;
293 }
294 }
295
296 void wxNSTextFieldControl::SetSelection( long from , long to )
297 {
298 NSText* editor = [m_textField currentEditor];
299 if ( editor )
300 {
301 [editor setSelectedRange:NSMakeRange(from, to-from)];
302 }
303 }
304
305 void wxNSTextFieldControl::WriteText(const wxString& str)
306 {
307 // temp hack to get logging working early
308 wxString former = GetStringValue();
309 SetStringValue( former + str );
310 }
311
312 void wxNSTextFieldControl::controlAction(WXWidget slf, void* _cmd, void *sender)
313 {
314 wxWindow* wxpeer = (wxWindow*) GetWXPeer();
315 if ( wxpeer && (wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER) )
316 {
317 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
318 event.SetEventObject( wxpeer );
319 event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
320 wxpeer->HandleWindowEvent( event );
321 }
322 }
323
324 //
325 //
326 //
327
328 wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
329 wxWindowMac* parent,
330 wxWindowID id,
331 const wxString& str,
332 const wxPoint& pos,
333 const wxSize& size,
334 long style,
335 long extraStyle)
336 {
337 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
338 NSTextField* v = nil;
339 wxWidgetCocoaImpl* c = NULL;
340
341 if ( style & wxTE_MULTILINE || style & wxTE_RICH || style & wxTE_RICH2 )
342 {
343 v = [[wxNSTextView alloc] initWithFrame:r];
344 c = new wxNSTextViewControl( wxpeer, v );
345 static_cast<wxNSTextViewControl*>(c)->SetStringValue(str);
346 }
347 else
348 {
349 if ( style & wxTE_PASSWORD )
350 v = [[wxNSSecureTextField alloc] initWithFrame:r];
351 else
352 v = [[wxNSTextField alloc] initWithFrame:r];
353
354 if ( style & wxNO_BORDER )
355 {
356 // FIXME: How can we remove the native control's border?
357 // setBordered is separate from the text ctrl's border.
358 }
359
360 [v setBezeled:NO];
361 [v setBordered:NO];
362
363 c = new wxNSTextFieldControl( wxpeer, v );
364 static_cast<wxNSTextFieldControl*>(c)->SetStringValue(str);
365 }
366
367 return c;
368 }
369
370
371 #endif // wxUSE_TEXTCTRL