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
) 
 752         m_macControl 
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds 
, "\p" , false , 0 , 0 , 1, 
 753             (style 
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc 
: kControlEditTextProc 
, (long) this ) ; 
 755         ::GetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextTEHandleTag 
, sizeof( TEHandle 
) , (char*)((TEHandle 
*)&m_macTE
) , &size 
) ; 
 762         featurSet 
= kControlSupportsEmbedding 
| kControlSupportsFocus  
| kControlWantsIdle
 
 763                 | kControlWantsActivate 
| kControlHandlesTracking 
| kControlHasSpecialBackground
 
 764                 | kControlGetsFocusOnClick 
| kControlSupportsLiveFeedback
; 
 765             /* create the control */ 
 766         m_macControl 
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0); 
 767             /* set up the mUP specific features and data */ 
 768         mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle 
); 
 770     MacPostControlCreate() ; 
 774         wxCharBuffer text 
= wxMacStringToCString( st 
) ; 
 775         ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, strlen(text
) , text 
) ; 
 779         STPTextPaneVars 
**tpvars
; 
 781         tpvars 
= (STPTextPaneVars 
**) GetControlReference((ControlHandle
) m_macControl
); 
 782             /* set the text in the record */ 
 783         m_macTXN 
=  (**tpvars
).fTXNRec 
; 
 785         TXNSetData( ((TXNObject
) m_macTXN
) , kTXNUnicodeTextData
,  (void*)st
.wc_str(), st
.Length() * 2, 
 786           kTXNStartOffset
, kTXNEndOffset
); 
 788         wxCharBuffer text 
= wxMacStringToCString( st 
) ; 
 789         TXNSetData( ((TXNObject
) m_macTXN
) , kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
 790           kTXNStartOffset
, kTXNEndOffset
); 
 792         m_macTXNvars 
= tpvars 
; 
 793         m_macUsesTXN 
= true ; 
 794         TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0); 
 795         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
 801 wxString 
wxTextCtrl::GetValue() const 
 808         err 
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0, 
 809             ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag
, &actualSize 
) ; 
 812            return wxEmptyString 
; 
 814        if ( actualSize 
> 0 ) 
 816                 wxCharBuffer 
buf(actualSize
) ; 
 817             ::GetControlData( (ControlHandle
) m_macControl
, 0, 
 818                 ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag
, 
 819                 actualSize 
, buf
.data() , &actualSize 
) ; 
 820             result 
= wxMacMakeStringFromCString( buf 
) ; 
 827         err 
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNUnicodeTextData 
); 
 835             actualSize 
= GetHandleSize( theText 
) ; 
 836             if ( actualSize 
> 0 ) 
 838                 wxChar 
*ptr 
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ; 
 839                 wxStrncpy( ptr 
, (wxChar
*) *theText 
, actualSize 
) ; 
 840                 ptr
[actualSize
] = 0 ; 
 841                 result
.UngetWriteBuf( actualSize 
) ; 
 843             DisposeHandle( theText 
) ; 
 847         err 
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNTextData 
); 
 855             actualSize 
= GetHandleSize( theText 
) ; 
 856             if ( actualSize 
> 0 ) 
 859                 result 
= wxMacMakeStringFromCString( *theText 
, actualSize 
) ; 
 862             DisposeHandle( theText 
) ; 
 870 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 874     *from 
= (**((TEHandle
) m_macTE
)).selStart
; 
 875     *to 
= (**((TEHandle
) m_macTE
)).selEnd
; 
 879         TXNGetSelection(  ((TXNObject
) m_macTXN
) , (TXNOffset
*) from 
, (TXNOffset
*) to 
) ; 
 883 void wxTextCtrl::SetValue(const wxString
& st
) 
 887         wxCharBuffer text 
= wxMacStringToCString( st 
) ; 
 888         ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, strlen(text
) , text 
) ; 
 892         bool formerEditable 
= m_editable 
; 
 893         if ( !formerEditable 
) 
 896         TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
