]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/textctrl.cpp
cleanup
[wxWidgets.git] / src / mac / carbon / textctrl.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
faa94f3e 2// Name: src/mac/carbon/textctrl.cpp
e9576ca5 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
3d1a4878 12#include "wx/wxprec.h"
fedad417
GD
13
14#if wxUSE_TEXTCTRL
15
88a7a4e1
WS
16#include "wx/textctrl.h"
17
18#ifndef WX_PRECOMP
19 #include "wx/intl.h"
670f9935 20 #include "wx/app.h"
de6185e2 21 #include "wx/utils.h"
da80ae71 22 #include "wx/dc.h"
f1e01716 23 #include "wx/button.h"
3b3dc801 24 #include "wx/menu.h"
9eddec69 25 #include "wx/settings.h"
246c5004 26 #include "wx/msgdlg.h"
1832043f 27 #include "wx/toplevel.h"
88a7a4e1 28#endif
5ca0d812 29
f5c6eb5c 30#ifdef __DARWIN__
88a7a4e1
WS
31 #include <sys/types.h>
32 #include <sys/stat.h>
e9576ca5 33#else
88a7a4e1 34 #include <stat.h>
e9576ca5 35#endif
2b5f62a0
VZ
36
37#if wxUSE_STD_IOSTREAM
38 #if wxUSE_IOSTREAMH
39 #include <fstream.h>
40 #else
41 #include <fstream>
42 #endif
43#endif
e9576ca5 44
e9576ca5 45#include "wx/filefn.h"
823c4e96 46#include "wx/sysopt.h"
e9576ca5
SC
47
48#if defined(__BORLANDC__) && !defined(__WIN32__)
670f9935 49 #include <alloc.h>
f5c6eb5c 50#elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
670f9935 51 #include <malloc.h>
e9576ca5
SC
52#endif
53
fef981b4
DS
54#ifndef __DARWIN__
55#include <MacTextEditor.h>
56#include <ATSUnicode.h>
57#include <TextCommon.h>
58#include <TextEncodingConverter.h>
59#endif
60
61#include "wx/mac/uma.h"
3f7f284d 62#include "wx/mac/carbon/private/mactext.h"
fef981b4 63
0f7817ab 64#ifndef __WXMAC_OSX__
3dee36ae 65enum
0f7817ab 66{
c88b7d28 67 kTXNVisibilityTag = 'visb' // set the visibility state of the object
0f7817ab
SC
68};
69#endif
70
72055702 71
5ca0d812 72class wxMacFunctor
587bc950 73{
7d8268a1 74public :
a8d2fb31 75 wxMacFunctor() {}
5ca0d812 76 virtual ~wxMacFunctor() {}
fef981b4 77
5ca0d812 78 virtual void* operator()() = 0 ;
fef981b4 79
c88b7d28 80 static void* CallBackProc( void *param )
587bc950 81 {
5ca0d812
SC
82 wxMacFunctor* f = (wxMacFunctor*) param ;
83 void *result = (*f)() ;
84 return result ;
587bc950 85 }
5ca0d812 86} ;
587bc950 87
fef981b4
DS
88template<typename classtype, typename param1type>
89
5ca0d812 90class wxMacObjectFunctor1 : public wxMacFunctor
587bc950 91{
5ca0d812
SC
92 typedef void (classtype::*function)( param1type p1 ) ;
93 typedef void (classtype::*ref_function)( const param1type& p1 ) ;
7d8268a1 94public :
5ca0d812 95 wxMacObjectFunctor1( classtype *obj , function f , param1type p1 ) :
fef981b4 96 wxMacFunctor()
587bc950 97 {
5ca0d812
SC
98 m_object = obj ;
99 m_function = f ;
100 m_param1 = p1 ;
587bc950 101 }
587bc950 102
5ca0d812 103 wxMacObjectFunctor1( classtype *obj , ref_function f , param1type p1 ) :
fef981b4 104 wxMacFunctor()
5ca0d812
SC
105 {
106 m_object = obj ;
107 m_refFunction = f ;
108 m_param1 = p1 ;
109 }
587bc950 110
d3c7fc99 111 virtual ~wxMacObjectFunctor1() {}
7d8268a1
WS
112
113 virtual void* operator()()
587bc950 114 {
c88b7d28 115 (m_object->*m_function)( m_param1 ) ;
5ca0d812
SC
116 return NULL ;
117 }
a8d2fb31 118
5ca0d812
SC
119private :
120 classtype* m_object ;
121 param1type m_param1 ;
122 union
123 {
fef981b4
DS
124 function m_function ;
125 ref_function m_refFunction ;
587bc950 126 } ;
5ca0d812 127} ;
587bc950 128
7d8268a1 129template<typename classtype, typename param1type>
5ca0d812
SC
130void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
131{
fef981b4 132 wxMacObjectFunctor1<classtype, param1type> params(object, function, p1) ;
7d8268a1 133 void *result =
fef981b4 134 MPRemoteCall( wxMacFunctor::CallBackProc , &params , kMPOwningProcessRemoteContext ) ;
5ca0d812
SC
135 return result ;
136}
587bc950 137
7d8268a1 138template<typename classtype, typename param1type>
5ca0d812
SC
139void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
140{
fef981b4 141 wxMacObjectFunctor1<classtype,param1type> params(object, function, p1) ;
7d8268a1 142 void *result =
fef981b4 143 MPRemoteCall( wxMacFunctor::CallBackProc , &params , kMPOwningProcessRemoteContext ) ;
5ca0d812 144 return result ;
587bc950
SC
145}
146
7d8268a1 147template<typename classtype, typename param1type>
5ca0d812
SC
148void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
149{
150 wxMutexGuiLeave() ;
151 void *result = wxMacMPRemoteCall( object , function , p1 ) ;
152 wxMutexGuiEnter() ;
153 return result ;
154}
29b30405 155
7d8268a1 156template<typename classtype, typename param1type>
5ca0d812
SC
157void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
158{
159 wxMutexGuiLeave() ;
160 void *result = wxMacMPRemoteCall( object , function , p1 ) ;
161 wxMutexGuiEnter() ;
162 return result ;
163}
a8d2fb31 164
72055702 165
5ca0d812 166// common parts for implementations based on MLTE
72055702 167
5ca0d812
SC
168class wxMacMLTEControl : public wxMacTextControl
169{
170public :
789ae0cf 171 wxMacMLTEControl( wxTextCtrl *peer ) ;
c88b7d28 172
5ca0d812 173 virtual wxString GetStringValue() const ;
c88b7d28 174 virtual void SetStringValue( const wxString &str ) ;
7d8268a1 175
5ca0d812 176 static TXNFrameOptions FrameOptionsFromWXStyle( long wxStyle ) ;
fef981b4 177
c88b7d28 178 void AdjustCreationAttributes( const wxColour& background, bool visible ) ;
5ca0d812 179
c88b7d28
DS
180 virtual void SetFont( const wxFont & font, const wxColour& foreground, long windowStyle ) ;
181 virtual void SetBackground( const wxBrush &brush ) ;
182 virtual void SetStyle( long start, long end, const wxTextAttr& style ) ;
5ca0d812
SC
183 virtual void Copy() ;
184 virtual void Cut() ;
185 virtual void Paste() ;
186 virtual bool CanPaste() const ;
c88b7d28 187 virtual void SetEditable( bool editable ) ;
7d8268a1 188 virtual wxTextPos GetLastPosition() const ;
c88b7d28
DS
189 virtual void Replace( long from, long to, const wxString &str ) ;
190 virtual void Remove( long from, long to ) ;
191 virtual void GetSelection( long* from, long* to ) const ;
192 virtual void SetSelection( long from, long to ) ;
7d8268a1 193
c88b7d28 194 virtual void WriteText( const wxString& str ) ;
fef981b4 195
0207e969
DS
196 virtual bool HasOwnContextMenu() const
197 {
64bd657c
SC
198#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
199 if ( UMAGetSystemVersion() >= 0x1040 )
200 {
201 TXNCommandEventSupportOptions options ;
202 TXNGetCommandEventSupport( m_txn , & options ) ;
203 return options & kTXNSupportEditCommandProcessing ;
204 }
205#endif
fef981b4 206
64bd657c
SC
207 return false ;
208 }
209
6df87058
KO
210 virtual void CheckSpelling(bool check)
211 {
212#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
213 TXNSetSpellCheckAsYouType( m_txn, (Boolean) check );
214#endif
215 }
5ca0d812
SC
216 virtual void Clear() ;
217
218 virtual bool CanUndo() const ;
219 virtual void Undo() ;
220 virtual bool CanRedo() const;
221 virtual void Redo() ;
222 virtual int GetNumberOfLines() const ;
223 virtual long XYToPosition(long x, long y) const ;
224 virtual bool PositionToXY(long pos, long *x, long *y) const ;
225 virtual void ShowPosition( long pos ) ;
226 virtual int GetLineLength(long lineNo) const ;
227 virtual wxString GetLineText(long lineNo) const ;
228
229 void SetTXNData( const wxString& st , TXNOffset start , TXNOffset end ) ;
09660720 230 TXNObject GetTXNObject() { return m_txn ; }
5ca0d812
SC
231
232protected :
8623a883 233 void TXNSetAttribute( const wxTextAttr& style , long from , long to ) ;
fef981b4 234
5ca0d812
SC
235 TXNObject m_txn ;
236} ;
72055702 237
5ca0d812 238#if TARGET_API_MAC_OSX
72055702 239
5ca0d812
SC
240// implementation available under OSX
241
788e118f
SC
242#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
243
7d8268a1 244class wxMacMLTEHIViewControl : public wxMacMLTEControl
5ca0d812
SC
245{
246public :
0f7817ab 247 wxMacMLTEHIViewControl( wxTextCtrl *wxPeer,
5ca0d812
SC
248 const wxString& str,
249 const wxPoint& pos,
250 const wxSize& size, long style ) ;
d3c7fc99 251 virtual ~wxMacMLTEHIViewControl() ;
9eddec69 252
5ca0d812
SC
253 virtual OSStatus SetFocus( ControlFocusPart focusPart ) ;
254 virtual bool HasFocus() const ;
44aa865d 255 virtual void SetBackground( const wxBrush &brush) ;
a8d2fb31 256
5ca0d812
SC
257protected :
258 HIViewRef m_scrollView ;
259 HIViewRef m_textView ;
fef981b4 260};
ef4a634b 261
788e118f
SC
262#endif
263
3556e470 264#endif
72055702 265
24260aae 266// 'classic' MLTE implementation
72055702 267
5ca0d812
SC
268class wxMacMLTEClassicControl : public wxMacMLTEControl
269{
270public :
0f7817ab 271 wxMacMLTEClassicControl( wxTextCtrl *wxPeer,
5ca0d812
SC
272 const wxString& str,
273 const wxPoint& pos,
274 const wxSize& size, long style ) ;
d3c7fc99 275 virtual ~wxMacMLTEClassicControl() ;
ffafe6ca 276
5ca0d812 277 virtual void VisibilityChanged(bool shown) ;
4e477040 278 virtual void SuperChangedPosition() ;
24260aae
SC
279
280 virtual void MacControlUserPaneDrawProc(wxInt16 part) ;
281 virtual wxInt16 MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) ;
282 virtual wxInt16 MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc) ;
283 virtual void MacControlUserPaneIdleProc() ;
284 virtual wxInt16 MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers) ;
285 virtual void MacControlUserPaneActivateProc(bool activating) ;
286 virtual wxInt16 MacControlUserPaneFocusProc(wxInt16 action) ;
287 virtual void MacControlUserPaneBackgroundProc(void* info) ;
288
ffafe6ca
DS
289 virtual bool SetupCursor( const wxPoint& WXUNUSED(pt) )
290 {
291 MacControlUserPaneIdleProc();
292 return true;
293 }
f2c3f2a8 294
0f7817ab
SC
295 virtual void SetRect( Rect *r ) ;
296
5ca0d812
SC
297protected :
298 OSStatus DoCreate();
3dee36ae 299
0f7817ab 300 void MacUpdatePosition() ;
fef981b4
DS
301 void MacActivatePaneText(bool setActive) ;
302 void MacFocusPaneText(bool setFocus) ;
303 void MacSetObjectVisibility(bool vis) ;
a8d2fb31 304
0f7817ab
SC
305private :
306 TXNFrameID m_txnFrameID ;
307 GrafPtr m_txnPort ;
5de694f0 308 WindowRef m_txnWindow ;
0f7817ab
SC
309 // bounds of the control as we last did set the txn frames
310 Rect m_txnControlBounds ;
ba75e603 311 Rect m_txnVisBounds ;
fef981b4 312
4e477040 313#ifdef __WXMAC_OSX__
fef981b4
DS
314 static pascal void TXNScrollActionProc( ControlRef controlRef , ControlPartCode partCode ) ;
315 static pascal void TXNScrollInfoProc(
316 SInt32 iValue, SInt32 iMaximumValue,
317 TXNScrollBarOrientation iScrollBarOrientation, SInt32 iRefCon ) ;
318
4e477040 319 ControlRef m_sbHorizontal ;
5de694f0 320 SInt32 m_lastHorizontalValue ;
4e477040 321 ControlRef m_sbVertical ;
5de694f0 322 SInt32 m_lastVerticalValue ;
4e477040 323#endif
fef981b4 324};
facd6764 325
fef981b4 326
9d112688 327IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
72055702 328
9d112688 329BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
7ea087b7 330 EVT_ERASE_BACKGROUND( wxTextCtrl::OnEraseBackground )
5ca0d812
SC
331 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
332 EVT_CHAR(wxTextCtrl::OnChar)
333 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
334 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
335 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
336 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
337 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
24eef584
SC
338 EVT_MENU(wxID_CLEAR, wxTextCtrl::OnDelete)
339 EVT_MENU(wxID_SELECTALL, wxTextCtrl::OnSelectAll)
340
341 EVT_CONTEXT_MENU(wxTextCtrl::OnContextMenu)
5ca0d812
SC
342
343 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
344 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
345 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
346 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
347 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
24eef584
SC
348 EVT_UPDATE_UI(wxID_CLEAR, wxTextCtrl::OnUpdateDelete)
349 EVT_UPDATE_UI(wxID_SELECTALL, wxTextCtrl::OnUpdateSelectAll)
5ca0d812 350END_EVENT_TABLE()
5ca0d812 351
fef981b4 352
a8d2fb31 353void wxTextCtrl::Init()
facd6764 354{
24eef584
SC
355 m_editable = true ;
356 m_dirty = false;
5ca0d812 357
b9bae707 358 m_maxLength = 0;
c88b7d28 359 m_privateContextMenu = NULL;
51478cd6 360 m_triggerOnSetValue = true ;
facd6764
SC
361}
362
5ca0d812 363wxTextCtrl::~wxTextCtrl()
facd6764 364{
24eef584 365 delete m_privateContextMenu;
facd6764
SC
366}
367
ffafe6ca 368bool wxTextCtrl::Create( wxWindow *parent,
c88b7d28
DS
369 wxWindowID id,
370 const wxString& str,
371 const wxPoint& pos,
372 const wxSize& size,
373 long style,
374 const wxValidator& validator,
ffafe6ca 375 const wxString& name )
5ca0d812 376{
7d8268a1 377 m_macIsUserPane = false ;
5ca0d812
SC
378 m_editable = true ;
379
c88b7d28
DS
380 if ( ! (style & wxNO_BORDER) )
381 style = (style & ~wxBORDER_MASK) | wxSUNKEN_BORDER ;
7d8268a1 382
ffafe6ca 383 if ( !wxTextCtrlBase::Create( parent, id, pos, size, style & ~(wxHSCROLL | wxVSCROLL), validator, name ) )
7d8268a1 384 return false;
ef4a634b 385
5ca0d812 386 if ( m_windowStyle & wxTE_MULTILINE )
facd6764 387 {
9e15c718 388 // always turn on this style for multi-line controls
5ca0d812
SC
389 m_windowStyle |= wxTE_PROCESS_ENTER;
390 style |= wxTE_PROCESS_ENTER ;
ed8c2780 391 }
3556e470 392
3f7f284d
RD
393 CreatePeer( str, pos, size, style );
394
395 MacPostControlCreate(pos, size) ;
396
397 // only now the embedding is correct and we can do a positioning update
398
399 MacSuperChangedPosition() ;
400
401 if ( m_windowStyle & wxTE_READONLY)
402 SetEditable( false ) ;
403
404 SetCursor( wxCursor( wxCURSOR_IBEAM ) ) ;
405
406 return true;
407}
408
409void wxTextCtrl::CreatePeer(
410 const wxString& str,
411 const wxPoint& pos,
412 const wxSize& size, long style )
413{
4d7528a1 414 bool forceMLTE = false ;
fef981b4 415
823c4e96 416#if wxUSE_SYSTEM_OPTIONS
ffafe6ca 417 if (wxSystemOptions::HasOption( wxMAC_TEXTCONTROL_USE_MLTE ) && (wxSystemOptions::GetOptionInt( wxMAC_TEXTCONTROL_USE_MLTE ) == 1))
823c4e96 418 {
4d7528a1 419 forceMLTE = true ;
823c4e96
SC
420 }
421#endif
4d7528a1 422
6239ee05
SC
423 if ( UMAGetSystemVersion() >= 0x1050 )
424 forceMLTE = false;
425
c88b7d28 426 if ( UMAGetSystemVersion() >= 0x1030 && !forceMLTE )
788e118f 427 {
4d7528a1
SC
428 if ( m_windowStyle & wxTE_MULTILINE )
429 m_peer = new wxMacMLTEHIViewControl( this , str , pos , size , style ) ;
788e118f 430 }
fef981b4 431
3556e470 432 if ( !m_peer )
7d8268a1 433 {
c88b7d28 434 if ( !(m_windowStyle & wxTE_MULTILINE) && !forceMLTE )
4f74e0d1 435 {
4d7528a1 436 m_peer = new wxMacUnicodeTextControl( this , str , pos , size , style ) ;
4f74e0d1 437 }
788e118f 438 }
fef981b4 439
6239ee05
SC
440 // the horizontal single line scrolling bug that made us keep the classic implementation
441 // is fixed in 10.5
442#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
3556e470 443 if ( !m_peer )
3556e470 444 m_peer = new wxMacMLTEClassicControl( this , str , pos , size , style ) ;
4f74e0d1 445#endif
facd6764
SC
446}
447
3dee36ae 448void wxTextCtrl::MacSuperChangedPosition()
4e477040
SC
449{
450 wxWindow::MacSuperChangedPosition() ;
451 GetPeer()->SuperChangedPosition() ;
452}
453
7d8268a1 454void wxTextCtrl::MacVisibilityChanged()
5ca0d812
SC
455{
456 GetPeer()->VisibilityChanged( MacIsReallyShown() ) ;
457}
facd6764 458
7d8268a1 459void wxTextCtrl::MacEnabledStateChanged()
5ca0d812 460{
72055702
SC
461}
462
6df87058
KO
463void wxTextCtrl::MacCheckSpelling(bool check)
464{
465 GetPeer()->CheckSpelling(check);
466}
467
5ca0d812
SC
468wxString wxTextCtrl::GetValue() const
469{
470 return GetPeer()->GetStringValue() ;
471}
ef4a634b 472
5ca0d812 473void wxTextCtrl::GetSelection(long* from, long* to) const
7d8268a1 474{
5ca0d812
SC
475 GetPeer()->GetSelection( from , to ) ;
476}
477
ee2ec18e 478void wxTextCtrl::DoSetValue(const wxString& str, int flags)
5ca0d812
SC
479{
480 // optimize redraws
481 if ( GetValue() == str )
ee2ec18e 482 return;
facd6764 483
c88b7d28 484 GetPeer()->SetStringValue( str ) ;
e8b4fd4b 485
ee2ec18e 486 if ( (flags & SetValue_SendEvent) && m_triggerOnSetValue )
51478cd6 487 {
ee2ec18e 488 SendTextUpdatedEvent();
51478cd6 489 }
72055702
SC
490}
491
5ca0d812
SC
492void wxTextCtrl::SetMaxLength(unsigned long len)
493{
494 m_maxLength = len ;
495}
72055702 496
5ca0d812
SC
497bool wxTextCtrl::SetFont( const wxFont& font )
498{
499 if ( !wxTextCtrlBase::SetFont( font ) )
7d8268a1
WS
500 return false ;
501
5ca0d812 502 GetPeer()->SetFont( font , GetForegroundColour() , GetWindowStyle() ) ;
fef981b4 503
5ca0d812
SC
504 return true ;
505}
506
507bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
508{
509 GetPeer()->SetStyle( start , end , style ) ;
fef981b4 510
5ca0d812
SC
511 return true ;
512}
513
514bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style)
515{
516 wxTextCtrlBase::SetDefaultStyle( style ) ;
517 SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
fef981b4 518
7d8268a1 519 return true ;
5ca0d812
SC
520}
521
522// Clipboard operations
fef981b4 523
5ca0d812
SC
524void wxTextCtrl::Copy()
525{
526 if (CanCopy())
7d8268a1 527 GetPeer()->Copy() ;
72055702
SC
528}
529
5ca0d812
SC
530void wxTextCtrl::Cut()
531{
532 if (CanCut())
533 {
7d8268a1 534 GetPeer()->Cut() ;
72055702 535
c88b7d28 536 wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, m_windowId );
5ca0d812 537 event.SetEventObject( this );
c88b7d28 538 GetEventHandler()->ProcessEvent( event );
5ca0d812
SC
539 }
540}
72055702 541
5ca0d812
SC
542void wxTextCtrl::Paste()
543{
544 if (CanPaste())
545 {
7d8268a1 546 GetPeer()->Paste() ;
fef981b4
DS
547
548 // TODO: eventually we should add setting the default style again
72055702 549
c88b7d28 550 wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, m_windowId );
5ca0d812 551 event.SetEventObject( this );
c88b7d28 552 GetEventHandler()->ProcessEvent( event );
5ca0d812
SC
553 }
554}
72055702 555
5ca0d812
SC
556bool wxTextCtrl::CanCopy() const
557{
558 // Can copy if there's a selection
559 long from, to;
c88b7d28 560 GetSelection( &from, &to );
ffafe6ca 561
5ca0d812
SC
562 return (from != to);
563}
ef4a634b 564
5ca0d812
SC
565bool wxTextCtrl::CanCut() const
566{
567 if ( !IsEditable() )
c88b7d28 568 return false;
a8d2fb31 569
5ca0d812
SC
570 // Can cut if there's a selection
571 long from, to;
c88b7d28 572 GetSelection( &from, &to );
ffafe6ca 573
5ca0d812 574 return (from != to);
72055702
SC
575}
576
5ca0d812
SC
577bool wxTextCtrl::CanPaste() const
578{
579 if (!IsEditable())
7d8268a1 580 return false;
72055702 581
5ca0d812
SC
582 return GetPeer()->CanPaste() ;
583}
facd6764 584
5ca0d812
SC
585void wxTextCtrl::SetEditable(bool editable)
586{
587 if ( editable != m_editable )
588 {
589 m_editable = editable ;
590 GetPeer()->SetEditable( editable ) ;
ed8c2780 591 }
72055702
SC
592}
593
5ca0d812
SC
594void wxTextCtrl::SetInsertionPoint(long pos)
595{
596 SetSelection( pos , pos ) ;
597}
72055702 598
5ca0d812
SC
599void wxTextCtrl::SetInsertionPointEnd()
600{
7d8268a1 601 wxTextPos pos = GetLastPosition();
ffafe6ca 602 SetInsertionPoint( pos );
5ca0d812 603}
facd6764 604
5ca0d812
SC
605long wxTextCtrl::GetInsertionPoint() const
606{
ffafe6ca 607 long begin, end ;
5ca0d812 608 GetSelection( &begin , &end ) ;
ffafe6ca 609
5ca0d812
SC
610 return begin ;
611}
facd6764 612
7d8268a1 613wxTextPos wxTextCtrl::GetLastPosition() const
5ca0d812 614{
c88b7d28 615 return GetPeer()->GetLastPosition() ;
72055702
SC
616}
617
5ca0d812
SC
618void wxTextCtrl::Replace(long from, long to, const wxString& str)
619{
ffafe6ca 620 GetPeer()->Replace( from , to , str ) ;
5ca0d812 621}
72055702 622
5ca0d812
SC
623void wxTextCtrl::Remove(long from, long to)
624{
625 GetPeer()->Remove( from , to ) ;
626}
facd6764 627
5ca0d812
SC
628void wxTextCtrl::SetSelection(long from, long to)
629{
630 GetPeer()->SetSelection( from , to ) ;
631}
632
5ca0d812
SC
633void wxTextCtrl::WriteText(const wxString& str)
634{
fef981b4 635 // TODO: this MPRemoting will be moved into a remoting peer proxy for any command
5ca0d812
SC
636 if ( !wxIsMainThread() )
637 {
fef981b4
DS
638 // unfortunately CW 8 is not able to correctly deduce the template types,
639 // so we have to instantiate explicitly
5ca0d812 640 wxMacMPRemoteGUICall<wxTextCtrl,wxString>( this , &wxTextCtrl::WriteText , str ) ;
ffafe6ca 641
5ca0d812
SC
642 return ;
643 }
ffafe6ca
DS
644
645 GetPeer()->WriteText( str ) ;
5ca0d812 646}
72055702 647
5ca0d812
SC
648void wxTextCtrl::AppendText(const wxString& text)
649{
650 SetInsertionPointEnd();
ffafe6ca 651 WriteText( text );
5ca0d812 652}
facd6764 653
5ca0d812
SC
654void wxTextCtrl::Clear()
655{
656 GetPeer()->Clear() ;
657}
facd6764 658
5ca0d812
SC
659bool wxTextCtrl::IsModified() const
660{
661 return m_dirty;
662}
facd6764 663
5ca0d812
SC
664bool wxTextCtrl::IsEditable() const
665{
666 return IsEnabled() && m_editable ;
72055702
SC
667}
668
5ca0d812
SC
669bool wxTextCtrl::AcceptsFocus() const
670{
671 // we don't want focus if we can't be edited
672 return /*IsEditable() && */ wxControl::AcceptsFocus();
673}
72055702 674
5ca0d812 675wxSize wxTextCtrl::DoGetBestSize() const
1b2b1638 676{
c88b7d28 677 int wText, hText;
ef4a634b 678
a8d2fb31
DS
679 // these are the numbers from the HIG:
680 // we reduce them by the borders first
c88b7d28 681 wText = 100 ;
72463754 682
fef981b4 683 switch ( m_windowVariant )
5ca0d812
SC
684 {
685 case wxWINDOW_VARIANT_NORMAL :
72463754 686 hText = 22 - 6 ;
5ca0d812 687 break ;
a8d2fb31 688
5ca0d812 689 case wxWINDOW_VARIANT_SMALL :
72463754 690 hText = 19 - 6 ;
5ca0d812 691 break ;
a8d2fb31 692
5ca0d812 693 case wxWINDOW_VARIANT_MINI :
c88b7d28 694 hText = 15 - 6 ;
5ca0d812 695 break ;
a8d2fb31 696
5ca0d812 697 default :
72463754 698 hText = 22 - 6;
7d8268a1 699 break ;
5ca0d812 700 }
72055702 701
72463754
SC
702 // as the above numbers have some free space around the text
703 // we get 5 lines like this anyway
5ca0d812 704 if ( m_windowStyle & wxTE_MULTILINE )
5ca0d812 705 hText *= 5 ;
ef4a634b 706
72463754
SC
707 if ( !HasFlag(wxNO_BORDER) )
708 hText += 6 ;
709
5ca0d812
SC
710 return wxSize(wText, hText);
711}
ef4a634b 712
5ca0d812
SC
713// ----------------------------------------------------------------------------
714// Undo/redo
715// ----------------------------------------------------------------------------
facd6764 716
5ca0d812
SC
717void wxTextCtrl::Undo()
718{
719 if (CanUndo())
5ca0d812 720 GetPeer()->Undo() ;
72055702
SC
721}
722
5ca0d812 723void wxTextCtrl::Redo()
587bc950 724{
5ca0d812 725 if (CanRedo())
5ca0d812 726 GetPeer()->Redo() ;
5ca0d812 727}
1b2b1638 728
5ca0d812
SC
729bool wxTextCtrl::CanUndo() const
730{
7d8268a1 731 if ( !IsEditable() )
7d8268a1 732 return false ;
a8d2fb31 733
5ca0d812
SC
734 return GetPeer()->CanUndo() ;
735}
72055702 736
5ca0d812 737bool wxTextCtrl::CanRedo() const
6bdd4f5d 738{
7d8268a1 739 if ( !IsEditable() )
7d8268a1 740 return false ;
a8d2fb31 741
5ca0d812 742 return GetPeer()->CanRedo() ;
6bdd4f5d
SC
743}
744
5ca0d812
SC
745void wxTextCtrl::MarkDirty()
746{
747 m_dirty = true;
748}
587bc950 749
5ca0d812
SC
750void wxTextCtrl::DiscardEdits()
751{
752 m_dirty = false;
753}
587bc950 754
5ca0d812
SC
755int wxTextCtrl::GetNumberOfLines() const
756{
757 return GetPeer()->GetNumberOfLines() ;
758}
587bc950 759
5ca0d812
SC
760long wxTextCtrl::XYToPosition(long x, long y) const
761{
762 return GetPeer()->XYToPosition( x , y ) ;
763}
587bc950 764
5ca0d812 765bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
72055702 766{
ffafe6ca 767 return GetPeer()->PositionToXY( pos , x , y ) ;
5ca0d812 768}
1fa29bdc 769
5ca0d812
SC
770void wxTextCtrl::ShowPosition(long pos)
771{
772 return GetPeer()->ShowPosition(pos) ;
773}
1fa29bdc 774
5ca0d812
SC
775int wxTextCtrl::GetLineLength(long lineNo) const
776{
777 return GetPeer()->GetLineLength(lineNo) ;
1b2b1638
SC
778}
779
5ca0d812 780wxString wxTextCtrl::GetLineText(long lineNo) const
1b2b1638 781{
5ca0d812 782 return GetPeer()->GetLineText(lineNo) ;
72055702
SC
783}
784
5ca0d812 785void wxTextCtrl::Command(wxCommandEvent & event)
72055702 786{
c88b7d28
DS
787 SetValue(event.GetString());
788 ProcessCommand(event);
5ca0d812 789}
72055702 790
5ca0d812
SC
791void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
792{
793 // By default, load the first file into the text window.
794 if (event.GetNumberOfFiles() > 0)
ffafe6ca 795 LoadFile( event.GetFiles()[0] );
5ca0d812 796}
ef4a634b 797
7ea087b7
SC
798void wxTextCtrl::OnEraseBackground(wxEraseEvent& event)
799{
800 // all erasing should be done by the real mac control implementation
801 // while this is true for MLTE under classic, the HITextView is somehow
802 // transparent but background erase is not working correctly, so intercept
803 // things while we can...
395480fb 804 event.Skip() ;
7ea087b7
SC
805}
806
5ca0d812
SC
807void wxTextCtrl::OnChar(wxKeyEvent& event)
808{
809 int key = event.GetKeyCode() ;
810 bool eat_key = false ;
72055702 811
c4d9fc39
SC
812 if ( key == 'a' && event.MetaDown() )
813 {
88a7a4e1
WS
814 SelectAll() ;
815
c4d9fc39
SC
816 return ;
817 }
818
5ca0d812 819 if ( key == 'c' && event.MetaDown() )
72055702 820 {
5ca0d812
SC
821 if ( CanCopy() )
822 Copy() ;
fef981b4 823
5ca0d812 824 return ;
72055702
SC
825 }
826
5ca0d812 827 if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
8e13c1ec 828 !( key == WXK_RETURN && ( (m_windowStyle & wxTE_PROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
faa94f3e 829// && key != WXK_PAGEUP && key != WXK_PAGEDOWN && key != WXK_HOME && key != WXK_END
5ca0d812 830 )
29e4a190 831 {
5ca0d812
SC
832 // eat it
833 return ;
834 }
d3016f30 835
b9bae707
VZ
836 // Check if we have reached the max # of chars (if it is set), but still
837 // allow navigation and deletion
faa94f3e 838 if ( !IsMultiLine() && m_maxLength && GetValue().length() >= m_maxLength &&
bdf0c19c 839 key != WXK_LEFT && key != WXK_RIGHT && key != WXK_TAB &&
8e13c1ec 840 key != WXK_BACK && !( key == WXK_RETURN && (m_windowStyle & wxTE_PROCESS_ENTER) )
bdf0c19c
KH
841 )
842 {
843 // eat it, we don't want to add more than allowed # of characters
b9bae707
VZ
844
845 // TODO: generate EVT_TEXT_MAXLEN()
bdf0c19c
KH
846 return;
847 }
848
5ca0d812
SC
849 // assume that any key not processed yet is going to modify the control
850 m_dirty = true;
587bc950 851
5ca0d812
SC
852 if ( key == 'v' && event.MetaDown() )
853 {
854 if ( CanPaste() )
855 Paste() ;
0207e969 856
5ca0d812 857 return ;
29e4a190 858 }
fef981b4 859
5ca0d812 860 if ( key == 'x' && event.MetaDown() )
ed8c2780 861 {
5ca0d812
SC
862 if ( CanCut() )
863 Cut() ;
fef981b4 864
5ca0d812 865 return ;
1b2b1638 866 }
a8d2fb31 867
5ca0d812
SC
868 switch ( key )
869 {
870 case WXK_RETURN:
8e13c1ec 871 if (m_windowStyle & wxTE_PROCESS_ENTER)
5ca0d812
SC
872 {
873 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
874 event.SetEventObject( this );
875 event.SetString( GetValue() );
876 if ( GetEventHandler()->ProcessEvent(event) )
877 return;
878 }
fef981b4 879
5ca0d812
SC
880 if ( !(m_windowStyle & wxTE_MULTILINE) )
881 {
6c20e8f8
VZ
882 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
883 if ( tlw && tlw->GetDefaultItem() )
fef981b4 884 {
6c20e8f8 885 wxButton *def = wxDynamicCast(tlw->GetDefaultItem(), wxButton);
5ca0d812
SC
886 if ( def && def->IsEnabled() )
887 {
888 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
889 event.SetEventObject(def);
890 def->Command(event);
fef981b4 891
5ca0d812 892 return ;
3dee36ae 893 }
5ca0d812
SC
894 }
895
896 // this will make wxWidgets eat the ENTER key so that
0207e969 897 // we actually prevent line wrapping in a single line text control
7d8268a1 898 eat_key = true;
5ca0d812 899 }
5ca0d812 900 break;
facd6764 901
5ca0d812
SC
902 case WXK_TAB:
903 if ( !(m_windowStyle & wxTE_PROCESS_TAB))
904 {
905 int flags = 0;
906 if (!event.ShiftDown())
907 flags |= wxNavigationKeyEvent::IsForward ;
908 if (event.ControlDown())
909 flags |= wxNavigationKeyEvent::WinChange ;
910 Navigate(flags);
fef981b4 911
5ca0d812
SC
912 return;
913 }
914 else
915 {
fef981b4
DS
916 // This is necessary (don't know why);
917 // otherwise the tab will not be inserted.
5ca0d812 918 WriteText(wxT("\t"));
4e6cc020 919 eat_key = true;
5ca0d812 920 }
a8d2fb31 921 break;
7d8268a1 922
a8d2fb31 923 default:
5ca0d812
SC
924 break;
925 }
facd6764 926
5ca0d812 927 if (!eat_key)
7f1de2b2 928 {
5ca0d812 929 // perform keystroke handling
665b537f 930 event.Skip(true) ;
7f1de2b2 931 }
a8d2fb31 932
5ca0d812 933 if ( ( key >= 0x20 && key < WXK_START ) ||
fce161de 934 ( key >= WXK_NUMPAD0 && key <= WXK_DIVIDE ) ||
5ca0d812
SC
935 key == WXK_RETURN ||
936 key == WXK_DELETE ||
937 key == WXK_BACK)
7f1de2b2 938 {
5ca0d812 939 wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
5ca0d812 940 event1.SetEventObject( this );
c88b7d28 941 wxPostEvent( GetEventHandler(), event1 );
7f1de2b2 942 }
5ca0d812 943}
facd6764 944
5ca0d812
SC
945// ----------------------------------------------------------------------------
946// standard handlers for standard edit menu events
947// ----------------------------------------------------------------------------
948
949void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
950{
951 Cut();
72055702
SC
952}
953
5ca0d812 954void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
facd6764 955{
5ca0d812
SC
956 Copy();
957}
7f1de2b2 958
5ca0d812
SC
959void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
960{
961 Paste();
facd6764
SC
962}
963
5ca0d812 964void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
facd6764 965{
5ca0d812 966 Undo();
facd6764
SC
967}
968
5ca0d812
SC
969void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
970{
971 Redo();
972}
facd6764 973
24eef584
SC
974void wxTextCtrl::OnDelete(wxCommandEvent& WXUNUSED(event))
975{
976 long from, to;
ffafe6ca 977
c88b7d28 978 GetSelection( &from, &to );
24eef584 979 if (from != -1 && to != -1)
c88b7d28 980 Remove( from, to );
24eef584
SC
981}
982
983void wxTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event))
984{
985 SetSelection(-1, -1);
986}
987
5ca0d812 988void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
72055702 989{
5ca0d812 990 event.Enable( CanCut() );
72055702
SC
991}
992
5ca0d812
SC
993void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
994{
995 event.Enable( CanCopy() );
72055702
SC
996}
997
5ca0d812 998void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
72055702 999{
5ca0d812 1000 event.Enable( CanPaste() );
72055702
SC
1001}
1002
5ca0d812 1003void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
29b30405 1004{
5ca0d812 1005 event.Enable( CanUndo() );
29b30405
SC
1006}
1007
5ca0d812 1008void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
facd6764 1009{
5ca0d812 1010 event.Enable( CanRedo() );
facd6764
SC
1011}
1012
24eef584
SC
1013void wxTextCtrl::OnUpdateDelete(wxUpdateUIEvent& event)
1014{
1015 long from, to;
ffafe6ca 1016
c88b7d28 1017 GetSelection( &from, &to );
0207e969 1018 event.Enable( from != -1 && to != -1 && from != to && IsEditable() ) ;
24eef584
SC
1019}
1020
1021void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event)
1022{
1023 event.Enable(GetLastPosition() > 0);
1024}
1025
a8d2fb31 1026// CS: Context Menus only work with MLTE implementations or non-multiline HIViews at the moment
24eef584
SC
1027
1028void wxTextCtrl::OnContextMenu(wxContextMenuEvent& event)
1029{
64bd657c
SC
1030 if ( GetPeer()->HasOwnContextMenu() )
1031 {
1032 event.Skip() ;
1033 return ;
1034 }
0207e969 1035
24eef584
SC
1036 if (m_privateContextMenu == NULL)
1037 {
1038 m_privateContextMenu = new wxMenu;
1039 m_privateContextMenu->Append(wxID_UNDO, _("&Undo"));
1040 m_privateContextMenu->Append(wxID_REDO, _("&Redo"));
1041 m_privateContextMenu->AppendSeparator();
1042 m_privateContextMenu->Append(wxID_CUT, _("Cu&t"));
1043 m_privateContextMenu->Append(wxID_COPY, _("&Copy"));
1044 m_privateContextMenu->Append(wxID_PASTE, _("&Paste"));
1045 m_privateContextMenu->Append(wxID_CLEAR, _("&Delete"));
1046 m_privateContextMenu->AppendSeparator();
1047 m_privateContextMenu->Append(wxID_SELECTALL, _("Select &All"));
1048 }
faa94f3e 1049
24eef584
SC
1050 if (m_privateContextMenu != NULL)
1051 PopupMenu(m_privateContextMenu);
1052}
1053
5ca0d812 1054bool wxTextCtrl::MacSetupCursor( const wxPoint& pt )
29b30405 1055{
0207e969 1056 if ( !GetPeer()->SetupCursor( pt ) )
f2c3f2a8
SC
1057 return wxWindow::MacSetupCursor( pt ) ;
1058 else
1059 return true ;
5ca0d812 1060}
a8d2fb31 1061
20b69855 1062#if !TARGET_API_MAC_OSX
24260aae 1063
5ca0d812 1064// user pane implementation
ef4a634b 1065
7d8268a1 1066void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part)
5ca0d812 1067{
24260aae 1068 GetPeer()->MacControlUserPaneDrawProc( part ) ;
29b30405
SC
1069}
1070
7d8268a1 1071wxInt16 wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
29b30405 1072{
24260aae 1073 return GetPeer()->MacControlUserPaneHitTestProc( x , y ) ;
29b30405
SC
1074}
1075
7d8268a1 1076wxInt16 wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
72055702 1077{
24260aae 1078 return GetPeer()->MacControlUserPaneTrackingProc( x , y , actionProc ) ;
72055702
SC
1079}
1080
7d8268a1 1081void wxTextCtrl::MacControlUserPaneIdleProc()
72055702 1082{
24260aae 1083 GetPeer()->MacControlUserPaneIdleProc( ) ;
72055702
SC
1084}
1085
7d8268a1 1086wxInt16 wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
72055702 1087{
24260aae 1088 return GetPeer()->MacControlUserPaneKeyDownProc( keyCode , charCode , modifiers ) ;
72055702
SC
1089}
1090
7d8268a1 1091void wxTextCtrl::MacControlUserPaneActivateProc(bool activating)
72055702 1092{
24260aae 1093 GetPeer()->MacControlUserPaneActivateProc( activating ) ;
72055702
SC
1094}
1095
7d8268a1 1096wxInt16 wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action)
72055702 1097{
24260aae 1098 return GetPeer()->MacControlUserPaneFocusProc( action ) ;
72055702
SC
1099}
1100
7d8268a1 1101void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info)
72055702 1102{
24260aae 1103 GetPeer()->MacControlUserPaneBackgroundProc( info ) ;
5ca0d812 1104}
24260aae 1105
20b69855 1106#endif
a8d2fb31 1107
5ca0d812
SC
1108// ----------------------------------------------------------------------------
1109// implementation base class
1110// ----------------------------------------------------------------------------
1111
0f7817ab
SC
1112wxMacTextControl::wxMacTextControl(wxTextCtrl* peer) :
1113 wxMacControl( peer )
5ca0d812 1114{
72055702
SC
1115}
1116
7d8268a1 1117wxMacTextControl::~wxMacTextControl()
72055702 1118{
72055702
SC
1119}
1120
89954433
VZ
1121void wxMacTextControl::SetStyle(long WXUNUSED(start),
1122 long WXUNUSED(end),
1123 const wxTextAttr& WXUNUSED(style))
72055702 1124{
72055702
SC
1125}
1126
7d8268a1 1127void wxMacTextControl::Copy()
72055702 1128{
72055702
SC
1129}
1130
7d8268a1 1131void wxMacTextControl::Cut()
72055702 1132{
72055702
SC
1133}
1134
7d8268a1 1135void wxMacTextControl::Paste()
72055702 1136{
72055702
SC
1137}
1138
7d8268a1
WS
1139bool wxMacTextControl::CanPaste() const
1140{
5ca0d812
SC
1141 return false ;
1142}
1143
89954433 1144void wxMacTextControl::SetEditable(bool WXUNUSED(editable))
72055702 1145{
7d8268a1 1146}
facd6764 1147
7d8268a1 1148wxTextPos wxMacTextControl::GetLastPosition() const
5ca0d812 1149{
faa94f3e 1150 return GetStringValue().length() ;
5ca0d812 1151}
facd6764 1152
44aa865d
SC
1153void wxMacTextControl::Replace( long from , long to , const wxString &val )
1154{
1155 SetSelection( from , to ) ;
fef981b4 1156 WriteText( val ) ;
44aa865d
SC
1157}
1158
1159void wxMacTextControl::Remove( long from , long to )
5ca0d812 1160{
44aa865d
SC
1161 SetSelection( from , to ) ;
1162 WriteText( wxEmptyString) ;
72055702
SC
1163}
1164
7d8268a1 1165void wxMacTextControl::Clear()
72055702 1166{
5ca0d812 1167 SetStringValue( wxEmptyString ) ;
72055702
SC
1168}
1169
7d8268a1 1170bool wxMacTextControl::CanUndo() const
72055702 1171{
5ca0d812
SC
1172 return false ;
1173}
587bc950 1174
a8d2fb31
DS
1175void wxMacTextControl::Undo()
1176{
1177}
5ca0d812
SC
1178
1179bool wxMacTextControl::CanRedo() const
1180{
1181 return false ;
7d8268a1 1182}
5ca0d812 1183
7d8268a1 1184void wxMacTextControl::Redo()
5ca0d812 1185{
72055702
SC
1186}
1187
89954433 1188long wxMacTextControl::XYToPosition(long WXUNUSED(x), long WXUNUSED(y)) const
72055702 1189{
5ca0d812
SC
1190 return 0 ;
1191}
72055702 1192
89954433
VZ
1193bool wxMacTextControl::PositionToXY(long WXUNUSED(pos),
1194 long *WXUNUSED(x),
1195 long *WXUNUSED(y)) const
5ca0d812
SC
1196{
1197 return false ;
72055702
SC
1198}
1199
7d8268a1
WS
1200void wxMacTextControl::ShowPosition( long WXUNUSED(pos) )
1201{
1202}
5ca0d812 1203
7d8268a1 1204int wxMacTextControl::GetNumberOfLines() const
7548762c 1205{
5ca0d812
SC
1206 ItemCount lines = 0 ;
1207 wxString content = GetStringValue() ;
1208 lines = 1;
fef981b4 1209
faa94f3e 1210 for (size_t i = 0; i < content.length() ; i++)
7548762c 1211 {
fef981b4
DS
1212 if (content[i] == '\r')
1213 lines++;
7548762c 1214 }
a8d2fb31 1215
5ca0d812
SC
1216 return lines ;
1217}
7548762c 1218
5ca0d812 1219wxString wxMacTextControl::GetLineText(long lineNo) const
7548762c 1220{
fef981b4 1221 // TODO: change this if possible to reflect real lines
5ca0d812 1222 wxString content = GetStringValue() ;
7d8268a1 1223
5ca0d812
SC
1224 // Find line first
1225 int count = 0;
faa94f3e 1226 for (size_t i = 0; i < content.length() ; i++)
7548762c 1227 {
5ca0d812
SC
1228 if (count == lineNo)
1229 {
1230 // Add chars in line then
1231 wxString tmp;
7d8268a1 1232
faa94f3e 1233 for (size_t j = i; j < content.length(); j++)
5ca0d812
SC
1234 {
1235 if (content[j] == '\n')
1236 return tmp;
7d8268a1 1237
5ca0d812
SC
1238 tmp += content[j];
1239 }
7d8268a1 1240
5ca0d812
SC
1241 return tmp;
1242 }
a8d2fb31 1243
fef981b4
DS
1244 if (content[i] == '\n')
1245 count++;
7548762c 1246 }
a8d2fb31 1247
5ca0d812
SC
1248 return wxEmptyString ;
1249}
7548762c 1250
a8d2fb31 1251int wxMacTextControl::GetLineLength(long lineNo) const
5ca0d812 1252{
fef981b4 1253 // TODO: change this if possible to reflect real lines
5ca0d812 1254 wxString content = GetStringValue() ;
7d8268a1 1255
5ca0d812
SC
1256 // Find line first
1257 int count = 0;
faa94f3e 1258 for (size_t i = 0; i < content.length() ; i++)
7548762c 1259 {
5ca0d812
SC
1260 if (count == lineNo)
1261 {
1262 // Count chars in line then
1263 count = 0;
faa94f3e 1264 for (size_t j = i; j < content.length(); j++)
5ca0d812
SC
1265 {
1266 count++;
a8d2fb31
DS
1267 if (content[j] == '\n')
1268 return count;
5ca0d812 1269 }
7d8268a1 1270
5ca0d812
SC
1271 return count;
1272 }
a8d2fb31 1273
fef981b4
DS
1274 if (content[i] == '\n')
1275 count++;
7548762c 1276 }
a8d2fb31 1277
5ca0d812
SC
1278 return 0 ;
1279}
7548762c 1280
5ca0d812
SC
1281// ----------------------------------------------------------------------------
1282// standard unicode control implementation
1283// ----------------------------------------------------------------------------
1284
1285#if TARGET_API_MAC_OSX
1286
ad604d0f
SC
1287// the current unicode textcontrol implementation has a bug : only if the control
1288// is currently having the focus, the selection can be retrieved by the corresponding
1289// data tag. So we have a mirroring using a member variable
1290// TODO : build event table using virtual member functions for wxMacControl
1291
1292static const EventTypeSpec unicodeTextControlEventList[] =
1293{
1294 { kEventClassControl , kEventControlSetFocusPart } ,
1295} ;
1296
1297static pascal OSStatus wxMacUnicodeTextControlControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1298{
1299 OSStatus result = eventNotHandledErr ;
1300 wxMacUnicodeTextControl* focus = (wxMacUnicodeTextControl*) data ;
1301 wxMacCarbonEvent cEvent( event ) ;
9eddec69 1302
ad604d0f
SC
1303 switch ( GetEventKind( event ) )
1304 {
1305 case kEventControlSetFocusPart :
1306 {
1307 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
1308 if ( controlPart == kControlFocusNoPart )
1309 {
1310 // about to loose focus -> store selection to field
1311 focus->GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &focus->m_selection );
1312 }
1313 result = CallNextEventHandler(handler,event) ;
1314 if ( controlPart != kControlFocusNoPart )
1315 {
1316 // about to gain focus -> set selection from field
1317 focus->SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &focus->m_selection );
1318 }
1319 break;
1320 }
1321 default:
1322 break ;
1323 }
9eddec69 1324
ad604d0f
SC
1325 return result ;
1326}
1327
1328static pascal OSStatus wxMacUnicodeTextControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
1329{
1330 OSStatus result = eventNotHandledErr ;
9eddec69 1331
ad604d0f
SC
1332 switch ( GetEventClass( event ) )
1333 {
1334 case kEventClassControl :
1335 result = wxMacUnicodeTextControlControlEventHandler( handler , event , data ) ;
1336 break ;
9eddec69 1337
ad604d0f
SC
1338 default :
1339 break ;
1340 }
1341 return result ;
1342}
1343
1344DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacUnicodeTextControlEventHandler )
1345
3f7f284d
RD
1346wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer ) : wxMacTextControl( wxPeer )
1347{
1348}
1349
0f7817ab 1350wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer,
ffafe6ca
DS
1351 const wxString& str,
1352 const wxPoint& pos,
1353 const wxSize& size, long style )
1354 : wxMacTextControl( wxPeer )
3f7f284d
RD
1355{
1356 Create( wxPeer, str, pos, size, style );
1357}
1358
1359bool wxMacUnicodeTextControl::Create( wxTextCtrl *wxPeer,
1360 const wxString& str,
1361 const wxPoint& pos,
1362 const wxSize& size, long style )
5ca0d812
SC
1363{
1364 m_font = wxPeer->GetFont() ;
1365 m_windowStyle = style ;
6239ee05 1366 m_selection.selStart = m_selection.selEnd = 0;
7d8268a1 1367 Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
5ca0d812 1368 wxString st = str ;
395480fb 1369 wxMacConvertNewlines10To13( &st ) ;
5ca0d812
SC
1370 wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
1371 CFStringRef cfr = cf ;
44cc96a8 1372
3f7f284d
RD
1373 m_valueTag = kControlEditTextCFStringTag ;
1374 CreateControl( wxPeer, &bounds, cfr );
7d8268a1 1375
5ca0d812 1376 if ( !(m_windowStyle & wxTE_MULTILINE) )
5ca0d812 1377 SetData<Boolean>( kControlEditTextPart , kControlEditTextSingleLineTag , true ) ;
ad604d0f
SC
1378
1379 InstallControlEventHandler( m_controlRef , GetwxMacUnicodeTextControlEventHandlerUPP(),
1380 GetEventTypeCount(unicodeTextControlEventList), unicodeTextControlEventList, this,
6239ee05 1381 NULL);
44cc96a8 1382
3f7f284d 1383 return true;
5ca0d812 1384}
7548762c 1385
5ca0d812 1386wxMacUnicodeTextControl::~wxMacUnicodeTextControl()
7548762c 1387{
7548762c
SC
1388}
1389
7d8268a1 1390void wxMacUnicodeTextControl::VisibilityChanged(bool shown)
7548762c 1391{
5ca0d812
SC
1392 if ( !(m_windowStyle & wxTE_MULTILINE) && shown )
1393 {
fef981b4
DS
1394 // work around a refresh issue insofar as not always the entire content is shown,
1395 // even if this would be possible
5ca0d812
SC
1396 ControlEditTextSelectionRec sel ;
1397 CFStringRef value = NULL ;
7548762c 1398
5ca0d812 1399 verify_noerr( GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
c88b7d28 1400 verify_noerr( GetData<CFStringRef>( 0, m_valueTag, &value ) );
5ca0d812
SC
1401 verify_noerr( SetData<CFStringRef>( 0, m_valueTag, &value ) );
1402 verify_noerr( SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
7d8268a1 1403
5ca0d812
SC
1404 CFRelease( value ) ;
1405 }
1406}
a8d2fb31 1407
7d8268a1 1408wxString wxMacUnicodeTextControl::GetStringValue() const
7548762c 1409{
5ca0d812 1410 wxString result ;
c88b7d28 1411 CFStringRef value = GetData<CFStringRef>(0, m_valueTag) ;
5ca0d812
SC
1412 if ( value )
1413 {
1414 wxMacCFStringHolder cf(value) ;
1415 result = cf.AsString() ;
1416 }
a8d2fb31 1417
2e7573f7 1418#if '\n' == 10
395480fb
SC
1419 wxMacConvertNewlines13To10( &result ) ;
1420#else
5ca0d812 1421 wxMacConvertNewlines10To13( &result ) ;
395480fb 1422#endif
a8d2fb31 1423
7548762c
SC
1424 return result ;
1425}
a8d2fb31 1426
c88b7d28 1427void wxMacUnicodeTextControl::SetStringValue( const wxString &str )
5ca0d812
SC
1428{
1429 wxString st = str ;
395480fb 1430 wxMacConvertNewlines10To13( &st ) ;
ffafe6ca 1431 wxMacCFStringHolder cf( st , m_font.GetEncoding() ) ;
0207e969 1432 verify_noerr( SetData<CFStringRef>( 0, m_valueTag , cf ) ) ;
5ca0d812 1433}
a8d2fb31 1434
3f7f284d
RD
1435void wxMacUnicodeTextControl::CreateControl( wxTextCtrl* peer, const Rect* bounds, CFStringRef cfr )
1436{
1437 Boolean isPassword = ( m_windowStyle & wxTE_PASSWORD ) != 0 ;
1438 if ( isPassword )
1439 {
1440 m_valueTag = kControlEditTextPasswordCFStringTag ;
1441 }
1442 OSStatus err = CreateEditUnicodeTextControl(
1443 MAC_WXHWND(peer->MacGetTopLevelWindowRef()), bounds , cfr ,
1444 isPassword , NULL , &m_controlRef ) ;
1445 verify_noerr( err );
1446}
1447
5ca0d812
SC
1448void wxMacUnicodeTextControl::Copy()
1449{
1450 SendHICommand( kHICommandCopy ) ;
1451}
a8d2fb31 1452
5ca0d812
SC
1453void wxMacUnicodeTextControl::Cut()
1454{
1455 SendHICommand( kHICommandCut ) ;
1456}
a8d2fb31 1457
5ca0d812
SC
1458void wxMacUnicodeTextControl::Paste()
1459{
1460 SendHICommand( kHICommandPaste ) ;
1461}
a8d2fb31 1462
5ca0d812
SC
1463bool wxMacUnicodeTextControl::CanPaste() const
1464{
1465 return true ;
1466}
a8d2fb31 1467
89954433 1468void wxMacUnicodeTextControl::SetEditable(bool WXUNUSED(editable))
5ca0d812 1469{
35d9ac06
SC
1470#if 0 // leads to problem because text cannot be selected anymore
1471 SetData<Boolean>( kControlEditTextPart , kControlEditTextLockedTag , (Boolean) !editable ) ;
1472#endif
5ca0d812 1473}
7548762c 1474
0207e969 1475void wxMacUnicodeTextControl::GetSelection( long* from, long* to ) const
7548762c 1476{
5ca0d812 1477 ControlEditTextSelectionRec sel ;
ad604d0f
SC
1478 if (HasFocus())
1479 verify_noerr( GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) ) ;
1480 else
1481 sel = m_selection ;
9eddec69 1482
0207e969
DS
1483 if ( from )
1484 *from = sel.selStart ;
1485 if ( to )
1486 *to = sel.selEnd ;
7548762c
SC
1487}
1488
7d8268a1 1489void wxMacUnicodeTextControl::SetSelection( long from , long to )
ef4a634b 1490{
5ca0d812 1491 ControlEditTextSelectionRec sel ;
ad604d0f
SC
1492 wxString result ;
1493 int textLength = 0 ;
1494 CFStringRef value = GetData<CFStringRef>(0, m_valueTag) ;
1495 if ( value )
1496 {
1497 wxMacCFStringHolder cf(value) ;
1832043f 1498 textLength = cf.AsString().length() ;
ad604d0f
SC
1499 }
1500
1a535eb9
SC
1501 if ((from == -1) && (to == -1))
1502 {
1503 from = 0 ;
9eddec69 1504 to = textLength ;
ad604d0f
SC
1505 }
1506 else
1507 {
1508 from = wxMin(textLength,wxMax(from,0)) ;
1509 to = wxMax(0,wxMin(textLength,to)) ;
1a535eb9 1510 }
a8d2fb31 1511
5ca0d812
SC
1512 sel.selStart = from ;
1513 sel.selEnd = to ;
ad604d0f
SC
1514 if ( HasFocus() )
1515 SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) ;
1516 else
1517 m_selection = sel;
5ca0d812 1518}
facd6764 1519
c88b7d28 1520void wxMacUnicodeTextControl::WriteText( const wxString& str )
5ca0d812
SC
1521{
1522 wxString st = str ;
395480fb 1523 wxMacConvertNewlines10To13( &st ) ;
0207e969
DS
1524
1525#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
ad604d0f
SC
1526 if ( HasFocus() )
1527 {
7548762c
SC
1528 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
1529 CFStringRef value = cf ;
5ca0d812 1530 SetData<CFStringRef>( 0, kControlEditTextInsertCFStringRefTag, &value );
ad604d0f 1531 }
df39467f 1532 else
ad604d0f
SC
1533#endif
1534 {
5ca0d812 1535 wxString val = GetStringValue() ;
7548762c
SC
1536 long start , end ;
1537 GetSelection( &start , &end ) ;
1538 val.Remove( start , end - start ) ;
1539 val.insert( start , str ) ;
5ca0d812 1540 SetStringValue( val ) ;
faa94f3e 1541 SetSelection( start + str.length() , start + str.length() ) ;
ad604d0f 1542 }
72055702
SC
1543}
1544
5ca0d812 1545#endif
facd6764 1546
5ca0d812
SC
1547// ----------------------------------------------------------------------------
1548// MLTE control implementation (common part)
1549// ----------------------------------------------------------------------------
facd6764 1550
a8d2fb31 1551// if MTLE is read only, no changes at all are allowed, not even from
5ca0d812
SC
1552// procedural API, in order to allow changes via API all the same we must undo
1553// the readonly status while we are executing, this class helps to do so
72055702 1554
5de694f0 1555class wxMacEditHelper
72055702 1556{
5ca0d812 1557public :
5de694f0 1558 wxMacEditHelper( TXNObject txn )
5ca0d812
SC
1559 {
1560 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1561 m_txn = txn ;
1562 TXNGetTXNObjectControls( m_txn , 1 , tag , m_data ) ;
1563 if ( m_data[0].uValue == kTXNReadOnly )
1564 {
1565 TXNControlData data[] = { { kTXNReadWrite } } ;
1566 TXNSetTXNObjectControls( m_txn , false , 1 , tag , data ) ;
1567 }
1568 }
a8d2fb31 1569
5de694f0 1570 ~wxMacEditHelper()
5ca0d812
SC
1571 {
1572 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1573 if ( m_data[0].uValue == kTXNReadOnly )
5ca0d812 1574 TXNSetTXNObjectControls( m_txn , false , 1 , tag , m_data ) ;
5ca0d812 1575 }
a8d2fb31 1576
fef981b4
DS
1577protected :
1578 TXNObject m_txn ;
1579 TXNControlData m_data[1] ;
5ca0d812 1580} ;
72055702 1581
ffafe6ca
DS
1582wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl *peer )
1583 : wxMacTextControl( peer )
789ae0cf 1584{
3dee36ae 1585 SetNeedsFocusRect( true ) ;
789ae0cf
SC
1586}
1587
7d8268a1 1588wxString wxMacMLTEControl::GetStringValue() const
72055702 1589{
5ca0d812
SC
1590 wxString result ;
1591 OSStatus err ;
1592 Size actualSize = 0;
c88b7d28 1593
5ca0d812
SC
1594 {
1595#if wxUSE_UNICODE
1596 Handle theText ;
c88b7d28 1597 err = TXNGetDataEncoded( m_txn, kTXNStartOffset, kTXNEndOffset, &theText, kTXNUnicodeTextData );
fef981b4 1598
5ca0d812 1599 // all done
fef981b4 1600 if ( err != noErr )
5ca0d812
SC
1601 {
1602 actualSize = 0 ;
1603 }
1604 else
1605 {
c88b7d28 1606 actualSize = GetHandleSize( theText ) / sizeof(UniChar) ;
5ca0d812
SC
1607 if ( actualSize > 0 )
1608 {
1609 wxChar *ptr = NULL ;
fef981b4 1610
7d8268a1 1611#if SIZEOF_WCHAR_T == 2
c88b7d28
DS
1612 ptr = new wxChar[actualSize + 1] ;
1613 wxStrncpy( ptr , (wxChar*)(*theText) , actualSize ) ;
5ca0d812 1614#else
c88b7d28 1615 SetHandleSize( theText, (actualSize + 1) * sizeof(UniChar) ) ;
5ca0d812
SC
1616 HLock( theText ) ;
1617 (((UniChar*)*theText)[actualSize]) = 0 ;
d9d488cf 1618 wxMBConvUTF16 converter ;
5ca0d812 1619 size_t noChars = converter.MB2WC( NULL , (const char*)*theText , 0 ) ;
88a7a4e1 1620 wxASSERT_MSG( noChars != wxCONV_FAILED, _T("Unable to count the number of characters in this string!") );
5ca0d812 1621 ptr = new wxChar[noChars + 1] ;
7d8268a1 1622
f3097709 1623 noChars = converter.MB2WC( ptr , (const char*)*theText , noChars + 1 ) ;
88a7a4e1 1624 wxASSERT_MSG( noChars != wxCONV_FAILED, _T("Conversion of string failed!") );
5ca0d812
SC
1625 ptr[noChars] = 0 ;
1626 HUnlock( theText ) ;
1627#endif
fef981b4 1628
5ca0d812
SC
1629 ptr[actualSize] = 0 ;
1630 result = wxString( ptr ) ;
c88b7d28 1631 delete [] ptr ;
5ca0d812 1632 }
a8d2fb31 1633
5ca0d812
SC
1634 DisposeHandle( theText ) ;
1635 }
1636#else
1637 Handle theText ;
c88b7d28 1638 err = TXNGetDataEncoded( m_txn , kTXNStartOffset, kTXNEndOffset, &theText, kTXNTextData );
0207e969 1639
5ca0d812 1640 // all done
0207e969 1641 if ( err != noErr )
5ca0d812
SC
1642 {
1643 actualSize = 0 ;
1644 }
1645 else
1646 {
1647 actualSize = GetHandleSize( theText ) ;
1648 if ( actualSize > 0 )
1649 {
1650 HLock( theText ) ;
1651 result = wxString( *theText , wxConvLocal , actualSize ) ;
1652 HUnlock( theText ) ;
1653 }
a8d2fb31 1654
5ca0d812
SC
1655 DisposeHandle( theText ) ;
1656 }
1657#endif
1658 }
a8d2fb31 1659
2e7573f7 1660#if '\n' == 10
395480fb
SC
1661 wxMacConvertNewlines13To10( &result ) ;
1662#else
5ca0d812 1663 wxMacConvertNewlines10To13( &result ) ;
395480fb 1664#endif
a8d2fb31 1665
5ca0d812 1666 return result ;
72055702
SC
1667}
1668
0207e969 1669void wxMacMLTEControl::SetStringValue( const wxString &str )
72055702 1670{
c88b7d28
DS
1671 wxString st = str;
1672 wxMacConvertNewlines10To13( &st );
395480fb 1673
5de694f0 1674 {
4f74e0d1
SC
1675#ifndef __LP64__
1676 wxMacWindowClipper c( m_peer ) ;
1677#endif
0207e969 1678
5de694f0 1679 {
c88b7d28
DS
1680 wxMacEditHelper help( m_txn );
1681 SetTXNData( st, kTXNStartOffset, kTXNEndOffset );
5de694f0 1682 }
0207e969 1683
fef981b4
DS
1684 TXNSetSelection( m_txn, 0, 0 );
1685 TXNShowSelection( m_txn, kTXNShowStart );
5de694f0 1686 }
5ca0d812 1687}
facd6764 1688
5ca0d812
SC
1689TXNFrameOptions wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle )
1690{
c88b7d28
DS
1691 TXNFrameOptions frameOptions = kTXNDontDrawCaretWhenInactiveMask;
1692
b7e28620 1693#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
c88b7d28 1694 frameOptions |= kTXNDoFontSubstitutionMask;
b7e28620 1695#endif
4d7528a1 1696
c88b7d28 1697 if ( ! (wxStyle & wxTE_NOHIDESEL) )
5ca0d812
SC
1698 frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ;
1699
c88b7d28
DS
1700 if ( wxStyle & (wxHSCROLL | wxTE_DONTWRAP) )
1701 frameOptions |= kTXNWantHScrollBarMask ;
1702
5ca0d812 1703 if ( wxStyle & wxTE_MULTILINE )
29e4a190 1704 {
c88b7d28 1705 frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
72055702 1706
c88b7d28 1707 if ( !(wxStyle & wxTE_NO_VSCROLL) )
5de694f0 1708 {
5ca0d812 1709 frameOptions |= kTXNWantVScrollBarMask ;
c88b7d28 1710
04c3457a
DS
1711 // The following code causes drawing problems on 10.4. Perhaps it can be restored for
1712 // older versions of the OS, but I'm not sure it's appropriate to put a grow icon here
1713 // anyways, as AFAIK users can't actually use it to resize the text ctrl.
1714// if ( frameOptions & kTXNWantHScrollBarMask )
1715// frameOptions |= kTXNDrawGrowIconMask ;
5de694f0 1716 }
5ca0d812
SC
1717 }
1718 else
c88b7d28 1719 {
5ca0d812 1720 frameOptions |= kTXNSingleLineOnlyMask ;
c88b7d28 1721 }
7d8268a1 1722
5ca0d812
SC
1723 return frameOptions ;
1724}
cfeff6f7 1725
89954433
VZ
1726void wxMacMLTEControl::AdjustCreationAttributes(const wxColour &background,
1727 bool WXUNUSED(visible))
5ca0d812 1728{
3dee36ae
WS
1729 TXNControlTag iControlTags[] =
1730 {
1731 kTXNDoFontSubstitution,
5de694f0
SC
1732 kTXNWordWrapStateTag ,
1733 };
3dee36ae
WS
1734 TXNControlData iControlData[] =
1735 {
c88b7d28
DS
1736 { true },
1737 { kTXNNoAutoWrap },
5de694f0 1738 };
3dee36ae 1739
5de694f0 1740 int toptag = WXSIZEOF( iControlTags ) ;
7d8268a1 1741
72055702
SC
1742 if ( m_windowStyle & wxTE_MULTILINE )
1743 {
c88b7d28
DS
1744 iControlData[1].uValue =
1745 (m_windowStyle & wxTE_DONTWRAP)
1746 ? kTXNNoAutoWrap
1747 : kTXNAutoWrap;
72055702 1748 }
0207e969 1749
ffafe6ca
DS
1750 OSStatus err = TXNSetTXNObjectControls( m_txn, false, toptag, iControlTags, iControlData ) ;
1751 verify_noerr( err );
facd6764 1752
fef981b4 1753 // setting the default font:
8e15e610 1754 // under 10.2 this causes a visible caret, therefore we avoid it
72055702 1755
8e15e610 1756 if ( UMAGetSystemVersion() >= 0x1030 )
72055702 1757 {
8e15e610
SC
1758 Str255 fontName ;
1759 SInt16 fontSize ;
1760 Style fontStyle ;
5ca0d812 1761
ffafe6ca 1762 GetThemeFont( kThemeSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
5ca0d812 1763
8e15e610
SC
1764 TXNTypeAttributes typeAttr[] =
1765 {
c88b7d28
DS
1766 { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } ,
1767 { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } ,
1768 { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } ,
8e15e610
SC
1769 } ;
1770
ffafe6ca
DS
1771 err = TXNSetTypeAttributes(
1772 m_txn, sizeof(typeAttr) / sizeof(TXNTypeAttributes),
1773 typeAttr, kTXNStartOffset, kTXNEndOffset );
1774 verify_noerr( err );
8e15e610 1775 }
3dee36ae 1776
5ca0d812
SC
1777 if ( m_windowStyle & wxTE_PASSWORD )
1778 {
ffafe6ca
DS
1779 UniChar c = 0x00A5 ;
1780 err = TXNEchoMode( m_txn , c , 0 , true );
1781 verify_noerr( err );
72055702 1782 }
5ca0d812
SC
1783
1784 TXNBackground tback;
1785 tback.bgType = kTXNBackgroundTypeRGB;
1786 tback.bg.color = MAC_WXCOLORREF( background.GetPixel() );
0207e969 1787 TXNSetBackground( m_txn , &tback );
a8d2fb31 1788
64bd657c
SC
1789#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
1790 if ( UMAGetSystemVersion() >= 0x1040 )
1791 {
1792 TXNCommandEventSupportOptions options ;
fef981b4 1793 if ( TXNGetCommandEventSupport( m_txn, &options ) == noErr )
64bd657c 1794 {
fef981b4
DS
1795 options |=
1796 kTXNSupportEditCommandProcessing
1797 | kTXNSupportEditCommandUpdating
fef981b4
DS
1798 | kTXNSupportFontCommandProcessing
1799 | kTXNSupportFontCommandUpdating;
9eddec69 1800
6239ee05
SC
1801 // only spell check when not read-only
1802 // use system options for the default
1803 bool checkSpelling = false ;
1804 if ( !(m_windowStyle & wxTE_READONLY) )
1805 {
1806#if wxUSE_SYSTEM_OPTIONS
1807 if ( wxSystemOptions::HasOption( wxMAC_TEXTCONTROL_USE_SPELL_CHECKER ) && (wxSystemOptions::GetOptionInt( wxMAC_TEXTCONTROL_USE_SPELL_CHECKER ) == 1) )
1808 {
1809 checkSpelling = true ;
1810 }
1811#endif
1812 }
1813
1814 if ( checkSpelling )
1815 options |=
1816 kTXNSupportSpellCheckCommandProcessing
1817 | kTXNSupportSpellCheckCommandUpdating;
1818
64bd657c
SC
1819 TXNSetCommandEventSupport( m_txn , options ) ;
1820 }
1821 }
1822#endif
72055702
SC
1823}
1824
7d8268a1 1825void wxMacMLTEControl::SetBackground( const wxBrush &brush )
7ea087b7
SC
1826{
1827 // currently only solid background are supported
1828 TXNBackground tback;
0207e969 1829
7ea087b7
SC
1830 tback.bgType = kTXNBackgroundTypeRGB;
1831 tback.bg.color = MAC_WXCOLORREF( brush.GetColour().GetPixel() );
0207e969 1832 TXNSetBackground( m_txn , &tback );
7ea087b7
SC
1833}
1834
0207e969 1835void wxMacMLTEControl::TXNSetAttribute( const wxTextAttr& style , long from , long to )
72055702 1836{
7d8268a1 1837 TXNTypeAttributes typeAttr[4] ;
5ca0d812 1838 RGBColor color ;
6239ee05
SC
1839 size_t typeAttrCount = 0 ;
1840
1841 TXNMargins margins;
1842 TXNControlTag controlTags[4];
1843 TXNControlData controlData[4];
1844 size_t controlAttrCount = 0;
1845
1846 TXNTab* tabs = NULL;
1847
1848 bool relayout = false;
fef981b4 1849
5ca0d812 1850 if ( style.HasFont() )
72055702 1851 {
6239ee05
SC
1852 wxASSERT( typeAttrCount < WXSIZEOF(typeAttr) );
1853 const wxFont &font = style.GetFont() ;
1854 typeAttr[typeAttrCount].tag = kTXNATSUIStyle ;
1855 typeAttr[typeAttrCount].size = kTXNATSUIStyleSize ;
1856 typeAttr[typeAttrCount].data.dataPtr = font.MacGetATSUStyle() ;
1857 typeAttrCount++ ;
5ca0d812 1858 }
fef981b4 1859
5ca0d812
SC
1860 if ( style.HasTextColour() )
1861 {
6239ee05 1862 wxASSERT( typeAttrCount < WXSIZEOF(typeAttr) );
5ca0d812 1863 color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ;
0207e969 1864
6239ee05
SC
1865 typeAttr[typeAttrCount].tag = kTXNQDFontColorAttribute ;
1866 typeAttr[typeAttrCount].size = kTXNQDFontColorAttributeSize ;
1867 typeAttr[typeAttrCount].data.dataPtr = (void*) &color ;
1868 typeAttrCount++ ;
72055702 1869 }
6239ee05
SC
1870
1871 if ( style.HasAlignment() )
1872 {
1873 wxASSERT( controlAttrCount < WXSIZEOF(controlTags) );
1874 SInt32 align;
1875
1876 switch ( style.GetAlignment() )
1877 {
1878 case wxTEXT_ALIGNMENT_LEFT:
1879 align = kTXNFlushLeft;
1880 break;
1881 case wxTEXT_ALIGNMENT_CENTRE:
1882 align = kTXNCenter;
1883 break;
1884 case wxTEXT_ALIGNMENT_RIGHT:
1885 align = kTXNFlushRight;
1886 break;
1887 case wxTEXT_ALIGNMENT_JUSTIFIED:
1888 align = kTXNFullJust;
1889 break;
1890 default :
1891 case wxTEXT_ALIGNMENT_DEFAULT:
1892 align = kTXNFlushDefault;
1893 break;
1894 }
1895
1896 controlTags[controlAttrCount] = kTXNJustificationTag ;
1897 controlData[controlAttrCount].sValue = align ;
1898 controlAttrCount++ ;
1899 }
1900
1901 if ( style.HasLeftIndent() || style.HasRightIndent() )
1902 {
1903 wxASSERT( controlAttrCount < WXSIZEOF(controlTags) );
1904 controlTags[controlAttrCount] = kTXNMarginsTag;
1905 controlData[controlAttrCount].marginsPtr = &margins;
1906 verify_noerr( TXNGetTXNObjectControls (m_txn, 1 ,
1907 &controlTags[controlAttrCount], &controlData[controlAttrCount]) );
1908 if ( style.HasLeftIndent() )
1909 {
1910 margins.leftMargin = style.GetLeftIndent() / 254.0 * 72 + 0.5;
1911 }
1912 if ( style.HasRightIndent() )
1913 {
1914 margins.rightMargin = style.GetRightIndent() / 254.0 * 72 + 0.5;
1915 }
1916 controlAttrCount++ ;
1917 }
1918
1919 if ( style.HasTabs() )
1920 {
1921 const wxArrayInt& tabarray = style.GetTabs();
1922 // unfortunately Mac only applies a tab distance, not individually different tabs
1923 controlTags[controlAttrCount] = kTXNTabSettingsTag;
1924 if ( tabarray.size() > 0 )
1925 controlData[controlAttrCount].tabValue.value = tabarray[0] / 254.0 * 72 + 0.5;
1926 else
1927 controlData[controlAttrCount].tabValue.value = 72 ;
fef981b4 1928
6239ee05
SC
1929 controlData[controlAttrCount].tabValue.tabType = kTXNLeftTab;
1930 controlAttrCount++ ;
1931 }
1932
1933 // unfortunately the relayout is not automatic
1934 if ( controlAttrCount > 0 )
1935 {
1936 verify_noerr( TXNSetTXNObjectControls (m_txn, false /* don't clear all */, controlAttrCount,
1937 controlTags, controlData) );
1938 relayout = true;
1939 }
1940
1941 if ( typeAttrCount > 0 )
1942 {
1943 verify_noerr( TXNSetTypeAttributes( m_txn , typeAttrCount, typeAttr, from , to ) );
1944 relayout = true;
1945 }
1946
1947 if ( tabs != NULL )
1948 {
1949 delete[] tabs;
1950 }
1951
1952 if ( relayout )
8623a883 1953 {
09660720 1954 TXNRecalcTextLayout( m_txn );
8623a883 1955 }
72055702
SC
1956}
1957
89954433
VZ
1958void wxMacMLTEControl::SetFont(const wxFont & font,
1959 const wxColour& foreground,
1960 long WXUNUSED(windowStyle))
72055702 1961{
0207e969
DS
1962 wxMacEditHelper help( m_txn ) ;
1963 TXNSetAttribute( wxTextAttr( foreground, wxNullColour, font ), kTXNStartOffset, kTXNEndOffset ) ;
72055702 1964}
a8d2fb31 1965
0207e969 1966void wxMacMLTEControl::SetStyle( long start, long end, const wxTextAttr& style )
7d8268a1 1967{
0207e969
DS
1968 wxMacEditHelper help( m_txn ) ;
1969 TXNSetAttribute( style, start, end ) ;
7d8268a1
WS
1970}
1971
1972void wxMacMLTEControl::Copy()
5ca0d812 1973{
0207e969 1974 TXNCopy( m_txn );
72055702
SC
1975}
1976
7d8268a1 1977void wxMacMLTEControl::Cut()
3a9fa0d6 1978{
0207e969 1979 TXNCut( m_txn );
3a9fa0d6
VZ
1980}
1981
7d8268a1 1982void wxMacMLTEControl::Paste()
72055702 1983{
0207e969 1984 TXNPaste( m_txn );
72055702
SC
1985}
1986
5ca0d812 1987bool wxMacMLTEControl::CanPaste() const
72055702 1988{
5ca0d812 1989 return TXNIsScrapPastable() ;
72055702
SC
1990}
1991
7d8268a1 1992void wxMacMLTEControl::SetEditable(bool editable)
72055702 1993{
5ca0d812
SC
1994 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1995 TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ;
c88b7d28 1996 TXNSetTXNObjectControls( m_txn, false, WXSIZEOF(tag), tag, data ) ;
5ca0d812 1997}
bd3169a7 1998
7d8268a1 1999wxTextPos wxMacMLTEControl::GetLastPosition() const
5ca0d812 2000{
7d8268a1 2001 wxTextPos actualsize = 0 ;
5ca0d812
SC
2002
2003 Handle theText ;
0207e969 2004 OSErr err = TXNGetDataEncoded( m_txn, kTXNStartOffset, kTXNEndOffset, &theText, kTXNTextData );
fef981b4
DS
2005
2006 // all done
2007 if ( err == noErr )
5ca0d812 2008 {
fef981b4
DS
2009 actualsize = GetHandleSize( theText ) ;
2010 DisposeHandle( theText ) ;
5ca0d812
SC
2011 }
2012 else
2013 {
fef981b4 2014 actualsize = 0 ;
5ca0d812
SC
2015 }
2016
2017 return actualsize ;
2018}
2019
44aa865d 2020void wxMacMLTEControl::Replace( long from , long to , const wxString &str )
5ca0d812
SC
2021{
2022 wxString value = str ;
395480fb 2023 wxMacConvertNewlines10To13( &value ) ;
5ca0d812 2024
5de694f0 2025 wxMacEditHelper help( m_txn ) ;
4f74e0d1 2026#ifndef __LP64__
0f7817ab 2027 wxMacWindowClipper c( m_peer ) ;
4f74e0d1 2028#endif
5ca0d812 2029
0207e969 2030 TXNSetSelection( m_txn, from, to ) ;
5ca0d812 2031 TXNClear( m_txn ) ;
0207e969 2032 SetTXNData( value, kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
5ca0d812
SC
2033}
2034
2035void wxMacMLTEControl::Remove( long from , long to )
2036{
4f74e0d1 2037#ifndef __LP64__
0f7817ab 2038 wxMacWindowClipper c( m_peer ) ;
4f74e0d1 2039#endif
5de694f0 2040 wxMacEditHelper help( m_txn ) ;
0207e969 2041 TXNSetSelection( m_txn , from , to ) ;
5ca0d812
SC
2042 TXNClear( m_txn ) ;
2043}
2044
2045void wxMacMLTEControl::GetSelection( long* from, long* to) const
2046{
6239ee05
SC
2047 TXNOffset f,t ;
2048 TXNGetSelection( m_txn , &f , &t ) ;
2049 *from = f;
2050 *to = t;
5ca0d812
SC
2051}
2052
7d8268a1 2053void wxMacMLTEControl::SetSelection( long from , long to )
5ca0d812 2054{
4f74e0d1 2055#ifndef __LP64__
0f7817ab 2056 wxMacWindowClipper c( m_peer ) ;
4f74e0d1 2057#endif
fef981b4
DS
2058
2059 // change the selection
5ca0d812 2060 if ((from == -1) && (to == -1))
0207e969 2061 TXNSelectAll( m_txn );
5ca0d812 2062 else
fef981b4 2063 TXNSetSelection( m_txn, from, to );
0207e969 2064
fef981b4 2065 TXNShowSelection( m_txn, kTXNShowStart );
5ca0d812
SC
2066}
2067
c88b7d28 2068void wxMacMLTEControl::WriteText( const wxString& str )
5ca0d812 2069{
5ca0d812 2070 wxString st = str ;
395480fb 2071 wxMacConvertNewlines10To13( &st ) ;
5ca0d812
SC
2072
2073 long start , end , dummy ;
0207e969 2074
5ca0d812 2075 GetSelection( &start , &dummy ) ;
4f74e0d1 2076#ifndef __LP64__
5de694f0 2077 wxMacWindowClipper c( m_peer ) ;
4f74e0d1 2078#endif
0207e969 2079
5de694f0
SC
2080 {
2081 wxMacEditHelper helper( m_txn ) ;
c88b7d28 2082 SetTXNData( st, kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
5de694f0 2083 }
a8d2fb31 2084
c88b7d28 2085 GetSelection( &dummy, &end ) ;
fef981b4
DS
2086
2087 // TODO: SetStyle( start , end , GetDefaultStyle() ) ;
5ca0d812
SC
2088}
2089
7d8268a1 2090void wxMacMLTEControl::Clear()
5ca0d812 2091{
4f74e0d1 2092#ifndef __LP64__
0f7817ab 2093 wxMacWindowClipper c( m_peer ) ;
4f74e0d1 2094#endif
0207e969 2095 wxMacEditHelper st( m_txn ) ;
5ca0d812 2096 TXNSetSelection( m_txn , kTXNStartOffset , kTXNEndOffset ) ;
c88b7d28 2097 TXNClear( m_txn ) ;
5ca0d812
SC
2098}
2099
7d8268a1 2100bool wxMacMLTEControl::CanUndo() const
5ca0d812
SC
2101{
2102 return TXNCanUndo( m_txn , NULL ) ;
2103}
2104
7d8268a1 2105void wxMacMLTEControl::Undo()
5ca0d812 2106{
7d8268a1
WS
2107 TXNUndo( m_txn ) ;
2108}
5ca0d812 2109
fef981b4 2110bool wxMacMLTEControl::CanRedo() const
5ca0d812
SC
2111{
2112 return TXNCanRedo( m_txn , NULL ) ;
7d8268a1 2113}
5ca0d812 2114
7d8268a1
WS
2115void wxMacMLTEControl::Redo()
2116{
5ca0d812
SC
2117 TXNRedo( m_txn ) ;
2118}
2119
7d8268a1 2120int wxMacMLTEControl::GetNumberOfLines() const
5ca0d812
SC
2121{
2122 ItemCount lines = 0 ;
fef981b4
DS
2123 TXNGetLineCount( m_txn, &lines ) ;
2124
5ca0d812
SC
2125 return lines ;
2126}
2127
2128long wxMacMLTEControl::XYToPosition(long x, long y) const
2129{
2130 Point curpt ;
fef981b4 2131 wxTextPos lastpos ;
7d8268a1 2132
fef981b4 2133 // TODO: find a better implementation : while we can get the
5ca0d812
SC
2134 // line metrics of a certain line, we don't get its starting
2135 // position, so it would probably be rather a binary search
2136 // for the start position
c88b7d28 2137 long xpos = 0, ypos = 0 ;
5ca0d812 2138 int lastHeight = 0 ;
5ca0d812 2139 ItemCount n ;
fef981b4
DS
2140
2141 lastpos = GetLastPosition() ;
ebe86b1e 2142 for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
bd3169a7
SC
2143 {
2144 if ( y == ypos && x == xpos )
2145 return n ;
7d8268a1 2146
ffafe6ca 2147 TXNOffsetToPoint( m_txn, n, &curpt ) ;
bd3169a7
SC
2148
2149 if ( curpt.v > lastHeight )
2150 {
2151 xpos = 0 ;
2152 if ( n > 0 )
2153 ++ypos ;
0207e969 2154
bd3169a7
SC
2155 lastHeight = curpt.v ;
2156 }
2157 else
2158 ++xpos ;
2159 }
a8d2fb31 2160
5ca0d812 2161 return 0 ;
72055702
SC
2162}
2163
c88b7d28 2164bool wxMacMLTEControl::PositionToXY( long pos, long *x, long *y ) const
72055702 2165{
bd3169a7 2166 Point curpt ;
fef981b4 2167 wxTextPos lastpos ;
7d8268a1 2168
fef981b4
DS
2169 if ( y )
2170 *y = 0 ;
2171 if ( x )
2172 *x = 0 ;
7d8268a1 2173
fef981b4 2174 lastpos = GetLastPosition() ;
bd3169a7
SC
2175 if ( pos <= lastpos )
2176 {
c88b7d28 2177 // TODO: find a better implementation - while we can get the
bd3169a7
SC
2178 // line metrics of a certain line, we don't get its starting
2179 // position, so it would probably be rather a binary search
2180 // for the start position
0207e969 2181 long xpos = 0, ypos = 0 ;
bd3169a7 2182 int lastHeight = 0 ;
bd3169a7 2183 ItemCount n ;
0207e969 2184
ebe86b1e 2185 for ( n = 0 ; n <= (ItemCount) pos ; ++n )
bd3169a7 2186 {
ffafe6ca 2187 TXNOffsetToPoint( m_txn, n, &curpt ) ;
bd3169a7
SC
2188
2189 if ( curpt.v > lastHeight )
2190 {
2191 xpos = 0 ;
2192 if ( n > 0 )
2193 ++ypos ;
0207e969 2194
bd3169a7
SC
2195 lastHeight = curpt.v ;
2196 }
2197 else
2198 ++xpos ;
2199 }
a8d2fb31 2200
fef981b4
DS
2201 if ( y )
2202 *y = ypos ;
2203 if ( x )
2204 *x = xpos ;
bd3169a7 2205 }
5ca0d812 2206
7d8268a1 2207 return false ;
72055702
SC
2208}
2209
7d8268a1 2210void wxMacMLTEControl::ShowPosition( long pos )
72055702 2211{
4f74e0d1
SC
2212 Point current, desired ;
2213 TXNOffset selstart, selend;
fef981b4 2214
4f74e0d1
SC
2215 TXNGetSelection( m_txn, &selstart, &selend );
2216 TXNOffsetToPoint( m_txn, selstart, &current );
2217 TXNOffsetToPoint( m_txn, pos, &desired );
fef981b4 2218
4f74e0d1
SC
2219 // TODO: use HIPoints for 10.3 and above
2220
2221 OSErr theErr = noErr;
2222 long dv = desired.v - current.v;
2223 long dh = desired.h - current.h;
2224 TXNShowSelection( m_txn, kTXNShowStart ) ; // NB: should this be kTXNShowStart or kTXNShowEnd ??
2225 theErr = TXNScroll( m_txn, kTXNScrollUnitsInPixels, kTXNScrollUnitsInPixels, &dv, &dh );
2226
2227 // there will be an error returned for classic MLTE implementation when the control is
2228 // invisible, but HITextView works correctly, so we don't assert that one
2229 // wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") );
5ca0d812
SC
2230}
2231
fef981b4 2232void wxMacMLTEControl::SetTXNData( const wxString& st, TXNOffset start, TXNOffset end )
5ca0d812
SC
2233{
2234#if wxUSE_UNICODE
2235#if SIZEOF_WCHAR_T == 2
1832043f 2236 size_t len = st.length() ;
fef981b4 2237 TXNSetData( m_txn, kTXNUnicodeTextData, (void*)st.wc_str(), len * 2, start, end );
5ca0d812 2238#else
d9d488cf 2239 wxMBConvUTF16 converter ;
c88b7d28
DS
2240 ByteCount byteBufferLen = converter.WC2MB( NULL, st.wc_str(), 0 ) ;
2241 UniChar *unibuf = (UniChar*)malloc( byteBufferLen ) ;
fef981b4
DS
2242 converter.WC2MB( (char*)unibuf, st.wc_str(), byteBufferLen ) ;
2243 TXNSetData( m_txn, kTXNUnicodeTextData, (void*)unibuf, byteBufferLen, start, end ) ;
7d8268a1 2244 free( unibuf ) ;
587bc950 2245#endif
5ca0d812 2246#else
c88b7d28 2247 wxCharBuffer text = st.mb_str( wxConvLocal ) ;
fef981b4 2248 TXNSetData( m_txn, kTXNTextData, (void*)text.data(), strlen( text ), start, end ) ;
7d8268a1 2249#endif
72055702
SC
2250}
2251
5ca0d812 2252wxString wxMacMLTEControl::GetLineText(long lineNo) const
72055702 2253{
5ca0d812 2254 wxString line ;
5ca0d812 2255
bd3169a7 2256 if ( lineNo < GetNumberOfLines() )
32b5be3d 2257 {
fef981b4
DS
2258 Point firstPoint;
2259 Fixed lineWidth, lineHeight, currentHeight;
2260 long ypos ;
7d8268a1 2261
ae25e5cc 2262 // get the first possible position in the control
ae25e5cc 2263 TXNOffsetToPoint(m_txn, 0, &firstPoint);
7d8268a1 2264
ae25e5cc
RN
2265 // Iterate through the lines until we reach the one we want,
2266 // adding to our current y pixel point position
fef981b4
DS
2267 ypos = 0 ;
2268 currentHeight = 0;
ae25e5cc 2269 while (ypos < lineNo)
32b5be3d 2270 {
ae25e5cc
RN
2271 TXNGetLineMetrics(m_txn, ypos++, &lineWidth, &lineHeight);
2272 currentHeight += lineHeight;
2273 }
7d8268a1 2274
eab19a7c 2275 Point thePoint = { firstPoint.v + (currentHeight >> 16), firstPoint.h + (0) };
ae25e5cc
RN
2276 TXNOffset theOffset;
2277 TXNPointToOffset(m_txn, thePoint, &theOffset);
7d8268a1 2278
ae25e5cc
RN
2279 wxString content = GetStringValue() ;
2280 Point currentPoint = thePoint;
fef981b4 2281 while (thePoint.v == currentPoint.v && theOffset < content.length())
ae25e5cc
RN
2282 {
2283 line += content[theOffset];
2284 TXNOffsetToPoint(m_txn, ++theOffset, &currentPoint);
21fd5529 2285 }
21fd5529 2286 }
fef981b4 2287
5ca0d812 2288 return line ;
72055702
SC
2289}
2290
ffafe6ca 2291int wxMacMLTEControl::GetLineLength(long lineNo) const
72055702 2292{
ae25e5cc
RN
2293 int theLength = 0;
2294
bd3169a7 2295 if ( lineNo < GetNumberOfLines() )
32b5be3d 2296 {
fef981b4
DS
2297 Point firstPoint;
2298 Fixed lineWidth, lineHeight, currentHeight;
ffafe6ca 2299 long ypos;
7d8268a1 2300
ae25e5cc 2301 // get the first possible position in the control
ae25e5cc 2302 TXNOffsetToPoint(m_txn, 0, &firstPoint);
7d8268a1 2303
ae25e5cc
RN
2304 // Iterate through the lines until we reach the one we want,
2305 // adding to our current y pixel point position
fef981b4
DS
2306 ypos = 0;
2307 currentHeight = 0;
ae25e5cc 2308 while (ypos < lineNo)
32b5be3d 2309 {
ae25e5cc
RN
2310 TXNGetLineMetrics(m_txn, ypos++, &lineWidth, &lineHeight);
2311 currentHeight += lineHeight;
2312 }
7d8268a1 2313
eab19a7c 2314 Point thePoint = { firstPoint.v + (currentHeight >> 16), firstPoint.h + (0) };
ae25e5cc
RN
2315 TXNOffset theOffset;
2316 TXNPointToOffset(m_txn, thePoint, &theOffset);
7d8268a1 2317
ae25e5cc
RN
2318 wxString content = GetStringValue() ;
2319 Point currentPoint = thePoint;
fef981b4 2320 while (thePoint.v == currentPoint.v && theOffset < content.length())
ae25e5cc
RN
2321 {
2322 ++theLength;
2323 TXNOffsetToPoint(m_txn, ++theOffset, &currentPoint);
29e4a190 2324 }
29e4a190 2325 }
fef981b4 2326
ae25e5cc 2327 return theLength ;
5ca0d812 2328}
21fd5529 2329
6239ee05 2330#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
4f74e0d1 2331
5ca0d812
SC
2332// ----------------------------------------------------------------------------
2333// MLTE control implementation (classic part)
2334// ----------------------------------------------------------------------------
21fd5529 2335
5de694f0
SC
2336// OS X Notes : We still don't have a full replacement for MLTE, so this implementation
2337// has to live on. We have different problems coming from outdated implementations on the
2338// various OS X versions. Most deal with the scrollbars: they are not correctly embedded
2339// while this can be solved on 10.3 by reassigning them the correct place, on 10.2 there is
2340// no way out, therefore we are using our own implementation and our own scrollbars ....
5ca0d812 2341
5de694f0 2342#ifdef __WXMAC_OSX__
0f7817ab 2343
5de694f0
SC
2344TXNScrollInfoUPP gTXNScrollInfoProc = NULL ;
2345ControlActionUPP gTXNScrollActionProc = NULL ;
0f7817ab 2346
fef981b4
DS
2347pascal void wxMacMLTEClassicControl::TXNScrollInfoProc(
2348 SInt32 iValue, SInt32 iMaximumValue,
0207e969 2349 TXNScrollBarOrientation iScrollBarOrientation, SInt32 iRefCon )
0f7817ab 2350{
5de694f0
SC
2351 wxMacMLTEClassicControl* mlte = (wxMacMLTEClassicControl*) iRefCon ;
2352 SInt32 value = wxMax( iValue , 0 ) ;
2353 SInt32 maximum = wxMax( iMaximumValue , 0 ) ;
3dee36ae 2354
5de694f0
SC
2355 if ( iScrollBarOrientation == kTXNHorizontal )
2356 {
2357 if ( mlte->m_sbHorizontal )
2358 {
2359 SetControl32BitValue( mlte->m_sbHorizontal , value ) ;
2360 SetControl32BitMaximum( mlte->m_sbHorizontal , maximum ) ;
2361 mlte->m_lastHorizontalValue = value ;
2362 }
2363 }
2364 else if ( iScrollBarOrientation == kTXNVertical )
5ca0d812 2365 {
5de694f0
SC
2366 if ( mlte->m_sbVertical )
2367 {
2368 SetControl32BitValue( mlte->m_sbVertical , value ) ;
2369 SetControl32BitMaximum( mlte->m_sbVertical , maximum ) ;
2370 mlte->m_lastVerticalValue = value ;
2371 }
72055702
SC
2372 }
2373}
2374
5de694f0 2375pascal void wxMacMLTEClassicControl::TXNScrollActionProc( ControlRef controlRef , ControlPartCode partCode )
72055702 2376{
5de694f0
SC
2377 wxMacMLTEClassicControl* mlte = (wxMacMLTEClassicControl*) GetControlReference( controlRef ) ;
2378 if ( mlte == NULL )
2379 return ;
3dee36ae 2380
5de694f0 2381 if ( controlRef != mlte->m_sbVertical && controlRef != mlte->m_sbHorizontal )
3dee36ae
WS
2382 return ;
2383
fef981b4 2384 OSStatus err ;
3dee36ae
WS
2385 bool isHorizontal = ( controlRef == mlte->m_sbHorizontal ) ;
2386
5de694f0
SC
2387 SInt32 minimum = 0 ;
2388 SInt32 maximum = GetControl32BitMaximum( controlRef ) ;
2389 SInt32 value = GetControl32BitValue( controlRef ) ;
2390 SInt32 delta = 0;
fef981b4 2391
5de694f0
SC
2392 switch ( partCode )
2393 {
2394 case kControlDownButtonPart :
2395 delta = 10 ;
2396 break ;
fef981b4 2397
5de694f0
SC
2398 case kControlUpButtonPart :
2399 delta = -10 ;
2400 break ;
fef981b4 2401
5de694f0
SC
2402 case kControlPageDownPart :
2403 delta = GetControlViewSize( controlRef ) ;
2404 break ;
fef981b4 2405
5de694f0 2406 case kControlPageUpPart :
fef981b4 2407 delta = -GetControlViewSize( controlRef ) ;
5de694f0 2408 break ;
fef981b4 2409
5de694f0 2410 case kControlIndicatorPart :
c88b7d28 2411 delta = value - (isHorizontal ? mlte->m_lastHorizontalValue : mlte->m_lastVerticalValue) ;
5de694f0 2412 break ;
fef981b4 2413
5de694f0
SC
2414 default :
2415 break ;
2416 }
fef981b4 2417
5de694f0 2418 if ( delta != 0 )
e600c175 2419 {
5de694f0 2420 SInt32 newValue = value ;
3dee36ae 2421
5de694f0
SC
2422 if ( partCode != kControlIndicatorPart )
2423 {
fef981b4 2424 if ( value + delta < minimum )
5de694f0
SC
2425 delta = minimum - value ;
2426 if ( value + delta > maximum )
2427 delta = maximum - value ;
2428
2429 SetControl32BitValue( controlRef , value + delta ) ;
2430 newValue = value + delta ;
2431 }
3dee36ae 2432
5de694f0
SC
2433 SInt32 verticalDelta = isHorizontal ? 0 : delta ;
2434 SInt32 horizontalDelta = isHorizontal ? delta : 0 ;
3dee36ae 2435
0207e969
DS
2436 err = TXNScroll(
2437 mlte->m_txn, kTXNScrollUnitsInPixels, kTXNScrollUnitsInPixels,
2438 &verticalDelta, &horizontalDelta );
ffafe6ca 2439 verify_noerr( err );
3dee36ae 2440
5de694f0
SC
2441 if ( isHorizontal )
2442 mlte->m_lastHorizontalValue = newValue ;
2443 else
2444 mlte->m_lastVerticalValue = newValue ;
5ca0d812 2445 }
5ca0d812 2446}
5de694f0 2447#endif
7d8268a1 2448
0f7817ab 2449// make correct activations
fef981b4 2450void wxMacMLTEClassicControl::MacActivatePaneText(bool setActive)
0f7817ab
SC
2451{
2452 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef);
ef4a634b 2453
5de694f0 2454 wxMacWindowClipper clipper( textctrl ) ;
c88b7d28 2455 TXNActivate( m_txn, m_txnFrameID, setActive );
0f7817ab 2456
5de694f0
SC
2457 ControlRef controlFocus = 0 ;
2458 GetKeyboardFocus( m_txnWindow , &controlFocus ) ;
2459 if ( controlFocus == m_controlRef )
fef981b4 2460 TXNFocus( m_txn, setActive );
5de694f0
SC
2461}
2462
fef981b4 2463void wxMacMLTEClassicControl::MacFocusPaneText(bool setFocus)
5de694f0 2464{
0207e969 2465 TXNFocus( m_txn, setFocus );
5ca0d812 2466}
1fa29bdc 2467
3dee36ae 2468// guards against inappropriate redraw (hidden objects drawing onto window)
0f7817ab 2469
fef981b4 2470void wxMacMLTEClassicControl::MacSetObjectVisibility(bool vis)
0f7817ab 2471{
789ae0cf
SC
2472 ControlRef controlFocus = 0 ;
2473 GetKeyboardFocus( m_txnWindow , &controlFocus ) ;
3dee36ae 2474
fef981b4 2475 if ( !vis && (controlFocus == m_controlRef ) )
789ae0cf 2476 SetKeyboardFocus( m_txnWindow , m_controlRef , kControlFocusNoPart ) ;
3dee36ae 2477
4611a719 2478 TXNControlTag iControlTags[1] = { kTXNVisibilityTag };
c88b7d28 2479 TXNControlData iControlData[1] = { { (UInt32)false } };
bd2213c2 2480
fef981b4 2481 verify_noerr( TXNGetTXNObjectControls( m_txn , 1, iControlTags, iControlData ) ) ;
3dee36ae 2482
bd2213c2
SC
2483 if ( iControlData[0].uValue != vis )
2484 {
2485 iControlData[0].uValue = vis ;
0207e969 2486 verify_noerr( TXNSetTXNObjectControls( m_txn, false , 1, iControlTags, iControlData ) ) ;
bd2213c2 2487 }
fef981b4 2488
0207e969
DS
2489 // currently, we always clip as partial visibility (overlapped) visibility is also a problem,
2490 // if we run into further problems we might set the FrameBounds to an empty rect here
5ca0d812 2491}
1fa29bdc 2492
0f7817ab 2493// make sure that the TXNObject is at the right position
5de694f0 2494
3dee36ae 2495void wxMacMLTEClassicControl::MacUpdatePosition()
0f7817ab 2496{
c88b7d28 2497 wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
0f7817ab
SC
2498 if ( textctrl == NULL )
2499 return ;
7d8268a1 2500
0f7817ab 2501 Rect bounds ;
c88b7d28 2502 UMAGetControlBoundsInWindowCoords( m_controlRef, &bounds );
3dee36ae 2503
ba75e603
SC
2504 wxRect visRect = textctrl->MacGetClippedClientRect() ;
2505 Rect visBounds = { visRect.y , visRect.x , visRect.y + visRect.height , visRect.x + visRect.width } ;
2506 int x , y ;
2507 x = y = 0 ;
2508 textctrl->MacWindowToRootWindow( &x , &y ) ;
2509 OffsetRect( &visBounds , x , y ) ;
3dee36ae 2510
c88b7d28 2511 if ( !EqualRect( &bounds, &m_txnControlBounds ) || !EqualRect( &visBounds, &m_txnVisBounds ) )
0f7817ab 2512 {
0f7817ab 2513 m_txnControlBounds = bounds ;
ba75e603 2514 m_txnVisBounds = visBounds ;
c88b7d28 2515 wxMacWindowClipper cl( textctrl ) ;
5de694f0 2516
4e477040
SC
2517#ifdef __WXMAC_OSX__
2518 if ( m_sbHorizontal || m_sbVertical )
2519 {
5de694f0
SC
2520 int w = bounds.right - bounds.left ;
2521 int h = bounds.bottom - bounds.top ;
4e477040
SC
2522
2523 if ( m_sbHorizontal )
2524 {
2525 Rect sbBounds ;
5de694f0 2526
4e477040 2527 sbBounds.left = -1 ;
5de694f0
SC
2528 sbBounds.top = h - 14 ;
2529 sbBounds.right = w + 1 ;
2530 sbBounds.bottom = h + 1 ;
3dee36ae 2531
4e477040 2532 SetControlBounds( m_sbHorizontal , &sbBounds ) ;
5de694f0 2533 SetControlViewSize( m_sbHorizontal , w ) ;
4e477040 2534 }
0207e969 2535
4e477040
SC
2536 if ( m_sbVertical )
2537 {
2538 Rect sbBounds ;
5de694f0
SC
2539
2540 sbBounds.left = w - 14 ;
4e477040 2541 sbBounds.top = -1 ;
5de694f0 2542 sbBounds.right = w + 1 ;
fef981b4 2543 sbBounds.bottom = m_sbHorizontal ? h - 14 : h + 1 ;
3dee36ae 2544
4e477040 2545 SetControlBounds( m_sbVertical , &sbBounds ) ;
5de694f0 2546 SetControlViewSize( m_sbVertical , h ) ;
4e477040
SC
2547 }
2548 }
3dee36ae 2549
c447d5a9
SC
2550 Rect oldviewRect ;
2551 TXNLongRect olddestRect ;
2552 TXNGetRectBounds( m_txn , &oldviewRect , &olddestRect , NULL ) ;
3dee36ae 2553
c447d5a9 2554 Rect viewRect = { m_txnControlBounds.top, m_txnControlBounds.left,
fef981b4
DS
2555 m_txnControlBounds.bottom - ( m_sbHorizontal ? 14 : 0 ) ,
2556 m_txnControlBounds.right - ( m_sbVertical ? 14 : 0 ) } ;
c447d5a9 2557 TXNLongRect destRect = { m_txnControlBounds.top, m_txnControlBounds.left,
fef981b4
DS
2558 m_txnControlBounds.bottom - ( m_sbHorizontal ? 14 : 0 ) ,
2559 m_txnControlBounds.right - ( m_sbVertical ? 14 : 0 ) } ;
3dee36ae 2560
c447d5a9
SC
2561 if ( olddestRect.right >= 10000 )
2562 destRect.right = destRect.left + 32000 ;
3dee36ae 2563
c447d5a9
SC
2564 if ( olddestRect.bottom >= 0x20000000 )
2565 destRect.bottom = destRect.top + 0x40000000 ;
3dee36ae
WS
2566
2567 SectRect( &viewRect , &visBounds , &viewRect ) ;
823c4e96 2568 TXNSetRectBounds( m_txn , &viewRect , &destRect , true ) ;
fef981b4
DS
2569
2570#if 0
2571 TXNSetFrameBounds(
2572 m_txn,
2573 m_txnControlBounds.top,
2574 m_txnControlBounds.left,
2575 m_txnControlBounds.bottom - (m_sbHorizontal ? 14 : 0),
2576 m_txnControlBounds.right - (m_sbVertical ? 14 : 0),
2577 m_txnFrameID );
2578#endif
5de694f0 2579#else
3dee36ae 2580
c88b7d28
DS
2581 TXNSetFrameBounds(
2582 m_txn, m_txnControlBounds.top, m_txnControlBounds.left,
2583 wxMax( m_txnControlBounds.bottom, m_txnControlBounds.top ),
2584 wxMax( m_txnControlBounds.right, m_txnControlBounds.left ), m_txnFrameID );
24eef584 2585#endif
c88b7d28
DS
2586
2587 // the SetFrameBounds method under Classic sometimes does not correctly scroll a selection into sight after a
5de694f0
SC
2588 // movement, therefore we have to force it
2589
fef981b4 2590 // this problem has been reported in OSX as well, so we use this here once again
0207e969 2591
5de694f0 2592 TXNLongRect textRect ;
3dee36ae 2593 TXNGetRectBounds( m_txn , NULL , NULL , &textRect ) ;
5de694f0 2594 if ( textRect.left < m_txnControlBounds.left )
fef981b4 2595 TXNShowSelection( m_txn , kTXNShowStart ) ;
e600c175 2596 }
5ca0d812
SC
2597}
2598
3dee36ae 2599void wxMacMLTEClassicControl::SetRect( Rect *r )
0f7817ab
SC
2600{
2601 wxMacControl::SetRect( r ) ;
2602 MacUpdatePosition() ;
2603}
2604
89954433 2605void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 WXUNUSED(thePart))
24260aae 2606{
c88b7d28 2607 wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
5ca0d812 2608 if ( textctrl == NULL )
e600c175 2609 return ;
7d8268a1 2610
5ca0d812
SC
2611 if ( textctrl->MacIsReallyShown() )
2612 {
2613 wxMacWindowClipper clipper( textctrl ) ;
0f7817ab 2614 TXNDraw( m_txn , NULL ) ;
e600c175 2615 }
5ca0d812
SC
2616}
2617
3dee36ae 2618wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
24260aae
SC
2619{
2620 Point where = { y , x } ;
a8d2fb31 2621 ControlPartCode result = kControlNoPart;
5de694f0 2622
0207e969 2623 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference( m_controlRef );
a8d2fb31 2624 if ( (textctrl != NULL) && textctrl->MacIsReallyShown() )
72055702 2625 {
fef981b4
DS
2626 if (PtInRect( where, &m_txnControlBounds ))
2627 {
5de694f0 2628 result = kControlEditTextPart ;
fef981b4 2629 }
7d8268a1 2630 else
3556e470
SC
2631 {
2632 // sometimes we get the coords also in control local coordinates, therefore test again
ab346e1c
VZ
2633 int x = 0 , y = 0 ;
2634 textctrl->MacClientToRootWindow( &x , &y ) ;
2635 where.h += x ;
2636 where.v += y ;
fef981b4 2637
0207e969 2638 if (PtInRect( where, &m_txnControlBounds ))
5de694f0 2639 result = kControlEditTextPart ;
3556e470 2640 }
5ca0d812 2641 }
a8d2fb31 2642
5ca0d812
SC
2643 return result;
2644}
2645
89954433 2646wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxInt16 y, void* WXUNUSED(actionProc) )
24260aae 2647{
a8d2fb31 2648 ControlPartCode result = kControlNoPart;
5de694f0 2649
0207e969 2650 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference( m_controlRef );
a8d2fb31 2651 if ( (textctrl != NULL) && textctrl->MacIsReallyShown() )
7d8268a1 2652 {
a8d2fb31 2653 Point startPt = { y , x } ;
ab346e1c 2654
5ca0d812 2655 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
ab346e1c
VZ
2656 int x = 0 , y = 0 ;
2657 textctrl->MacClientToRootWindow( &x , &y ) ;
2658 startPt.h += x ;
2659 startPt.v += y ;
7d8268a1 2660
24260aae 2661 switch (MacControlUserPaneHitTestProc( startPt.h , startPt.v ))
5ca0d812 2662 {
5de694f0 2663 case kControlEditTextPart :
7d8268a1
WS
2664 {
2665 wxMacWindowClipper clipper( textctrl ) ;
7d8268a1 2666 EventRecord rec ;
c88b7d28 2667
7d8268a1 2668 ConvertEventRefToEventRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
24260aae 2669 TXNClick( m_txn, &rec );
7d8268a1 2670 }
fef981b4 2671 break;
a8d2fb31 2672
fef981b4
DS
2673 default :
2674 break;
5ca0d812
SC
2675 }
2676 }
a8d2fb31
DS
2677
2678 return result;
5ca0d812
SC
2679}
2680
3dee36ae 2681void wxMacMLTEClassicControl::MacControlUserPaneIdleProc()
24260aae 2682{
c88b7d28 2683 wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
5ca0d812
SC
2684 if ( textctrl == NULL )
2685 return ;
24260aae 2686
3dee36ae 2687 if (textctrl->MacIsReallyShown())
24260aae 2688 {
3dee36ae 2689 if (IsControlActive(m_controlRef))
24260aae 2690 {
5ca0d812 2691 Point mousep;
7d8268a1 2692
5ca0d812
SC
2693 wxMacWindowClipper clipper( textctrl ) ;
2694 GetMouse(&mousep);
5de694f0
SC
2695
2696 TXNIdle(m_txn);
2697
3dee36ae 2698 if (PtInRect(mousep, &m_txnControlBounds))
24260aae 2699 {
fef981b4
DS
2700 RgnHandle theRgn = NewRgn();
2701 RectRgn(theRgn, &m_txnControlBounds);
5de694f0
SC
2702 TXNAdjustCursor(m_txn, theRgn);
2703 DisposeRgn(theRgn);
72055702 2704 }
5ca0d812
SC
2705 }
2706 }
2707}
72055702 2708
3dee36ae 2709wxInt16 wxMacMLTEClassicControl::MacControlUserPaneKeyDownProc (wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
24260aae 2710{
c88b7d28 2711 wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
5ca0d812 2712 if ( textctrl == NULL )
a8d2fb31 2713 return kControlNoPart;
7d8268a1 2714
5de694f0 2715 wxMacWindowClipper clipper( textctrl ) ;
ef4a634b 2716
5de694f0
SC
2717 EventRecord ev ;
2718 memset( &ev , 0 , sizeof( ev ) ) ;
2719 ev.what = keyDown ;
2720 ev.modifiers = modifiers ;
fef981b4
DS
2721 ev.message = ((keyCode << 8) & keyCodeMask) | (charCode & charCodeMask);
2722 TXNKeyDown( m_txn , &ev );
3dee36ae 2723
5de694f0
SC
2724 return kControlEntireControl;
2725}
24260aae 2726
c88b7d28 2727void wxMacMLTEClassicControl::MacControlUserPaneActivateProc(bool activating)
24260aae 2728{
5de694f0 2729 MacActivatePaneText( activating );
72055702
SC
2730}
2731
3dee36ae 2732wxInt16 wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action)
24260aae 2733{
c88b7d28 2734 ControlPartCode focusResult = kControlFocusNoPart;
7d8268a1 2735
c88b7d28 2736 wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
5ca0d812 2737 if ( textctrl == NULL )
c88b7d28 2738 return focusResult;
0f7817ab
SC
2739
2740 wxMacWindowClipper clipper( textctrl ) ;
3dee36ae 2741
a8d2fb31 2742 ControlRef controlFocus = NULL ;
5de694f0
SC
2743 GetKeyboardFocus( m_txnWindow , &controlFocus ) ;
2744 bool wasFocused = ( controlFocus == m_controlRef ) ;
2745
3dee36ae 2746 switch (action)
24260aae 2747 {
5de694f0
SC
2748 case kControlFocusPrevPart:
2749 case kControlFocusNextPart:
0207e969
DS
2750 MacFocusPaneText( !wasFocused );
2751 focusResult = (!wasFocused ? (ControlPartCode) kControlEditTextPart : (ControlPartCode) kControlFocusNoPart);
5de694f0 2752 break;
3dee36ae 2753
5ca0d812 2754 case kControlFocusNoPart:
5de694f0 2755 default:
a8d2fb31 2756 MacFocusPaneText( false );
5ca0d812
SC
2757 focusResult = kControlFocusNoPart;
2758 break;
5ca0d812 2759 }
0f7817ab 2760
5ca0d812 2761 return focusResult;
72055702
SC
2762}
2763
89954433 2764void wxMacMLTEClassicControl::MacControlUserPaneBackgroundProc( void *WXUNUSED(info) )
24260aae
SC
2765{
2766}
2767
0f7817ab 2768wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxTextCtrl *wxPeer,
ffafe6ca
DS
2769 const wxString& str,
2770 const wxPoint& pos,
2771 const wxSize& size, long style )
2772 : wxMacMLTEControl( wxPeer )
72055702 2773{
5ca0d812
SC
2774 m_font = wxPeer->GetFont() ;
2775 m_windowStyle = style ;
7d8268a1 2776 Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
72055702 2777
c88b7d28 2778 short featureSet =
0207e969
DS
2779 kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
2780 | kControlWantsActivate | kControlHandlesTracking
2781// | kControlHasSpecialBackground
2782 | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
72055702 2783
ffafe6ca
DS
2784 OSStatus err = ::CreateUserPaneControl(
2785 MAC_WXHWND(wxPeer->GetParent()->MacGetTopLevelWindowRef()),
2786 &bounds, featureSet, &m_controlRef );
2787 verify_noerr( err );
7d8268a1 2788
0f7817ab 2789 DoCreate();
7d8268a1 2790
a8d2fb31 2791 AdjustCreationAttributes( *wxWHITE , true ) ;
5ca0d812 2792
bd2213c2
SC
2793 MacSetObjectVisibility( wxPeer->MacIsReallyShown() ) ;
2794
24eef584
SC
2795 {
2796 wxString st = str ;
2797 wxMacConvertNewlines10To13( &st ) ;
2798 wxMacWindowClipper clipper( m_peer ) ;
2799 SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ;
0207e969 2800 TXNSetSelection( m_txn, 0, 0 ) ;
24eef584 2801 }
72055702
SC
2802}
2803
5ca0d812 2804wxMacMLTEClassicControl::~wxMacMLTEClassicControl()
72055702 2805{
0207e969 2806 TXNDeleteObject( m_txn );
5de694f0 2807 m_txn = NULL ;
72055702
SC
2808}
2809
7d8268a1 2810void wxMacMLTEClassicControl::VisibilityChanged(bool shown)
72055702 2811{
0f7817ab 2812 MacSetObjectVisibility( shown ) ;
4e477040
SC
2813 wxMacControl::VisibilityChanged( shown ) ;
2814}
2815
2816void wxMacMLTEClassicControl::SuperChangedPosition()
2817{
2818 MacUpdatePosition() ;
2819 wxMacControl::SuperChangedPosition() ;
72055702
SC
2820}
2821
24260aae
SC
2822#ifdef __WXMAC_OSX__
2823
5de694f0
SC
2824ControlUserPaneDrawUPP gTPDrawProc = NULL;
2825ControlUserPaneHitTestUPP gTPHitProc = NULL;
2826ControlUserPaneTrackingUPP gTPTrackProc = NULL;
2827ControlUserPaneIdleUPP gTPIdleProc = NULL;
2828ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
2829ControlUserPaneActivateUPP gTPActivateProc = NULL;
2830ControlUserPaneFocusUPP gTPFocusProc = NULL;
2831
24260aae
SC
2832static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
2833{
2834 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2835 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae 2836 if ( win )
ffafe6ca 2837 win->MacControlUserPaneDrawProc( part ) ;
24260aae
SC
2838}
2839
c7fe80e2 2840static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
24260aae
SC
2841{
2842 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2843 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae 2844 if ( win )
ffafe6ca 2845 return win->MacControlUserPaneHitTestProc( where.h , where.v ) ;
24260aae
SC
2846 else
2847 return kControlNoPart ;
2848}
2849
c7fe80e2 2850static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
24260aae
SC
2851{
2852 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2853 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae 2854 if ( win )
ffafe6ca 2855 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc ) ;
24260aae
SC
2856 else
2857 return kControlNoPart ;
2858}
2859
2860static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
2861{
2862 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2863 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae
SC
2864 if ( win )
2865 win->MacControlUserPaneIdleProc() ;
2866}
2867
2868static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
2869{
2870 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2871 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae 2872 if ( win )
ffafe6ca 2873 return win->MacControlUserPaneKeyDownProc( keyCode, charCode, modifiers ) ;
24260aae
SC
2874 else
2875 return kControlNoPart ;
2876}
2877
2878static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
2879{
2880 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2881 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae 2882 if ( win )
ffafe6ca 2883 win->MacControlUserPaneActivateProc( activating ) ;
24260aae
SC
2884}
2885
2886static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
2887{
2888 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2889 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae 2890 if ( win )
ffafe6ca 2891 return win->MacControlUserPaneFocusProc( action ) ;
24260aae
SC
2892 else
2893 return kControlNoPart ;
2894}
2895
fef981b4 2896#if 0
24260aae
SC
2897static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
2898{
2899 wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
bc8f7aee 2900 wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
24260aae
SC
2901 if ( win )
2902 win->MacControlUserPaneBackgroundProc(info) ;
2903}
2904#endif
2905
fef981b4
DS
2906#endif // __WXMAC_OSX__
2907
5de694f0
SC
2908// TXNRegisterScrollInfoProc
2909
5ca0d812 2910OSStatus wxMacMLTEClassicControl::DoCreate()
2b5f62a0 2911{
5ca0d812 2912 Rect bounds;
5ca0d812 2913 OSStatus err = noErr ;
7d8268a1 2914
fef981b4 2915 // set up our globals
24260aae
SC
2916#ifdef __WXMAC_OSX__
2917 if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(wxMacControlUserPaneDrawProc);
2918 if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(wxMacControlUserPaneHitTestProc);
2919 if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(wxMacControlUserPaneTrackingProc);
2920 if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(wxMacControlUserPaneIdleProc);
2921 if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(wxMacControlUserPaneKeyDownProc);
2922 if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(wxMacControlUserPaneActivateProc);
2923 if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(wxMacControlUserPaneFocusProc);
5de694f0
SC
2924
2925 if (gTXNScrollInfoProc == NULL ) gTXNScrollInfoProc = NewTXNScrollInfoUPP(TXNScrollInfoProc) ;
2926 if (gTXNScrollActionProc == NULL ) gTXNScrollActionProc = NewControlActionUPP(TXNScrollActionProc) ;
24260aae 2927#endif
7d8268a1 2928
fef981b4 2929 // set the initial settings for our private data
7d8268a1 2930
a8d2fb31 2931 m_txnWindow = GetControlOwner(m_controlRef);
5de694f0 2932 m_txnPort = (GrafPtr) GetWindowPort(m_txnWindow);
7d8268a1 2933
24260aae 2934#ifdef __WXMAC_OSX__
fef981b4 2935 // set up the user pane procedures
5ca0d812
SC
2936 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
2937 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
2938 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
2939 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
2940 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
2941 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
2942 SetControlData(m_controlRef, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
24260aae 2943#endif
c88b7d28 2944
fef981b4 2945 // calculate the rectangles used by the control
c88b7d28 2946 UMAGetControlBoundsInWindowCoords( m_controlRef, &bounds );
3dee36ae 2947
0f7817ab 2948 m_txnControlBounds = bounds ;
ba75e603 2949 m_txnVisBounds = bounds ;
3dee36ae 2950
fef981b4
DS
2951 CGrafPtr origPort ;
2952 GDHandle origDev ;
7d8268a1 2953
c88b7d28 2954 GetGWorld( &origPort, &origDev ) ;
fef981b4 2955 SetPort( m_txnPort );
7d8268a1 2956
fef981b4 2957 // create the new edit field
c88b7d28 2958 TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( m_windowStyle );
7d8268a1 2959
4e477040 2960#ifdef __WXMAC_OSX__
fef981b4
DS
2961 // the scrollbars are not correctly embedded but are inserted at the root:
2962 // this gives us problems as we have erratic redraws even over the structure area
4e477040 2963
5de694f0
SC
2964 m_sbHorizontal = 0 ;
2965 m_sbVertical = 0 ;
2966 m_lastHorizontalValue = 0 ;
2967 m_lastVerticalValue = 0 ;
3dee36ae 2968
5de694f0
SC
2969 Rect sb = { 0 , 0 , 0 , 0 } ;
2970 if ( frameOptions & kTXNWantVScrollBarMask )
2971 {
c88b7d28
DS
2972 CreateScrollBarControl( m_txnWindow, &sb, 0, 0, 100, 1, true, gTXNScrollActionProc, &m_sbVertical );
2973 SetControlReference( m_sbVertical, (SInt32)this );
5de694f0 2974 SetControlAction( m_sbVertical, gTXNScrollActionProc );
c88b7d28
DS
2975 ShowControl( m_sbVertical );
2976 EmbedControl( m_sbVertical , m_controlRef );
2977 frameOptions &= ~kTXNWantVScrollBarMask;
5de694f0 2978 }
fef981b4 2979
5de694f0
SC
2980 if ( frameOptions & kTXNWantHScrollBarMask )
2981 {
c88b7d28
DS
2982 CreateScrollBarControl( m_txnWindow, &sb, 0, 0, 100, 1, true, gTXNScrollActionProc, &m_sbHorizontal );
2983 SetControlReference( m_sbHorizontal, (SInt32)this );
5de694f0 2984 SetControlAction( m_sbHorizontal, gTXNScrollActionProc );
c88b7d28
DS
2985 ShowControl( m_sbHorizontal );
2986 EmbedControl( m_sbHorizontal, m_controlRef );
5de694f0
SC
2987 frameOptions &= ~(kTXNWantHScrollBarMask | kTXNDrawGrowIconMask);
2988 }
4e477040
SC
2989
2990#endif
2991
ffafe6ca
DS
2992 err = TXNNewObject(
2993 NULL, m_txnWindow, &bounds, frameOptions,
2994 kTXNTextEditStyleFrameType, kTXNTextensionFile, kTXNSystemDefaultEncoding,
2995 &m_txn, &m_txnFrameID, NULL );
2996 verify_noerr( err );
3dee36ae 2997
fef981b4
DS
2998#if 0
2999 TXNControlTag iControlTags[] = { kTXNUseCarbonEvents };
c88b7d28 3000 TXNControlData iControlData[] = { { (UInt32)&cInfo } };
fef981b4
DS
3001 int toptag = WXSIZEOF( iControlTags ) ;
3002 TXNCarbonEventInfo cInfo ;
55d0b180
SC
3003 cInfo.useCarbonEvents = false ;
3004 cInfo.filler = 0 ;
3005 cInfo.flags = 0 ;
3006 cInfo.fDictionary = NULL ;
3007
c88b7d28 3008 verify_noerr( TXNSetTXNObjectControls( m_txn, false, toptag, iControlTags, iControlData ) );
fef981b4 3009#endif
55d0b180 3010
4e477040 3011#ifdef __WXMAC_OSX__
c88b7d28 3012 TXNRegisterScrollInfoProc( m_txn, gTXNScrollInfoProc, (SInt32)this );
4e477040
SC
3013#endif
3014
0f7817ab 3015 SetGWorld( origPort , origDev ) ;
ffafe6ca 3016
5ca0d812 3017 return err;
facd6764 3018}
4f74e0d1 3019#endif
facd6764 3020
5ca0d812
SC
3021// ----------------------------------------------------------------------------
3022// MLTE control implementation (OSX part)
3023// ----------------------------------------------------------------------------
facd6764 3024
5ca0d812 3025#if TARGET_API_MAC_OSX
facd6764 3026
3b92f0e0
SC
3027#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
3028
09660720 3029// tiger multi-line textcontrols with no CR in the entire content
9eddec69 3030// don't scroll automatically, so we need a hack.
09660720
SC
3031// This attempt only works 'before' the key (ie before CallNextEventHandler)
3032// is processed, thus the scrolling always occurs one character too late, but
3033// better than nothing ...
3034
3035static const EventTypeSpec eventList[] =
3036{
3037 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
3038} ;
9eddec69 3039
09660720
SC
3040static pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
3041{
3042 OSStatus result = eventNotHandledErr ;
3043 wxMacMLTEHIViewControl* focus = (wxMacMLTEHIViewControl*) data ;
9eddec69 3044
09660720
SC
3045 switch ( GetEventKind( event ) )
3046 {
3047 case kEventTextInputUnicodeForKeyEvent :
3048 {
3049 if ( UMAGetSystemVersion() >= 0x1040 )
3050 {
3051 TXNOffset from , to ;
3052 TXNGetSelection( focus->GetTXNObject() , &from , &to ) ;
3053 if ( from == to )
3054 TXNShowSelection( focus->GetTXNObject() , kTXNShowStart );
3055 }
3056 result = CallNextEventHandler(handler,event);
3057 break;
3058 }
3059 default:
3060 break ;
3061 }
9eddec69 3062
09660720
SC
3063 return result ;
3064}
3065
3066static pascal OSStatus wxMacTextControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
3067{
3068 OSStatus result = eventNotHandledErr ;
9eddec69 3069
09660720
SC
3070 switch ( GetEventClass( event ) )
3071 {
3072 case kEventClassTextInput :
3073 result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
3074 break ;
9eddec69 3075
09660720
SC
3076 default :
3077 break ;
3078 }
3079 return result ;
3080}
3081
3082DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTextControlEventHandler )
3083
0f7817ab 3084wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl *wxPeer,
ffafe6ca
DS
3085 const wxString& str,
3086 const wxPoint& pos,
3087 const wxSize& size, long style ) : wxMacMLTEControl( wxPeer )
facd6764 3088{
5ca0d812
SC
3089 m_font = wxPeer->GetFont() ;
3090 m_windowStyle = style ;
7d8268a1 3091 Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
5ca0d812 3092 wxString st = str ;
395480fb 3093 wxMacConvertNewlines10To13( &st ) ;
7d8268a1 3094
ffafe6ca
DS
3095 HIRect hr = {
3096 { bounds.left , bounds.top },
3097 { bounds.right - bounds.left, bounds.bottom - bounds.top } } ;
facd6764 3098
5ca0d812
SC
3099 m_scrollView = NULL ;
3100 TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( style ) ;
6cfe4844 3101 if (( frameOptions & (kTXNWantVScrollBarMask | kTXNWantHScrollBarMask)) || !(frameOptions &kTXNSingleLineOnlyMask))
5ca0d812 3102 {
6cfe4844
SC
3103 if ( frameOptions & (kTXNWantVScrollBarMask | kTXNWantHScrollBarMask) )
3104 {
3105 HIScrollViewCreate(
3106 (frameOptions & kTXNWantHScrollBarMask ? kHIScrollViewOptionsHorizScroll : 0)
3107 | (frameOptions & kTXNWantVScrollBarMask ? kHIScrollViewOptionsVertScroll : 0) ,
3108 &m_scrollView ) ;
3109 }
3110 else
3111 {
3112 HIScrollViewCreate(kHIScrollViewOptionsVertScroll,&m_scrollView);
3113 HIScrollViewSetScrollBarAutoHide(m_scrollView,true);
3114 }
7d8268a1
WS
3115
3116 HIViewSetFrame( m_scrollView, &hr );
3117 HIViewSetVisible( m_scrollView, true );
5ca0d812 3118 }
7d8268a1 3119
5ca0d812
SC
3120 m_textView = NULL ;
3121 HITextViewCreate( NULL , 0, frameOptions , &m_textView ) ;
0207e969 3122 m_txn = HITextViewGetTXNObject( m_textView ) ;
5ca0d812
SC
3123 HIViewSetVisible( m_textView , true ) ;
3124 if ( m_scrollView )
3125 {
3126 HIViewAddSubview( m_scrollView , m_textView ) ;
3127 m_controlRef = m_scrollView ;
0207e969 3128 wxPeer->MacInstallEventHandler( (WXWidget) m_textView ) ;
5ca0d812
SC
3129 }
3130 else
3131 {
7d8268a1 3132 HIViewSetFrame( m_textView, &hr );
5ca0d812
SC
3133 m_controlRef = m_textView ;
3134 }
7d8268a1 3135
0f7817ab 3136 AdjustCreationAttributes( *wxWHITE , true ) ;
4f74e0d1 3137#ifndef __LP64__
0f7817ab 3138 wxMacWindowClipper c( m_peer ) ;
4f74e0d1 3139#endif
5ca0d812
SC
3140 SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ;
3141
fef981b4
DS
3142 TXNSetSelection( m_txn, 0, 0 );
3143 TXNShowSelection( m_txn, kTXNShowStart );
09660720
SC
3144
3145 InstallControlEventHandler( m_textView , GetwxMacTextControlEventHandlerUPP(),
3146 GetEventTypeCount(eventList), eventList, this,
6239ee05 3147 NULL);
09660720
SC
3148}
3149
3150wxMacMLTEHIViewControl::~wxMacMLTEHIViewControl()
3151{
facd6764
SC
3152}
3153
7d8268a1 3154OSStatus wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart )
facd6764 3155{
fef981b4 3156 return SetKeyboardFocus( GetControlOwner( m_textView ), m_textView, focusPart ) ;
facd6764
SC
3157}
3158
7d8268a1 3159bool wxMacMLTEHIViewControl::HasFocus() const
facd6764 3160{
5ca0d812 3161 ControlRef control ;
6239ee05
SC
3162 if ( GetUserFocusWindow() == NULL )
3163 return false;
3164
5ca0d812
SC
3165 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
3166 return control == m_textView ;
facd6764
SC
3167}
3168
44aa865d
SC
3169void wxMacMLTEHIViewControl::SetBackground( const wxBrush &brush )
3170{
3171 wxMacMLTEControl::SetBackground( brush ) ;
fef981b4
DS
3172
3173#if 0
44aa865d
SC
3174 CGColorSpaceRef rgbSpace = CGColorSpaceCreateDeviceRGB();
3175 RGBColor col = MAC_WXCOLORREF(brush.GetColour().GetPixel()) ;
3176
3177 float component[4] ;
3178 component[0] = col.red / 65536.0 ;
3179 component[1] = col.green / 65536.0 ;
3180 component[2] = col.blue / 65536.0 ;
3181 component[3] = 1.0 ; // alpha
0207e969 3182
ffafe6ca
DS
3183 CGColorRef color = CGColorCreate( rgbSpace , component );
3184 HITextViewSetBackgroundColor( m_textView , color );
44aa865d 3185 CGColorSpaceRelease( rgbSpace );
fef981b4 3186#endif
44aa865d
SC
3187}
3188
3b92f0e0
SC
3189#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
3190
3191
fedad417 3192#endif
5ca0d812
SC
3193
3194#endif // wxUSE_TEXTCTRL