1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/classic/textctrl.cpp
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
17 #include <sys/types.h>
23 #include "wx/msgdlg.h"
25 #if wxUSE_STD_IOSTREAM
35 #include "wx/button.h"
36 #include "wx/toplevel.h"
37 #include "wx/textctrl.h"
38 #include "wx/notebook.h"
39 #include "wx/tabctrl.h"
40 #include "wx/settings.h"
41 #include "wx/filefn.h"
44 #if defined(__BORLANDC__) && !defined(__WIN32__)
46 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
53 #include <MacTextEditor.h>
54 #include <ATSUnicode.h>
55 #include <TextCommon.h>
56 #include <TextEncodingConverter.h>
57 #include "wx/mac/uma.h"
59 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
61 extern wxControl
*wxFindControlFromMacControl(ControlHandle inControl
) ;
63 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
64 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
65 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
66 // an alternate path for carbon key events that routes automatically into the same wx flow of events
70 /* kmUPTextPart is the part code we return to indicate the user has clicked
71 in the text area of our control */
72 #define kmUPTextPart 1
74 /* kmUPScrollPart is the part code we return to indicate the user has clicked
75 in the scroll bar part of the control. */
76 #define kmUPScrollPart 2
79 /* routines for using existing user pane controls.
80 These routines are useful for cases where you would like to use an
81 existing user pane control in, say, a dialog window as a scrolling
84 /* mUPOpenControl initializes a user pane control so it will be drawn
85 and will behave as a scrolling text edit field inside of a window.
86 This routine performs all of the initialization steps necessary,
87 except it does not create the user pane control itself. theControl
88 should refer to a user pane control that you have either created
89 yourself or extracted from a dialog's control heirarchy using
90 the GetDialogItemAsControl routine. */
91 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
);
93 /* Utility Routines */
99 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
100 routine. In our focus switching routine this part code is understood
101 as meaning 'the user has clicked in the control and we need to switch
102 the current focus to ourselves before we can continue'. */
103 #define kUserClickedToFocusPart 100
106 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
107 slow the speed of 'auto scrolling' inside of our clickloop routine.
108 This value prevents the text from wizzzzzing by while the mouse
109 is being held down inside of the text area. */
110 #define kmUPClickScrollDelayTicks 3
113 /* STPTextPaneVars is a structure used for storing the the mUP Control's
114 internal variables and state information. A handle to this record is
115 stored in the pane control's reference value field using the
116 SetControlReference routine. */
119 /* OS records referenced */
120 TXNObject fTXNRec
; /* the txn record */
121 TXNFrameID fTXNFrame
; /* the txn frame ID */
122 ControlHandle fUserPaneRec
; /* handle to the user pane control */
123 WindowPtr fOwner
; /* window containing control */
124 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
126 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
127 Boolean fIsActive
; /* true while the control is drawn in the active state */
128 Boolean fTEActive
; /* reflects the activation state of the text edit record */
129 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
130 /* calculated locations */
131 Rect fRTextArea
; /* area where the text is drawn */
132 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
133 Rect fRTextOutline
; /* rectangle used to draw the border */
134 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
135 /* our focus advance override routine */
136 EventHandlerUPP handlerUPP
;
137 EventHandlerRef handlerRef
;
144 /* Univerals Procedure Pointer variables used by the
145 mUP Control. These variables are set up
146 the first time that mUPOpenControl is called. */
147 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
148 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
149 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
150 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
151 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
152 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
153 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
155 /* TPActivatePaneText activates or deactivates the text edit record
156 according to the value of setActive. The primary purpose of this
157 routine is to ensure each call is only made once. */
158 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
159 STPTextPaneVars
*varsp
;
161 if (varsp
->fTEActive
!= setActive
) {
163 varsp
->fTEActive
= setActive
;
165 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
168 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
173 /* TPFocusPaneText set the focus state for the text record. */
174 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
175 STPTextPaneVars
*varsp
;
177 if (varsp
->fInFocus
!= setFocus
) {
178 varsp
->fInFocus
= setFocus
;
179 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
184 /* TPPaneDrawProc is called to redraw the control and for update events
185 referring to the control. This routine erases the text area's background,
186 and redraws the text. This routine assumes the scroll bar has been
187 redrawn by a call to DrawControls. */
188 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
189 STPTextPaneVars
**tpvars
, *varsp
;
192 /* set up our globals */
194 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
195 if (tpvars
!= NULL
) {
196 state
= HGetState((Handle
) tpvars
);
197 HLock((Handle
) tpvars
);
200 /* save the drawing state */
201 SetPort((**tpvars
).fDrawingEnvironment
);
202 /* verify our boundary */
203 GetControlBounds(theControl
, &bounds
);
205 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
206 if ( ! EqualRect(&bounds
, &varsp
->fRFocusOutline
) ) {
207 // scrollbar is on the border, we add one
208 Rect oldbounds
= varsp
->fRFocusOutline
;
209 InsetRect( &oldbounds
, -1 , -1 ) ;
211 if ( IsControlVisible( theControl
) )
212 InvalWindowRect( GetControlOwner( theControl
) , &oldbounds
) ;
213 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
214 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
215 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
216 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
217 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
218 if ( IsControlVisible( theControl
) )
219 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
220 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
222 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
223 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
227 if ( IsControlVisible( theControl
) )
229 /* update the text region */
230 RGBColor white
= { 65535 , 65535 , 65535 } ;
231 RGBBackColor( &white
) ;
232 EraseRgn(varsp
->fTextBackgroundRgn
);
233 TXNDraw(varsp
->fTXNRec
, NULL
);
234 /* restore the drawing environment */
235 /* draw the text frame and focus frame (if necessary) */
236 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
237 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
)
238 DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
239 /* release our globals */
240 HSetState((Handle
) tpvars
, state
);
246 /* TPPaneHitTestProc is called when the control manager would
247 like to determine what part of the control the mouse resides over.
248 We also call this routine from our tracking proc to determine how
249 to handle mouse clicks. */
250 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
251 STPTextPaneVars
**tpvars
;
252 ControlPartCode result
;
254 /* set up our locals and lock down our globals*/
256 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
257 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
258 state
= HGetState((Handle
) tpvars
);
259 HLock((Handle
) tpvars
);
260 /* find the region where we clicked */
261 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
262 result
= kmUPTextPart
;
264 /* release oure globals */
265 HSetState((Handle
) tpvars
, state
);
274 /* TPPaneTrackingProc is called when the mouse is being held down
275 over our control. This routine handles clicks in the text area
276 and in the scroll bar. */
277 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
278 STPTextPaneVars
**tpvars
, *varsp
;
280 ControlPartCode partCodeResult
;
281 /* make sure we have some variables... */
283 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
284 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
286 state
= HGetState((Handle
) tpvars
);
287 HLock((Handle
) tpvars
);
289 /* we don't do any of these functions unless we're in focus */
290 if ( ! varsp
->fInFocus
) {
292 owner
= GetControlOwner(theControl
);
293 ClearKeyboardFocus(owner
);
294 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
296 /* find the location for the click */
297 switch (TPPaneHitTestProc(theControl
, startPt
)) {
299 /* handle clicks in the text part */
301 { SetPort((**tpvars
).fDrawingEnvironment
);
302 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
304 TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent());
307 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
308 TXNClick( varsp
->fTXNRec
, &rec
);
315 HSetState((Handle
) tpvars
, state
);
317 return partCodeResult
;
321 /* TPPaneIdleProc is our user pane idle routine. When our text field
322 is active and in focus, we use this routine to set the cursor. */
323 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
324 STPTextPaneVars
**tpvars
, *varsp
;
326 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
327 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
328 /* if we're not active, then we have nothing to say about the cursor */
329 if ((**tpvars
).fIsActive
) {
333 /* lock down the globals */
334 state
= HGetState((Handle
) tpvars
);
335 HLock((Handle
) tpvars
);
337 /* get the current mouse coordinates (in our window) */
338 SetPortWindowPort(GetControlOwner(theControl
));
339 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
341 /* there's a 'focus thing' and an 'unfocused thing' */
342 if (varsp
->fInFocus
) {
343 /* flash the cursor */
344 SetPort((**tpvars
).fDrawingEnvironment
);
345 TXNIdle(varsp
->fTXNRec
);
347 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
349 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
350 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
355 // SetThemeCursor(kThemeArrowCursor);
358 /* if it's in our bounds, set the cursor */
359 GetControlBounds(theControl
, &bounds
);
360 if (PtInRect(mousep
, &bounds
))
362 // SetThemeCursor(kThemeArrowCursor);
366 HSetState((Handle
) tpvars
, state
);
372 /* TPPaneKeyDownProc is called whenever a keydown event is directed
373 at our control. Here, we direct the keydown event to the text
374 edit record and redraw the scroll bar and text field as appropriate. */
375 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
376 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
377 STPTextPaneVars
**tpvars
;
378 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
379 if (tpvars
!= NULL
) {
380 if ((**tpvars
).fInFocus
) {
381 /* turn autoscrolling on and send the key event to text edit */
382 SetPort((**tpvars
).fDrawingEnvironment
);
383 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
385 memset( &ev
, 0 , sizeof( ev
) ) ;
387 ev
.modifiers
= modifiers
;
388 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
389 TXNKeyDown( (**tpvars
).fTXNRec
, &ev
);
392 return kControlEntireControl
;
396 /* TPPaneActivateProc is called when the window containing
397 the user pane control receives activate events. Here, we redraw
398 the control and it's text as necessary for the activation state. */
399 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
401 STPTextPaneVars
**tpvars
, *varsp
;
404 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
405 if (tpvars
!= NULL
) {
406 state
= HGetState((Handle
) tpvars
);
407 HLock((Handle
) tpvars
);
409 /* de/activate the text edit record */
410 SetPort((**tpvars
).fDrawingEnvironment
);
411 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
412 GetControlBounds(theControl
, &bounds
);
413 varsp
->fIsActive
= activating
;
414 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
415 /* redraw the frame */
416 if ( IsControlVisible( theControl
) )
418 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
420 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
422 HSetState((Handle
) tpvars
, state
);
427 /* TPPaneFocusProc is called when every the focus changes to or
428 from our control. Herein, switch the focus appropriately
429 according to the parameters and redraw the control as
431 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
432 ControlPartCode focusResult
;
433 STPTextPaneVars
**tpvars
, *varsp
;
436 focusResult
= kControlFocusNoPart
;
437 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
438 if (tpvars
!= NULL
) {
439 state
= HGetState((Handle
) tpvars
);
440 HLock((Handle
) tpvars
);
442 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
443 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
444 and kControlFocusNextPart will be received. When the user clicks in our field
445 and it is not the current focus, then the constant kUserClickedToFocusPart will
446 be received. The constant kControlFocusNoPart will be received when our control
447 is the current focus and the user clicks in another control. In your focus routine,
448 you should respond to these codes as follows:
450 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
451 the control and the focus rectangle as necessary.
453 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
454 depending on its current state. redraw the control and the focus rectangle
455 as appropriate for the new focus state. If the focus state is 'off', return the constant
456 kControlFocusNoPart, otherwise return a non-zero part code.
457 kUserClickedToFocusPart - is a constant defined for this example. You should
458 define your own value for handling click-to-focus type events. */
459 /* calculate the next highlight state */
462 case kControlFocusNoPart
:
463 TPFocusPaneText(tpvars
, false);
464 focusResult
= kControlFocusNoPart
;
466 case kUserClickedToFocusPart
:
467 TPFocusPaneText(tpvars
, true);
470 case kControlFocusPrevPart
:
471 case kControlFocusNextPart
:
472 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
473 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
476 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
477 /* redraw the text fram and focus rectangle to indicate the
479 if ( IsControlVisible( theControl
) )
481 /* save the drawing state */
482 SetPort((**tpvars
).fDrawingEnvironment
);
483 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
484 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
485 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
488 HSetState((Handle
) tpvars
, state
);
494 /* mUPOpenControl initializes a user pane control so it will be drawn
495 and will behave as a scrolling text edit field inside of a window.
496 This routine performs all of the initialization steps necessary,
497 except it does not create the user pane control itself. theControl
498 should refer to a user pane control that you have either created
499 yourself or extracted from a dialog's control heirarchy using
500 the GetDialogItemAsControl routine. */
501 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
)
505 STPTextPaneVars
**tpvars
, *varsp
;
506 OSStatus err
= noErr
;
507 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
510 /* set up our globals */
511 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
512 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
513 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
514 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
515 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
516 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
517 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
519 /* allocate our private storage */
520 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
521 SetControlReference(theControl
, (long) tpvars
);
522 HLock((Handle
) tpvars
);
524 /* set the initial settings for our private data */
525 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
526 varsp
->fInFocus
= false;
527 varsp
->fIsActive
= true;
528 varsp
->fTEActive
= true; // in order to get a deactivate
529 varsp
->fUserPaneRec
= theControl
;
530 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
532 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
534 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
535 /* set up the user pane procedures */
536 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
537 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
538 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
539 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
540 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
541 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
542 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
543 /* calculate the rectangles used by the control */
544 GetControlBounds(theControl
, &bounds
);
545 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
546 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
547 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
548 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
549 /* calculate the background region for the text. In this case, it's kindof
550 and irregular region because we're setting the scroll bar a little ways inside
552 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
554 /* set up the drawing environment */
555 SetPort(varsp
->fDrawingEnvironment
);
557 /* create the new edit field */
559 TXNFrameOptions frameOptions
=
560 kTXNDontDrawCaretWhenInactiveMask
;
561 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
562 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
564 if ( wxStyle
& wxTE_MULTILINE
)
566 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
567 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
570 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
571 frameOptions
|= kTXNWantHScrollBarMask
;
574 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
575 frameOptions
|= kTXNWantVScrollBarMask
;
578 frameOptions
|= kTXNSingleLineOnlyMask
;
580 if ( wxStyle
& wxTE_READONLY
)
581 frameOptions
|= kTXNReadOnlyMask
;
583 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
585 kTXNTextEditStyleFrameType
,
587 kTXNSystemDefaultEncoding
,
588 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
590 if ( !IsControlVisible( theControl
) )
591 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
592 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
595 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
597 TXNControlTag tag
= kTXNWordWrapStateTag
;
599 dat
.uValue
= kTXNNoAutoWrap
;
600 TXNSetTXNObjectControls( varsp
->fTXNRec
, false , 1 , &tag
, &dat
) ;
606 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
608 TXNTypeAttributes typeAttr
[] =
610 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
611 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
612 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
615 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
618 /* set the field's background */
620 tback
.bgType
= kTXNBackgroundTypeRGB
;
621 tback
.bg
.color
= rgbWhite
;
622 TXNSetBackground( varsp
->fTXNRec
, &tback
);
624 /* unlock our storage */
625 HUnlock((Handle
) tpvars
);
626 /* perform final activations and setup for our text field. Here,
627 we assume that the window is going to be the 'active' window. */
628 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
636 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
638 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
639 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
640 EVT_CHAR(wxTextCtrl::OnChar
)
641 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
642 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
643 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
644 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
645 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
647 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
648 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
649 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
650 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
651 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
654 static void SetTXNData( TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
657 #if SIZEOF_WCHAR_T == 2
658 size_t len
= st
.Len() ;
659 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
662 wxMBConvUTF16BE converter
;
663 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
664 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
665 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
666 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
671 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
672 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
678 void wxTextCtrl::Init()
682 m_macTXNvars
= NULL
;
683 m_macUsesTXN
= false ;
688 m_maxLength
= TE_UNLIMITED_LENGTH
;
691 wxTextCtrl::~wxTextCtrl()
695 SetControlReference((ControlHandle
)m_macControl
, 0) ;
696 TXNDeleteObject((TXNObject
)m_macTXN
);
697 /* delete our private storage */
698 DisposeHandle((Handle
) m_macTXNvars
);
699 /* zero the control reference */
703 const short kVerticalMargin
= 2 ;
704 const short kHorizontalMargin
= 2 ;
706 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
709 const wxSize
& size
, long style
,
710 const wxValidator
& validator
,
711 const wxString
& name
)
715 m_macTXNvars
= NULL
;
716 m_macUsesTXN
= false ;
719 m_macUsesTXN
= ! (style
& wxTE_PASSWORD
) ;
721 m_macUsesTXN
&= (TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
) ;
723 // base initialization
724 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
727 wxSize mySize
= size
;
730 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
731 m_macVerticalBorder
= 3 ;
735 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
736 m_macVerticalBorder
= 5 ;
743 if ( mySize.y == -1 )
746 if ( m_windowStyle & wxTE_MULTILINE )
749 mySize.y += 2 * m_macVerticalBorder ;
752 MacPreControlCreate( parent
, id
, wxEmptyString
, pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
754 if ( m_windowStyle
& wxTE_MULTILINE
)
756 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
757 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
759 m_windowStyle
|= wxTE_PROCESS_ENTER
;
762 if ( m_windowStyle
& wxTE_READONLY
)
768 wxMacConvertNewlines13To10( &st
) ;
771 m_macControl
= (WXWidget
) ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds
, "\p" , false , 0 , 0 , 1,
772 (style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
774 ::GetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*)((TEHandle
*)&m_macTE
) , &size
) ;
781 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
782 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
783 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
784 /* create the control */
785 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
786 /* set up the mUP specific features and data */
787 mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle
);
789 MacPostControlCreate() ;
793 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
794 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
798 STPTextPaneVars
**tpvars
;
800 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
801 /* set the text in the record */
802 m_macTXN
= (**tpvars
).fTXNRec
;
803 SetTXNData( (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
804 m_macTXNvars
= tpvars
;
805 m_macUsesTXN
= true ;
806 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
807 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
813 wxString
wxTextCtrl::GetValue() const
820 err
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0,
821 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, &actualSize
) ;
824 return wxEmptyString
;
826 if ( actualSize
> 0 )
828 wxCharBuffer
buf(actualSize
) ;
829 ::GetControlData( (ControlHandle
) m_macControl
, 0,
830 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
,
831 actualSize
, buf
.data() , &actualSize
) ;
832 result
= wxString( buf
, wxConvLocal
) ;
839 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
847 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
848 if ( actualSize
> 0 )
850 wxChar
*ptr
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ;
851 #if SIZEOF_WCHAR_T == 2
852 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
854 wxMBConvUTF16BE converter
;
856 converter
.MB2WC( ptr
, (const char*)*theText
, actualSize
) ;
859 ptr
[actualSize
] = 0 ;
860 result
.UngetWriteBuf( actualSize
*sizeof(wxChar
) ) ;
862 DisposeHandle( theText
) ;
866 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
874 actualSize
= GetHandleSize( theText
) ;
875 if ( actualSize
> 0 )
878 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
881 DisposeHandle( theText
) ;
885 wxMacConvertNewlines10To13( &result
) ;
889 void wxTextCtrl::GetSelection(long* from
, long* to
) const
893 *from
= (**((TEHandle
) m_macTE
)).selStart
;
894 *to
= (**((TEHandle
) m_macTE
)).selEnd
;
898 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
902 void wxTextCtrl::SetValue(const wxString
& str
)
905 wxMacConvertNewlines13To10( &st
) ;
908 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
909 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
913 bool formerEditable
= m_editable
;
914 if ( !formerEditable
)
916 SetTXNData( (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
917 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
918 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
919 if ( !formerEditable
)
920 SetEditable(formerEditable
) ;
925 void wxTextCtrl::SetMaxLength(unsigned long len
)
930 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
934 bool formerEditable
= m_editable
;
935 if ( !formerEditable
)
937 TXNTypeAttributes typeAttr
[4] ;
938 Str255 fontName
= "\pMonaco" ;
939 SInt16 fontSize
= 12 ;
940 Style fontStyle
= normal
;
942 int attrCounter
= 0 ;
943 if ( style
.HasFont() )
945 const wxFont
&font
= style
.GetFont() ;
946 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
947 fontSize
= font
.GetPointSize() ;
948 if ( font
.GetUnderlined() )
949 fontStyle
|= underline
;
950 if ( font
.GetWeight() == wxBOLD
)
952 if ( font
.GetStyle() == wxITALIC
)
953 fontStyle
|= italic
;
955 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
956 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
957 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
958 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
959 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
960 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
961 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
962 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
963 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
967 if ( style
.HasTextColour() )
969 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
970 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
971 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
972 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
976 if ( attrCounter
> 0 )
980 #endif // __WXDEBUG__
981 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
);
982 wxASSERT_MSG( status
== noErr
, wxT("Couldn't set text attributes") ) ;
984 if ( !formerEditable
)
985 SetEditable(formerEditable
) ;
990 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
992 wxTextCtrlBase::SetDefaultStyle( style
) ;
993 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
997 // Clipboard operations
998 void wxTextCtrl::Copy()
1002 if ( !m_macUsesTXN
)
1004 TECopy( ((TEHandle
) m_macTE
) ) ;
1005 ClearCurrentScrap();
1007 MacRedrawControl() ;
1011 ClearCurrentScrap();
1012 TXNCopy((TXNObject
)m_macTXN
);
1013 TXNConvertToPublicScrap();
1018 void wxTextCtrl::Cut()
1022 if ( !m_macUsesTXN
)
1024 TECut( ((TEHandle
) m_macTE
) ) ;
1025 ClearCurrentScrap();
1027 MacRedrawControl() ;
1031 ClearCurrentScrap();
1032 TXNCut((TXNObject
)m_macTXN
);
1033 TXNConvertToPublicScrap();
1035 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1036 event
.SetEventObject( this );
1037 GetEventHandler()->ProcessEvent(event
);
1041 void wxTextCtrl::Paste()
1045 if ( !m_macUsesTXN
)
1048 TEPaste( (TEHandle
) m_macTE
) ;
1049 MacRedrawControl() ;
1053 TXNConvertFromPublicScrap();
1054 TXNPaste((TXNObject
)m_macTXN
);
1055 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1057 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1058 event
.SetEventObject( this );
1059 GetEventHandler()->ProcessEvent(event
);
1063 bool wxTextCtrl::CanCopy() const
1065 // Can copy if there's a selection
1067 GetSelection(& from
, & to
);
1068 return (from
!= to
);
1071 bool wxTextCtrl::CanCut() const
1073 if ( !IsEditable() )
1077 // Can cut if there's a selection
1079 GetSelection(& from
, & to
);
1080 return (from
!= to
);
1083 bool wxTextCtrl::CanPaste() const
1089 OSStatus err
= noErr
;
1092 err
= GetCurrentScrap( &scrapRef
);
1093 if ( err
!= noTypeErr
&& err
!= memFullErr
)
1095 ScrapFlavorFlags flavorFlags
;
1098 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
1100 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
1110 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
1118 void wxTextCtrl::SetEditable(bool editable
)
1120 if ( editable
!= m_editable
)
1122 m_editable
= editable
;
1123 if ( !m_macUsesTXN
)
1126 UMAActivateControl( (ControlHandle
) m_macControl
) ;
1128 UMADeactivateControl((ControlHandle
) m_macControl
) ;
1132 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1133 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1134 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1139 void wxTextCtrl::SetInsertionPoint(long pos
)
1141 SetSelection( pos
, pos
) ;
1144 void wxTextCtrl::SetInsertionPointEnd()
1146 wxTextPos pos
= GetLastPosition();
1147 SetInsertionPoint(pos
);
1150 long wxTextCtrl::GetInsertionPoint() const
1153 GetSelection( &begin
, &end
) ;
1157 wxTextPos
wxTextCtrl::GetLastPosition() const
1159 if ( !m_macUsesTXN
)
1161 return (**((TEHandle
) m_macTE
)).teLength
;
1167 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1175 actualsize
= GetHandleSize( theText
) ;
1176 DisposeHandle( theText
) ;
1182 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1184 wxString value
= str
;
1185 wxMacConvertNewlines13To10( &value
) ;
1186 if ( !m_macUsesTXN
)
1188 ControlEditTextSelectionRec selection
;
1190 selection
.selStart
= from
;
1191 selection
.selEnd
= to
;
1192 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1193 TESetSelect( from
, to
, ((TEHandle
) m_macTE
) ) ;
1194 TEDelete( ((TEHandle
) m_macTE
) ) ;
1195 TEInsert( value
, value
.length() , ((TEHandle
) m_macTE
) ) ;
1199 bool formerEditable
= m_editable
;
1200 if ( !formerEditable
)
1202 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1203 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1204 SetTXNData( (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1205 if ( !formerEditable
)
1206 SetEditable( formerEditable
) ;
1211 void wxTextCtrl::Remove(long from
, long to
)
1213 if ( !m_macUsesTXN
)
1215 ControlEditTextSelectionRec selection
;
1217 selection
.selStart
= from
;
1218 selection
.selEnd
= to
;
1219 ::SetControlData( (ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1220 TEDelete( ((TEHandle
) m_macTE
) ) ;
1224 bool formerEditable
= m_editable
;
1225 if ( !formerEditable
)
1227 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1228 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1229 if ( !formerEditable
)
1230 SetEditable( formerEditable
) ;
1235 void wxTextCtrl::SetSelection(long from
, long to
)
1237 if ( !m_macUsesTXN
)
1239 ControlEditTextSelectionRec selection
;
1240 if ((from
== -1) && (to
== -1))
1242 selection
.selStart
= 0 ;
1243 selection
.selEnd
= 32767 ;
1247 selection
.selStart
= from
;
1248 selection
.selEnd
= to
;
1251 TESetSelect( selection
.selStart
, selection
.selEnd
, ((TEHandle
) m_macTE
) ) ;
1252 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1256 STPTextPaneVars
**tpvars
;
1257 /* set up our locals */
1258 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
1259 /* and our drawing environment as the operation
1260 may force a redraw in the text area. */
1261 SetPort((**tpvars
).fDrawingEnvironment
);
1262 /* change the selection */
1263 if ((from
== -1) && (to
== -1))
1264 TXNSelectAll((TXNObject
) m_macTXN
);
1266 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
1267 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1271 bool wxTextCtrl::LoadFile(const wxString
& file
)
1273 if ( wxTextCtrlBase::LoadFile(file
) )
1281 void wxTextCtrl::WriteText(const wxString
& str
)
1284 wxMacConvertNewlines13To10( &st
) ;
1285 if ( !m_macUsesTXN
)
1287 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1288 TEInsert( text
, strlen(text
) , ((TEHandle
) m_macTE
) ) ;
1292 bool formerEditable
= m_editable
;
1293 if ( !formerEditable
)
1295 long start
, end
, dummy
;
1296 GetSelection( &start
, &dummy
) ;
1297 SetTXNData( (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1298 GetSelection( &dummy
, &end
) ;
1299 SetStyle( start
, end
, GetDefaultStyle() ) ;
1300 if ( !formerEditable
)
1301 SetEditable( formerEditable
) ;
1303 MacRedrawControl() ;
1306 void wxTextCtrl::AppendText(const wxString
& text
)
1308 SetInsertionPointEnd();
1312 void wxTextCtrl::Clear()
1314 if ( !m_macUsesTXN
)
1316 ::SetControlData((ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
1320 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1321 TXNClear((TXNObject
)m_macTXN
);
1326 bool wxTextCtrl::IsModified() const
1331 bool wxTextCtrl::IsEditable() const
1333 return IsEnabled() && m_editable
;
1336 bool wxTextCtrl::AcceptsFocus() const
1338 // we don't want focus if we can't be edited
1339 return /*IsEditable() && */ wxControl::AcceptsFocus();
1342 wxSize
wxTextCtrl::DoGetBestSize() const
1357 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
1359 int wText = DEFAULT_ITEM_WIDTH;
1361 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
1363 return wxSize(wText, hText);
1365 if ( m_windowStyle
& wxTE_MULTILINE
)
1369 hText
+= 2 * m_macVerticalBorder
;
1370 wText
+= 2 * m_macHorizontalBorder
;
1371 //else: for single line control everything is ok
1372 return wxSize(wText
, hText
);
1375 // ----------------------------------------------------------------------------
1377 // ----------------------------------------------------------------------------
1379 void wxTextCtrl::Undo()
1385 TXNUndo((TXNObject
)m_macTXN
);
1390 void wxTextCtrl::Redo()
1396 TXNRedo((TXNObject
)m_macTXN
);
1401 bool wxTextCtrl::CanUndo() const
1403 if ( !IsEditable() )
1409 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1414 bool wxTextCtrl::CanRedo() const
1416 if ( !IsEditable() )
1422 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1427 // Makes modifie or unmodified
1428 void wxTextCtrl::MarkDirty()
1433 void wxTextCtrl::DiscardEdits()
1438 int wxTextCtrl::GetNumberOfLines() const
1443 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1448 wxString content
= GetValue() ;
1451 for (size_t i
= 0; i
< content
.length() ; i
++)
1453 if (content
[i
] == '\r') count
++;
1459 long wxTextCtrl::XYToPosition(long x
, long y
) const
1465 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1470 void wxTextCtrl::ShowPosition(long pos
)
1472 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1477 TXNOffset selstart
, selend
;
1478 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1479 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1480 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1481 //TODO use HIPoints for 10.3 and above
1482 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1484 OSErr theErr
= noErr
;
1485 SInt32 dv
= desired
.v
- current
.v
;
1486 SInt32 dh
= desired
.h
- current
.h
;
1487 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1488 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1489 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1495 int wxTextCtrl::GetLineLength(long lineNo
) const
1497 // TODO change this if possible to reflect real lines
1498 wxString content
= GetValue() ;
1502 for (size_t i
= 0; i
< content
.length() ; i
++)
1504 if (count
== lineNo
)
1506 // Count chars in line then
1508 for (size_t j
= i
; j
< content
.length(); j
++)
1511 if (content
[j
] == '\n') return count
;
1516 if (content
[i
] == '\n') count
++;
1521 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1523 // TODO change this if possible to reflect real lines
1524 wxString content
= GetValue() ;
1528 for (size_t i
= 0; i
< content
.length() ; i
++)
1530 if (count
== lineNo
)
1532 // Add chars in line then
1535 for (size_t j
= i
; j
< content
.length(); j
++)
1537 if (content
[j
] == '\n')
1545 if (content
[i
] == '\n') count
++;
1547 return wxEmptyString
;
1554 void wxTextCtrl::Command(wxCommandEvent
& event
)
1556 SetValue (event
.GetString());
1557 ProcessCommand (event
);
1560 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1562 // By default, load the first file into the text window.
1563 if (event
.GetNumberOfFiles() > 0)
1565 LoadFile(event
.GetFiles()[0]);
1569 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1571 int key
= event
.GetKeyCode() ;
1572 bool eat_key
= false ;
1574 if ( key
== 'c' && event
.MetaDown() )
1581 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1582 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxTE_PROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1583 /* && key != WXK_PAGEUP && key != WXK_PAGEDOWN && key != WXK_HOME && key != WXK_END */
1590 // assume that any key not processed yet is going to modify the control
1593 if ( key
== 'v' && event
.MetaDown() )
1599 if ( key
== 'x' && event
.MetaDown() )
1608 if (m_windowStyle
& wxTE_PROCESS_ENTER
)
1610 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1611 event
.SetEventObject( this );
1612 event
.SetString( GetValue() );
1613 if ( GetEventHandler()->ProcessEvent(event
) )
1616 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1618 wxWindow
*parent
= GetParent();
1619 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1620 parent
= parent
->GetParent() ;
1622 if ( parent
&& parent
->GetDefaultItem() )
1624 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1626 if ( def
&& def
->IsEnabled() )
1628 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1629 event
.SetEventObject(def
);
1630 def
->Command(event
);
1635 // this will make wxWidgets eat the ENTER key so that
1636 // we actually prevent line wrapping in a single line
1644 if ( !(m_windowStyle
& wxTE_PROCESS_TAB
))
1647 if (!event
.ShiftDown())
1648 flags
|= wxNavigationKeyEvent::IsForward
;
1649 if (event
.ControlDown())
1650 flags
|= wxNavigationKeyEvent::WinChange
;
1656 // This is necessary (don't know why) or the tab will not
1658 WriteText(wxT("\t"));
1665 // perform keystroke handling
1667 if ( m_macUsesTXN
&& wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1668 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1672 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1674 EventRecord
*ev
= &rec
;
1677 keychar
= short(ev
->message
& charCodeMask
);
1678 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1680 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1684 EventRecord
*ev
= (EventRecord
*) wxTheApp
->MacGetCurrentEvent() ;
1687 keychar
= short(ev
->message
& charCodeMask
);
1688 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1690 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1693 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1694 key
== WXK_RETURN
||
1695 key
== WXK_DELETE
||
1698 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1699 event1
.SetEventObject( this );
1700 wxPostEvent(GetEventHandler(),event1
);
1704 void wxTextCtrl::MacSuperShown( bool show
)
1706 bool former
= m_macControlIsShown
;
1707 wxControl::MacSuperShown( show
) ;
1708 if ( (former
!= m_macControlIsShown
) && m_macUsesTXN
)
1710 if ( m_macControlIsShown
)
1711 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1712 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1714 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1715 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1719 bool wxTextCtrl::Show(bool show
)
1721 bool former
= m_macControlIsShown
;
1723 bool retval
= wxControl::Show( show
) ;
1725 if ( former
!= m_macControlIsShown
&& m_macUsesTXN
)
1727 if ( m_macControlIsShown
)
1728 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1729 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1731 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1732 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1738 // ----------------------------------------------------------------------------
1739 // standard handlers for standard edit menu events
1740 // ----------------------------------------------------------------------------
1742 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1747 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1752 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1757 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1762 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1767 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1769 event
.Enable( CanCut() );
1772 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1774 event
.Enable( CanCopy() );
1777 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1779 event
.Enable( CanPaste() );
1782 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1784 event
.Enable( CanUndo() );
1787 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1789 event
.Enable( CanRedo() );
1792 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1797 return wxWindow::MacSetupCursor( pt
) ;