1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "textctrl.h" 
  21   #include <sys/types.h> 
  27 #if wxUSE_STD_IOSTREAM 
  37 #include "wx/button.h" 
  38 #include "wx/toplevel.h" 
  39 #include "wx/textctrl.h" 
  40 #include "wx/notebook.h" 
  41 #include "wx/tabctrl.h" 
  42 #include "wx/settings.h" 
  43 #include "wx/filefn.h" 
  46 #if defined(__BORLANDC__) && !defined(__WIN32__) 
  48 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__) 
  55 #include <MacTextEditor.h> 
  56 #include "ATSUnicode.h" 
  57 #include "TextCommon.h" 
  58 #include "TextEncodingConverter.h" 
  59 #include "wx/mac/uma.h" 
  61 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL 
  63 extern wxControl 
*wxFindControlFromMacControl(ControlHandle inControl 
) ; 
  65 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon 
  66 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the 
  67 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have 
  68 // an alternate path for carbon key events that routes automatically into the same wx flow of events 
  70 #include "MacTextEditor.h" 
  74 /* kmUPTextPart is the part code we return to indicate the user has clicked 
  75     in the text area of our control */ 
  76 #define kmUPTextPart 1 
  78 /* kmUPScrollPart is the part code we return to indicate the user has clicked 
  79     in the scroll bar part of the control. */ 
  80 #define kmUPScrollPart 2 
  83 /* routines for using existing user pane controls. 
  84     These routines are useful for cases where you would like to use an 
  85     existing user pane control in, say, a dialog window as a scrolling 
  88 /* mUPOpenControl initializes a user pane control so it will be drawn 
  89     and will behave as a scrolling text edit field inside of a window. 
  90     This routine performs all of the initialization steps necessary, 
  91     except it does not create the user pane control itself.  theControl 
  92     should refer to a user pane control that you have either created 
  93     yourself or extracted from a dialog's control heirarchy using 
  94     the GetDialogItemAsControl routine.  */ 
  95 OSStatus 
mUPOpenControl(ControlHandle theControl
, long wxStyle
); 
  97 /* Utility Routines */ 
 103 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus 
 104     routine.  In our focus switching routine this part code is understood 
 105     as meaning 'the user has clicked in the control and we need to switch 
 106     the current focus to ourselves before we can continue'. */ 
 107 #define kUserClickedToFocusPart 100 
 110 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to 
 111     slow the speed of 'auto scrolling' inside of our clickloop routine. 
 112     This value prevents the text from wizzzzzing by while the mouse 
 113     is being held down inside of the text area. */ 
 114 #define kmUPClickScrollDelayTicks 3 
 117 /* STPTextPaneVars is a structure used for storing the the mUP Control's 
 118     internal variables and state information.  A handle to this record is 
 119     stored in the pane control's reference value field using the 
 120     SetControlReference routine. */ 
 123         /* OS records referenced */ 
 124     TXNObject fTXNRec
; /* the txn record */ 
 125     TXNFrameID fTXNFrame
; /* the txn frame ID */ 
 126     ControlHandle fUserPaneRec
;  /* handle to the user pane control */ 
 127     WindowPtr fOwner
; /* window containing control */ 
 128     GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */ 
 130     Boolean fInFocus
; /* true while the focus rect is drawn around the control */ 
 131     Boolean fIsActive
; /* true while the control is drawn in the active state */ 
 132     Boolean fTEActive
; /* reflects the activation state of the text edit record */ 
 133     Boolean fInDialogWindow
; /* true if displayed in a dialog window */ 
 134         /* calculated locations */ 
 135     Rect fRTextArea
; /* area where the text is drawn */ 
 136     Rect fRFocusOutline
;  /* rectangle used to draw the focus box */ 
 137     Rect fRTextOutline
; /* rectangle used to draw the border */ 
 138     RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */ 
 139         /* our focus advance override routine */ 
 140     EventHandlerUPP handlerUPP
; 
 141     EventHandlerRef handlerRef
; 
 148 /* Univerals Procedure Pointer variables used by the 
 149     mUP Control.  These variables are set up 
 150     the first time that mUPOpenControl is called. */ 
 151 ControlUserPaneDrawUPP gTPDrawProc 
= NULL
; 
 152 ControlUserPaneHitTestUPP gTPHitProc 
= NULL
; 
 153 ControlUserPaneTrackingUPP gTPTrackProc 
= NULL
; 
 154 ControlUserPaneIdleUPP gTPIdleProc 
= NULL
; 
 155 ControlUserPaneKeyDownUPP gTPKeyProc 
= NULL
; 
 156 ControlUserPaneActivateUPP gTPActivateProc 
= NULL
; 
 157 ControlUserPaneFocusUPP gTPFocusProc 
