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