1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/textctrl.cpp 
   4 // Author:      Stefan Csomor 
   5 // Modified by: Ryan Norton (MLTE GetLineLength and GetLineText) 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  16 #include "wx/textctrl.h" 
  23     #include "wx/button.h" 
  25     #include "wx/settings.h" 
  26     #include "wx/msgdlg.h" 
  27     #include "wx/toplevel.h" 
  31     #include <sys/types.h> 
  37 #if wxUSE_STD_IOSTREAM 
  45 #include "wx/filefn.h" 
  46 #include "wx/sysopt.h" 
  47 #include "wx/thread.h" 
  49 #include "wx/mac/uma.h" 
  50 #include "wx/mac/carbon/private/mactext.h" 
  56     virtual ~wxMacFunctor() {} 
  58     virtual void* operator()() = 0 ; 
  60     static void* CallBackProc( void *param 
) 
  62         wxMacFunctor
* f 
= (wxMacFunctor
*) param 
; 
  63         void *result 
= (*f
)() ; 
  68 template<typename classtype
, typename param1type
> 
  70 class wxMacObjectFunctor1 
: public wxMacFunctor
 
  72     typedef void (classtype::*function
)( param1type p1 
) ; 
  73     typedef void (classtype::*ref_function
)( const param1type
& p1 
) ; 
  75     wxMacObjectFunctor1( classtype 
*obj 
, function f 
, param1type p1 
) : 
  83     wxMacObjectFunctor1( classtype 
*obj 
, ref_function f 
, param1type p1 
) : 
  91     virtual ~wxMacObjectFunctor1() {} 
  93     virtual void* operator()() 
  95         (m_object
->*m_function
)( m_param1 
) ; 
 100     classtype
* m_object 
; 
 101     param1type m_param1 
; 
 104         function m_function 
; 
 105         ref_function m_refFunction 
; 
 109 template<typename classtype
, typename param1type
> 
 110 void* wxMacMPRemoteCall( classtype 
*object 
, void (classtype::*function
)( param1type p1 
) , param1type p1 
) 
 112     wxMacObjectFunctor1
<classtype
, param1type
> params(object
, function
, p1
) ; 
 114         MPRemoteCall( wxMacFunctor::CallBackProc 
, ¶ms 
, kMPOwningProcessRemoteContext 
) ; 
 118 template<typename classtype
, typename param1type
> 
 119 void* wxMacMPRemoteCall( classtype 
*object 
, void (classtype::*function
)( const param1type
& p1 
) , param1type p1 
) 
 121     wxMacObjectFunctor1
<classtype
,param1type
> params(object
, function
, p1
) ; 
 123         MPRemoteCall( wxMacFunctor::CallBackProc 
, ¶ms 
, kMPOwningProcessRemoteContext 
) ; 
 127 template<typename classtype
, typename param1type
> 
 128 void* wxMacMPRemoteGUICall( classtype 
*object 
, void (classtype::*function
)( param1type p1 
) , param1type p1 
) 
 131     void *result 
= wxMacMPRemoteCall( object 
, function 
, p1 
) ; 
 136 template<typename classtype
, typename param1type
> 
 137 void* wxMacMPRemoteGUICall( classtype 
*object 
, void (classtype::*function
)( const param1type
& p1 
) , param1type p1 
) 
 140     void *result 
= wxMacMPRemoteCall( object 
, function 
, p1 
) ; 
 145 class WXDLLEXPORT wxMacPortSaver
 
 147     DECLARE_NO_COPY_CLASS(wxMacPortSaver
) 
 150     wxMacPortSaver( GrafPtr port 
); 
 158  Clips to the visible region of a control within the current port 
 161 class WXDLLEXPORT wxMacWindowClipper 
: public wxMacPortSaver
 
 163     DECLARE_NO_COPY_CLASS(wxMacWindowClipper
) 
 166     wxMacWindowClipper( const wxWindow
* win 
); 
 167     ~wxMacWindowClipper(); 
 170     RgnHandle m_formerClip
; 
 174 wxMacPortSaver::wxMacPortSaver( GrafPtr port 
) 
 176     ::GetPort( &m_port 
); 
 180 wxMacPortSaver::~wxMacPortSaver() 
 185 wxMacWindowClipper::wxMacWindowClipper( const wxWindow
* win 
) : 
 186 wxMacPortSaver( (GrafPtr
) GetWindowPort( (WindowRef
) win
->MacGetTopLevelWindowRef() ) ) 
 188     m_newPort 
= (GrafPtr
) GetWindowPort( (WindowRef
) win
->MacGetTopLevelWindowRef() ) ; 
 189     m_formerClip 
= NewRgn() ; 
 190     m_newClip 
= NewRgn() ; 
 191     GetClip( m_formerClip 
) ; 
 195         // guard against half constructed objects, this just leads to a empty clip 
 196         if ( win
->GetPeer() ) 
 199             win
->MacWindowToRootWindow( &x
, &y 
) ; 
 201             // get area including focus rect 
 202             HIShapeGetAsQDRgn( ((wxWindow
*)win
)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip 
); 
 203             if ( !EmptyRgn( m_newClip 
) ) 
 204                 OffsetRgn( m_newClip 
, x 
, y 
) ; 
 207         SetClip( m_newClip 
) ; 
 211 wxMacWindowClipper::~wxMacWindowClipper() 
 213     SetPort( m_newPort 
) ; 
 214     SetClip( m_formerClip 
) ; 
 215     DisposeRgn( m_newClip 
) ; 
 216     DisposeRgn( m_formerClip 
) ; 
 219 // common parts for implementations based on MLTE 
 221 class wxMacMLTEControl 
: public wxMacTextControl
 
 224     wxMacMLTEControl( wxTextCtrl 
*peer 
) ; 
 226     virtual wxString 
GetStringValue() const ; 
 227     virtual void SetStringValue( const wxString 
&str 
) ; 
 229     static TXNFrameOptions 
FrameOptionsFromWXStyle( long wxStyle 
) ; 
 231     void AdjustCreationAttributes( const wxColour
& background
, bool visible 
) ; 
 233     virtual void SetFont( const wxFont 
& font
, const wxColour
& foreground
, long windowStyle 
) ; 
 234     virtual void SetBackgroundColour(const wxColour
& col 
); 
 235     virtual void SetStyle( long start
, long end
, const wxTextAttr
& style 
) ; 
 236     virtual void Copy() ; 
 238     virtual void Paste() ; 
 239     virtual bool CanPaste() const ; 
 240     virtual void SetEditable( bool editable 
) ; 
 241     virtual wxTextPos 
GetLastPosition() const ; 
 242     virtual void Replace( long from
, long to
, const wxString 
&str 
) ; 
 243     virtual void Remove( long from
, long to 
) ; 
 244     virtual void GetSelection( long* from
, long* to 
) const ; 
 245     virtual void SetSelection( long from
, long to 
) ; 
 247     virtual void WriteText( const wxString
& str 
) ; 
 249     virtual bool HasOwnContextMenu() const 
 251         TXNCommandEventSupportOptions options 
; 
 252         TXNGetCommandEventSupport( m_txn 
, & options 
) ; 
 253         return options 
& kTXNSupportEditCommandProcessing 
; 
 256     virtual void CheckSpelling(bool check
) 
 258         TXNSetSpellCheckAsYouType( m_txn
, (Boolean
) check 
); 
 260     virtual void Clear() ; 
 262     virtual bool CanUndo() const ; 
 263     virtual void Undo() ; 
 264     virtual bool CanRedo()  const; 
 265     virtual void Redo() ; 
 266     virtual int GetNumberOfLines() const ; 
 267     virtual long XYToPosition(long x
, long y
) const ; 
 268     virtual bool PositionToXY(long pos
, long *x
, long *y
) const ; 
 269     virtual void ShowPosition( long pos 
) ; 
 270     virtual int GetLineLength(long lineNo
) const ; 
 271     virtual wxString 
GetLineText(long lineNo
) const ; 
 273     void SetTXNData( const wxString
& st 
, TXNOffset start 
, TXNOffset end 
) ; 
 274     TXNObject 
GetTXNObject() { return m_txn 
; } 
 277     void TXNSetAttribute( const wxTextAttr
& style 
, long from 
, long to 
) ; 
 282 // implementation available under OSX 
 284 class wxMacMLTEHIViewControl 
: public wxMacMLTEControl
 
 287     wxMacMLTEHIViewControl( wxTextCtrl 
*wxPeer
, 
 290                              const wxSize
& size
, long style 
) ; 
 291     virtual ~wxMacMLTEHIViewControl() ; 
 293     virtual OSStatus 
SetFocus( ControlFocusPart focusPart 
) ; 
 294     virtual bool HasFocus() const ; 
 295     virtual void SetBackgroundColour(const wxColour
& col 
) ; 
 298     HIViewRef m_scrollView 
; 
 299     HIViewRef m_textView 
; 
 302 // 'classic' MLTE implementation 
 304 class wxMacMLTEClassicControl 
: public wxMacMLTEControl
 
 307     wxMacMLTEClassicControl( wxTextCtrl 
*wxPeer
, 
 310                              const wxSize
& size
, long style 
) ; 
 311     virtual ~wxMacMLTEClassicControl() ; 
 313     virtual void VisibilityChanged(bool shown
) ; 
 314     virtual void SuperChangedPosition() ; 
 316     virtual void            MacControlUserPaneDrawProc(wxInt16 part
) ; 
 317     virtual wxInt16         
MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
) ; 
 318     virtual wxInt16         
MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
) ; 
 319     virtual void            MacControlUserPaneIdleProc() ; 
 320     virtual wxInt16         
MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
) ; 
 321     virtual void            MacControlUserPaneActivateProc(bool activating
) ; 
 322     virtual wxInt16         
MacControlUserPaneFocusProc(wxInt16 action
) ; 
 323     virtual void            MacControlUserPaneBackgroundProc(void* info
) ; 
 325     virtual bool SetupCursor( const wxPoint
& WXUNUSED(pt
) ) 
 327         MacControlUserPaneIdleProc(); 
 331     virtual void            SetRect( Rect 
*r 
) ; 
 336     void                    MacUpdatePosition() ; 
 337     void                    MacActivatePaneText(bool setActive
) ; 
 338     void                    MacFocusPaneText(bool setFocus
) ; 
 339     void                    MacSetObjectVisibility(bool vis
) ; 
 342     TXNFrameID              m_txnFrameID 
; 
 344     WindowRef               m_txnWindow 
; 
 345     // bounds of the control as we last did set the txn frames 
 346     Rect                    m_txnControlBounds 
; 
 347     Rect                    m_txnVisBounds 
; 
 349     static pascal void TXNScrollActionProc( ControlRef controlRef 
, ControlPartCode partCode 
) ; 
 350     static pascal void TXNScrollInfoProc( 
 351         SInt32 iValue
, SInt32 iMaximumValue
, 
 352         TXNScrollBarOrientation iScrollBarOrientation
, SInt32 iRefCon 
) ; 
 354     ControlRef              m_sbHorizontal 
; 
 355     SInt32                  m_lastHorizontalValue 
; 
 356     ControlRef              m_sbVertical 
; 
 357     SInt32                  m_lastVerticalValue 
; 
 361 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxTextCtrlBase
) 
 363 BEGIN_EVENT_TABLE(wxTextCtrl
, wxTextCtrlBase
) 
 364     EVT_DROP_FILES(wxTextCtrl::OnDropFiles
) 
 365     EVT_CHAR(wxTextCtrl::OnChar
) 
 366     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
 367     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
 368     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
 369     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
 370     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
 371     EVT_MENU(wxID_CLEAR
, wxTextCtrl::OnDelete
) 
 372     EVT_MENU(wxID_SELECTALL
, wxTextCtrl::OnSelectAll
) 
 374     EVT_CONTEXT_MENU(wxTextCtrl::OnContextMenu
) 
 376     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
 377     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
 378     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
 379     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
 380     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
 381     EVT_UPDATE_UI(wxID_CLEAR
, wxTextCtrl::OnUpdateDelete
) 
 382     EVT_UPDATE_UI(wxID_SELECTALL
, wxTextCtrl::OnUpdateSelectAll
) 
 386 void wxTextCtrl::Init() 
 392     m_privateContextMenu 