,  (void*)st
.wc_str(), st
.Length() * 2 , 
 897           kTXNStartOffset
, kTXNEndOffset
); 
 899         wxCharBuffer text 
= wxMacStringToCString( st 
) ; 
 900         TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
 901           kTXNStartOffset
, kTXNEndOffset
); 
 903         TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0); 
 904         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
 905         if ( !formerEditable 
) 
 906             SetEditable(formerEditable
) ; 
 911 void wxTextCtrl::SetMaxLength(unsigned long len
) 
 916 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
) 
 920         bool formerEditable 
= m_editable 
; 
 921         if ( !formerEditable 
) 
 923         TXNTypeAttributes typeAttr
[4] ; 
 924         Str255 fontName 
= "\pMonaco" ; 
 925         SInt16 fontSize 
= 12 ; 
 926         Style fontStyle 
= normal 
; 
 928         int attrCounter 
= 0 ; 
 929         if ( style
.HasFont() ) 
 931             const wxFont 
&font 
= style
.GetFont() ; 
 932             wxMacStringToPascal( font
.GetFaceName() , fontName 
) ; 
 933             fontSize 
= font
.GetPointSize() ; 
 934             if ( font
.GetUnderlined() ) 
 935                 fontStyle 
|= underline 
; 
 936             if ( font
.GetWeight() == wxBOLD 
) 
 938             if ( font
.GetStyle() == wxITALIC 
) 
 939                 fontStyle 
|= italic 
; 
 941             typeAttr
[attrCounter
].tag 
= kTXNQDFontNameAttribute 
; 
 942             typeAttr
[attrCounter
].size 
= kTXNQDFontNameAttributeSize 
; 
 943             typeAttr
[attrCounter
].data
.dataPtr 
= (void*) fontName 
; 
 944             typeAttr
[attrCounter
+1].tag 
= kTXNQDFontSizeAttribute 
; 
 945             typeAttr
[attrCounter
+1].size 
= kTXNFontSizeAttributeSize 
; 
 946             typeAttr
[attrCounter
+1].data
.dataValue 
=  (fontSize 
<< 16) ; 
 947             typeAttr
[attrCounter
+2].tag 
= kTXNQDFontStyleAttribute 
; 
 948             typeAttr
[attrCounter
+2].size 
= kTXNQDFontStyleAttributeSize 
; 
 949             typeAttr
[attrCounter
+2].data
.dataValue 
= fontStyle 
; 
 953         if ( style
.HasTextColour() ) 
 955             typeAttr
[attrCounter
].tag 
= kTXNQDFontColorAttribute 
; 
 956             typeAttr
[attrCounter
].size 
= kTXNQDFontColorAttributeSize 
; 
 957             typeAttr
[attrCounter
].data
.dataPtr 
= (void*) &color 
; 
 958             color 
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ; 
 962         if ( attrCounter 
> 0 ) 
 966 #endif // __WXDEBUG__ 
 967                 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter 
, typeAttr
, start
,end
); 
 968             wxASSERT_MSG( status 
== noErr 
, wxT("Couldn't set text attributes") ) ; 
 970         if ( !formerEditable 
) 
 971             SetEditable(formerEditable
) ; 
 976 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
) 
 978     wxTextCtrlBase::SetDefaultStyle( style 
) ; 
 979     SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
 983 // Clipboard operations 
 984 void wxTextCtrl::Copy() 
 990             TECopy( ((TEHandle
) m_macTE
) ) ; 
 998             TXNCopy((TXNObject
)m_macTXN
); 
 999             TXNConvertToPublicScrap(); 
