1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
21 #include <sys/types.h>
27 #if wxUSE_STD_IOSTREAM
37 #include "wx/button.h"
38 #include "wx/toplevel.h"
39 #include "wx/textctrl.h"
40 #include "wx/notebook.h"
41 #include "wx/tabctrl.h"
42 #include "wx/settings.h"
43 #include "wx/filefn.h"
46 #if defined(__BORLANDC__) && !defined(__WIN32__)
48 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
55 #include <MacTextEditor.h>
56 #include "ATSUnicode.h"
57 #include "TextCommon.h"
58 #include "TextEncodingConverter.h"
59 #include "wx/mac/uma.h"
61 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
63 extern wxControl
*wxFindControlFromMacControl(ControlHandle inControl
) ;
65 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
66 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
67 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
68 // an alternate path for carbon key events that routes automatically into the same wx flow of events
70 #include "MacTextEditor.h"
74 /* kmUPTextPart is the part code we return to indicate the user has clicked
75 in the text area of our control */
76 #define kmUPTextPart 1
78 /* kmUPScrollPart is the part code we return to indicate the user has clicked
79 in the scroll bar part of the control. */
80 #define kmUPScrollPart 2
83 /* routines for using existing user pane controls.
84 These routines are useful for cases where you would like to use an
85 existing user pane control in, say, a dialog window as a scrolling
88 /* mUPOpenControl initializes a user pane control so it will be drawn
89 and will behave as a scrolling text edit field inside of a window.
90 This routine performs all of the initialization steps necessary,
91 except it does not create the user pane control itself. theControl
92 should refer to a user pane control that you have either created
93 yourself or extracted from a dialog's control heirarchy using
94 the GetDialogItemAsControl routine. */
95 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
);
97 /* Utility Routines */
103 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
104 routine. In our focus switching routine this part code is understood
105 as meaning 'the user has clicked in the control and we need to switch
106 the current focus to ourselves before we can continue'. */
107 #define kUserClickedToFocusPart 100
110 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
111 slow the speed of 'auto scrolling' inside of our clickloop routine.
112 This value prevents the text from wizzzzzing by while the mouse
113 is being held down inside of the text area. */
114 #define kmUPClickScrollDelayTicks 3
117 /* STPTextPaneVars is a structure used for storing the the mUP Control's
118 internal variables and state information. A handle to this record is
119 stored in the pane control's reference value field using the
120 SetControlReference routine. */
123 /* OS records referenced */
124 TXNObject fTXNRec
; /* the txn record */
125 TXNFrameID fTXNFrame
; /* the txn frame ID */
126 ControlHandle fUserPaneRec
; /* handle to the user pane control */
127 WindowPtr fOwner
; /* window containing control */
128 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
130 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
131 Boolean fIsActive
; /* true while the control is drawn in the active state */
132 Boolean fTEActive
; /* reflects the activation state of the text edit record */
133 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
134 /* calculated locations */
135 Rect fRTextArea
; /* area where the text is drawn */
136 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
137 Rect fRTextOutline
; /* rectangle used to draw the border */
138 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
139 /* our focus advance override routine */
140 EventHandlerUPP handlerUPP
;
141 EventHandlerRef handlerRef
;
148 /* Univerals Procedure Pointer variables used by the
149 mUP Control. These variables are set up
150 the first time that mUPOpenControl is called. */
151 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
152 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
153 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
154 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
155 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
156 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
157 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
159 /* TPActivatePaneText activates or deactivates the text edit record
160 according to the value of setActive. The primary purpose of this
161 routine is to ensure each call is only made once. */
162 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
163 STPTextPaneVars
*varsp
;
165 if (varsp
->fTEActive
!= setActive
) {
167 varsp
->fTEActive
= setActive
;
169 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
172 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
177 /* TPFocusPaneText set the focus state for the text record. */
178 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
179 STPTextPaneVars
*varsp
;
181 if (varsp
->fInFocus
!= setFocus
) {
182 varsp
->fInFocus
= setFocus
;
183 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
188 /* TPPaneDrawProc is called to redraw the control and for update events
189 referring to the control. This routine erases the text area's background,
190 and redraws the text. This routine assumes the scroll bar has been
191 redrawn by a call to DrawControls. */
192 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
193 STPTextPaneVars
**tpvars
, *varsp
;
196 /* set up our globals */
198 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
199 if (tpvars
!= NULL
) {
200 state
= HGetState((Handle
) tpvars
);
201 HLock((Handle
) tpvars
);
204 /* save the drawing state */
205 SetPort((**tpvars
).fDrawingEnvironment
);
206 /* verify our boundary */
207 GetControlBounds(theControl
, &bounds
);
209 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
210 if ( ! EqualRect(&bounds
, &varsp
->fRFocusOutline
) ) {
211 // scrollbar is on the border, we add one
212 Rect oldbounds
= varsp
->fRFocusOutline
;
213 InsetRect( &oldbounds
, -1 , -1 ) ;
215 InvalWindowRect( GetControlOwner( theControl
) , &oldbounds
) ;
216 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
217 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
218 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
219 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
220 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
221 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
222 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
225 /* update the text region */
226 RGBColor white
= { 65535 , 65535 , 65535 } ;
227 RGBBackColor( &white
) ;
228 EraseRgn(varsp
->fTextBackgroundRgn
);
229 TXNDraw(varsp
->fTXNRec
, NULL
);
230 /* restore the drawing environment */
231 /* draw the text frame and focus frame (if necessary) */
232 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
233 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
234 /* release our globals */
235 HSetState((Handle
) tpvars
, state
);
241 /* TPPaneHitTestProc is called when the control manager would
242 like to determine what part of the control the mouse resides over.
243 We also call this routine from our tracking proc to determine how
244 to handle mouse clicks. */
245 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
246 STPTextPaneVars
**tpvars
;
247 ControlPartCode result
;
249 /* set up our locals and lock down our globals*/
251 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
252 if (tpvars
!= NULL
) {
253 state
= HGetState((Handle
) tpvars
);
254 HLock((Handle
) tpvars
);
255 /* find the region where we clicked */
256 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
257 result
= kmUPTextPart
;
259 /* release oure globals */
260 HSetState((Handle
) tpvars
, state
);
269 /* TPPaneTrackingProc is called when the mouse is being held down
270 over our control. This routine handles clicks in the text area
271 and in the scroll bar. */
272 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
273 STPTextPaneVars
**tpvars
, *varsp
;
275 ControlPartCode partCodeResult
;
276 /* make sure we have some variables... */
278 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
279 if (tpvars
!= NULL
) {
281 state
= HGetState((Handle
) tpvars
);
282 HLock((Handle
) tpvars
);
284 /* we don't do any of these functions unless we're in focus */
285 if ( ! varsp
->fInFocus
) {
287 owner
= GetControlOwner(theControl
);
288 ClearKeyboardFocus(owner
);
289 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
291 /* find the location for the click */
292 switch (TPPaneHitTestProc(theControl
, startPt
)) {
294 /* handle clicks in the text part */
296 { SetPort((**tpvars
).fDrawingEnvironment
);
297 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
299 TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent());
302 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
303 TXNClick( varsp
->fTXNRec
, &rec
);
310 HSetState((Handle
) tpvars
, state
);
312 return partCodeResult
;
316 /* TPPaneIdleProc is our user pane idle routine. When our text field
317 is active and in focus, we use this routine to set the cursor. */
318 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
319 STPTextPaneVars
**tpvars
, *varsp
;
321 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
322 if (tpvars
!= NULL
) {
323 /* if we're not active, then we have nothing to say about the cursor */
324 if ((**tpvars
).fIsActive
) {
328 /* lock down the globals */
329 state
= HGetState((Handle
) tpvars
);
330 HLock((Handle
) tpvars
);
332 /* get the current mouse coordinates (in our window) */
333 SetPortWindowPort(GetControlOwner(theControl
));
334 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
336 /* there's a 'focus thing' and an 'unfocused thing' */
337 if (varsp
->fInFocus
) {
338 /* flash the cursor */
339 SetPort((**tpvars
).fDrawingEnvironment
);
340 TXNIdle(varsp
->fTXNRec
);
342 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
344 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
345 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
350 // SetThemeCursor(kThemeArrowCursor);
353 /* if it's in our bounds, set the cursor */
354 GetControlBounds(theControl
, &bounds
);
355 if (PtInRect(mousep
, &bounds
))
357 // SetThemeCursor(kThemeArrowCursor);
361 HSetState((Handle
) tpvars
, state
);
367 /* TPPaneKeyDownProc is called whenever a keydown event is directed
368 at our control. Here, we direct the keydown event to the text
369 edit record and redraw the scroll bar and text field as appropriate. */
370 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
371 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
372 STPTextPaneVars
**tpvars
;
373 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
374 if (tpvars
!= NULL
) {
375 if ((**tpvars
).fInFocus
) {
376 /* turn autoscrolling on and send the key event to text edit */
377 SetPort((**tpvars
).fDrawingEnvironment
);
378 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
380 memset( &ev
, 0 , sizeof( ev
) ) ;
382 ev
.modifiers
= modifiers
;
383 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
384 TXNKeyDown( (**tpvars
).fTXNRec
, &ev
);
387 return kControlEntireControl
;
391 /* TPPaneActivateProc is called when the window containing
392 the user pane control receives activate events. Here, we redraw
393 the control and it's text as necessary for the activation state. */
394 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
396 STPTextPaneVars
**tpvars
, *varsp
;
399 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
400 if (tpvars
!= NULL
) {
401 state
= HGetState((Handle
) tpvars
);
402 HLock((Handle
) tpvars
);
404 /* de/activate the text edit record */
405 SetPort((**tpvars
).fDrawingEnvironment
);
406 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
407 GetControlBounds(theControl
, &bounds
);
408 varsp
->fIsActive
= activating
;
409 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
410 /* redraw the frame */
411 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
412 if (varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
413 HSetState((Handle
) tpvars
, state
);
418 /* TPPaneFocusProc is called when every the focus changes to or
419 from our control. Herein, switch the focus appropriately
420 according to the parameters and redraw the control as
422 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
423 ControlPartCode focusResult
;
424 STPTextPaneVars
**tpvars
, *varsp
;
427 focusResult
= kControlFocusNoPart
;
428 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
429 if (tpvars
!= NULL
) {
430 state
= HGetState((Handle
) tpvars
);
431 HLock((Handle
) tpvars
);
433 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
434 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
435 and kControlFocusNextPart will be received. When the user clicks in our field
436 and it is not the current focus, then the constant kUserClickedToFocusPart will
437 be received. The constant kControlFocusNoPart will be received when our control
438 is the current focus and the user clicks in another control. In your focus routine,
439 you should respond to these codes as follows:
441 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
442 the control and the focus rectangle as necessary.
444 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
445 depending on its current state. redraw the control and the focus rectangle
446 as appropriate for the new focus state. If the focus state is 'off', return the constant
447 kControlFocusNoPart, otherwise return a non-zero part code.
448 kUserClickedToFocusPart - is a constant defined for this example. You should
449 define your own value for handling click-to-focus type events. */
450 /* save the drawing state */
451 SetPort((**tpvars
).fDrawingEnvironment
);
452 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
453 /* calculate the next highlight state */
456 case kControlFocusNoPart
:
457 TPFocusPaneText(tpvars
, false);
458 focusResult
= kControlFocusNoPart
;
460 case kUserClickedToFocusPart
:
461 TPFocusPaneText(tpvars
, true);
464 case kControlFocusPrevPart
:
465 case kControlFocusNextPart
:
466 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
467 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
470 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
471 /* redraw the text fram and focus rectangle to indicate the
473 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
474 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
476 HSetState((Handle
) tpvars
, state
);
482 /* mUPOpenControl initializes a user pane control so it will be drawn
483 and will behave as a scrolling text edit field inside of a window.
484 This routine performs all of the initialization steps necessary,
485 except it does not create the user pane control itself. theControl
486 should refer to a user pane control that you have either created
487 yourself or extracted from a dialog's control heirarchy using
488 the GetDialogItemAsControl routine. */
489 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
)
493 STPTextPaneVars
**tpvars
, *varsp
;
494 OSStatus err
= noErr
;
495 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
498 /* set up our globals */
499 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
500 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
501 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
502 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
503 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
504 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
505 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
507 /* allocate our private storage */
508 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
509 SetControlReference(theControl
, (long) tpvars
);
510 HLock((Handle
) tpvars
);
512 /* set the initial settings for our private data */
513 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
514 varsp
->fInFocus
= false;
515 varsp
->fIsActive
= true;
516 varsp
->fTEActive
= true; // in order to get a deactivate
517 varsp
->fUserPaneRec
= theControl
;
518 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
520 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
522 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
523 /* set up the user pane procedures */
524 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
525 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
526 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
527 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
528 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
529 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
530 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
531 /* calculate the rectangles used by the control */
532 GetControlBounds(theControl
, &bounds
);
533 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
534 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
535 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
536 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
537 /* calculate the background region for the text. In this case, it's kindof
538 and irregular region because we're setting the scroll bar a little ways inside
540 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
542 /* set up the drawing environment */
543 SetPort(varsp
->fDrawingEnvironment
);
545 /* create the new edit field */
547 TXNFrameOptions frameOptions
=
548 kTXNDontDrawCaretWhenInactiveMask
;
549 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
550 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
552 if ( wxStyle
& wxTE_MULTILINE
)
554 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
555 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
558 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
559 frameOptions
|= kTXNWantHScrollBarMask
;
562 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
563 frameOptions
|= kTXNWantVScrollBarMask
;
566 frameOptions
|= kTXNSingleLineOnlyMask
;
568 if ( wxStyle
& wxTE_READONLY
)
569 frameOptions
|= kTXNReadOnlyMask
;
571 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
573 kTXNTextEditStyleFrameType
,
575 kTXNSystemDefaultEncoding
,
576 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
582 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
584 TXNTypeAttributes typeAttr
[] =
586 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
587 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
588 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
591 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
594 /* set the field's background */
596 tback
.bgType
= kTXNBackgroundTypeRGB
;
597 tback
.bg
.color
= rgbWhite
;
598 TXNSetBackground( varsp
->fTXNRec
, &tback
);
600 /* unlock our storage */
601 HUnlock((Handle
) tpvars
);
602 /* perform final activations and setup for our text field. Here,
603 we assume that the window is going to be the 'active' window. */
604 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
612 #if !USE_SHARED_LIBRARY
613 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
615 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
616 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
617 EVT_CHAR(wxTextCtrl::OnChar
)
618 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
619 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
620 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
621 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
622 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
624 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
625 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
626 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
627 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
628 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
633 wxTextCtrl::wxTextCtrl()
637 m_macTXNvars
= NULL
;
638 m_macUsesTXN
= false ;
640 m_maxLength
= TE_UNLIMITED_LENGTH
;
643 wxTextCtrl::~wxTextCtrl()
647 SetControlReference((ControlHandle
)m_macControl
, 0) ;
648 TXNDeleteObject((TXNObject
)m_macTXN
);
649 /* delete our private storage */
650 DisposeHandle((Handle
) m_macTXNvars
);
651 /* zero the control reference */
655 const short kVerticalMargin
= 2 ;
656 const short kHorizontalMargin
= 2 ;
658 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
661 const wxSize
& size
, long style
,
662 const wxValidator
& validator
,
663 const wxString
& name
)
667 m_macTXNvars
= NULL
;
668 m_macUsesTXN
= false ;
671 m_macUsesTXN
= ! (style
& wxTE_PASSWORD
) ;
673 m_macUsesTXN
&= (TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
) ;
675 // base initialization
676 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
679 wxSize mySize
= size
;
682 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
683 m_macVerticalBorder
= 3 ;
687 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
688 m_macVerticalBorder
= 5 ;
695 if ( mySize.y == -1 )
698 if ( m_windowStyle & wxTE_MULTILINE )
701 mySize.y += 2 * m_macVerticalBorder ;
704 MacPreControlCreate( parent
, id
, wxEmptyString
, pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
706 if ( m_windowStyle
& wxTE_MULTILINE
)
708 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
709 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
711 m_windowStyle
|= wxTE_PROCESS_ENTER
;
714 if ( m_windowStyle
& wxTE_READONLY
)
721 m_macControl
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds
, "\p" , true , 0 , 0 , 1,
722 (style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
724 ::GetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*)((TEHandle
*)&m_macTE
) , &size
) ;
731 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
732 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
733 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
734 /* create the control */
735 m_macControl
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", true, featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
736 /* set up the mUP specific features and data */
737 mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle
);
739 MacPostControlCreate() ;
743 wxCharBuffer text
= wxMacStringToCString( st
) ;
744 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
748 STPTextPaneVars
**tpvars
;
750 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
751 /* set the text in the record */
752 m_macTXN
= (**tpvars
).fTXNRec
;
754 TXNSetData( ((TXNObject
) m_macTXN
) , kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2,
755 kTXNStartOffset
, kTXNEndOffset
);
757 wxCharBuffer text
= wxMacStringToCString( st
) ;
758 TXNSetData( ((TXNObject
) m_macTXN
) , kTXNTextData
, (void*)text
.data(), strlen( text
) ,
759 kTXNStartOffset
, kTXNEndOffset
);
761 m_macTXNvars
= tpvars
;
762 m_macUsesTXN
= true ;
763 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
764 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
770 wxString
wxTextCtrl::GetValue() const
777 err
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0,
778 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, &actualSize
) ;
781 return wxEmptyString
;
783 if ( actualSize
> 0 )
785 wxCharBuffer
buf(actualSize
) ;
786 ::GetControlData( (ControlHandle
) m_macControl
, 0,
787 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
,
788 actualSize
, buf
.data() , &actualSize
) ;
789 result
= wxMacMakeStringFromCString( buf
) ;
796 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
804 actualSize
= GetHandleSize( theText
) ;
805 if ( actualSize
> 0 )
807 wxChar
*ptr
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ;
808 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
809 ptr
[actualSize
] = 0 ;
810 result
.UngetWriteBuf( actualSize
) ;
812 DisposeHandle( theText
) ;
816 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
824 actualSize
= GetHandleSize( theText
) ;
825 if ( actualSize
> 0 )
828 result
= wxMacMakeStringFromCString( *theText
, actualSize
) ;
831 DisposeHandle( theText
) ;
839 void wxTextCtrl::GetSelection(long* from
, long* to
) const
843 *from
= (**((TEHandle
) m_macTE
)).selStart
;
844 *to
= (**((TEHandle
) m_macTE
)).selEnd
;
848 TXNGetSelection( ((TXNObject
) m_macTXN
) , (TXNOffset
*) from
, (TXNOffset
*) to
) ;
852 void wxTextCtrl::SetValue(const wxString
& st
)
856 wxCharBuffer text
= wxMacStringToCString( st
) ;
857 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
861 bool formerEditable
= m_editable
;
862 if ( !formerEditable
)
865 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2 ,
866 kTXNStartOffset
, kTXNEndOffset
);
868 wxCharBuffer text
= wxMacStringToCString( st
) ;
869 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)text
.data(), strlen( text
) ,
870 kTXNStartOffset
, kTXNEndOffset
);
872 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
873 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
874 if ( !formerEditable
)
875 SetEditable(formerEditable
) ;
880 void wxTextCtrl::SetMaxLength(unsigned long len
)
885 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
889 bool formerEditable
= m_editable
;
890 if ( !formerEditable
)
892 TXNTypeAttributes typeAttr
[4] ;
893 Str255 fontName
= "\pMonaco" ;
894 SInt16 fontSize
= 12 ;
895 Style fontStyle
= normal
;
897 int attrCounter
= 0 ;
898 if ( style
.HasFont() )
900 const wxFont
&font
= style
.GetFont() ;
901 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
902 fontSize
= font
.GetPointSize() ;
903 if ( font
.GetUnderlined() )
904 fontStyle
|= underline
;
905 if ( font
.GetWeight() == wxBOLD
)
907 if ( font
.GetStyle() == wxITALIC
)
908 fontStyle
|= italic
;
910 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
911 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
912 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
913 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
914 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
915 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
916 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
917 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
918 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
922 if ( style
.HasTextColour() )
924 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
925 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
926 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
927 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
931 if ( attrCounter
> 0 )
935 #endif // __WXDEBUG__
936 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
);
937 wxASSERT_MSG( status
== noErr
, wxT("Couldn't set text attributes") ) ;
939 if ( !formerEditable
)
940 SetEditable(formerEditable
) ;
945 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
947 wxTextCtrlBase::SetDefaultStyle( style
) ;
948 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
952 // Clipboard operations
953 void wxTextCtrl::Copy()
959 TECopy( ((TEHandle
) m_macTE
) ) ;
967 TXNCopy((TXNObject
)m_macTXN
);
968 TXNConvertToPublicScrap();
973 void wxTextCtrl::Cut()
979 TECut( ((TEHandle
) m_macTE
) ) ;
987 TXNCut((TXNObject
)m_macTXN
);
988 TXNConvertToPublicScrap();
990 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
991 event
.SetString( GetValue() ) ;
992 event
.SetEventObject( this );
993 GetEventHandler()->ProcessEvent(event
);
997 void wxTextCtrl::Paste()
1001 if ( !m_macUsesTXN
)
1004 TEPaste( (TEHandle
) m_macTE
) ;
1005 MacRedrawControl() ;
1009 TXNConvertFromPublicScrap();
1010 TXNPaste((TXNObject
)m_macTXN
);
1011 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1013 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1014 event
.SetString( GetValue() ) ;
1015 event
.SetEventObject( this );
1016 GetEventHandler()->ProcessEvent(event
);
1020 bool wxTextCtrl::CanCopy() const
1022 // Can copy if there's a selection
1024 GetSelection(& from
, & to
);
1025 return (from
!= to
);
1028 bool wxTextCtrl::CanCut() const
1030 if ( !IsEditable() )
1034 // Can cut if there's a selection
1036 GetSelection(& from
, & to
);
1037 return (from
!= to
);
1040 bool wxTextCtrl::CanPaste() const
1046 OSStatus err
= noErr
;
1049 err
= GetCurrentScrap( &scrapRef
);
1050 if ( err
!= noTypeErr
&& err
!= memFullErr
)
1052 ScrapFlavorFlags flavorFlags
;
1055 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
1057 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
1067 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
1075 void wxTextCtrl::SetEditable(bool editable
)
1077 if ( editable
!= m_editable
)
1079 m_editable
= editable
;
1080 if ( !m_macUsesTXN
)
1083 UMAActivateControl( (ControlHandle
) m_macControl
) ;
1085 UMADeactivateControl((ControlHandle
) m_macControl
) ;
1089 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1090 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1091 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1096 void wxTextCtrl::SetInsertionPoint(long pos
)
1098 SetSelection( pos
, pos
) ;
1101 void wxTextCtrl::SetInsertionPointEnd()
1103 long pos
= GetLastPosition();
1104 SetInsertionPoint(pos
);
1107 long wxTextCtrl::GetInsertionPoint() const
1110 GetSelection( &begin
, &end
) ;
1114 long wxTextCtrl::GetLastPosition() const
1116 if ( !m_macUsesTXN
)
1118 return (**((TEHandle
) m_macTE
)).teLength
;
1124 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1132 actualsize
= GetHandleSize( theText
) ;
1133 DisposeHandle( theText
) ;
1139 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
1141 if ( !m_macUsesTXN
)
1143 ControlEditTextSelectionRec selection
;
1145 selection
.selStart
= from
;
1146 selection
.selEnd
= to
;
1147 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1148 TESetSelect( from
, to
, ((TEHandle
) m_macTE
) ) ;
1149 TEDelete( ((TEHandle
) m_macTE
) ) ;
1150 TEInsert( value
, value
.Length() , ((TEHandle
) m_macTE
) ) ;
1154 bool formerEditable
= m_editable
;
1155 if ( !formerEditable
)
1157 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1158 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1160 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)value
.wc_str(), value
.Length() * 2 ,
1161 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1163 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)value
.c_str(), value
.Length(),
1164 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1166 if ( !formerEditable
)
1167 SetEditable( formerEditable
) ;
1172 void wxTextCtrl::Remove(long from
, long to
)
1174 if ( !m_macUsesTXN
)
1176 ControlEditTextSelectionRec selection
;
1178 selection
.selStart
= from
;
1179 selection
.selEnd
= to
;
1180 ::SetControlData( (ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1181 TEDelete( ((TEHandle
) m_macTE
) ) ;
1185 bool formerEditable
= m_editable
;
1186 if ( !formerEditable
)
1188 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1189 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1190 if ( !formerEditable
)
1191 SetEditable( formerEditable
) ;
1196 void wxTextCtrl::SetSelection(long from
, long to
)
1202 to
= GetLastPosition();
1204 if ( !m_macUsesTXN
)
1206 ControlEditTextSelectionRec selection
;
1207 selection
.selStart
= from
;
1208 selection
.selEnd
= to
;
1210 TESetSelect( selection
.selStart
, selection
.selEnd
, ((TEHandle
) m_macTE
) ) ;
1211 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1215 STPTextPaneVars
**tpvars
;
1216 /* set up our locals */
1217 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
1218 /* and our drawing environment as the operation
1219 may force a redraw in the text area. */
1220 SetPort((**tpvars
).fDrawingEnvironment
);
1221 /* change the selection */
1222 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
1223 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1227 bool wxTextCtrl::LoadFile(const wxString
& file
)
1229 if ( wxTextCtrlBase::LoadFile(file
) )
1237 void wxTextCtrl::WriteText(const wxString
& st
)
1239 if ( !m_macUsesTXN
)
1241 wxCharBuffer text
= wxMacStringToCString( st
) ;
1242 TEInsert( text
, strlen(text
) , ((TEHandle
) m_macTE
) ) ;
1246 bool formerEditable
= m_editable
;
1247 if ( !formerEditable
)
1249 long start
, end
, dummy
;
1250 GetSelection( &start
, &dummy
) ;
1252 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2 ,
1253 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1255 wxCharBuffer text
= wxMacStringToCString( st
) ;
1256 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)text
.data(), strlen( text
) ,
1257 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1259 GetSelection( &dummy
, &end
) ;
1260 SetStyle( start
, end
, GetDefaultStyle() ) ;
1261 if ( !formerEditable
)
1262 SetEditable( formerEditable
) ;
1264 MacRedrawControl() ;
1267 void wxTextCtrl::AppendText(const wxString
& text
)
1269 SetInsertionPointEnd();
1273 void wxTextCtrl::Clear()
1275 if ( !IsEditable() )
1279 if ( !m_macUsesTXN
)
1281 ::SetControlData((ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
1285 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1286 TXNClear((TXNObject
)m_macTXN
);
1291 bool wxTextCtrl::IsModified() const
1296 bool wxTextCtrl::IsEditable() const
1298 return IsEnabled() && m_editable
;
1301 bool wxTextCtrl::AcceptsFocus() const
1303 // we don't want focus if we can't be edited
1304 return /*IsEditable() && */ wxControl::AcceptsFocus();
1307 wxSize
wxTextCtrl::DoGetBestSize() const
1322 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
1324 int wText = DEFAULT_ITEM_WIDTH;
1326 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
1328 return wxSize(wText, hText);
1330 if ( m_windowStyle
& wxTE_MULTILINE
)
1334 hText
+= 2 * m_macVerticalBorder
;
1335 wText
+= 2 * m_macHorizontalBorder
;
1336 //else: for single line control everything is ok
1337 return wxSize(wText
, hText
);
1340 // ----------------------------------------------------------------------------
1342 // ----------------------------------------------------------------------------
1344 void wxTextCtrl::Undo()
1350 TXNUndo((TXNObject
)m_macTXN
);
1355 void wxTextCtrl::Redo()
1361 TXNRedo((TXNObject
)m_macTXN
);
1366 bool wxTextCtrl::CanUndo() const
1368 if ( !IsEditable() )
1374 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1379 bool wxTextCtrl::CanRedo() const
1381 if ( !IsEditable() )
1387 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1392 // Makes 'unmodified'
1393 void wxTextCtrl::DiscardEdits()
1398 int wxTextCtrl::GetNumberOfLines() const
1400 // TODO change this if possible to reflect real lines
1401 wxString content
= GetValue() ;
1404 for (size_t i
= 0; i
< content
.Length() ; i
++)
1406 if (content
[i
] == '\r') count
++;
1412 long wxTextCtrl::XYToPosition(long x
, long y
) const
1418 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1423 void wxTextCtrl::ShowPosition(long pos
)
1428 int wxTextCtrl::GetLineLength(long lineNo
) const
1430 // TODO change this if possible to reflect real lines
1431 wxString content
= GetValue() ;
1435 for (size_t i
= 0; i
< content
.Length() ; i
++)
1437 if (count
== lineNo
)
1439 // Count chars in line then
1441 for (size_t j
= i
; j
< content
.Length(); j
++)
1444 if (content
[j
] == '\r') return count
;
1449 if (content
[i
] == '\r') count
++;
1454 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1456 // TODO change this if possible to reflect real lines
1457 wxString content
= GetValue() ;
1461 for (size_t i
= 0; i
< content
.Length() ; i
++)
1463 if (count
== lineNo
)
1465 // Add chars in line then
1468 for (size_t j
= i
; j
< content
.Length(); j
++)
1470 if (content
[j
] == '\r')
1478 if (content
[i
] == '\r') count
++;
1480 return wxEmptyString
;
1487 void wxTextCtrl::Command(wxCommandEvent
& event
)
1489 SetValue (event
.GetString());
1490 ProcessCommand (event
);
1493 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1495 // By default, load the first file into the text window.
1496 if (event
.GetNumberOfFiles() > 0)
1498 LoadFile(event
.GetFiles()[0]);
1502 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1504 int key
= event
.GetKeyCode() ;
1505 bool eat_key
= false ;
1507 if ( key
== 'c' && event
.MetaDown() )
1514 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1515 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1516 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1522 if ( key
== 'v' && event
.MetaDown() )
1528 if ( key
== 'x' && event
.MetaDown() )
1537 if (m_windowStyle
& wxPROCESS_ENTER
)
1539 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1540 event
.SetEventObject( this );
1541 event
.SetString( GetValue() );
1542 if ( GetEventHandler()->ProcessEvent(event
) )
1545 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1547 wxWindow
*parent
= GetParent();
1548 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1549 parent
= parent
->GetParent() ;
1551 if ( parent
&& parent
->GetDefaultItem() )
1553 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1555 if ( def
&& def
->IsEnabled() )
1557 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1558 event
.SetEventObject(def
);
1559 def
->Command(event
);
1564 // this will make wxWindows eat the ENTER key so that
1565 // we actually prevent line wrapping in a single line
1573 // always produce navigation event - even if we process TAB
1574 // ourselves the fact that we got here means that the user code
1575 // decided to skip processing of this TAB - probably to let it
1576 // do its default job.
1578 wxNavigationKeyEvent eventNav
;
1579 eventNav
.SetDirection(!event
.ShiftDown());
1580 eventNav
.SetWindowChange(event
.ControlDown());
1581 eventNav
.SetEventObject(this);
1583 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1597 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1598 key
== WXK_RETURN
||
1599 key
== WXK_DELETE
||
1602 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1603 event1
.SetString( GetValue() ) ;
1604 event1
.SetEventObject( this );
1605 wxPostEvent(GetEventHandler(),event1
);
1609 void wxTextCtrl::MacSuperShown( bool show
)
1611 bool former
= m_macControlIsShown
;
1612 wxControl::MacSuperShown( show
) ;
1613 if ( (former
!= m_macControlIsShown
) && m_macUsesTXN
)
1615 if ( m_macControlIsShown
)
1616 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1617 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1619 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1620 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1624 bool wxTextCtrl::Show(bool show
)
1626 bool former
= m_macControlIsShown
;
1628 bool retval
= wxControl::Show( show
) ;
1630 if ( former
!= m_macControlIsShown
&& m_macUsesTXN
)
1632 if ( m_macControlIsShown
)
1633 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1634 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1636 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1637 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1643 // ----------------------------------------------------------------------------
1644 // standard handlers for standard edit menu events
1645 // ----------------------------------------------------------------------------
1647 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1652 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1657 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1662 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1667 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1672 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1674 event
.Enable( CanCut() );
1677 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1679 event
.Enable( CanCopy() );
1682 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1684 event
.Enable( CanPaste() );
1687 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1689 event
.Enable( CanUndo() );
1692 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1694 event
.Enable( CanRedo() );
1697 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1702 return wxWindow::MacSetupCursor( pt
) ;