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