= NULL
; 
 393     m_triggerOnSetValue 
= true ; 
 396 wxTextCtrl::~wxTextCtrl() 
 398     delete m_privateContextMenu
; 
 401 bool wxTextCtrl::Create( wxWindow 
*parent
, 
 407     const wxValidator
& validator
, 
 408     const wxString
& name 
) 
 410     m_macIsUserPane 
= false ; 
 413     if ( ! (style 
& wxNO_BORDER
) ) 
 414         style 
= (style 
& ~wxBORDER_MASK
) | wxSUNKEN_BORDER 
; 
 416     if ( !wxTextCtrlBase::Create( parent
, id
, pos
, size
, style 
& ~(wxHSCROLL 
| wxVSCROLL
), validator
, name 
) ) 
 419     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
 421         // always turn on this style for multi-line controls 
 422         m_windowStyle 
|= wxTE_PROCESS_ENTER
; 
 423         style 
|= wxTE_PROCESS_ENTER 
; 
 426     CreatePeer( str
, pos
, size
, style 
); 
 428     MacPostControlCreate(pos
, size
) ; 
 430     // only now the embedding is correct and we can do a positioning update 
 432     MacSuperChangedPosition() ; 
 434     if ( m_windowStyle 
& wxTE_READONLY
) 
 435         SetEditable( false ) ; 
 437     SetCursor( wxCursor( wxCURSOR_IBEAM 
) ) ; 
 442 void wxTextCtrl::CreatePeer( 
 445            const wxSize
& size
, long style 
) 
 447     bool forceMLTE 
= false ; 
 449 #if wxUSE_SYSTEM_OPTIONS 
 450     if (wxSystemOptions::HasOption( wxMAC_TEXTCONTROL_USE_MLTE 
) && (wxSystemOptions::GetOptionInt( wxMAC_TEXTCONTROL_USE_MLTE 
) == 1)) 
 456     if ( UMAGetSystemVersion() >= 0x1050 ) 
 461         if ( m_windowStyle 
& wxTE_MULTILINE 
|| ( UMAGetSystemVersion() >= 0x1050 ) ) 
 462             m_peer 
= new wxMacMLTEHIViewControl( this , str 
, pos 
, size 
, style 
) ; 
 467         if ( !(m_windowStyle 
& wxTE_MULTILINE
) && !forceMLTE 
) 
 469             m_peer 
= new wxMacUnicodeTextControl( this , str 
, pos 
, size 
, style 
) ; 
 473     // the horizontal single line scrolling bug that made us keep the classic implementation 
 475 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 
 477         m_peer 
= new wxMacMLTEClassicControl( this , str 
, pos 
, size 
, style 
) ; 
 481 void wxTextCtrl::MacSuperChangedPosition() 
 483     wxWindow::MacSuperChangedPosition() ; 
 484     GetPeer()->SuperChangedPosition() ; 
 487 void wxTextCtrl::MacVisibilityChanged() 
 489     GetPeer()->VisibilityChanged( GetPeer()->IsVisible() ); 
 492 void wxTextCtrl::MacCheckSpelling(bool check
) 
 494     GetPeer()->CheckSpelling(check
); 
 497 wxString 
wxTextCtrl::GetValue() const 
 499     return GetPeer()->GetStringValue() ; 
 502 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 504     GetPeer()->GetSelection( from 
, to 
) ; 
 507 void wxTextCtrl::DoSetValue(const wxString
& str
, int flags
) 
 510     if ( GetValue() == str 
) 
 513     GetPeer()->SetStringValue( str 
) ; 
 515     if ( (flags 
& SetValue_SendEvent
) && m_triggerOnSetValue 
) 
 517         SendTextUpdatedEvent(); 
 521 void wxTextCtrl::SetMaxLength(unsigned long len
) 
 526 bool wxTextCtrl::SetFont( const wxFont
& font 
) 
 528     if ( !wxTextCtrlBase::SetFont( font 
) ) 
 531     GetPeer()->SetFont( font 
, GetForegroundColour() , GetWindowStyle() ) ; 
 536 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
) 
 538     GetPeer()->SetStyle( start 
, end 
, style 
) ; 
 543 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
) 
 545     wxTextCtrlBase::SetDefaultStyle( style 
) ; 
 546     SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
 551 // Clipboard operations 
 553 void wxTextCtrl::Copy() 
 559 void wxTextCtrl::Cut() 
 565         wxCommandEvent 
event( wxEVT_COMMAND_TEXT_UPDATED
, m_windowId 
); 
 566         event
.SetEventObject( this ); 
 567         HandleWindowEvent( event 
); 
 571 void wxTextCtrl::Paste() 
 577         // TODO: eventually we should add setting the default style again 
 579         wxCommandEvent 
event( wxEVT_COMMAND_TEXT_UPDATED
, m_windowId 
); 
 580         event
.SetEventObject( this ); 
 581         HandleWindowEvent( event 
); 
 585 bool wxTextCtrl::CanCopy() const 
 587     // Can copy if there's a selection 
 589     GetSelection( &from
, &to 
); 
 594 bool wxTextCtrl::CanCut() const 
 599     // Can cut if there's a selection 
 601     GetSelection( &from
, &to 
); 
 606 bool wxTextCtrl::CanPaste() const 
 611     return GetPeer()->CanPaste() ; 
 614 void wxTextCtrl::SetEditable(bool editable
) 
 616     if ( editable 
!= m_editable 
) 
 618         m_editable 
= editable 
; 
 619         GetPeer()->SetEditable( editable 
) ; 
 623 void wxTextCtrl::SetInsertionPoint(long pos
) 
 625     SetSelection( pos 
, pos 
) ; 
 628 void wxTextCtrl::SetInsertionPointEnd() 
 630     wxTextPos pos 
= GetLastPosition(); 
 631     SetInsertionPoint( pos 
); 
 634 long wxTextCtrl::GetInsertionPoint() const 
 637     GetSelection( &begin 
, &end 
) ; 
 642 wxTextPos 
wxTextCtrl::GetLastPosition() const 
 644     return GetPeer()->GetLastPosition() ; 
 647 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
) 
 649     GetPeer()->Replace( from 
, to 
, str 
) ; 
 652 void wxTextCtrl::Remove(long from
, long to
) 
 654     GetPeer()->Remove( from 
, to 
) ; 
 657 void wxTextCtrl::SetSelection(long from
, long to
) 
 659     GetPeer()->SetSelection( from 
, to 
) ; 
 662 void wxTextCtrl::WriteText(const wxString
& str
) 
 664     // TODO: this MPRemoting will be moved into a remoting peer proxy for any command 
 665     if ( !wxIsMainThread() ) 
 667         // unfortunately CW 8 is not able to correctly deduce the template types, 
 668         // so we have to instantiate explicitly 
 669         wxMacMPRemoteGUICall
<wxTextCtrl
,wxString
>( this , &wxTextCtrl::WriteText 
, str 
) ; 
 674     GetPeer()->WriteText( str 
) ; 
 677 void wxTextCtrl::AppendText(const wxString
& text
) 
 679     SetInsertionPointEnd(); 
 683 void wxTextCtrl::Clear() 
 688 bool wxTextCtrl::IsModified() const 
 693 bool wxTextCtrl::IsEditable() const 
 695     return IsEnabled() && m_editable 
; 
 698 bool wxTextCtrl::AcceptsFocus() const 
 700     // we don't want focus if we can't be edited 
 701     return /*IsEditable() && */ wxControl::AcceptsFocus(); 
 704 wxSize 
wxTextCtrl::DoGetBestSize() const 
 708     // these are the numbers from the HIG: 
 709     // we reduce them by the borders first 
 712     switch ( m_windowVariant 
) 
 714         case wxWINDOW_VARIANT_NORMAL 
: 
 718         case wxWINDOW_VARIANT_SMALL 
: 
 722         case wxWINDOW_VARIANT_MINI 
: 
 731     // as the above numbers have some free space around the text 
 732     // we get 5 lines like this anyway 
 733     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
 736     if ( !HasFlag(wxNO_BORDER
) ) 
 739     return wxSize(wText
, hText
); 
 742 // ---------------------------------------------------------------------------- 
 744 // ---------------------------------------------------------------------------- 
 746 void wxTextCtrl::Undo() 
 752 void wxTextCtrl::Redo() 
 758 bool wxTextCtrl::CanUndo() const 
 763     return GetPeer()->CanUndo() ; 
 766 bool wxTextCtrl::CanRedo() const 
 771     return GetPeer()->CanRedo() ; 
 774 void wxTextCtrl::MarkDirty() 
 779 void wxTextCtrl::DiscardEdits() 
 784 int wxTextCtrl::GetNumberOfLines() const 
 786     return GetPeer()->GetNumberOfLines() ; 
 789 long wxTextCtrl::XYToPosition(long x
, long y
) const 
 791     return GetPeer()->XYToPosition( x 
, y 
) ; 
 794 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const 
 796     return GetPeer()->PositionToXY( pos 
, x 
, y 
) ; 
 799 void wxTextCtrl::ShowPosition(long pos
) 
 801     return GetPeer()->ShowPosition(pos
) ; 
 804 int wxTextCtrl::GetLineLength(long lineNo
) const 
 806     return GetPeer()->GetLineLength(lineNo
) ; 
 809 wxString 
wxTextCtrl::GetLineText(long lineNo
) const 
 811     return GetPeer()->GetLineText(lineNo
) ; 
 814 void wxTextCtrl::Command(wxCommandEvent 
& event
) 
 816     SetValue(event
.GetString()); 
 817     ProcessCommand(event
); 
 820 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
) 
 822     // By default, load the first file into the text window. 
 823     if (event
.GetNumberOfFiles() > 0) 
 824         LoadFile( event
.GetFiles()[0] ); 
 827 void wxTextCtrl::OnChar(wxKeyEvent
& event
) 
 829     int key 
= event
.GetKeyCode() ; 
 830     bool eat_key 
= false ; 
 832     if ( key 
== 'a' && event
.MetaDown() ) 
 839     if ( key 
== 'c' && event
.MetaDown() ) 
 847     if ( !IsEditable() && key 
!= WXK_LEFT 
&& key 
!= WXK_RIGHT 
&& key 
!= WXK_DOWN 
&& key 
!= WXK_UP 
&& key 
!= WXK_TAB 
&& 
 848         !( key 
== WXK_RETURN 
&& ( (m_windowStyle 
& wxTE_PROCESS_ENTER
) || (m_windowStyle 
& wxTE_MULTILINE
) ) ) 
 849 //        && key != WXK_PAGEUP && key != WXK_PAGEDOWN && key != WXK_HOME && key != WXK_END 
 856     // Check if we have reached the max # of chars (if it is set), but still 
 857     // allow navigation and deletion 
 858     if ( !IsMultiLine() && m_maxLength 
&& GetValue().length() >= m_maxLength 
&& 
 859         key 
!= WXK_LEFT 
&& key 
!= WXK_RIGHT 
&& key 
!= WXK_TAB 
&& 
 860         key 
!= WXK_BACK 
&& !( key 
== WXK_RETURN 
&& (m_windowStyle 
& wxTE_PROCESS_ENTER
) ) 
 863         // eat it, we don't want to add more than allowed # of characters 
 865         // TODO: generate EVT_TEXT_MAXLEN() 
 869     // assume that any key not processed yet is going to modify the control 
 872     if ( key 
== 'v' && event
.MetaDown() ) 
 880     if ( key 
== 'x' && event
.MetaDown() ) 
 891             if (m_windowStyle 
& wxTE_PROCESS_ENTER
) 
 893                 wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
 894                 event
.SetEventObject( this ); 
 895                 event
.SetString( GetValue() ); 
 896                 if ( HandleWindowEvent(event
) ) 
 900             if ( !(m_windowStyle 
& wxTE_MULTILINE
) ) 
 902                 wxTopLevelWindow 
*tlw 
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
); 
 903                 if ( tlw 
&& tlw
->GetDefaultItem() ) 
 905                     wxButton 
*def 
= wxDynamicCast(tlw
->GetDefaultItem(), wxButton
); 
 906                     if ( def 
&& def
->IsEnabled() ) 
 908                         wxCommandEvent 
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() ); 
 909                         event
