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