= NULL
; 
 159 /* TPActivatePaneText activates or deactivates the text edit record 
 160     according to the value of setActive.  The primary purpose of this 
 161     routine is to ensure each call is only made once. */ 
 162 static void TPActivatePaneText(STPTextPaneVars 
**tpvars
, Boolean setActive
) { 
 163     STPTextPaneVars 
*varsp
; 
 165     if (varsp
->fTEActive 
!= setActive
) { 
 167         varsp
->fTEActive 
= setActive
; 
 169         TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
); 
 172             TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
); 
 177 /* TPFocusPaneText set the focus state for the text record. */ 
 178 static void TPFocusPaneText(STPTextPaneVars 
**tpvars
, Boolean setFocus
) { 
 179     STPTextPaneVars 
*varsp
; 
 181     if (varsp
->fInFocus 
!= setFocus
) { 
 182         varsp
->fInFocus 
= setFocus
; 
 183         TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
); 
 188 /* TPPaneDrawProc is called to redraw the control and for update events 
 189     referring to the control.  This routine erases the text area's background, 
 190     and redraws the text.  This routine assumes the scroll bar has been 
 191     redrawn by a call to DrawControls. */ 
 192 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) { 
 193     STPTextPaneVars 
**tpvars
, *varsp
; 
 196         /* set up our globals */ 
 198     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 199     if (tpvars 
!= NULL
) { 
 200         state 
= HGetState((Handle
) tpvars
); 
 201         HLock((Handle
) tpvars
); 
 204             /* save the drawing state */ 
 205         SetPort((**tpvars
).fDrawingEnvironment
); 
 206            /* verify our boundary */ 
 207         GetControlBounds(theControl
, &bounds
); 
 209         wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 210         if ( ! EqualRect(&bounds
, &varsp
->fRFocusOutline
) ) { 
 211             // scrollbar is on the border, we add one 
 212             Rect oldbounds 
= varsp
->fRFocusOutline 
; 
 213             InsetRect( &oldbounds 
, -1 , -1 ) ; 
 215             if ( IsControlVisible( theControl 
) ) 
 216                 InvalWindowRect( GetControlOwner( theControl 
) , &oldbounds 
) ; 
 217             SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 218             SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 219             SetRect(&varsp
->fRTextArea
, bounds
.left 
+ 2 , bounds
.top 
+ (varsp
->fMultiline 
? 0 : 2) , 
 220                 bounds
.right 
- (varsp
->fMultiline 
? 0 : 2), bounds
.bottom 
- (varsp
->fMultiline 
? 0 : 2)); 
 221             RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
); 
 222             if ( IsControlVisible( theControl 
) ) 
 223                 TXNSetFrameBounds(  varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
, 
 224                     varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
); 
 226                 TXNSetFrameBounds(  varsp
->fTXNRec
, varsp
->fRTextArea
.top 
+ 30000 , varsp
->fRTextArea
.left 
+ 30000 , 
 227                     varsp
->fRTextArea
.bottom 
+ 30000 , varsp
->fRTextArea
.right 
+ 30000 , varsp
->fTXNFrame
); 
 231         if ( IsControlVisible( theControl 
) ) 
 233             /* update the text region */ 
 234             RGBColor white 
= { 65535 , 65535 , 65535 } ; 
 235             RGBBackColor( &white 
) ; 
 236             EraseRgn(varsp
->fTextBackgroundRgn
); 
 237             TXNDraw(varsp
->fTXNRec
, NULL
); 
 238                 /* restore the drawing environment */ 
 239                 /* draw the text frame and focus frame (if necessary) */ 
 240             DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive 
? kThemeStateActive
: kThemeStateInactive
); 
 241             if ((**tpvars
).fIsActive 
&& varsp
->fInFocus
)  
 242                 DrawThemeFocusRect(&varsp
->fRFocusOutline
, true); 
 243                 /* release our globals */ 
 244             HSetState((Handle
) tpvars
, state
); 
 250 /* TPPaneHitTestProc is called when the control manager would 
 251     like to determine what part of the control the mouse resides over. 
 252     We also call this routine from our tracking proc to determine how 
 253     to handle mouse clicks. */ 
 254 static pascal ControlPartCode 
TPPaneHitTestProc(ControlHandle theControl
, Point where
) { 
 255     STPTextPaneVars 
**tpvars
; 
 256     ControlPartCode result
; 
 258         /* set up our locals and lock down our globals*/ 
 260     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 261     if (tpvars 
!= NULL 
&& IsControlVisible( theControl
) ) { 
 262         state 
= HGetState((Handle
) tpvars
); 
 263         HLock((Handle
) tpvars
); 
 264             /* find the region where we clicked */ 
 265         if (PtInRect(where
, &(**tpvars
).fRTextArea
)) { 
 266             result 
= kmUPTextPart
; 
 268             /* release oure globals */ 
 269         HSetState((Handle
) tpvars
, state
); 
 278 /* TPPaneTrackingProc is called when the mouse is being held down 
 279     over our control.  This routine handles clicks in the text area 
 280     and in the scroll bar. */ 
 281 static pascal ControlPartCode 
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) { 
 282     STPTextPaneVars 
**tpvars
, *varsp
; 
 284     ControlPartCode partCodeResult
; 
 285         /* make sure we have some variables... */ 
 287     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 288     if (tpvars 
!= NULL 
&& IsControlVisible( theControl 
) ) { 
 290         state 
= HGetState((Handle
) tpvars
); 
 291         HLock((Handle
) tpvars
); 
 293             /* we don't do any of these functions unless we're in focus */ 
 294         if ( ! varsp
->fInFocus
) { 
 296             owner 
= GetControlOwner(theControl
); 
 297             ClearKeyboardFocus(owner
); 
 298             SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
); 
 300             /* find the location for the click */ 
 301         switch (TPPaneHitTestProc(theControl
, startPt
)) { 
 303                 /* handle clicks in the text part */ 
 305                 {   SetPort((**tpvars
).fDrawingEnvironment
); 
 306                     wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 308                     TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent()); 
 311                     ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec 
) ; 
 312                     TXNClick( varsp
->fTXNRec
, &rec 
); 
 319         HSetState((Handle
) tpvars
, state
); 
 321     return partCodeResult
; 
 325 /* TPPaneIdleProc is our user pane idle routine.  When our text field 
 326     is active and in focus, we use this routine to set the cursor. */ 
 327 static pascal void TPPaneIdleProc(ControlHandle theControl
) { 
 328     STPTextPaneVars 
**tpvars
, *varsp
; 
 330     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 331     if (tpvars 
!= NULL 
&& IsControlVisible( theControl 
) ) { 
 332             /* if we're not active, then we have nothing to say about the cursor */ 
 333         if ((**tpvars
).fIsActive
) { 
 337                 /* lock down the globals */ 
 338             state 
= HGetState((Handle
) tpvars
); 
 339             HLock((Handle
) tpvars
); 
 341                 /* get the current mouse coordinates (in our window) */ 
 342             SetPortWindowPort(GetControlOwner(theControl
)); 
 343             wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 345                 /* there's a 'focus thing' and an 'unfocused thing' */ 
 346             if (varsp
->fInFocus
) { 
 347                     /* flash the cursor */ 
 348                 SetPort((**tpvars
).fDrawingEnvironment
); 
 349                 TXNIdle(varsp
->fTXNRec
); 
 351                 if (PtInRect(mousep
, &varsp
->fRTextArea
)) { 
 353                     RectRgn((theRgn 
= NewRgn()), &varsp
->fRTextArea
); 
 354                     TXNAdjustCursor(varsp
->fTXNRec
, theRgn
); 
 359                  // SetThemeCursor(kThemeArrowCursor); 
 362                 /* if it's in our bounds, set the cursor */ 
 363                 GetControlBounds(theControl
, &bounds
); 
 364                 if (PtInRect(mousep
, &bounds
)) 
 366                 //    SetThemeCursor(kThemeArrowCursor); 
 370             HSetState((Handle
) tpvars
, state
); 
 376 /* TPPaneKeyDownProc is called whenever a keydown event is directed 
 377     at our control.  Here, we direct the keydown event to the text 
 378     edit record and redraw the scroll bar and text field as appropriate. */ 
 379 static pascal ControlPartCode 
TPPaneKeyDownProc(ControlHandle theControl
, 
 380                             SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) { 
 381     STPTextPaneVars 
**tpvars
; 
 382     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 383     if (tpvars 
!= NULL
) { 
 384         if ((**tpvars
).fInFocus
) { 
 385                 /* turn autoscrolling on and send the key event to text edit */ 
 386             SetPort((**tpvars
).fDrawingEnvironment
); 
 387             wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 389             memset( &ev 
, 0 , sizeof( ev 
) ) ; 
 391             ev
.modifiers 
= modifiers 
; 
 392             ev
.message 
= (( keyCode 
<< 8 ) & keyCodeMask 
) + ( charCode 
& charCodeMask 
) ; 
 393             TXNKeyDown( (**tpvars
).fTXNRec
, &ev
); 
 396     return kControlEntireControl
; 
 400 /* TPPaneActivateProc is called when the window containing 
 401     the user pane control receives activate events. Here, we redraw 
 402     the control and it's text as necessary for the activation state. */ 
 403 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) { 
 405     STPTextPaneVars 
**tpvars
, *varsp
; 
 408     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 409     if (tpvars 
!= NULL
) { 
 410         state 
= HGetState((Handle
) tpvars
); 
 411         HLock((Handle
) tpvars
); 
 413             /* de/activate the text edit record */ 
 414         SetPort((**tpvars
).fDrawingEnvironment
); 
 415         wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 416         GetControlBounds(theControl
, &bounds
); 
 417         varsp
->fIsActive 
= activating
; 
 418         TPActivatePaneText(tpvars
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 419             /* redraw the frame */ 
 420         if ( IsControlVisible( theControl 
) ) 
 422             DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive 
? kThemeStateActive
: kThemeStateInactive
); 
 424                 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
); 
 426         HSetState((Handle
) tpvars
, state
); 
 431 /* TPPaneFocusProc is called when every the focus changes to or 
 432     from our control.  Herein, switch the focus appropriately 
 433     according to the parameters and redraw the control as 
 435 static pascal ControlPartCode 
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) { 
 436     ControlPartCode focusResult
; 
 437     STPTextPaneVars 
**tpvars
, *varsp
; 
 440     focusResult 
= kControlFocusNoPart
; 
 441     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 442     if (tpvars 
!= NULL 
) { 
 443         state 
= HGetState((Handle
) tpvars
); 
 444         HLock((Handle
) tpvars
); 
 446             /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is 
 447             tabbing forwards (or shift tabbing backwards) through the items in the dialog, 
 448             and kControlFocusNextPart will be received.  When the user clicks in our field 
 449             and it is not the current focus, then the constant kUserClickedToFocusPart will 
 450             be received.  The constant kControlFocusNoPart will be received when our control 
 451             is the current focus and the user clicks in another control.  In your focus routine, 
 452             you should respond to these codes as follows: 
 454             kControlFocusNoPart - turn off focus and return kControlFocusNoPart.  redraw 
 455                 the control and the focus rectangle as necessary. 
 457             kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off 
 458                 depending on its current state.  redraw the control and the focus rectangle 
 459                 as appropriate for the new focus state.  If the focus state is 'off', return the constant 
 460                 kControlFocusNoPart, otherwise return a non-zero part code. 
 461             kUserClickedToFocusPart - is a constant defined for this example.  You should 
 462                 define your own value for handling click-to-focus type events. */ 
 463             /* save the drawing state */ 
 464         SetPort((**tpvars
).fDrawingEnvironment
); 
 465         wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 466             /* calculate the next highlight state */ 
 469             case kControlFocusNoPart
: 
 470                 TPFocusPaneText(tpvars
, false); 
 471                 focusResult 
= kControlFocusNoPart
; 
 473             case kUserClickedToFocusPart
: 
 474                 TPFocusPaneText(tpvars
, true); 
 477             case kControlFocusPrevPart
: 
 478             case kControlFocusNextPart
: 
 479                 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
)); 
 480                 focusResult 
= varsp
->fInFocus 
? 1 : kControlFocusNoPart
; 
 483         TPActivatePaneText(tpvars
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 484         /* redraw the text fram and focus rectangle to indicate the 
 486         if ( IsControlVisible( theControl 
) ) 
 488             DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive 
? kThemeStateActive
: kThemeStateInactive
); 
 489             DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 492         HSetState((Handle
) tpvars
, state
); 
 498 /* mUPOpenControl initializes a user pane control so it will be drawn 
 499     and will behave as a scrolling text edit field inside of a window. 
 500     This routine performs all of the initialization steps necessary, 
 501     except it does not create the user pane control itself.  theControl 
 502     should refer to a user pane control that you have either created 
 503     yourself or extracted from a dialog's control heirarchy using 
 504     the GetDialogItemAsControl routine.  */ 
 505 OSStatus 
mUPOpenControl(ControlHandle theControl
, long wxStyle 
) 
 509     STPTextPaneVars 
**tpvars
, *varsp
; 
 510     OSStatus err 
= noErr 
; 
 511     RGBColor rgbWhite 
= {0xFFFF, 0xFFFF, 0xFFFF}; 
 514         /* set up our globals */ 
 515     if (gTPDrawProc 
== NULL
) gTPDrawProc 
= NewControlUserPaneDrawUPP(TPPaneDrawProc
); 
 516     if (gTPHitProc 
== NULL
) gTPHitProc 
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
); 
 517     if (gTPTrackProc 
== NULL
) gTPTrackProc 
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
); 
 518     if (gTPIdleProc 
== NULL
) gTPIdleProc 
= NewControlUserPaneIdleUPP(TPPaneIdleProc
); 
 519     if (gTPKeyProc 
== NULL
) gTPKeyProc 
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
); 
 520     if (gTPActivateProc 
== NULL
) gTPActivateProc 
= NewControlUserPaneActivateUPP(TPPaneActivateProc
); 
 521     if (gTPFocusProc 
== NULL
) gTPFocusProc 
= NewControlUserPaneFocusUPP(TPPaneFocusProc
); 
 523         /* allocate our private storage */ 
 524     tpvars 
= (STPTextPaneVars 
**) NewHandleClear(sizeof(STPTextPaneVars
)); 
 525     SetControlReference(theControl
, (long) tpvars
); 
 526     HLock((Handle
) tpvars
); 
 528         /* set the initial settings for our private data */ 
 529     varsp
->fMultiline 
= wxStyle 
& wxTE_MULTILINE 
; 
 530     varsp
->fInFocus 
= false; 
 531     varsp
->fIsActive 
= true; 
 532     varsp
->fTEActive 
= true; // in order to get a deactivate 
 533     varsp
->fUserPaneRec 
= theControl
; 
 534     theWindow 
= varsp
->fOwner 
= GetControlOwner(theControl
); 
 536     varsp
->fDrawingEnvironment 
= (GrafPtr
)  GetWindowPort(theWindow
); 
 538     varsp
->fInDialogWindow 
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind 
); 
 539         /* set up the user pane procedures */ 
 540     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
); 
 541     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
); 
 542     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
); 
 543     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
); 
 544     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
); 
 545     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
); 
 546     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
); 
 547         /* calculate the rectangles used by the control */ 
 548     GetControlBounds(theControl
, &bounds
); 
 549     SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 550     SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 551     SetRect(&varsp
->fRTextArea
, bounds
.left 
+ 2 , bounds
.top 
+ (varsp
->fMultiline 
? 0 : 2) , 
 552         bounds
.right 
- (varsp
->fMultiline 
? 0 : 2), bounds
.bottom 
- (varsp
->fMultiline 
? 0 : 2)); 
 553         /* calculate the background region for the text.  In this case, it's kindof 
 554         and irregular region because we're setting the scroll bar a little ways inside 
 556     RectRgn((varsp
->fTextBackgroundRgn 
= NewRgn()), &varsp
->fRTextOutline
); 
 558         /* set up the drawing environment */ 
 559     SetPort(varsp
->fDrawingEnvironment
); 
 561         /* create the new edit field */ 
 563     TXNFrameOptions frameOptions 
= 
 564         kTXNDontDrawCaretWhenInactiveMask 
; 
 565     if ( ! ( wxStyle 
& wxTE_NOHIDESEL 
) ) 
 566         frameOptions 
|= kTXNDontDrawSelectionWhenInactiveMask 
; 
 568     if ( wxStyle 
& wxTE_MULTILINE 
) 
 570         if ( ! ( wxStyle 
& wxTE_DONTWRAP 
) ) 
 571             frameOptions 
|= kTXNAlwaysWrapAtViewEdgeMask 
; 
 574             frameOptions 
|= kTXNAlwaysWrapAtViewEdgeMask 
; 
 575             frameOptions 
|= kTXNWantHScrollBarMask 
; 
 578         if ( !(wxStyle 
& wxTE_NO_VSCROLL 
) ) 
 579             frameOptions 
|= kTXNWantVScrollBarMask 
; 
 582         frameOptions 
|= kTXNSingleLineOnlyMask 
; 
 584     if ( wxStyle 
& wxTE_READONLY 
) 
 585         frameOptions 
|= kTXNReadOnlyMask 
; 
 587     TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
, 
 589         kTXNTextEditStyleFrameType
, 
 591         kTXNSystemDefaultEncoding
, 
 592         &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
); 
 594     if ( !IsControlVisible( theControl 
) ) 
 595         TXNSetFrameBounds(  varsp
->fTXNRec
, varsp
->fRTextArea
.top 
+ 30000 , varsp
->fRTextArea
.left 
+ 30000 , 
 596             varsp
->fRTextArea
.bottom 
+ 30000 , varsp
->fRTextArea
.right 
+ 30000 , varsp
->fTXNFrame
); 
 599     if ( (wxStyle 
& wxTE_MULTILINE
) && (wxStyle 
& wxTE_DONTWRAP
) ) 
 601         TXNControlTag tag 
