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