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 #include "wx/msgdlg.h" 
  29 #if wxUSE_STD_IOSTREAM 
  39 #include "wx/button.h" 
  40 #include "wx/toplevel.h" 
  41 #include "wx/textctrl.h" 
  42 #include "wx/notebook.h" 
  43 #include "wx/tabctrl.h" 
  44 #include "wx/settings.h" 
  45 #include "wx/filefn.h" 
  48 #if defined(__BORLANDC__) && !defined(__WIN32__) 
  50 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__) 
  57 #include <MacTextEditor.h> 
  58 #include "ATSUnicode.h" 
  59 #include "TextCommon.h" 
  60 #include "TextEncodingConverter.h" 
  61 #include "wx/mac/uma.h" 
  63 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL 
  65 extern wxControl 
*wxFindControlFromMacControl(ControlHandle inControl 
) ; 
  67 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon 
  68 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the 
  69 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have 
  70 // an alternate path for carbon key events that routes automatically into the same wx flow of events 
  72 #include "MacTextEditor.h" 
  76 /* kmUPTextPart is the part code we return to indicate the user has clicked 
  77     in the text area of our control */ 
  78 #define kmUPTextPart 1 
  80 /* kmUPScrollPart is the part code we return to indicate the user has clicked 
  81     in the scroll bar part of the control. */ 
  82 #define kmUPScrollPart 2 
  85 /* routines for using existing user pane controls. 
  86     These routines are useful for cases where you would like to use an 
  87     existing user pane control in, say, a dialog window as a scrolling 
  90 /* mUPOpenControl initializes a user pane control so it will be drawn 
  91     and will behave as a scrolling text edit field inside of a window. 
  92     This routine performs all of the initialization steps necessary, 
  93     except it does not create the user pane control itself.  theControl 
  94     should refer to a user pane control that you have either created 
  95     yourself or extracted from a dialog's control heirarchy using 
  96     the GetDialogItemAsControl routine.  */ 
  97 OSStatus 
mUPOpenControl(ControlHandle theControl
, long wxStyle
); 
  99 /* Utility Routines */ 
 105 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus 
 106     routine.  In our focus switching routine this part code is understood 
 107     as meaning 'the user has clicked in the control and we need to switch 
 108     the current focus to ourselves before we can continue'. */ 
 109 #define kUserClickedToFocusPart 100 
 112 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to 
 113     slow the speed of 'auto scrolling' inside of our clickloop routine. 
 114     This value prevents the text from wizzzzzing by while the mouse 
 115     is being held down inside of the text area. */ 
 116 #define kmUPClickScrollDelayTicks 3 
 119 /* STPTextPaneVars is a structure used for storing the the mUP Control's 
 120     internal variables and state information.  A handle to this record is 
 121     stored in the pane control's reference value field using the 
 122     SetControlReference routine. */ 
 125         /* OS records referenced */ 
 126     TXNObject fTXNRec
; /* the txn record */ 
 127     TXNFrameID fTXNFrame
; /* the txn frame ID */ 
 128     ControlHandle fUserPaneRec
;  /* handle to the user pane control */ 
 129     WindowPtr fOwner
; /* window containing control */ 
 130     GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */ 
 132     Boolean fInFocus
; /* true while the focus rect is drawn around the control */ 
 133     Boolean fIsActive
; /* true while the control is drawn in the active state */ 
 134     Boolean fTEActive
; /* reflects the activation state of the text edit record */ 
 135     Boolean fInDialogWindow
; /* true if displayed in a dialog window */ 
 136         /* calculated locations */ 
 137     Rect fRTextArea
; /* area where the text is drawn */ 
 138     Rect fRFocusOutline
;  /* rectangle used to draw the focus box */ 
 139     Rect fRTextOutline
; /* rectangle used to draw the border */ 
 140     RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */ 
 141         /* our focus advance override routine */ 
 142     EventHandlerUPP handlerUPP
; 
 143     EventHandlerRef handlerRef
; 
 150 /* Univerals Procedure Pointer variables used by the 
 151     mUP Control.  These variables are set up 
 152     the first time that mUPOpenControl is called. */ 
 153 ControlUserPaneDrawUPP gTPDrawProc 
= NULL
; 
 154 ControlUserPaneHitTestUPP gTPHitProc 
= NULL
; 
 155 ControlUserPaneTrackingUPP gTPTrackProc 
= NULL
; 
 156 ControlUserPaneIdleUPP gTPIdleProc 
= NULL
; 
 157 ControlUserPaneKeyDownUPP gTPKeyProc 
= NULL
; 
 158 ControlUserPaneActivateUPP gTPActivateProc 
= NULL
; 
 159 ControlUserPaneFocusUPP gTPFocusProc 
