1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
21 #include <sys/types.h>
27 #include "wx/msgdlg.h"
29 #if wxUSE_STD_IOSTREAM
39 #include "wx/button.h"
40 #include "wx/toplevel.h"
41 #include "wx/textctrl.h"
42 #include "wx/notebook.h"
43 #include "wx/tabctrl.h"
44 #include "wx/settings.h"
45 #include "wx/filefn.h"
48 #if defined(__BORLANDC__) && !defined(__WIN32__)
50 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
57 #include <MacTextEditor.h>
58 #include "ATSUnicode.h"
59 #include "TextCommon.h"
60 #include "TextEncodingConverter.h"
61 #include "wx/mac/uma.h"
63 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
65 extern wxControl
*wxFindControlFromMacControl(ControlHandle inControl
) ;
67 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
68 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
69 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
70 // an alternate path for carbon key events that routes automatically into the same wx flow of events
72 #include "MacTextEditor.h"
76 /* kmUPTextPart is the part code we return to indicate the user has clicked
77 in the text area of our control */
78 #define kmUPTextPart 1
80 /* kmUPScrollPart is the part code we return to indicate the user has clicked
81 in the scroll bar part of the control. */
82 #define kmUPScrollPart 2
85 /* routines for using existing user pane controls.
86 These routines are useful for cases where you would like to use an
87 existing user pane control in, say, a dialog window as a scrolling
90 /* mUPOpenControl initializes a user pane control so it will be drawn
91 and will behave as a scrolling text edit field inside of a window.
92 This routine performs all of the initialization steps necessary,
93 except it does not create the user pane control itself. theControl
94 should refer to a user pane control that you have either created
95 yourself or extracted from a dialog's control heirarchy using
96 the GetDialogItemAsControl routine. */
97 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
);
99 /* Utility Routines */
105 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
106 routine. In our focus switching routine this part code is understood
107 as meaning 'the user has clicked in the control and we need to switch
108 the current focus to ourselves before we can continue'. */
109 #define kUserClickedToFocusPart 100
112 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
113 slow the speed of 'auto scrolling' inside of our clickloop routine.
114 This value prevents the text from wizzzzzing by while the mouse
115 is being held down inside of the text area. */
116 #define kmUPClickScrollDelayTicks 3
119 /* STPTextPaneVars is a structure used for storing the the mUP Control's
120 internal variables and state information. A handle to this record is
121 stored in the pane control's reference value field using the
122 SetControlReference routine. */
125 /* OS records referenced */
126 TXNObject fTXNRec
; /* the txn record */
127 TXNFrameID fTXNFrame
; /* the txn frame ID */
128 ControlHandle fUserPaneRec
; /* handle to the user pane control */
129 WindowPtr fOwner
; /* window containing control */
130 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
132 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
133 Boolean fIsActive
; /* true while the control is drawn in the active state */
134 Boolean fTEActive
; /* reflects the activation state of the text edit record */
135 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
136 /* calculated locations */
137 Rect fRTextArea
; /* area where the text is drawn */
138 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
139 Rect fRTextOutline
; /* rectangle used to draw the border */
140 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
141 /* our focus advance override routine */
142 EventHandlerUPP handlerUPP
;
143 EventHandlerRef handlerRef
;
150 /* Univerals Procedure Pointer variables used by the
151 mUP Control. These variables are set up
152 the first time that mUPOpenControl is called. */
153 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
154 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
155 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
156 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
157 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
158 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
159 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
161 /* TPActivatePaneText activates or deactivates the text edit record
162 according to the value of setActive. The primary purpose of this
163 routine is to ensure each call is only made once. */
164 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
165 STPTextPaneVars
*varsp
;
167 if (varsp
->fTEActive
!= setActive
) {
169 varsp
->fTEActive
= setActive
;
171 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
174 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
179 /* TPFocusPaneText set the focus state for the text record. */
180 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
181 STPTextPaneVars
*varsp
;
183 if (varsp
->fInFocus
!= setFocus
) {
184 varsp
->fInFocus
= setFocus
;
185 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
190 /* TPPaneDrawProc is called to redraw the control and for update events
191 referring to the control. This routine erases the text area's background,
192 and redraws the text. This routine assumes the scroll bar has been
193 redrawn by a call to DrawControls. */
194 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
195 STPTextPaneVars
**tpvars
, *varsp
;
198 /* set up our globals */
200 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
201 if (tpvars
!= NULL
) {
202 state
= HGetState((Handle
) tpvars
);
203 HLock((Handle
) tpvars
);
206 /* save the drawing state */
207 SetPort((**tpvars
).fDrawingEnvironment
);
208 /* verify our boundary */
209 GetControlBounds(theControl
, &bounds
);
211 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
212 if ( ! EqualRect(&bounds
, &varsp
->fRFocusOutline
) ) {
213 // scrollbar is on the border, we add one
214 Rect oldbounds
= varsp
->fRFocusOutline
;
215 InsetRect( &oldbounds
, -1 , -1 ) ;
217 if ( IsControlVisible( theControl
) )
218 InvalWindowRect( GetControlOwner( theControl
) , &oldbounds
) ;
219 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
220 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
221 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
222 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
223 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
224 if ( IsControlVisible( theControl
) )
225 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
226 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
228 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
229 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
233 if ( IsControlVisible( theControl
) )
235 /* update the text region */
236 RGBColor white
= { 65535 , 65535 , 65535 } ;
237 RGBBackColor( &white
) ;
238 EraseRgn(varsp
->fTextBackgroundRgn
);
239 TXNDraw(varsp
->fTXNRec
, NULL
);
240 /* restore the drawing environment */
241 /* draw the text frame and focus frame (if necessary) */
242 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
243 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
)
244 DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
245 /* release our globals */
246 HSetState((Handle
) tpvars
, state
);
252 /* TPPaneHitTestProc is called when the control manager would
253 like to determine what part of the control the mouse resides over.
254 We also call this routine from our tracking proc to determine how
255 to handle mouse clicks. */
256 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
257 STPTextPaneVars
**tpvars
;
258 ControlPartCode result
;
260 /* set up our locals and lock down our globals*/
262 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
263 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
264 state
= HGetState((Handle
) tpvars
);
265 HLock((Handle
) tpvars
);
266 /* find the region where we clicked */
267 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
268 result
= kmUPTextPart
;
270 /* release oure globals */
271 HSetState((Handle
) tpvars
, state
);
280 /* TPPaneTrackingProc is called when the mouse is being held down
281 over our control. This routine handles clicks in the text area
282 and in the scroll bar. */
283 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
284 STPTextPaneVars
**tpvars
, *varsp
;
286 ControlPartCode partCodeResult
;
287 /* make sure we have some variables... */
289 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
290 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
292 state
= HGetState((Handle
) tpvars
);
293 HLock((Handle
) tpvars
);
295 /* we don't do any of these functions unless we're in focus */
296 if ( ! varsp
->fInFocus
) {
298 owner
= GetControlOwner(theControl
);
299 ClearKeyboardFocus(owner
);
300 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
302 /* find the location for the click */
303 switch (TPPaneHitTestProc(theControl
, startPt
)) {
305 /* handle clicks in the text part */
307 { SetPort((**tpvars
).fDrawingEnvironment
);
308 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
310 TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent());
313 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
314 TXNClick( varsp
->fTXNRec
, &rec
);
321 HSetState((Handle
) tpvars
, state
);
323 return partCodeResult
;
327 /* TPPaneIdleProc is our user pane idle routine. When our text field
328 is active and in focus, we use this routine to set the cursor. */
329 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
330 STPTextPaneVars
**tpvars
, *varsp
;
332 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
333 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
334 /* if we're not active, then we have nothing to say about the cursor */
335 if ((**tpvars
).fIsActive
) {
339 /* lock down the globals */
340 state
= HGetState((Handle
) tpvars
);
341 HLock((Handle
) tpvars
);
343 /* get the current mouse coordinates (in our window) */
344 SetPortWindowPort(GetControlOwner(theControl
));
345 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
347 /* there's a 'focus thing' and an 'unfocused thing' */
348 if (varsp
->fInFocus
) {
349 /* flash the cursor */
350 SetPort((**tpvars
).fDrawingEnvironment
);
351 TXNIdle(varsp
->fTXNRec
);
353 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
355 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
356 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
361 // SetThemeCursor(kThemeArrowCursor);
364 /* if it's in our bounds, set the cursor */
365 GetControlBounds(theControl
, &bounds
);
366 if (PtInRect(mousep
, &bounds
))
368 // SetThemeCursor(kThemeArrowCursor);
372 HSetState((Handle
) tpvars
, state
);
378 /* TPPaneKeyDownProc is called whenever a keydown event is directed
379 at our control. Here, we direct the keydown event to the text
380 edit record and redraw the scroll bar and text field as appropriate. */
381 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
382 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
383 STPTextPaneVars
**tpvars
;
384 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
385 if (tpvars
!= NULL
) {
386 if ((**tpvars
).fInFocus
) {
387 /* turn autoscrolling on and send the key event to text edit */
388 SetPort((**tpvars
).fDrawingEnvironment
);
389 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
391 memset( &ev
, 0 , sizeof( ev
) ) ;
393 ev
.modifiers
= modifiers
;
394 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
395 TXNKeyDown( (**tpvars
).fTXNRec
, &ev
);
398 return kControlEntireControl
;
402 /* TPPaneActivateProc is called when the window containing
403 the user pane control receives activate events. Here, we redraw
404 the control and it's text as necessary for the activation state. */
405 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
407 STPTextPaneVars
**tpvars
, *varsp
;
410 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
411 if (tpvars
!= NULL
) {
412 state
= HGetState((Handle
) tpvars
);
413 HLock((Handle
) tpvars
);
415 /* de/activate the text edit record */
416 SetPort((**tpvars
).fDrawingEnvironment
);
417 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
418 GetControlBounds(theControl
, &bounds
);
419 varsp
->fIsActive
= activating
;
420 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
421 /* redraw the frame */
422 if ( IsControlVisible( theControl
) )
424 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
426 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
428 HSetState((Handle
) tpvars
, state
);
433 /* TPPaneFocusProc is called when every the focus changes to or
434 from our control. Herein, switch the focus appropriately
435 according to the parameters and redraw the control as
437 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
438 ControlPartCode focusResult
;
439 STPTextPaneVars
**tpvars
, *varsp
;
442 focusResult
= kControlFocusNoPart
;
443 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
444 if (tpvars
!= NULL
) {
445 state
= HGetState((Handle
) tpvars
);
446 HLock((Handle
) tpvars
);
448 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
449 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
450 and kControlFocusNextPart will be received. When the user clicks in our field
451 and it is not the current focus, then the constant kUserClickedToFocusPart will
452 be received. The constant kControlFocusNoPart will be received when our control
453 is the current focus and the user clicks in another control. In your focus routine,
454 you should respond to these codes as follows:
456 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
457 the control and the focus rectangle as necessary.
459 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
460 depending on its current state. redraw the control and the focus rectangle
461 as appropriate for the new focus state. If the focus state is 'off', return the constant
462 kControlFocusNoPart, otherwise return a non-zero part code.
463 kUserClickedToFocusPart - is a constant defined for this example. You should
464 define your own value for handling click-to-focus type events. */
465 /* calculate the next highlight state */
468 case kControlFocusNoPart
:
469 TPFocusPaneText(tpvars
, false);
470 focusResult
= kControlFocusNoPart
;
472 case kUserClickedToFocusPart
:
473 TPFocusPaneText(tpvars
, true);
476 case kControlFocusPrevPart
:
477 case kControlFocusNextPart
:
478 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
479 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
482 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
483 /* redraw the text fram and focus rectangle to indicate the
485 if ( IsControlVisible( theControl
) )
487 /* save the drawing state */
488 SetPort((**tpvars
).fDrawingEnvironment
);
489 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
490 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
491 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
494 HSetState((Handle
) tpvars
, state
);
500 /* mUPOpenControl initializes a user pane control so it will be drawn
501 and will behave as a scrolling text edit field inside of a window.
502 This routine performs all of the initialization steps necessary,
503 except it does not create the user pane control itself. theControl
504 should refer to a user pane control that you have either created
505 yourself or extracted from a dialog's control heirarchy using
506 the GetDialogItemAsControl routine. */
507 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
)
511 STPTextPaneVars
**tpvars
, *varsp
;
512 OSStatus err
= noErr
;
513 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
516 /* set up our globals */
517 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
518 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
519 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
520 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
521 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
522 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
523 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
525 /* allocate our private storage */
526 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
527 SetControlReference(theControl
, (long) tpvars
);
528 HLock((Handle
) tpvars
);
530 /* set the initial settings for our private data */
531 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
532 varsp
->fInFocus
= false;
533 varsp
->fIsActive
= true;
534 varsp
->fTEActive
= true; // in order to get a deactivate
535 varsp
->fUserPaneRec
= theControl
;
536 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
538 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
540 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
541 /* set up the user pane procedures */
542 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
543 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
544 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
545 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
546 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
547 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
548 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
549 /* calculate the rectangles used by the control */
550 GetControlBounds(theControl
, &bounds
);
551 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
552 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
553 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
554 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
555 /* calculate the background region for the text. In this case, it's kindof
556 and irregular region because we're setting the scroll bar a little ways inside
558 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
560 /* set up the drawing environment */
561 SetPort(varsp
->fDrawingEnvironment
);
563 /* create the new edit field */
565 TXNFrameOptions frameOptions
=
566 kTXNDontDrawCaretWhenInactiveMask
;
567 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
568 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
570 if ( wxStyle
& wxTE_MULTILINE
)
572 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
573 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
576 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
577 frameOptions
|= kTXNWantHScrollBarMask
;
580 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
581 frameOptions
|= kTXNWantVScrollBarMask
;
584 frameOptions
|= kTXNSingleLineOnlyMask
;
586 if ( wxStyle
& wxTE_READONLY
)
587 frameOptions
|= kTXNReadOnlyMask
;
589 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
591 kTXNTextEditStyleFrameType
,
593 kTXNSystemDefaultEncoding
,
594 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
596 if ( !IsControlVisible( theControl
) )
597 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
598 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
601 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
603 TXNControlTag tag
= kTXNWordWrapStateTag
;
605 dat
.uValue
= kTXNNoAutoWrap
;
606 TXNSetTXNObjectControls( varsp
->fTXNRec
, false , 1 , &tag
, &dat
) ;
612 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
614 TXNTypeAttributes typeAttr
[] =
616 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
617 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
618 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
621 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
624 /* set the field's background */
626 tback
.bgType
= kTXNBackgroundTypeRGB
;
627 tback
.bg
.color
= rgbWhite
;
628 TXNSetBackground( varsp
->fTXNRec
, &tback
);
630 /* unlock our storage */
631 HUnlock((Handle
) tpvars
);
632 /* perform final activations and setup for our text field. Here,
633 we assume that the window is going to be the 'active' window. */
634 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
642 #if !USE_SHARED_LIBRARY
643 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
645 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
646 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
647 EVT_CHAR(wxTextCtrl::OnChar
)
648 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
649 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
650 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
651 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
652 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
654 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
655 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
656 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
657 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
658 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
663 void wxTextCtrl::Init()
667 m_macTXNvars
= NULL
;
668 m_macUsesTXN
= false ;
673 m_maxLength
= TE_UNLIMITED_LENGTH
;
676 wxTextCtrl::~wxTextCtrl()
680 SetControlReference((ControlHandle
)m_macControl
, 0) ;
681 TXNDeleteObject((TXNObject
)m_macTXN
);
682 /* delete our private storage */
683 DisposeHandle((Handle
) m_macTXNvars
);
684 /* zero the control reference */
688 const short kVerticalMargin
= 2 ;
689 const short kHorizontalMargin
= 2 ;
691 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
694 const wxSize
& size
, long style
,
695 const wxValidator
& validator
,
696 const wxString
& name
)
700 m_macTXNvars
= NULL
;
701 m_macUsesTXN
= false ;
704 m_macUsesTXN
= ! (style
& wxTE_PASSWORD
) ;
706 m_macUsesTXN
&= (TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
) ;
708 // base initialization
709 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
712 wxSize mySize
= size
;
715 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
716 m_macVerticalBorder
= 3 ;
720 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
721 m_macVerticalBorder
= 5 ;
728 if ( mySize.y == -1 )
731 if ( m_windowStyle & wxTE_MULTILINE )
734 mySize.y += 2 * m_macVerticalBorder ;
737 MacPreControlCreate( parent
, id
, wxEmptyString
, pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
739 if ( m_windowStyle
& wxTE_MULTILINE
)
741 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
742 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
744 m_windowStyle
|= wxTE_PROCESS_ENTER
;
747 if ( m_windowStyle
& wxTE_READONLY
)
753 wxMacConvertNewlines13To10( &st
) ;
756 m_macControl
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds
, "\p" , false , 0 , 0 , 1,
757 (style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
759 ::GetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*)((TEHandle
*)&m_macTE
) , &size
) ;
766 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
767 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
768 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
769 /* create the control */
770 m_macControl
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
771 /* set up the mUP specific features and data */
772 mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle
);
774 MacPostControlCreate() ;
778 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
779 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
783 STPTextPaneVars
**tpvars
;
785 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
786 /* set the text in the record */
787 m_macTXN
= (**tpvars
).fTXNRec
;
789 TXNSetData( ((TXNObject
) m_macTXN
) , kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2,
790 kTXNStartOffset
, kTXNEndOffset
);
792 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
793 TXNSetData( ((TXNObject
) m_macTXN
) , kTXNTextData
, (void*)text
.data(), strlen( text
) ,
794 kTXNStartOffset
, kTXNEndOffset
);
796 m_macTXNvars
= tpvars
;
797 m_macUsesTXN
= true ;
798 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
799 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
805 wxString
wxTextCtrl::GetValue() const
812 err
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0,
813 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, &actualSize
) ;
816 return wxEmptyString
;
818 if ( actualSize
> 0 )
820 wxCharBuffer
buf(actualSize
) ;
821 ::GetControlData( (ControlHandle
) m_macControl
, 0,
822 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
,
823 actualSize
, buf
.data() , &actualSize
) ;
824 result
= wxString( buf
, wxConvLocal
) ;
831 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
839 actualSize
= GetHandleSize( theText
) ;
840 if ( actualSize
> 0 )
842 wxChar
*ptr
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ;
843 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
844 ptr
[actualSize
] = 0 ;
845 result
.UngetWriteBuf( actualSize
) ;
847 DisposeHandle( theText
) ;
851 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
859 actualSize
= GetHandleSize( theText
) ;
860 if ( actualSize
> 0 )
863 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
866 DisposeHandle( theText
) ;
870 wxMacConvertNewlines10To13( &result
) ;
874 void wxTextCtrl::GetSelection(long* from
, long* to
) const
878 *from
= (**((TEHandle
) m_macTE
)).selStart
;
879 *to
= (**((TEHandle
) m_macTE
)).selEnd
;
883 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
887 void wxTextCtrl::SetValue(const wxString
& str
)
890 wxMacConvertNewlines13To10( &st
) ;
893 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
894 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
898 bool formerEditable
= m_editable
;
899 if ( !formerEditable
)
902 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2 ,
903 kTXNStartOffset
, kTXNEndOffset
);
905 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
906 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)text
.data(), strlen( text
) ,
907 kTXNStartOffset
, kTXNEndOffset
);
909 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
910 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
911 if ( !formerEditable
)
912 SetEditable(formerEditable
) ;
917 void wxTextCtrl::SetMaxLength(unsigned long len
)
922 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
926 bool formerEditable
= m_editable
;
927 if ( !formerEditable
)
929 TXNTypeAttributes typeAttr
[4] ;
930 Str255 fontName
= "\pMonaco" ;
931 SInt16 fontSize
= 12 ;
932 Style fontStyle
= normal
;
934 int attrCounter
= 0 ;
935 if ( style
.HasFont() )
937 const wxFont
&font
= style
.GetFont() ;
938 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
939 fontSize
= font
.GetPointSize() ;
940 if ( font
.GetUnderlined() )
941 fontStyle
|= underline
;
942 if ( font
.GetWeight() == wxBOLD
)
944 if ( font
.GetStyle() == wxITALIC
)
945 fontStyle
|= italic
;
947 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
948 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
949 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
950 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
951 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
952 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
953 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
954 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
955 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
959 if ( style
.HasTextColour() )
961 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
962 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
963 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
964 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
968 if ( attrCounter
> 0 )
972 #endif // __WXDEBUG__
973 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
);
974 wxASSERT_MSG( status
== noErr
, wxT("Couldn't set text attributes") ) ;
976 if ( !formerEditable
)
977 SetEditable(formerEditable
) ;
982 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
984 wxTextCtrlBase::SetDefaultStyle( style
) ;
985 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
989 // Clipboard operations
990 void wxTextCtrl::Copy()
996 TECopy( ((TEHandle
) m_macTE
) ) ;
1003 ClearCurrentScrap();
1004 TXNCopy((TXNObject
)m_macTXN
);
1005 TXNConvertToPublicScrap();
1010 void wxTextCtrl::Cut()
1014 if ( !m_macUsesTXN
)
1016 TECut( ((TEHandle
) m_macTE
) ) ;
1017 ClearCurrentScrap();
1019 MacRedrawControl() ;
1023 ClearCurrentScrap();
1024 TXNCut((TXNObject
)m_macTXN
);
1025 TXNConvertToPublicScrap();
1027 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1028 event
.SetString( GetValue() ) ;
1029 event
.SetEventObject( this );
1030 GetEventHandler()->ProcessEvent(event
);
1034 void wxTextCtrl::Paste()
1038 if ( !m_macUsesTXN
)
1041 TEPaste( (TEHandle
) m_macTE
) ;
1042 MacRedrawControl() ;
1046 TXNConvertFromPublicScrap();
1047 TXNPaste((TXNObject
)m_macTXN
);
1048 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1050 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1051 event
.SetString( GetValue() ) ;
1052 event
.SetEventObject( this );
1053 GetEventHandler()->ProcessEvent(event
);
1057 bool wxTextCtrl::CanCopy() const
1059 // Can copy if there's a selection
1061 GetSelection(& from
, & to
);
1062 return (from
!= to
);
1065 bool wxTextCtrl::CanCut() const
1067 if ( !IsEditable() )
1071 // Can cut if there's a selection
1073 GetSelection(& from
, & to
);
1074 return (from
!= to
);
1077 bool wxTextCtrl::CanPaste() const
1083 OSStatus err
= noErr
;
1086 err
= GetCurrentScrap( &scrapRef
);
1087 if ( err
!= noTypeErr
&& err
!= memFullErr
)
1089 ScrapFlavorFlags flavorFlags
;
1092 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
1094 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
1104 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
1112 void wxTextCtrl::SetEditable(bool editable
)
1114 if ( editable
!= m_editable
)
1116 m_editable
= editable
;
1117 if ( !m_macUsesTXN
)
1120 UMAActivateControl( (ControlHandle
) m_macControl
) ;
1122 UMADeactivateControl((ControlHandle
) m_macControl
) ;
1126 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1127 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1128 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1133 void wxTextCtrl::SetInsertionPoint(long pos
)
1135 SetSelection( pos
, pos
) ;
1138 void wxTextCtrl::SetInsertionPointEnd()
1140 long pos
= GetLastPosition();
1141 SetInsertionPoint(pos
);
1144 long wxTextCtrl::GetInsertionPoint() const
1147 GetSelection( &begin
, &end
) ;
1151 long wxTextCtrl::GetLastPosition() const
1153 if ( !m_macUsesTXN
)
1155 return (**((TEHandle
) m_macTE
)).teLength
;
1161 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1169 actualsize
= GetHandleSize( theText
) ;
1170 DisposeHandle( theText
) ;
1176 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1178 wxString value
= str
;
1179 wxMacConvertNewlines13To10( &value
) ;
1180 if ( !m_macUsesTXN
)
1182 ControlEditTextSelectionRec selection
;
1184 selection
.selStart
= from
;
1185 selection
.selEnd
= to
;
1186 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1187 TESetSelect( from
, to
, ((TEHandle
) m_macTE
) ) ;
1188 TEDelete( ((TEHandle
) m_macTE
) ) ;
1189 TEInsert( value
, value
.Length() , ((TEHandle
) m_macTE
) ) ;
1193 bool formerEditable
= m_editable
;
1194 if ( !formerEditable
)
1196 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1197 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1199 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)value
.wc_str(), value
.Length() * 2 ,
1200 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1202 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)value
.c_str(), value
.Length(),
1203 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
) ;
1298 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2 ,
1299 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1301 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1302 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)text
.data(), strlen( text
) ,
1303 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1305 GetSelection( &dummy
, &end
) ;
1306 SetStyle( start
, end
, GetDefaultStyle() ) ;
1307 if ( !formerEditable
)
1308 SetEditable( formerEditable
) ;
1310 MacRedrawControl() ;
1313 void wxTextCtrl::AppendText(const wxString
& text
)
1315 SetInsertionPointEnd();
1319 void wxTextCtrl::Clear()
1321 if ( !m_macUsesTXN
)
1323 ::SetControlData((ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
1327 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1328 TXNClear((TXNObject
)m_macTXN
);
1333 bool wxTextCtrl::IsModified() const
1338 bool wxTextCtrl::IsEditable() const
1340 return IsEnabled() && m_editable
;
1343 bool wxTextCtrl::AcceptsFocus() const
1345 // we don't want focus if we can't be edited
1346 return /*IsEditable() && */ wxControl::AcceptsFocus();
1349 wxSize
wxTextCtrl::DoGetBestSize() const
1364 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
1366 int wText = DEFAULT_ITEM_WIDTH;
1368 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
1370 return wxSize(wText, hText);
1372 if ( m_windowStyle
& wxTE_MULTILINE
)
1376 hText
+= 2 * m_macVerticalBorder
;
1377 wText
+= 2 * m_macHorizontalBorder
;
1378 //else: for single line control everything is ok
1379 return wxSize(wText
, hText
);
1382 // ----------------------------------------------------------------------------
1384 // ----------------------------------------------------------------------------
1386 void wxTextCtrl::Undo()
1392 TXNUndo((TXNObject
)m_macTXN
);
1397 void wxTextCtrl::Redo()
1403 TXNRedo((TXNObject
)m_macTXN
);
1408 bool wxTextCtrl::CanUndo() const
1410 if ( !IsEditable() )
1416 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1421 bool wxTextCtrl::CanRedo() const
1423 if ( !IsEditable() )
1429 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1434 // Makes modifie or unmodified
1435 void wxTextCtrl::MarkDirty()
1440 void wxTextCtrl::DiscardEdits()
1445 int wxTextCtrl::GetNumberOfLines() const
1450 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1455 wxString content
= GetValue() ;
1458 for (size_t i
= 0; i
< content
.Length() ; i
++)
1460 if (content
[i
] == '\r') count
++;
1466 long wxTextCtrl::XYToPosition(long x
, long y
) const
1472 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1477 void wxTextCtrl::ShowPosition(long pos
)
1479 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1484 TXNOffset selstart
, selend
;
1485 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1486 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1487 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1488 //TODO use HIPoints for 10.3 and above
1489 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1491 OSErr theErr
= noErr
;
1492 SInt32 dv
= desired
.v
- current
.v
;
1493 SInt32 dh
= desired
.h
- current
.h
;
1494 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1495 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1496 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1502 int wxTextCtrl::GetLineLength(long lineNo
) const
1504 // TODO change this if possible to reflect real lines
1505 wxString content
= GetValue() ;
1509 for (size_t i
= 0; i
< content
.Length() ; i
++)
1511 if (count
== lineNo
)
1513 // Count chars in line then
1515 for (size_t j
= i
; j
< content
.Length(); j
++)
1518 if (content
[j
] == '\n') return count
;
1523 if (content
[i
] == '\n') count
++;
1528 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1530 // TODO change this if possible to reflect real lines
1531 wxString content
= GetValue() ;
1535 for (size_t i
= 0; i
< content
.Length() ; i
++)
1537 if (count
== lineNo
)
1539 // Add chars in line then
1542 for (size_t j
= i
; j
< content
.Length(); j
++)
1544 if (content
[j
] == '\n')
1552 if (content
[i
] == '\n') count
++;
1554 return wxEmptyString
;
1561 void wxTextCtrl::Command(wxCommandEvent
& event
)
1563 SetValue (event
.GetString());
1564 ProcessCommand (event
);
1567 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1569 // By default, load the first file into the text window.
1570 if (event
.GetNumberOfFiles() > 0)
1572 LoadFile(event
.GetFiles()[0]);
1576 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1578 int key
= event
.GetKeyCode() ;
1579 bool eat_key
= false ;
1581 if ( key
== 'c' && event
.MetaDown() )
1588 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1589 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1590 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1597 // assume that any key not processed yet is going to modify the control
1600 if ( key
== 'v' && event
.MetaDown() )
1606 if ( key
== 'x' && event
.MetaDown() )
1615 if (m_windowStyle
& wxPROCESS_ENTER
)
1617 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1618 event
.SetEventObject( this );
1619 event
.SetString( GetValue() );
1620 if ( GetEventHandler()->ProcessEvent(event
) )
1623 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1625 wxWindow
*parent
= GetParent();
1626 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1627 parent
= parent
->GetParent() ;
1629 if ( parent
&& parent
->GetDefaultItem() )
1631 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1633 if ( def
&& def
->IsEnabled() )
1635 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1636 event
.SetEventObject(def
);
1637 def
->Command(event
);
1642 // this will make wxWindows eat the ENTER key so that
1643 // we actually prevent line wrapping in a single line
1651 // always produce navigation event - even if we process TAB
1652 // ourselves the fact that we got here means that the user code
1653 // decided to skip processing of this TAB - probably to let it
1654 // do its default job.
1656 wxNavigationKeyEvent eventNav
;
1657 eventNav
.SetDirection(!event
.ShiftDown());
1658 eventNav
.SetWindowChange(event
.ControlDown());
1659 eventNav
.SetEventObject(this);
1661 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1672 // perform keystroke handling
1674 if ( m_macUsesTXN
&& wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1675 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1679 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1681 EventRecord
*ev
= &rec
;
1684 keychar
= short(ev
->message
& charCodeMask
);
1685 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1687 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1691 EventRecord
*ev
= (EventRecord
*) wxTheApp
->MacGetCurrentEvent() ;
1694 keychar
= short(ev
->message
& charCodeMask
);
1695 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1697 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1700 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1701 key
== WXK_RETURN
||
1702 key
== WXK_DELETE
||
1705 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1706 event1
.SetString( GetValue() ) ;
1707 event1
.SetEventObject( this );
1708 wxPostEvent(GetEventHandler(),event1
);
1712 void wxTextCtrl::MacSuperShown( bool show
)
1714 bool former
= m_macControlIsShown
;
1715 wxControl::MacSuperShown( show
) ;
1716 if ( (former
!= m_macControlIsShown
) && m_macUsesTXN
)
1718 if ( m_macControlIsShown
)
1719 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1720 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1722 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1723 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1727 bool wxTextCtrl::Show(bool show
)
1729 bool former
= m_macControlIsShown
;
1731 bool retval
= wxControl::Show( show
) ;
1733 if ( former
!= m_macControlIsShown
&& m_macUsesTXN
)
1735 if ( m_macControlIsShown
)
1736 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1737 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1739 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1740 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1746 // ----------------------------------------------------------------------------
1747 // standard handlers for standard edit menu events
1748 // ----------------------------------------------------------------------------
1750 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1755 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1760 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1765 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1770 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1775 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1777 event
.Enable( CanCut() );
1780 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1782 event
.Enable( CanCopy() );
1785 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1787 event
.Enable( CanPaste() );
1790 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1792 event
.Enable( CanUndo() );
1795 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1797 event
.Enable( CanRedo() );
1800 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1805 return wxWindow::MacSetupCursor( pt
) ;