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