= NULL
; 
 161 /* TPActivatePaneText activates or deactivates the text edit record 
 162     according to the value of setActive.  The primary purpose of this 
 163     routine is to ensure each call is only made once. */ 
 164 static void TPActivatePaneText(STPTextPaneVars 
**tpvars
, Boolean setActive
) { 
 165     STPTextPaneVars 
*varsp
; 
 167     if (varsp
->fTEActive 
!= setActive
) { 
 169         varsp
->fTEActive 
= setActive
; 
 171         TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
); 
 174             TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
); 
 179 /* TPFocusPaneText set the focus state for the text record. */ 
 180 static void TPFocusPaneText(STPTextPaneVars 
**tpvars
, Boolean setFocus
) { 
 181     STPTextPaneVars 
*varsp
; 
 183     if (varsp
->fInFocus 
!= setFocus
) { 
 184         varsp
->fInFocus 
= setFocus
; 
 185         TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
); 
 190 /* TPPaneDrawProc is called to redraw the control and for update events 
 191     referring to the control.  This routine erases the text area's background, 
 192     and redraws the text.  This routine assumes the scroll bar has been 
 193     redrawn by a call to DrawControls. */ 
 194 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) { 
 195     STPTextPaneVars 
**tpvars
, *varsp
; 
 198         /* set up our globals */ 
 200     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 201     if (tpvars 
!= NULL
) { 
 202         state 
= HGetState((Handle
) tpvars
); 
 203         HLock((Handle
) tpvars
); 
 206             /* save the drawing state */ 
 207         SetPort((**tpvars
).fDrawingEnvironment
); 
 208            /* verify our boundary */ 
 209         GetControlBounds(theControl
, &bounds
); 
 211         wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 212         if ( ! EqualRect(&bounds
, &varsp
->fRFocusOutline
) ) { 
 213             // scrollbar is on the border, we add one 
 214             Rect oldbounds 
= varsp
->fRFocusOutline 
; 
 215             InsetRect( &oldbounds 
, -1 , -1 ) ; 
 217             if ( IsControlVisible( theControl 
) ) 
 218                 InvalWindowRect( GetControlOwner( theControl 
) , &oldbounds 
) ; 
 219             SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 220             SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 221             SetRect(&varsp
->fRTextArea
, bounds
.left 
+ 2 , bounds
.top 
+ (varsp
->fMultiline 
? 0 : 2) , 
 222                 bounds
.right 
- (varsp
->fMultiline 
? 0 : 2), bounds
.bottom 
- (varsp
->fMultiline 
? 0 : 2)); 
 223             RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
); 
 224             if ( IsControlVisible( theControl 
) ) 
 225                 TXNSetFrameBounds(  varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
, 
 226                     varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
); 
 228                 TXNSetFrameBounds(  varsp
->fTXNRec
, varsp
->fRTextArea
.top 
+ 30000 , varsp
->fRTextArea
.left 
+ 30000 , 
 229                     varsp
->fRTextArea
.bottom 
+ 30000 , varsp
->fRTextArea
.right 
+ 30000 , varsp
->fTXNFrame
); 
 233         if ( IsControlVisible( theControl 
) ) 
 235             /* update the text region */ 
 236             RGBColor white 
= { 65535 , 65535 , 65535 } ; 
 237             RGBBackColor( &white 
) ; 
 238             EraseRgn(varsp
->fTextBackgroundRgn
); 
 239             TXNDraw(varsp
->fTXNRec
, NULL
); 
 240                 /* restore the drawing environment */ 
 241                 /* draw the text frame and focus frame (if necessary) */ 
 242             DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive 
? kThemeStateActive
: kThemeStateInactive
); 
 243             if ((**tpvars
).fIsActive 
&& varsp
->fInFocus
)  
 244                 DrawThemeFocusRect(&varsp
->fRFocusOutline
, true); 
 245                 /* release our globals */ 
 246             HSetState((Handle
) tpvars
, state
); 
 252 /* TPPaneHitTestProc is called when the control manager would 
 253     like to determine what part of the control the mouse resides over. 
 254     We also call this routine from our tracking proc to determine how 
 255     to handle mouse clicks. */ 
 256 static pascal ControlPartCode 
TPPaneHitTestProc(ControlHandle theControl
, Point where
) { 
 257     STPTextPaneVars 
**tpvars
; 
 258     ControlPartCode result
; 
 260         /* set up our locals and lock down our globals*/ 
 262     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 263     if (tpvars 
!= NULL 
&& IsControlVisible( theControl
) ) { 
 264         state 
= HGetState((Handle
) tpvars
); 
 265         HLock((Handle
) tpvars
); 
 266             /* find the region where we clicked */ 
 267         if (PtInRect(where
, &(**tpvars
).fRTextArea
)) { 
 268             result 
= kmUPTextPart
; 
 270             /* release oure globals */ 
 271         HSetState((Handle
) tpvars
, state
); 
 280 /* TPPaneTrackingProc is called when the mouse is being held down 
 281     over our control.  This routine handles clicks in the text area 
 282     and in the scroll bar. */ 
 283 static pascal ControlPartCode 
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) { 
 284     STPTextPaneVars 
**tpvars
, *varsp
; 
 286     ControlPartCode partCodeResult
; 
 287         /* make sure we have some variables... */ 
 289     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 290     if (tpvars 
!= NULL 
&& IsControlVisible( theControl 
) ) { 
 292         state 
= HGetState((Handle
) tpvars
); 
 293         HLock((Handle
) tpvars
); 
 295             /* we don't do any of these functions unless we're in focus */ 
 296         if ( ! varsp
->fInFocus
) { 
 298             owner 
= GetControlOwner(theControl
); 
 299             ClearKeyboardFocus(owner
); 
 300             SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
); 
 302             /* find the location for the click */ 
 303         switch (TPPaneHitTestProc(theControl
, startPt
)) { 
 305                 /* handle clicks in the text part */ 
 307                 {   SetPort((**tpvars
).fDrawingEnvironment
); 
 308                     wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 310                     TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent()); 
 313                     ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec 
) ; 
 314                     TXNClick( varsp
->fTXNRec
, &rec 
); 
 321         HSetState((Handle
) tpvars
, state
); 
 323     return partCodeResult
; 
 327 /* TPPaneIdleProc is our user pane idle routine.  When our text field 
 328     is active and in focus, we use this routine to set the cursor. */ 
 329 static pascal void TPPaneIdleProc(ControlHandle theControl
) { 
 330     STPTextPaneVars 
**tpvars
, *varsp
; 
 332     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 333     if (tpvars 
!= NULL 
&& IsControlVisible( theControl 
) ) { 
 334             /* if we're not active, then we have nothing to say about the cursor */ 
 335         if ((**tpvars
).fIsActive
) { 
 339                 /* lock down the globals */ 
 340             state 
= HGetState((Handle
) tpvars
); 
 341             HLock((Handle
) tpvars
); 
 343                 /* get the current mouse coordinates (in our window) */ 
 344             SetPortWindowPort(GetControlOwner(theControl
)); 
 345             wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 347                 /* there's a 'focus thing' and an 'unfocused thing' */ 
 348             if (varsp
->fInFocus
) { 
 349                     /* flash the cursor */ 
 350                 SetPort((**tpvars
).fDrawingEnvironment
); 
 351                 TXNIdle(varsp
->fTXNRec
); 
 353                 if (PtInRect(mousep
, &varsp
->fRTextArea
)) { 
 355                     RectRgn((theRgn 
= NewRgn()), &varsp
->fRTextArea
); 
 356                     TXNAdjustCursor(varsp
->fTXNRec
, theRgn
); 
 361                  // SetThemeCursor(kThemeArrowCursor); 
 364                 /* if it's in our bounds, set the cursor */ 
 365                 GetControlBounds(theControl
, &bounds
); 
 366                 if (PtInRect(mousep
, &bounds
)) 
 368                 //    SetThemeCursor(kThemeArrowCursor); 
 372             HSetState((Handle
) tpvars
, state
); 
 378 /* TPPaneKeyDownProc is called whenever a keydown event is directed 
 379     at our control.  Here, we direct the keydown event to the text 
 380     edit record and redraw the scroll bar and text field as appropriate. */ 
 381 static pascal ControlPartCode 
TPPaneKeyDownProc(ControlHandle theControl
, 
 382                             SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) { 
 383     STPTextPaneVars 
**tpvars
; 
 384     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 385     if (tpvars 
!= NULL
) { 
 386         if ((**tpvars
).fInFocus
) { 
 387                 /* turn autoscrolling on and send the key event to text edit */ 
 388             SetPort((**tpvars
).fDrawingEnvironment
); 
 389             wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 391             memset( &ev 
, 0 , sizeof( ev 
) ) ; 
 393             ev
.modifiers 
= modifiers 
; 
 394             ev
.message 
= (( keyCode 
<< 8 ) & keyCodeMask 
) + ( charCode 
& charCodeMask 
) ; 
 395             TXNKeyDown( (**tpvars
).fTXNRec
, &ev
); 
 398     return kControlEntireControl
; 
 402 /* TPPaneActivateProc is called when the window containing 
 403     the user pane control receives activate events. Here, we redraw 
 404     the control and it's text as necessary for the activation state. */ 
 405 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) { 
 407     STPTextPaneVars 
**tpvars
, *varsp
; 
 410     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 411     if (tpvars 
!= NULL
) { 
 412         state 
= HGetState((Handle
) tpvars
); 
 413         HLock((Handle
) tpvars
); 
 415             /* de/activate the text edit record */ 
 416         SetPort((**tpvars
).fDrawingEnvironment
); 
 417         wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 418         GetControlBounds(theControl
, &bounds
); 
 419         varsp
->fIsActive 
= activating
; 
 420         TPActivatePaneText(tpvars
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 421             /* redraw the frame */ 
 422         if ( IsControlVisible( theControl 
) ) 
 424             DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive 
? kThemeStateActive
: kThemeStateInactive
); 
 426                 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
); 
 428         HSetState((Handle
) tpvars
, state
); 
 433 /* TPPaneFocusProc is called when every the focus changes to or 
 434     from our control.  Herein, switch the focus appropriately 
 435     according to the parameters and redraw the control as 
 437 static pascal ControlPartCode 
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) { 
 438     ControlPartCode focusResult
; 
 439     STPTextPaneVars 
**tpvars
, *varsp
; 
 442     focusResult 
= kControlFocusNoPart
; 
 443     tpvars 
= (STPTextPaneVars 
**) GetControlReference(theControl
); 
 444     if (tpvars 
!= NULL 
) { 
 445         state 
= HGetState((Handle
) tpvars
); 
 446         HLock((Handle
) tpvars
); 
 448             /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is 
 449             tabbing forwards (or shift tabbing backwards) through the items in the dialog, 
 450             and kControlFocusNextPart will be received.  When the user clicks in our field 
 451             and it is not the current focus, then the constant kUserClickedToFocusPart will 
 452             be received.  The constant kControlFocusNoPart will be received when our control 
 453             is the current focus and the user clicks in another control.  In your focus routine, 
 454             you should respond to these codes as follows: 
 456             kControlFocusNoPart - turn off focus and return kControlFocusNoPart.  redraw 
 457                 the control and the focus rectangle as necessary. 
 459             kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off 
 460                 depending on its current state.  redraw the control and the focus rectangle 
 461                 as appropriate for the new focus state.  If the focus state is 'off', return the constant 
 462                 kControlFocusNoPart, otherwise return a non-zero part code. 
 463             kUserClickedToFocusPart - is a constant defined for this example.  You should 
 464                 define your own value for handling click-to-focus type events. */ 
 465              /* calculate the next highlight state */ 
 468             case kControlFocusNoPart
: 
 469                 TPFocusPaneText(tpvars
, false); 
 470                 focusResult 
= kControlFocusNoPart
; 
 472             case kUserClickedToFocusPart
: 
 473                 TPFocusPaneText(tpvars
, true); 
 476             case kControlFocusPrevPart
: 
 477             case kControlFocusNextPart
: 
 478                 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
)); 
 479                 focusResult 
= varsp
->fInFocus 
? 1 : kControlFocusNoPart
; 
 482         TPActivatePaneText(tpvars
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 483         /* redraw the text fram and focus rectangle to indicate the 
 485         if ( IsControlVisible( theControl 
) ) 
 487            /* save the drawing state */ 
 488                 SetPort((**tpvars
).fDrawingEnvironment
); 
 489                 wxMacWindowClipper 
clipper( wxFindControlFromMacControl(theControl 
) ) ; 
 490             DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive 
? kThemeStateActive
: kThemeStateInactive
); 
 491             DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 494         HSetState((Handle
) tpvars
, state
); 
 500 /* mUPOpenControl initializes a user pane control so it will be drawn 
 501     and will behave as a scrolling text edit field inside of a window. 
 502     This routine performs all of the initialization steps necessary, 
 503     except it does not create the user pane control itself.  theControl 
 504     should refer to a user pane control that you have either created 
 505     yourself or extracted from a dialog's control heirarchy using 
 506     the GetDialogItemAsControl routine.  */ 
 507 OSStatus 
mUPOpenControl(ControlHandle theControl
, long wxStyle 
) 
 511     STPTextPaneVars 
**tpvars
, *varsp
; 
 512     OSStatus err 
= noErr 
; 
 513     RGBColor rgbWhite 
= {0xFFFF, 0xFFFF, 0xFFFF}; 
 516         /* set up our globals */ 
 517     if (gTPDrawProc 
== NULL
) gTPDrawProc 
= NewControlUserPaneDrawUPP(TPPaneDrawProc
); 
 518     if (gTPHitProc 
== NULL
) gTPHitProc 
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
); 
 519     if (gTPTrackProc 
== NULL
) gTPTrackProc 
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
); 
 520     if (gTPIdleProc 
== NULL
) gTPIdleProc 
= NewControlUserPaneIdleUPP(TPPaneIdleProc
); 
 521     if (gTPKeyProc 
== NULL
) gTPKeyProc 
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
); 
 522     if (gTPActivateProc 
== NULL
) gTPActivateProc 
= NewControlUserPaneActivateUPP(TPPaneActivateProc
); 
 523     if (gTPFocusProc 
== NULL
) gTPFocusProc 
= NewControlUserPaneFocusUPP(TPPaneFocusProc
); 
 525         /* allocate our private storage */ 
 526     tpvars 
= (STPTextPaneVars 
**) NewHandleClear(sizeof(STPTextPaneVars
)); 
 527     SetControlReference(theControl
, (long) tpvars
); 
 528     HLock((Handle
) tpvars
); 
 530         /* set the initial settings for our private data */ 
 531     varsp
->fMultiline 
= wxStyle 
& wxTE_MULTILINE 
; 
 532     varsp
->fInFocus 
= false; 
 533     varsp
->fIsActive 
= true; 
 534     varsp
->fTEActive 
= true; // in order to get a deactivate 
 535     varsp
->fUserPaneRec 
= theControl
; 
 536     theWindow 
= varsp
->fOwner 
= GetControlOwner(theControl
); 
 538     varsp
->fDrawingEnvironment 
= (GrafPtr
)  GetWindowPort(theWindow
); 
 540     varsp
->fInDialogWindow 
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind 
); 
 541         /* set up the user pane procedures */ 
 542     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
); 
 543     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
); 
 544     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
); 
 545     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
); 
 546     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
); 
 547     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
); 
 548     SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
); 
 549         /* calculate the rectangles used by the control */ 
 550     GetControlBounds(theControl
, &bounds
); 
 551     SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 552     SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
); 
 553     SetRect(&varsp
->fRTextArea
, bounds
.left 
+ 2 , bounds
.top 
+ (varsp
->fMultiline 
? 0 : 2) , 
 554         bounds
.right 
- (varsp
->fMultiline 
? 0 : 2), bounds
.bottom 
- (varsp
->fMultiline 
? 0 : 2)); 
 555         /* calculate the background region for the text.  In this case, it's kindof 
 556         and irregular region because we're setting the scroll bar a little ways inside 
 558     RectRgn((varsp
->fTextBackgroundRgn 
= NewRgn()), &varsp
->fRTextOutline
); 
 560         /* set up the drawing environment */ 
 561     SetPort(varsp
->fDrawingEnvironment
); 
 563         /* create the new edit field */ 
 565     TXNFrameOptions frameOptions 