= kTXNWordWrapStateTag 
; 
 603         dat
.uValue 
= kTXNNoAutoWrap 
; 
 604         TXNSetTXNObjectControls( varsp
->fTXNRec 
, false , 1 , &tag 
, &dat 
) ; 
 610         GetThemeFont(kThemeSmallSystemFont 
, GetApplicationScript() , fontName 
, &fontSize 
, &fontStyle 
) ; 
 612         TXNTypeAttributes typeAttr
[] = 
 614             {   kTXNQDFontNameAttribute 
, kTXNQDFontNameAttributeSize 
, { (void*) fontName 
} } , 
 615             {   kTXNQDFontSizeAttribute 
, kTXNFontSizeAttributeSize 
, { (void*) (fontSize 
<< 16) } } , 
 616             {   kTXNQDFontStyleAttribute 
, kTXNQDFontStyleAttributeSize 
, {  (void*) normal 
} } , 
 619     err 
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr 
) / sizeof(TXNTypeAttributes
) , typeAttr
, 
 622         /* set the field's background */ 
 624     tback
.bgType 
= kTXNBackgroundTypeRGB
; 
 625     tback
.bg
.color 
= rgbWhite
; 
 626     TXNSetBackground( varsp
->fTXNRec
, &tback
); 
 628         /* unlock our storage */ 
 629     HUnlock((Handle
) tpvars
); 
 630         /* perform final activations and setup for our text field.  Here, 
 631         we assume that the window is going to be the 'active' window. */ 
 632     TPActivatePaneText(tpvars
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 640 #if !USE_SHARED_LIBRARY 
 641 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
) 
 643 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
) 
 644     EVT_DROP_FILES(wxTextCtrl::OnDropFiles
) 
 645     EVT_CHAR(wxTextCtrl::OnChar
) 
 646     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
 647     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
 648     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
 649     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
 650     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
 652     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
 653     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
 654     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
 655     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
 656     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
 661 void wxTextCtrl::Init() 
 665   m_macTXNvars 
