1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
22 #include <sys/types.h>
28 #include "wx/msgdlg.h"
30 #if wxUSE_STD_IOSTREAM
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"
49 #if defined(__BORLANDC__) && !defined(__WIN32__)
51 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
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
65 #include <MacTextEditor.h>
66 #include <ATSUnicode.h>
67 #include <TextCommon.h>
68 #include <TextEncodingConverter.h>
69 #include "wx/mac/uma.h"
75 virtual ~wxMacFunctor() {}
76 virtual void* operator()() = 0 ;
77 static void* CallBackProc(void *param
)
79 wxMacFunctor
* f
= (wxMacFunctor
*) param
;
80 void *result
= (*f
)() ;
85 template<typename classtype
,typename param1type
>
86 class wxMacObjectFunctor1
: public wxMacFunctor
88 typedef void (classtype::*function
)( param1type p1
) ;
89 typedef void (classtype::*ref_function
)( const param1type
& p1
) ;
91 wxMacObjectFunctor1( classtype
*obj
, function f
, param1type p1
) :
99 wxMacObjectFunctor1( classtype
*obj
, ref_function f
, param1type p1
) :
107 ~wxMacObjectFunctor1() {}
109 virtual void* operator()()
111 (m_object
->*m_function
)(m_param1
) ;
115 classtype
* m_object
;
116 param1type m_param1
;
119 function m_function
;
120 ref_function m_refFunction
;
124 template<typename classtype
, typename param1type
>
125 void* wxMacMPRemoteCall( classtype
*object
, void (classtype::*function
)( param1type p1
) , param1type p1
)
127 wxMacObjectFunctor1
<classtype
,param1type
> params(object
,function
,p1
) ;
129 MPRemoteCall( wxMacFunctor::CallBackProc
, ¶ms
, kMPOwningProcessRemoteContext
) ;
133 template<typename classtype
, typename param1type
>
134 void* wxMacMPRemoteCall( classtype
*object
, void (classtype::*function
)( const param1type
& p1
) , param1type p1
)
136 wxMacObjectFunctor1
<classtype
,param1type
> params(object
,function
,p1
) ;
138 MPRemoteCall( wxMacFunctor::CallBackProc
, ¶ms
, kMPOwningProcessRemoteContext
) ;
142 template<typename classtype
, typename param1type
>
143 void* wxMacMPRemoteGUICall( classtype
*object
, void (classtype::*function
)( param1type p1
) , param1type p1
)
146 void *result
= wxMacMPRemoteCall( object
, function
, p1
) ;
151 template<typename classtype
, typename param1type
>
152 void* wxMacMPRemoteGUICall( classtype
*object
, void (classtype::*function
)( const param1type
& p1
) , param1type p1
)
155 void *result
= wxMacMPRemoteCall( object
, function
, p1
) ;
159 // common interface for all implementations
160 class wxMacTextControl
: public wxMacControl
164 ~wxMacTextControl() ;
166 virtual wxString
GetStringValue() const = 0 ;
167 virtual void SetStringValue( const wxString
&val
) = 0 ;
168 virtual void SetStyle(long start
, long end
, const wxTextAttr
& style
) ;
169 virtual void Copy() ;
171 virtual void Paste() ;
172 virtual bool CanPaste() const ;
173 virtual void SetEditable(bool editable
) ;
174 virtual long GetLastPosition() const ;
175 virtual void Replace( long from
, long to
, const wxString str
) ;
176 virtual void Remove( long from
, long to
) = 0 ;
177 virtual void SetSelection( long from
, long to
) = 0 ;
178 virtual void GetSelection( long* from
, long* to
) const = 0 ;
179 virtual void WriteText(const wxString
& str
) = 0 ;
181 virtual void Clear() ;
182 virtual bool CanUndo() const;
183 virtual void Undo() ;
184 virtual bool CanRedo() const;
185 virtual void Redo() ;
186 virtual int GetNumberOfLines() const ;
187 virtual long XYToPosition(long x
, long y
) const;
188 virtual bool PositionToXY(long pos
, long *x
, long *y
) const ;
189 virtual void ShowPosition( long WXUNUSED(pos
) ) ;
190 virtual int GetLineLength(long lineNo
) const ;
191 virtual wxString
GetLineText(long lineNo
) const ;
194 // common parts for implementations based on MLTE
196 class wxMacMLTEControl
: public wxMacTextControl
199 virtual wxString
GetStringValue() const ;
200 virtual void SetStringValue( const wxString
&str
) ;
202 static int ConvertAttribute( const wxTextAttr
& style
, TXNTypeAttributes attr
[] ) ;
203 static TXNFrameOptions
FrameOptionsFromWXStyle( long wxStyle
) ;
204 void AdjustCreationAttributes( const wxColour
& background
, bool visible
) ;
206 virtual void SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
) ;
207 virtual void SetStyle(long start
, long end
, const wxTextAttr
& style
) ;
208 virtual void Copy() ;
210 virtual void Paste() ;
211 virtual bool CanPaste() const ;
212 virtual void SetEditable(bool editable
) ;
213 virtual long GetLastPosition() const ;
214 virtual void Replace( long from
, long to
, const wxString str
) ;
215 virtual void Remove( long from
, long to
) ;
216 virtual void GetSelection( long* from
, long* to
) const ;
217 virtual void SetSelection( long from
, long to
) ;
219 virtual void WriteText(const wxString
& str
) ;
220 virtual void Clear() ;
222 virtual bool CanUndo() const ;
223 virtual void Undo() ;
224 virtual bool CanRedo() const;
225 virtual void Redo() ;
226 virtual int GetNumberOfLines() const ;
227 virtual long XYToPosition(long x
, long y
) const ;
228 virtual bool PositionToXY(long pos
, long *x
, long *y
) const ;
229 virtual void ShowPosition( long pos
) ;
230 virtual int GetLineLength(long lineNo
) const ;
231 virtual wxString
GetLineText(long lineNo
) const ;
233 void SetTXNData( const wxString
& st
, TXNOffset start
, TXNOffset end
) ;
239 #if TARGET_API_MAC_OSX
241 // implementation available under OSX
243 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
245 class wxMacMLTEHIViewControl
: public wxMacMLTEControl
248 wxMacMLTEHIViewControl( wxWindow
*wxPeer
,
251 const wxSize
& size
, long style
) ;
252 virtual OSStatus
SetFocus( ControlFocusPart focusPart
) ;
253 virtual bool HasFocus() const ;
254 virtual bool NeedsFocusRect() const ;
256 HIViewRef m_scrollView
;
257 HIViewRef m_textView
;
262 class wxMacUnicodeTextControl
: public wxMacTextControl
265 wxMacUnicodeTextControl( wxWindow
*wxPeer
,
268 const wxSize
& size
, long style
) ;
269 ~wxMacUnicodeTextControl();
270 virtual void VisibilityChanged(bool shown
);
271 virtual wxString
GetStringValue() const ;
272 virtual void SetStringValue( const wxString
&str
) ;
275 virtual void Paste();
276 virtual bool CanPaste() const;
277 virtual void SetEditable(bool editable
) ;
278 virtual void Remove( long from
, long to
) ;
279 virtual void GetSelection( long* from
, long* to
) const ;
280 virtual void SetSelection( long from
, long to
) ;
281 virtual void WriteText(const wxString
& str
) ;
283 // contains the tag for the content (is different for password and non-password controls)
289 // implementation available under classic
291 class STPTextPaneVars
;
293 class wxMacMLTEClassicControl
: public wxMacMLTEControl
296 wxMacMLTEClassicControl( wxWindow
*wxPeer
,
299 const wxSize
& size
, long style
) ;
300 ~wxMacMLTEClassicControl() ;
301 virtual void VisibilityChanged(bool shown
) ;
305 // hack to make public until we have migrated all procs
306 STPTextPaneVars
* m_macTXNvars
;
309 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
311 #if !USE_SHARED_LIBRARY
312 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
314 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
315 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
316 EVT_CHAR(wxTextCtrl::OnChar
)
317 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
318 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
319 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
320 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
321 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
323 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
324 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
325 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
326 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
327 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
332 void wxTextCtrl::Init()
337 m_maxLength
= TE_UNLIMITED_LENGTH
;
340 wxTextCtrl::~wxTextCtrl()
345 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
348 const wxSize
& size
, long style
,
349 const wxValidator
& validator
,
350 const wxString
& name
)
352 m_macIsUserPane
= FALSE
;
355 if ( !HasFlag(wxNO_BORDER
) )
356 style
|= wxSUNKEN_BORDER
;
358 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
361 wxSize mySize
= size
;
363 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
365 if ( m_windowStyle
& wxTE_MULTILINE
)
367 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
368 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
370 m_windowStyle
|= wxTE_PROCESS_ENTER
;
371 style
|= wxTE_PROCESS_ENTER
;
374 #if TARGET_API_MAC_OSX
375 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
376 if ( UMAGetSystemVersion() >= 0x1030 )
378 m_peer
= new wxMacMLTEHIViewControl( this , str
, pos
, size
, style
) ;
381 #if !wxMAC_AWAYS_USE_MLTE
384 m_peer
= new wxMacUnicodeTextControl( this , str
, pos
, size
, style
) ;
390 // this control draws the border itself
391 if ( !HasFlag(wxNO_BORDER
) )
392 m_windowStyle
&= ~wxSUNKEN_BORDER
;
393 m_peer
= new wxMacMLTEClassicControl( this , str
, pos
, size
, style
) ;
396 MacPostControlCreate(pos
,size
) ;
398 if ( m_windowStyle
& wxTE_READONLY
)
400 SetEditable( false ) ;
407 void wxTextCtrl::MacVisibilityChanged()
409 GetPeer()->VisibilityChanged( MacIsReallyShown() ) ;
412 void wxTextCtrl::MacEnabledStateChanged()
416 wxString
wxTextCtrl::GetValue() const
418 return GetPeer()->GetStringValue() ;
421 void wxTextCtrl::GetSelection(long* from
, long* to
) const
423 GetPeer()->GetSelection( from
, to
) ;
426 void wxTextCtrl::SetValue(const wxString
& str
)
429 if ( GetValue() == str
)
432 GetPeer()->SetStringValue(str
) ;
435 void wxTextCtrl::SetMaxLength(unsigned long len
)
440 bool wxTextCtrl::SetFont( const wxFont
& font
)
442 if ( !wxTextCtrlBase::SetFont( font
) )
445 GetPeer()->SetFont( font
, GetForegroundColour() , GetWindowStyle() ) ;
449 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
451 GetPeer()->SetStyle( start
, end
, style
) ;
455 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
457 wxTextCtrlBase::SetDefaultStyle( style
) ;
458 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
462 // Clipboard operations
463 void wxTextCtrl::Copy()
471 void wxTextCtrl::Cut()
477 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
478 event
.SetString( GetValue() ) ;
479 event
.SetEventObject( this );
480 GetEventHandler()->ProcessEvent(event
);
484 void wxTextCtrl::Paste()
489 // eventually we should add setting the default style again
491 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
492 event
.SetString( GetValue() ) ;
493 event
.SetEventObject( this );
494 GetEventHandler()->ProcessEvent(event
);
498 bool wxTextCtrl::CanCopy() const
500 // Can copy if there's a selection
502 GetSelection(& from
, & to
);
506 bool wxTextCtrl::CanCut() const
512 // Can cut if there's a selection
514 GetSelection(& from
, & to
);
518 bool wxTextCtrl::CanPaste() const
523 return GetPeer()->CanPaste() ;
526 void wxTextCtrl::SetEditable(bool editable
)
528 if ( editable
!= m_editable
)
530 m_editable
= editable
;
531 GetPeer()->SetEditable( editable
) ;
535 void wxTextCtrl::SetInsertionPoint(long pos
)
537 SetSelection( pos
, pos
) ;
540 void wxTextCtrl::SetInsertionPointEnd()
542 long pos
= GetLastPosition();
543 SetInsertionPoint(pos
);
546 long wxTextCtrl::GetInsertionPoint() const
549 GetSelection( &begin
, &end
) ;
553 long wxTextCtrl::GetLastPosition() const
555 return GetPeer()->GetLastPosition( ) ;
558 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
560 GetPeer()->Replace( from
, to
, str
) ;
563 void wxTextCtrl::Remove(long from
, long to
)
565 GetPeer()->Remove( from
, to
) ;
568 void wxTextCtrl::SetSelection(long from
, long to
)
570 GetPeer()->SetSelection( from
, to
) ;
573 bool wxTextCtrl::LoadFile(const wxString
& file
)
575 if ( wxTextCtrlBase::LoadFile(file
) )
583 void wxTextCtrl::WriteText(const wxString
& str
)
585 // TODO this MPRemoting will be moved into a remoting peer proxy for any command
586 if ( !wxIsMainThread() )
588 // unfortunately CW 8 is not able to correctly deduce the template types, so we have
589 // to instantiate explicitely
590 wxMacMPRemoteGUICall
<wxTextCtrl
,wxString
>( this , &wxTextCtrl::WriteText
, str
) ;
595 GetPeer()->WriteText( str
) ;
599 void wxTextCtrl::AppendText(const wxString
& text
)
601 SetInsertionPointEnd();
605 void wxTextCtrl::Clear()
610 bool wxTextCtrl::IsModified() const
615 bool wxTextCtrl::IsEditable() const
617 return IsEnabled() && m_editable
;
620 bool wxTextCtrl::AcceptsFocus() const
622 // we don't want focus if we can't be edited
623 return /*IsEditable() && */ wxControl::AcceptsFocus();
626 wxSize
wxTextCtrl::DoGetBestSize() const
632 // these are the numbers from the HIG, we reduce them by the borders
635 switch( m_windowVariant
)
637 case wxWINDOW_VARIANT_NORMAL
:
640 case wxWINDOW_VARIANT_SMALL
:
643 case wxWINDOW_VARIANT_MINI
:
651 // as the above numbers have some free space around the text
652 // we get 5 lines like this anyway
653 if ( m_windowStyle
& wxTE_MULTILINE
)
658 if ( !HasFlag(wxNO_BORDER
) )
661 return wxSize(wText
, hText
);
664 // ----------------------------------------------------------------------------
666 // ----------------------------------------------------------------------------
668 void wxTextCtrl::Undo()
676 void wxTextCtrl::Redo()
684 bool wxTextCtrl::CanUndo() const
690 return GetPeer()->CanUndo() ;
693 bool wxTextCtrl::CanRedo() const
699 return GetPeer()->CanRedo() ;
702 void wxTextCtrl::MarkDirty()
707 void wxTextCtrl::DiscardEdits()
712 int wxTextCtrl::GetNumberOfLines() const
714 return GetPeer()->GetNumberOfLines() ;
717 long wxTextCtrl::XYToPosition(long x
, long y
) const
719 return GetPeer()->XYToPosition( x
, y
) ;
722 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
724 return GetPeer()->PositionToXY(pos
, x
, y
) ;
727 void wxTextCtrl::ShowPosition(long pos
)
729 return GetPeer()->ShowPosition(pos
) ;
732 int wxTextCtrl::GetLineLength(long lineNo
) const
734 return GetPeer()->GetLineLength(lineNo
) ;
737 wxString
wxTextCtrl::GetLineText(long lineNo
) const
739 return GetPeer()->GetLineText(lineNo
) ;
746 void wxTextCtrl::Command(wxCommandEvent
& event
)
748 SetValue (event
.GetString());
749 ProcessCommand (event
);
752 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
754 // By default, load the first file into the text window.
755 if (event
.GetNumberOfFiles() > 0)
757 LoadFile(event
.GetFiles()[0]);
761 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
763 int key
= event
.GetKeyCode() ;
764 bool eat_key
= false ;
766 if ( key
== 'c' && event
.MetaDown() )
773 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
774 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
775 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
782 // assume that any key not processed yet is going to modify the control
785 if ( key
== 'v' && event
.MetaDown() )
791 if ( key
== 'x' && event
.MetaDown() )
800 if (m_windowStyle
& wxPROCESS_ENTER
)
802 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
803 event
.SetEventObject( this );
804 event
.SetString( GetValue() );
805 if ( GetEventHandler()->ProcessEvent(event
) )
808 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
810 wxWindow
*parent
= GetParent();
811 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
812 parent
= parent
->GetParent() ;
814 if ( parent
&& parent
->GetDefaultItem() )
816 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
818 if ( def
&& def
->IsEnabled() )
820 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
821 event
.SetEventObject(def
);
827 // this will make wxWidgets eat the ENTER key so that
828 // we actually prevent line wrapping in a single line
836 if ( !(m_windowStyle
& wxTE_PROCESS_TAB
))
839 if (!event
.ShiftDown())
840 flags
|= wxNavigationKeyEvent::IsForward
;
841 if (event
.ControlDown())
842 flags
|= wxNavigationKeyEvent::WinChange
;
848 // This is necessary (don't know why) or the tab will not
850 WriteText(wxT("\t"));
858 // perform keystroke handling
859 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
860 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
864 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
866 EventRecord
*ev
= &rec
;
869 keychar
= short(ev
->message
& charCodeMask
);
870 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
872 m_peer
->HandleKey( keycode
, keychar
, ev
->modifiers
) ;
876 if ( ( key
>= 0x20 && key
< WXK_START
) ||
881 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
882 event1
.SetString( GetValue() ) ;
883 event1
.SetEventObject( this );
884 wxPostEvent(GetEventHandler(),event1
);
888 // ----------------------------------------------------------------------------
889 // standard handlers for standard edit menu events
890 // ----------------------------------------------------------------------------
892 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
897 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
902 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
907 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
912 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
917 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
919 event
.Enable( CanCut() );
922 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
924 event
.Enable( CanCopy() );
927 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
929 event
.Enable( CanPaste() );
932 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
934 event
.Enable( CanUndo() );
937 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
939 event
.Enable( CanRedo() );
942 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
947 // user pane implementation
949 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
953 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
955 return kControlNoPart
;
958 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
960 return kControlNoPart
;
963 void wxTextCtrl::MacControlUserPaneIdleProc()
967 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
969 return kControlNoPart
;
972 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
976 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
978 return kControlNoPart
;
981 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)
985 // ----------------------------------------------------------------------------
986 // implementation base class
987 // ----------------------------------------------------------------------------
989 wxMacTextControl::wxMacTextControl()
993 wxMacTextControl::~wxMacTextControl()
997 void wxMacTextControl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1001 void wxMacTextControl::Copy()
1005 void wxMacTextControl::Cut()
1009 void wxMacTextControl::Paste()
1013 bool wxMacTextControl::CanPaste() const
1018 void wxMacTextControl::SetEditable(bool editable
)
1022 long wxMacTextControl::GetLastPosition() const
1024 return GetStringValue().Length() ;
1027 void wxMacTextControl::Replace( long from
, long to
, const wxString str
)
1031 void wxMacTextControl::Clear()
1033 SetStringValue( wxEmptyString
) ;
1036 bool wxMacTextControl::CanUndo() const
1041 void wxMacTextControl::Undo() { }
1043 bool wxMacTextControl::CanRedo() const
1048 void wxMacTextControl::Redo()
1052 long wxMacTextControl::XYToPosition(long x
, long y
) const
1057 bool wxMacTextControl::PositionToXY(long pos
, long *x
, long *y
) const
1062 void wxMacTextControl::ShowPosition( long WXUNUSED(pos
) )
1066 int wxMacTextControl::GetNumberOfLines() const
1068 ItemCount lines
= 0 ;
1069 wxString content
= GetStringValue() ;
1071 for (size_t i
= 0; i
< content
.Length() ; i
++)
1073 if (content
[i
] == '\r') lines
++;
1078 wxString
wxMacTextControl::GetLineText(long lineNo
) const
1080 // TODO change this if possible to reflect real lines
1081 wxString content
= GetStringValue() ;
1085 for (size_t i
= 0; i
< content
.Length() ; i
++)
1087 if (count
== lineNo
)
1089 // Add chars in line then
1092 for (size_t j
= i
; j
< content
.Length(); j
++)
1094 if (content
[j
] == '\n')
1102 if (content
[i
] == '\n') count
++;
1104 return wxEmptyString
;
1107 int wxMacTextControl::GetLineLength(long lineNo
) const
1109 // TODO change this if possible to reflect real lines
1110 wxString content
= GetStringValue() ;
1114 for (size_t i
= 0; i
< content
.Length() ; i
++)
1116 if (count
== lineNo
)
1118 // Count chars in line then
1120 for (size_t j
= i
; j
< content
.Length(); j
++)
1123 if (content
[j
] == '\n') return count
;
1128 if (content
[i
] == '\n') count
++;
1133 // ----------------------------------------------------------------------------
1134 // standard unicode control implementation
1135 // ----------------------------------------------------------------------------
1137 #if TARGET_API_MAC_OSX
1139 wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxWindow
*wxPeer
,
1140 const wxString
& str
,
1142 const wxSize
& size
, long style
)
1144 m_font
= wxPeer
->GetFont() ;
1145 m_windowStyle
= style
;
1146 Rect bounds
= wxMacGetBoundsForControl( wxPeer
, pos
, size
) ;
1148 wxMacConvertNewlines13To10( &st
) ;
1149 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding()) ;
1150 CFStringRef cfr
= cf
;
1151 Boolean isPassword
= ( m_windowStyle
& wxTE_PASSWORD
) != 0 ;
1152 m_valueTag
= isPassword
? kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
;
1153 CreateEditUnicodeTextControl( MAC_WXHWND(wxPeer
->MacGetTopLevelWindowRef()), &bounds
, cfr
, isPassword
, NULL
, &m_controlRef
) ;
1155 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1157 SetData
<Boolean
>( kControlEditTextPart
, kControlEditTextSingleLineTag
, true ) ;
1161 wxMacUnicodeTextControl::~wxMacUnicodeTextControl()
1165 void wxMacUnicodeTextControl::VisibilityChanged(bool shown
)
1167 if ( !(m_windowStyle
& wxTE_MULTILINE
) && shown
)
1169 // work around a refresh issue insofar as not always the entire content is shown even if this would be possible
1170 ControlEditTextSelectionRec sel
;
1171 CFStringRef value
= NULL
;
1173 verify_noerr( GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel
) );
1174 verify_noerr( GetData
<CFStringRef
>( 0, m_valueTag
, &value
) );
1175 verify_noerr( SetData
<CFStringRef
>( 0, m_valueTag
, &value
) );
1176 verify_noerr( SetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel
) );
1178 CFRelease( value
) ;
1181 wxString
wxMacUnicodeTextControl::GetStringValue() const
1184 CFStringRef value
= GetData
<CFStringRef
>(0,m_valueTag
) ;
1187 wxMacCFStringHolder
cf(value
) ;
1188 result
= cf
.AsString() ;
1190 wxMacConvertNewlines10To13( &result
) ;
1193 void wxMacUnicodeTextControl::SetStringValue( const wxString
&str
)
1196 wxMacConvertNewlines13To10( &st
) ;
1197 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1198 verify_noerr( SetData
<CFStringRef
>( 0, m_valueTag
, cf
) ) ;
1200 void wxMacUnicodeTextControl::Copy()
1202 SendHICommand( kHICommandCopy
) ;
1204 void wxMacUnicodeTextControl::Cut()
1206 SendHICommand( kHICommandCut
) ;
1208 void wxMacUnicodeTextControl::Paste()
1210 SendHICommand( kHICommandPaste
) ;
1212 bool wxMacUnicodeTextControl::CanPaste() const
1216 void wxMacUnicodeTextControl::SetEditable(bool editable
)
1218 SetData
<Boolean
>( 0 , kControlEditTextLockedTag
, (Boolean
) !editable
) ;
1220 void wxMacUnicodeTextControl::Remove( long from
, long to
)
1224 void wxMacUnicodeTextControl::GetSelection( long* from
, long* to
) const
1226 ControlEditTextSelectionRec sel
;
1227 verify_noerr(GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel
) ) ;
1228 if ( from
) *from
= sel
.selStart
;
1229 if ( to
) *to
= sel
.selEnd
;
1232 void wxMacUnicodeTextControl::SetSelection( long from
, long to
)
1234 ControlEditTextSelectionRec sel
;
1235 sel
.selStart
= from
;
1237 SetData
<ControlEditTextSelectionRec
>( 0 , kControlEditTextSelectionTag
, &sel
) ;
1240 void wxMacUnicodeTextControl::WriteText(const wxString
& str
)
1243 wxMacConvertNewlines13To10( &st
) ;
1244 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1245 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1246 CFStringRef value
= cf
;
1247 SetData
<CFStringRef
>( 0, kControlEditTextInsertCFStringRefTag
, &value
);
1249 wxString val
= GetStringValue() ;
1251 GetSelection( &start
, &end
) ;
1252 val
.Remove( start
, end
- start
) ;
1253 val
.insert( start
, str
) ;
1254 SetStringValue( val
) ;
1255 SetInsertionPoint( start
+ str
.Length() ) ;
1261 // ----------------------------------------------------------------------------
1262 // MLTE control implementation (common part)
1263 // ----------------------------------------------------------------------------
1265 #if TARGET_API_MAC_OSX == 0
1266 // declaration needed because of one line in the code...
1267 static void TPUpdateVisibility(ControlRef theControl
) ;
1270 // if mlte is on read only , no changes at all are allowed, not even from
1271 // procedural API, in order to allow changes via API all the same we must undo
1272 // the readonly status while we are executing, this class helps to do so
1277 EditHelper( TXNObject txn
)
1279 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1281 TXNGetTXNObjectControls( m_txn
, 1 , tag
, m_data
) ;
1282 if ( m_data
[0].uValue
== kTXNReadOnly
)
1284 TXNControlData data
[] = { { kTXNReadWrite
} } ;
1285 TXNSetTXNObjectControls( m_txn
, false , 1 , tag
, data
) ;
1290 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1291 if ( m_data
[0].uValue
== kTXNReadOnly
)
1293 TXNSetTXNObjectControls( m_txn
, false , 1 , tag
, m_data
) ;
1298 TXNControlData m_data
[1] ;
1301 wxString
wxMacMLTEControl::GetStringValue() const
1305 Size actualSize
= 0;
1309 err
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
1317 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
1318 if ( actualSize
> 0 )
1320 wxChar
*ptr
= NULL
;
1321 #if SIZEOF_WCHAR_T == 2
1322 ptr
= new wxChar
[actualSize
+ 1 ] ;
1323 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
1326 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
1328 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
1329 wxMBConvUTF16BE converter
;
1330 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
1331 ptr
= new wxChar
[noChars
+ 1] ;
1333 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
1335 HUnlock( theText
) ;
1337 ptr
[actualSize
] = 0 ;
1338 result
= wxString( ptr
) ;
1341 DisposeHandle( theText
) ;
1345 err
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1353 actualSize
= GetHandleSize( theText
) ;
1354 if ( actualSize
> 0 )
1357 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
1358 HUnlock( theText
) ;
1360 DisposeHandle( theText
) ;
1364 wxMacConvertNewlines10To13( &result
) ;
1368 void wxMacMLTEControl::SetStringValue( const wxString
&str
)
1371 wxMacConvertNewlines13To10( &st
) ;
1372 EditHelper
help(m_txn
) ;
1374 // wxMacWindowClipper c( this ) ;
1375 #if !TARGET_API_MAC_OSX
1376 // otherwise scrolling might have problems ?
1377 TPUpdateVisibility( m_controlRef
) ;
1379 SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset
) ;
1380 TXNSetSelection( m_txn
, 0, 0);
1381 TXNShowSelection( m_txn
, kTXNShowStart
);
1384 TXNFrameOptions
wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle
)
1386 TXNFrameOptions frameOptions
=
1387 kTXNDontDrawCaretWhenInactiveMask
;
1388 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
1389 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
1391 if ( wxStyle
& wxTE_MULTILINE
)
1393 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
1394 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
1397 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
1398 frameOptions
|= kTXNWantHScrollBarMask
;
1401 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
1402 frameOptions
|= kTXNWantVScrollBarMask
;
1405 frameOptions
|= kTXNSingleLineOnlyMask
;
1407 if ( wxStyle
& wxHSCROLL
)
1408 frameOptions
|= kTXNWantHScrollBarMask
;
1410 return frameOptions
;
1413 void wxMacMLTEControl::AdjustCreationAttributes( const wxColour
&background
, bool visible
)
1415 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
1416 TXNControlData iControlData
[3] = { {false}, {kTXNNoAutoWrap
} };
1418 #if TARGET_API_MAC_OSX
1419 iControlTags
[2] = kTXNVisibilityTag
;
1420 iControlData
[2].uValue
= visible
;
1424 if ( m_windowStyle
& wxTE_MULTILINE
)
1426 if (m_windowStyle
& wxTE_DONTWRAP
)
1427 iControlData
[1].uValue
= kTXNNoAutoWrap
;
1429 iControlData
[1].uValue
= kTXNAutoWrap
;
1432 verify_noerr( TXNSetTXNObjectControls( m_txn
, false, toptag
,
1433 iControlTags
, iControlData
)) ;
1435 // setting the default font
1441 GetThemeFont(kThemeSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
1443 TXNTypeAttributes typeAttr
[] =
1445 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
1446 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
1447 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
1450 verify_noerr( TXNSetTypeAttributes (m_txn
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
1454 if ( m_windowStyle
& wxTE_PASSWORD
)
1457 verify_noerr(TXNEchoMode( m_txn
, c
, 0 , true )) ;
1460 TXNBackground tback
;
1461 tback
.bgType
= kTXNBackgroundTypeRGB
;
1462 tback
.bg
.color
= MAC_WXCOLORREF( background
.GetPixel() );
1463 TXNSetBackground( m_txn
, &tback
);
1466 int wxMacMLTEControl::ConvertAttribute( const wxTextAttr
& style
, TXNTypeAttributes typeAttr
[] )
1468 Str255 fontName
= "\pMonaco" ;
1469 SInt16 fontSize
= 12 ;
1470 Style fontStyle
= normal
;
1472 int attrCounter
= 0 ;
1473 if ( style
.HasFont() )
1475 const wxFont
&font
= style
.GetFont() ;
1476 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1477 fontSize
= font
.GetPointSize() ;
1478 if ( font
.GetUnderlined() )
1479 fontStyle
|= underline
;
1480 if ( font
.GetWeight() == wxBOLD
)
1482 if ( font
.GetStyle() == wxITALIC
)
1483 fontStyle
|= italic
;
1485 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1486 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1487 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1488 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1489 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1490 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1491 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1492 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1493 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1497 if ( style
.HasTextColour() )
1499 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1500 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1501 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1502 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1505 return attrCounter
;
1508 void wxMacMLTEControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
)
1510 EditHelper
help(m_txn
) ;
1511 wxTextAttr
style(wxNullColour
,wxNullColour
,font
) ;
1512 TXNTypeAttributes typeAttr
[4] ;
1513 int attrCounter
= ConvertAttribute( style
, typeAttr
) ;
1514 if ( attrCounter
> 0 )
1516 verify_noerr( TXNSetTypeAttributes ( m_txn
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
1519 void wxMacMLTEControl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1521 EditHelper
help(m_txn
) ;
1522 TXNTypeAttributes typeAttr
[4] ;
1523 int attrCounter
= ConvertAttribute( style
, typeAttr
) ;
1524 if ( attrCounter
> 0 )
1526 verify_noerr( TXNSetTypeAttributes ( m_txn
, attrCounter
, typeAttr
, start
,end
) );
1530 void wxMacMLTEControl::Copy()
1532 ClearCurrentScrap();
1534 TXNConvertToPublicScrap();
1537 void wxMacMLTEControl::Cut()
1539 ClearCurrentScrap();
1541 TXNConvertToPublicScrap();
1544 void wxMacMLTEControl::Paste()
1546 TXNConvertFromPublicScrap();
1550 bool wxMacMLTEControl::CanPaste() const
1552 return TXNIsScrapPastable() ;
1555 void wxMacMLTEControl::SetEditable(bool editable
)
1557 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1558 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1559 TXNSetTXNObjectControls( m_txn
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1562 long wxMacMLTEControl::GetLastPosition() const
1564 long actualsize
= 0 ;
1567 OSErr err
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1575 actualsize
= GetHandleSize( theText
) ;
1576 DisposeHandle( theText
) ;
1582 void wxMacMLTEControl::Replace( long from
, long to
, const wxString str
)
1584 wxString value
= str
;
1585 wxMacConvertNewlines13To10( &value
) ;
1587 EditHelper
help( m_txn
) ;
1589 TXNSetSelection(m_txn
, from
, to
) ;
1591 SetTXNData( str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1594 void wxMacMLTEControl::Remove( long from
, long to
)
1596 EditHelper
help( m_txn
) ;
1598 TXNSetSelection(m_txn
, from
, to
) ;
1602 void wxMacMLTEControl::GetSelection( long* from
, long* to
) const
1604 TXNGetSelection( m_txn
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1607 void wxMacMLTEControl::SetSelection( long from
, long to
)
1609 /* change the selection */
1610 if ((from
== -1) && (to
== -1))
1611 TXNSelectAll(m_txn
);
1613 TXNSetSelection( m_txn
, from
, to
);
1614 TXNShowSelection( m_txn
, kTXNShowStart
);
1617 void wxMacMLTEControl::WriteText(const wxString
& str
)
1619 EditHelper
helper( m_txn
) ;
1621 wxMacConvertNewlines13To10( &st
) ;
1623 long start
, end
, dummy
;
1624 GetSelection( &start
, &dummy
) ;
1625 SetTXNData( st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1626 GetSelection( &dummy
, &end
) ;
1627 // TODO SetStyle( start , end , GetDefaultStyle() ) ;
1630 void wxMacMLTEControl::Clear()
1632 EditHelper
st(m_txn
) ;
1633 TXNSetSelection( m_txn
, kTXNStartOffset
, kTXNEndOffset
) ;
1637 bool wxMacMLTEControl::CanUndo() const
1639 return TXNCanUndo( m_txn
, NULL
) ;
1642 void wxMacMLTEControl::Undo()
1647 bool wxMacMLTEControl::CanRedo() const
1649 return TXNCanRedo( m_txn
, NULL
) ;
1652 void wxMacMLTEControl::Redo()
1657 int wxMacMLTEControl::GetNumberOfLines() const
1659 ItemCount lines
= 0 ;
1660 TXNGetLineCount(m_txn
, &lines
) ;
1664 long wxMacMLTEControl::XYToPosition(long x
, long y
) const
1668 long lastpos
= GetLastPosition() ;
1670 // TODO find a better implementation : while we can get the
1671 // line metrics of a certain line, we don't get its starting
1672 // position, so it would probably be rather a binary search
1673 // for the start position
1676 int lastHeight
= 0 ;
1679 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1681 if ( y
== ypos
&& x
== xpos
)
1684 TXNOffsetToPoint( m_txn
, n
, &curpt
);
1686 if ( curpt
.v
> lastHeight
)
1691 lastHeight
= curpt
.v
;
1699 bool wxMacMLTEControl::PositionToXY(long pos
, long *x
, long *y
) const
1703 long lastpos
= GetLastPosition() ;
1708 if ( pos
<= lastpos
)
1710 // TODO find a better implementation : while we can get the
1711 // line metrics of a certain line, we don't get its starting
1712 // position, so it would probably be rather a binary search
1713 // for the start position
1716 int lastHeight
= 0 ;
1719 for ( n
= 0 ; n
<= (ItemCount
) pos
; ++n
)
1721 TXNOffsetToPoint(m_txn
, n
, &curpt
);
1723 if ( curpt
.v
> lastHeight
)
1728 lastHeight
= curpt
.v
;
1733 if ( y
) *y
= ypos
;
1734 if ( x
) *x
= xpos
;
1740 void wxMacMLTEControl::ShowPosition( long pos
)
1742 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1746 TXNOffset selstart
, selend
;
1747 TXNGetSelection( m_txn
, &selstart
, &selend
) ;
1748 TXNOffsetToPoint( m_txn
, selstart
, ¤t
);
1749 TXNOffsetToPoint( m_txn
, pos
, &desired
);
1750 //TODO use HIPoints for 10.3 and above
1751 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1753 OSErr theErr
= noErr
;
1754 SInt32 dv
= desired
.v
- current
.v
;
1755 SInt32 dh
= desired
.h
- current
.h
;
1756 TXNShowSelection( m_txn
, true ) ;
1757 theErr
= TXNScroll( m_txn
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1758 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1764 void wxMacMLTEControl::SetTXNData( const wxString
& st
, TXNOffset start
, TXNOffset end
)
1767 #if SIZEOF_WCHAR_T == 2
1768 size_t len
= st
.Len() ;
1769 TXNSetData( m_txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
1772 wxMBConvUTF16BE converter
;
1773 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
1774 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
1775 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
1776 TXNSetData( m_txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
1781 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1782 TXNSetData( m_txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
1788 wxString
wxMacMLTEControl::GetLineText(long lineNo
) const
1792 wxString content
= GetStringValue() ;
1794 if ( lineNo
< GetNumberOfLines() )
1796 // TODO find a better implementation : while we can get the
1797 // line metrics of a certain line, we don't get its starting
1798 // position, so it would probably be rather a binary search
1799 // for the start position
1802 int lastHeight
= 0 ;
1803 long lastpos
= GetLastPosition() ;
1806 for ( n
= 0 ; n
<= (ItemCount
)lastpos
; ++n
)
1808 TXNOffsetToPoint( m_txn
, n
, &curpt
);
1810 if ( curpt
.v
> lastHeight
)
1812 if ( ypos
== lineNo
)
1818 lastHeight
= curpt
.v
;
1822 if ( ypos
== lineNo
)
1823 line
+= content
[n
] ;
1831 int wxMacMLTEControl::GetLineLength(long lineNo
) const
1834 if ( lineNo
< GetNumberOfLines() )
1836 // TODO find a better implementation : while we can get the
1837 // line metrics of a certain line, we don't get its starting
1838 // position, so it would probably be rather a binary search
1839 // for the start position
1842 int lastHeight
= 0 ;
1843 long lastpos
= GetLastPosition() ;
1846 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1848 TXNOffsetToPoint( m_txn
, n
, &curpt
);
1850 if ( curpt
.v
> lastHeight
)
1852 if ( ypos
== lineNo
)
1858 lastHeight
= curpt
.v
;
1868 // ----------------------------------------------------------------------------
1869 // MLTE control implementation (classic part)
1870 // ----------------------------------------------------------------------------
1872 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
1873 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
1874 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
1875 // an alternate path for carbon key events that routes automatically into the same wx flow of events
1879 /* kmUPTextPart is the part code we return to indicate the user has clicked
1880 in the text area of our control */
1881 #define kmUPTextPart 1
1884 /* routines for using existing user pane controls.
1885 These routines are useful for cases where you would like to use an
1886 existing user pane control in, say, a dialog window as a scrolling
1889 /* Utility Routines */
1891 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
1892 routine. In our focus switching routine this part code is understood
1893 as meaning 'the user has clicked in the control and we need to switch
1894 the current focus to ourselves before we can continue'. */
1895 #define kUserClickedToFocusPart 100
1897 /* STPTextPaneVars is a structure used for storing the the mUP Control's
1898 internal variables and state information. A handle to this record is
1899 stored in the pane control's reference value field using the
1900 SetControlReference routine. */
1902 class STPTextPaneVars
{
1904 /* OS records referenced */
1905 TXNObject fTXNRec
; /* the txn record */
1906 TXNFrameID fTXNFrame
; /* the txn frame ID */
1907 ControlRef fUserPaneRec
; /* handle to the user pane control */
1908 WindowPtr fOwner
; /* window containing control */
1909 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
1911 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
1912 Boolean fIsActive
; /* true while the control is drawn in the active state */
1913 Boolean fTXNObjectActive
; /* reflects the activation state of the text edit record */
1914 Boolean fFocusDrawState
; /* true if focus is drawn (default: true) */
1915 /* calculated locations */
1916 Rect fRBounds
; /* control bounds */
1917 Rect fRTextArea
; /* area where the text is drawn */
1918 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
1919 Rect fRTextOutline
; /* rectangle used to draw the border */
1920 RgnHandle fRTextOutlineRegion
; /* background region for the text, erased before calling TEUpdate */
1921 /* our focus advance override routine */
1922 EventHandlerUPP handlerUPP
;
1923 EventHandlerRef handlerRef
;
1929 /* Univerals Procedure Pointer variables used by the
1930 mUP Control. These variables are set up
1931 the first time that mUPOpenControl is called. */
1932 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
1933 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
1934 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
1935 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
1936 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
1937 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
1938 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
1940 // one place for calculating all
1941 static void TPCalculateBounds(STPTextPaneVars
*varsp
, const Rect
& bounds
)
1943 SetRect(&varsp
->fRBounds
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1944 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1945 // eventually make TextOutline inset 1,1
1946 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1947 if ( !varsp
->fNoBorders
)
1949 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
1950 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
1954 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
1955 bounds
.right
, bounds
.bottom
);
1959 OSStatus
MLTESetObjectVisibility( STPTextPaneVars
*varsp
, Boolean vis
, long wxStyle
)
1961 OSStatus err
= noErr
;
1962 #if TARGET_API_MAC_OSX
1963 TXNControlTag iControlTags
[1] = { kTXNVisibilityTag
};
1964 TXNControlData iControlData
[1] = {{ vis
}};
1965 err
= ::TXNSetTXNObjectControls( varsp
->fTXNRec
, false, 1, iControlTags
, iControlData
);
1967 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
1968 if ( vis
&& textctrl
)
1971 UMAGetControlBoundsInWindowCoords( varsp
->fUserPaneRec
, &bounds
);
1972 TPCalculateBounds( varsp
, bounds
) ;
1973 wxMacWindowClipper
cl(textctrl
) ;
1974 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
1975 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
1976 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
1981 // make sure we don't miss changes as carbon events are not available for these under classic
1982 static void TPUpdateVisibility(ControlRef theControl
) {
1983 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
1984 if ( textctrl
== NULL
)
1987 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
1990 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
1991 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
1993 // invalidate old position
1994 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
1995 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
1997 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
2000 Rect oldBounds
= varsp
->fRBounds
;
2001 TPCalculateBounds( varsp
, bounds
) ;
2002 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
2003 if ( varsp
->fVisible
)
2005 wxMacWindowClipper
cl(textctrl
) ;
2006 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
2007 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
2009 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
2010 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
2014 // make correct activations
2015 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
2017 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
2018 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
2020 varsp
->fTXNObjectActive
= setActive
;
2021 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
2022 if (varsp
->fInFocus
)
2023 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
2027 // update focus outlines
2028 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
2031 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
2033 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
2034 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
2038 // update TXN focus state
2039 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
2040 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
2042 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
2043 varsp
->fInFocus
= setFocus
;
2044 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
2049 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
2050 /* set up our globals */
2052 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2053 if ( textctrl
== NULL
)
2055 TPUpdateVisibility( theControl
) ;
2057 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2058 if ( textctrl
->MacIsReallyShown() )
2060 wxMacWindowClipper
clipper( textctrl
) ;
2061 TXNDraw(varsp
->fTXNRec
, NULL
);
2062 if ( !varsp
->fNoBorders
)
2063 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
2064 TPRedrawFocusOutline( varsp
) ;
2070 /* TPPaneHitTestProc is called when the control manager would
2071 like to determine what part of the control the mouse resides over.
2072 We also call this routine from our tracking proc to determine how
2073 to handle mouse clicks. */
2074 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
2075 ControlPartCode result
;
2076 /* set up our locals and lock down our globals*/
2078 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2079 if ( textctrl
== NULL
)
2081 TPUpdateVisibility( theControl
) ;
2082 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2083 if (textctrl
->MacIsReallyShown() )
2085 if (PtInRect(where
, &varsp
->fRBounds
))
2086 result
= kmUPTextPart
;
2089 // sometimes we get the coords also in control local coordinates, therefore test again
2090 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
2093 textctrl
->MacClientToRootWindow( &x
, &y
) ;
2097 if (PtInRect(where
, &varsp
->fRBounds
))
2098 result
= kmUPTextPart
;
2110 /* TPPaneTrackingProc is called when the mouse is being held down
2111 over our control. This routine handles clicks in the text area
2112 and in the scroll bar. */
2113 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
2115 ControlPartCode partCodeResult
;
2116 /* make sure we have some variables... */
2118 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2119 if ( textctrl
== NULL
)
2121 TPUpdateVisibility( theControl
) ;
2122 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2123 if (textctrl
->MacIsReallyShown() )
2125 /* we don't do any of these functions unless we're in focus */
2126 if ( ! varsp
->fInFocus
) {
2128 owner
= GetControlOwner(theControl
);
2129 ClearKeyboardFocus(owner
);
2130 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
2132 /* find the location for the click */
2133 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
2134 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
2137 textctrl
->MacClientToRootWindow( &x
, &y
) ;
2142 switch (TPPaneHitTestProc(theControl
, startPt
))
2145 /* handle clicks in the text part */
2148 wxMacWindowClipper
clipper( textctrl
) ;
2151 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
2152 TXNClick( varsp
->fTXNRec
, &rec
);
2159 return partCodeResult
;
2163 /* TPPaneIdleProc is our user pane idle routine. When our text field
2164 is active and in focus, we use this routine to set the cursor. */
2165 static pascal void TPPaneIdleProc(ControlRef theControl
) {
2167 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2168 if ( textctrl
== NULL
)
2170 TPUpdateVisibility( theControl
) ;
2171 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2172 if (textctrl
->MacIsReallyShown()) {
2173 /* if we're not active, then we have nothing to say about the cursor */
2174 if (varsp
->fIsActive
) {
2178 wxMacWindowClipper
clipper( textctrl
) ;
2180 /* there's a 'focus thing' and an 'unfocused thing' */
2181 if (varsp
->fInFocus
) {
2182 /* flash the cursor */
2183 SetPort(varsp
->fDrawingEnvironment
);
2184 TXNIdle(varsp
->fTXNRec
);
2185 /* set the cursor */
2186 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
2188 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
2189 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
2194 // SetThemeCursor(kThemeArrowCursor);
2197 /* if it's in our bounds, set the cursor */
2198 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
2199 if (PtInRect(mousep
, &bounds
))
2201 // SetThemeCursor(kThemeArrowCursor);
2209 /* TPPaneKeyDownProc is called whenever a keydown event is directed
2210 at our control. Here, we direct the keydown event to the text
2211 edit record and redraw the scroll bar and text field as appropriate. */
2212 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
2213 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
2215 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2216 if ( textctrl
== NULL
)
2218 TPUpdateVisibility( theControl
) ;
2220 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2221 if (varsp
->fInFocus
)
2223 /* turn autoscrolling on and send the key event to text edit */
2224 wxMacWindowClipper
clipper( textctrl
) ;
2226 memset( &ev
, 0 , sizeof( ev
) ) ;
2228 ev
.modifiers
= modifiers
;
2229 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
2230 TXNKeyDown( varsp
->fTXNRec
, &ev
);
2232 return kControlEntireControl
;
2236 /* TPPaneActivateProc is called when the window containing
2237 the user pane control receives activate events. Here, we redraw
2238 the control and it's text as necessary for the activation state. */
2239 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
2241 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2243 if ( textctrl
== NULL
)
2245 TPUpdateVisibility( theControl
) ;
2247 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2249 varsp
->fIsActive
= activating
;
2250 wxMacWindowClipper
clipper( textctrl
) ;
2251 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
2252 /* redraw the frame */
2253 if ( textctrl
->MacIsReallyShown() )
2255 if ( !varsp
->fNoBorders
)
2256 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
2257 TPRedrawFocusOutline( varsp
) ;
2262 /* TPPaneFocusProc is called when every the focus changes to or
2263 from our control. Herein, switch the focus appropriately
2264 according to the parameters and redraw the control as
2266 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
2267 ControlPartCode focusResult
;
2269 focusResult
= kControlFocusNoPart
;
2270 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2271 if ( textctrl
== NULL
)
2273 TPUpdateVisibility( theControl
) ;
2274 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2275 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
2276 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
2277 and kControlFocusNextPart will be received. When the user clicks in our field
2278 and it is not the current focus, then the constant kUserClickedToFocusPart will
2279 be received. The constant kControlFocusNoPart will be received when our control
2280 is the current focus and the user clicks in another control. In your focus routine,
2281 you should respond to these codes as follows:
2283 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
2284 the control and the focus rectangle as necessary.
2286 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
2287 depending on its current state. redraw the control and the focus rectangle
2288 as appropriate for the new focus state. If the focus state is 'off', return the constant
2289 kControlFocusNoPart, otherwise return a non-zero part code.
2290 kUserClickedToFocusPart - is a constant defined for this example. You should
2291 define your own value for handling click-to-focus type events. */
2292 /* calculate the next highlight state */
2295 case kControlFocusNoPart
:
2296 TPFocusPaneText(varsp
, false);
2297 focusResult
= kControlFocusNoPart
;
2299 case kUserClickedToFocusPart
:
2300 TPFocusPaneText(varsp
, true);
2303 case kControlFocusPrevPart
:
2304 case kControlFocusNextPart
:
2305 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
2306 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
2309 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
2310 /* redraw the text fram and focus rectangle to indicate the
2312 if ( textctrl
->MacIsReallyShown() )
2314 wxMacWindowClipper
c( textctrl
) ;
2315 if ( !varsp
->fNoBorders
)
2316 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
2317 TPRedrawFocusOutline( varsp
) ;
2322 wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxWindow
*wxPeer
,
2323 const wxString
& str
,
2325 const wxSize
& size
, long style
)
2327 m_font
= wxPeer
->GetFont() ;
2328 m_windowStyle
= style
;
2329 Rect bounds
= wxMacGetBoundsForControl( wxPeer
, pos
, size
) ;
2331 wxMacConvertNewlines13To10( &st
) ;
2333 wxMacConvertNewlines13To10( &st
) ;
2337 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
2338 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
2339 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
2340 /* create the control */
2342 verify_noerr( ::CreateUserPaneControl( MAC_WXHWND(wxPeer
->GetParent()->MacGetTopLevelWindowRef()), &bounds
, featurSet
, &m_controlRef
) );
2345 // wxMacWindowClipper c(wxPeer) ;
2349 if ( wxPeer
->MacIsReallyShown() )
2350 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , style
) ;
2353 // wxMacWindowClipper clipper( wxPeer ) ;
2355 TPUpdateVisibility( m_controlRef
) ;
2357 SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset
) ;
2359 TXNSetSelection( m_txn
, 0, 0);
2360 TXNShowSelection( m_txn
, kTXNShowStart
);
2363 AdjustCreationAttributes( *wxWHITE
, true ) ;
2366 wxMacMLTEClassicControl::~wxMacMLTEClassicControl()
2368 // SetControlReference(m_controlRef , 0) ;
2369 TXNDeleteObject(m_txn
);
2373 void wxMacMLTEClassicControl::VisibilityChanged(bool shown
)
2375 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, shown
, m_windowStyle
) ;
2377 InvalWindowRect( GetControlOwner( m_controlRef
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
2380 OSStatus
wxMacMLTEClassicControl::DoCreate()
2383 WindowRef theWindow
;
2385 OSStatus err
= noErr
;
2387 /* set up our globals */
2388 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
2389 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
2390 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
2391 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
2392 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
2393 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
2394 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
2396 /* allocate our private storage */
2397 m_macTXNvars
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
2399 /* set the initial settings for our private data */
2400 m_macTXNvars
->fMultiline
= m_windowStyle
& wxTE_MULTILINE
;
2401 m_macTXNvars
->fNoBorders
= m_windowStyle
& wxNO_BORDER
;
2402 m_macTXNvars
->fInFocus
= false;
2403 m_macTXNvars
->fIsActive
= true;
2404 m_macTXNvars
->fTXNObjectActive
= false;
2405 m_macTXNvars
->fFocusDrawState
= false ;
2406 m_macTXNvars
->fUserPaneRec
= m_controlRef
;
2407 m_macTXNvars
->fVisible
= true ;
2409 theWindow
= m_macTXNvars
->fOwner
= GetControlOwner(m_controlRef
);
2411 m_macTXNvars
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
2413 /* set up the user pane procedures */
2414 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
2415 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
2416 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
2417 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
2418 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
2419 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
2420 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
2422 /* calculate the rectangles used by the control */
2423 UMAGetControlBoundsInWindowCoords(m_controlRef
, &bounds
);
2424 m_macTXNvars
->fRTextOutlineRegion
= NewRgn() ;
2425 TPCalculateBounds( m_macTXNvars
, bounds
) ;
2427 /* set up the drawing environment */
2428 SetPort(m_macTXNvars
->fDrawingEnvironment
);
2430 /* create the new edit field */
2432 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( m_windowStyle
) ;
2434 verify_noerr(TXNNewObject(NULL
, m_macTXNvars
->fOwner
, &m_macTXNvars
->fRTextArea
,
2436 kTXNTextEditStyleFrameType
,
2438 kTXNSystemDefaultEncoding
,
2439 &m_macTXNvars
->fTXNRec
, &m_macTXNvars
->fTXNFrame
, (TXNObjectRefcon
) m_macTXNvars
));
2440 m_txn
= m_macTXNvars
->fTXNRec
;
2442 /* perform final activations and setup for our text field. Here,
2443 we assume that the window is going to be the 'active' window. */
2444 TPActivatePaneText(m_macTXNvars
, m_macTXNvars
->fIsActive
&& m_macTXNvars
->fInFocus
);
2449 // ----------------------------------------------------------------------------
2450 // MLTE control implementation (OSX part)
2451 // ----------------------------------------------------------------------------
2453 #if TARGET_API_MAC_OSX
2455 wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxWindow
*wxPeer
,
2456 const wxString
& str
,
2458 const wxSize
& size
, long style
)
2460 m_font
= wxPeer
->GetFont() ;
2461 m_windowStyle
= style
;
2462 Rect bounds
= wxMacGetBoundsForControl( wxPeer
, pos
, size
) ;
2464 wxMacConvertNewlines13To10( &st
) ;
2466 HIRect hr
= { bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
} ;
2468 m_scrollView
= NULL
;
2469 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( style
) ;
2470 if ( frameOptions
& (kTXNWantVScrollBarMask
|kTXNWantHScrollBarMask
) )
2472 HIScrollViewCreate(( frameOptions
& kTXNWantHScrollBarMask
? kHIScrollViewOptionsHorizScroll
: 0) |
2473 ( frameOptions
& kTXNWantVScrollBarMask
? kHIScrollViewOptionsVertScroll
: 0 ) , &m_scrollView
) ;
2475 HIViewSetFrame( m_scrollView
, &hr
);
2476 HIViewSetVisible( m_scrollView
, true );
2480 HITextViewCreate( NULL
, 0, frameOptions
, &m_textView
) ;
2481 m_txn
= HITextViewGetTXNObject( m_textView
) ;
2482 HIViewSetVisible( m_textView
, true ) ;
2485 HIViewAddSubview( m_scrollView
, m_textView
) ;
2486 m_controlRef
= m_scrollView
;
2487 wxPeer
->MacInstallEventHandler( (WXWidget
) m_textView
) ;
2491 HIViewSetFrame( m_textView
, &hr
);
2492 m_controlRef
= m_textView
;
2496 SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset
) ;
2498 TXNSetSelection( m_txn
, 0, 0);
2499 TXNShowSelection( m_txn
, kTXNShowStart
);
2501 AdjustCreationAttributes( *wxWHITE
, true ) ;
2504 OSStatus
wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart
)
2506 return SetKeyboardFocus( GetControlOwner( m_textView
) ,
2507 m_textView
, focusPart
) ;
2510 bool wxMacMLTEHIViewControl::HasFocus() const
2512 ControlRef control
;
2513 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2514 return control
== m_textView
;
2517 bool wxMacMLTEHIViewControl::NeedsFocusRect() const
2519 return m_windowStyle
& wxNO_BORDER
? false : true;
2524 #endif // wxUSE_TEXTCTRL