= 
 566         kTXNDontDrawCaretWhenInactiveMask 
; 
 567     if ( ! ( wxStyle 
& wxTE_NOHIDESEL 
) ) 
 568         frameOptions 
|= kTXNDontDrawSelectionWhenInactiveMask 
; 
 570     if ( wxStyle 
& wxTE_MULTILINE 
) 
 572         if ( ! ( wxStyle 
& wxTE_DONTWRAP 
) ) 
 573             frameOptions 
|= kTXNAlwaysWrapAtViewEdgeMask 
; 
 576             frameOptions 
|= kTXNAlwaysWrapAtViewEdgeMask 
; 
 577             frameOptions 
|= kTXNWantHScrollBarMask 
; 
 580         if ( !(wxStyle 
& wxTE_NO_VSCROLL 
) ) 
 581             frameOptions 
|= kTXNWantVScrollBarMask 
; 
 584         frameOptions 
|= kTXNSingleLineOnlyMask 
; 
 586     if ( wxStyle 
& wxTE_READONLY 
) 
 587         frameOptions 
|= kTXNReadOnlyMask 
; 
 589     TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
, 
 591         kTXNTextEditStyleFrameType
, 
 593         kTXNSystemDefaultEncoding
, 
 594         &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
); 
 596     if ( !IsControlVisible( theControl 
) ) 
 597         TXNSetFrameBounds(  varsp
->fTXNRec
, varsp
->fRTextArea
.top 
+ 30000 , varsp
->fRTextArea
.left 
+ 30000 , 
 598             varsp
->fRTextArea
.bottom 
+ 30000 , varsp
->fRTextArea
.right 
+ 30000 , varsp
->fTXNFrame
); 
 601     if ( (wxStyle 
& wxTE_MULTILINE
) && (wxStyle 
& wxTE_DONTWRAP
) ) 
 603         TXNControlTag tag 
