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