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