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
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
);
220 if (!wxFindControlFromMacControl(theControl
)->HasFlag(wxNO_BORDER
))
222 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
223 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
227 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
228 bounds
.right
, bounds
.bottom
);
230 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
231 if ( IsControlVisible( theControl
) )
232 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
233 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
235 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
236 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
240 if ( IsControlVisible( theControl
) )
242 /* update the text region */
243 RGBColor white
= { 65535 , 65535 , 65535 } ;
244 RGBBackColor( &white
) ;
245 EraseRgn(varsp
->fTextBackgroundRgn
);
246 TXNDraw(varsp
->fTXNRec
, NULL
);
247 /* restore the drawing environment */
248 /* draw the text frame and focus frame (if necessary) */
249 if (!wxFindControlFromMacControl(theControl
)->HasFlag(wxNO_BORDER
))
251 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
252 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
)
253 DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
255 /* release our globals */
256 HSetState((Handle
) tpvars
, state
);
262 /* TPPaneHitTestProc is called when the control manager would
263 like to determine what part of the control the mouse resides over.
264 We also call this routine from our tracking proc to determine how
265 to handle mouse clicks. */
266 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
267 STPTextPaneVars
**tpvars
;
268 ControlPartCode result
;
270 /* set up our locals and lock down our globals*/
272 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
273 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
274 state
= HGetState((Handle
) tpvars
);
275 HLock((Handle
) tpvars
);
276 /* find the region where we clicked */
277 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
278 result
= kmUPTextPart
;
280 /* release oure globals */
281 HSetState((Handle
) tpvars
, state
);
290 /* TPPaneTrackingProc is called when the mouse is being held down
291 over our control. This routine handles clicks in the text area
292 and in the scroll bar. */
293 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
294 STPTextPaneVars
**tpvars
, *varsp
;
296 ControlPartCode partCodeResult
;
297 /* make sure we have some variables... */
299 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
300 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
302 state
= HGetState((Handle
) tpvars
);
303 HLock((Handle
) tpvars
);
305 /* we don't do any of these functions unless we're in focus */
306 if ( ! varsp
->fInFocus
) {
308 owner
= GetControlOwner(theControl
);
309 ClearKeyboardFocus(owner
);
310 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
312 /* find the location for the click */
313 switch (TPPaneHitTestProc(theControl
, startPt
)) {
315 /* handle clicks in the text part */
317 { SetPort((**tpvars
).fDrawingEnvironment
);
318 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
320 TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent());
323 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
324 TXNClick( varsp
->fTXNRec
, &rec
);
331 HSetState((Handle
) tpvars
, state
);
333 return partCodeResult
;
337 /* TPPaneIdleProc is our user pane idle routine. When our text field
338 is active and in focus, we use this routine to set the cursor. */
339 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
340 STPTextPaneVars
**tpvars
, *varsp
;
342 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
343 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
344 /* if we're not active, then we have nothing to say about the cursor */
345 if ((**tpvars
).fIsActive
) {
349 /* lock down the globals */
350 state
= HGetState((Handle
) tpvars
);
351 HLock((Handle
) tpvars
);
353 /* get the current mouse coordinates (in our window) */
354 SetPortWindowPort(GetControlOwner(theControl
));
355 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
357 /* there's a 'focus thing' and an 'unfocused thing' */
358 if (varsp
->fInFocus
) {
359 /* flash the cursor */
360 SetPort((**tpvars
).fDrawingEnvironment
);
361 TXNIdle(varsp
->fTXNRec
);
363 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
365 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
366 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
371 // SetThemeCursor(kThemeArrowCursor);
374 /* if it's in our bounds, set the cursor */
375 GetControlBounds(theControl
, &bounds
);
376 if (PtInRect(mousep
, &bounds
))
378 // SetThemeCursor(kThemeArrowCursor);
382 HSetState((Handle
) tpvars
, state
);
388 /* TPPaneKeyDownProc is called whenever a keydown event is directed
389 at our control. Here, we direct the keydown event to the text
390 edit record and redraw the scroll bar and text field as appropriate. */
391 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
392 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
393 STPTextPaneVars
**tpvars
;
394 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
395 if (tpvars
!= NULL
) {
396 if ((**tpvars
).fInFocus
) {
397 /* turn autoscrolling on and send the key event to text edit */
398 SetPort((**tpvars
).fDrawingEnvironment
);
399 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
401 memset( &ev
, 0 , sizeof( ev
) ) ;
403 ev
.modifiers
= modifiers
;
404 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
405 TXNKeyDown( (**tpvars
).fTXNRec
, &ev
);
408 return kControlEntireControl
;
412 /* TPPaneActivateProc is called when the window containing
413 the user pane control receives activate events. Here, we redraw
414 the control and it's text as necessary for the activation state. */
415 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
417 STPTextPaneVars
**tpvars
, *varsp
;
420 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
421 if (tpvars
!= NULL
) {
422 state
= HGetState((Handle
) tpvars
);
423 HLock((Handle
) tpvars
);
425 /* de/activate the text edit record */
426 SetPort((**tpvars
).fDrawingEnvironment
);
427 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
428 GetControlBounds(theControl
, &bounds
);
429 varsp
->fIsActive
= activating
;
430 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
431 /* redraw the frame */
432 if ( IsControlVisible( theControl
) )
434 if (!wxFindControlFromMacControl(theControl
)->HasFlag(wxNO_BORDER
))
436 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
438 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
441 HSetState((Handle
) tpvars
, state
);
446 /* TPPaneFocusProc is called when every the focus changes to or
447 from our control. Herein, switch the focus appropriately
448 according to the parameters and redraw the control as
450 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
451 ControlPartCode focusResult
;
452 STPTextPaneVars
**tpvars
, *varsp
;
455 focusResult
= kControlFocusNoPart
;
456 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
457 if (tpvars
!= NULL
) {
458 state
= HGetState((Handle
) tpvars
);
459 HLock((Handle
) tpvars
);
461 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
462 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
463 and kControlFocusNextPart will be received. When the user clicks in our field
464 and it is not the current focus, then the constant kUserClickedToFocusPart will
465 be received. The constant kControlFocusNoPart will be received when our control
466 is the current focus and the user clicks in another control. In your focus routine,
467 you should respond to these codes as follows:
469 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
470 the control and the focus rectangle as necessary.
472 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
473 depending on its current state. redraw the control and the focus rectangle
474 as appropriate for the new focus state. If the focus state is 'off', return the constant
475 kControlFocusNoPart, otherwise return a non-zero part code.
476 kUserClickedToFocusPart - is a constant defined for this example. You should
477 define your own value for handling click-to-focus type events. */
478 /* calculate the next highlight state */
481 case kControlFocusNoPart
:
482 TPFocusPaneText(tpvars
, false);
483 focusResult
= kControlFocusNoPart
;
485 case kUserClickedToFocusPart
:
486 TPFocusPaneText(tpvars
, true);
489 case kControlFocusPrevPart
:
490 case kControlFocusNextPart
:
491 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
492 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
495 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
496 /* redraw the text fram and focus rectangle to indicate the
498 if ( IsControlVisible( theControl
) )
500 if (!wxFindControlFromMacControl(theControl
)->HasFlag(wxNO_BORDER
))
502 /* save the drawing state */
503 SetPort((**tpvars
).fDrawingEnvironment
);
504 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
505 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
506 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
510 HSetState((Handle
) tpvars
, state
);
516 /* mUPOpenControl initializes a user pane control so it will be drawn
517 and will behave as a scrolling text edit field inside of a window.
518 This routine performs all of the initialization steps necessary,
519 except it does not create the user pane control itself. theControl
520 should refer to a user pane control that you have either created
521 yourself or extracted from a dialog's control heirarchy using
522 the GetDialogItemAsControl routine. */
523 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
)
527 STPTextPaneVars
**tpvars
, *varsp
;
528 OSStatus err
= noErr
;
529 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
532 /* set up our globals */
533 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
534 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
535 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
536 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
537 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
538 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
539 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
541 /* allocate our private storage */
542 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
543 SetControlReference(theControl
, (long) tpvars
);
544 HLock((Handle
) tpvars
);
546 /* set the initial settings for our private data */
547 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
548 varsp
->fInFocus
= false;
549 varsp
->fIsActive
= true;
550 varsp
->fTEActive
= true; // in order to get a deactivate
551 varsp
->fUserPaneRec
= theControl
;
552 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
554 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
556 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
557 /* set up the user pane procedures */
558 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
559 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
560 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
561 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
562 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
563 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
564 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
565 /* calculate the rectangles used by the control */
566 GetControlBounds(theControl
, &bounds
);
567 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
568 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
569 if ((wxStyle
& wxNO_BORDER
) != wxNO_BORDER
)
571 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
572 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
576 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
577 bounds
.right
, bounds
.bottom
);
580 /* calculate the background region for the text. In this case, it's kindof
581 and irregular region because we're setting the scroll bar a little ways inside
583 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
585 /* set up the drawing environment */
586 SetPort(varsp
->fDrawingEnvironment
);
588 /* create the new edit field */
590 TXNFrameOptions frameOptions
=
591 kTXNDontDrawCaretWhenInactiveMask
;
592 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
593 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
595 if ( wxStyle
& wxTE_MULTILINE
)
597 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
598 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
601 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
602 frameOptions
|= kTXNWantHScrollBarMask
;
605 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
606 frameOptions
|= kTXNWantVScrollBarMask
;
609 frameOptions
|= kTXNSingleLineOnlyMask
;
611 if ( wxStyle
& wxTE_READONLY
)
612 frameOptions
|= kTXNReadOnlyMask
;
614 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
616 kTXNTextEditStyleFrameType
,
618 kTXNSystemDefaultEncoding
,
619 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
621 if ( !IsControlVisible( theControl
) )
622 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
623 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
626 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
628 TXNControlTag tag
= kTXNWordWrapStateTag
;
630 dat
.uValue
= kTXNNoAutoWrap
;
631 TXNSetTXNObjectControls( varsp
->fTXNRec
, false , 1 , &tag
, &dat
) ;
637 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
639 TXNTypeAttributes typeAttr
[] =
641 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
642 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
643 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
646 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
649 /* set the field's background */
651 tback
.bgType
= kTXNBackgroundTypeRGB
;
652 tback
.bg
.color
= rgbWhite
;
653 TXNSetBackground( varsp
->fTXNRec
, &tback
);
655 /* unlock our storage */
656 HUnlock((Handle
) tpvars
);
657 /* perform final activations and setup for our text field. Here,
658 we assume that the window is going to be the 'active' window. */
659 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
667 #if !USE_SHARED_LIBRARY
668 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
670 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
671 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
672 EVT_CHAR(wxTextCtrl::OnChar
)
673 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
674 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
675 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
676 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
677 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
679 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
680 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
681 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
682 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
683 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
687 static void SetTXNData( TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
690 #if SIZEOF_WCHAR_T == 2
691 size_t len
= st
.Len() ;
692 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
695 wxMBConvUTF16BE converter
;
696 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
697 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
698 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
699 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
704 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
705 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
711 void wxTextCtrl::Init()
715 m_macTXNvars
= NULL
;
716 m_macUsesTXN
= false ;
721 m_maxLength
= TE_UNLIMITED_LENGTH
;
724 wxTextCtrl::~wxTextCtrl()
728 SetControlReference((ControlHandle
)m_macControl
, 0) ;
729 TXNDeleteObject((TXNObject
)m_macTXN
);
730 /* delete our private storage */
731 DisposeHandle((Handle
) m_macTXNvars
);
732 /* zero the control reference */
736 const short kVerticalMargin
= 2 ;
737 const short kHorizontalMargin
= 2 ;
739 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
742 const wxSize
& size
, long style
,
743 const wxValidator
& validator
,
744 const wxString
& name
)
748 m_macTXNvars
= NULL
;
749 m_macUsesTXN
= false ;
752 m_macUsesTXN
= ! (style
& wxTE_PASSWORD
) ;
754 m_macUsesTXN
&= (TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
) ;
756 // base initialization
757 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
760 wxSize mySize
= size
;
761 if (style
& wxNO_BORDER
)
763 m_macHorizontalBorder
= 0 ;
764 m_macVerticalBorder
= 0 ;
766 else if ( m_macUsesTXN
)
768 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
769 m_macVerticalBorder
= 3 ;
773 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
774 m_macVerticalBorder
= 5 ;
781 if ( mySize.y == -1 )
784 if ( m_windowStyle & wxTE_MULTILINE )
787 mySize.y += 2 * m_macVerticalBorder ;
790 MacPreControlCreate( parent
, id
, wxEmptyString
, pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
792 if ( m_windowStyle
& wxTE_MULTILINE
)
794 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
795 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
797 m_windowStyle
|= wxTE_PROCESS_ENTER
;
800 if ( m_windowStyle
& wxTE_READONLY
)
806 wxMacConvertNewlines13To10( &st
) ;
809 m_macControl
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds
, "\p" , false , 0 , 0 , 1,
810 (style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
812 ::GetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*)((TEHandle
*)&m_macTE
) , &size
) ;
819 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
820 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
821 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
822 /* create the control */
823 m_macControl
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
824 /* set up the mUP specific features and data */
825 mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle
);
827 MacPostControlCreate() ;
831 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
832 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
836 STPTextPaneVars
**tpvars
;
838 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
839 /* set the text in the record */
840 m_macTXN
= (**tpvars
).fTXNRec
;
841 SetTXNData( (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
842 m_macTXNvars
= tpvars
;
843 m_macUsesTXN
= true ;
844 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
845 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
851 wxString
wxTextCtrl::GetValue() const
858 err
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0,
859 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, &actualSize
) ;
862 return wxEmptyString
;
864 if ( actualSize
> 0 )
866 wxCharBuffer
buf(actualSize
) ;
867 ::GetControlData( (ControlHandle
) m_macControl
, 0,
868 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
,
869 actualSize
, buf
.data() , &actualSize
) ;
870 result
= wxString( buf
, wxConvLocal
) ;
877 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
885 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
886 if ( actualSize
> 0 )
888 wxChar
*ptr
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ;
889 #if SIZEOF_WCHAR_T == 2
890 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
892 wxMBConvUTF16BE converter
;
894 converter
.MB2WC( ptr
, (const char*)*theText
, actualSize
) ;
897 ptr
[actualSize
] = 0 ;
898 result
.UngetWriteBuf( actualSize
*sizeof(wxChar
) ) ;
900 DisposeHandle( theText
) ;
904 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
912 actualSize
= GetHandleSize( theText
) ;
913 if ( actualSize
> 0 )
916 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
919 DisposeHandle( theText
) ;
923 wxMacConvertNewlines10To13( &result
) ;
927 void wxTextCtrl::GetSelection(long* from
, long* to
) const
931 *from
= (**((TEHandle
) m_macTE
)).selStart
;
932 *to
= (**((TEHandle
) m_macTE
)).selEnd
;
936 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
940 void wxTextCtrl::SetValue(const wxString
& str
)
943 wxMacConvertNewlines13To10( &st
) ;
946 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
947 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
951 bool formerEditable
= m_editable
;
952 if ( !formerEditable
)
954 SetTXNData( (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
955 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
956 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
957 if ( !formerEditable
)
958 SetEditable(formerEditable
) ;
963 void wxTextCtrl::SetMaxLength(unsigned long len
)
968 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
972 bool formerEditable
= m_editable
;
973 if ( !formerEditable
)
975 TXNTypeAttributes typeAttr
[4] ;
976 Str255 fontName
= "\pMonaco" ;
977 SInt16 fontSize
= 12 ;
978 Style fontStyle
= normal
;
980 int attrCounter
= 0 ;
981 if ( style
.HasFont() )
983 const wxFont
&font
= style
.GetFont() ;
984 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
985 fontSize
= font
.GetPointSize() ;
986 if ( font
.GetUnderlined() )
987 fontStyle
|= underline
;
988 if ( font
.GetWeight() == wxBOLD
)
990 if ( font
.GetStyle() == wxITALIC
)
991 fontStyle
|= italic
;
993 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
994 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
995 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
996 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
997 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
998 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
999 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1000 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1001 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1005 if ( style
.HasTextColour() )
1007 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1008 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1009 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1010 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1014 if ( attrCounter
> 0 )
1018 #endif // __WXDEBUG__
1019 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
);
1020 wxASSERT_MSG( status
== noErr
, wxT("Couldn't set text attributes") ) ;
1022 if ( !formerEditable
)
1023 SetEditable(formerEditable
) ;
1028 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1030 wxTextCtrlBase::SetDefaultStyle( style
) ;
1031 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1035 // Clipboard operations
1036 void wxTextCtrl::Copy()
1040 if ( !m_macUsesTXN
)
1042 TECopy( ((TEHandle
) m_macTE
) ) ;
1043 ClearCurrentScrap();
1045 MacRedrawControl() ;
1049 ClearCurrentScrap();
1050 TXNCopy((TXNObject
)m_macTXN
);
1051 TXNConvertToPublicScrap();
1056 void wxTextCtrl::Cut()
1060 if ( !m_macUsesTXN
)
1062 TECut( ((TEHandle
) m_macTE
) ) ;
1063 ClearCurrentScrap();
1065 MacRedrawControl() ;
1069 ClearCurrentScrap();
1070 TXNCut((TXNObject
)m_macTXN
);
1071 TXNConvertToPublicScrap();
1073 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1074 event
.SetString( GetValue() ) ;
1075 event
.SetEventObject( this );
1076 GetEventHandler()->ProcessEvent(event
);
1080 void wxTextCtrl::Paste()
1084 if ( !m_macUsesTXN
)
1087 TEPaste( (TEHandle
) m_macTE
) ;
1088 MacRedrawControl() ;
1092 TXNConvertFromPublicScrap();
1093 TXNPaste((TXNObject
)m_macTXN
);
1094 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1096 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1097 event
.SetString( GetValue() ) ;
1098 event
.SetEventObject( this );
1099 GetEventHandler()->ProcessEvent(event
);
1103 bool wxTextCtrl::CanCopy() const
1105 // Can copy if there's a selection
1107 GetSelection(& from
, & to
);
1108 return (from
!= to
);
1111 bool wxTextCtrl::CanCut() const
1113 if ( !IsEditable() )
1117 // Can cut if there's a selection
1119 GetSelection(& from
, & to
);
1120 return (from
!= to
);
1123 bool wxTextCtrl::CanPaste() const
1129 OSStatus err
= noErr
;
1132 err
= GetCurrentScrap( &scrapRef
);
1133 if ( err
!= noTypeErr
&& err
!= memFullErr
)
1135 ScrapFlavorFlags flavorFlags
;
1138 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
1140 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
1150 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
1158 void wxTextCtrl::SetEditable(bool editable
)
1160 if ( editable
!= m_editable
)
1162 m_editable
= editable
;
1163 if ( !m_macUsesTXN
)
1166 UMAActivateControl( (ControlHandle
) m_macControl
) ;
1168 UMADeactivateControl((ControlHandle
) m_macControl
) ;
1172 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1173 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1174 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1179 void wxTextCtrl::SetInsertionPoint(long pos
)
1181 SetSelection( pos
, pos
) ;
1184 void wxTextCtrl::SetInsertionPointEnd()
1186 long pos
= GetLastPosition();
1187 SetInsertionPoint(pos
);
1190 long wxTextCtrl::GetInsertionPoint() const
1193 GetSelection( &begin
, &end
) ;
1197 long wxTextCtrl::GetLastPosition() const
1199 if ( !m_macUsesTXN
)
1201 return (**((TEHandle
) m_macTE
)).teLength
;
1207 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1215 actualsize
= GetHandleSize( theText
) ;
1216 DisposeHandle( theText
) ;
1222 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1224 wxString value
= str
;
1225 wxMacConvertNewlines13To10( &value
) ;
1226 if ( !m_macUsesTXN
)
1228 ControlEditTextSelectionRec selection
;
1230 selection
.selStart
= from
;
1231 selection
.selEnd
= to
;
1232 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1233 TESetSelect( from
, to
, ((TEHandle
) m_macTE
) ) ;
1234 TEDelete( ((TEHandle
) m_macTE
) ) ;
1235 TEInsert( value
, value
.Length() , ((TEHandle
) m_macTE
) ) ;
1239 bool formerEditable
= m_editable
;
1240 if ( !formerEditable
)
1242 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1243 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1244 SetTXNData( (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1245 if ( !formerEditable
)
1246 SetEditable( formerEditable
) ;
1251 void wxTextCtrl::Remove(long from
, long to
)
1253 if ( !m_macUsesTXN
)
1255 ControlEditTextSelectionRec selection
;
1257 selection
.selStart
= from
;
1258 selection
.selEnd
= to
;
1259 ::SetControlData( (ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1260 TEDelete( ((TEHandle
) m_macTE
) ) ;
1264 bool formerEditable
= m_editable
;
1265 if ( !formerEditable
)
1267 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1268 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1269 if ( !formerEditable
)
1270 SetEditable( formerEditable
) ;
1275 void wxTextCtrl::SetSelection(long from
, long to
)
1277 if ( !m_macUsesTXN
)
1279 ControlEditTextSelectionRec selection
;
1280 if ((from
== -1) && (to
== -1))
1282 selection
.selStart
= 0 ;
1283 selection
.selEnd
= 32767 ;
1287 selection
.selStart
= from
;
1288 selection
.selEnd
= to
;
1291 TESetSelect( selection
.selStart
, selection
.selEnd
, ((TEHandle
) m_macTE
) ) ;
1292 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1296 STPTextPaneVars
**tpvars
;
1297 /* set up our locals */
1298 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
1299 /* and our drawing environment as the operation
1300 may force a redraw in the text area. */
1301 SetPort((**tpvars
).fDrawingEnvironment
);
1302 /* change the selection */
1303 if ((from
== -1) && (to
== -1))
1304 TXNSelectAll((TXNObject
) m_macTXN
);
1306 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
1307 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1311 bool wxTextCtrl::LoadFile(const wxString
& file
)
1313 if ( wxTextCtrlBase::LoadFile(file
) )
1321 void wxTextCtrl::WriteText(const wxString
& str
)
1324 wxMacConvertNewlines13To10( &st
) ;
1325 if ( !m_macUsesTXN
)
1327 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1328 TEInsert( text
, strlen(text
) , ((TEHandle
) m_macTE
) ) ;
1332 bool formerEditable
= m_editable
;
1333 if ( !formerEditable
)
1335 long start
, end
, dummy
;
1336 GetSelection( &start
, &dummy
) ;
1337 SetTXNData( (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1338 GetSelection( &dummy
, &end
) ;
1339 SetStyle( start
, end
, GetDefaultStyle() ) ;
1340 if ( !formerEditable
)
1341 SetEditable( formerEditable
) ;
1343 MacRedrawControl() ;
1346 void wxTextCtrl::AppendText(const wxString
& text
)
1348 SetInsertionPointEnd();
1352 void wxTextCtrl::Clear()
1354 if ( !m_macUsesTXN
)
1356 ::SetControlData((ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
1360 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1361 TXNClear((TXNObject
)m_macTXN
);
1366 bool wxTextCtrl::IsModified() const
1371 bool wxTextCtrl::IsEditable() const
1373 return IsEnabled() && m_editable
;
1376 bool wxTextCtrl::AcceptsFocus() const
1378 // we don't want focus if we can't be edited
1379 return /*IsEditable() && */ wxControl::AcceptsFocus();
1382 wxSize
wxTextCtrl::DoGetBestSize() const
1397 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
1399 int wText = DEFAULT_ITEM_WIDTH;
1401 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
1403 return wxSize(wText, hText);
1405 if ( m_windowStyle
& wxTE_MULTILINE
)
1409 hText
+= 2 * m_macVerticalBorder
;
1410 wText
+= 2 * m_macHorizontalBorder
;
1411 //else: for single line control everything is ok
1412 return wxSize(wText
, hText
);
1415 // ----------------------------------------------------------------------------
1417 // ----------------------------------------------------------------------------
1419 void wxTextCtrl::Undo()
1425 TXNUndo((TXNObject
)m_macTXN
);
1430 void wxTextCtrl::Redo()
1436 TXNRedo((TXNObject
)m_macTXN
);
1441 bool wxTextCtrl::CanUndo() const
1443 if ( !IsEditable() )
1449 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1454 bool wxTextCtrl::CanRedo() const
1456 if ( !IsEditable() )
1462 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1467 // Makes modifie or unmodified
1468 void wxTextCtrl::MarkDirty()
1473 void wxTextCtrl::DiscardEdits()
1478 int wxTextCtrl::GetNumberOfLines() const
1483 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1488 wxString content
= GetValue() ;
1491 for (size_t i
= 0; i
< content
.Length() ; i
++)
1493 if (content
[i
] == '\r') count
++;
1499 long wxTextCtrl::XYToPosition(long x
, long y
) const
1505 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1510 void wxTextCtrl::ShowPosition(long pos
)
1512 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1517 TXNOffset selstart
, selend
;
1518 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1519 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1520 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1521 //TODO use HIPoints for 10.3 and above
1522 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1524 OSErr theErr
= noErr
;
1525 SInt32 dv
= desired
.v
- current
.v
;
1526 SInt32 dh
= desired
.h
- current
.h
;
1527 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1528 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1529 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1535 int wxTextCtrl::GetLineLength(long lineNo
) const
1537 // TODO change this if possible to reflect real lines
1538 wxString content
= GetValue() ;
1542 for (size_t i
= 0; i
< content
.Length() ; i
++)
1544 if (count
== lineNo
)
1546 // Count chars in line then
1548 for (size_t j
= i
; j
< content
.Length(); j
++)
1551 if (content
[j
] == '\n') return count
;
1556 if (content
[i
] == '\n') count
++;
1561 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1563 // TODO change this if possible to reflect real lines
1564 wxString content
= GetValue() ;
1568 for (size_t i
= 0; i
< content
.Length() ; i
++)
1570 if (count
== lineNo
)
1572 // Add chars in line then
1575 for (size_t j
= i
; j
< content
.Length(); j
++)
1577 if (content
[j
] == '\n')
1585 if (content
[i
] == '\n') count
++;
1587 return wxEmptyString
;
1594 void wxTextCtrl::Command(wxCommandEvent
& event
)
1596 SetValue (event
.GetString());
1597 ProcessCommand (event
);
1600 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1602 // By default, load the first file into the text window.
1603 if (event
.GetNumberOfFiles() > 0)
1605 LoadFile(event
.GetFiles()[0]);
1609 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1611 int key
= event
.GetKeyCode() ;
1612 bool eat_key
= false ;
1614 if ( key
== 'c' && event
.MetaDown() )
1621 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1622 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1623 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1630 // assume that any key not processed yet is going to modify the control
1633 if ( key
== 'v' && event
.MetaDown() )
1639 if ( key
== 'x' && event
.MetaDown() )
1648 if (m_windowStyle
& wxPROCESS_ENTER
)
1650 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1651 event
.SetEventObject( this );
1652 event
.SetString( GetValue() );
1653 if ( GetEventHandler()->ProcessEvent(event
) )
1656 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1658 wxWindow
*parent
= GetParent();
1659 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1660 parent
= parent
->GetParent() ;
1662 if ( parent
&& parent
->GetDefaultItem() )
1664 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1666 if ( def
&& def
->IsEnabled() )
1668 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1669 event
.SetEventObject(def
);
1670 def
->Command(event
);
1675 // this will make wxWindows eat the ENTER key so that
1676 // we actually prevent line wrapping in a single line
1684 // always produce navigation event - even if we process TAB
1685 // ourselves the fact that we got here means that the user code
1686 // decided to skip processing of this TAB - probably to let it
1687 // do its default job.
1689 wxNavigationKeyEvent eventNav
;
1690 eventNav
.SetDirection(!event
.ShiftDown());
1691 eventNav
.SetWindowChange(event
.ControlDown());
1692 eventNav
.SetEventObject(this);
1694 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1705 // perform keystroke handling
1707 if ( m_macUsesTXN
&& wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1708 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1712 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1714 EventRecord
*ev
= &rec
;
1717 keychar
= short(ev
->message
& charCodeMask
);
1718 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1720 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1724 EventRecord
*ev
= (EventRecord
*) wxTheApp
->MacGetCurrentEvent() ;
1727 keychar
= short(ev
->message
& charCodeMask
);
1728 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1730 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1733 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1734 key
== WXK_RETURN
||
1735 key
== WXK_DELETE
||
1738 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1739 event1
.SetString( GetValue() ) ;
1740 event1
.SetEventObject( this );
1741 wxPostEvent(GetEventHandler(),event1
);
1745 void wxTextCtrl::MacSuperShown( bool show
)
1747 bool former
= m_macControlIsShown
;
1748 wxControl::MacSuperShown( show
) ;
1749 if ( (former
!= m_macControlIsShown
) && m_macUsesTXN
)
1751 if ( m_macControlIsShown
)
1752 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1753 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1755 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1756 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1760 bool wxTextCtrl::Show(bool show
)
1762 bool former
= m_macControlIsShown
;
1764 bool retval
= wxControl::Show( show
) ;
1766 if ( former
!= m_macControlIsShown
&& m_macUsesTXN
)
1768 if ( m_macControlIsShown
)
1769 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1770 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1772 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1773 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1779 // ----------------------------------------------------------------------------
1780 // standard handlers for standard edit menu events
1781 // ----------------------------------------------------------------------------
1783 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1788 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1793 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1798 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1803 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1808 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1810 event
.Enable( CanCut() );
1813 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1815 event
.Enable( CanCopy() );
1818 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1820 event
.Enable( CanPaste() );
1823 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1825 event
.Enable( CanUndo() );
1828 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1830 event
.Enable( CanRedo() );
1833 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1838 return wxWindow::MacSetupCursor( pt
) ;