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