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