1004 void wxTextCtrl::Cut() 
1008         if ( !m_macUsesTXN 
) 
1010             TECut( ((TEHandle
) m_macTE
) ) ; 
1011             ClearCurrentScrap(); 
1013             MacRedrawControl() ; 
1017             ClearCurrentScrap(); 
1018             TXNCut((TXNObject
)m_macTXN
); 
1019             TXNConvertToPublicScrap(); 
1021         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1022         event
.SetString( GetValue() ) ; 
1023         event
.SetEventObject( this ); 
1024         GetEventHandler()->ProcessEvent(event
); 
1028 void wxTextCtrl::Paste() 
1032         if ( !m_macUsesTXN 
) 
1035             TEPaste( (TEHandle
) m_macTE 
) ; 
1036             MacRedrawControl() ; 
1040             TXNConvertFromPublicScrap(); 
1041             TXNPaste((TXNObject
)m_macTXN
); 
1042             SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
1044         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1045         event
.SetString( GetValue() ) ; 
1046         event
.SetEventObject( this ); 
1047         GetEventHandler()->ProcessEvent(event
); 
1051 bool wxTextCtrl::CanCopy() const 
1053     // Can copy if there's a selection 
1055     GetSelection(& from
, & to
); 
1056     return (from 
!= to
); 
1059 bool wxTextCtrl::CanCut() const 
1061     if ( !IsEditable() ) 
1065     // Can cut if there's a selection 
1067     GetSelection(& from
, & to
); 
1068     return (from 
!= to
); 
1071 bool wxTextCtrl::CanPaste() const 
1077     OSStatus err 
= noErr
; 
1080     err 
= GetCurrentScrap( &scrapRef 
); 
1081     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
1083         ScrapFlavorFlags    flavorFlags
; 
1086         if (( err 
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags 
)) == noErr
) 
1088             if (( err 
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount 
)) == noErr
) 
1098     if ( GetScrap( NULL 
, 'TEXT' , &offset 
) > 0 ) 
1106 void wxTextCtrl::SetEditable(bool editable
) 
1108     if ( editable 
!= m_editable 
) 
1110         m_editable 
= editable 
; 
1111         if ( !m_macUsesTXN 
) 
1114                 UMAActivateControl( (ControlHandle
) m_macControl 
) ; 
1116                 UMADeactivateControl((ControlHandle
)  m_macControl 
) ; 
1120             TXNControlTag tag
[] = { kTXNIOPrivilegesTag 
} ; 
1121             TXNControlData data
[] = { { editable 
? kTXNReadWrite 
: kTXNReadOnly 
} } ; 
1122             TXNSetTXNObjectControls( (TXNObject
) m_macTXN 
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag 
, data 
) ; 
1127 void wxTextCtrl::SetInsertionPoint(long pos
) 
1129     SetSelection( pos 
, pos 
) ; 
1132 void wxTextCtrl::SetInsertionPointEnd() 
1134     long pos 
= GetLastPosition(); 
1135     SetInsertionPoint(pos
); 
1138 long wxTextCtrl::GetInsertionPoint() const 
1141     GetSelection( &begin 
, &end 
) ; 
1145 long wxTextCtrl::GetLastPosition() const 
1147     if ( !m_macUsesTXN 
) 
1149         return (**((TEHandle
) m_macTE
)).teLength 
; 
1155         OSErr err 
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNTextData 
); 
1163             actualsize 
= GetHandleSize( theText 
) ; 
1164             DisposeHandle( theText 
) ; 
1170 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
) 
1172     if ( !m_macUsesTXN 
) 
1174         ControlEditTextSelectionRec selection 
; 
1176         selection
.selStart 
= from 
; 
1177         selection
.selEnd 
= to 
; 
1178         ::SetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1179         TESetSelect( from 
, to  
, ((TEHandle
) m_macTE
) ) ; 
1180         TEDelete( ((TEHandle
) m_macTE
) ) ; 
1181         TEInsert( value 
, value
.Length() , ((TEHandle
) m_macTE
) ) ; 
1185         bool formerEditable 
= m_editable 
; 
1186         if ( !formerEditable 
) 
1188         TXNSetSelection( ((TXNObject
) m_macTXN
) , from 
, to 
) ; 
1189         TXNClear( ((TXNObject
) m_macTXN
) ) ; 
1191         TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
,  (void*)value
.wc_str(), value
.Length() * 2 , 
1192           kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1194         TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
,  (void*)value
.c_str(), value
.Length(), 
1195             kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1197         if ( !formerEditable 
) 
1198             SetEditable( formerEditable 
) ; 
1203 void wxTextCtrl::Remove(long from
, long to
) 
1205     if ( !m_macUsesTXN 
) 
1207         ControlEditTextSelectionRec selection 
; 
1209         selection
.selStart 
= from 
; 
1210         selection
.selEnd 
= to 
; 
1211         ::SetControlData( (ControlHandle
) m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1212         TEDelete( ((TEHandle
) m_macTE
) ) ; 
1216         bool formerEditable 
= m_editable 
; 
1217         if ( !formerEditable 
) 
1219         TXNSetSelection( ((TXNObject
) m_macTXN
) , from 
, to 
) ; 
1220         TXNClear( ((TXNObject
) m_macTXN
) ) ; 
1221         if ( !formerEditable 
) 
1222             SetEditable( formerEditable 
) ; 
1227 void wxTextCtrl::SetSelection(long from
, long to
) 
1229     if ( !m_macUsesTXN 
) 
1231         ControlEditTextSelectionRec selection 
; 
1232         if ((from 
== -1) && (to 
== -1)) 
1234                 selection
.selStart 
= 0 ; 
1235                 selection
.selEnd 
= 32767 ; 
1239                 selection
.selStart 
= from 
; 
1240                 selection
.selEnd 
= to 
; 
1243         TESetSelect( selection
.selStart 
, selection
.selEnd 
, ((TEHandle
) m_macTE
) ) ; 
1244         ::SetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1248         STPTextPaneVars 
**tpvars
; 
1249         /* set up our locals */ 
1250         tpvars 
= (STPTextPaneVars 
**) GetControlReference((ControlHandle
) m_macControl
); 
1251         /* and our drawing environment as the operation 
1252         may force a redraw in the text area. */ 
1253         SetPort((**tpvars
).fDrawingEnvironment
); 
1254         /* change the selection */ 
1255         if ((from 
== -1) && (to 
== -1)) 
1256                 TXNSelectAll((TXNObject
) m_macTXN
); 
1258                 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
); 
1259         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
1263 bool wxTextCtrl::LoadFile(const wxString
& file
) 
1265     if ( wxTextCtrlBase::LoadFile(file
) ) 
1273 void wxTextCtrl::WriteText(const wxString
& st
) 
1275     if ( !m_macUsesTXN 
) 
1277         wxCharBuffer text 
= wxMacStringToCString( st 
) ; 
1278         TEInsert( text 
, strlen(text
) , ((TEHandle
) m_macTE
) ) ; 
1282         bool formerEditable 
= m_editable 
; 
1283         if ( !formerEditable 
) 
1285         long start 
, end 
, dummy 
; 
1286         GetSelection( &start 
, &dummy 
) ; 
1288         TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
,  (void*)st
.wc_str(), st
.Length() * 2 , 
1289           kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1291         wxCharBuffer text 
= wxMacStringToCString( st 
) ; 
1292         TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
1293           kTXNUseCurrentSelection
, kTXNUseCurrentSelection
); 
1295         GetSelection( &dummy 
, &end 
) ; 
1296         SetStyle( start 
, end 
, GetDefaultStyle() ) ; 
1297         if ( !formerEditable 
) 
1298             SetEditable( formerEditable 
) ; 
1300     MacRedrawControl() ; 
1303 void wxTextCtrl::AppendText(const wxString
& text
) 
1305     SetInsertionPointEnd(); 
1309 void wxTextCtrl::Clear() 
1311     if ( !IsEditable() ) 
1315     if ( !m_macUsesTXN 
) 
1317         ::SetControlData((ControlHandle
)  m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, 0 , (char*) ((const char*)NULL
) ) ; 
1321         TXNSetSelection( (TXNObject
)m_macTXN 
, kTXNStartOffset 
, kTXNEndOffset 
) ; 
1322         TXNClear((TXNObject
)m_macTXN
); 
1327 bool wxTextCtrl::IsModified() const 
1332 bool wxTextCtrl::IsEditable() const 
1334     return IsEnabled() && m_editable 
; 
1337 bool wxTextCtrl::AcceptsFocus() const 
1339     // we don't want focus if we can't be edited 
1340     return /*IsEditable() && */ wxControl::AcceptsFocus(); 
1343 wxSize 
wxTextCtrl::DoGetBestSize() const 
1358     wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); 
1360     int wText = DEFAULT_ITEM_WIDTH; 
1362     int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); 
1364     return wxSize(wText, hText); 
1366     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
1370     hText 
+= 2 * m_macVerticalBorder 
; 
1371     wText 
+= 2 * m_macHorizontalBorder 
; 
1372     //else: for single line control everything is ok 
1373     return wxSize(wText
, hText
); 
1376 // ---------------------------------------------------------------------------- 
1378 // ---------------------------------------------------------------------------- 
1380 void wxTextCtrl::Undo() 
1386             TXNUndo((TXNObject
)m_macTXN
);  
1391 void wxTextCtrl::Redo() 
1397             TXNRedo((TXNObject
)m_macTXN
);  
1402 bool wxTextCtrl::CanUndo() const 
1404     if ( !IsEditable() )  
1410         return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);  
1415 bool wxTextCtrl::CanRedo() const 
1417     if ( !IsEditable() )  
1423         return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);  
1428 // Makes 'unmodified' 
1429 void wxTextCtrl::DiscardEdits() 
1434 int wxTextCtrl::GetNumberOfLines() const 
1436     // TODO change this if possible to reflect real lines 
1437     wxString content 
= GetValue() ; 
1440     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1442         if (content
[i
] == '\r') count
++; 
1448 long wxTextCtrl::XYToPosition(long x
, long y
) const 
1454 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const 
1459 void wxTextCtrl::ShowPosition(long pos
) 
1464 int wxTextCtrl::GetLineLength(long lineNo
) const 
1466     // TODO change this if possible to reflect real lines 
1467     wxString content 
= GetValue() ; 
1471     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1473         if (count 
== lineNo
) 
1475             // Count chars in line then 
1477             for (size_t j 
= i
; j 
< content
.Length(); j
++) 
1480                 if (content
[j
] == '\r') return count
; 
1485         if (content
[i
] == '\r') count
++; 
1490 wxString 
wxTextCtrl::GetLineText(long lineNo
) const 
1492     // TODO change this if possible to reflect real lines 
1493     wxString content 
= GetValue() ; 
1497     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1499         if (count 
== lineNo
) 
1501             // Add chars in line then 
1504             for (size_t j 
= i
; j 
< content
.Length(); j
++) 
1506                 if (content
[j
] == '\r') 
1514         if (content
[i
] == '\r') count
++; 
1516     return wxEmptyString 
; 
1523 void wxTextCtrl::Command(wxCommandEvent 
& event
) 
1525     SetValue (event
.GetString()); 
1526     ProcessCommand (event
); 
1529 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
) 
1531     // By default, load the first file into the text window. 
1532     if (event
.GetNumberOfFiles() > 0) 
1534         LoadFile(event
.GetFiles()[0]); 
1538 void wxTextCtrl::OnChar(wxKeyEvent
& event
) 
1540     int key 
= event
.GetKeyCode() ; 
1541     bool eat_key 
= false ; 
1543     if ( key 
== 'c' && event
.MetaDown() ) 
1550     if ( !IsEditable() && key 
!= WXK_LEFT 
&& key 
!= WXK_RIGHT 
&& key 
!= WXK_DOWN 
&& key 
!= WXK_UP 
&& key 
!= WXK_TAB 
&& 
1551         !( key 
== WXK_RETURN 
&& ( (m_windowStyle 
& wxPROCESS_ENTER
) || (m_windowStyle 
& wxTE_MULTILINE
) ) ) 
1552 /*        && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */ 
1559     // assume that any key not processed yet is going to modify the control 
1562     if ( key 
== 'v' && event
.MetaDown() ) 
1568     if ( key 
== 'x' && event
.MetaDown() ) 
1577             if (m_windowStyle 
& wxPROCESS_ENTER
) 
1579                 wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
1580                 event
.SetEventObject( this ); 
1581                 event
.SetString( GetValue() ); 
1582                 if ( GetEventHandler()->ProcessEvent(event
) ) 
1585             if ( !(m_windowStyle 
& wxTE_MULTILINE
) ) 
1587                 wxWindow 
*parent 
= GetParent(); 
1588                 while( parent 
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL 
) { 
1589                   parent 
= parent
->GetParent() ; 
1591                 if ( parent 
&& parent
->GetDefaultItem() ) 
1593                     wxButton 
*def 
= wxDynamicCast(parent
->GetDefaultItem(), 
1595                     if ( def 
&& def
->IsEnabled() ) 
1597                         wxCommandEvent 
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() ); 
1598                         event
.SetEventObject(def
); 
1599                         def
->Command(event
); 
1604                 // this will make wxWindows eat the ENTER key so that 
1605                 // we actually prevent line wrapping in a single line 
1613             // always produce navigation event - even if we process TAB 
1614             // ourselves the fact that we got here means that the user code 
1615             // decided to skip processing of this TAB - probably to let it 
1616             // do its default job. 
1618                 wxNavigationKeyEvent eventNav
; 
1619                 eventNav
.SetDirection(!event
.ShiftDown()); 
1620                 eventNav
.SetWindowChange(event
.ControlDown()); 
1621                 eventNav
.SetEventObject(this); 
1623                 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) ) 
1634         // perform keystroke handling 
1636         if ( m_macUsesTXN 
&& wxTheApp
->MacGetCurrentEvent() != NULL 
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL 
) 
1637             CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ; 
1642             if ( wxMacConvertEventToRecord(  (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec 
) ) 
1644                 EventRecord 
*ev 
= &rec 
; 
1647                 keychar 
= short(ev
->message 
& charCodeMask
); 
1648                 keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
1650                 ::HandleControlKey( (ControlHandle
) m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
1654     if ( ( key 
>= 0x20 && key 
< WXK_START 
) || 
1655          key 
== WXK_RETURN 
|| 
1656          key 
== WXK_DELETE 
|| 
1659         wxCommandEvent 
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1660         event1
.SetString( GetValue() ) ; 
1661         event1
.SetEventObject( this ); 
1662         wxPostEvent(GetEventHandler(),event1
); 
1666 void  wxTextCtrl::MacSuperShown( bool show 
) 
1668     bool former 
= m_macControlIsShown 
; 
1669     wxControl::MacSuperShown( show 
) ; 
1670     if ( (former 
!= m_macControlIsShown
) && m_macUsesTXN 
) 
1672         if ( m_macControlIsShown 
) 
1673             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1674                 (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1676             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1677                (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1681 bool  wxTextCtrl::Show(bool show
) 
1683     bool former 
= m_macControlIsShown 
; 
1685     bool retval 
= wxControl::Show( show 
) ; 
1687     if ( former 
!= m_macControlIsShown 
&& m_macUsesTXN 
) 
1689         if ( m_macControlIsShown 
) 
1690             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1691                 (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1693             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1694                (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1700 // ---------------------------------------------------------------------------- 
1701 // standard handlers for standard edit menu events 
1702 // ---------------------------------------------------------------------------- 
1704 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
1709 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
1714 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
1719 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
1724 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
1729 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
1731     event
.Enable( CanCut() ); 
1734 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
1736     event
.Enable( CanCopy() ); 
1739 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
1741     event
.Enable( CanPaste() ); 
1744 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
1746     event
.Enable( CanUndo() ); 
1749 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
1751     event
.Enable( CanRedo() ); 
1754 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt 
) 
1759         return wxWindow::MacSetupCursor( pt 
) ;