.SetEventObject(def
); 
 916                 // this will make wxWidgets eat the ENTER key so that 
 917                 // we actually prevent line wrapping in a single line text control 
 923             if ( !(m_windowStyle 
& wxTE_PROCESS_TAB
)) 
 926                 if (!event
.ShiftDown()) 
 927                     flags 
|= wxNavigationKeyEvent::IsForward 
; 
 928                 if (event
.ControlDown()) 
 929                     flags 
|= wxNavigationKeyEvent::WinChange 
; 
 936                 // This is necessary (don't know why); 
 937                 // otherwise the tab will not be inserted. 
 938                 WriteText(wxT("\t")); 
 949         // perform keystroke handling 
 953     if ( ( key 
>= 0x20 && key 
< WXK_START 
) || 
 954          ( key 
>= WXK_NUMPAD0 
&& key 
<= WXK_DIVIDE 
) || 
 959         wxCommandEvent 
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
 960         event1
.SetEventObject( this ); 
 961         wxPostEvent( GetEventHandler(), event1 
); 
 965 // ---------------------------------------------------------------------------- 
 966 // standard handlers for standard edit menu events 
 967 // ---------------------------------------------------------------------------- 
 969 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
 974 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
 979 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
 984 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 989 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 994 void wxTextCtrl::OnDelete(wxCommandEvent
& WXUNUSED(event
)) 
 998     GetSelection( &from
, &to 
); 
 999     if (from 
!= -1 && to 
!= -1) 
1003 void wxTextCtrl::OnSelectAll(wxCommandEvent
& WXUNUSED(event
)) 
1005     SetSelection(-1, -1); 
1008 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
1010     event
.Enable( CanCut() ); 
1013 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
1015     event
.Enable( CanCopy() ); 
1018 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
1020     event
.Enable( CanPaste() ); 
1023 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
1025     event
.Enable( CanUndo() ); 
1028 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
1030     event
.Enable( CanRedo() ); 
1033 void wxTextCtrl::OnUpdateDelete(wxUpdateUIEvent
& event
) 
1037     GetSelection( &from
, &to 
); 
1038     event
.Enable( from 
!= -1 && to 
!= -1 && from 
!= to 
&& IsEditable() ) ; 
1041 void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent
& event
) 
1043     event
.Enable(GetLastPosition() > 0); 
1046 // CS: Context Menus only work with MLTE implementations or non-multiline HIViews at the moment 
1048 void wxTextCtrl::OnContextMenu(wxContextMenuEvent
& event
) 
1050     if ( GetPeer()->HasOwnContextMenu() ) 
1056     if (m_privateContextMenu 
== NULL
) 
1058         m_privateContextMenu 
= new wxMenu
; 
1059         m_privateContextMenu
->Append(wxID_UNDO
, _("&Undo")); 
1060         m_privateContextMenu
->Append(wxID_REDO
, _("&Redo")); 
1061         m_privateContextMenu
->AppendSeparator(); 
1062         m_privateContextMenu
->Append(wxID_CUT
, _("Cu&t")); 
1063         m_privateContextMenu
->Append(wxID_COPY
, _("&Copy")); 
1064         m_privateContextMenu
->Append(wxID_PASTE
, _("&Paste")); 
1065         m_privateContextMenu
->Append(wxID_CLEAR
, _("&Delete")); 
1066         m_privateContextMenu
->AppendSeparator(); 
1067         m_privateContextMenu
->Append(wxID_SELECTALL
, _("Select &All")); 
1070     if (m_privateContextMenu 
!= NULL
) 
1071         PopupMenu(m_privateContextMenu
); 
1074 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt 
) 
1076     if ( !GetPeer()->SetupCursor( pt 
) ) 
1077         return wxWindow::MacSetupCursor( pt 
) ; 
1082 // ---------------------------------------------------------------------------- 
1083 // implementation base class 
1084 // ---------------------------------------------------------------------------- 
1086 wxMacTextControl::wxMacTextControl(wxTextCtrl
* peer
) : 
1087     wxMacControl( peer 
) 
1091 wxMacTextControl::~wxMacTextControl() 
1095 void wxMacTextControl::SetStyle(long WXUNUSED(start
), 
1097                                 const wxTextAttr
& WXUNUSED(style
)) 
1101 void wxMacTextControl::Copy() 
1105 void wxMacTextControl::Cut() 
1109 void wxMacTextControl::Paste() 
1113 bool wxMacTextControl::CanPaste() const 
1118 void wxMacTextControl::SetEditable(bool WXUNUSED(editable
)) 
1122 wxTextPos 
wxMacTextControl::GetLastPosition() const 
1124     return GetStringValue().length() ; 
1127 void wxMacTextControl::Replace( long from 
, long to 
, const wxString 
&val 
) 
1129     SetSelection( from 
, to 
) ; 
1133 void wxMacTextControl::Remove( long from 
, long to 
) 
1135     SetSelection( from 
, to 
) ; 
1136     WriteText( wxEmptyString
) ; 
1139 void wxMacTextControl::Clear() 
1141     SetStringValue( wxEmptyString 
) ; 
1144 bool wxMacTextControl::CanUndo() const 
1149 void wxMacTextControl::Undo() 
1153 bool wxMacTextControl::CanRedo()  const 
1158 void wxMacTextControl::Redo() 
1162 long wxMacTextControl::XYToPosition(long WXUNUSED(x
), long WXUNUSED(y
)) const 
1167 bool wxMacTextControl::PositionToXY(long WXUNUSED(pos
), 
1169                                     long *WXUNUSED(y
)) const 
1174 void wxMacTextControl::ShowPosition( long WXUNUSED(pos
) ) 
1178 int wxMacTextControl::GetNumberOfLines() const 
1180     ItemCount lines 
= 0 ; 
1181     wxString content 
= GetStringValue() ; 
1184     for (size_t i 
= 0; i 
< content
.length() ; i
++) 
1186         if (content
[i
] == '\r') 
1193 wxString 
wxMacTextControl::GetLineText(long lineNo
) const 
1195     // TODO: change this if possible to reflect real lines 
1196     wxString content 
= GetStringValue() ; 
1200     for (size_t i 
= 0; i 
< content
.length() ; i
++) 
1202         if (count 
== lineNo
) 
1204             // Add chars in line then 
1207             for (size_t j 
= i
; j 
< content
.length(); j
++) 
1209                 if (content
[j
] == '\n') 
1218         if (content
[i
] == '\n') 
1222     return wxEmptyString 
; 
1225 int wxMacTextControl::GetLineLength(long lineNo
) const 
1227     // TODO: change this if possible to reflect real lines 
1228     wxString content 
= GetStringValue() ; 
1232     for (size_t i 
= 0; i 
< content
.length() ; i
++) 
1234         if (count 
== lineNo
) 
1236             // Count chars in line then 
1238             for (size_t j 
= i
; j 
< content
.length(); j
++) 
1241                 if (content
[j
] == '\n') 
1248         if (content
[i
] == '\n') 
1255 // ---------------------------------------------------------------------------- 
1256 // standard unicode control implementation 
1257 // ---------------------------------------------------------------------------- 
1259 // the current unicode textcontrol implementation has a bug : only if the control 
1260 // is currently having the focus, the selection can be retrieved by the corresponding 
1261 // data tag. So we have a mirroring using a member variable 
1262 // TODO : build event table using virtual member functions for wxMacControl 
1264 static const EventTypeSpec unicodeTextControlEventList
[] = 
1266     { kEventClassControl 
, kEventControlSetFocusPart 
} , 
1269 static pascal OSStatus 
wxMacUnicodeTextControlControlEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
1271     OSStatus result 
= eventNotHandledErr 
; 
1272     wxMacUnicodeTextControl
* focus 
= (wxMacUnicodeTextControl
*) data 
; 
1273     wxMacCarbonEvent 
cEvent( event 
) ; 
1275     switch ( GetEventKind( event 
) ) 
1277         case kEventControlSetFocusPart 
: 
1279             ControlPartCode controlPart 
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart 
, typeControlPartCode 
); 
1280             if ( controlPart 
== kControlFocusNoPart 
) 
1282                 // about to loose focus -> store selection to field 
1283                 focus
->GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &focus
->m_selection 
); 
1285             result 
= CallNextEventHandler(handler
,event
) ; 
1286             if ( controlPart 
!= kControlFocusNoPart 
) 
1288                 // about to gain focus -> set selection from field 
1289                 focus
->SetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &focus
->m_selection 
); 
1300 static pascal OSStatus 
wxMacUnicodeTextControlEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
1302     OSStatus result 
= eventNotHandledErr 
; 
1304     switch ( GetEventClass( event 
) ) 
1306         case kEventClassControl 
: 
1307             result 
= wxMacUnicodeTextControlControlEventHandler( handler 
, event 
, data 
) ; 
1316 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacUnicodeTextControlEventHandler 
) 
1318 wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl 
*wxPeer 
) : wxMacTextControl( wxPeer 
) 
1322 wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl 
*wxPeer
, 
1323     const wxString
& str
, 
1325     const wxSize
& size
, long style 
) 
1326     : wxMacTextControl( wxPeer 
) 
1328     Create( wxPeer
, str
, pos
, size
, style 
); 
1331 bool wxMacUnicodeTextControl::Create( wxTextCtrl 
*wxPeer
, 
1332     const wxString
& str
, 
1334     const wxSize
& size
, long style 
) 
1336     m_font 
= wxPeer
->GetFont() ; 
1337     m_windowStyle 
= style 
; 
1338     m_selection
.selStart 
= m_selection
.selEnd 
= 0; 
1339     Rect bounds 
= wxMacGetBoundsForControl( wxPeer 
, pos 
, size 
) ; 
1341     wxMacConvertNewlines10To13( &st 
) ; 
1342     wxCFStringRef 
cf(st 
, m_font
.GetEncoding()) ; 
1343     CFStringRef cfr 
= cf 
; 
1345     m_valueTag 
= kControlEditTextCFStringTag 
; 
1346     CreateControl( wxPeer
, &bounds
, cfr 
); 
1348     if ( !(m_windowStyle 
& wxTE_MULTILINE
) ) 
1349         SetData
<Boolean
>( kControlEditTextPart 
, kControlEditTextSingleLineTag 
, true ) ; 
1351     InstallControlEventHandler( m_controlRef 
, GetwxMacUnicodeTextControlEventHandlerUPP(), 
1352                                 GetEventTypeCount(unicodeTextControlEventList
), unicodeTextControlEventList
, this, 
1358 wxMacUnicodeTextControl::~wxMacUnicodeTextControl() 
1362 void wxMacUnicodeTextControl::VisibilityChanged(bool shown
) 
1364     if ( !(m_windowStyle 
& wxTE_MULTILINE
) && shown 
) 
1366         // work around a refresh issue insofar as not always the entire content is shown, 
1367         // even if this would be possible 
1368         ControlEditTextSelectionRec sel 
; 
1369         CFStringRef value 
= NULL 
; 
1371         verify_noerr( GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel 
) ); 
1372         verify_noerr( GetData
<CFStringRef
>( 0, m_valueTag
, &value 
) ); 
1373         verify_noerr( SetData
<CFStringRef
>( 0, m_valueTag
, &value 
) ); 
1374         verify_noerr( SetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel 
) ); 
1376         CFRelease( value 
) ; 
1380 wxString 
wxMacUnicodeTextControl::GetStringValue() const 
1383     CFStringRef value 
= GetData
<CFStringRef
>(0, m_valueTag
) ; 
1386         wxCFStringRef 
cf(value
) ; 
1387         result 
= cf
.AsString() ; 
1391     wxMacConvertNewlines13To10( &result 
) ; 
1393     wxMacConvertNewlines10To13( &result 
) ; 
1399 void wxMacUnicodeTextControl::SetStringValue( const wxString 
&str 
) 
1402     wxMacConvertNewlines10To13( &st 
) ; 
1403     wxCFStringRef 
cf( st 
, m_font
.GetEncoding() ) ; 
1404     verify_noerr( SetData
<CFStringRef
>( 0, m_valueTag 
, cf 
) ) ; 
1407 void wxMacUnicodeTextControl::CreateControl( wxTextCtrl
* peer
, const Rect
* bounds
, CFStringRef cfr 
) 
1409     Boolean isPassword 
= ( m_windowStyle 
& wxTE_PASSWORD 
) != 0 ; 
1412         m_valueTag 
= kControlEditTextPasswordCFStringTag 
; 
1414     OSStatus err 
= CreateEditUnicodeTextControl( 
1415         MAC_WXHWND(peer
->MacGetTopLevelWindowRef()), bounds 
, cfr 
, 
1416         isPassword 
, NULL 
, &m_controlRef 
) ; 
1417     verify_noerr( err 
); 
1420 void wxMacUnicodeTextControl::Copy() 
1422     SendHICommand( kHICommandCopy 
) ; 
1425 void wxMacUnicodeTextControl::Cut() 
1427     SendHICommand( kHICommandCut 
) ; 
1430 void wxMacUnicodeTextControl::Paste() 
1432     SendHICommand( kHICommandPaste 
) ; 
1435 bool wxMacUnicodeTextControl::CanPaste() const 
1440 void wxMacUnicodeTextControl::SetEditable(bool WXUNUSED(editable
)) 
1442 #if 0 // leads to problem because text cannot be selected anymore 
1443     SetData
<Boolean
>( kControlEditTextPart 
, kControlEditTextLockedTag 
, (Boolean
) !editable 
) ; 
1447 void wxMacUnicodeTextControl::GetSelection( long* from
, long* to 
) const 
1449     ControlEditTextSelectionRec sel 
; 
1451         verify_noerr( GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel 
) ) ; 
1456         *from 
= sel
.selStart 
; 
1461 void wxMacUnicodeTextControl::SetSelection( long from 
, long to 
) 
1463     ControlEditTextSelectionRec sel 
; 
1465     int textLength 
= 0 ; 
1466     CFStringRef value 
= GetData
<CFStringRef
>(0, m_valueTag
) ; 
1469         wxCFStringRef 
cf(value
) ; 
1470         textLength 
= cf
.AsString().length() ; 
1473     if ((from 
== -1) && (to 
== -1)) 
1480         from 
= wxMin(textLength
,wxMax(from
,0)) ; 
1484             to 
= wxMax(0,wxMin(textLength
,to
)) ; 
1487     sel
.selStart 
= from 
; 
1490         SetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel 
) ; 
1495 void wxMacUnicodeTextControl::WriteText( const wxString
& str 
) 
1498     wxMacConvertNewlines10To13( &st 
) ; 
1502         wxCFStringRef 
cf(st 
, m_font
.GetEncoding() ) ; 
1503         CFStringRef value 
= cf 
; 
1504         SetData
<CFStringRef
>( 0, kControlEditTextInsertCFStringRefTag
, &value 
); 
1508         wxString val 
= GetStringValue() ; 
1510         GetSelection( &start 
, &end 
) ; 
1511         val
.Remove( start 
, end 
- start 
) ; 
1512         val
.insert( start 
, str 
) ; 
1513         SetStringValue( val 
) ; 
1514         SetSelection( start 
+ str
.length() , start 
+ str
.length() ) ; 
1518 // ---------------------------------------------------------------------------- 
1519 // MLTE control implementation (common part) 
1520 // ---------------------------------------------------------------------------- 
1522 // if MTLE is read only, no changes at all are allowed, not even from 
1523 // procedural API, in order to allow changes via API all the same we must undo 
1524 // the readonly status while we are executing, this class helps to do so 
1526 class wxMacEditHelper
 