= NULL 
; 
 666   m_macUsesTXN 
= false ; 
 671   m_maxLength 
= TE_UNLIMITED_LENGTH 
; 
 674 wxTextCtrl::~wxTextCtrl() 
 678         SetControlReference((ControlHandle
)m_macControl
, 0) ; 
 679         TXNDeleteObject((TXNObject
)m_macTXN
); 
 680         /* delete our private storage */ 
 681         DisposeHandle((Handle
) m_macTXNvars
); 
 682         /* zero the control reference */ 
 686 const short kVerticalMargin 
= 2 ; 
 687 const short kHorizontalMargin 
= 2 ; 
 689 bool wxTextCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
 692            const wxSize
& size
, long style
, 
 693            const wxValidator
& validator
, 
 694            const wxString
& name
) 
 698     m_macTXNvars 
= NULL 
; 
 699     m_macUsesTXN 
= false ; 
 702     m_macUsesTXN 
= ! (style 
& wxTE_PASSWORD 
) ; 
 704     m_macUsesTXN 
&= (TXNInitTextension 
!= (void*) kUnresolvedCFragSymbolAddress
) ; 
 706     // base initialization 
 707     if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style 
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) ) 
 710     wxSize mySize 
= size 
; 
 713         m_macHorizontalBorder 
