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
) ;