revamping classic MLTE implementation
[wxWidgets.git] / src / mac / carbon / textctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: textctrl.cpp
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$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "textctrl.h"
14 #endif
15
16 #include "wx/wxprec.h"
17
18 #if wxUSE_TEXTCTRL
19
20
21 #ifdef __DARWIN__
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #else
25 #include <stat.h>
26 #endif
27
28 #include "wx/msgdlg.h"
29
30 #if wxUSE_STD_IOSTREAM
31 #if wxUSE_IOSTREAMH
32 #include <fstream.h>
33 #else
34 #include <fstream>
35 #endif
36 #endif
37
38 #include "wx/app.h"
39 #include "wx/dc.h"
40 #include "wx/button.h"
41 #include "wx/toplevel.h"
42 #include "wx/textctrl.h"
43 #include "wx/notebook.h"
44 #include "wx/tabctrl.h"
45 #include "wx/settings.h"
46 #include "wx/filefn.h"
47 #include "wx/utils.h"
48
49 #if defined(__BORLANDC__) && !defined(__WIN32__)
50 #include <alloc.h>
51 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
52 #include <malloc.h>
53 #endif
54
55 #ifndef __DARWIN__
56 #include <Scrap.h>
57 #endif
58
59 // if this is set to 1 then under OSX 10.2 the 'classic' MLTE implementation will be used
60 // if set to 0 then the unicode textctrl will be used
61 #ifndef wxMAC_AWAYS_USE_MLTE
62 #define wxMAC_AWAYS_USE_MLTE 1
63 #endif
64
65 #ifndef __WXMAC_OSX__
66 enum
67 {
68 kTXNVisibilityTag = 'visb' /*set the visibility state of the object */
69 };
70 #endif
71
72 #include <MacTextEditor.h>
73 #include <ATSUnicode.h>
74 #include <TextCommon.h>
75 #include <TextEncodingConverter.h>
76 #include "wx/mac/uma.h"
77
78 class wxMacFunctor
79 {
80 public :
81 wxMacFunctor(){}
82 virtual ~wxMacFunctor() {}
83 virtual void* operator()() = 0 ;
84 static void* CallBackProc(void *param)
85 {
86 wxMacFunctor* f = (wxMacFunctor*) param ;
87 void *result = (*f)() ;
88 return result ;
89 }
90 } ;
91
92 template<typename classtype,typename param1type>
93 class wxMacObjectFunctor1 : public wxMacFunctor
94 {
95 typedef void (classtype::*function)( param1type p1 ) ;
96 typedef void (classtype::*ref_function)( const param1type& p1 ) ;
97 public :
98 wxMacObjectFunctor1( classtype *obj , function f , param1type p1 ) :
99 wxMacFunctor( )
100 {
101 m_object = obj ;
102 m_function = f ;
103 m_param1 = p1 ;
104 }
105
106 wxMacObjectFunctor1( classtype *obj , ref_function f , param1type p1 ) :
107 wxMacFunctor( )
108 {
109 m_object = obj ;
110 m_refFunction = f ;
111 m_param1 = p1 ;
112 }
113
114 ~wxMacObjectFunctor1() {}
115
116 virtual void* operator()()
117 {
118 (m_object->*m_function)(m_param1) ;
119 return NULL ;
120 }
121 private :
122 classtype* m_object ;
123 param1type m_param1 ;
124 union
125 {
126 function m_function ;
127 ref_function m_refFunction ;
128 } ;
129 } ;
130
131 template<typename classtype, typename param1type>
132 void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
133 {
134 wxMacObjectFunctor1<classtype,param1type> params(object,function,p1) ;
135 void *result =
136 MPRemoteCall( wxMacFunctor::CallBackProc , &params , kMPOwningProcessRemoteContext ) ;
137 return result ;
138 }
139
140 template<typename classtype, typename param1type>
141 void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
142 {
143 wxMacObjectFunctor1<classtype,param1type> params(object,function,p1) ;
144 void *result =
145 MPRemoteCall( wxMacFunctor::CallBackProc , &params , kMPOwningProcessRemoteContext ) ;
146 return result ;
147 }
148
149 template<typename classtype, typename param1type>
150 void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
151 {
152 wxMutexGuiLeave() ;
153 void *result = wxMacMPRemoteCall( object , function , p1 ) ;
154 wxMutexGuiEnter() ;
155 return result ;
156 }
157
158 template<typename classtype, typename param1type>
159 void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
160 {
161 wxMutexGuiLeave() ;
162 void *result = wxMacMPRemoteCall( object , function , p1 ) ;
163 wxMutexGuiEnter() ;
164 return result ;
165 }
166 // common interface for all implementations
167 class wxMacTextControl : public wxMacControl
168 {
169 public :
170 wxMacTextControl( wxTextCtrl *peer ) ;
171 ~wxMacTextControl() ;
172
173 virtual wxString GetStringValue() const = 0 ;
174 virtual void SetStringValue( const wxString &val ) = 0 ;
175 virtual void SetStyle(long start, long end, const wxTextAttr& style) ;
176 virtual void Copy() ;
177 virtual void Cut() ;
178 virtual void Paste() ;
179 virtual bool CanPaste() const ;
180 virtual void SetEditable(bool editable) ;
181 virtual wxTextPos GetLastPosition() const ;
182 virtual void Replace( long from , long to , const wxString str ) ;
183 virtual void Remove( long from , long to ) = 0 ;
184 virtual void SetSelection( long from , long to ) = 0 ;
185 virtual void GetSelection( long* from, long* to) const = 0 ;
186 virtual void WriteText(const wxString& str) = 0 ;
187
188 virtual void Clear() ;
189 virtual bool CanUndo() const;
190 virtual void Undo() ;
191 virtual bool CanRedo() const;
192 virtual void Redo() ;
193 virtual int GetNumberOfLines() const ;
194 virtual long XYToPosition(long x, long y) const;
195 virtual bool PositionToXY(long pos, long *x, long *y) const ;
196 virtual void ShowPosition( long WXUNUSED(pos) ) ;
197 virtual int GetLineLength(long lineNo) const ;
198 virtual wxString GetLineText(long lineNo) const ;
199
200 #ifndef __WXMAC_OSX__
201 virtual void MacControlUserPaneDrawProc(wxInt16 part) = 0 ;
202 virtual wxInt16 MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) = 0 ;
203 virtual wxInt16 MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc) = 0 ;
204 virtual void MacControlUserPaneIdleProc() = 0 ;
205 virtual wxInt16 MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers) = 0 ;
206 virtual void MacControlUserPaneActivateProc(bool activating) = 0 ;
207 virtual wxInt16 MacControlUserPaneFocusProc(wxInt16 action) = 0 ;
208 virtual void MacControlUserPaneBackgroundProc(void* info) = 0 ;
209 #endif
210 } ;
211
212 // common parts for implementations based on MLTE
213
214 class wxMacMLTEControl : public wxMacTextControl
215 {
216 public :
217 wxMacMLTEControl( wxTextCtrl *peer ) : wxMacTextControl( peer ) {}
218 virtual wxString GetStringValue() const ;
219 virtual void SetStringValue( const wxString &str) ;
220
221 static TXNFrameOptions FrameOptionsFromWXStyle( long wxStyle ) ;
222 void AdjustCreationAttributes( const wxColour& background , bool visible ) ;
223
224 virtual void SetFont( const wxFont & font , const wxColour& foreground , long windowStyle ) ;
225 virtual void SetBackground( const wxBrush &brush) ;
226 virtual void SetStyle(long start, long end, const wxTextAttr& style) ;
227 virtual void Copy() ;
228 virtual void Cut() ;
229 virtual void Paste() ;
230 virtual bool CanPaste() const ;
231 virtual void SetEditable(bool editable) ;
232 virtual wxTextPos GetLastPosition() const ;
233 virtual void Replace( long from , long to , const wxString str ) ;
234 virtual void Remove( long from , long to ) ;
235 virtual void GetSelection( long* from, long* to) const ;
236 virtual void SetSelection( long from , long to ) ;
237
238 virtual void WriteText(const wxString& str) ;
239 virtual void Clear() ;
240
241 virtual bool CanUndo() const ;
242 virtual void Undo() ;
243 virtual bool CanRedo() const;
244 virtual void Redo() ;
245 virtual int GetNumberOfLines() const ;
246 virtual long XYToPosition(long x, long y) const ;
247 virtual bool PositionToXY(long pos, long *x, long *y) const ;
248 virtual void ShowPosition( long pos ) ;
249 virtual int GetLineLength(long lineNo) const ;
250 virtual wxString GetLineText(long lineNo) const ;
251
252 void SetTXNData( const wxString& st , TXNOffset start , TXNOffset end ) ;
253
254 protected :
255 void TXNSetAttribute( const wxTextAttr& style , long from , long to ) ;
256 TXNObject m_txn ;
257 } ;
258
259 #if TARGET_API_MAC_OSX
260
261 // implementation available under OSX
262
263 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
264
265 class wxMacMLTEHIViewControl : public wxMacMLTEControl
266 {
267 public :
268 wxMacMLTEHIViewControl( wxTextCtrl *wxPeer,
269 const wxString& str,
270 const wxPoint& pos,
271 const wxSize& size, long style ) ;
272 virtual OSStatus SetFocus( ControlFocusPart focusPart ) ;
273 virtual bool HasFocus() const ;
274 virtual bool NeedsFocusRect() const;
275 protected :
276 HIViewRef m_scrollView ;
277 HIViewRef m_textView ;
278 } ;
279
280 #endif
281
282 class wxMacUnicodeTextControl : public wxMacTextControl
283 {
284 public :
285 wxMacUnicodeTextControl( wxTextCtrl *wxPeer,
286 const wxString& str,
287 const wxPoint& pos,
288 const wxSize& size, long style ) ;
289 ~wxMacUnicodeTextControl();
290 virtual void VisibilityChanged(bool shown);
291 virtual wxString GetStringValue() const ;
292 virtual void SetStringValue( const wxString &str) ;
293 virtual void Copy();
294 virtual void Cut();
295 virtual void Paste();
296 virtual bool CanPaste() const;
297 virtual void SetEditable(bool editable) ;
298 virtual void Remove( long from , long to ) ;
299 virtual void GetSelection( long* from, long* to) const ;
300 virtual void SetSelection( long from , long to ) ;
301 virtual void WriteText(const wxString& str) ;
302 protected :
303 // contains the tag for the content (is different for password and non-password controls)
304 OSType m_valueTag ;
305 } ;
306
307 #endif
308
309 // 'classic' MLTE implementation
310
311 class wxMacMLTEClassicControl : public wxMacMLTEControl
312 {
313 public :
314 wxMacMLTEClassicControl( wxTextCtrl *wxPeer,
315 const wxString& str,
316 const wxPoint& pos,
317 const wxSize& size, long style ) ;
318 ~wxMacMLTEClassicControl() ;
319 virtual void VisibilityChanged(bool shown) ;
320 virtual bool NeedsFocusRect() const;
321
322 virtual void MacControlUserPaneDrawProc(wxInt16 part) ;
323 virtual wxInt16 MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) ;
324 virtual wxInt16 MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc) ;
325 virtual void MacControlUserPaneIdleProc() ;
326 virtual wxInt16 MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers) ;
327 virtual void MacControlUserPaneActivateProc(bool activating) ;
328 virtual wxInt16 MacControlUserPaneFocusProc(wxInt16 action) ;
329 virtual void MacControlUserPaneBackgroundProc(void* info) ;
330
331 virtual void SetRect( Rect *r ) ;
332
333 protected :
334 OSStatus DoCreate();
335
336 void MacUpdatePosition() ;
337 void MacActivatePaneText(Boolean setActive) ;
338 void MacFocusPaneText(Boolean setFocus) ;
339
340 void MacSetObjectVisibility(Boolean vis) ;
341 private :
342 TXNFrameID m_txnFrameID ;
343 GrafPtr m_txnPort ;
344 // bounds of the control as we last did set the txn frames
345 Rect m_txnControlBounds ;
346
347 bool m_txnIsFocused ;
348 bool m_txnIsActive ;
349 bool m_txnIsVisible ;
350 bool m_controlIsActive ;
351 } ;
352
353 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
354
355 #if !USE_SHARED_LIBRARY
356 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
357
358 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
359 EVT_ERASE_BACKGROUND( wxTextCtrl::OnEraseBackground )
360 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
361 EVT_CHAR(wxTextCtrl::OnChar)
362 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
363 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
364 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
365 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
366 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
367
368 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
369 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
370 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
371 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
372 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
373 END_EVENT_TABLE()
374 #endif
375
376 // Text item
377 void wxTextCtrl::Init()
378 {
379 m_editable = true ;
380 m_dirty = false;
381
382 m_maxLength = TE_UNLIMITED_LENGTH ;
383 }
384
385 wxTextCtrl::~wxTextCtrl()
386 {
387 }
388
389
390 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
391 const wxString& str,
392 const wxPoint& pos,
393 const wxSize& size, long style,
394 const wxValidator& validator,
395 const wxString& name)
396 {
397 m_macIsUserPane = false ;
398 m_editable = true ;
399
400 if ( ! ( style & wxNO_BORDER) )
401 style = ( style & ~wxBORDER_MASK) | wxSUNKEN_BORDER ;
402
403 if ( !wxTextCtrlBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
404 return false;
405
406 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
407
408 if ( m_windowStyle & wxTE_MULTILINE )
409 {
410 wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
411 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
412
413 m_windowStyle |= wxTE_PROCESS_ENTER;
414 style |= wxTE_PROCESS_ENTER ;
415 }
416
417 #ifdef __WXMAC_OSX__
418 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
419 if ( UMAGetSystemVersion() >= 0x1030 )
420 {
421 m_peer = new wxMacMLTEHIViewControl( this , str , pos , size , style ) ;
422 }
423 #endif
424 #if !wxMAC_AWAYS_USE_MLTE
425 if ( !m_peer )
426 {
427 m_peer = new wxMacUnicodeTextControl( this , str , pos , size , style ) ;
428 }
429 #endif
430 #endif
431 if ( !m_peer )
432 {
433 m_peer = new wxMacMLTEClassicControl( this , str , pos , size , style ) ;
434 }
435
436 MacPostControlCreate(pos,size) ;
437
438 if ( m_windowStyle & wxTE_READONLY)
439 {
440 SetEditable( false ) ;
441 }
442
443 return true;
444 }
445
446 void wxTextCtrl::MacVisibilityChanged()
447 {
448 GetPeer()->VisibilityChanged( MacIsReallyShown() ) ;
449 }
450
451 void wxTextCtrl::MacEnabledStateChanged()
452 {
453 }
454
455 wxString wxTextCtrl::GetValue() const
456 {
457 return GetPeer()->GetStringValue() ;
458 }
459
460 void wxTextCtrl::GetSelection(long* from, long* to) const
461 {
462 GetPeer()->GetSelection( from , to ) ;
463 }
464
465 void wxTextCtrl::SetValue(const wxString& str)
466 {
467 // optimize redraws
468 if ( GetValue() == str )
469 return ;
470
471 GetPeer()->SetStringValue(str) ;
472
473 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
474 event.SetString( GetValue() ) ;
475 event.SetEventObject( this );
476 GetEventHandler()->ProcessEvent(event);
477 }
478
479 void wxTextCtrl::SetMaxLength(unsigned long len)
480 {
481 m_maxLength = len ;
482 }
483
484 bool wxTextCtrl::SetFont( const wxFont& font )
485 {
486 if ( !wxTextCtrlBase::SetFont( font ) )
487 return false ;
488
489 GetPeer()->SetFont( font , GetForegroundColour() , GetWindowStyle() ) ;
490 return true ;
491 }
492
493 bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
494 {
495 GetPeer()->SetStyle( start , end , style ) ;
496 return true ;
497 }
498
499 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style)
500 {
501 wxTextCtrlBase::SetDefaultStyle( style ) ;
502 SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
503 return true ;
504 }
505
506 // Clipboard operations
507 void wxTextCtrl::Copy()
508 {
509 if (CanCopy())
510 {
511 GetPeer()->Copy() ;
512 }
513 }
514
515 void wxTextCtrl::Cut()
516 {
517 if (CanCut())
518 {
519 GetPeer()->Cut() ;
520
521 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
522 event.SetEventObject( this );
523 GetEventHandler()->ProcessEvent(event);
524 }
525 }
526
527 void wxTextCtrl::Paste()
528 {
529 if (CanPaste())
530 {
531 GetPeer()->Paste() ;
532 // eventually we should add setting the default style again
533
534 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
535 event.SetEventObject( this );
536 GetEventHandler()->ProcessEvent(event);
537 }
538 }
539
540 bool wxTextCtrl::CanCopy() const
541 {
542 // Can copy if there's a selection
543 long from, to;
544 GetSelection(& from, & to);
545 return (from != to);
546 }
547
548 bool wxTextCtrl::CanCut() const
549 {
550 if ( !IsEditable() )
551 {
552 return false ;
553 }
554 // Can cut if there's a selection
555 long from, to;
556 GetSelection(& from, & to);
557 return (from != to);
558 }
559
560 bool wxTextCtrl::CanPaste() const
561 {
562 if (!IsEditable())
563 return false;
564
565 return GetPeer()->CanPaste() ;
566 }
567
568 void wxTextCtrl::SetEditable(bool editable)
569 {
570 if ( editable != m_editable )
571 {
572 m_editable = editable ;
573 GetPeer()->SetEditable( editable ) ;
574 }
575 }
576
577 void wxTextCtrl::SetInsertionPoint(long pos)
578 {
579 SetSelection( pos , pos ) ;
580 }
581
582 void wxTextCtrl::SetInsertionPointEnd()
583 {
584 wxTextPos pos = GetLastPosition();
585 SetInsertionPoint(pos);
586 }
587
588 long wxTextCtrl::GetInsertionPoint() const
589 {
590 long begin,end ;
591 GetSelection( &begin , &end ) ;
592 return begin ;
593 }
594
595 wxTextPos wxTextCtrl::GetLastPosition() const
596 {
597 return GetPeer()->GetLastPosition( ) ;
598 }
599
600 void wxTextCtrl::Replace(long from, long to, const wxString& str)
601 {
602 GetPeer()->Replace( from , to , str) ;
603 }
604
605 void wxTextCtrl::Remove(long from, long to)
606 {
607 GetPeer()->Remove( from , to ) ;
608 }
609
610 void wxTextCtrl::SetSelection(long from, long to)
611 {
612 GetPeer()->SetSelection( from , to ) ;
613 }
614
615 bool wxTextCtrl::LoadFile(const wxString& file)
616 {
617 if ( wxTextCtrlBase::LoadFile(file) )
618 {
619 return true;
620 }
621
622 return false;
623 }
624
625 void wxTextCtrl::WriteText(const wxString& str)
626 {
627 // TODO this MPRemoting will be moved into a remoting peer proxy for any command
628 if ( !wxIsMainThread() )
629 {
630 // unfortunately CW 8 is not able to correctly deduce the template types, so we have
631 // to instantiate explicitely
632 wxMacMPRemoteGUICall<wxTextCtrl,wxString>( this , &wxTextCtrl::WriteText , str ) ;
633 return ;
634 }
635 else
636 {
637 GetPeer()->WriteText( str ) ;
638 }
639 }
640
641 void wxTextCtrl::AppendText(const wxString& text)
642 {
643 SetInsertionPointEnd();
644 WriteText(text);
645 }
646
647 void wxTextCtrl::Clear()
648 {
649 GetPeer()->Clear() ;
650 }
651
652 bool wxTextCtrl::IsModified() const
653 {
654 return m_dirty;
655 }
656
657 bool wxTextCtrl::IsEditable() const
658 {
659 return IsEnabled() && m_editable ;
660 }
661
662 bool wxTextCtrl::AcceptsFocus() const
663 {
664 // we don't want focus if we can't be edited
665 return /*IsEditable() && */ wxControl::AcceptsFocus();
666 }
667
668 wxSize wxTextCtrl::DoGetBestSize() const
669 {
670 int wText = 100 ;
671
672 int hText;
673
674 // these are the numbers from the HIG, we reduce them by the borders
675 // first
676
677 switch( m_windowVariant )
678 {
679 case wxWINDOW_VARIANT_NORMAL :
680 hText = 22 - 6 ;
681 break ;
682 case wxWINDOW_VARIANT_SMALL :
683 hText = 19 - 6 ;
684 break ;
685 case wxWINDOW_VARIANT_MINI :
686 hText= 15 - 6 ;
687 break ;
688 default :
689 hText = 22 - 6;
690 break ;
691 }
692
693 // as the above numbers have some free space around the text
694 // we get 5 lines like this anyway
695 if ( m_windowStyle & wxTE_MULTILINE )
696 {
697 hText *= 5 ;
698 }
699
700 if ( !HasFlag(wxNO_BORDER) )
701 hText += 6 ;
702
703 return wxSize(wText, hText);
704 }
705
706 // ----------------------------------------------------------------------------
707 // Undo/redo
708 // ----------------------------------------------------------------------------
709
710 void wxTextCtrl::Undo()
711 {
712 if (CanUndo())
713 {
714 GetPeer()->Undo() ;
715 }
716 }
717
718 void wxTextCtrl::Redo()
719 {
720 if (CanRedo())
721 {
722 GetPeer()->Redo() ;
723 }
724 }
725
726 bool wxTextCtrl::CanUndo() const
727 {
728 if ( !IsEditable() )
729 {
730 return false ;
731 }
732 return GetPeer()->CanUndo() ;
733 }
734
735 bool wxTextCtrl::CanRedo() const
736 {
737 if ( !IsEditable() )
738 {
739 return false ;
740 }
741 return GetPeer()->CanRedo() ;
742 }
743
744 void wxTextCtrl::MarkDirty()
745 {
746 m_dirty = true;
747 }
748
749 void wxTextCtrl::DiscardEdits()
750 {
751 m_dirty = false;
752 }
753
754 int wxTextCtrl::GetNumberOfLines() const
755 {
756 return GetPeer()->GetNumberOfLines() ;
757 }
758
759 long wxTextCtrl::XYToPosition(long x, long y) const
760 {
761 return GetPeer()->XYToPosition( x , y ) ;
762 }
763
764 bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
765 {
766 return GetPeer()->PositionToXY(pos , x , y ) ;
767 }
768
769 void wxTextCtrl::ShowPosition(long pos)
770 {
771 return GetPeer()->ShowPosition(pos) ;
772 }
773
774 int wxTextCtrl::GetLineLength(long lineNo) const
775 {
776 return GetPeer()->GetLineLength(lineNo) ;
777 }
778
779 wxString wxTextCtrl::GetLineText(long lineNo) const
780 {
781 return GetPeer()->GetLineText(lineNo) ;
782 }
783
784 /*
785 * Text item
786 */
787
788 void wxTextCtrl::Command(wxCommandEvent & event)
789 {
790 SetValue (event.GetString());
791 ProcessCommand (event);
792 }
793
794 void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
795 {
796 // By default, load the first file into the text window.
797 if (event.GetNumberOfFiles() > 0)
798 {
799 LoadFile(event.GetFiles()[0]);
800 }
801 }
802
803 void wxTextCtrl::OnEraseBackground(wxEraseEvent& event)
804 {
805 // all erasing should be done by the real mac control implementation
806 // while this is true for MLTE under classic, the HITextView is somehow
807 // transparent but background erase is not working correctly, so intercept
808 // things while we can...
809 event.Skip() ;
810 }
811
812 void wxTextCtrl::OnChar(wxKeyEvent& event)
813 {
814 int key = event.GetKeyCode() ;
815 bool eat_key = false ;
816
817 if ( key == 'c' && event.MetaDown() )
818 {
819 if ( CanCopy() )
820 Copy() ;
821 return ;
822 }
823
824 if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
825 !( key == WXK_RETURN && ( (m_windowStyle & wxPROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
826 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
827 )
828 {
829 // eat it
830 return ;
831 }
832
833 // Check if we have reached the max # of chars, but still allow navigation and deletion
834 if ( !IsMultiLine() && GetValue().Length() >= m_maxLength &&
835 key != WXK_LEFT && key != WXK_RIGHT && key != WXK_TAB &&
836 key != WXK_BACK && !( key == WXK_RETURN && (m_windowStyle & wxPROCESS_ENTER) )
837 )
838 {
839 // eat it, we don't want to add more than allowed # of characters
840 return;
841 }
842
843 // assume that any key not processed yet is going to modify the control
844 m_dirty = true;
845
846 if ( key == 'v' && event.MetaDown() )
847 {
848 if ( CanPaste() )
849 Paste() ;
850 return ;
851 }
852 if ( key == 'x' && event.MetaDown() )
853 {
854 if ( CanCut() )
855 Cut() ;
856 return ;
857 }
858 switch ( key )
859 {
860 case WXK_RETURN:
861 if (m_windowStyle & wxPROCESS_ENTER)
862 {
863 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
864 event.SetEventObject( this );
865 event.SetString( GetValue() );
866 if ( GetEventHandler()->ProcessEvent(event) )
867 return;
868 }
869 if ( !(m_windowStyle & wxTE_MULTILINE) )
870 {
871 wxWindow *parent = GetParent();
872 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
873 parent = parent->GetParent() ;
874 }
875 if ( parent && parent->GetDefaultItem() )
876 {
877 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
878 wxButton);
879 if ( def && def->IsEnabled() )
880 {
881 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
882 event.SetEventObject(def);
883 def->Command(event);
884 return ;
885 }
886 }
887
888 // this will make wxWidgets eat the ENTER key so that
889 // we actually prevent line wrapping in a single line
890 // text control
891 eat_key = true;
892 }
893
894 break;
895
896 case WXK_TAB:
897 if ( !(m_windowStyle & wxTE_PROCESS_TAB))
898 {
899 int flags = 0;
900 if (!event.ShiftDown())
901 flags |= wxNavigationKeyEvent::IsForward ;
902 if (event.ControlDown())
903 flags |= wxNavigationKeyEvent::WinChange ;
904 Navigate(flags);
905 return;
906 }
907 else
908 {
909 // This is necessary (don't know why) or the tab will not
910 // be inserted.
911 WriteText(wxT("\t"));
912 }
913
914 break;
915 }
916
917 if (!eat_key)
918 {
919 // perform keystroke handling
920 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
921 CallNextEventHandler((EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
922 else
923 {
924 EventRecord rec ;
925 if ( wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) )
926 {
927 EventRecord *ev = &rec ;
928 short keycode ;
929 short keychar ;
930 keychar = short(ev->message & charCodeMask);
931 keycode = short(ev->message & keyCodeMask) >> 8 ;
932
933 m_peer->HandleKey( keycode , keychar , ev->modifiers ) ;
934 }
935 }
936 }
937 if ( ( key >= 0x20 && key < WXK_START ) ||
938 key == WXK_RETURN ||
939 key == WXK_DELETE ||
940 key == WXK_BACK)
941 {
942 wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
943 event1.SetEventObject( this );
944 wxPostEvent(GetEventHandler(),event1);
945 }
946 }
947
948 // ----------------------------------------------------------------------------
949 // standard handlers for standard edit menu events
950 // ----------------------------------------------------------------------------
951
952 void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
953 {
954 Cut();
955 }
956
957 void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
958 {
959 Copy();
960 }
961
962 void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
963 {
964 Paste();
965 }
966
967 void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
968 {
969 Undo();
970 }
971
972 void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
973 {
974 Redo();
975 }
976
977 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
978 {
979 event.Enable( CanCut() );
980 }
981
982 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
983 {
984 event.Enable( CanCopy() );
985 }
986
987 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
988 {
989 event.Enable( CanPaste() );
990 }
991
992 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
993 {
994 event.Enable( CanUndo() );
995 }
996
997 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
998 {
999 event.Enable( CanRedo() );
1000 }
1001
1002 bool wxTextCtrl::MacSetupCursor( const wxPoint& pt )
1003 {
1004 return true ;
1005 }
1006 #if !TARGET_API_MAC_OSX
1007
1008 // user pane implementation
1009
1010 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part)
1011 {
1012 GetPeer()->MacControlUserPaneDrawProc( part ) ;
1013 }
1014
1015 wxInt16 wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
1016 {
1017 return GetPeer()->MacControlUserPaneHitTestProc( x , y ) ;
1018 }
1019
1020 wxInt16 wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
1021 {
1022 return GetPeer()->MacControlUserPaneTrackingProc( x , y , actionProc ) ;
1023 }
1024
1025 void wxTextCtrl::MacControlUserPaneIdleProc()
1026 {
1027 GetPeer()->MacControlUserPaneIdleProc( ) ;
1028 }
1029
1030 wxInt16 wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
1031 {
1032 return GetPeer()->MacControlUserPaneKeyDownProc( keyCode , charCode , modifiers ) ;
1033 }
1034
1035 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating)
1036 {
1037 GetPeer()->MacControlUserPaneActivateProc( activating ) ;
1038 }
1039
1040 wxInt16 wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action)
1041 {
1042 return GetPeer()->MacControlUserPaneFocusProc( action ) ;
1043 }
1044
1045 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info)
1046 {
1047 GetPeer()->MacControlUserPaneBackgroundProc( info ) ;
1048 }
1049
1050 #endif
1051 // ----------------------------------------------------------------------------
1052 // implementation base class
1053 // ----------------------------------------------------------------------------
1054
1055 wxMacTextControl::wxMacTextControl(wxTextCtrl* peer) :
1056 wxMacControl( peer )
1057 {
1058 }
1059
1060 wxMacTextControl::~wxMacTextControl()
1061 {
1062 }
1063
1064 void wxMacTextControl::SetStyle(long start, long end, const wxTextAttr& style)
1065 {
1066 }
1067
1068 void wxMacTextControl::Copy()
1069 {
1070 }
1071
1072 void wxMacTextControl::Cut()
1073 {
1074 }
1075
1076 void wxMacTextControl::Paste()
1077 {
1078 }
1079
1080 bool wxMacTextControl::CanPaste() const
1081 {
1082 return false ;
1083 }
1084
1085 void wxMacTextControl::SetEditable(bool editable)
1086 {
1087 }
1088
1089 wxTextPos wxMacTextControl::GetLastPosition() const
1090 {
1091 return GetStringValue().Length() ;
1092 }
1093
1094 void wxMacTextControl::Replace( long from , long to , const wxString str )
1095 {
1096 }
1097
1098 void wxMacTextControl::Clear()
1099 {
1100 SetStringValue( wxEmptyString ) ;
1101 }
1102
1103 bool wxMacTextControl::CanUndo() const
1104 {
1105 return false ;
1106 }
1107
1108 void wxMacTextControl::Undo() { }
1109
1110 bool wxMacTextControl::CanRedo() const
1111 {
1112 return false ;
1113 }
1114
1115 void wxMacTextControl::Redo()
1116 {
1117 }
1118
1119 long wxMacTextControl::XYToPosition(long x, long y) const
1120 {
1121 return 0 ;
1122 }
1123
1124 bool wxMacTextControl::PositionToXY(long pos, long *x, long *y) const
1125 {
1126 return false ;
1127 }
1128
1129 void wxMacTextControl::ShowPosition( long WXUNUSED(pos) )
1130 {
1131 }
1132
1133 int wxMacTextControl::GetNumberOfLines() const
1134 {
1135 ItemCount lines = 0 ;
1136 wxString content = GetStringValue() ;
1137 lines = 1;
1138 for (size_t i = 0; i < content.Length() ; i++)
1139 {
1140 if (content[i] == '\r') lines++;
1141 }
1142 return lines ;
1143 }
1144
1145 wxString wxMacTextControl::GetLineText(long lineNo) const
1146 {
1147 // TODO change this if possible to reflect real lines
1148 wxString content = GetStringValue() ;
1149
1150 // Find line first
1151 int count = 0;
1152 for (size_t i = 0; i < content.Length() ; i++)
1153 {
1154 if (count == lineNo)
1155 {
1156 // Add chars in line then
1157 wxString tmp;
1158
1159 for (size_t j = i; j < content.Length(); j++)
1160 {
1161 if (content[j] == '\n')
1162 return tmp;
1163
1164 tmp += content[j];
1165 }
1166
1167 return tmp;
1168 }
1169 if (content[i] == '\n') count++;
1170 }
1171 return wxEmptyString ;
1172 }
1173
1174 int wxMacTextControl::GetLineLength(long lineNo) const
1175 {
1176 // TODO change this if possible to reflect real lines
1177 wxString content = GetStringValue() ;
1178
1179 // Find line first
1180 int count = 0;
1181 for (size_t i = 0; i < content.Length() ; i++)
1182 {
1183 if (count == lineNo)
1184 {
1185 // Count chars in line then
1186 count = 0;
1187 for (size_t j = i; j < content.Length(); j++)
1188 {
1189 count++;
1190 if (content[j] == '\n') return count;
1191 }
1192
1193 return count;
1194 }
1195 if (content[i] == '\n') count++;
1196 }
1197 return 0 ;
1198 }
1199
1200 // ----------------------------------------------------------------------------
1201 // standard unicode control implementation
1202 // ----------------------------------------------------------------------------
1203
1204 #if TARGET_API_MAC_OSX
1205
1206 wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer,
1207 const wxString& str,
1208 const wxPoint& pos,
1209 const wxSize& size, long style ) : wxMacTextControl( wxPeer )
1210 {
1211 m_font = wxPeer->GetFont() ;
1212 m_windowStyle = style ;
1213 Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
1214 wxString st = str ;
1215 wxMacConvertNewlines10To13( &st ) ;
1216 wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
1217 CFStringRef cfr = cf ;
1218 Boolean isPassword = ( m_windowStyle & wxTE_PASSWORD ) != 0 ;
1219 m_valueTag = isPassword ? kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag ;
1220 CreateEditUnicodeTextControl( MAC_WXHWND(wxPeer->MacGetTopLevelWindowRef()), &bounds , cfr , isPassword , NULL , &m_controlRef ) ;
1221
1222 if ( !(m_windowStyle & wxTE_MULTILINE) )
1223 {
1224 SetData<Boolean>( kControlEditTextPart , kControlEditTextSingleLineTag , true ) ;
1225 }
1226 }
1227
1228 wxMacUnicodeTextControl::~wxMacUnicodeTextControl()
1229 {
1230 }
1231
1232 void wxMacUnicodeTextControl::VisibilityChanged(bool shown)
1233 {
1234 if ( !(m_windowStyle & wxTE_MULTILINE) && shown )
1235 {
1236 // work around a refresh issue insofar as not always the entire content is shown even if this would be possible
1237 ControlEditTextSelectionRec sel ;
1238 CFStringRef value = NULL ;
1239
1240 verify_noerr( GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
1241 verify_noerr( GetData<CFStringRef>( 0, m_valueTag , &value ) );
1242 verify_noerr( SetData<CFStringRef>( 0, m_valueTag, &value ) );
1243 verify_noerr( SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
1244
1245 CFRelease( value ) ;
1246 }
1247 }
1248 wxString wxMacUnicodeTextControl::GetStringValue() const
1249 {
1250 wxString result ;
1251 CFStringRef value = GetData<CFStringRef>(0,m_valueTag) ;
1252 if ( value )
1253 {
1254 wxMacCFStringHolder cf(value) ;
1255 result = cf.AsString() ;
1256 }
1257 #if '\n' == 10
1258 wxMacConvertNewlines13To10( &result ) ;
1259 #else
1260 wxMacConvertNewlines10To13( &result ) ;
1261 #endif
1262 return result ;
1263 }
1264 void wxMacUnicodeTextControl::SetStringValue( const wxString &str)
1265 {
1266 wxString st = str ;
1267 wxMacConvertNewlines10To13( &st ) ;
1268 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
1269 verify_noerr( SetData<CFStringRef>( 0, m_valueTag , cf ) ) ;
1270 }
1271 void wxMacUnicodeTextControl::Copy()
1272 {
1273 SendHICommand( kHICommandCopy ) ;
1274 }
1275 void wxMacUnicodeTextControl::Cut()
1276 {
1277 SendHICommand( kHICommandCut ) ;
1278 }
1279 void wxMacUnicodeTextControl::Paste()
1280 {
1281 SendHICommand( kHICommandPaste ) ;
1282 }
1283 bool wxMacUnicodeTextControl::CanPaste() const
1284 {
1285 return true ;
1286 }
1287 void wxMacUnicodeTextControl::SetEditable(bool editable)
1288 {
1289 SetData<Boolean>( 0 , kControlEditTextLockedTag , (Boolean) !editable ) ;
1290 }
1291 void wxMacUnicodeTextControl::Remove( long from , long to )
1292 {
1293 }
1294
1295 void wxMacUnicodeTextControl::GetSelection( long* from, long* to) const
1296 {
1297 ControlEditTextSelectionRec sel ;
1298 verify_noerr(GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) ) ;
1299 if ( from ) *from = sel.selStart ;
1300 if ( to ) *to = sel.selEnd ;
1301 }
1302
1303 void wxMacUnicodeTextControl::SetSelection( long from , long to )
1304 {
1305 ControlEditTextSelectionRec sel ;
1306 sel.selStart = from ;
1307 sel.selEnd = to ;
1308 SetData<ControlEditTextSelectionRec>( 0 , kControlEditTextSelectionTag, &sel ) ;
1309 }
1310
1311 void wxMacUnicodeTextControl::WriteText(const wxString& str)
1312 {
1313 wxString st = str ;
1314 wxMacConvertNewlines10To13( &st ) ;
1315 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1316 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
1317 CFStringRef value = cf ;
1318 SetData<CFStringRef>( 0, kControlEditTextInsertCFStringRefTag, &value );
1319 #else
1320 wxString val = GetStringValue() ;
1321 long start , end ;
1322 GetSelection( &start , &end ) ;
1323 val.Remove( start , end - start ) ;
1324 val.insert( start , str ) ;
1325 SetStringValue( val ) ;
1326 SetSelection( start + str.Length() , start + str.Length() ) ;
1327 #endif
1328 }
1329
1330 #endif
1331
1332 // ----------------------------------------------------------------------------
1333 // MLTE control implementation (common part)
1334 // ----------------------------------------------------------------------------
1335
1336 // if mlte is on read only , no changes at all are allowed, not even from
1337 // procedural API, in order to allow changes via API all the same we must undo
1338 // the readonly status while we are executing, this class helps to do so
1339
1340 class EditHelper
1341 {
1342 public :
1343 EditHelper( TXNObject txn )
1344 {
1345 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1346 m_txn = txn ;
1347 TXNGetTXNObjectControls( m_txn , 1 , tag , m_data ) ;
1348 if ( m_data[0].uValue == kTXNReadOnly )
1349 {
1350 TXNControlData data[] = { { kTXNReadWrite } } ;
1351 TXNSetTXNObjectControls( m_txn , false , 1 , tag , data ) ;
1352 }
1353 }
1354 ~EditHelper()
1355 {
1356 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1357 if ( m_data[0].uValue == kTXNReadOnly )
1358 {
1359 TXNSetTXNObjectControls( m_txn , false , 1 , tag , m_data ) ;
1360 }
1361 }
1362 protected :
1363 TXNObject m_txn ;
1364 TXNControlData m_data[1] ;
1365 } ;
1366
1367 wxString wxMacMLTEControl::GetStringValue() const
1368 {
1369 wxString result ;
1370 OSStatus err ;
1371 Size actualSize = 0;
1372 {
1373 #if wxUSE_UNICODE
1374 Handle theText ;
1375 err = TXNGetDataEncoded( m_txn , kTXNStartOffset, kTXNEndOffset, &theText , kTXNUnicodeTextData );
1376 // all done
1377 if ( err )
1378 {
1379 actualSize = 0 ;
1380 }
1381 else
1382 {
1383 actualSize = GetHandleSize( theText ) / sizeof( UniChar) ;
1384 if ( actualSize > 0 )
1385 {
1386 wxChar *ptr = NULL ;
1387 #if SIZEOF_WCHAR_T == 2
1388 ptr = new wxChar[actualSize + 1 ] ;
1389 wxStrncpy( ptr , (wxChar*) *theText , actualSize ) ;
1390 #else
1391 SetHandleSize( theText , ( actualSize + 1 ) * sizeof( UniChar ) ) ;
1392 HLock( theText ) ;
1393 (((UniChar*)*theText)[actualSize]) = 0 ;
1394 wxMBConvUTF16BE converter ;
1395 size_t noChars = converter.MB2WC( NULL , (const char*)*theText , 0 ) ;
1396 ptr = new wxChar[noChars + 1] ;
1397
1398 noChars = converter.MB2WC( ptr , (const char*)*theText , noChars ) ;
1399 ptr[noChars] = 0 ;
1400 HUnlock( theText ) ;
1401 #endif
1402 ptr[actualSize] = 0 ;
1403 result = wxString( ptr ) ;
1404 delete[] ptr ;
1405 }
1406 DisposeHandle( theText ) ;
1407 }
1408 #else
1409 Handle theText ;
1410 err = TXNGetDataEncoded( m_txn , kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
1411 // all done
1412 if ( err )
1413 {
1414 actualSize = 0 ;
1415 }
1416 else
1417 {
1418 actualSize = GetHandleSize( theText ) ;
1419 if ( actualSize > 0 )
1420 {
1421 HLock( theText ) ;
1422 result = wxString( *theText , wxConvLocal , actualSize ) ;
1423 HUnlock( theText ) ;
1424 }
1425 DisposeHandle( theText ) ;
1426 }
1427 #endif
1428 }
1429 #if '\n' == 10
1430 wxMacConvertNewlines13To10( &result ) ;
1431 #else
1432 wxMacConvertNewlines10To13( &result ) ;
1433 #endif
1434 return result ;
1435 }
1436
1437 void wxMacMLTEControl::SetStringValue( const wxString &str)
1438 {
1439 wxString st = str ;
1440
1441 wxMacConvertNewlines10To13( &st ) ;
1442 EditHelper help(m_txn) ;
1443
1444 #if !TARGET_API_MAC_OSX
1445 // otherwise scrolling might have problems ?
1446 // MacUpdatePosition( m_controlRef ) ;
1447 #endif
1448 wxMacWindowClipper c( m_peer ) ;
1449 SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ;
1450 TXNSetSelection( m_txn, 0, 0);
1451 TXNShowSelection( m_txn, kTXNShowStart);
1452 }
1453
1454 TXNFrameOptions wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle )
1455 {
1456 TXNFrameOptions frameOptions =
1457 kTXNDontDrawCaretWhenInactiveMask ;
1458 if ( ! ( wxStyle & wxTE_NOHIDESEL ) )
1459 frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ;
1460
1461 if ( wxStyle & wxTE_MULTILINE )
1462 {
1463 if ( ! ( wxStyle & wxTE_DONTWRAP ) )
1464 frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
1465 else
1466 {
1467 frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
1468 frameOptions |= kTXNWantHScrollBarMask ;
1469 }
1470
1471 if ( !(wxStyle & wxTE_NO_VSCROLL ) )
1472 frameOptions |= kTXNWantVScrollBarMask ;
1473 }
1474 else
1475 frameOptions |= kTXNSingleLineOnlyMask ;
1476
1477 if ( wxStyle & wxHSCROLL )
1478 frameOptions |= kTXNWantHScrollBarMask ;
1479
1480 return frameOptions ;
1481 }
1482
1483 void wxMacMLTEControl::AdjustCreationAttributes( const wxColour &background, bool visible )
1484 {
1485 TXNControlTag iControlTags[3] = { kTXNDoFontSubstitution, kTXNWordWrapStateTag };
1486 TXNControlData iControlData[3] = { {false}, {kTXNNoAutoWrap} };
1487 int toptag = 2 ;
1488 #if TARGET_API_MAC_OSX
1489 iControlTags[2] = kTXNVisibilityTag ;
1490 iControlData[2].uValue = visible ;
1491 toptag++ ;
1492 #endif
1493
1494 if ( m_windowStyle & wxTE_MULTILINE )
1495 {
1496 if (m_windowStyle & wxTE_DONTWRAP)
1497 iControlData[1].uValue = kTXNNoAutoWrap ;
1498 else
1499 iControlData[1].uValue = kTXNAutoWrap ;
1500 }
1501 verify_noerr( TXNSetTXNObjectControls( m_txn, true, toptag,
1502 iControlTags, iControlData )) ;
1503
1504 // setting the default font
1505
1506 Str255 fontName ;
1507 SInt16 fontSize ;
1508 Style fontStyle ;
1509
1510 GetThemeFont(kThemeSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
1511
1512 TXNTypeAttributes typeAttr[] =
1513 {
1514 { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } ,
1515 { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } ,
1516 { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } ,
1517 } ;
1518
1519 verify_noerr( TXNSetTypeAttributes (m_txn, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr,
1520 kTXNStartOffset,
1521 kTXNEndOffset) );
1522
1523 if ( m_windowStyle & wxTE_PASSWORD )
1524 {
1525 UniChar c = 0xA5 ;
1526 verify_noerr(TXNEchoMode( m_txn , c , 0 , true )) ;
1527 }
1528
1529 TXNBackground tback;
1530 tback.bgType = kTXNBackgroundTypeRGB;
1531 tback.bg.color = MAC_WXCOLORREF( background.GetPixel() );
1532 TXNSetBackground( m_txn , &tback);
1533 }
1534
1535 void wxMacMLTEControl::SetBackground( const wxBrush &brush )
1536 {
1537 // currently only solid background are supported
1538 TXNBackground tback;
1539 tback.bgType = kTXNBackgroundTypeRGB;
1540 tback.bg.color = MAC_WXCOLORREF( brush.GetColour().GetPixel() );
1541 TXNSetBackground( m_txn , &tback);
1542 }
1543
1544 void wxMacMLTEControl::TXNSetAttribute( const wxTextAttr& style , long from , long to)
1545 {
1546 TXNTypeAttributes typeAttr[4] ;
1547 Str255 fontName = "\pMonaco" ;
1548 SInt16 fontSize = 12 ;
1549 Style fontStyle = normal ;
1550 RGBColor color ;
1551 int attrCounter = 0 ;
1552 if ( style.HasFont() )
1553 {
1554 const wxFont &font = style.GetFont() ;
1555 wxMacStringToPascal( font.GetFaceName() , fontName ) ;
1556 fontSize = font.GetPointSize() ;
1557 if ( font.GetUnderlined() )
1558 fontStyle |= underline ;
1559 if ( font.GetWeight() == wxBOLD )
1560 fontStyle |= bold ;
1561 if ( font.GetStyle() == wxITALIC )
1562 fontStyle |= italic ;
1563
1564 typeAttr[attrCounter].tag = kTXNQDFontNameAttribute ;
1565 typeAttr[attrCounter].size = kTXNQDFontNameAttributeSize ;
1566 typeAttr[attrCounter].data.dataPtr = (void*) fontName ;
1567 typeAttr[attrCounter+1].tag = kTXNQDFontSizeAttribute ;
1568 typeAttr[attrCounter+1].size = kTXNFontSizeAttributeSize ;
1569 typeAttr[attrCounter+1].data.dataValue = (fontSize << 16) ;
1570 typeAttr[attrCounter+2].tag = kTXNQDFontStyleAttribute ;
1571 typeAttr[attrCounter+2].size = kTXNQDFontStyleAttributeSize ;
1572 typeAttr[attrCounter+2].data.dataValue = fontStyle ;
1573 attrCounter += 3 ;
1574 }
1575 if ( style.HasTextColour() )
1576 {
1577 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1578 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1579 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1580 color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ;
1581 attrCounter += 1 ;
1582 }
1583 if ( attrCounter > 0 )
1584 {
1585 verify_noerr( TXNSetTypeAttributes ( m_txn , attrCounter , typeAttr, from , to) );
1586 }
1587 }
1588
1589 void wxMacMLTEControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
1590 {
1591 EditHelper help(m_txn) ;
1592 TXNSetAttribute( wxTextAttr(foreground,wxNullColour,font) , kTXNStartOffset,kTXNEndOffset ) ;
1593 }
1594 void wxMacMLTEControl::SetStyle(long start, long end, const wxTextAttr& style)
1595 {
1596 EditHelper help(m_txn) ;
1597 TXNSetAttribute( style , start,end ) ;
1598 }
1599
1600 void wxMacMLTEControl::Copy()
1601 {
1602 ClearCurrentScrap();
1603 TXNCopy(m_txn);
1604 TXNConvertToPublicScrap();
1605 }
1606
1607 void wxMacMLTEControl::Cut()
1608 {
1609 ClearCurrentScrap();
1610 TXNCut(m_txn);
1611 TXNConvertToPublicScrap();
1612 }
1613
1614 void wxMacMLTEControl::Paste()
1615 {
1616 TXNConvertFromPublicScrap();
1617 TXNPaste(m_txn);
1618 }
1619
1620 bool wxMacMLTEControl::CanPaste() const
1621 {
1622 return TXNIsScrapPastable() ;
1623 }
1624
1625 void wxMacMLTEControl::SetEditable(bool editable)
1626 {
1627 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1628 TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ;
1629 TXNSetTXNObjectControls( m_txn , false , sizeof(tag) / sizeof (TXNControlTag) , tag , data ) ;
1630 }
1631
1632 wxTextPos wxMacMLTEControl::GetLastPosition() const
1633 {
1634 wxTextPos actualsize = 0 ;
1635
1636 Handle theText ;
1637 OSErr err = TXNGetDataEncoded( m_txn, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
1638 /* all done */
1639 if ( err )
1640 {
1641 actualsize = 0 ;
1642 }
1643 else
1644 {
1645 actualsize = GetHandleSize( theText ) ;
1646 DisposeHandle( theText ) ;
1647 }
1648
1649 return actualsize ;
1650 }
1651
1652 void wxMacMLTEControl::Replace( long from , long to , const wxString str )
1653 {
1654 wxString value = str ;
1655 wxMacConvertNewlines10To13( &value ) ;
1656
1657 EditHelper help( m_txn ) ;
1658 wxMacWindowClipper c( m_peer ) ;
1659
1660 TXNSetSelection(m_txn , from , to ) ;
1661 TXNClear( m_txn ) ;
1662 SetTXNData( value , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
1663 }
1664
1665 void wxMacMLTEControl::Remove( long from , long to )
1666 {
1667 wxMacWindowClipper c( m_peer ) ;
1668 EditHelper help( m_txn ) ;
1669 TXNSetSelection(m_txn , from , to ) ;
1670 TXNClear( m_txn ) ;
1671 }
1672
1673 void wxMacMLTEControl::GetSelection( long* from, long* to) const
1674 {
1675 TXNGetSelection( m_txn , (TXNOffset*) from , (TXNOffset*) to ) ;
1676 }
1677
1678 void wxMacMLTEControl::SetSelection( long from , long to )
1679 {
1680 wxMacWindowClipper c( m_peer ) ;
1681 /* change the selection */
1682 if ((from == -1) && (to == -1))
1683 TXNSelectAll(m_txn);
1684 else
1685 TXNSetSelection( m_txn, from, to);
1686 TXNShowSelection( m_txn, kTXNShowStart);
1687 }
1688
1689 void wxMacMLTEControl::WriteText(const wxString& str)
1690 {
1691 EditHelper helper( m_txn ) ;
1692 wxString st = str ;
1693 wxMacConvertNewlines10To13( &st ) ;
1694
1695 wxMacWindowClipper c( m_peer ) ;
1696 long start , end , dummy ;
1697 GetSelection( &start , &dummy ) ;
1698 SetTXNData( st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
1699 GetSelection( &dummy , &end ) ;
1700 // TODO SetStyle( start , end , GetDefaultStyle() ) ;
1701 }
1702
1703 void wxMacMLTEControl::Clear()
1704 {
1705 EditHelper st(m_txn) ;
1706 wxMacWindowClipper c( m_peer ) ;
1707 TXNSetSelection( m_txn , kTXNStartOffset , kTXNEndOffset ) ;
1708 TXNClear(m_txn);
1709 }
1710
1711 bool wxMacMLTEControl::CanUndo() const
1712 {
1713 return TXNCanUndo( m_txn , NULL ) ;
1714 }
1715
1716 void wxMacMLTEControl::Undo()
1717 {
1718 TXNUndo( m_txn ) ;
1719 }
1720
1721 bool wxMacMLTEControl::CanRedo() const
1722 {
1723 return TXNCanRedo( m_txn , NULL ) ;
1724 }
1725
1726 void wxMacMLTEControl::Redo()
1727 {
1728 TXNRedo( m_txn ) ;
1729 }
1730
1731 int wxMacMLTEControl::GetNumberOfLines() const
1732 {
1733 ItemCount lines = 0 ;
1734 TXNGetLineCount(m_txn, &lines ) ;
1735 return lines ;
1736 }
1737
1738 long wxMacMLTEControl::XYToPosition(long x, long y) const
1739 {
1740 Point curpt ;
1741
1742 wxTextPos lastpos = GetLastPosition() ;
1743
1744 // TODO find a better implementation : while we can get the
1745 // line metrics of a certain line, we don't get its starting
1746 // position, so it would probably be rather a binary search
1747 // for the start position
1748 long xpos = 0 ;
1749 long ypos = 0 ;
1750 int lastHeight = 0 ;
1751
1752 ItemCount n ;
1753 for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
1754 {
1755 if ( y == ypos && x == xpos )
1756 return n ;
1757
1758 TXNOffsetToPoint( m_txn , n , &curpt);
1759
1760 if ( curpt.v > lastHeight )
1761 {
1762 xpos = 0 ;
1763 if ( n > 0 )
1764 ++ypos ;
1765 lastHeight = curpt.v ;
1766 }
1767 else
1768 ++xpos ;
1769 }
1770 return 0 ;
1771 }
1772
1773 bool wxMacMLTEControl::PositionToXY(long pos, long *x, long *y) const
1774 {
1775 Point curpt ;
1776
1777 wxTextPos lastpos = GetLastPosition() ;
1778
1779 if ( y ) *y = 0 ;
1780 if ( x ) *x = 0 ;
1781
1782 if ( pos <= lastpos )
1783 {
1784 // TODO find a better implementation : while we can get the
1785 // line metrics of a certain line, we don't get its starting
1786 // position, so it would probably be rather a binary search
1787 // for the start position
1788 long xpos = 0 ;
1789 long ypos = 0 ;
1790 int lastHeight = 0 ;
1791
1792 ItemCount n ;
1793 for ( n = 0 ; n <= (ItemCount) pos ; ++n )
1794 {
1795 TXNOffsetToPoint(m_txn , n , &curpt);
1796
1797 if ( curpt.v > lastHeight )
1798 {
1799 xpos = 0 ;
1800 if ( n > 0 )
1801 ++ypos ;
1802 lastHeight = curpt.v ;
1803 }
1804 else
1805 ++xpos ;
1806 }
1807 if ( y ) *y = ypos ;
1808 if ( x ) *x = xpos ;
1809 }
1810
1811 return false ;
1812 }
1813
1814 void wxMacMLTEControl::ShowPosition( long pos )
1815 {
1816 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1817 {
1818 Point current ;
1819 Point desired ;
1820 TXNOffset selstart , selend ;
1821 TXNGetSelection( m_txn , &selstart , &selend) ;
1822 TXNOffsetToPoint( m_txn, selstart , &current);
1823 TXNOffsetToPoint( m_txn, pos , &desired);
1824 //TODO use HIPoints for 10.3 and above
1825 if ( (UInt32) TXNScroll != (UInt32) kUnresolvedCFragSymbolAddress )
1826 {
1827 OSErr theErr = noErr;
1828 SInt32 dv = desired.v - current.v ;
1829 SInt32 dh = desired.h - current.h ;
1830 TXNShowSelection( m_txn , true ) ;
1831 theErr = TXNScroll( m_txn, kTXNScrollUnitsInPixels , kTXNScrollUnitsInPixels , &dv , &dh );
1832 wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") );
1833 }
1834 }
1835 #endif
1836 }
1837
1838 void wxMacMLTEControl::SetTXNData( const wxString& st , TXNOffset start , TXNOffset end )
1839 {
1840 #if wxUSE_UNICODE
1841 #if SIZEOF_WCHAR_T == 2
1842 size_t len = st.Len() ;
1843 TXNSetData( m_txn , kTXNUnicodeTextData, (void*)st.wc_str(), len * 2,
1844 start, end);
1845 #else
1846 wxMBConvUTF16BE converter ;
1847 ByteCount byteBufferLen = converter.WC2MB( NULL , st.wc_str() , 0 ) ;
1848 UniChar *unibuf = (UniChar*) malloc(byteBufferLen) ;
1849 converter.WC2MB( (char*) unibuf , st.wc_str() , byteBufferLen ) ;
1850 TXNSetData( m_txn , kTXNUnicodeTextData, (void*)unibuf, byteBufferLen ,
1851 start, end);
1852 free( unibuf ) ;
1853 #endif
1854 #else
1855 wxCharBuffer text = st.mb_str(wxConvLocal) ;
1856 TXNSetData( m_txn , kTXNTextData, (void*)text.data(), strlen( text ) ,
1857 start, end);
1858 #endif
1859 }
1860
1861
1862 wxString wxMacMLTEControl::GetLineText(long lineNo) const
1863 {
1864 wxString line ;
1865
1866 if ( lineNo < GetNumberOfLines() )
1867 {
1868 long ypos = 0 ;
1869
1870 Fixed lineWidth,
1871 lineHeight,
1872 currentHeight = 0;
1873
1874 // get the first possible position in the control
1875 Point firstPoint;
1876 TXNOffsetToPoint(m_txn, 0, &firstPoint);
1877
1878 // Iterate through the lines until we reach the one we want,
1879 // adding to our current y pixel point position
1880 while (ypos < lineNo)
1881 {
1882 TXNGetLineMetrics(m_txn, ypos++, &lineWidth, &lineHeight);
1883 currentHeight += lineHeight;
1884 }
1885
1886 Point thePoint = { firstPoint.v + (currentHeight >> 16), firstPoint.h + (0) };
1887 TXNOffset theOffset;
1888 TXNPointToOffset(m_txn, thePoint, &theOffset);
1889
1890 wxString content = GetStringValue() ;
1891 Point currentPoint = thePoint;
1892 while(thePoint.v == currentPoint.v && theOffset < content.length())
1893 {
1894 line += content[theOffset];
1895 TXNOffsetToPoint(m_txn, ++theOffset, &currentPoint);
1896 }
1897 }
1898 return line ;
1899 }
1900
1901 int wxMacMLTEControl::GetLineLength(long lineNo) const
1902 {
1903 int theLength = 0;
1904
1905 if ( lineNo < GetNumberOfLines() )
1906 {
1907 long ypos = 0 ;
1908
1909 Fixed lineWidth,
1910 lineHeight,
1911 currentHeight = 0;
1912
1913 // get the first possible position in the control
1914 Point firstPoint;
1915 TXNOffsetToPoint(m_txn, 0, &firstPoint);
1916
1917 // Iterate through the lines until we reach the one we want,
1918 // adding to our current y pixel point position
1919 while (ypos < lineNo)
1920 {
1921 TXNGetLineMetrics(m_txn, ypos++, &lineWidth, &lineHeight);
1922 currentHeight += lineHeight;
1923 }
1924
1925 Point thePoint = { firstPoint.v + (currentHeight >> 16), firstPoint.h + (0) };
1926 TXNOffset theOffset;
1927 TXNPointToOffset(m_txn, thePoint, &theOffset);
1928
1929 wxString content = GetStringValue() ;
1930 Point currentPoint = thePoint;
1931 while(thePoint.v == currentPoint.v && theOffset < content.length())
1932 {
1933 ++theLength;
1934 TXNOffsetToPoint(m_txn, ++theOffset, &currentPoint);
1935 }
1936 }
1937 return theLength ;
1938 }
1939
1940
1941 // ----------------------------------------------------------------------------
1942 // MLTE control implementation (classic part)
1943 // ----------------------------------------------------------------------------
1944
1945 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
1946 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
1947 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
1948 // an alternate path for carbon key events that routes automatically into the same wx flow of events
1949
1950 /* part codes */
1951
1952 /* kmUPTextPart is the part code we return to indicate the user has clicked
1953 in the text area of our control */
1954 #define kmUPTextPart 1
1955
1956
1957 /* routines for using existing user pane controls.
1958 These routines are useful for cases where you would like to use an
1959 existing user pane control in, say, a dialog window as a scrolling
1960 text edit field.*/
1961
1962 /* Utility Routines */
1963
1964 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
1965 routine. In our focus switching routine this part code is understood
1966 as meaning 'the user has clicked in the control and we need to switch
1967 the current focus to ourselves before we can continue'. */
1968 #define kUserClickedToFocusPart 100
1969
1970 /* STPTextPaneVars is a structure used for storing the the mUP Control's
1971 internal variables and state information. A handle to this record is
1972 stored in the pane control's reference value field using the
1973 SetControlReference routine. */
1974
1975 /* Univerals Procedure Pointer variables used by the
1976 mUP Control. These variables are set up
1977 the first time that mUPOpenControl is called. */
1978 ControlUserPaneDrawUPP gTPDrawProc = NULL;
1979 ControlUserPaneHitTestUPP gTPHitProc = NULL;
1980 ControlUserPaneTrackingUPP gTPTrackProc = NULL;
1981 ControlUserPaneIdleUPP gTPIdleProc = NULL;
1982 ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
1983 ControlUserPaneActivateUPP gTPActivateProc = NULL;
1984 ControlUserPaneFocusUPP gTPFocusProc = NULL;
1985
1986
1987 class wxMacMLTENoDraw
1988 {
1989 public :
1990 wxMacMLTENoDraw( TXNObject txn ) ;
1991 ~wxMacMLTENoDraw() ;
1992
1993 private :
1994 bool m_formerDraw ;
1995 TXNObject m_txn ;
1996 } ;
1997
1998 wxMacMLTENoDraw::wxMacMLTENoDraw( TXNObject txn )
1999 {
2000 m_txn = txn ;
2001 #ifdef __WXMAC_OSX__
2002 TXNControlTag iControlTags[1] = { kTXNVisibilityTag };
2003 TXNControlData iControlData[1] ;
2004
2005 TXNGetTXNObjectControls( m_txn , 1 , iControlTags , iControlData ) ;
2006 m_formerDraw = iControlData[0].uValue ;
2007 if ( m_formerDraw )
2008 {
2009 iControlData[0].uValue = 0 ;
2010 TXNSetTXNObjectControls( m_txn , 1 , true , iControlTags , iControlData ) ;
2011 }
2012 #endif
2013 }
2014
2015 wxMacMLTENoDraw::~wxMacMLTENoDraw()
2016 {
2017 #ifdef __WXMAC_OSX__
2018 if ( m_formerDraw )
2019 {
2020 TXNControlTag iControlTags[1] = { kTXNVisibilityTag };
2021 TXNControlData iControlData[1] ;
2022
2023 iControlData[0].uValue = m_formerDraw ;
2024 TXNSetTXNObjectControls( m_txn , 1 , true , iControlTags , iControlData ) ;
2025 }
2026 #endif
2027 }
2028
2029
2030 // make correct activations
2031 void wxMacMLTEClassicControl::MacActivatePaneText(Boolean setActive)
2032 {
2033 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2034 if (m_txnIsActive != setActive && textctrl->MacIsReallyShown() )
2035 {
2036 m_txnIsActive = setActive;
2037 // TXNSetScrollBarState
2038
2039 TXNActivate(m_txn, m_txnFrameID, m_txnIsActive);
2040 if (m_txnIsFocused)
2041 TXNFocus( m_txn, m_txnIsActive);
2042 }
2043 }
2044
2045 // update TXN focus state
2046 void wxMacMLTEClassicControl::MacFocusPaneText(Boolean setFocus) {
2047 /* wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); */
2048
2049 if (m_txnIsFocused != setFocus /*&& textctrl->MacIsReallyShown() */ ) {
2050 m_txnIsFocused = setFocus;
2051 TXNFocus( m_txn, m_txnIsFocused);
2052 }
2053 }
2054
2055 // makes sure that the TXNObject is either offscreen or on screen
2056
2057 void wxMacMLTEClassicControl::MacSetObjectVisibility(Boolean vis)
2058 {
2059 #ifdef __WXMAC_OSX__
2060 OSStatus err = noErr ;
2061
2062 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2063 if ( textctrl )
2064 {
2065 UMAGetControlBoundsInWindowCoords( m_controlRef, &m_txnControlBounds);
2066 TXNControlTag iControlTags[1] = { kTXNVisibilityTag };
2067 TXNControlData iControlData[1] = { { vis } };
2068
2069 TXNSetTXNObjectControls( m_txn , 1 , true , iControlTags , iControlData ) ;
2070 }
2071 #endif
2072 }
2073
2074 // make sure that the TXNObject is at the right position
2075 void wxMacMLTEClassicControl::MacUpdatePosition()
2076 {
2077 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2078 if ( textctrl == NULL )
2079 return ;
2080
2081 Rect bounds ;
2082 UMAGetControlBoundsInWindowCoords(m_controlRef, &bounds);
2083
2084 if ( !EqualRect( &bounds , &m_txnControlBounds ) )
2085 {
2086 // old position
2087 Rect oldBounds = m_txnControlBounds ;
2088 m_txnControlBounds = bounds ;
2089 wxMacWindowClipper cl(textctrl) ;
2090 TXNSetFrameBounds( m_txn, m_txnControlBounds.top, m_txnControlBounds.left,
2091 m_txnControlBounds.bottom, m_txnControlBounds.right, m_txnFrameID);
2092 }
2093 }
2094
2095 void wxMacMLTEClassicControl::SetRect( Rect *r )
2096 {
2097 wxMacControl::SetRect( r ) ;
2098 MacUpdatePosition() ;
2099 }
2100
2101 // draw the control
2102 void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 thePart)
2103 {
2104 /* set up our globals */
2105
2106 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2107 if ( textctrl == NULL )
2108 return ;
2109
2110 if ( textctrl->MacIsReallyShown() )
2111 {
2112 wxMacWindowClipper clipper( textctrl ) ;
2113 TXNDraw( m_txn , NULL ) ;
2114 }
2115 }
2116
2117
2118 /* TPPaneHitTestProc is called when the control manager would
2119 like to determine what part of the control the mouse resides over.
2120 We also call this routine from our tracking proc to determine how
2121 to handle mouse clicks. */
2122 wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
2123 {
2124 Point where = { y , x } ;
2125 ControlPartCode result;
2126 /* set up our locals and lock down our globals*/
2127 result = 0;
2128 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2129 if ( textctrl == NULL )
2130 return 0 ;
2131
2132 if (textctrl->MacIsReallyShown() )
2133 {
2134 if (PtInRect(where, &m_txnControlBounds))
2135 result = kmUPTextPart;
2136 else
2137 {
2138 // sometimes we get the coords also in control local coordinates, therefore test again
2139 if ( textctrl->MacGetTopLevelWindow()->MacUsesCompositing() )
2140 {
2141 int x = 0 , y = 0 ;
2142 textctrl->MacClientToRootWindow( &x , &y ) ;
2143 where.h += x ;
2144 where.v += y ;
2145 }
2146 if (PtInRect(where, &m_txnControlBounds))
2147 result = kmUPTextPart;
2148 else
2149 result = 0;
2150 }
2151 }
2152 return result;
2153 }
2154
2155 /* TPPaneTrackingProc is called when the mouse is being held down
2156 over our control. This routine handles clicks in the text area
2157 and in the scroll bar. */
2158
2159 wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxInt16 y, void* actionProc )
2160 {
2161 Point startPt = { y ,x } ;
2162 ControlPartCode partCodeResult;
2163 /* make sure we have some variables... */
2164 partCodeResult = 0;
2165 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2166 if ( textctrl == NULL )
2167 return 0;
2168
2169 if (textctrl->MacIsReallyShown() )
2170 {
2171 /* we don't do any of these functions unless we're in focus */
2172 if ( ! m_txnIsFocused) {
2173 WindowPtr owner;
2174 owner = GetControlOwner(m_controlRef);
2175 ClearKeyboardFocus(owner);
2176 SetKeyboardFocus(owner, m_controlRef, kUserClickedToFocusPart);
2177 }
2178 /* find the location for the click */
2179 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
2180 if ( textctrl->MacGetTopLevelWindow()->MacUsesCompositing() )
2181 {
2182 int x = 0 , y = 0 ;
2183 textctrl->MacClientToRootWindow( &x , &y ) ;
2184 startPt.h += x ;
2185 startPt.v += y ;
2186 }
2187
2188 switch (MacControlUserPaneHitTestProc( startPt.h , startPt.v ))
2189 {
2190 /* handle clicks in the text part */
2191 case kmUPTextPart:
2192 {
2193 wxMacWindowClipper clipper( textctrl ) ;
2194
2195 EventRecord rec ;
2196 ConvertEventRefToEventRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
2197 TXNClick( m_txn, &rec );
2198
2199 }
2200 break;
2201
2202 }
2203 }
2204 return partCodeResult;
2205 }
2206
2207
2208 /* TPPaneIdleProc is our user pane idle routine. When our text field
2209 is active and in focus, we use this routine to set the cursor. */
2210 void wxMacMLTEClassicControl::MacControlUserPaneIdleProc()
2211 {
2212 /* set up locals */
2213 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2214 if ( textctrl == NULL )
2215 return ;
2216
2217 if (textctrl->MacIsReallyShown())
2218 {
2219 /* if we're not active, then we have nothing to say about the cursor */
2220 if (m_controlIsActive)
2221 {
2222 Rect bounds;
2223 Point mousep;
2224
2225 wxMacWindowClipper clipper( textctrl ) ;
2226 GetMouse(&mousep);
2227 /* there's a 'focus thing' and an 'unfocused thing' */
2228 if (m_txnIsFocused)
2229 {
2230 /* flash the cursor */
2231 SetPort(m_txnPort);
2232 TXNIdle(m_txn);
2233 /* set the cursor */
2234 if (PtInRect(mousep, &m_txnControlBounds))
2235 {
2236 RgnHandle theRgn;
2237 RectRgn((theRgn = NewRgn()), &m_txnControlBounds);
2238 TXNAdjustCursor(m_txn, theRgn);
2239 DisposeRgn(theRgn);
2240 }
2241 else
2242 {
2243 // SetThemeCursor(kThemeArrowCursor);
2244 }
2245 }
2246 else
2247 {
2248 /* if it's in our bounds, set the cursor */
2249 UMAGetControlBoundsInWindowCoords(m_controlRef, &bounds);
2250 if (PtInRect(mousep, &bounds))
2251 {
2252 // SetThemeCursor(kThemeArrowCursor);
2253 }
2254 }
2255 }
2256 }
2257 }
2258
2259
2260 /* TPPaneKeyDownProc is called whenever a keydown event is directed
2261 at our control. Here, we direct the keydown event to the text
2262 edit record and redraw the scroll bar and text field as appropriate. */
2263 wxInt16 wxMacMLTEClassicControl::MacControlUserPaneKeyDownProc (wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
2264 {
2265 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2266 if ( textctrl == NULL )
2267 return 0;
2268 // MacUpdatePosition() ;
2269
2270 if (m_txnIsFocused)
2271 {
2272 /* turn autoscrolling on and send the key event to text edit */
2273 wxMacWindowClipper clipper( textctrl ) ;
2274 EventRecord ev ;
2275 memset( &ev , 0 , sizeof( ev ) ) ;
2276 ev.what = keyDown ;
2277 ev.modifiers = modifiers ;
2278 ev.message = (( keyCode << 8 ) & keyCodeMask ) + ( charCode & charCodeMask ) ;
2279 TXNKeyDown( m_txn , &ev);
2280 }
2281 return kControlEntireControl;
2282 }
2283
2284
2285 /* TPPaneActivateProc is called when the window containing
2286 the user pane control receives activate events. Here, we redraw
2287 the control and it's text as necessary for the activation state. */
2288
2289 void wxMacMLTEClassicControl::MacControlUserPaneActivateProc( bool activating)
2290 {
2291 /* set up locals */
2292 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2293
2294 if ( textctrl == NULL )
2295 return ;
2296
2297 if ( m_controlIsActive != activating )
2298 {
2299 wxLogDebug(wxString::Format( wxT("id %xd activating with %d") , (long) this , activating ) ) ;
2300 // MacUpdatePosition() ;
2301 m_controlIsActive = activating;
2302 wxMacWindowClipper clipper( textctrl ) ;
2303 MacActivatePaneText( activating );
2304 }
2305
2306
2307 }
2308
2309
2310 /* TPPaneFocusProc is called when every the focus changes to or
2311 from our control. Herein, switch the focus appropriately
2312 according to the parameters and redraw the control as
2313 necessary. */
2314 wxInt16 wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action)
2315 {
2316 wxLogDebug(wxString::Format( wxT("id %xd Focus Proc with action %d") , (long) this , action ) ) ;
2317 ControlPartCode focusResult;
2318
2319 focusResult = kControlFocusNoPart;
2320 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
2321 if ( textctrl == NULL )
2322 return 0;
2323
2324 wxMacWindowClipper clipper( textctrl ) ;
2325
2326 // MacUpdatePosition() ;
2327
2328 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
2329 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
2330 and kControlFocusNextPart will be received. When the user clicks in our field
2331 and it is not the current focus, then the constant kUserClickedToFocusPart will
2332 be received. The constant kControlFocusNoPart will be received when our control
2333 is the current focus and the user clicks in another control. In your focus routine,
2334 you should respond to these codes as follows:
2335
2336 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
2337 the control and the focus rectangle as necessary.
2338
2339 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
2340 depending on its current state. redraw the control and the focus rectangle
2341 as appropriate for the new focus state. If the focus state is 'off', return the constant
2342 kControlFocusNoPart, otherwise return a non-zero part code.
2343 kUserClickedToFocusPart - is a constant defined for this example. You should
2344 define your own value for handling click-to-focus type events. */
2345 /* calculate the next highlight state */
2346 switch (action)
2347 {
2348 default:
2349 case kControlFocusNoPart:
2350 MacFocusPaneText( false);
2351 focusResult = kControlFocusNoPart;
2352 break;
2353 case kUserClickedToFocusPart:
2354 MacFocusPaneText(true);
2355 focusResult = 1;
2356 break;
2357 case kControlFocusPrevPart:
2358 case kControlFocusNextPart:
2359 MacFocusPaneText( ( ! m_txnIsFocused));
2360 focusResult = m_txnIsFocused ? 1 : kControlFocusNoPart;
2361 break;
2362 }
2363
2364 return focusResult;
2365 }
2366
2367 void wxMacMLTEClassicControl::MacControlUserPaneBackgroundProc( void *info )
2368 {
2369 }
2370
2371 wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxTextCtrl *wxPeer,
2372 const wxString& str,
2373 const wxPoint& pos,
2374 const wxSize& size, long style ) : wxMacMLTEControl( wxPeer )
2375 {
2376 m_font = wxPeer->GetFont() ;
2377 m_windowStyle = style ;
2378 Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
2379 wxString st = str ;
2380 wxMacConvertNewlines10To13( &st ) ;
2381
2382 short featurSet;
2383
2384 featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
2385 | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground
2386 | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
2387 /* create the control */
2388
2389 verify_noerr( ::CreateUserPaneControl( MAC_WXHWND(wxPeer->GetParent()->MacGetTopLevelWindowRef()), &bounds, featurSet, &m_controlRef ) );
2390
2391 DoCreate();
2392
2393 if ( wxPeer->MacIsReallyShown() )
2394 MacSetObjectVisibility( true ) ;
2395
2396 AdjustCreationAttributes( *wxWHITE , true ) ;
2397
2398 {
2399 wxMacWindowClipper clipper( m_peer ) ;
2400 SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ;
2401 TXNSetSelection( m_txn, 0, 0);
2402 TXNShowSelection( m_txn, kTXNShowStart);
2403 }
2404 }
2405
2406 wxMacMLTEClassicControl::~wxMacMLTEClassicControl()
2407 {
2408 // SetControlReference(m_controlRef , 0) ;
2409 TXNDeleteObject(m_txn);
2410 }
2411
2412 void wxMacMLTEClassicControl::VisibilityChanged(bool shown)
2413 {
2414 MacSetObjectVisibility( shown ) ;
2415 }
2416
2417 bool wxMacMLTEClassicControl::NeedsFocusRect() const
2418 {
2419 return true;
2420 }
2421
2422 #ifdef __WXMAC_OSX__
2423
2424 static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
2425 {
2426 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2427 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2428 if ( win )
2429 win->MacControlUserPaneDrawProc(part) ;
2430 }
2431
2432 static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
2433 {
2434 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2435 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2436 if ( win )
2437 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
2438 else
2439 return kControlNoPart ;
2440 }
2441
2442 static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
2443 {
2444 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2445 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2446 if ( win )
2447 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
2448 else
2449 return kControlNoPart ;
2450 }
2451
2452 static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
2453 {
2454 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2455 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2456 if ( win )
2457 win->MacControlUserPaneIdleProc() ;
2458 }
2459
2460 static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
2461 {
2462 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2463 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2464 if ( win )
2465 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
2466 else
2467 return kControlNoPart ;
2468 }
2469
2470 static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
2471 {
2472 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2473 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2474 if ( win )
2475 win->MacControlUserPaneActivateProc(activating) ;
2476 }
2477
2478 static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
2479 {
2480 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2481 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2482 if ( win )
2483 return win->MacControlUserPaneFocusProc(action) ;
2484 else
2485 return kControlNoPart ;
2486 }
2487
2488 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
2489 {
2490 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
2491 wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast<wxMacMLTEClassicControl*>(textCtrl->GetPeer()) : NULL ;
2492 if ( win )
2493 win->MacControlUserPaneBackgroundProc(info) ;
2494 }
2495 #endif
2496
2497 OSStatus wxMacMLTEClassicControl::DoCreate()
2498 {
2499 Rect bounds;
2500
2501 OSStatus err = noErr ;
2502
2503 /* set up our globals */
2504 #ifdef __WXMAC_OSX__
2505 if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(wxMacControlUserPaneDrawProc);
2506 if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(wxMacControlUserPaneHitTestProc);
2507 if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(wxMacControlUserPaneTrackingProc);
2508 if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(wxMacControlUserPaneIdleProc);
2509 if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(wxMacControlUserPaneKeyDownProc);
2510 if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(wxMacControlUserPaneActivateProc);
2511 if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(wxMacControlUserPaneFocusProc);
2512 #endif
2513
2514 /* set the initial settings for our private data */
2515
2516 m_txnIsFocused = false;
2517 m_controlIsActive = true;
2518 m_txnIsActive = false;
2519 m_txnIsVisible = true ;
2520
2521 WindowRef owningWindow = GetControlOwner(m_controlRef);
2522 m_txnPort = (GrafPtr) GetWindowPort(owningWindow);
2523
2524 #ifdef __WXMAC_OSX__
2525 /* set up the user pane procedures */
2526 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
2527 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
2528 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
2529 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
2530 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
2531 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
2532 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
2533 #endif
2534 /* calculate the rectangles used by the control */
2535 UMAGetControlBoundsInWindowCoords(m_controlRef, &bounds);
2536
2537 m_txnControlBounds = bounds ;
2538
2539 CGrafPtr origPort = NULL ;
2540 GDHandle origDev = NULL ;
2541 GetGWorld( &origPort , &origDev ) ;
2542 SetPort(m_txnPort);
2543
2544 /* create the new edit field */
2545
2546 TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( m_windowStyle ) ;
2547
2548 verify_noerr(TXNNewObject(NULL, owningWindow , &bounds,
2549 frameOptions ,
2550 kTXNTextEditStyleFrameType,
2551 kTXNTextensionFile,
2552 kTXNSystemDefaultEncoding,
2553 &m_txn, &m_txnFrameID, NULL ) );
2554
2555 /* perform final activations and setup for our text field. Here,
2556 we assume that the window is going to be the 'active' window. */
2557 // MacActivatePaneText(m_controlIsActive && m_txnIsFocused);
2558 /* all done */
2559 SetGWorld( origPort , origDev ) ;
2560 return err;
2561 }
2562
2563 // ----------------------------------------------------------------------------
2564 // MLTE control implementation (OSX part)
2565 // ----------------------------------------------------------------------------
2566
2567 #if TARGET_API_MAC_OSX
2568
2569 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
2570
2571 wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl *wxPeer,
2572 const wxString& str,
2573 const wxPoint& pos,
2574 const wxSize& size, long style ) : wxMacMLTEControl( wxPeer )
2575 {
2576 m_font = wxPeer->GetFont() ;
2577 m_windowStyle = style ;
2578 Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
2579 wxString st = str ;
2580 wxMacConvertNewlines10To13( &st ) ;
2581
2582 HIRect hr = { bounds.left , bounds.top , bounds.right - bounds.left , bounds.bottom- bounds.top } ;
2583
2584 m_scrollView = NULL ;
2585 TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( style ) ;
2586 if ( frameOptions & (kTXNWantVScrollBarMask|kTXNWantHScrollBarMask) )
2587 {
2588 HIScrollViewCreate(( frameOptions & kTXNWantHScrollBarMask ? kHIScrollViewOptionsHorizScroll : 0) |
2589 ( frameOptions & kTXNWantVScrollBarMask ? kHIScrollViewOptionsVertScroll: 0 ) , &m_scrollView ) ;
2590
2591 HIViewSetFrame( m_scrollView, &hr );
2592 HIViewSetVisible( m_scrollView, true );
2593 }
2594
2595 m_textView = NULL ;
2596 HITextViewCreate( NULL , 0, frameOptions , &m_textView ) ;
2597 m_txn = HITextViewGetTXNObject( m_textView) ;
2598 HIViewSetVisible( m_textView , true ) ;
2599 if ( m_scrollView )
2600 {
2601 HIViewAddSubview( m_scrollView , m_textView ) ;
2602 m_controlRef = m_scrollView ;
2603 wxPeer->MacInstallEventHandler( (WXWidget) m_textView ) ;
2604 }
2605 else
2606 {
2607 HIViewSetFrame( m_textView, &hr );
2608 m_controlRef = m_textView ;
2609 }
2610
2611 AdjustCreationAttributes( *wxWHITE , true ) ;
2612
2613 wxMacWindowClipper c( m_peer ) ;
2614 SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ;
2615
2616 TXNSetSelection( m_txn, 0, 0);
2617 TXNShowSelection( m_txn, kTXNShowStart);
2618
2619 }
2620
2621 OSStatus wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart )
2622 {
2623 return SetKeyboardFocus( GetControlOwner( m_textView ) ,
2624 m_textView , focusPart ) ;
2625 }
2626
2627 bool wxMacMLTEHIViewControl::HasFocus() const
2628 {
2629 ControlRef control ;
2630 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2631 return control == m_textView ;
2632 }
2633
2634 bool wxMacMLTEHIViewControl::NeedsFocusRect() const
2635 {
2636 return m_windowStyle & wxNO_BORDER ? false : true;
2637 }
2638
2639 #endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
2640
2641
2642 #endif
2643
2644 #endif // wxUSE_TEXTCTRL