= kTXNWordWrapStateTag 
; 
 605         dat
.uValue 
= kTXNNoAutoWrap 
; 
 606         TXNSetTXNObjectControls( varsp
->fTXNRec 
, false , 1 , &tag 
, &dat 
) ; 
 612         GetThemeFont(kThemeSmallSystemFont 
, GetApplicationScript() , fontName 
, &fontSize 
, &fontStyle 
) ; 
 614         TXNTypeAttributes typeAttr
[] = 
 616             {   kTXNQDFontNameAttribute 
, kTXNQDFontNameAttributeSize 
, { (void*) fontName 
} } , 
 617             {   kTXNQDFontSizeAttribute 
, kTXNFontSizeAttributeSize 
, { (void*) (fontSize 
<< 16) } } , 
 618             {   kTXNQDFontStyleAttribute 
, kTXNQDFontStyleAttributeSize 
, {  (void*) normal 
} } , 
 621     err 
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr 
) / sizeof(TXNTypeAttributes
) , typeAttr
, 
 624         /* set the field's background */ 
 626     tback
.bgType 
= kTXNBackgroundTypeRGB
; 
 627     tback
.bg
.color 
= rgbWhite
; 
 628     TXNSetBackground( varsp
->fTXNRec
, &tback
); 
 630         /* unlock our storage */ 
 631     HUnlock((Handle
) tpvars
); 
 632         /* perform final activations and setup for our text field.  Here, 
 633         we assume that the window is going to be the 'active' window. */ 
 634     TPActivatePaneText(tpvars
, varsp
->fIsActive 
&& varsp
->fInFocus
); 
 642 #if !USE_SHARED_LIBRARY 
 643 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
) 
 645 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
) 
 646     EVT_DROP_FILES(wxTextCtrl::OnDropFiles
) 
 647     EVT_CHAR(wxTextCtrl::OnChar
) 
 648     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
 649     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
 650     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
 651     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
 652     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
 654     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
 655     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
 656     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
 657     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
 658     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
 662 static void SetTXNData( TXNObject txn 
, const wxString
& st 
, TXNOffset start 
, TXNOffset end 
) 
 665         size_t len 
= st
.Len() ; 
 666 #if SIZEOF_WCHAR_T == 2 
 667     TXNSetData( txn 
, kTXNUnicodeTextData
,  (void*)st
.wc_str(), len 
* 2, 
 670     ByteCount byteBufferLen 
= len 
* sizeof( UniChar 
) ; 
 671         UniChar 
*unibuf 
= (UniChar
*) malloc(byteBufferLen
) ; 
 672         wxMBConvUTF16BE converter 
; 
 673         converter
.WC2MB( (char*) unibuf 
, st
.wc_str() , byteBufferLen 
) ; 
 674     TXNSetData( txn 
, kTXNUnicodeTextData
,  (void*)unibuf
, len 
* 2, 
 679         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
)  ; 
 680     TXNSetData( txn 
, kTXNTextData
,  (void*)text
.data(), strlen( text 
) , 
 686 void wxTextCtrl::Init() 
 690   m_macTXNvars 
= NULL 
; 
 691   m_macUsesTXN 
= false ; 
 696   m_maxLength 
= TE_UNLIMITED_LENGTH 
; 
 699 wxTextCtrl::~wxTextCtrl() 
 703         SetControlReference((ControlHandle
)m_macControl
, 0) ; 
 704         TXNDeleteObject((TXNObject
)m_macTXN
); 
 705         /* delete our private storage */ 
 706         DisposeHandle((Handle
) m_macTXNvars
); 
 707         /* zero the control reference */ 
 711 const short kVerticalMargin 
= 2 ; 
 712 const short kHorizontalMargin 
= 2 ; 
 714 bool wxTextCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
 717            const wxSize
& size
, long style
, 
 718            const wxValidator
& validator
, 
 719            const wxString
& name
) 
 723     m_macTXNvars 
= NULL 
; 
 724     m_macUsesTXN 
= false ; 
 727     m_macUsesTXN 
= ! (style 
& wxTE_PASSWORD 
) ; 
 729     m_macUsesTXN 
&= (TXNInitTextension 
!= (void*) kUnresolvedCFragSymbolAddress
) ; 
 731     // base initialization 
 732     if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style 
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) ) 
 735     wxSize mySize 