1529     wxMacEditHelper( TXNObject txn 
) 
1531         TXNControlTag tag
[] = { kTXNIOPrivilegesTag 
} ; 
1533         TXNGetTXNObjectControls( m_txn 
, 1 , tag 
, m_data 
) ; 
1534         if ( m_data
[0].uValue 
== kTXNReadOnly 
) 
1536             TXNControlData data
[] = { { kTXNReadWrite 
} } ; 
1537             TXNSetTXNObjectControls( m_txn 
, false , 1 , tag 
, data 
) ; 
1543         TXNControlTag tag
[] = { kTXNIOPrivilegesTag 
} ; 
1544         if ( m_data
[0].uValue 
== kTXNReadOnly 
) 
1545             TXNSetTXNObjectControls( m_txn 
, false , 1 , tag 
, m_data 
) ; 
1550     TXNControlData m_data
[1] ; 
1553 wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl 
*peer 
) 
1554     : wxMacTextControl( peer 
) 
1556     SetNeedsFocusRect( true ) ; 
1559 wxString 
wxMacMLTEControl::GetStringValue() const 
1563     Size actualSize 
= 0; 
1568         err 
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData 
); 
1577             actualSize 
= GetHandleSize( theText 
) / sizeof(UniChar
) ; 
1578             if ( actualSize 
> 0 ) 
1580                 wxChar 
*ptr 
= NULL 
; 
1582 #if SIZEOF_WCHAR_T == 2 
1583                 ptr 
= new wxChar
[actualSize 
+ 1] ; 
1584                 wxStrncpy( ptr 
, (wxChar
*)(*theText
) , actualSize 
) ; 
1586                 SetHandleSize( theText
, (actualSize 
+ 1) * sizeof(UniChar
) ) ; 
1588                 (((UniChar
*)*theText
)[actualSize
]) = 0 ; 
1589                 wxMBConvUTF16 converter 
; 
1590                 size_t noChars 
= converter
.MB2WC( NULL 
, (const char*)*theText 
, 0 ) ; 
1591                 wxASSERT_MSG( noChars 
!= wxCONV_FAILED
, _T("Unable to count the number of characters in this string!") ); 
1592                 ptr 
= new wxChar
[noChars 
+ 1] ; 
1594                 noChars 
= converter
.MB2WC( ptr 
, (const char*)*theText 
, noChars 
+ 1 ) ; 
1595                 wxASSERT_MSG( noChars 
!= wxCONV_FAILED
, _T("Conversion of string failed!") ); 
1597                 HUnlock( theText 
) ; 
1600                 ptr
[actualSize
] = 0 ; 
1601                 result 
= wxString( ptr 
) ; 
1605             DisposeHandle( theText 
) ; 
1609         err 
= TXNGetDataEncoded( m_txn 
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData 
); 
1618             actualSize 
= GetHandleSize( theText 
) ; 
1619             if ( actualSize 
> 0 ) 
1622                 result 
= wxString( *theText 
, wxConvLocal 
, actualSize 
) ; 
1623                 HUnlock( theText 
) ; 
1626             DisposeHandle( theText 
) ; 
1632     wxMacConvertNewlines13To10( &result 
) ; 
1634     wxMacConvertNewlines10To13( &result 
) ; 
1640 void wxMacMLTEControl::SetStringValue( const wxString 
&str 
) 
1643     wxMacConvertNewlines10To13( &st 
); 
1647         wxMacWindowClipper 
c( m_peer 
) ; 
1651             wxMacEditHelper 
help( m_txn 
); 
1652             SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset 
); 
1655         TXNSetSelection( m_txn
, 0, 0 ); 
1656         TXNShowSelection( m_txn
, kTXNShowStart 
); 
1660 TXNFrameOptions 
wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle 
) 
1662     TXNFrameOptions frameOptions 
= kTXNDontDrawCaretWhenInactiveMask
; 
1664     frameOptions 
|= kTXNDoFontSubstitutionMask
; 
1666     if ( ! (wxStyle 
& wxTE_NOHIDESEL
) ) 
1667         frameOptions 
|= kTXNDontDrawSelectionWhenInactiveMask 
; 
1669     if ( wxStyle 
& (wxHSCROLL 
| wxTE_DONTWRAP
) ) 
1670         frameOptions 
|= kTXNWantHScrollBarMask 
; 
1672     if ( wxStyle 
& wxTE_MULTILINE 
) 
1674         if ( ! (wxStyle 
& wxTE_DONTWRAP 
) ) 
1675             frameOptions 
|= kTXNAlwaysWrapAtViewEdgeMask 
; 
1677         if ( !(wxStyle 
& wxTE_NO_VSCROLL
) ) 
1679             frameOptions 
|= kTXNWantVScrollBarMask 
; 
1681             // The following code causes drawing problems on 10.4. Perhaps it can be restored for 
1682             // older versions of the OS, but I'm not sure it's appropriate to put a grow icon here 
1683             // anyways, as AFAIK users can't actually use it to resize the text ctrl. 
1684 //            if ( frameOptions & kTXNWantHScrollBarMask ) 
1685 //                frameOptions |= kTXNDrawGrowIconMask ; 
1690         frameOptions 
|= kTXNSingleLineOnlyMask 
; 
1693     return frameOptions 
; 
1696 void wxMacMLTEControl::AdjustCreationAttributes(const wxColour 
&background
, 
1697                                                 bool WXUNUSED(visible
)) 
1699     TXNControlTag iControlTags
[] = 
1701             kTXNDoFontSubstitution
, 
1702             kTXNWordWrapStateTag 
, 
1704     TXNControlData iControlData
[] = 
1710     int toptag 
= WXSIZEOF( iControlTags 
) ; 
1712     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
1714         iControlData
[1].uValue 
= 
1715             (m_windowStyle 
& wxTE_DONTWRAP
) 
1720     OSStatus err 
= TXNSetTXNObjectControls( m_txn
, false, toptag
, iControlTags
, iControlData 
) ; 
1721     verify_noerr( err 
); 
1723     // setting the default font: 
1724     // under 10.2 this causes a visible caret, therefore we avoid it 
1730     GetThemeFont( kThemeSystemFont 
, GetApplicationScript() , fontName 
, &fontSize 
, &fontStyle 
) ; 
1732     TXNTypeAttributes typeAttr
[] = 
1734         { kTXNQDFontNameAttribute 
, kTXNQDFontNameAttributeSize 
, { (void*) fontName 
} } , 
1735         { kTXNQDFontSizeAttribute 
, kTXNFontSizeAttributeSize 
, { (void*) (fontSize 
<< 16) } } , 
1736         { kTXNQDFontStyleAttribute 
, kTXNQDFontStyleAttributeSize 
, { (void*) normal 
} } , 
1739     err 
= TXNSetTypeAttributes( 
1740         m_txn
, sizeof(typeAttr
) / sizeof(TXNTypeAttributes
), 
1741         typeAttr
, kTXNStartOffset
, kTXNEndOffset 
); 
1742     verify_noerr( err 
); 
1744     if ( m_windowStyle 
& wxTE_PASSWORD 
) 
1746         UniChar c 
= 0x00A5 ; 
1747         err 
= TXNEchoMode( m_txn 
, c 
, 0 , true ); 
1748         verify_noerr( err 
); 
1751     TXNBackground tback
; 
1752     tback
.bgType 
= kTXNBackgroundTypeRGB
; 
1753     background
.GetRGBColor( &tback
.bg
.color 
); 
1754     TXNSetBackground( m_txn 
, &tback 
); 
1757     TXNCommandEventSupportOptions options 
; 
1758     if ( TXNGetCommandEventSupport( m_txn
, &options 
) == noErr 
) 
1761             kTXNSupportEditCommandProcessing
 
