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