= size 
; 
 738         m_macHorizontalBorder 
= 5 ; // additional pixels around the real control 
 739         m_macVerticalBorder 
= 3 ; 
 743         m_macHorizontalBorder 
= 5 ; // additional pixels around the real control 
 744         m_macVerticalBorder 
= 5 ; 
 751     if ( mySize.y == -1 ) 
 754         if ( m_windowStyle & wxTE_MULTILINE ) 
 757         mySize.y += 2 * m_macVerticalBorder ; 
 760     MacPreControlCreate( parent 
, id 
,  wxEmptyString 
, pos 
, mySize 
,style
, validator 
, name 
, &bounds 
, title 
) ; 
 762     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
 764         wxASSERT_MSG( !(m_windowStyle 
& wxTE_PROCESS_ENTER
), 
 765                       wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") ); 
 767         m_windowStyle 
|= wxTE_PROCESS_ENTER
; 
 770     if ( m_windowStyle 
& wxTE_READONLY
) 
 776     wxMacConvertNewlines13To10( &st 
) ; 
 779         m_macControl 
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds 
, "\p" , false , 0 , 0 , 1, 
 780             (style 
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc 
: kControlEditTextProc 
, (long) this ) ; 
 782         ::GetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextTEHandleTag 
, sizeof( TEHandle 
) , (char*)((TEHandle 
*)&m_macTE
) , &size 
) ; 
 789         featurSet 
= kControlSupportsEmbedding 
| kControlSupportsFocus  
| kControlWantsIdle
 
 790                 | kControlWantsActivate 
| kControlHandlesTracking 
| kControlHasSpecialBackground
 
 791                 | kControlGetsFocusOnClick 
| kControlSupportsLiveFeedback
; 
 792             /* create the control */ 
 793         m_macControl 
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0); 
 794             /* set up the mUP specific features and data */ 
 795         mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle 
); 
 797     MacPostControlCreate() ; 
 801         wxCharBuffer text 
= st
.mb_str(wxConvLocal
) ; 
 802         ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, strlen(text
) , text 
) ; 
 806         STPTextPaneVars 
**tpvars
; 
 808         tpvars 
= (STPTextPaneVars 
**) GetControlReference((ControlHandle
) m_macControl
); 
 809             /* set the text in the record */ 
 810         m_macTXN 
=  (**tpvars
).fTXNRec 
; 
 811         SetTXNData( (TXNObject
) m_macTXN 
, st 
, kTXNStartOffset
, kTXNEndOffset 
) ; 
 812         m_macTXNvars 
= tpvars 
; 
 813         m_macUsesTXN 
= true ; 
 814         TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0); 
 815         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
 821 wxString 
wxTextCtrl::GetValue() const 
 828         err 
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0, 
 829             ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag
, &actualSize 
) ; 
 832            return wxEmptyString 
; 
 834        if ( actualSize 
> 0 ) 
 836                 wxCharBuffer 
buf(actualSize
) ; 
 837             ::GetControlData( (ControlHandle
) m_macControl
, 0, 
 838                 ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag
, 
 839                 actualSize 
, buf
.data() , &actualSize 
) ; 
 840             result 
= wxString( buf 
, wxConvLocal
) ; 
 847         err 
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNUnicodeTextData 
); 
 855             actualSize 
= GetHandleSize( theText 
) ; 
 856             if ( actualSize 
> 0 ) 
 858                 wxChar 
*ptr 
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ; 
 859 #if SIZEOF_WCHAR_T == 2                          
 860                 wxStrncpy( ptr 
, (wxChar
*) *theText 
, actualSize 
) ; 
 862                                 wxMBConvUTF16BE converter 
; 
 864                                 converter
.MB2WC( ptr 
, (const char*)*theText 
, actualSize
*sizeof(wxChar
) ) ; 
 867                 ptr
[actualSize
] = 0 ; 
 868                 result
.UngetWriteBuf( actualSize 
) ; 
 870             DisposeHandle( theText 
) ; 
 874         err 
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNTextData 
); 
 882             actualSize 
= GetHandleSize( theText 
) ; 
 883             if ( actualSize 
> 0 ) 
 886                 result 
= wxString( *theText 
, wxConvLocal 
, actualSize 
) ; 
 889             DisposeHandle( theText 
) ; 
 893     wxMacConvertNewlines10To13( &result 
) ; 
 897 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 901     *from 
= (**((TEHandle
) m_macTE
)).selStart
; 
 902     *to 
= (**((TEHandle
) m_macTE
)).selEnd
; 
 906         TXNGetSelection( (TXNObject
) m_macTXN 
, (TXNOffset
*) from 
, (TXNOffset
*) to 
) ; 
 910 void wxTextCtrl::SetValue(const wxString
& str
) 
 913     wxMacConvertNewlines13To10( &st 
) ; 
 916         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
) ; 
 917         ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, strlen(text
) , text 
) ; 
 921         bool formerEditable 
= m_editable 
; 
 922         if ( !formerEditable 
) 
 924         SetTXNData( (TXNObject
) m_macTXN 
, st 
, kTXNStartOffset
, kTXNEndOffset 
) ; 
 925         TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0); 
 926         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
 927         if ( !formerEditable 
) 
 928             SetEditable(formerEditable
) ; 
 933 void wxTextCtrl::SetMaxLength(unsigned long len
) 
 938 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
) 
 942         bool formerEditable 
= m_editable 
; 
 943         if ( !formerEditable 
) 
 945         TXNTypeAttributes typeAttr
[4] ; 
 946         Str255 fontName 
= "\pMonaco" ; 
 947         SInt16 fontSize 
= 12 ; 
 948         Style fontStyle 
= normal 
; 
 950         int attrCounter 
= 0 ; 
 951         if ( style
.HasFont() ) 
 953             const wxFont 
&font 
= style
.GetFont() ; 
 954             wxMacStringToPascal( font
.GetFaceName() , fontName 
) ; 
 955             fontSize 
= font
.GetPointSize() ; 
 956             if ( font
.GetUnderlined() ) 
 957                 fontStyle 
|= underline 
; 
 958             if ( font
.GetWeight() == wxBOLD 
) 
 960             if ( font
.GetStyle() == wxITALIC 
) 
 961                 fontStyle 
|= italic 
; 
 963             typeAttr
[attrCounter
].tag 
= kTXNQDFontNameAttribute 
; 
 964             typeAttr
[attrCounter
].size 
= kTXNQDFontNameAttributeSize 
; 
 965             typeAttr