1762             | kTXNSupportEditCommandUpdating
 
1763             | kTXNSupportFontCommandProcessing
 
1764             | kTXNSupportFontCommandUpdating
; 
1766         // only spell check when not read-only  
1767         // use system options for the default 
1768         bool checkSpelling 
= false ;  
1769         if ( !(m_windowStyle 
& wxTE_READONLY
) ) 
1771 #if wxUSE_SYSTEM_OPTIONS 
1772             if ( wxSystemOptions::HasOption( wxMAC_TEXTCONTROL_USE_SPELL_CHECKER 
) && (wxSystemOptions::GetOptionInt( wxMAC_TEXTCONTROL_USE_SPELL_CHECKER 
) == 1) ) 
1774                 checkSpelling 
= true ; 
1779         if ( checkSpelling 
) 
1781                 kTXNSupportSpellCheckCommandProcessing
 
1782                 | kTXNSupportSpellCheckCommandUpdating
;               
1784         TXNSetCommandEventSupport( m_txn 
, options 
) ; 
1788 void wxMacMLTEControl::SetBackgroundColour(const wxColour
& col 
) 
1790     TXNBackground tback
; 
1791     tback
.bgType 
= kTXNBackgroundTypeRGB
; 
1792     col
.GetRGBColor(&tback
.bg
.color
); 
1793     TXNSetBackground( m_txn 
, &tback 
); 
1796 static inline int wxConvertToTXN(int x
) 
1798     return wx_static_cast(int, x 
/ 254.0 * 72 + 0.5); 
1801 void wxMacMLTEControl::TXNSetAttribute( const wxTextAttr
& style 
, long from 
, long to 
) 
1803     TXNTypeAttributes typeAttr
[4] ; 
1805     size_t typeAttrCount 
= 0 ; 
1808     TXNControlTag    controlTags
[4]; 
1809     TXNControlData   controlData
[4]; 
1810     size_t controlAttrCount 
= 0; 
1812     TXNTab
* tabs 
= NULL
; 
1814     bool relayout 
= false; 
1817     if ( style
.HasFont() ) 
1819         wxASSERT( typeAttrCount 
< WXSIZEOF(typeAttr
) ); 
1820         font 
= style
.GetFont() ; 
1821         typeAttr
[typeAttrCount
].tag 
= kTXNATSUIStyle 
; 
1822         typeAttr
[typeAttrCount
].size 
= kTXNATSUIStyleSize 
; 
1823         typeAttr
[typeAttrCount
].data
.dataPtr 
= font
.MacGetATSUStyle() ; 
1827     if ( style
.HasTextColour() ) 
1829         wxASSERT( typeAttrCount 
< WXSIZEOF(typeAttr
) ); 
1830         style
.GetTextColour().GetRGBColor( &color 
); 
1831         typeAttr
[typeAttrCount
].tag 
= kTXNQDFontColorAttribute 
; 
1832         typeAttr
[typeAttrCount
].size 
= kTXNQDFontColorAttributeSize 
; 
1833         typeAttr
[typeAttrCount
].data
.dataPtr 
= (void*) &color 
; 
1837     if ( style
.HasAlignment() ) 
1839         wxASSERT( controlAttrCount 
< WXSIZEOF(controlTags
) ); 
1842         switch ( style
.GetAlignment() ) 
1844             case wxTEXT_ALIGNMENT_LEFT
: 
1845                 align 
= kTXNFlushLeft
; 
1847             case wxTEXT_ALIGNMENT_CENTRE
: 
1850             case wxTEXT_ALIGNMENT_RIGHT
: 
1851                 align 
= kTXNFlushRight
; 
1853             case wxTEXT_ALIGNMENT_JUSTIFIED
: 
1854                 align 
= kTXNFullJust
; 
1857             case wxTEXT_ALIGNMENT_DEFAULT
: 
1858                 align 
= kTXNFlushDefault
; 
1862         controlTags
[controlAttrCount
] = kTXNJustificationTag 
; 
1863         controlData
[controlAttrCount
].sValue 
= align 
; 
1864         controlAttrCount
++ ; 
1867     if ( style
.HasLeftIndent() || style
.HasRightIndent() ) 
1869         wxASSERT( controlAttrCount 
< WXSIZEOF(controlTags
) ); 
1870         controlTags
[controlAttrCount
] = kTXNMarginsTag
; 
1871         controlData
[controlAttrCount
].marginsPtr 
= &margins
; 
1872         verify_noerr( TXNGetTXNObjectControls (m_txn
, 1 , 
1873                                 &controlTags
[controlAttrCount
], &controlData
[controlAttrCount
]) ); 
1874         if ( style
.HasLeftIndent() ) 
1876             margins
.leftMargin 
= wxConvertToTXN(style
.GetLeftIndent()); 
1878         if ( style
.HasRightIndent() ) 
1880             margins
.rightMargin 
= wxConvertToTXN(style
.GetRightIndent()); 
1882         controlAttrCount
++ ; 
1885     if ( style
.HasTabs() ) 
1887         const wxArrayInt
& tabarray 
= style
.GetTabs(); 
1888         // unfortunately Mac only applies a tab distance, not individually different tabs 
1889         controlTags
[controlAttrCount
] = kTXNTabSettingsTag
; 
1890         if ( tabarray
.size() > 0 ) 
1891             controlData
[controlAttrCount
].tabValue
.value 
= wxConvertToTXN(tabarray
[0]); 
1893             controlData
[controlAttrCount
].tabValue
.value 
= 72 ; 
1895         controlData
[controlAttrCount
].tabValue
.tabType 
= kTXNLeftTab
; 
1896         controlAttrCount
++ ; 
1899     // unfortunately the relayout is not automatic 
1900     if ( controlAttrCount 
> 0 ) 
1902         verify_noerr( TXNSetTXNObjectControls (m_txn
, false /* don't clear all */, controlAttrCount
, 
1903                                 controlTags
, controlData
) ); 
1907     if ( typeAttrCount 
> 0 ) 
1909         verify_noerr( TXNSetTypeAttributes( m_txn 
, typeAttrCount
, typeAttr
, from 
, to 
) ); 
1920         TXNRecalcTextLayout( m_txn 
); 
1924 void wxMacMLTEControl::SetFont(const wxFont 
& font
, 
1925                                const wxColour
& foreground
, 
1926                                long WXUNUSED(windowStyle
)) 
1928     wxMacEditHelper 
help( m_txn 
) ; 
1929     TXNSetAttribute( wxTextAttr( foreground
, wxNullColour
, font 
), kTXNStartOffset
, kTXNEndOffset 
) ; 
1932 void wxMacMLTEControl::SetStyle( long start
, long end
, const wxTextAttr
& style 
) 
1934     wxMacEditHelper 
help( m_txn 
) ; 
1935     TXNSetAttribute( style
, start
, end 
) ; 
1938 void wxMacMLTEControl::Copy() 
1943 void wxMacMLTEControl::Cut() 
1948 void wxMacMLTEControl::Paste() 
1953 bool wxMacMLTEControl::CanPaste() const 
1955     return TXNIsScrapPastable() ; 
1958 void wxMacMLTEControl::SetEditable(bool editable
) 
1960     TXNControlTag tag
[] = { kTXNIOPrivilegesTag 
} ; 
1961     TXNControlData data
[] = { { editable 
? kTXNReadWrite 
: kTXNReadOnly 
} } ; 
1962     TXNSetTXNObjectControls( m_txn
, false, WXSIZEOF(tag
), tag
, data 
) ; 
1965 wxTextPos 
wxMacMLTEControl::GetLastPosition() const 
1967     wxTextPos actualsize 
= 0 ; 
1970     OSErr err 
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData 
); 
1975         actualsize 
= GetHandleSize( theText 
) ; 
1976         DisposeHandle( theText 
) ; 
1986 void wxMacMLTEControl::Replace( long from 
, long to 
, const wxString 
&str 
) 
1988     wxString value 
= str 
; 
1989     wxMacConvertNewlines10To13( &value 
) ; 
1991     wxMacEditHelper 
help( m_txn 
) ; 
1993     wxMacWindowClipper 
c( m_peer 
) ; 
1996     TXNSetSelection( m_txn
, from
, to 
== -1 ? kTXNEndOffset 
: to 
) ; 
1998     SetTXNData( value
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection 
) ; 
2001 void wxMacMLTEControl::Remove( long from 
, long to 
) 
2004     wxMacWindowClipper 
c( m_peer 
) ; 
2006     wxMacEditHelper 
help( m_txn 
) ; 
2007     TXNSetSelection( m_txn 
, from 
, to 
) ; 
2011 void wxMacMLTEControl::GetSelection( long* from
, long* to
) const 
2014     TXNGetSelection( m_txn 
, &f 
, &t 
) ; 
2019 void wxMacMLTEControl::SetSelection( long from 
, long to 
) 
2022     wxMacWindowClipper 
c( m_peer 
) ; 
2025     // change the selection 
2026     if ((from 
== -1) && (to 
== -1)) 
2027         TXNSelectAll( m_txn 
); 
2029         TXNSetSelection( m_txn
, from
, to 
== -1 ? kTXNEndOffset 
: to 
); 
2031     TXNShowSelection( m_txn
, kTXNShowStart 
); 
2034 void wxMacMLTEControl::WriteText( const wxString
& str 
) 
2037     wxMacConvertNewlines10To13( &st 
) ; 
2039     long start 
, end 
, dummy 
; 
2041     GetSelection( &start 
, &dummy 
) ; 
2043     wxMacWindowClipper 
c( m_peer 
) ; 
2047         wxMacEditHelper 
helper( m_txn 
) ; 
2048         SetTXNData( st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection 
) ; 
2051     GetSelection( &dummy
, &end 
) ; 
2053     // TODO: SetStyle( start , end , GetDefaultStyle() ) ; 
2056 void wxMacMLTEControl::Clear() 
2059     wxMacWindowClipper 
c( m_peer 
) ; 
2061     wxMacEditHelper 
st( m_txn 
) ; 
2062     TXNSetSelection( m_txn 
, kTXNStartOffset 
, kTXNEndOffset 
) ; 
2066 bool wxMacMLTEControl::CanUndo() const 
2068     return TXNCanUndo( m_txn 
, NULL 
) ; 
2071 void wxMacMLTEControl::Undo() 
2076 bool wxMacMLTEControl::CanRedo() const 
2078     return TXNCanRedo( m_txn 
, NULL 
) ; 
2081 void wxMacMLTEControl::Redo() 
2086 int wxMacMLTEControl::GetNumberOfLines() const 
2088     ItemCount lines 
= 0 ; 
2089     TXNGetLineCount( m_txn
, &lines 
) ; 
2094 long wxMacMLTEControl::XYToPosition(long x
, long y
) const 
2099     // TODO: find a better implementation : while we can get the 
2100     // line metrics of a certain line, we don't get its starting 
2101     // position, so it would probably be rather a binary search 
2102     // for the start position 
2103     long xpos 
= 0, ypos 
= 0 ; 
2104     int lastHeight 
= 0 ; 
2107     lastpos 
= GetLastPosition() ; 
2108     for ( n 
= 0 ; n 
<= (ItemCount
) lastpos 
; ++n 
) 
2110         if ( y 
== ypos 
&& x 
== xpos 
) 
2113         TXNOffsetToPoint( m_txn
, n
, &curpt 
) ; 
2115         if ( curpt
.v 
> lastHeight 
) 
2121             lastHeight 
= curpt
.v 
; 
2130 bool wxMacMLTEControl::PositionToXY( long pos
, long *x
, long *y 
) const 
2140     lastpos 
= GetLastPosition() ; 
2141     if ( pos 
<= lastpos 
) 
2143         // TODO: find a better implementation - while we can get the 
2144         // line metrics of a certain line, we don't get its starting 
2145         // position, so it would probably be rather a binary search 
2146         // for the start position 
2147         long xpos 
= 0, ypos 
= 0 ; 
2148         int lastHeight 
= 0 ; 
2151         for ( n 
= 0 ; n 
<= (ItemCount
) pos 
; ++n 
) 
2153             TXNOffsetToPoint( m_txn
, n
, &curpt 
) ; 
2155             if ( curpt
.v 
> lastHeight 
) 
2161                 lastHeight 
= curpt
.v 
; 
2176 void wxMacMLTEControl::ShowPosition( long pos 
) 
2178     Point current
, desired 
; 
2179     TXNOffset selstart
, selend
; 
2181     TXNGetSelection( m_txn
, &selstart
, &selend 
); 
2182     TXNOffsetToPoint( m_txn
, selstart
, ¤t 
); 
2183     TXNOffsetToPoint( m_txn
, pos
, &desired 
); 
2185     // TODO: use HIPoints for 10.3 and above 
2187     OSErr theErr 
= noErr
; 
2188     long dv 
= desired
.v 
- current
.v
; 
2189     long dh 
= desired
.h 
- current
.h
; 
2190     TXNShowSelection( m_txn
, kTXNShowStart 
) ; // NB: should this be kTXNShowStart or kTXNShowEnd ?? 
2191     theErr 
= TXNScroll( m_txn
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh 
); 
2193     // there will be an error returned for classic MLTE implementation when the control is 
2194     // invisible, but HITextView works correctly, so we don't assert that one 
2195     // wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") ); 
2198 void wxMacMLTEControl::SetTXNData( const wxString
& st
, TXNOffset start
, TXNOffset end 
) 
2201 #if SIZEOF_WCHAR_T == 2 
2202     size_t len 
= st
.length() ; 
2203     TXNSetData( m_txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len 
* 2, start
, end 
); 
2205     wxMBConvUTF16 converter 
; 
2206     ByteCount byteBufferLen 
= converter
.WC2MB( NULL
, st
.wc_str(), 0 ) ; 
2207     UniChar 
*unibuf 
= (UniChar
*)malloc( byteBufferLen 
) ; 
2208     converter
.WC2MB( (char*)unibuf
, st
.wc_str(), byteBufferLen 
) ; 
2209     TXNSetData( m_txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
, start
, end 
) ; 
2213     wxCharBuffer text 
= st
.mb_str( wxConvLocal 
) ; 
2214     TXNSetData( m_txn
, kTXNTextData
, (void*)text
.data(), strlen( text 
), start
, end 
) ; 
2218 wxString 
wxMacMLTEControl::GetLineText(long lineNo
) const 
2222     if ( lineNo 
< GetNumberOfLines() ) 
2225         Fixed lineWidth
, lineHeight
, currentHeight
; 
2228         // get the first possible position in the control 
2229         TXNOffsetToPoint(m_txn
, 0, &firstPoint
); 
2231         // Iterate through the lines until we reach the one we want, 
2232         // adding to our current y pixel point position 
2235         while (ypos 
< lineNo
) 
2237             TXNGetLineMetrics(m_txn
, ypos
++, &lineWidth
, &lineHeight
); 
2238             currentHeight 
+= lineHeight
; 
2241         Point thePoint 
= { firstPoint
.v 
+ (currentHeight 
>> 16), firstPoint
.h 
+ (0) }; 
2242         TXNOffset theOffset
; 
2243         TXNPointToOffset(m_txn
, thePoint
, &theOffset
); 
2245         wxString content 
= GetStringValue() ; 
2246         Point currentPoint 
= thePoint
; 
2247         while (thePoint
.v 
== currentPoint
.v 
&& theOffset 
< content
.length()) 
2249             line 
+= content
[theOffset
]; 
2250             TXNOffsetToPoint(m_txn
, ++theOffset
, ¤tPoint
); 
2257 int wxMacMLTEControl::GetLineLength(long lineNo
) const 
2261     if ( lineNo 
< GetNumberOfLines() ) 
2264         Fixed lineWidth
, lineHeight
, currentHeight
; 
2267         // get the first possible position in the control 
2268         TXNOffsetToPoint(m_txn
, 0, &firstPoint
); 
2270         // Iterate through the lines until we reach the one we want, 
2271         // adding to our current y pixel point position 
2274         while (ypos 
< lineNo
) 
2276             TXNGetLineMetrics(m_txn
, ypos
++, &lineWidth
, &lineHeight
); 
2277             currentHeight 
+= lineHeight
; 
2280         Point thePoint 
= { firstPoint
.v 
+ (currentHeight 
>> 16), firstPoint
.h 
+ (0) }; 
2281         TXNOffset theOffset
; 
2282         TXNPointToOffset(m_txn
, thePoint
, &theOffset
); 
2284         wxString content 
= GetStringValue() ; 
2285         Point currentPoint 
= thePoint
; 
2286         while (thePoint
.v 
== currentPoint
.v 
&& theOffset 
< content
.length()) 
2289             TXNOffsetToPoint(m_txn
, ++theOffset
, ¤tPoint
); 
2296 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 
2298 // ---------------------------------------------------------------------------- 
2299 // MLTE control implementation (classic part) 
2300 // ---------------------------------------------------------------------------- 
2302 // OS X Notes : We still don't have a full replacement for MLTE, so this implementation 
2303 // has to live on. We have different problems coming from outdated implementations on the 
2304 // various OS X versions. Most deal with the scrollbars: they are not correctly embedded 
2305 // while this can be solved on 10.3 by reassigning them the correct place, on 10.2 there is 
2306 // no way out, therefore we are using our own implementation and our own scrollbars .... 
2308 TXNScrollInfoUPP gTXNScrollInfoProc 
= NULL 
; 
2309 ControlActionUPP gTXNScrollActionProc 
= NULL 
; 
2311 pascal void wxMacMLTEClassicControl::TXNScrollInfoProc( 
2312     SInt32 iValue
, SInt32 iMaximumValue
, 
2313     TXNScrollBarOrientation iScrollBarOrientation
, SInt32 iRefCon 
) 
2315     wxMacMLTEClassicControl
* mlte 
= (wxMacMLTEClassicControl
*) iRefCon 
; 
2316     SInt32 value 
=  wxMax( iValue 
, 0 ) ; 
2317     SInt32 maximum 
= wxMax( iMaximumValue 
, 0 ) ; 
2319     if ( iScrollBarOrientation 
== kTXNHorizontal 
) 
2321         if ( mlte
->m_sbHorizontal 
) 
2323             SetControl32BitValue( mlte
->m_sbHorizontal 
, value 
) ; 
2324             SetControl32BitMaximum( mlte
->m_sbHorizontal 
, maximum 
) ; 
2325             mlte
->m_lastHorizontalValue 
= value 
; 
2328     else if ( iScrollBarOrientation 
== kTXNVertical 
) 
2330         if ( mlte
->m_sbVertical 
) 
2332             SetControl32BitValue( mlte
->m_sbVertical 
, value 
) ; 
2333             SetControl32BitMaximum( mlte
->m_sbVertical 
, maximum 
) ; 
2334             mlte
->m_lastVerticalValue 
= value 
; 
2339 pascal void wxMacMLTEClassicControl::TXNScrollActionProc( ControlRef controlRef 
, ControlPartCode partCode 
) 
2341     wxMacMLTEClassicControl
* mlte 
= (wxMacMLTEClassicControl
*) GetControlReference( controlRef 
) ; 
2345     if ( controlRef 
!= mlte
->m_sbVertical 
&& controlRef 
!= mlte
->m_sbHorizontal 
) 
2349     bool isHorizontal 
= ( controlRef 
== mlte
->m_sbHorizontal 
) ; 
2351     SInt32 minimum 
= 0 ; 
2352     SInt32 maximum 
= GetControl32BitMaximum( controlRef 
) ; 
2353     SInt32 value 
= GetControl32BitValue( controlRef 
) ; 
2358         case kControlDownButtonPart 
: 
2362         case kControlUpButtonPart 
: 
2366         case kControlPageDownPart 
: 
2367             delta 
= GetControlViewSize( controlRef 
) ; 
2370         case kControlPageUpPart 
: 
2371             delta 
= -GetControlViewSize( controlRef 
) ; 
2374         case kControlIndicatorPart 
: 
2375             delta 
= value 
- (isHorizontal 
? mlte
->m_lastHorizontalValue 
: mlte
->m_lastVerticalValue
) ; 
2384         SInt32 newValue 
= value 
; 
2386         if ( partCode 
!= kControlIndicatorPart 
) 
2388             if ( value 
+ delta 
< minimum 
) 
2389                 delta 
= minimum 
- value 
; 
2390             if ( value 
+ delta 
> maximum 
) 
2391                 delta 
= maximum 
- value 
; 
2393             SetControl32BitValue( controlRef 
, value 
+ delta 
) ; 
2394             newValue 
= value 
+ delta 
; 
2397         SInt32 verticalDelta 
= isHorizontal 
? 0 : delta 
; 
2398         SInt32 horizontalDelta 
= isHorizontal 
? delta 
: 0 ; 
2401             mlte
->m_txn
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, 
2402             &verticalDelta
, &horizontalDelta 
); 
2403         verify_noerr( err 
); 
2406             mlte
->m_lastHorizontalValue 
= newValue 
; 
2408             mlte
->m_lastVerticalValue 
= newValue 
; 
2412 // make correct activations 
2413 void wxMacMLTEClassicControl::MacActivatePaneText(bool setActive
) 
2415     wxTextCtrl
* textctrl 
= (wxTextCtrl
*) GetControlReference(m_controlRef
); 
2417     wxMacWindowClipper 
clipper( textctrl 
) ; 
2418     TXNActivate( m_txn
, m_txnFrameID
, setActive 
); 
2420     ControlRef controlFocus 
= 0 ; 
2421     GetKeyboardFocus( m_txnWindow 
, &controlFocus 
) ; 
2422     if ( controlFocus 
== m_controlRef 
) 
2423         TXNFocus( m_txn
, setActive 
); 
2426 void wxMacMLTEClassicControl::MacFocusPaneText(bool setFocus
) 
2428     TXNFocus( m_txn
, setFocus 
); 
2431 // guards against inappropriate redraw (hidden objects drawing onto window) 
2433 void wxMacMLTEClassicControl::MacSetObjectVisibility(bool vis
) 
2435     ControlRef controlFocus 
= 0 ; 
2436     GetKeyboardFocus( m_txnWindow 
, &controlFocus 
) ; 
2438     if ( !vis 
&& (controlFocus 
== m_controlRef 
) ) 
2439         SetKeyboardFocus( m_txnWindow 
, m_controlRef 
, kControlFocusNoPart 
) ; 
2441     TXNControlTag iControlTags
[1] = { kTXNVisibilityTag 
}; 
2442     TXNControlData iControlData
[1] = { { (UInt32
)false } }; 
2444     verify_noerr( TXNGetTXNObjectControls( m_txn 
, 1, iControlTags
, iControlData 
) ) ; 
2446     if ( iControlData
[0].uValue 
!= vis 
) 
2448         iControlData
[0].uValue 
= vis 
; 
2449         verify_noerr( TXNSetTXNObjectControls( m_txn
, false , 1, iControlTags
, iControlData 
) ) ; 
2452     // currently, we always clip as partial visibility (overlapped) visibility is also a problem, 
2453     // if we run into further problems we might set the FrameBounds to an empty rect here 
2456 // make sure that the TXNObject is at the right position 
2458 void wxMacMLTEClassicControl::MacUpdatePosition() 
2460     wxTextCtrl
* textctrl 
= (wxTextCtrl
*)GetControlReference( m_controlRef 
); 
2461     if ( textctrl 
== NULL 
) 
2465     GetRectInWindowCoords( &bounds 
); 
2467     wxRect visRect 
= textctrl
->MacGetClippedClientRect() ; 
2468     Rect visBounds 
= { visRect
.y 
, visRect
.x 
, visRect
.y 
+ visRect
.height 
, visRect
.x 
+ visRect
.width 
} ; 
2471     textctrl
->MacWindowToRootWindow( &x 
, &y 
) ; 
2472     OffsetRect( &visBounds 
, x 
, y 
) ; 
2474     if ( !EqualRect( &bounds
, &m_txnControlBounds 
) || !EqualRect( &visBounds
, &m_txnVisBounds 
) ) 
2476         m_txnControlBounds 
= bounds 
; 
2477         m_txnVisBounds 
= visBounds 
; 
2478         wxMacWindowClipper 
cl( textctrl 
) ; 
2480         if ( m_sbHorizontal 
|| m_sbVertical 
) 
2482             int w 
= bounds
.right 
- bounds
.left 
; 
2483             int h 
= bounds
.bottom 
- bounds
.top 
; 
2485             if ( m_sbHorizontal 
) 
2489                 sbBounds
.left 
= -1 ; 
2490                 sbBounds
.top 
= h 
- 14 ; 
2491                 sbBounds
.right 
= w 
+ 1 ; 
2492                 sbBounds
.bottom 
= h 
+ 1 ; 
2494                 SetControlBounds( m_sbHorizontal 
, &sbBounds 
) ; 
2495                 SetControlViewSize( m_sbHorizontal 
, w 
) ; 
2502                 sbBounds
.left 
= w 
- 14 ; 
2504                 sbBounds
.right 
= w 
+ 1 ; 
2505                 sbBounds
.bottom 
= m_sbHorizontal 
? h 
- 14 : h 
+ 1 ; 
2507                 SetControlBounds( m_sbVertical 
, &sbBounds 
) ; 
2508                 SetControlViewSize( m_sbVertical 
, h 
) ; 
2513         TXNLongRect olddestRect 
; 
2514         TXNGetRectBounds( m_txn 
, &oldviewRect 
, &olddestRect 
, NULL 
) ; 
2516         Rect viewRect 
= { m_txnControlBounds
.top
, m_txnControlBounds
.left
, 
2517             m_txnControlBounds
.bottom 
- ( m_sbHorizontal 
? 14 : 0 ) , 
2518             m_txnControlBounds
.right 
- ( m_sbVertical 
? 14 : 0 ) } ; 
2519         TXNLongRect destRect 
= { m_txnControlBounds
.top
, m_txnControlBounds
.left
, 
2520             m_txnControlBounds
.bottom 
- ( m_sbHorizontal 
? 14 : 0 ) , 
2521             m_txnControlBounds
.right 
- ( m_sbVertical 
? 14 : 0 ) } ; 
2523         if ( olddestRect
.right 
>= 10000 ) 
2524             destRect
.right 
= destRect
.left 
+ 32000 ; 
2526         if ( olddestRect
.bottom 
>= 0x20000000 ) 
2527             destRect
.bottom 
= destRect
.top 
+ 0x40000000 ; 
2529         SectRect( &viewRect 
, &visBounds 
, &viewRect 
) ; 
2530         TXNSetRectBounds( m_txn 
, &viewRect 
, &destRect 
, true ) ; 
2535             m_txnControlBounds
.top
, 
2536             m_txnControlBounds
.left
, 
2537             m_txnControlBounds
.bottom 
- (m_sbHorizontal 
? 14 : 0), 
2538             m_txnControlBounds
.right 
- (m_sbVertical 
? 14 : 0), 
2542         // the SetFrameBounds method under Classic sometimes does not correctly scroll a selection into sight after a 
2543         // movement, therefore we have to force it 
2545         // this problem has been reported in OSX as well, so we use this here once again 
2547         TXNLongRect textRect 
; 
2548         TXNGetRectBounds( m_txn 
, NULL 
, NULL 
, &textRect 
) ; 
2549         if ( textRect
.left 
< m_txnControlBounds
.left 
) 
2550             TXNShowSelection( m_txn 
, kTXNShowStart 
) ; 
2554 void wxMacMLTEClassicControl::SetRect( Rect 
*r 
) 
2556     wxMacControl::SetRect( r 
) ; 
2557     MacUpdatePosition() ; 
2560 void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 
WXUNUSED(thePart
)) 
2562     wxTextCtrl
* textctrl 
= (wxTextCtrl
*)GetControlReference( m_controlRef 
); 
2563     if ( textctrl 
== NULL 
) 
2566     if ( textctrl
->IsShownOnScreen() ) 
2568         wxMacWindowClipper 
clipper( textctrl 
) ; 
2569         TXNDraw( m_txn 
, NULL 
) ; 
2573 wxInt16 
wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
) 
2575     Point where 
= { y 
, x 
} ; 
2576     ControlPartCode result 
= kControlNoPart
; 
2578     wxTextCtrl
* textctrl 
= (wxTextCtrl
*) GetControlReference( m_controlRef 
); 
2579     if ( (textctrl 
!= NULL
) && textctrl
->IsShownOnScreen() ) 
2581         if (PtInRect( where
, &m_txnControlBounds 
)) 
2583             result 
= kControlEditTextPart 
; 
2587             // sometimes we get the coords also in control local coordinates, therefore test again 
2589             textctrl
->MacClientToRootWindow( &x 
, &y 
) ; 
2593             if (PtInRect( where
, &m_txnControlBounds 
)) 
2594                 result 
= kControlEditTextPart 
; 
2601 wxInt16 
wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x
, wxInt16 y
, void* WXUNUSED(actionProc
) ) 
2603     ControlPartCode result 
= kControlNoPart
; 
2605     wxTextCtrl
* textctrl 
= (wxTextCtrl
*) GetControlReference( m_controlRef 
); 
2606     if ( (textctrl 
!= NULL
) && textctrl
->IsShownOnScreen() ) 
2608         Point startPt 
= { y 
, x 
} ; 
2610         // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them 
2612         textctrl
->MacClientToRootWindow( &x 
, &y 
) ; 
2616         switch (MacControlUserPaneHitTestProc( startPt
.h 
, startPt
.v 
)) 
2618             case kControlEditTextPart 
: 
2620                 wxMacWindowClipper 
clipper( textctrl 
) ; 
2623                 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec 
) ; 
2624                 TXNClick( m_txn
, &rec 
); 
2636 void wxMacMLTEClassicControl::MacControlUserPaneIdleProc() 
2638     wxTextCtrl
* textctrl 
= (wxTextCtrl
*)GetControlReference( m_controlRef 
); 
2639     if ( textctrl 
== NULL 
) 
2642     if (textctrl
->IsShownOnScreen()) 
2644         if (IsControlActive(m_controlRef
)) 
2648             wxMacWindowClipper 
clipper( textctrl 
) ; 
2653             if (PtInRect(mousep
, &m_txnControlBounds
)) 
2655                 RgnHandle theRgn 
= NewRgn(); 
2656                 RectRgn(theRgn
, &m_txnControlBounds
); 
2657                 TXNAdjustCursor(m_txn
, theRgn
); 
2664 wxInt16 
wxMacMLTEClassicControl::MacControlUserPaneKeyDownProc (wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
) 
2666     wxTextCtrl
* textctrl 
= (wxTextCtrl
*)GetControlReference( m_controlRef 
); 
2667     if ( textctrl 
== NULL 
) 
2668         return kControlNoPart
; 
2670     wxMacWindowClipper 
clipper( textctrl 
) ; 
2673     memset( &ev 
, 0 , sizeof( ev 
) ) ; 
2675     ev
.modifiers 
= modifiers 
; 
2676     ev
.message 
= ((keyCode 
<< 8) & keyCodeMask
) | (charCode 
& charCodeMask
); 
2677     TXNKeyDown( m_txn 
, &ev 
); 
2679     return kControlEntireControl
; 
2682 void wxMacMLTEClassicControl::MacControlUserPaneActivateProc(bool activating
) 
2684     MacActivatePaneText( activating 
); 
2687 wxInt16 
wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action
) 
2689     ControlPartCode focusResult 
= kControlFocusNoPart
; 
2691     wxTextCtrl
* textctrl 
= (wxTextCtrl
*)GetControlReference( m_controlRef 
); 
2692     if ( textctrl 
== NULL 
) 
2695     wxMacWindowClipper 
clipper( textctrl 
) ; 
2697     ControlRef controlFocus 
= NULL 
; 
2698     GetKeyboardFocus( m_txnWindow 
, &controlFocus 
) ; 
2699     bool wasFocused 
= ( controlFocus 
== m_controlRef 
) ; 
2703         case kControlFocusPrevPart
: 
2704         case kControlFocusNextPart
: 
2705             MacFocusPaneText( !wasFocused 
); 
2706             focusResult 
= (!wasFocused 
? (ControlPartCode
) kControlEditTextPart 
: (ControlPartCode
) kControlFocusNoPart
); 
2709         case kControlFocusNoPart
: 
2711             MacFocusPaneText( false ); 
2712             focusResult 
= kControlFocusNoPart
; 
2719 void wxMacMLTEClassicControl::MacControlUserPaneBackgroundProc( void *WXUNUSED(info
) ) 
2723 wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxTextCtrl 
*wxPeer
, 
2724     const wxString
& str
, 
2726     const wxSize
& size
, long style 
) 
2727     : wxMacMLTEControl( wxPeer 
) 
2729     m_font 
= wxPeer
->GetFont() ; 
2730     m_windowStyle 
= style 
; 
2731     Rect bounds 
= wxMacGetBoundsForControl( wxPeer 
, pos 
, size 
) ; 
2734         kControlSupportsEmbedding 
| kControlSupportsFocus 
| kControlWantsIdle
 
