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