[attrCounter
].data
.dataPtr 
= (void*) fontName 
; 
 966             typeAttr
[attrCounter
+1].tag 
= kTXNQDFontSizeAttribute 
; 
 967             typeAttr
[attrCounter
+1].size 
= kTXNFontSizeAttributeSize 
; 
 968             typeAttr
[attrCounter
+1].data
.dataValue 
=  (fontSize 
<< 16) ; 
 969             typeAttr
[attrCounter
+2].tag 
= kTXNQDFontStyleAttribute 
; 
 970             typeAttr
[attrCounter
+2].size 
= kTXNQDFontStyleAttributeSize 
; 
 971             typeAttr
[attrCounter
+2].data
.dataValue 
= fontStyle 
; 
 975         if ( style
.HasTextColour() ) 
 977             typeAttr
[attrCounter
].tag 
= kTXNQDFontColorAttribute 
; 
 978             typeAttr
[attrCounter
].size 
= kTXNQDFontColorAttributeSize 
; 
 979             typeAttr
[attrCounter
].data
.dataPtr 
= (void*) &color 
; 
 980             color 
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ; 
 984         if ( attrCounter 
> 0 ) 
 988 #endif // __WXDEBUG__ 
 989                 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter 
, typeAttr
, start
,end
); 
 990             wxASSERT_MSG( status 
== noErr 
, wxT("Couldn't set text attributes") ) ; 
 992         if ( !formerEditable 
) 
 993             SetEditable(formerEditable
) ; 
 998 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
) 
1000     wxTextCtrlBase::SetDefaultStyle( style 
) ; 
1001     SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
1005 // Clipboard operations 
1006 void wxTextCtrl::Copy() 
1010       if ( !m_macUsesTXN 
) 
1012             TECopy( ((TEHandle
) m_macTE
) ) ; 
1013             ClearCurrentScrap(); 
1015             MacRedrawControl() ; 
1019             ClearCurrentScrap(); 
1020             TXNCopy((TXNObject
)m_macTXN
); 
1021             TXNConvertToPublicScrap(); 
1026 void wxTextCtrl::Cut() 
1030         if ( !m_macUsesTXN 
) 
1032             TECut( ((TEHandle
) m_macTE
) ) ; 
1033             ClearCurrentScrap(); 
1035             MacRedrawControl() ; 
1039             ClearCurrentScrap(); 
1040             TXNCut((TXNObject
)m_macTXN
); 
1041             TXNConvertToPublicScrap(); 
1043         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1044         event
.SetString( GetValue() ) ; 
1045         event
.SetEventObject( this ); 
1046         GetEventHandler()->ProcessEvent(event
); 
1050 void wxTextCtrl::Paste() 
1054         if ( !m_macUsesTXN 
) 
1057             TEPaste( (TEHandle
) m_macTE 
) ; 
1058             MacRedrawControl() ; 
1062             TXNConvertFromPublicScrap(); 
1063             TXNPaste((TXNObject
)m_macTXN
); 
1064             SetStyle( kTXNUseCurrentSelection 
, kTXNUseCurrentSelection 
, GetDefaultStyle() ) ; 
1066         wxCommandEvent 
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1067         event
.SetString( GetValue() ) ; 
1068         event
.SetEventObject( this ); 
1069         GetEventHandler()->ProcessEvent(event
); 
1073 bool wxTextCtrl::CanCopy() const 
1075     // Can copy if there's a selection 
1077     GetSelection(& from
, & to
); 
1078     return (from 
!= to
); 
1081 bool wxTextCtrl::CanCut() const 
1083     if ( !IsEditable() ) 
1087     // Can cut if there's a selection 
1089     GetSelection(& from
, & to
); 
1090     return (from 
!= to
); 
1093 bool wxTextCtrl::CanPaste() const 
1099     OSStatus err 
= noErr
; 
1102     err 
= GetCurrentScrap( &scrapRef 
); 
1103     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
1105         ScrapFlavorFlags    flavorFlags
; 
1108         if (( err 
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags 
)) == noErr
) 
1110             if (( err 
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount 
)) == noErr
) 
1120     if ( GetScrap( NULL 
, 'TEXT' , &offset 
) > 0 ) 
1128 void wxTextCtrl::SetEditable(bool editable
) 
1130     if ( editable 
!= m_editable 
) 
1132         m_editable 
= editable 
; 
1133         if ( !m_macUsesTXN 
) 
1136                 UMAActivateControl( (ControlHandle
) m_macControl 
) ; 
1138                 UMADeactivateControl((ControlHandle
)  m_macControl 
) ; 
1142             TXNControlTag tag
[] = { kTXNIOPrivilegesTag 
} ; 
1143             TXNControlData data
[] = { { editable 
? kTXNReadWrite 
: kTXNReadOnly 
} } ; 
1144             TXNSetTXNObjectControls( (TXNObject
) m_macTXN 
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag 
, data 
) ; 
1149 void wxTextCtrl::SetInsertionPoint(long pos
) 
1151     SetSelection( pos 
, pos 
) ; 
1154 void wxTextCtrl::SetInsertionPointEnd() 
1156     long pos 
= GetLastPosition(); 
1157     SetInsertionPoint(pos
); 
1160 long wxTextCtrl::GetInsertionPoint() const 
1163     GetSelection( &begin 
, &end 
) ; 
1167 long wxTextCtrl::GetLastPosition() const 
1169     if ( !m_macUsesTXN 
) 
1171         return (**((TEHandle
) m_macTE
)).teLength 
; 
1177         OSErr err 
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText 
, kTXNTextData 
); 
1185             actualsize 
= GetHandleSize( theText 
) ; 
1186             DisposeHandle( theText 
) ; 
1192 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
) 
1194     wxString value 
= str 
; 
1195     wxMacConvertNewlines13To10( &value 
) ; 
1196     if ( !m_macUsesTXN 
) 
1198         ControlEditTextSelectionRec selection 
; 
1200         selection
.selStart 
= from 
; 
1201         selection
.selEnd 
= to 
; 
1202         ::SetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1203         TESetSelect( from 
, to  
, ((TEHandle
) m_macTE
) ) ; 
1204         TEDelete( ((TEHandle
) m_macTE
) ) ; 
1205         TEInsert( value 
, value
.Length() , ((TEHandle
) m_macTE
) ) ; 
1209         bool formerEditable 
= m_editable 
; 
1210         if ( !formerEditable 
) 
1212         TXNSetSelection( ((TXNObject
) m_macTXN
) , from 
, to 
) ; 
1213         TXNClear( ((TXNObject
) m_macTXN
) ) ; 
1214         SetTXNData( (TXNObject
) m_macTXN 
, str 
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection 
) ; 
1215         if ( !formerEditable 
) 
1216             SetEditable( formerEditable 
) ; 
1221 void wxTextCtrl::Remove(long from
, long to
) 
1223     if ( !m_macUsesTXN 
) 
1225         ControlEditTextSelectionRec selection 
; 
1227         selection
.selStart 
= from 
; 
1228         selection
.selEnd 
= to 
; 
1229         ::SetControlData( (ControlHandle
) m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1230         TEDelete( ((TEHandle
) m_macTE
) ) ; 
1234         bool formerEditable 
= m_editable 
; 
1235         if ( !formerEditable 
) 
1237         TXNSetSelection( ((TXNObject
) m_macTXN
) , from 
, to 
) ; 
1238         TXNClear( ((TXNObject
) m_macTXN
) ) ; 
1239         if ( !formerEditable 
) 
1240             SetEditable( formerEditable 
) ; 
1245 void wxTextCtrl::SetSelection(long from
, long to
) 
1247     if ( !m_macUsesTXN 
) 
1249         ControlEditTextSelectionRec selection 
; 
1250         if ((from 
== -1) && (to 
== -1)) 
1252                 selection
.selStart 
= 0 ; 
1253                 selection
.selEnd 
= 32767 ; 
1257                 selection
.selStart 
= from 
; 
1258                 selection
.selEnd 
= to 
; 
1261         TESetSelect( selection
.selStart 
, selection
.selEnd 
, ((TEHandle
) m_macTE
) ) ; 
1262         ::SetControlData((ControlHandle
)  m_macControl 
, 0, kControlEditTextSelectionTag 
, sizeof( selection 
) , (char*) &selection 
) ; 
1266         STPTextPaneVars 
**tpvars
; 
1267         /* set up our locals */ 
1268         tpvars 
= (STPTextPaneVars 
**) GetControlReference((ControlHandle
) m_macControl
); 
1269         /* and our drawing environment as the operation 
1270         may force a redraw in the text area. */ 
1271         SetPort((**tpvars
).fDrawingEnvironment
); 
1272         /* change the selection */ 
1273         if ((from 
== -1) && (to 
== -1)) 
1274                 TXNSelectAll((TXNObject
) m_macTXN
); 
1276                 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
); 
1277         TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
); 
1281 bool wxTextCtrl::LoadFile(const wxString
& file
) 
1283     if ( wxTextCtrlBase::LoadFile(file
) ) 
1291 void wxTextCtrl::WriteText(const wxString
& str
) 
1294     wxMacConvertNewlines13To10( &st 
) ; 
1295     if ( !m_macUsesTXN 
) 
1297         wxCharBuffer text 
=  st
.mb_str(wxConvLocal
) ; 
1298         TEInsert( text 
, strlen(text
) , ((TEHandle
) m_macTE
) ) ; 
1302         bool formerEditable 
= m_editable 
; 
1303         if ( !formerEditable 
) 
1305         long start 
, end 
, dummy 
; 
1306         GetSelection( &start 
, &dummy 
) ; 
1307         SetTXNData( (TXNObject
) m_macTXN 
, st 
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection 
) ; 
1308         GetSelection( &dummy 
, &end 
) ; 
1309         SetStyle( start 
, end 
, GetDefaultStyle() ) ; 
1310         if ( !formerEditable 
) 
1311             SetEditable( formerEditable 
) ; 
1313     MacRedrawControl() ; 
1316 void wxTextCtrl::AppendText(const wxString
& text
) 
1318     SetInsertionPointEnd(); 
1322 void wxTextCtrl::Clear() 
1324     if ( !m_macUsesTXN 
) 
1326         ::SetControlData((ControlHandle
)  m_macControl
, 0, ( m_windowStyle 
& wxTE_PASSWORD 
) ? kControlEditTextPasswordTag 
: kControlEditTextTextTag 
, 0 , (char*) ((const char*)NULL
) ) ; 
1330         TXNSetSelection( (TXNObject
)m_macTXN 
, kTXNStartOffset 
, kTXNEndOffset 
) ; 
1331         TXNClear((TXNObject
)m_macTXN
); 
1336 bool wxTextCtrl::IsModified() const 
1341 bool wxTextCtrl::IsEditable() const 
1343     return IsEnabled() && m_editable 
; 
1346 bool wxTextCtrl::AcceptsFocus() const 
1348     // we don't want focus if we can't be edited 
1349     return /*IsEditable() && */ wxControl::AcceptsFocus(); 
1352 wxSize 
wxTextCtrl::DoGetBestSize() const 
1367     wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); 
1369     int wText = DEFAULT_ITEM_WIDTH; 
1371     int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); 
1373     return wxSize(wText, hText); 
1375     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
1379     hText 
+= 2 * m_macVerticalBorder 
; 
1380     wText 
+= 2 * m_macHorizontalBorder 
; 
1381     //else: for single line control everything is ok 
1382     return wxSize(wText
, hText
); 
1385 // ---------------------------------------------------------------------------- 
1387 // ---------------------------------------------------------------------------- 
1389 void wxTextCtrl::Undo() 
1395             TXNUndo((TXNObject
)m_macTXN
);  
1400 void wxTextCtrl::Redo() 
1406             TXNRedo((TXNObject
)m_macTXN
);  
1411 bool wxTextCtrl::CanUndo() const 
1413     if ( !IsEditable() )  
1419         return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);  
1424 bool wxTextCtrl::CanRedo() const 
1426     if ( !IsEditable() )  
1432         return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);  
1437 // Makes modifie or unmodified 
1438 void wxTextCtrl::MarkDirty() 
1443 void wxTextCtrl::DiscardEdits() 
1448 int wxTextCtrl::GetNumberOfLines() const 
1453         TXNGetLineCount((TXNObject
)m_macTXN
, &lines 
) ; 
1458         wxString content 
= GetValue() ; 
1461         for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1463             if (content
[i
] == '\r') count
++; 
1469 long wxTextCtrl::XYToPosition(long x
, long y
) const 
1475 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const 
1480 void wxTextCtrl::ShowPosition(long pos
) 
1482 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER) 
1487         TXNOffset selstart 
, selend 
; 
1488         TXNGetSelection(  (TXNObject
) m_macTXN 
, &selstart 
, &selend
) ; 
1489         TXNOffsetToPoint( (TXNObject
) m_macTXN
,  selstart 
, ¤t
); 
1490         TXNOffsetToPoint( (TXNObject
) m_macTXN
,  pos 
, &desired
); 
1491         //TODO use HIPoints for 10.3 and above 
1492         if ( (UInt32
) TXNScroll 
!= (UInt32
) kUnresolvedCFragSymbolAddress 
) 
1494             OSErr theErr 
= noErr
; 
1495             SInt32 dv 
= desired
.v 
- current
.v 
; 
1496             SInt32 dh 
= desired
.h 
- current
.h 
; 
1497             TXNShowSelection(  (TXNObject
) m_macTXN 
, true ) ; 
1498             theErr 
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels 
, kTXNScrollUnitsInPixels 
, &dv 
, &dh 
);           
1499             wxASSERT_MSG( theErr 
== noErr
, _T("TXNScroll returned an error!") ); 
1505 int wxTextCtrl::GetLineLength(long lineNo
) const 
1507     // TODO change this if possible to reflect real lines 
1508     wxString content 
= GetValue() ; 
1512     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1514         if (count 
== lineNo
) 
1516             // Count chars in line then 
1518             for (size_t j 
= i
; j 
< content
.Length(); j
++) 
1521                 if (content
[j
] == '\n') return count
; 
1526         if (content
[i
] == '\n') count
++; 
1531 wxString 
wxTextCtrl::GetLineText(long lineNo
) const 
1533     // TODO change this if possible to reflect real lines 
1534     wxString content 
= GetValue() ; 
1538     for (size_t i 
= 0; i 
< content
.Length() ; i
++) 
1540         if (count 
== lineNo
) 
1542             // Add chars in line then 
1545             for (size_t j 
= i
; j 
< content
.Length(); j
++) 
1547                 if (content
[j
] == '\n') 
1555         if (content
[i
] == '\n') count
++; 
1557     return wxEmptyString 
; 
1564 void wxTextCtrl::Command(wxCommandEvent 
& event
) 
1566     SetValue (event
.GetString()); 
1567     ProcessCommand (event
); 
1570 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
) 
1572     // By default, load the first file into the text window. 
1573     if (event
.GetNumberOfFiles() > 0) 
1575         LoadFile(event
.GetFiles()[0]); 
1579 void wxTextCtrl::OnChar(wxKeyEvent
& event
) 
1581     int key 
= event
.GetKeyCode() ; 
1582     bool eat_key 
= false ; 
1584     if ( key 
== 'c' && event
.MetaDown() ) 
1591     if ( !IsEditable() && key 
!= WXK_LEFT 
&& key 
!= WXK_RIGHT 
&& key 
!= WXK_DOWN 
&& key 
!= WXK_UP 
&& key 
!= WXK_TAB 
&& 
1592         !( key 
== WXK_RETURN 
&& ( (m_windowStyle 
& wxPROCESS_ENTER
) || (m_windowStyle 
& wxTE_MULTILINE
) ) ) 
1593 /*        && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */ 
1600     // assume that any key not processed yet is going to modify the control 
1603     if ( key 
== 'v' && event
.MetaDown() ) 
1609     if ( key 
== 'x' && event
.MetaDown() ) 
1618             if (m_windowStyle 
& wxPROCESS_ENTER
) 
1620                 wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
1621                 event
.SetEventObject( this ); 
1622                 event
.SetString( GetValue() ); 
1623                 if ( GetEventHandler()->ProcessEvent(event
) ) 
1626             if ( !(m_windowStyle 
& wxTE_MULTILINE
) ) 
1628                 wxWindow 
*parent 
= GetParent(); 
1629                 while( parent 
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL 
) { 
1630                   parent 
= parent
->GetParent() ; 
1632                 if ( parent 
&& parent
->GetDefaultItem() ) 
1634                     wxButton 
*def 
= wxDynamicCast(parent
->GetDefaultItem(), 
1636                     if ( def 
&& def
->IsEnabled() ) 
1638                         wxCommandEvent 
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() ); 
1639                         event
.SetEventObject(def
); 
1640                         def
->Command(event
); 
1645                 // this will make wxWindows eat the ENTER key so that 
1646                 // we actually prevent line wrapping in a single line 
1654             // always produce navigation event - even if we process TAB 
1655             // ourselves the fact that we got here means that the user code 
1656             // decided to skip processing of this TAB - probably to let it 
1657             // do its default job. 
1659                 wxNavigationKeyEvent eventNav
; 
1660                 eventNav
.SetDirection(!event
.ShiftDown()); 
1661                 eventNav
.SetWindowChange(event
.ControlDown()); 
1662                 eventNav
.SetEventObject(this); 
1664                 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) ) 
1675         // perform keystroke handling 
1677         if ( m_macUsesTXN 
&& wxTheApp
->MacGetCurrentEvent() != NULL 
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL 
) 
1678             CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ; 
1682             if ( wxMacConvertEventToRecord(  (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec 
) ) 
1684                 EventRecord 
*ev 
= &rec 
; 
1687                 keychar 
= short(ev
->message 
& charCodeMask
); 
1688                 keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
1690                 ::HandleControlKey( (ControlHandle
) m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
1694         EventRecord 
*ev 
= (EventRecord
*) wxTheApp
->MacGetCurrentEvent() ; 
1697         keychar 
= short(ev
->message 
& charCodeMask
); 
1698         keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
1700         ::HandleControlKey( (ControlHandle
) m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
1703     if ( ( key 
>= 0x20 && key 
< WXK_START 
) || 
1704          key 
== WXK_RETURN 
|| 
1705          key 
== WXK_DELETE 
|| 
1708         wxCommandEvent 
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
); 
1709         event1
.SetString( GetValue() ) ; 
1710         event1
.SetEventObject( this ); 
1711         wxPostEvent(GetEventHandler(),event1
); 
1715 void  wxTextCtrl::MacSuperShown( bool show 
) 
1717     bool former 
= m_macControlIsShown 
; 
1718     wxControl::MacSuperShown( show 
) ; 
1719     if ( (former 
!= m_macControlIsShown
) && m_macUsesTXN 
) 
1721         if ( m_macControlIsShown 
) 
1722             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1723                 (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1725             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1726                (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1730 bool  wxTextCtrl::Show(bool show
) 
1732     bool former 
= m_macControlIsShown 
; 
1734     bool retval 
= wxControl::Show( show 
) ; 
1736     if ( former 
!= m_macControlIsShown 
&& m_macUsesTXN 
) 
1738         if ( m_macControlIsShown 
) 
1739             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1740                 (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1742             TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.top 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.left
, 
1743                (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.bottom 
+ 30000, (**(STPTextPaneVars 
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars 
**)m_macTXNvars
).fTXNFrame
); 
1749 // ---------------------------------------------------------------------------- 
1750 // standard handlers for standard edit menu events 
1751 // ---------------------------------------------------------------------------- 
1753 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
1758 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
1763 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
1768 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
1773 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
1778 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
1780     event
.Enable( CanCut() ); 
1783 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
1785     event
.Enable( CanCopy() ); 
1788 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
1790     event
.Enable( CanPaste() ); 
1793 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
1795     event
.Enable( CanUndo() ); 
1798 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
1800     event
.Enable( CanRedo() ); 
1803 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt 
) 
1808         return wxWindow::MacSetupCursor( pt 
) ;