2735         | kControlWantsActivate  
| kControlHandlesTracking
 
2736 //    | kControlHasSpecialBackground 
2737         | kControlGetsFocusOnClick 
| kControlSupportsLiveFeedback
; 
2739    OSStatus err 
= ::CreateUserPaneControl( 
2740         MAC_WXHWND(wxPeer
->GetParent()->MacGetTopLevelWindowRef()), 
2741         &bounds
, featureSet
, &m_controlRef 
); 
2742     verify_noerr( err 
); 
2746     AdjustCreationAttributes( *wxWHITE 
, true ) ; 
2748     MacSetObjectVisibility( wxPeer
->IsShownOnScreen() ) ; 
2752         wxMacConvertNewlines10To13( &st 
) ; 
2753         wxMacWindowClipper 
clipper( m_peer 
) ; 
2754         SetTXNData( st 
, kTXNStartOffset
, kTXNEndOffset 
) ; 
2755         TXNSetSelection( m_txn
, 0, 0 ) ; 
2759 wxMacMLTEClassicControl::~wxMacMLTEClassicControl() 
2761     TXNDeleteObject( m_txn 
); 
2765 void wxMacMLTEClassicControl::VisibilityChanged(bool shown
) 
2767     MacSetObjectVisibility( shown 
) ; 
2768     wxMacControl::VisibilityChanged( shown 
) ; 
2771 void wxMacMLTEClassicControl::SuperChangedPosition() 
2773     MacUpdatePosition() ; 
2774     wxMacControl::SuperChangedPosition() ; 
2777 ControlUserPaneDrawUPP gTPDrawProc 
= NULL
; 
2778 ControlUserPaneHitTestUPP gTPHitProc 
= NULL
; 
2779 ControlUserPaneTrackingUPP gTPTrackProc 
= NULL
; 
2780 ControlUserPaneIdleUPP gTPIdleProc 
= NULL
; 
2781 ControlUserPaneKeyDownUPP gTPKeyProc 
= NULL
; 
2782 ControlUserPaneActivateUPP gTPActivateProc 
= NULL
; 
2783 ControlUserPaneFocusUPP gTPFocusProc 
= NULL
; 
2785 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
) 
2787     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2788     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2790         win
->MacControlUserPaneDrawProc( part 
) ; 
2793 static pascal ControlPartCode 
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
) 
2795     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2796     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2798         return win
->MacControlUserPaneHitTestProc( where
.h 
, where
.v 
) ; 
2800         return kControlNoPart 
; 
2803 static pascal ControlPartCode 
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
) 
2805     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2806     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2808         return win
->MacControlUserPaneTrackingProc( startPt
.h 
, startPt
.v 
, (void*) actionProc 
) ; 
2810         return kControlNoPart 
; 
2813 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
) 
2815     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2816     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2818         win
->MacControlUserPaneIdleProc() ; 
2821 static pascal ControlPartCode 
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) 
2823     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2824     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2826         return win
->MacControlUserPaneKeyDownProc( keyCode
, charCode
, modifiers 
) ; 
2828         return kControlNoPart 
; 
2831 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
) 
2833     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2834     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2836         win
->MacControlUserPaneActivateProc( activating 
) ; 
2839 static pascal ControlPartCode 
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
) 
2841     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2842     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2844         return win
->MacControlUserPaneFocusProc( action 
) ; 
2846         return kControlNoPart 
; 
2850 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
) 
2852     wxTextCtrl 
*textCtrl 
=  wxDynamicCast( wxFindControlFromMacControl(control
) , wxTextCtrl 
) ; 
2853     wxMacMLTEClassicControl 
* win 
= textCtrl 
? (wxMacMLTEClassicControl
*)(textCtrl
->GetPeer()) : NULL 
; 
2855         win
->MacControlUserPaneBackgroundProc(info
) ; 
2859 // TXNRegisterScrollInfoProc 
2861 OSStatus 
wxMacMLTEClassicControl::DoCreate() 
2864     OSStatus err 
= noErr 
; 
2866     // set up our globals 
2867     if (gTPDrawProc 
== NULL
) gTPDrawProc 
= NewControlUserPaneDrawUPP(wxMacControlUserPaneDrawProc
); 
2868     if (gTPHitProc 
== NULL
) gTPHitProc 
= NewControlUserPaneHitTestUPP(wxMacControlUserPaneHitTestProc
); 
2869     if (gTPTrackProc 
== NULL
) gTPTrackProc 
= NewControlUserPaneTrackingUPP(wxMacControlUserPaneTrackingProc
); 
2870     if (gTPIdleProc 
== NULL
) gTPIdleProc 
= NewControlUserPaneIdleUPP(wxMacControlUserPaneIdleProc
); 
2871     if (gTPKeyProc 
== NULL
) gTPKeyProc 
= NewControlUserPaneKeyDownUPP(wxMacControlUserPaneKeyDownProc
); 
2872     if (gTPActivateProc 
== NULL
) gTPActivateProc 
= NewControlUserPaneActivateUPP(wxMacControlUserPaneActivateProc
); 
2873     if (gTPFocusProc 
== NULL
) gTPFocusProc 
= NewControlUserPaneFocusUPP(wxMacControlUserPaneFocusProc
); 
2875     if (gTXNScrollInfoProc 
== NULL 
) gTXNScrollInfoProc 
= NewTXNScrollInfoUPP(TXNScrollInfoProc
) ; 
2876     if (gTXNScrollActionProc 
== NULL 
) gTXNScrollActionProc 
= NewControlActionUPP(TXNScrollActionProc
) ; 
2878     // set the initial settings for our private data 
2880     m_txnWindow 
= GetControlOwner(m_controlRef
); 
2881     m_txnPort 
= (GrafPtr
) GetWindowPort(m_txnWindow
); 
2883     // set up the user pane procedures 
2884     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
); 
2885     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
); 
2886     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
); 
2887     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
); 
2888     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
); 
2889     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
); 
2890     SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
); 
2892     // calculate the rectangles used by the control 
2893     GetRectInWindowCoords( &bounds 
); 
2895     m_txnControlBounds 
= bounds 
; 
2896     m_txnVisBounds 
= bounds 
; 
2901     GetGWorld( &origPort
, &origDev 
) ; 
2902     SetPort( m_txnPort 
); 
2904     // create the new edit field 
2905     TXNFrameOptions frameOptions 
= FrameOptionsFromWXStyle( m_windowStyle 
); 
2907     // the scrollbars are not correctly embedded but are inserted at the root: 
2908     // this gives us problems as we have erratic redraws even over the structure area 
2910     m_sbHorizontal 
= 0 ; 
2912     m_lastHorizontalValue 
= 0 ; 
2913     m_lastVerticalValue 
= 0 ; 
2915     Rect sb 
= { 0 , 0 , 0 , 0 } ; 
2916     if ( frameOptions 
& kTXNWantVScrollBarMask 
) 
2918         CreateScrollBarControl( m_txnWindow
, &sb
, 0, 0, 100, 1, true, gTXNScrollActionProc
, &m_sbVertical 
); 
2919         SetControlReference( m_sbVertical
, (SInt32
)this ); 
2920         SetControlAction( m_sbVertical
, gTXNScrollActionProc 
); 
2921         ShowControl( m_sbVertical 
); 
2922         EmbedControl( m_sbVertical 
, m_controlRef 
); 
2923         frameOptions 
&= ~kTXNWantVScrollBarMask
; 
2926     if ( frameOptions 
& kTXNWantHScrollBarMask 
) 
2928         CreateScrollBarControl( m_txnWindow
, &sb
, 0, 0, 100, 1, true, gTXNScrollActionProc
, &m_sbHorizontal 
); 
2929         SetControlReference( m_sbHorizontal
, (SInt32
)this ); 
2930         SetControlAction( m_sbHorizontal
, gTXNScrollActionProc 
); 
2931         ShowControl( m_sbHorizontal 
); 
2932         EmbedControl( m_sbHorizontal
, m_controlRef 
); 
2933         frameOptions 
&= ~(kTXNWantHScrollBarMask 
| kTXNDrawGrowIconMask
); 
2937         NULL
, m_txnWindow
, &bounds
, frameOptions
, 
2938         kTXNTextEditStyleFrameType
, kTXNTextensionFile
, kTXNSystemDefaultEncoding
, 
2939         &m_txn
, &m_txnFrameID
, NULL 
); 
2940     verify_noerr( err 
); 
2943     TXNControlTag iControlTags
[] = { kTXNUseCarbonEvents 
}; 
2944     TXNControlData iControlData
[] = { { (UInt32
)&cInfo 
} }; 
2945     int toptag 
= WXSIZEOF( iControlTags 
) ; 
2946     TXNCarbonEventInfo cInfo 
; 
2947     cInfo
.useCarbonEvents 
= false ; 
2950     cInfo
.fDictionary 
= NULL 
; 
2952     verify_noerr( TXNSetTXNObjectControls( m_txn
, false, toptag
, iControlTags
, iControlData 
) ); 
2955     TXNRegisterScrollInfoProc( m_txn
, gTXNScrollInfoProc
, (SInt32
)this ); 
2957     SetGWorld( origPort 
, origDev 
) ; 
2963 // ---------------------------------------------------------------------------- 
2964 // MLTE control implementation (OSX part) 
2965 // ---------------------------------------------------------------------------- 
2967 // tiger multi-line textcontrols with no CR in the entire content 
2968 // don't scroll automatically, so we need a hack. 
2969 // This attempt only works 'before' the key (ie before CallNextEventHandler) 
2970 // is processed, thus the scrolling always occurs one character too late, but 
2971 // better than nothing ... 
2973 static const EventTypeSpec eventList
[] = 
2975     { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent 
} , 
2978 static pascal OSStatus 
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
2980     OSStatus result 
= eventNotHandledErr 
; 
2981     wxMacMLTEHIViewControl
* focus 
= (wxMacMLTEHIViewControl
*) data 
; 
2983     switch ( GetEventKind( event 
) ) 
2985         case kEventTextInputUnicodeForKeyEvent 
: 
2987             TXNOffset from 
, to 
; 
2988             TXNGetSelection( focus
->GetTXNObject() , &from 
, &to 
) ; 
2990                 TXNShowSelection( focus
->GetTXNObject() , kTXNShowStart 
); 
2991             result 
= CallNextEventHandler(handler
,event
); 
3001 static pascal OSStatus 
wxMacTextControlEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
3003     OSStatus result 
= eventNotHandledErr 
; 
3005     switch ( GetEventClass( event 
) ) 
3007         case kEventClassTextInput 
: 
3008             result 
= wxMacUnicodeTextEventHandler( handler 
, event 
, data 
) ; 
3017 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTextControlEventHandler 
) 
3019 wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl 
*wxPeer
, 
3020     const wxString
& str
, 
3022     const wxSize
& size
, long style 
) : wxMacMLTEControl( wxPeer 
) 
3024     m_font 
= wxPeer
->GetFont() ; 
3025     m_windowStyle 
= style 
; 
3026     Rect bounds 
= wxMacGetBoundsForControl( wxPeer 
, pos 
, size 
) ; 
3028     wxMacConvertNewlines10To13( &st 
) ; 
3031         { bounds
.left 
, bounds
.top 
}, 
3032         { bounds
.right 
- bounds
.left
, bounds
.bottom 
- bounds
.top 
} } ; 
3034     m_scrollView 
= NULL 
; 
3035     TXNFrameOptions frameOptions 
= FrameOptionsFromWXStyle( style 
) ; 
3036     if (( frameOptions 
& (kTXNWantVScrollBarMask 
| kTXNWantHScrollBarMask
)) || (frameOptions 
&kTXNSingleLineOnlyMask
)) 
3038         if ( frameOptions 
& (kTXNWantVScrollBarMask 
| kTXNWantHScrollBarMask
) ) 
3041                 (frameOptions 
& kTXNWantHScrollBarMask 
? kHIScrollViewOptionsHorizScroll 
: 0) 
3042                 | (frameOptions 
& kTXNWantVScrollBarMask 
? kHIScrollViewOptionsVertScroll 
: 0) , 
3047             HIScrollViewCreate(kHIScrollViewOptionsVertScroll
,&m_scrollView
); 
3048             HIScrollViewSetScrollBarAutoHide(m_scrollView
,true); 
3051         HIViewSetFrame( m_scrollView
, &hr 
); 
3052         HIViewSetVisible( m_scrollView
, true ); 
3056     HITextViewCreate( NULL 
, 0, frameOptions 
, &m_textView 
) ; 
3057     m_txn 
= HITextViewGetTXNObject( m_textView 
) ; 
3058     HIViewSetVisible( m_textView 
, true ) ; 
3061         HIViewAddSubview( m_scrollView 
, m_textView 
) ; 
3062         m_controlRef 
= m_scrollView 
; 
3063         wxPeer
->MacInstallEventHandler( (WXWidget
) m_textView 
) ; 
3067         HIViewSetFrame( m_textView
, &hr 
); 
3068         m_controlRef 
= m_textView 
; 
3071     AdjustCreationAttributes( *wxWHITE 
, true ) ; 
3073     wxMacWindowClipper 
c( m_peer 
) ; 
3075     SetTXNData( st 
, kTXNStartOffset
, kTXNEndOffset 
) ; 
3077     TXNSetSelection( m_txn
, 0, 0 ); 
3078     TXNShowSelection( m_txn
, kTXNShowStart 
); 
3080     InstallControlEventHandler( m_textView 
, GetwxMacTextControlEventHandlerUPP(), 
3081                                 GetEventTypeCount(eventList
), eventList
, this, 
3085 wxMacMLTEHIViewControl::~wxMacMLTEHIViewControl() 
3089 OSStatus 
wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart 
) 
3091     return SetKeyboardFocus( GetControlOwner( m_textView 
), m_textView
, focusPart 
) ; 
3094 bool wxMacMLTEHIViewControl::HasFocus() const 
3096     ControlRef control 
; 
3097     if ( GetUserFocusWindow() == NULL 
) 
3100     GetKeyboardFocus( GetUserFocusWindow() , &control 
) ; 
3101     return control 
== m_textView 
; 
3104 void wxMacMLTEHIViewControl::SetBackgroundColour(const wxColour
& col 
) 
3106     HITextViewSetBackgroundColor( m_textView
, col
.GetPixel() ); 
3109 #endif // wxUSE_TEXTCTRL