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