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