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