= 5 ; // additional pixels around the real control 
 714         m_macVerticalBorder 
= 3 ; 
 718         m_macHorizontalBorder 
= 5 ; // additional pixels around the real control 
 719         m_macVerticalBorder 
= 5 ; 
 726     if ( mySize.y == -1 ) 
 729         if ( m_windowStyle & wxTE_MULTILINE ) 
 732         mySize.y += 2 * m_macVerticalBorder ; 
 735     MacPreControlCreate( parent 
, id 
,  wxEmptyString 
, pos 
, mySize 
,style
, validator 
, name 
, &bounds 
, title 
) ; 
 737     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
 739         wxASSERT_MSG( !(m_windowStyle 
& wxTE_PROCESS_ENTER
), 
 740                       wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") ); 
 742         m_windowStyle 
|= wxTE_PROCESS_ENTER
; 
 745     if ( m_windowStyle 
& wxTE_READONLY
) 
 751     st
.Replace(wxT("\n"), wxT("\r")); 
 754         m_macControl 
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds 
, "\p" , false , 0 , 0 , 1, 
 755             (style 
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc 
: kControlEditTextProc 
, (long) this ) ; 
 757         ::GetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextTEHandleTag 
, sizeof( TEHandle 
) , (char*)((TEHandle 
*)&m_macTE
) , &size 
) ; 
 764         featurSet 
= kControlSupportsEmbedding 
| kControlSupportsFocus  
| kControlWantsIdle
 
 765                 | kControlWantsActivate 
| kControlHandlesTracking 
| kControlHasSpecialBackground
 
 766                 | kControlGetsFocusOnClick 
| kControlSupportsLiveFeedback
; 
 767             /* create the control */ 
 768         m_macControl 
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0); 
 769             /* set up the mUP specific features and data */ 
 770         mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle 
); 
 772     MacPostControlCreate() ; 
 776         wxCharBuffer text 
= st
.mb_str(wxConvLocal
) ; 
 777         ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, strlen(text
) , text 
) ; 
 781         STPTextPaneVars 
**tpvars
; 
 783         tpvars 
= (STPTextPaneVars 
**) GetControlReference((ControlHandle
) m_macControl
); 
 784             /* set the text in the record */ 
 785         m_macTXN 
=  (**tpvars
).fTXNRec 
; 
 787         TXNSetData( ((TXNObject
) m_macTXN
) , kTXNUnicodeTextData
,  (void*)st
.wc_str(), st
.Length() * 2, 
 788           kTXNStartOffset
, kTXNEndOffset
); 
 790         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
)  ; 
 791         TXNSetData( ((TXNObject
) m_macTXN
) , kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
 792           kTXNStartOffset
, kTXNEndOffset
); 
 794         m_macTXNvars 
= tpvars 
; 
 795         m_macUsesTXN 
= true ; 
 796         TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0); 
 797         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
 803 wxString 
wxTextCtrl::GetValue() const 
 810         err 
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0, 
 811             ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag
, &actualSize 
) ; 
 814            return wxEmptyString 
; 
 816        if ( actualSize 
> 0 ) 
 818                 wxCharBuffer 
buf(actualSize
) ; 
 819             ::GetControlData( (ControlHandle
) m_macControl
, 0, 
 820                 ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag
, 
 821                 actualSize 
, buf
.data() , &actualSize 
) ; 
 822             result 
= wxString( buf 
, wxConvLocal
) ; 
 829         err 
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNUnicodeTextData 
); 
 837             actualSize 
= GetHandleSize( theText 
) ; 
 838             if ( actualSize 
> 0 ) 
 840                 wxChar 
*ptr 
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ; 
 841                 wxStrncpy( ptr 
, (wxChar
*) *theText 
, actualSize 
) ; 
 842                 ptr
[actualSize
] = 0 ; 
 843                 result
.UngetWriteBuf( actualSize 
) ; 
 845             DisposeHandle( theText 
) ; 
 849         err 
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNTextData 
); 
 857             actualSize 
= GetHandleSize( theText 
) ; 
 858             if ( actualSize 
> 0 ) 
 861                 result 
= wxString( *theText 
, wxConvLocal 
, actualSize 
) ; 
 864             DisposeHandle( theText 
) ; 
 868     result
.Replace(wxT("\r"),wxT("\n")) ; 
 872 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 876     *from 
= (**((TEHandle
) m_macTE
)).selStart
; 
 877     *to 
= (**((TEHandle
) m_macTE
)).selEnd
; 
 881         TXNGetSelection(  ((TXNObject
) m_macTXN
) , (TXNOffset
*) from 
, (TXNOffset
*) to 
) ; 
 885 void wxTextCtrl::SetValue(const wxString
& str
) 
 888     st
.Replace(wxT("\n"), wxT("\r")); 
 891         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
) ; 
 892         ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, strlen(text
) , text 
) ; 
 896         bool formerEditable 
= m_editable 
; 
 897         if ( !formerEditable 
) 
 900         TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
,  (void*)st
.wc_str(), st
.Length() * 2 , 
 901           kTXNStartOffset
, kTXNEndOffset
); 
 903         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
) ; 
 904         TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
 905           kTXNStartOffset
, kTXNEndOffset
); 
 907         TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0); 
 908         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
 909         if ( !formerEditable 
) 
 910             SetEditable(formerEditable
) ; 
 915 void wxTextCtrl::SetMaxLength(unsigned long len
) 
 920 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
) 
 924         bool formerEditable 
= m_editable 
; 
 925         if ( !formerEditable 
) 
 927         TXNTypeAttributes typeAttr
[4] ; 
 928         Str255 fontName 
= "\pMonaco" ; 
 929         SInt16 fontSize 
= 12 ; 
 930         Style fontStyle 
= normal 
; 
 932         int attrCounter 
