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 switch( m_windowVariant
)
634 case wxWINDOW_VARIANT_NORMAL
:
637 case wxWINDOW_VARIANT_SMALL
:
640 case wxWINDOW_VARIANT_MINI
:
648 if ( HasFlag(wxNO_BORDER
) )
651 if ( m_windowStyle
& wxTE_MULTILINE
)
656 return wxSize(wText
, hText
);
659 // ----------------------------------------------------------------------------
661 // ----------------------------------------------------------------------------
663 void wxTextCtrl::Undo()
671 void wxTextCtrl::Redo()
679 bool wxTextCtrl::CanUndo() const
685 return GetPeer()->CanUndo() ;
688 bool wxTextCtrl::CanRedo() const
694 return GetPeer()->CanRedo() ;
697 void wxTextCtrl::MarkDirty()
702 void wxTextCtrl::DiscardEdits()
707 int wxTextCtrl::GetNumberOfLines() const
709 return GetPeer()->GetNumberOfLines() ;
712 long wxTextCtrl::XYToPosition(long x
, long y
) const
714 return GetPeer()->XYToPosition( x
, y
) ;
717 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
719 return GetPeer()->PositionToXY(pos
, x
, y
) ;
722 void wxTextCtrl::ShowPosition(long pos
)
724 return GetPeer()->ShowPosition(pos
) ;
727 int wxTextCtrl::GetLineLength(long lineNo
) const
729 return GetPeer()->GetLineLength(lineNo
) ;
732 wxString
wxTextCtrl::GetLineText(long lineNo
) const
734 return GetPeer()->GetLineText(lineNo
) ;
741 void wxTextCtrl::Command(wxCommandEvent
& event
)
743 SetValue (event
.GetString());
744 ProcessCommand (event
);
747 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
749 // By default, load the first file into the text window.
750 if (event
.GetNumberOfFiles() > 0)
752 LoadFile(event
.GetFiles()[0]);
756 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
758 int key
= event
.GetKeyCode() ;
759 bool eat_key
= false ;
761 if ( key
== 'c' && event
.MetaDown() )
768 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
769 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
770 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
777 // assume that any key not processed yet is going to modify the control
780 if ( key
== 'v' && event
.MetaDown() )
786 if ( key
== 'x' && event
.MetaDown() )
795 if (m_windowStyle
& wxPROCESS_ENTER
)
797 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
798 event
.SetEventObject( this );
799 event
.SetString( GetValue() );
800 if ( GetEventHandler()->ProcessEvent(event
) )
803 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
805 wxWindow
*parent
= GetParent();
806 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
807 parent
= parent
->GetParent() ;
809 if ( parent
&& parent
->GetDefaultItem() )
811 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
813 if ( def
&& def
->IsEnabled() )
815 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
816 event
.SetEventObject(def
);
822 // this will make wxWidgets eat the ENTER key so that
823 // we actually prevent line wrapping in a single line
831 if ( !(m_windowStyle
& wxTE_PROCESS_TAB
))
834 if (!event
.ShiftDown())
835 flags
|= wxNavigationKeyEvent::IsForward
;
836 if (event
.ControlDown())
837 flags
|= wxNavigationKeyEvent::WinChange
;
843 // This is necessary (don't know why) or the tab will not
845 WriteText(wxT("\t"));
853 // perform keystroke handling
854 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
855 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
859 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
861 EventRecord
*ev
= &rec
;
864 keychar
= short(ev
->message
& charCodeMask
);
865 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
867 m_peer
->HandleKey( keycode
, keychar
, ev
->modifiers
) ;
871 if ( ( key
>= 0x20 && key
< WXK_START
) ||
876 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
877 event1
.SetString( GetValue() ) ;
878 event1
.SetEventObject( this );
879 wxPostEvent(GetEventHandler(),event1
);
883 // ----------------------------------------------------------------------------
884 // standard handlers for standard edit menu events
885 // ----------------------------------------------------------------------------
887 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
892 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
897 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
902 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
907 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
912 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
914 event
.Enable( CanCut() );
917 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
919 event
.Enable( CanCopy() );
922 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
924 event
.Enable( CanPaste() );
927 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
929 event
.Enable( CanUndo() );
932 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
934 event
.Enable( CanRedo() );
937 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
942 // user pane implementation
944 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
948 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
950 return kControlNoPart
;
953 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
955 return kControlNoPart
;
958 void wxTextCtrl::MacControlUserPaneIdleProc()
962 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
964 return kControlNoPart
;
967 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
971 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
973 return kControlNoPart
;
976 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)
980 // ----------------------------------------------------------------------------
981 // implementation base class
982 // ----------------------------------------------------------------------------
984 wxMacTextControl::wxMacTextControl()
988 wxMacTextControl::~wxMacTextControl()
992 void wxMacTextControl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
996 void wxMacTextControl::Copy()
1000 void wxMacTextControl::Cut()
1004 void wxMacTextControl::Paste()
1008 bool wxMacTextControl::CanPaste() const
1013 void wxMacTextControl::SetEditable(bool editable
)
1017 long wxMacTextControl::GetLastPosition() const
1019 return GetStringValue().Length() ;
1022 void wxMacTextControl::Replace( long from
, long to
, const wxString str
)
1026 void wxMacTextControl::Clear()
1028 SetStringValue( wxEmptyString
) ;
1031 bool wxMacTextControl::CanUndo() const
1036 void wxMacTextControl::Undo() { }
1038 bool wxMacTextControl::CanRedo() const
1043 void wxMacTextControl::Redo()
1047 long wxMacTextControl::XYToPosition(long x
, long y
) const
1052 bool wxMacTextControl::PositionToXY(long pos
, long *x
, long *y
) const
1057 void wxMacTextControl::ShowPosition( long WXUNUSED(pos
) )
1061 int wxMacTextControl::GetNumberOfLines() const
1063 ItemCount lines
= 0 ;
1064 wxString content
= GetStringValue() ;
1066 for (size_t i
= 0; i
< content
.Length() ; i
++)
1068 if (content
[i
] == '\r') lines
++;
1073 wxString
wxMacTextControl::GetLineText(long lineNo
) const
1075 // TODO change this if possible to reflect real lines
1076 wxString content
= GetStringValue() ;
1080 for (size_t i
= 0; i
< content
.Length() ; i
++)
1082 if (count
== lineNo
)
1084 // Add chars in line then
1087 for (size_t j
= i
; j
< content
.Length(); j
++)
1089 if (content
[j
] == '\n')
1097 if (content
[i
] == '\n') count
++;
1099 return wxEmptyString
;
1102 int wxMacTextControl::GetLineLength(long lineNo
) const
1104 // TODO change this if possible to reflect real lines
1105 wxString content
= GetStringValue() ;
1109 for (size_t i
= 0; i
< content
.Length() ; i
++)
1111 if (count
== lineNo
)
1113 // Count chars in line then
1115 for (size_t j
= i
; j
< content
.Length(); j
++)
1118 if (content
[j
] == '\n') return count
;
1123 if (content
[i
] == '\n') count
++;
1128 // ----------------------------------------------------------------------------
1129 // standard unicode control implementation
1130 // ----------------------------------------------------------------------------
1132 #if TARGET_API_MAC_OSX
1134 wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxWindow
*wxPeer
,
1135 const wxString
& str
,
1137 const wxSize
& size
, long style
)
1139 m_font
= wxPeer
->GetFont() ;
1140 m_windowStyle
= style
;
1141 Rect bounds
= wxMacGetBoundsForControl( wxPeer
, pos
, size
) ;
1143 wxMacConvertNewlines13To10( &st
) ;
1144 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding()) ;
1145 CFStringRef cfr
= cf
;
1146 Boolean isPassword
= ( m_windowStyle
& wxTE_PASSWORD
) != 0 ;
1147 m_valueTag
= isPassword
? kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
;
1148 CreateEditUnicodeTextControl( MAC_WXHWND(wxPeer
->MacGetTopLevelWindowRef()), &bounds
, cfr
, isPassword
, NULL
, &m_controlRef
) ;
1150 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1152 SetData
<Boolean
>( kControlEditTextPart
, kControlEditTextSingleLineTag
, true ) ;
1156 wxMacUnicodeTextControl::~wxMacUnicodeTextControl()
1160 void wxMacUnicodeTextControl::VisibilityChanged(bool shown
)
1162 if ( !(m_windowStyle
& wxTE_MULTILINE
) && shown
)
1164 // work around a refresh issue insofar as not always the entire content is shown even if this would be possible
1165 ControlEditTextSelectionRec sel
;
1166 CFStringRef value
= NULL
;
1168 verify_noerr( GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel
) );
1169 verify_noerr( GetData
<CFStringRef
>( 0, m_valueTag
, &value
) );
1170 verify_noerr( SetData
<CFStringRef
>( 0, m_valueTag
, &value
) );
1171 verify_noerr( SetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel
) );
1173 CFRelease( value
) ;
1176 wxString
wxMacUnicodeTextControl::GetStringValue() const
1179 CFStringRef value
= GetData
<CFStringRef
>(0,m_valueTag
) ;
1182 wxMacCFStringHolder
cf(value
) ;
1183 result
= cf
.AsString() ;
1185 wxMacConvertNewlines10To13( &result
) ;
1188 void wxMacUnicodeTextControl::SetStringValue( const wxString
&str
)
1191 wxMacConvertNewlines13To10( &st
) ;
1192 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1193 verify_noerr( SetData
<CFStringRef
>( 0, m_valueTag
, cf
) ) ;
1195 void wxMacUnicodeTextControl::Copy()
1197 SendHICommand( kHICommandCopy
) ;
1199 void wxMacUnicodeTextControl::Cut()
1201 SendHICommand( kHICommandCut
) ;
1203 void wxMacUnicodeTextControl::Paste()
1205 SendHICommand( kHICommandPaste
) ;
1207 bool wxMacUnicodeTextControl::CanPaste() const
1211 void wxMacUnicodeTextControl::SetEditable(bool editable
)
1213 SetData
<Boolean
>( 0 , kControlEditTextLockedTag
, (Boolean
) !editable
) ;
1215 void wxMacUnicodeTextControl::Remove( long from
, long to
)
1219 void wxMacUnicodeTextControl::GetSelection( long* from
, long* to
) const
1221 ControlEditTextSelectionRec sel
;
1222 verify_noerr(GetData
<ControlEditTextSelectionRec
>( 0, kControlEditTextSelectionTag
, &sel
) ) ;
1223 if ( from
) *from
= sel
.selStart
;
1224 if ( to
) *to
= sel
.selEnd
;
1227 void wxMacUnicodeTextControl::SetSelection( long from
, long to
)
1229 ControlEditTextSelectionRec sel
;
1230 sel
.selStart
= from
;
1232 SetData
<ControlEditTextSelectionRec
>( 0 , kControlEditTextSelectionTag
, &sel
) ;
1235 void wxMacUnicodeTextControl::WriteText(const wxString
& str
)
1238 wxMacConvertNewlines13To10( &st
) ;
1239 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1240 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1241 CFStringRef value
= cf
;
1242 SetData
<CFStringRef
>( 0, kControlEditTextInsertCFStringRefTag
, &value
);
1244 wxString val
= GetStringValue() ;
1246 GetSelection( &start
, &end
) ;
1247 val
.Remove( start
, end
- start
) ;
1248 val
.insert( start
, str
) ;
1249 SetStringValue( val
) ;
1250 SetInsertionPoint( start
+ str
.Length() ) ;
1256 // ----------------------------------------------------------------------------
1257 // MLTE control implementation (common part)
1258 // ----------------------------------------------------------------------------
1260 #if TARGET_API_MAC_OSX == 0
1261 // declaration needed because of one line in the code...
1262 static void TPUpdateVisibility(ControlRef theControl
) ;
1265 // if mlte is on read only , no changes at all are allowed, not even from
1266 // procedural API, in order to allow changes via API all the same we must undo
1267 // the readonly status while we are executing, this class helps to do so
1272 EditHelper( TXNObject txn
)
1274 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1276 TXNGetTXNObjectControls( m_txn
, 1 , tag
, m_data
) ;
1277 if ( m_data
[0].uValue
== kTXNReadOnly
)
1279 TXNControlData data
[] = { { kTXNReadWrite
} } ;
1280 TXNSetTXNObjectControls( m_txn
, false , 1 , tag
, data
) ;
1285 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1286 if ( m_data
[0].uValue
== kTXNReadOnly
)
1288 TXNSetTXNObjectControls( m_txn
, false , 1 , tag
, m_data
) ;
1293 TXNControlData m_data
[1] ;
1296 wxString
wxMacMLTEControl::GetStringValue() const
1300 Size actualSize
= 0;
1304 err
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
1312 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
1313 if ( actualSize
> 0 )
1315 wxChar
*ptr
= NULL
;
1316 #if SIZEOF_WCHAR_T == 2
1317 ptr
= new wxChar
[actualSize
+ 1 ] ;
1318 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
1321 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
1323 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
1324 wxMBConvUTF16BE converter
;
1325 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
1326 ptr
= new wxChar
[noChars
+ 1] ;
1328 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
1330 HUnlock( theText
) ;
1332 ptr
[actualSize
] = 0 ;
1333 result
= wxString( ptr
) ;
1336 DisposeHandle( theText
) ;
1340 err
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1348 actualSize
= GetHandleSize( theText
) ;
1349 if ( actualSize
> 0 )
1352 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
1353 HUnlock( theText
) ;
1355 DisposeHandle( theText
) ;
1359 wxMacConvertNewlines10To13( &result
) ;
1363 void wxMacMLTEControl::SetStringValue( const wxString
&str
)
1366 wxMacConvertNewlines13To10( &st
) ;
1367 EditHelper
help(m_txn
) ;
1369 // wxMacWindowClipper c( this ) ;
1370 #if !TARGET_API_MAC_OSX
1371 // otherwise scrolling might have problems ?
1372 TPUpdateVisibility( m_controlRef
) ;
1374 SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset
) ;
1375 TXNSetSelection( m_txn
, 0, 0);
1376 TXNShowSelection( m_txn
, kTXNShowStart
);
1379 TXNFrameOptions
wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle
)
1381 TXNFrameOptions frameOptions
=
1382 kTXNDontDrawCaretWhenInactiveMask
;
1383 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
1384 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
1386 if ( wxStyle
& wxTE_MULTILINE
)
1388 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
1389 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
1392 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
1393 frameOptions
|= kTXNWantHScrollBarMask
;
1396 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
1397 frameOptions
|= kTXNWantVScrollBarMask
;
1400 frameOptions
|= kTXNSingleLineOnlyMask
;
1402 if ( wxStyle
& wxHSCROLL
)
1403 frameOptions
|= kTXNWantHScrollBarMask
;
1405 return frameOptions
;
1408 void wxMacMLTEControl::AdjustCreationAttributes( const wxColour
&background
, bool visible
)
1410 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
1411 TXNControlData iControlData
[3] = { {false}, {kTXNNoAutoWrap
} };
1413 #if TARGET_API_MAC_OSX
1414 iControlTags
[2] = kTXNVisibilityTag
;
1415 iControlData
[2].uValue
= visible
;
1419 if ( m_windowStyle
& wxTE_MULTILINE
)
1421 if (m_windowStyle
& wxTE_DONTWRAP
)
1422 iControlData
[1].uValue
= kTXNNoAutoWrap
;
1424 iControlData
[1].uValue
= kTXNAutoWrap
;
1427 verify_noerr( TXNSetTXNObjectControls( m_txn
, false, toptag
,
1428 iControlTags
, iControlData
)) ;
1430 // setting the default font
1436 GetThemeFont(kThemeSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
1438 TXNTypeAttributes typeAttr
[] =
1440 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
1441 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
1442 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
1445 verify_noerr( TXNSetTypeAttributes (m_txn
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
1449 if ( m_windowStyle
& wxTE_PASSWORD
)
1452 verify_noerr(TXNEchoMode( m_txn
, c
, 0 , true )) ;
1455 TXNBackground tback
;
1456 tback
.bgType
= kTXNBackgroundTypeRGB
;
1457 tback
.bg
.color
= MAC_WXCOLORREF( background
.GetPixel() );
1458 TXNSetBackground( m_txn
, &tback
);
1461 int wxMacMLTEControl::ConvertAttribute( const wxTextAttr
& style
, TXNTypeAttributes typeAttr
[] )
1463 Str255 fontName
= "\pMonaco" ;
1464 SInt16 fontSize
= 12 ;
1465 Style fontStyle
= normal
;
1467 int attrCounter
= 0 ;
1468 if ( style
.HasFont() )
1470 const wxFont
&font
= style
.GetFont() ;
1471 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1472 fontSize
= font
.GetPointSize() ;
1473 if ( font
.GetUnderlined() )
1474 fontStyle
|= underline
;
1475 if ( font
.GetWeight() == wxBOLD
)
1477 if ( font
.GetStyle() == wxITALIC
)
1478 fontStyle
|= italic
;
1480 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1481 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1482 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1483 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1484 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1485 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1486 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1487 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1488 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1492 if ( style
.HasTextColour() )
1494 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1495 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1496 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1497 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1500 return attrCounter
;
1503 void wxMacMLTEControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
)
1505 EditHelper
help(m_txn
) ;
1506 wxTextAttr
style(wxNullColour
,wxNullColour
,font
) ;
1507 TXNTypeAttributes typeAttr
[4] ;
1508 int attrCounter
= ConvertAttribute( style
, typeAttr
) ;
1509 if ( attrCounter
> 0 )
1511 verify_noerr( TXNSetTypeAttributes ( m_txn
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
1514 void wxMacMLTEControl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1516 EditHelper
help(m_txn
) ;
1517 TXNTypeAttributes typeAttr
[4] ;
1518 int attrCounter
= ConvertAttribute( style
, typeAttr
) ;
1519 if ( attrCounter
> 0 )
1521 verify_noerr( TXNSetTypeAttributes ( m_txn
, attrCounter
, typeAttr
, start
,end
) );
1525 void wxMacMLTEControl::Copy()
1527 ClearCurrentScrap();
1529 TXNConvertToPublicScrap();
1532 void wxMacMLTEControl::Cut()
1534 ClearCurrentScrap();
1536 TXNConvertToPublicScrap();
1539 void wxMacMLTEControl::Paste()
1541 TXNConvertFromPublicScrap();
1545 bool wxMacMLTEControl::CanPaste() const
1547 return TXNIsScrapPastable() ;
1550 void wxMacMLTEControl::SetEditable(bool editable
)
1552 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1553 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1554 TXNSetTXNObjectControls( m_txn
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1557 long wxMacMLTEControl::GetLastPosition() const
1559 long actualsize
= 0 ;
1562 OSErr err
= TXNGetDataEncoded( m_txn
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1570 actualsize
= GetHandleSize( theText
) ;
1571 DisposeHandle( theText
) ;
1577 void wxMacMLTEControl::Replace( long from
, long to
, const wxString str
)
1579 wxString value
= str
;
1580 wxMacConvertNewlines13To10( &value
) ;
1582 EditHelper
help( m_txn
) ;
1584 TXNSetSelection(m_txn
, from
, to
) ;
1586 SetTXNData( str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1589 void wxMacMLTEControl::Remove( long from
, long to
)
1591 EditHelper
help( m_txn
) ;
1593 TXNSetSelection(m_txn
, from
, to
) ;
1597 void wxMacMLTEControl::GetSelection( long* from
, long* to
) const
1599 TXNGetSelection( m_txn
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1602 void wxMacMLTEControl::SetSelection( long from
, long to
)
1604 /* change the selection */
1605 if ((from
== -1) && (to
== -1))
1606 TXNSelectAll(m_txn
);
1608 TXNSetSelection( m_txn
, from
, to
);
1609 TXNShowSelection( m_txn
, kTXNShowStart
);
1612 void wxMacMLTEControl::WriteText(const wxString
& str
)
1614 EditHelper
helper( m_txn
) ;
1616 wxMacConvertNewlines13To10( &st
) ;
1618 long start
, end
, dummy
;
1619 GetSelection( &start
, &dummy
) ;
1620 SetTXNData( st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1621 GetSelection( &dummy
, &end
) ;
1622 // TODO SetStyle( start , end , GetDefaultStyle() ) ;
1625 void wxMacMLTEControl::Clear()
1627 EditHelper
st(m_txn
) ;
1628 TXNSetSelection( m_txn
, kTXNStartOffset
, kTXNEndOffset
) ;
1632 bool wxMacMLTEControl::CanUndo() const
1634 return TXNCanUndo( m_txn
, NULL
) ;
1637 void wxMacMLTEControl::Undo()
1642 bool wxMacMLTEControl::CanRedo() const
1644 return TXNCanRedo( m_txn
, NULL
) ;
1647 void wxMacMLTEControl::Redo()
1652 int wxMacMLTEControl::GetNumberOfLines() const
1654 ItemCount lines
= 0 ;
1655 TXNGetLineCount(m_txn
, &lines
) ;
1659 long wxMacMLTEControl::XYToPosition(long x
, long y
) const
1663 long lastpos
= GetLastPosition() ;
1665 // TODO find a better implementation : while we can get the
1666 // line metrics of a certain line, we don't get its starting
1667 // position, so it would probably be rather a binary search
1668 // for the start position
1671 int lastHeight
= 0 ;
1674 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1676 if ( y
== ypos
&& x
== xpos
)
1679 TXNOffsetToPoint( m_txn
, n
, &curpt
);
1681 if ( curpt
.v
> lastHeight
)
1686 lastHeight
= curpt
.v
;
1694 bool wxMacMLTEControl::PositionToXY(long pos
, long *x
, long *y
) const
1698 long lastpos
= GetLastPosition() ;
1703 if ( pos
<= lastpos
)
1705 // TODO find a better implementation : while we can get the
1706 // line metrics of a certain line, we don't get its starting
1707 // position, so it would probably be rather a binary search
1708 // for the start position
1711 int lastHeight
= 0 ;
1714 for ( n
= 0 ; n
<= (ItemCount
) pos
; ++n
)
1716 TXNOffsetToPoint(m_txn
, n
, &curpt
);
1718 if ( curpt
.v
> lastHeight
)
1723 lastHeight
= curpt
.v
;
1728 if ( y
) *y
= ypos
;
1729 if ( x
) *x
= xpos
;
1735 void wxMacMLTEControl::ShowPosition( long pos
)
1737 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1741 TXNOffset selstart
, selend
;
1742 TXNGetSelection( m_txn
, &selstart
, &selend
) ;
1743 TXNOffsetToPoint( m_txn
, selstart
, ¤t
);
1744 TXNOffsetToPoint( m_txn
, pos
, &desired
);
1745 //TODO use HIPoints for 10.3 and above
1746 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1748 OSErr theErr
= noErr
;
1749 SInt32 dv
= desired
.v
- current
.v
;
1750 SInt32 dh
= desired
.h
- current
.h
;
1751 TXNShowSelection( m_txn
, true ) ;
1752 theErr
= TXNScroll( m_txn
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1753 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1759 void wxMacMLTEControl::SetTXNData( const wxString
& st
, TXNOffset start
, TXNOffset end
)
1762 #if SIZEOF_WCHAR_T == 2
1763 size_t len
= st
.Len() ;
1764 TXNSetData( m_txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
1767 wxMBConvUTF16BE converter
;
1768 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
1769 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
1770 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
1771 TXNSetData( m_txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
1776 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1777 TXNSetData( m_txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
1783 wxString
wxMacMLTEControl::GetLineText(long lineNo
) const
1787 wxString content
= GetStringValue() ;
1789 if ( lineNo
< GetNumberOfLines() )
1791 // TODO find a better implementation : while we can get the
1792 // line metrics of a certain line, we don't get its starting
1793 // position, so it would probably be rather a binary search
1794 // for the start position
1797 int lastHeight
= 0 ;
1798 long lastpos
= GetLastPosition() ;
1801 for ( n
= 0 ; n
<= (ItemCount
)lastpos
; ++n
)
1803 TXNOffsetToPoint( m_txn
, n
, &curpt
);
1805 if ( curpt
.v
> lastHeight
)
1807 if ( ypos
== lineNo
)
1813 lastHeight
= curpt
.v
;
1817 if ( ypos
== lineNo
)
1818 line
+= content
[n
] ;
1826 int wxMacMLTEControl::GetLineLength(long lineNo
) const
1829 if ( lineNo
< GetNumberOfLines() )
1831 // TODO find a better implementation : while we can get the
1832 // line metrics of a certain line, we don't get its starting
1833 // position, so it would probably be rather a binary search
1834 // for the start position
1837 int lastHeight
= 0 ;
1838 long lastpos
= GetLastPosition() ;
1841 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1843 TXNOffsetToPoint( m_txn
, n
, &curpt
);
1845 if ( curpt
.v
> lastHeight
)
1847 if ( ypos
== lineNo
)
1853 lastHeight
= curpt
.v
;
1863 // ----------------------------------------------------------------------------
1864 // MLTE control implementation (classic part)
1865 // ----------------------------------------------------------------------------
1867 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
1868 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
1869 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
1870 // an alternate path for carbon key events that routes automatically into the same wx flow of events
1874 /* kmUPTextPart is the part code we return to indicate the user has clicked
1875 in the text area of our control */
1876 #define kmUPTextPart 1
1879 /* routines for using existing user pane controls.
1880 These routines are useful for cases where you would like to use an
1881 existing user pane control in, say, a dialog window as a scrolling
1884 /* Utility Routines */
1886 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
1887 routine. In our focus switching routine this part code is understood
1888 as meaning 'the user has clicked in the control and we need to switch
1889 the current focus to ourselves before we can continue'. */
1890 #define kUserClickedToFocusPart 100
1892 /* STPTextPaneVars is a structure used for storing the the mUP Control's
1893 internal variables and state information. A handle to this record is
1894 stored in the pane control's reference value field using the
1895 SetControlReference routine. */
1897 class STPTextPaneVars
{
1899 /* OS records referenced */
1900 TXNObject fTXNRec
; /* the txn record */
1901 TXNFrameID fTXNFrame
; /* the txn frame ID */
1902 ControlRef fUserPaneRec
; /* handle to the user pane control */
1903 WindowPtr fOwner
; /* window containing control */
1904 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
1906 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
1907 Boolean fIsActive
; /* true while the control is drawn in the active state */
1908 Boolean fTXNObjectActive
; /* reflects the activation state of the text edit record */
1909 Boolean fFocusDrawState
; /* true if focus is drawn (default: true) */
1910 /* calculated locations */
1911 Rect fRBounds
; /* control bounds */
1912 Rect fRTextArea
; /* area where the text is drawn */
1913 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
1914 Rect fRTextOutline
; /* rectangle used to draw the border */
1915 RgnHandle fRTextOutlineRegion
; /* background region for the text, erased before calling TEUpdate */
1916 /* our focus advance override routine */
1917 EventHandlerUPP handlerUPP
;
1918 EventHandlerRef handlerRef
;
1924 /* Univerals Procedure Pointer variables used by the
1925 mUP Control. These variables are set up
1926 the first time that mUPOpenControl is called. */
1927 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
1928 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
1929 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
1930 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
1931 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
1932 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
1933 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
1935 // one place for calculating all
1936 static void TPCalculateBounds(STPTextPaneVars
*varsp
, const Rect
& bounds
)
1938 SetRect(&varsp
->fRBounds
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1939 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1940 // eventually make TextOutline inset 1,1
1941 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1942 if ( !varsp
->fNoBorders
)
1944 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
1945 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
1949 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
1950 bounds
.right
, bounds
.bottom
);
1954 OSStatus
MLTESetObjectVisibility( STPTextPaneVars
*varsp
, Boolean vis
, long wxStyle
)
1956 OSStatus err
= noErr
;
1957 #if TARGET_API_MAC_OSX
1958 TXNControlTag iControlTags
[1] = { kTXNVisibilityTag
};
1959 TXNControlData iControlData
[1] = {{ vis
}};
1960 err
= ::TXNSetTXNObjectControls( varsp
->fTXNRec
, false, 1, iControlTags
, iControlData
);
1962 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
1963 if ( vis
&& textctrl
)
1966 UMAGetControlBoundsInWindowCoords( varsp
->fUserPaneRec
, &bounds
);
1967 TPCalculateBounds( varsp
, bounds
) ;
1968 wxMacWindowClipper
cl(textctrl
) ;
1969 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
1970 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
1971 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
1976 // make sure we don't miss changes as carbon events are not available for these under classic
1977 static void TPUpdateVisibility(ControlRef theControl
) {
1978 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
1979 if ( textctrl
== NULL
)
1982 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
1985 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
1986 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
1988 // invalidate old position
1989 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
1990 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
1992 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
1995 Rect oldBounds
= varsp
->fRBounds
;
1996 TPCalculateBounds( varsp
, bounds
) ;
1997 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
1998 if ( varsp
->fVisible
)
2000 wxMacWindowClipper
cl(textctrl
) ;
2001 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
2002 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
2004 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
2005 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
2009 // make correct activations
2010 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
2012 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
2013 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
2015 varsp
->fTXNObjectActive
= setActive
;
2016 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
2017 if (varsp
->fInFocus
)
2018 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
2022 // update focus outlines
2023 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
2026 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
2028 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
2029 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
2033 // update TXN focus state
2034 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
2035 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
2037 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
2038 varsp
->fInFocus
= setFocus
;
2039 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
2044 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
2045 /* set up our globals */
2047 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2048 if ( textctrl
== NULL
)
2050 TPUpdateVisibility( theControl
) ;
2052 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2053 if ( textctrl
->MacIsReallyShown() )
2055 wxMacWindowClipper
clipper( textctrl
) ;
2056 TXNDraw(varsp
->fTXNRec
, NULL
);
2057 if ( !varsp
->fNoBorders
)
2058 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
2059 TPRedrawFocusOutline( varsp
) ;
2065 /* TPPaneHitTestProc is called when the control manager would
2066 like to determine what part of the control the mouse resides over.
2067 We also call this routine from our tracking proc to determine how
2068 to handle mouse clicks. */
2069 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
2070 ControlPartCode result
;
2071 /* set up our locals and lock down our globals*/
2073 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2074 if ( textctrl
== NULL
)
2076 TPUpdateVisibility( theControl
) ;
2077 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2078 if (textctrl
->MacIsReallyShown() )
2080 if (PtInRect(where
, &varsp
->fRBounds
))
2081 result
= kmUPTextPart
;
2084 // sometimes we get the coords also in control local coordinates, therefore test again
2085 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
2088 textctrl
->MacClientToRootWindow( &x
, &y
) ;
2092 if (PtInRect(where
, &varsp
->fRBounds
))
2093 result
= kmUPTextPart
;
2105 /* TPPaneTrackingProc is called when the mouse is being held down
2106 over our control. This routine handles clicks in the text area
2107 and in the scroll bar. */
2108 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
2110 ControlPartCode partCodeResult
;
2111 /* make sure we have some variables... */
2113 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2114 if ( textctrl
== NULL
)
2116 TPUpdateVisibility( theControl
) ;
2117 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2118 if (textctrl
->MacIsReallyShown() )
2120 /* we don't do any of these functions unless we're in focus */
2121 if ( ! varsp
->fInFocus
) {
2123 owner
= GetControlOwner(theControl
);
2124 ClearKeyboardFocus(owner
);
2125 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
2127 /* find the location for the click */
2128 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
2129 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
2132 textctrl
->MacClientToRootWindow( &x
, &y
) ;
2137 switch (TPPaneHitTestProc(theControl
, startPt
))
2140 /* handle clicks in the text part */
2143 wxMacWindowClipper
clipper( textctrl
) ;
2146 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
2147 TXNClick( varsp
->fTXNRec
, &rec
);
2154 return partCodeResult
;
2158 /* TPPaneIdleProc is our user pane idle routine. When our text field
2159 is active and in focus, we use this routine to set the cursor. */
2160 static pascal void TPPaneIdleProc(ControlRef theControl
) {
2162 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2163 if ( textctrl
== NULL
)
2165 TPUpdateVisibility( theControl
) ;
2166 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2167 if (textctrl
->MacIsReallyShown()) {
2168 /* if we're not active, then we have nothing to say about the cursor */
2169 if (varsp
->fIsActive
) {
2173 wxMacWindowClipper
clipper( textctrl
) ;
2175 /* there's a 'focus thing' and an 'unfocused thing' */
2176 if (varsp
->fInFocus
) {
2177 /* flash the cursor */
2178 SetPort(varsp
->fDrawingEnvironment
);
2179 TXNIdle(varsp
->fTXNRec
);
2180 /* set the cursor */
2181 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
2183 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
2184 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
2189 // SetThemeCursor(kThemeArrowCursor);
2192 /* if it's in our bounds, set the cursor */
2193 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
2194 if (PtInRect(mousep
, &bounds
))
2196 // SetThemeCursor(kThemeArrowCursor);
2204 /* TPPaneKeyDownProc is called whenever a keydown event is directed
2205 at our control. Here, we direct the keydown event to the text
2206 edit record and redraw the scroll bar and text field as appropriate. */
2207 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
2208 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
2210 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2211 if ( textctrl
== NULL
)
2213 TPUpdateVisibility( theControl
) ;
2215 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2216 if (varsp
->fInFocus
)
2218 /* turn autoscrolling on and send the key event to text edit */
2219 wxMacWindowClipper
clipper( textctrl
) ;
2221 memset( &ev
, 0 , sizeof( ev
) ) ;
2223 ev
.modifiers
= modifiers
;
2224 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
2225 TXNKeyDown( varsp
->fTXNRec
, &ev
);
2227 return kControlEntireControl
;
2231 /* TPPaneActivateProc is called when the window containing
2232 the user pane control receives activate events. Here, we redraw
2233 the control and it's text as necessary for the activation state. */
2234 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
2236 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2238 if ( textctrl
== NULL
)
2240 TPUpdateVisibility( theControl
) ;
2242 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2244 varsp
->fIsActive
= activating
;
2245 wxMacWindowClipper
clipper( textctrl
) ;
2246 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
2247 /* redraw the frame */
2248 if ( textctrl
->MacIsReallyShown() )
2250 if ( !varsp
->fNoBorders
)
2251 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
2252 TPRedrawFocusOutline( varsp
) ;
2257 /* TPPaneFocusProc is called when every the focus changes to or
2258 from our control. Herein, switch the focus appropriately
2259 according to the parameters and redraw the control as
2261 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
2262 ControlPartCode focusResult
;
2264 focusResult
= kControlFocusNoPart
;
2265 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
2266 if ( textctrl
== NULL
)
2268 TPUpdateVisibility( theControl
) ;
2269 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) ((wxMacMLTEClassicControl
*)textctrl
->GetPeer())->m_macTXNvars
;
2270 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
2271 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
2272 and kControlFocusNextPart will be received. When the user clicks in our field
2273 and it is not the current focus, then the constant kUserClickedToFocusPart will
2274 be received. The constant kControlFocusNoPart will be received when our control
2275 is the current focus and the user clicks in another control. In your focus routine,
2276 you should respond to these codes as follows:
2278 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
2279 the control and the focus rectangle as necessary.
2281 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
2282 depending on its current state. redraw the control and the focus rectangle
2283 as appropriate for the new focus state. If the focus state is 'off', return the constant
2284 kControlFocusNoPart, otherwise return a non-zero part code.
2285 kUserClickedToFocusPart - is a constant defined for this example. You should
2286 define your own value for handling click-to-focus type events. */
2287 /* calculate the next highlight state */
2290 case kControlFocusNoPart
:
2291 TPFocusPaneText(varsp
, false);
2292 focusResult
= kControlFocusNoPart
;
2294 case kUserClickedToFocusPart
:
2295 TPFocusPaneText(varsp
, true);
2298 case kControlFocusPrevPart
:
2299 case kControlFocusNextPart
:
2300 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
2301 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
2304 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
2305 /* redraw the text fram and focus rectangle to indicate the
2307 if ( textctrl
->MacIsReallyShown() )
2309 wxMacWindowClipper
c( textctrl
) ;
2310 if ( !varsp
->fNoBorders
)
2311 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
2312 TPRedrawFocusOutline( varsp
) ;
2317 wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxWindow
*wxPeer
,
2318 const wxString
& str
,
2320 const wxSize
& size
, long style
)
2322 m_font
= wxPeer
->GetFont() ;
2323 m_windowStyle
= style
;
2324 Rect bounds
= wxMacGetBoundsForControl( wxPeer
, pos
, size
) ;
2326 wxMacConvertNewlines13To10( &st
) ;
2328 wxMacConvertNewlines13To10( &st
) ;
2332 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
2333 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
2334 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
2335 /* create the control */
2337 verify_noerr( ::CreateUserPaneControl( MAC_WXHWND(wxPeer
->GetParent()->MacGetTopLevelWindowRef()), &bounds
, featurSet
, &m_controlRef
) );
2340 // wxMacWindowClipper c(wxPeer) ;
2344 if ( wxPeer
->MacIsReallyShown() )
2345 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , style
) ;
2348 // wxMacWindowClipper clipper( wxPeer ) ;
2350 TPUpdateVisibility( m_controlRef
) ;
2352 SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset
) ;
2354 TXNSetSelection( m_txn
, 0, 0);
2355 TXNShowSelection( m_txn
, kTXNShowStart
);
2358 AdjustCreationAttributes( *wxWHITE
, true ) ;
2361 wxMacMLTEClassicControl::~wxMacMLTEClassicControl()
2363 // SetControlReference(m_controlRef , 0) ;
2364 TXNDeleteObject(m_txn
);
2368 void wxMacMLTEClassicControl::VisibilityChanged(bool shown
)
2370 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, shown
, m_windowStyle
) ;
2372 InvalWindowRect( GetControlOwner( m_controlRef
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
2375 OSStatus
wxMacMLTEClassicControl::DoCreate()
2378 WindowRef theWindow
;
2380 OSStatus err
= noErr
;
2382 /* set up our globals */
2383 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
2384 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
2385 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
2386 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
2387 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
2388 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
2389 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
2391 /* allocate our private storage */
2392 m_macTXNvars
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
2394 /* set the initial settings for our private data */
2395 m_macTXNvars
->fMultiline
= m_windowStyle
& wxTE_MULTILINE
;
2396 m_macTXNvars
->fNoBorders
= m_windowStyle
& wxNO_BORDER
;
2397 m_macTXNvars
->fInFocus
= false;
2398 m_macTXNvars
->fIsActive
= true;
2399 m_macTXNvars
->fTXNObjectActive
= false;
2400 m_macTXNvars
->fFocusDrawState
= false ;
2401 m_macTXNvars
->fUserPaneRec
= m_controlRef
;
2402 m_macTXNvars
->fVisible
= true ;
2404 theWindow
= m_macTXNvars
->fOwner
= GetControlOwner(m_controlRef
);
2406 m_macTXNvars
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
2408 /* set up the user pane procedures */
2409 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
2410 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
2411 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
2412 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
2413 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
2414 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
2415 SetControlData(m_controlRef
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
2417 /* calculate the rectangles used by the control */
2418 UMAGetControlBoundsInWindowCoords(m_controlRef
, &bounds
);
2419 m_macTXNvars
->fRTextOutlineRegion
= NewRgn() ;
2420 TPCalculateBounds( m_macTXNvars
, bounds
) ;
2422 /* set up the drawing environment */
2423 SetPort(m_macTXNvars
->fDrawingEnvironment
);
2425 /* create the new edit field */
2427 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( m_windowStyle
) ;
2429 verify_noerr(TXNNewObject(NULL
, m_macTXNvars
->fOwner
, &m_macTXNvars
->fRTextArea
,
2431 kTXNTextEditStyleFrameType
,
2433 kTXNSystemDefaultEncoding
,
2434 &m_macTXNvars
->fTXNRec
, &m_macTXNvars
->fTXNFrame
, (TXNObjectRefcon
) m_macTXNvars
));
2435 m_txn
= m_macTXNvars
->fTXNRec
;
2437 /* perform final activations and setup for our text field. Here,
2438 we assume that the window is going to be the 'active' window. */
2439 TPActivatePaneText(m_macTXNvars
, m_macTXNvars
->fIsActive
&& m_macTXNvars
->fInFocus
);
2444 // ----------------------------------------------------------------------------
2445 // MLTE control implementation (OSX part)
2446 // ----------------------------------------------------------------------------
2448 #if TARGET_API_MAC_OSX
2450 wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxWindow
*wxPeer
,
2451 const wxString
& str
,
2453 const wxSize
& size
, long style
)
2455 m_font
= wxPeer
->GetFont() ;
2456 m_windowStyle
= style
;
2457 Rect bounds
= wxMacGetBoundsForControl( wxPeer
, pos
, size
) ;
2459 wxMacConvertNewlines13To10( &st
) ;
2461 HIRect hr
= { bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
} ;
2463 m_scrollView
= NULL
;
2464 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( style
) ;
2465 if ( frameOptions
& (kTXNWantVScrollBarMask
|kTXNWantHScrollBarMask
) )
2467 HIScrollViewCreate(( frameOptions
& kTXNWantHScrollBarMask
? kHIScrollViewOptionsHorizScroll
: 0) |
2468 ( frameOptions
& kTXNWantVScrollBarMask
? kHIScrollViewOptionsVertScroll
: 0 ) , &m_scrollView
) ;
2470 HIViewSetFrame( m_scrollView
, &hr
);
2471 HIViewSetVisible( m_scrollView
, true );
2475 HITextViewCreate( NULL
, 0, frameOptions
, &m_textView
) ;
2476 m_txn
= HITextViewGetTXNObject( m_textView
) ;
2477 HIViewSetVisible( m_textView
, true ) ;
2480 HIViewAddSubview( m_scrollView
, m_textView
) ;
2481 m_controlRef
= m_scrollView
;
2482 wxPeer
->MacInstallEventHandler( (WXWidget
) m_textView
) ;
2486 HIViewSetFrame( m_textView
, &hr
);
2487 m_controlRef
= m_textView
;
2491 SetTXNData( st
, kTXNStartOffset
, kTXNEndOffset
) ;
2493 TXNSetSelection( m_txn
, 0, 0);
2494 TXNShowSelection( m_txn
, kTXNShowStart
);
2496 AdjustCreationAttributes( *wxWHITE
, true ) ;
2499 OSStatus
wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart
)
2501 return SetKeyboardFocus( GetControlOwner( m_textView
) ,
2502 m_textView
, focusPart
) ;
2505 bool wxMacMLTEHIViewControl::HasFocus() const
2507 ControlRef control
;
2508 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2509 return control
== m_textView
;
2512 bool wxMacMLTEHIViewControl::NeedsFocusRect() const
2514 return m_windowStyle
& wxNO_BORDER
? false : true;
2519 #endif // wxUSE_TEXTCTRL