= 0 ; 
 933         if ( style
.HasFont() ) 
 935             const wxFont 
&font 
= style
.GetFont() ; 
 936             wxMacStringToPascal( font
.GetFaceName() , fontName 
) ; 
 937             fontSize 
= font
.GetPointSize() ; 
 938             if ( font
.GetUnderlined() ) 
 939                 fontStyle 
|= underline 
; 
 940             if ( font
.GetWeight() == wxBOLD 
) 
 942             if ( font
.GetStyle() == wxITALIC 
) 
 943                 fontStyle 
|= italic 
; 
 945             typeAttr
[attrCounter
].tag 
= kTXNQDFontNameAttribute 
; 
 946             typeAttr
[attrCounter
].size 
= kTXNQDFontNameAttributeSize 
; 
 947             typeAttr
[attrCounter
].data
.dataPtr 
= (void*) fontName 
; 
 948             typeAttr
[attrCounter
+1].tag 
= kTXNQDFontSizeAttribute 
; 
 949             typeAttr
[attrCounter
+1].size 
= kTXNFontSizeAttributeSize 
; 
 950             typeAttr
[attrCounter
+1].data
.dataValue 
=  (fontSize 
<< 16) ; 
 951             typeAttr
[attrCounter
+2].tag 
= kTXNQDFontStyleAttribute 
; 
 952             typeAttr
[attrCounter
+2].size 
= kTXNQDFontStyleAttributeSize 
; 
 953             typeAttr
[attrCounter
+2].data
.dataValue 
= fontStyle 
; 
 957         if ( style
.HasTextColour() ) 
 959             typeAttr
[attrCounter
].tag 
= kTXNQDFontColorAttribute 
; 
 960             typeAttr
[attrCounter
].size 
= kTXNQDFontColorAttributeSize 
; 
 961             typeAttr
[attrCounter
].data
.dataPtr 
= (void*) &color 
; 
 962             color 
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ; 
 966         if ( attrCounter 
> 0 ) 
 970 #endif // __WXDEBUG__ 
 971                 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter 
, typeAttr
, start
,end
); 
 972             wxASSERT_MSG( status 
== noErr 
, wxT("Couldn't set text attributes") ) ; 
 974         if ( !formerEditable 
) 
 975             SetEditable(formerEditable
) ; 
 980 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
) 
 982     wxTextCtrlBase::SetDefaultStyle( style 
) ; 
 983     SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
 987 // Clipboard operations 
 988 void wxTextCtrl::Copy() 
 994             TECopy( ((TEHandle
) m_macTE
) ) ; 
1001             ClearCurrentScrap(); 
1002             TXNCopy((TXNObject
)m_macTXN
); 
1003             TXNConvertToPublicScrap(); 
1008 void wxTextCtrl::Cut() 
1012         if ( !m_macUsesTXN 
) 
1014             TECut( ((TEHandle
) m_macTE
) ) ; 
1015             ClearCurrentScrap(); 
1017             MacRedrawControl() ; 
1021             ClearCurrentScrap(); 
1022             TXNCut((TXNObject
)m_macTXN
); 
1023             TXNConvertToPublicScrap(); 
1025         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1026         event
.SetString( GetValue() ) ; 
1027         event
.SetEventObject( this ); 
1028         GetEventHandler()->ProcessEvent(event
); 
1032 void wxTextCtrl::Paste() 
1036         if ( !m_macUsesTXN 
) 
1039             TEPaste( (TEHandle
) m_macTE 
) ; 
1040             MacRedrawControl() ; 
1044             TXNConvertFromPublicScrap(); 
1045             TXNPaste((TXNObject
)m_macTXN
); 
1046             SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
1048         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1049         event
.SetString( GetValue() ) ; 
1050         event
.SetEventObject( this ); 
1051         GetEventHandler()->ProcessEvent(event
); 
1055 bool wxTextCtrl::CanCopy() const 
1057     // Can copy if there's a selection 
1059     GetSelection(& from
, & to
); 
1060     return (from 
!= to
); 
1063 bool wxTextCtrl::CanCut() const 
1065     if ( !IsEditable() ) 
1069     // Can cut if there's a selection 
1071     GetSelection(& from
, & to
); 
1072     return (from 
!= to
); 
1075 bool wxTextCtrl::CanPaste() const 
1081     OSStatus err 
= noErr
; 
1084     err 
= GetCurrentScrap( &scrapRef 
); 
1085     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
1087         ScrapFlavorFlags    flavorFlags
; 
1090         if (( err 
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags 
)) == noErr
) 
1092             if (( err 
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount 
)) == noErr
) 
1102     if ( GetScrap( NULL 
, 'TEXT' , &offset 
) > 0 ) 
1110 void wxTextCtrl::SetEditable(bool editable
) 
1112     if ( editable 
!= m_editable 
) 
1114         m_editable 
= editable 
; 
1115         if ( !m_macUsesTXN 
) 
1118                 UMAActivateControl( (ControlHandle
) m_macControl 
) ; 
1120                 UMADeactivateControl((ControlHandle
)  m_macControl 
) ; 
1124             TXNControlTag tag
[] = { kTXNIOPrivilegesTag 
} ; 
1125             TXNControlData data
[] = { { editable 
? kTXNReadWrite 
: kTXNReadOnly 
} } ; 
1126             TXNSetTXNObjectControls( (TXNObject
) m_macTXN 
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag 
, data 
) ; 
1131 void wxTextCtrl::SetInsertionPoint(long pos
) 
1133     SetSelection( pos 
, pos 
) ; 
1136 void wxTextCtrl::SetInsertionPointEnd() 
1138     long pos 
= GetLastPosition(); 
1139     SetInsertionPoint(pos
); 
1142 long wxTextCtrl::GetInsertionPoint() const 
1145     GetSelection( &begin 
, &end 
) ; 
1149 long wxTextCtrl::GetLastPosition() const 
1151     if ( !m_macUsesTXN 
) 
1153         return (**((TEHandle
) m_macTE
)).teLength 
; 
1159         OSErr err 
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNTextData 
); 
1167             actualsize 
= GetHandleSize( theText 
) ; 
1168             DisposeHandle( theText 
) ; 
1174 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
) 
1176     wxString value 
= str 
; 
1177     value
.Replace(wxT("\n"), wxT("\r")); 
1178     if ( !m_macUsesTXN 
) 
1180         ControlEditTextSelectionRec selection 
; 
1182         selection
.selStart 
= from 
; 
1183         selection
.selEnd 
= to 
; 
1184         ::SetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1185         TESetSelect( from 
, to  
, ((TEHandle
) m_macTE
) ) ; 
1186         TEDelete( ((TEHandle
) m_macTE
) ) ; 
1187         TEInsert( value 
, value
.Length() , ((TEHandle
) m_macTE
) ) ; 
1191         bool formerEditable 
= m_editable 
; 
1192         if ( !formerEditable 
) 
1194         TXNSetSelection( ((TXNObject
) m_macTXN
) , from 
, to 
) ; 
1195         TXNClear( ((TXNObject
) m_macTXN
) ) ; 
1197         TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
,  (void*)value
.wc_str(), value
.Length() * 2 , 
1198           kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1200         TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
,  (void*)value
.c_str(), value
.Length(), 
1201             kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1203         if ( !formerEditable 
) 
1204             SetEditable( formerEditable 
) ; 
1209 void wxTextCtrl::Remove(long from
, long to
) 
1211     if ( !m_macUsesTXN 
) 
1213         ControlEditTextSelectionRec selection 
; 
1215         selection
.selStart 
= from 
; 
1216         selection
.selEnd 
= to 
; 
1217         ::SetControlData( (ControlHandle
) m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1218         TEDelete( ((TEHandle
) m_macTE
) ) ; 
1222         bool formerEditable 
= m_editable 
; 
1223         if ( !formerEditable 
) 
1225         TXNSetSelection( ((TXNObject
) m_macTXN
) , from 
, to 
) ; 
1226         TXNClear( ((TXNObject
) m_macTXN
) ) ; 
1227         if ( !formerEditable 
) 
1228             SetEditable( formerEditable 
) ; 
1233 void wxTextCtrl::SetSelection(long from
, long to
) 
1235     if ( !m_macUsesTXN 
) 
1237         ControlEditTextSelectionRec selection 
; 
1238         if ((from 
== -1) && (to 
== -1)) 
1240                 selection
.selStart 
= 0 ; 
1241                 selection
.selEnd 
= 32767 ; 
1245                 selection
.selStart 
= from 
; 
1246                 selection
.selEnd 
= to 
; 
1249         TESetSelect( selection
.selStart 
, selection
.selEnd 
, ((TEHandle
) m_macTE
) ) ; 
1250         ::SetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1254         STPTextPaneVars 
**tpvars
; 
1255         /* set up our locals */ 
1256         tpvars 
= (STPTextPaneVars 
**) GetControlReference((ControlHandle
) m_macControl
); 
1257         /* and our drawing environment as the operation 
1258         may force a redraw in the text area. */ 
1259         SetPort((**tpvars
).fDrawingEnvironment
); 
1260         /* change the selection */ 
1261         if ((from 
== -1) && (to 
== -1)) 
1262                 TXNSelectAll((TXNObject
) m_macTXN
); 
1264                 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
); 
1265         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
1269 bool wxTextCtrl::LoadFile(const wxString
& file
) 
1271     if ( wxTextCtrlBase::LoadFile(file
) ) 
1279 void wxTextCtrl::WriteText(const wxString
& str
) 
1282     st
.Replace(wxT("\n"), wxT("\r")); 
1283     if ( !m_macUsesTXN 
) 
1285         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
) ; 
1286         TEInsert( text 
, strlen(text
) , ((TEHandle
) m_macTE
) ) ; 
1290         bool formerEditable 
= m_editable 
; 
1291         if ( !formerEditable 
) 
1293         long start 
, end 
, dummy 
; 
1294         GetSelection( &start 
, &dummy 
) ; 
1296         TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
,  (void*)st
.wc_str(), st
.Length() * 2 , 
1297           kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1299         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
) ; 
1300         TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
1301           kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1303         GetSelection( &dummy 
, &end 
) ; 
1304         SetStyle( start 
, end 
, GetDefaultStyle() ) ; 
1305         if ( !formerEditable 
) 
1306             SetEditable( formerEditable 
) ; 
1308     MacRedrawControl() ; 
1311 void wxTextCtrl::AppendText(const wxString
& text
) 
1313     SetInsertionPointEnd(); 
1317 void wxTextCtrl::Clear() 
1319     if ( !IsEditable() ) 
1323     if ( !m_macUsesTXN 
) 
1325         ::SetControlData((ControlHandle
)  m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, 0 , (char*) ((const char*)NULL
) ) ; 
1329         TXNSetSelection( (TXNObject
)m_macTXN 
, kTXNStartOffset 
, kTXNEndOffset 
) ; 
1330         TXNClear((TXNObject
)m_macTXN
); 
1335 bool wxTextCtrl::IsModified() const 
1340 bool wxTextCtrl::IsEditable() const 
1342     return IsEnabled() && m_editable 
; 
1345 bool wxTextCtrl::AcceptsFocus() const 
1347     // we don't want focus if we can't be edited 
1348     return /*IsEditable() && */ wxControl::AcceptsFocus(); 
1351 wxSize 
wxTextCtrl::DoGetBestSize() const 
1366     wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); 
1368     int wText = DEFAULT_ITEM_WIDTH; 
1370     int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); 
1372     return wxSize(wText, hText); 
1374     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
1378     hText 
+= 2 * m_macVerticalBorder 
; 
1379     wText 
+= 2 * m_macHorizontalBorder 
; 
1380     //else: for single line control everything is ok 
1381     return wxSize(wText
, hText
); 
1384 // ---------------------------------------------------------------------------- 
1386 // ---------------------------------------------------------------------------- 
1388 void wxTextCtrl::Undo() 
1394             TXNUndo((TXNObject
)m_macTXN
);  
1399 void wxTextCtrl::Redo() 
1405             TXNRedo((TXNObject
)m_macTXN
);  
1410 bool wxTextCtrl::CanUndo() const 
1412     if ( !IsEditable() )  
1418         return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);  
1423 bool wxTextCtrl::CanRedo() const 
1425     if ( !IsEditable() )  
1431         return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);  
1436 // Makes 'unmodified' 
1437 void wxTextCtrl::DiscardEdits() 
1442 int wxTextCtrl::GetNumberOfLines() const 
1444     // TODO change this if possible to reflect real lines 
1445     wxString content 
= GetValue() ; 
1448     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1450         if (content
[i
] == '\r') count
++; 
1456 long wxTextCtrl::XYToPosition(long x
, long y
) const 
1462 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const 
1467 void wxTextCtrl::ShowPosition(long pos
) 
1472 int wxTextCtrl::GetLineLength(long lineNo
) const 
1474     // TODO change this if possible to reflect real lines 
1475     wxString content 
= GetValue() ; 
1479     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1481         if (count 
== lineNo
) 
1483             // Count chars in line then 
1485             for (size_t j 
= i
; j 
< content
.Length(); j
++) 
1488                 if (content
[j
] == '\n') return count
; 
1493         if (content
[i
] == '\n') count
++; 
1498 wxString 
wxTextCtrl::GetLineText(long lineNo
) const 
1500     // TODO change this if possible to reflect real lines 
1501     wxString content 
= GetValue() ; 
1505     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1507         if (count 
== lineNo
) 
1509             // Add chars in line then 
1512             for (size_t j 
= i
; j 
< content
.Length(); j
++) 
1514                 if (content
[j
] == '\n') 
1522         if (content
[i
] == '\n') count
++; 
1524     return wxEmptyString 
; 
1531 void wxTextCtrl::Command(wxCommandEvent 
& event
) 
1533     SetValue (event
.GetString()); 
1534     ProcessCommand (event
); 
1537 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
) 
1539     // By default, load the first file into the text window. 
1540     if (event
.GetNumberOfFiles() > 0) 
1542         LoadFile(event
.GetFiles()[0]); 
1546 void wxTextCtrl::OnChar(wxKeyEvent
& event
) 
1548     int key 
= event
.GetKeyCode() ; 
1549     bool eat_key 
= false ; 
1551     if ( key 
== 'c' && event
.MetaDown() ) 
1558     if ( !IsEditable() && key 
!= WXK_LEFT 
&& key 
!= WXK_RIGHT 
&& key 
!= WXK_DOWN 
&& key 
!= WXK_UP 
&& key 
!= WXK_TAB 
&& 
1559         !( key 
== WXK_RETURN 
&& ( (m_windowStyle 
& wxPROCESS_ENTER
) || (m_windowStyle 
& wxTE_MULTILINE
) ) ) 
1560 /*        && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */ 
1567     // assume that any key not processed yet is going to modify the control 
1570     if ( key 
== 'v' && event
.MetaDown() ) 
1576     if ( key 
== 'x' && event
.MetaDown() ) 
1585             if (m_windowStyle 
& wxPROCESS_ENTER
) 
1587                 wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
1588                 event
.SetEventObject( this ); 
1589                 event
.SetString( GetValue() ); 
1590                 if ( GetEventHandler()->ProcessEvent(event
) ) 
1593             if ( !(m_windowStyle 
& wxTE_MULTILINE
) ) 
1595                 wxWindow 
*parent 
= GetParent(); 
1596                 while( parent 
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL 
) { 
1597                   parent 
= parent
->GetParent() ; 
1599                 if ( parent 
&& parent
->GetDefaultItem() ) 
1601                     wxButton 
*def 
= wxDynamicCast(parent
->GetDefaultItem(), 
1603                     if ( def 
&& def
->IsEnabled() ) 
1605                         wxCommandEvent 
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() ); 
1606                         event
.SetEventObject(def
); 
1607                         def
->Command(event
); 
1612                 // this will make wxWindows eat the ENTER key so that 
1613                 // we actually prevent line wrapping in a single line 
1621             // always produce navigation event - even if we process TAB 
1622             // ourselves the fact that we got here means that the user code 
1623             // decided to skip processing of this TAB - probably to let it 
1624             // do its default job. 
1626                 wxNavigationKeyEvent eventNav
; 
1627                 eventNav
.SetDirection(!event
.ShiftDown()); 
1628                 eventNav
.SetWindowChange(event
.ControlDown()); 
1629                 eventNav
.SetEventObject(this); 
1631                 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) ) 
1642         // perform keystroke handling 
1644         if ( m_macUsesTXN 
&& wxTheApp
->MacGetCurrentEvent() != NULL 
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL 
) 
1645             CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ; 
1649             if ( wxMacConvertEventToRecord(  (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec 
) ) 
1651                 EventRecord 
*ev 
= &rec 
; 
1654                 keychar 
= short(ev
->message 
& charCodeMask
); 
1655                 keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
1657                 ::HandleControlKey( (ControlHandle
) m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
1661         EventRecord 
*ev 
= (EventRecord
*) wxTheApp
->MacGetCurrentEvent() ; 
1664         keychar 
= short(ev
->message 
& charCodeMask
); 
1665         keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
1667         ::HandleControlKey( (ControlHandle
) m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
1670     if ( ( key 
>= 0x20 && key 
< WXK_START 
) || 
1671          key 
== WXK_RETURN 
|| 
1672          key 
== WXK_DELETE 
|| 
1675         wxCommandEvent 
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1676         event1
.SetString( GetValue() ) ; 
1677         event1
.SetEventObject( this ); 
1678         wxPostEvent(GetEventHandler(),event1
); 
1682 void  wxTextCtrl::MacSuperShown( bool show 
) 
1684     bool former 
= m_macControlIsShown 
; 
1685     wxControl::MacSuperShown( show 
) ; 
1686     if ( (former 
!= m_macControlIsShown
) && m_macUsesTXN 
) 
1688         if ( m_macControlIsShown 
) 
1689             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1690                 (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1692             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1693                (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1697 bool  wxTextCtrl::Show(bool show
) 
1699     bool former 
= m_macControlIsShown 
; 
1701     bool retval 
= wxControl::Show( show 
) ; 
1703     if ( former 
!= m_macControlIsShown 
&& m_macUsesTXN 
) 
1705         if ( m_macControlIsShown 
) 
1706             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1707                 (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1709             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1710                (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1716 // ---------------------------------------------------------------------------- 
1717 // standard handlers for standard edit menu events 
1718 // ---------------------------------------------------------------------------- 
1720 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
1725 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
1730 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
1735 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
1740 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
1745 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
1747     event
.Enable( CanCut() ); 
1750 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
1752     event
.Enable( CanCopy() ); 
1755 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
1757     event
.Enable( CanPaste() ); 
1760 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
1762     event
.Enable( CanUndo() ); 
1765 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
1767     event
.Enable( CanRedo() ); 
1770 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt 
) 
1775         return wxWindow::MacSetupCursor( pt 
) ;