1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
21 #include <sys/types.h>
27 #if wxUSE_STD_IOSTREAM
37 #include "wx/button.h"
38 #include "wx/toplevel.h"
39 #include "wx/textctrl.h"
40 #include "wx/notebook.h"
41 #include "wx/tabctrl.h"
42 #include "wx/settings.h"
43 #include "wx/filefn.h"
46 #if defined(__BORLANDC__) && !defined(__WIN32__)
48 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
55 #include <MacTextEditor.h>
56 #include "ATSUnicode.h"
57 #include "TextCommon.h"
58 #include "TextEncodingConverter.h"
59 #include "wx/mac/uma.h"
61 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
63 extern wxControl
*wxFindControlFromMacControl(ControlHandle inControl
) ;
65 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
66 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
67 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
68 // an alternate path for carbon key events that routes automatically into the same wx flow of events
70 #include "MacTextEditor.h"
74 /* kmUPTextPart is the part code we return to indicate the user has clicked
75 in the text area of our control */
76 #define kmUPTextPart 1
78 /* kmUPScrollPart is the part code we return to indicate the user has clicked
79 in the scroll bar part of the control. */
80 #define kmUPScrollPart 2
83 /* routines for using existing user pane controls.
84 These routines are useful for cases where you would like to use an
85 existing user pane control in, say, a dialog window as a scrolling
88 /* mUPOpenControl initializes a user pane control so it will be drawn
89 and will behave as a scrolling text edit field inside of a window.
90 This routine performs all of the initialization steps necessary,
91 except it does not create the user pane control itself. theControl
92 should refer to a user pane control that you have either created
93 yourself or extracted from a dialog's control heirarchy using
94 the GetDialogItemAsControl routine. */
95 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
);
97 /* Utility Routines */
103 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
104 routine. In our focus switching routine this part code is understood
105 as meaning 'the user has clicked in the control and we need to switch
106 the current focus to ourselves before we can continue'. */
107 #define kUserClickedToFocusPart 100
110 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
111 slow the speed of 'auto scrolling' inside of our clickloop routine.
112 This value prevents the text from wizzzzzing by while the mouse
113 is being held down inside of the text area. */
114 #define kmUPClickScrollDelayTicks 3
117 /* STPTextPaneVars is a structure used for storing the the mUP Control's
118 internal variables and state information. A handle to this record is
119 stored in the pane control's reference value field using the
120 SetControlReference routine. */
123 /* OS records referenced */
124 TXNObject fTXNRec
; /* the txn record */
125 TXNFrameID fTXNFrame
; /* the txn frame ID */
126 ControlHandle fUserPaneRec
; /* handle to the user pane control */
127 WindowPtr fOwner
; /* window containing control */
128 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
130 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
131 Boolean fIsActive
; /* true while the control is drawn in the active state */
132 Boolean fTEActive
; /* reflects the activation state of the text edit record */
133 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
134 /* calculated locations */
135 Rect fRTextArea
; /* area where the text is drawn */
136 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
137 Rect fRTextOutline
; /* rectangle used to draw the border */
138 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
139 /* our focus advance override routine */
140 EventHandlerUPP handlerUPP
;
141 EventHandlerRef handlerRef
;
148 /* Univerals Procedure Pointer variables used by the
149 mUP Control. These variables are set up
150 the first time that mUPOpenControl is called. */
151 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
152 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
153 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
154 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
155 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
156 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
157 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
159 /* TPActivatePaneText activates or deactivates the text edit record
160 according to the value of setActive. The primary purpose of this
161 routine is to ensure each call is only made once. */
162 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
163 STPTextPaneVars
*varsp
;
165 if (varsp
->fTEActive
!= setActive
) {
167 varsp
->fTEActive
= setActive
;
169 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
172 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
177 /* TPFocusPaneText set the focus state for the text record. */
178 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
179 STPTextPaneVars
*varsp
;
181 if (varsp
->fInFocus
!= setFocus
) {
182 varsp
->fInFocus
= setFocus
;
183 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
188 /* TPPaneDrawProc is called to redraw the control and for update events
189 referring to the control. This routine erases the text area's background,
190 and redraws the text. This routine assumes the scroll bar has been
191 redrawn by a call to DrawControls. */
192 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
193 STPTextPaneVars
**tpvars
, *varsp
;
196 /* set up our globals */
198 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
199 if (tpvars
!= NULL
) {
200 state
= HGetState((Handle
) tpvars
);
201 HLock((Handle
) tpvars
);
204 /* save the drawing state */
205 SetPort((**tpvars
).fDrawingEnvironment
);
206 /* verify our boundary */
207 GetControlBounds(theControl
, &bounds
);
209 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
210 if ( ! EqualRect(&bounds
, &varsp
->fRFocusOutline
) ) {
211 // scrollbar is on the border, we add one
212 Rect oldbounds
= varsp
->fRFocusOutline
;
213 InsetRect( &oldbounds
, -1 , -1 ) ;
215 if ( IsControlVisible( theControl
) )
216 InvalWindowRect( GetControlOwner( theControl
) , &oldbounds
) ;
217 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
218 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
219 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
220 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
221 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
222 if ( IsControlVisible( theControl
) )
223 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
224 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
226 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
227 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
231 if ( IsControlVisible( theControl
) )
233 /* update the text region */
234 RGBColor white
= { 65535 , 65535 , 65535 } ;
235 RGBBackColor( &white
) ;
236 EraseRgn(varsp
->fTextBackgroundRgn
);
237 TXNDraw(varsp
->fTXNRec
, NULL
);
238 /* restore the drawing environment */
239 /* draw the text frame and focus frame (if necessary) */
240 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
241 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
)
242 DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
243 /* release our globals */
244 HSetState((Handle
) tpvars
, state
);
250 /* TPPaneHitTestProc is called when the control manager would
251 like to determine what part of the control the mouse resides over.
252 We also call this routine from our tracking proc to determine how
253 to handle mouse clicks. */
254 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
255 STPTextPaneVars
**tpvars
;
256 ControlPartCode result
;
258 /* set up our locals and lock down our globals*/
260 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
261 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
262 state
= HGetState((Handle
) tpvars
);
263 HLock((Handle
) tpvars
);
264 /* find the region where we clicked */
265 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
266 result
= kmUPTextPart
;
268 /* release oure globals */
269 HSetState((Handle
) tpvars
, state
);
278 /* TPPaneTrackingProc is called when the mouse is being held down
279 over our control. This routine handles clicks in the text area
280 and in the scroll bar. */
281 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
282 STPTextPaneVars
**tpvars
, *varsp
;
284 ControlPartCode partCodeResult
;
285 /* make sure we have some variables... */
287 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
288 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
290 state
= HGetState((Handle
) tpvars
);
291 HLock((Handle
) tpvars
);
293 /* we don't do any of these functions unless we're in focus */
294 if ( ! varsp
->fInFocus
) {
296 owner
= GetControlOwner(theControl
);
297 ClearKeyboardFocus(owner
);
298 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
300 /* find the location for the click */
301 switch (TPPaneHitTestProc(theControl
, startPt
)) {
303 /* handle clicks in the text part */
305 { SetPort((**tpvars
).fDrawingEnvironment
);
306 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
308 TXNClick( varsp
->fTXNRec
, (const EventRecord
*) wxTheApp
->MacGetCurrentEvent());
311 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
312 TXNClick( varsp
->fTXNRec
, &rec
);
319 HSetState((Handle
) tpvars
, state
);
321 return partCodeResult
;
325 /* TPPaneIdleProc is our user pane idle routine. When our text field
326 is active and in focus, we use this routine to set the cursor. */
327 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
328 STPTextPaneVars
**tpvars
, *varsp
;
330 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
331 if (tpvars
!= NULL
&& IsControlVisible( theControl
) ) {
332 /* if we're not active, then we have nothing to say about the cursor */
333 if ((**tpvars
).fIsActive
) {
337 /* lock down the globals */
338 state
= HGetState((Handle
) tpvars
);
339 HLock((Handle
) tpvars
);
341 /* get the current mouse coordinates (in our window) */
342 SetPortWindowPort(GetControlOwner(theControl
));
343 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
345 /* there's a 'focus thing' and an 'unfocused thing' */
346 if (varsp
->fInFocus
) {
347 /* flash the cursor */
348 SetPort((**tpvars
).fDrawingEnvironment
);
349 TXNIdle(varsp
->fTXNRec
);
351 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
353 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
354 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
359 // SetThemeCursor(kThemeArrowCursor);
362 /* if it's in our bounds, set the cursor */
363 GetControlBounds(theControl
, &bounds
);
364 if (PtInRect(mousep
, &bounds
))
366 // SetThemeCursor(kThemeArrowCursor);
370 HSetState((Handle
) tpvars
, state
);
376 /* TPPaneKeyDownProc is called whenever a keydown event is directed
377 at our control. Here, we direct the keydown event to the text
378 edit record and redraw the scroll bar and text field as appropriate. */
379 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
380 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
381 STPTextPaneVars
**tpvars
;
382 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
383 if (tpvars
!= NULL
) {
384 if ((**tpvars
).fInFocus
) {
385 /* turn autoscrolling on and send the key event to text edit */
386 SetPort((**tpvars
).fDrawingEnvironment
);
387 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
389 memset( &ev
, 0 , sizeof( ev
) ) ;
391 ev
.modifiers
= modifiers
;
392 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
393 TXNKeyDown( (**tpvars
).fTXNRec
, &ev
);
396 return kControlEntireControl
;
400 /* TPPaneActivateProc is called when the window containing
401 the user pane control receives activate events. Here, we redraw
402 the control and it's text as necessary for the activation state. */
403 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
405 STPTextPaneVars
**tpvars
, *varsp
;
408 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
409 if (tpvars
!= NULL
) {
410 state
= HGetState((Handle
) tpvars
);
411 HLock((Handle
) tpvars
);
413 /* de/activate the text edit record */
414 SetPort((**tpvars
).fDrawingEnvironment
);
415 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
416 GetControlBounds(theControl
, &bounds
);
417 varsp
->fIsActive
= activating
;
418 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
419 /* redraw the frame */
420 if ( IsControlVisible( theControl
) )
422 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
424 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
426 HSetState((Handle
) tpvars
, state
);
431 /* TPPaneFocusProc is called when every the focus changes to or
432 from our control. Herein, switch the focus appropriately
433 according to the parameters and redraw the control as
435 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
436 ControlPartCode focusResult
;
437 STPTextPaneVars
**tpvars
, *varsp
;
440 focusResult
= kControlFocusNoPart
;
441 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
442 if (tpvars
!= NULL
) {
443 state
= HGetState((Handle
) tpvars
);
444 HLock((Handle
) tpvars
);
446 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
447 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
448 and kControlFocusNextPart will be received. When the user clicks in our field
449 and it is not the current focus, then the constant kUserClickedToFocusPart will
450 be received. The constant kControlFocusNoPart will be received when our control
451 is the current focus and the user clicks in another control. In your focus routine,
452 you should respond to these codes as follows:
454 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
455 the control and the focus rectangle as necessary.
457 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
458 depending on its current state. redraw the control and the focus rectangle
459 as appropriate for the new focus state. If the focus state is 'off', return the constant
460 kControlFocusNoPart, otherwise return a non-zero part code.
461 kUserClickedToFocusPart - is a constant defined for this example. You should
462 define your own value for handling click-to-focus type events. */
463 /* calculate the next highlight state */
466 case kControlFocusNoPart
:
467 TPFocusPaneText(tpvars
, false);
468 focusResult
= kControlFocusNoPart
;
470 case kUserClickedToFocusPart
:
471 TPFocusPaneText(tpvars
, true);
474 case kControlFocusPrevPart
:
475 case kControlFocusNextPart
:
476 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
477 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
480 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
481 /* redraw the text fram and focus rectangle to indicate the
483 if ( IsControlVisible( theControl
) )
485 /* save the drawing state */
486 SetPort((**tpvars
).fDrawingEnvironment
);
487 wxMacWindowClipper
clipper( wxFindControlFromMacControl(theControl
) ) ;
488 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
489 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
492 HSetState((Handle
) tpvars
, state
);
498 /* mUPOpenControl initializes a user pane control so it will be drawn
499 and will behave as a scrolling text edit field inside of a window.
500 This routine performs all of the initialization steps necessary,
501 except it does not create the user pane control itself. theControl
502 should refer to a user pane control that you have either created
503 yourself or extracted from a dialog's control heirarchy using
504 the GetDialogItemAsControl routine. */
505 OSStatus
mUPOpenControl(ControlHandle theControl
, long wxStyle
)
509 STPTextPaneVars
**tpvars
, *varsp
;
510 OSStatus err
= noErr
;
511 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
514 /* set up our globals */
515 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
516 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
517 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
518 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
519 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
520 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
521 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
523 /* allocate our private storage */
524 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
525 SetControlReference(theControl
, (long) tpvars
);
526 HLock((Handle
) tpvars
);
528 /* set the initial settings for our private data */
529 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
530 varsp
->fInFocus
= false;
531 varsp
->fIsActive
= true;
532 varsp
->fTEActive
= true; // in order to get a deactivate
533 varsp
->fUserPaneRec
= theControl
;
534 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
536 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
538 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
539 /* set up the user pane procedures */
540 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
541 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
542 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
543 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
544 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
545 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
546 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
547 /* calculate the rectangles used by the control */
548 GetControlBounds(theControl
, &bounds
);
549 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
550 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
551 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
552 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
553 /* calculate the background region for the text. In this case, it's kindof
554 and irregular region because we're setting the scroll bar a little ways inside
556 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
558 /* set up the drawing environment */
559 SetPort(varsp
->fDrawingEnvironment
);
561 /* create the new edit field */
563 TXNFrameOptions frameOptions
=
564 kTXNDontDrawCaretWhenInactiveMask
;
565 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
566 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
568 if ( wxStyle
& wxTE_MULTILINE
)
570 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
571 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
574 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
575 frameOptions
|= kTXNWantHScrollBarMask
;
578 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
579 frameOptions
|= kTXNWantVScrollBarMask
;
582 frameOptions
|= kTXNSingleLineOnlyMask
;
584 if ( wxStyle
& wxTE_READONLY
)
585 frameOptions
|= kTXNReadOnlyMask
;
587 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
589 kTXNTextEditStyleFrameType
,
591 kTXNSystemDefaultEncoding
,
592 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
594 if ( !IsControlVisible( theControl
) )
595 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
+ 30000 , varsp
->fRTextArea
.left
+ 30000 ,
596 varsp
->fRTextArea
.bottom
+ 30000 , varsp
->fRTextArea
.right
+ 30000 , varsp
->fTXNFrame
);
599 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
601 TXNControlTag tag
= kTXNWordWrapStateTag
;
603 dat
.uValue
= kTXNNoAutoWrap
;
604 TXNSetTXNObjectControls( varsp
->fTXNRec
, false , 1 , &tag
, &dat
) ;
610 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
612 TXNTypeAttributes typeAttr
[] =
614 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
615 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
616 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
619 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
622 /* set the field's background */
624 tback
.bgType
= kTXNBackgroundTypeRGB
;
625 tback
.bg
.color
= rgbWhite
;
626 TXNSetBackground( varsp
->fTXNRec
, &tback
);
628 /* unlock our storage */
629 HUnlock((Handle
) tpvars
);
630 /* perform final activations and setup for our text field. Here,
631 we assume that the window is going to be the 'active' window. */
632 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
640 #if !USE_SHARED_LIBRARY
641 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
643 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
644 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
645 EVT_CHAR(wxTextCtrl::OnChar
)
646 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
647 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
648 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
649 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
650 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
652 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
653 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
654 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
655 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
656 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
661 void wxTextCtrl::Init()
665 m_macTXNvars
= NULL
;
666 m_macUsesTXN
= false ;
671 m_maxLength
= TE_UNLIMITED_LENGTH
;
674 wxTextCtrl::~wxTextCtrl()
678 SetControlReference((ControlHandle
)m_macControl
, 0) ;
679 TXNDeleteObject((TXNObject
)m_macTXN
);
680 /* delete our private storage */
681 DisposeHandle((Handle
) m_macTXNvars
);
682 /* zero the control reference */
686 const short kVerticalMargin
= 2 ;
687 const short kHorizontalMargin
= 2 ;
689 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
692 const wxSize
& size
, long style
,
693 const wxValidator
& validator
,
694 const wxString
& name
)
698 m_macTXNvars
= NULL
;
699 m_macUsesTXN
= false ;
702 m_macUsesTXN
= ! (style
& wxTE_PASSWORD
) ;
704 m_macUsesTXN
&= (TXNInitTextension
!= (void*) kUnresolvedCFragSymbolAddress
) ;
706 // base initialization
707 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
710 wxSize mySize
= size
;
713 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
714 m_macVerticalBorder
= 3 ;
718 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
719 m_macVerticalBorder
= 5 ;
726 if ( mySize.y == -1 )
729 if ( m_windowStyle & wxTE_MULTILINE )
732 mySize.y += 2 * m_macVerticalBorder ;
735 MacPreControlCreate( parent
, id
, wxEmptyString
, pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
737 if ( m_windowStyle
& wxTE_MULTILINE
)
739 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
740 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
742 m_windowStyle
|= wxTE_PROCESS_ENTER
;
745 if ( m_windowStyle
& wxTE_READONLY
)
751 st
.Replace(wxT("\n"), wxT("\r"));
754 m_macControl
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds
, "\p" , false , 0 , 0 , 1,
755 (style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
757 ::GetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*)((TEHandle
*)&m_macTE
) , &size
) ;
764 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
765 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
766 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
767 /* create the control */
768 m_macControl
= NewControl(MAC_WXHWND(parent
->MacGetRootWindow()), &bounds
, "\p", false , featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
769 /* set up the mUP specific features and data */
770 mUPOpenControl((ControlHandle
) m_macControl
, m_windowStyle
);
772 MacPostControlCreate() ;
776 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
777 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
781 STPTextPaneVars
**tpvars
;
783 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
784 /* set the text in the record */
785 m_macTXN
= (**tpvars
).fTXNRec
;
787 TXNSetData( ((TXNObject
) m_macTXN
) , kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2,
788 kTXNStartOffset
, kTXNEndOffset
);
790 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
791 TXNSetData( ((TXNObject
) m_macTXN
) , kTXNTextData
, (void*)text
.data(), strlen( text
) ,
792 kTXNStartOffset
, kTXNEndOffset
);
794 m_macTXNvars
= tpvars
;
795 m_macUsesTXN
= true ;
796 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
797 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
803 wxString
wxTextCtrl::GetValue() const
810 err
= ::GetControlDataSize((ControlHandle
) m_macControl
, 0,
811 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, &actualSize
) ;
814 return wxEmptyString
;
816 if ( actualSize
> 0 )
818 wxCharBuffer
buf(actualSize
) ;
819 ::GetControlData( (ControlHandle
) m_macControl
, 0,
820 ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
,
821 actualSize
, buf
.data() , &actualSize
) ;
822 result
= wxString( buf
, wxConvLocal
) ;
829 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
837 actualSize
= GetHandleSize( theText
) ;
838 if ( actualSize
> 0 )
840 wxChar
*ptr
= result
.GetWriteBuf(actualSize
*sizeof(wxChar
)) ;
841 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
842 ptr
[actualSize
] = 0 ;
843 result
.UngetWriteBuf( actualSize
) ;
845 DisposeHandle( theText
) ;
849 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
857 actualSize
= GetHandleSize( theText
) ;
858 if ( actualSize
> 0 )
861 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
864 DisposeHandle( theText
) ;
868 result
.Replace(wxT("\r"),wxT("\n")) ;
872 void wxTextCtrl::GetSelection(long* from
, long* to
) const
876 *from
= (**((TEHandle
) m_macTE
)).selStart
;
877 *to
= (**((TEHandle
) m_macTE
)).selEnd
;
881 TXNGetSelection( ((TXNObject
) m_macTXN
) , (TXNOffset
*) from
, (TXNOffset
*) to
) ;
885 void wxTextCtrl::SetValue(const wxString
& str
)
888 st
.Replace(wxT("\n"), wxT("\r"));
891 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
892 ::SetControlData( (ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, strlen(text
) , text
) ;
896 bool formerEditable
= m_editable
;
897 if ( !formerEditable
)
900 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2 ,
901 kTXNStartOffset
, kTXNEndOffset
);
903 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
904 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)text
.data(), strlen( text
) ,
905 kTXNStartOffset
, kTXNEndOffset
);
907 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
908 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
909 if ( !formerEditable
)
910 SetEditable(formerEditable
) ;
915 void wxTextCtrl::SetMaxLength(unsigned long len
)
920 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
924 bool formerEditable
= m_editable
;
925 if ( !formerEditable
)
927 TXNTypeAttributes typeAttr
[4] ;
928 Str255 fontName
= "\pMonaco" ;
929 SInt16 fontSize
= 12 ;
930 Style fontStyle
= normal
;
932 int attrCounter
= 0 ;
933 if ( style
.HasFont() )
935 const wxFont
&font
= style
.GetFont() ;
936 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
937 fontSize
= font
.GetPointSize() ;
938 if ( font
.GetUnderlined() )
939 fontStyle
|= underline
;
940 if ( font
.GetWeight() == wxBOLD
)
942 if ( font
.GetStyle() == wxITALIC
)
943 fontStyle
|= italic
;
945 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
946 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
947 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
948 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
949 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
950 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
951 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
952 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
953 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
957 if ( style
.HasTextColour() )
959 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
960 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
961 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
962 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
966 if ( attrCounter
> 0 )
970 #endif // __WXDEBUG__
971 TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
);
972 wxASSERT_MSG( status
== noErr
, wxT("Couldn't set text attributes") ) ;
974 if ( !formerEditable
)
975 SetEditable(formerEditable
) ;
980 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
982 wxTextCtrlBase::SetDefaultStyle( style
) ;
983 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
987 // Clipboard operations
988 void wxTextCtrl::Copy()
994 TECopy( ((TEHandle
) m_macTE
) ) ;
1001 ClearCurrentScrap();
1002 TXNCopy((TXNObject
)m_macTXN
);
1003 TXNConvertToPublicScrap();
1008 void wxTextCtrl::Cut()
1012 if ( !m_macUsesTXN
)
1014 TECut( ((TEHandle
) m_macTE
) ) ;
1015 ClearCurrentScrap();
1017 MacRedrawControl() ;
1021 ClearCurrentScrap();
1022 TXNCut((TXNObject
)m_macTXN
);
1023 TXNConvertToPublicScrap();
1025 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1026 event
.SetString( GetValue() ) ;
1027 event
.SetEventObject( this );
1028 GetEventHandler()->ProcessEvent(event
);
1032 void wxTextCtrl::Paste()
1036 if ( !m_macUsesTXN
)
1039 TEPaste( (TEHandle
) m_macTE
) ;
1040 MacRedrawControl() ;
1044 TXNConvertFromPublicScrap();
1045 TXNPaste((TXNObject
)m_macTXN
);
1046 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1048 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1049 event
.SetString( GetValue() ) ;
1050 event
.SetEventObject( this );
1051 GetEventHandler()->ProcessEvent(event
);
1055 bool wxTextCtrl::CanCopy() const
1057 // Can copy if there's a selection
1059 GetSelection(& from
, & to
);
1060 return (from
!= to
);
1063 bool wxTextCtrl::CanCut() const
1065 if ( !IsEditable() )
1069 // Can cut if there's a selection
1071 GetSelection(& from
, & to
);
1072 return (from
!= to
);
1075 bool wxTextCtrl::CanPaste() const
1081 OSStatus err
= noErr
;
1084 err
= GetCurrentScrap( &scrapRef
);
1085 if ( err
!= noTypeErr
&& err
!= memFullErr
)
1087 ScrapFlavorFlags flavorFlags
;
1090 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
1092 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
1102 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
1110 void wxTextCtrl::SetEditable(bool editable
)
1112 if ( editable
!= m_editable
)
1114 m_editable
= editable
;
1115 if ( !m_macUsesTXN
)
1118 UMAActivateControl( (ControlHandle
) m_macControl
) ;
1120 UMADeactivateControl((ControlHandle
) m_macControl
) ;
1124 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1125 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1126 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1131 void wxTextCtrl::SetInsertionPoint(long pos
)
1133 SetSelection( pos
, pos
) ;
1136 void wxTextCtrl::SetInsertionPointEnd()
1138 long pos
= GetLastPosition();
1139 SetInsertionPoint(pos
);
1142 long wxTextCtrl::GetInsertionPoint() const
1145 GetSelection( &begin
, &end
) ;
1149 long wxTextCtrl::GetLastPosition() const
1151 if ( !m_macUsesTXN
)
1153 return (**((TEHandle
) m_macTE
)).teLength
;
1159 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1167 actualsize
= GetHandleSize( theText
) ;
1168 DisposeHandle( theText
) ;
1174 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1176 wxString value
= str
;
1177 value
.Replace(wxT("\n"), wxT("\r"));
1178 if ( !m_macUsesTXN
)
1180 ControlEditTextSelectionRec selection
;
1182 selection
.selStart
= from
;
1183 selection
.selEnd
= to
;
1184 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1185 TESetSelect( from
, to
, ((TEHandle
) m_macTE
) ) ;
1186 TEDelete( ((TEHandle
) m_macTE
) ) ;
1187 TEInsert( value
, value
.Length() , ((TEHandle
) m_macTE
) ) ;
1191 bool formerEditable
= m_editable
;
1192 if ( !formerEditable
)
1194 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1195 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1197 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)value
.wc_str(), value
.Length() * 2 ,
1198 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1200 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)value
.c_str(), value
.Length(),
1201 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1203 if ( !formerEditable
)
1204 SetEditable( formerEditable
) ;
1209 void wxTextCtrl::Remove(long from
, long to
)
1211 if ( !m_macUsesTXN
)
1213 ControlEditTextSelectionRec selection
;
1215 selection
.selStart
= from
;
1216 selection
.selEnd
= to
;
1217 ::SetControlData( (ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1218 TEDelete( ((TEHandle
) m_macTE
) ) ;
1222 bool formerEditable
= m_editable
;
1223 if ( !formerEditable
)
1225 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1226 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1227 if ( !formerEditable
)
1228 SetEditable( formerEditable
) ;
1233 void wxTextCtrl::SetSelection(long from
, long to
)
1235 if ( !m_macUsesTXN
)
1237 ControlEditTextSelectionRec selection
;
1238 if ((from
== -1) && (to
== -1))
1240 selection
.selStart
= 0 ;
1241 selection
.selEnd
= 32767 ;
1245 selection
.selStart
= from
;
1246 selection
.selEnd
= to
;
1249 TESetSelect( selection
.selStart
, selection
.selEnd
, ((TEHandle
) m_macTE
) ) ;
1250 ::SetControlData((ControlHandle
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
1254 STPTextPaneVars
**tpvars
;
1255 /* set up our locals */
1256 tpvars
= (STPTextPaneVars
**) GetControlReference((ControlHandle
) m_macControl
);
1257 /* and our drawing environment as the operation
1258 may force a redraw in the text area. */
1259 SetPort((**tpvars
).fDrawingEnvironment
);
1260 /* change the selection */
1261 if ((from
== -1) && (to
== -1))
1262 TXNSelectAll((TXNObject
) m_macTXN
);
1264 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
1265 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1269 bool wxTextCtrl::LoadFile(const wxString
& file
)
1271 if ( wxTextCtrlBase::LoadFile(file
) )
1279 void wxTextCtrl::WriteText(const wxString
& str
)
1282 st
.Replace(wxT("\n"), wxT("\r"));
1283 if ( !m_macUsesTXN
)
1285 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1286 TEInsert( text
, strlen(text
) , ((TEHandle
) m_macTE
) ) ;
1290 bool formerEditable
= m_editable
;
1291 if ( !formerEditable
)
1293 long start
, end
, dummy
;
1294 GetSelection( &start
, &dummy
) ;
1296 TXNSetData( ((TXNObject
) m_macTXN
), kTXNUnicodeTextData
, (void*)st
.wc_str(), st
.Length() * 2 ,
1297 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1299 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
1300 TXNSetData( ((TXNObject
) m_macTXN
), kTXNTextData
, (void*)text
.data(), strlen( text
) ,
1301 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1303 GetSelection( &dummy
, &end
) ;
1304 SetStyle( start
, end
, GetDefaultStyle() ) ;
1305 if ( !formerEditable
)
1306 SetEditable( formerEditable
) ;
1308 MacRedrawControl() ;
1311 void wxTextCtrl::AppendText(const wxString
& text
)
1313 SetInsertionPointEnd();
1317 void wxTextCtrl::Clear()
1319 if ( !IsEditable() )
1323 if ( !m_macUsesTXN
)
1325 ::SetControlData((ControlHandle
) m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
1329 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1330 TXNClear((TXNObject
)m_macTXN
);
1335 bool wxTextCtrl::IsModified() const
1340 bool wxTextCtrl::IsEditable() const
1342 return IsEnabled() && m_editable
;
1345 bool wxTextCtrl::AcceptsFocus() const
1347 // we don't want focus if we can't be edited
1348 return /*IsEditable() && */ wxControl::AcceptsFocus();
1351 wxSize
wxTextCtrl::DoGetBestSize() const
1366 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
1368 int wText = DEFAULT_ITEM_WIDTH;
1370 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
1372 return wxSize(wText, hText);
1374 if ( m_windowStyle
& wxTE_MULTILINE
)
1378 hText
+= 2 * m_macVerticalBorder
;
1379 wText
+= 2 * m_macHorizontalBorder
;
1380 //else: for single line control everything is ok
1381 return wxSize(wText
, hText
);
1384 // ----------------------------------------------------------------------------
1386 // ----------------------------------------------------------------------------
1388 void wxTextCtrl::Undo()
1394 TXNUndo((TXNObject
)m_macTXN
);
1399 void wxTextCtrl::Redo()
1405 TXNRedo((TXNObject
)m_macTXN
);
1410 bool wxTextCtrl::CanUndo() const
1412 if ( !IsEditable() )
1418 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1423 bool wxTextCtrl::CanRedo() const
1425 if ( !IsEditable() )
1431 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1436 // Makes 'unmodified'
1437 void wxTextCtrl::DiscardEdits()
1442 int wxTextCtrl::GetNumberOfLines() const
1444 // TODO change this if possible to reflect real lines
1445 wxString content
= GetValue() ;
1448 for (size_t i
= 0; i
< content
.Length() ; i
++)
1450 if (content
[i
] == '\r') count
++;
1456 long wxTextCtrl::XYToPosition(long x
, long y
) const
1462 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1467 void wxTextCtrl::ShowPosition(long pos
)
1472 int wxTextCtrl::GetLineLength(long lineNo
) const
1474 // TODO change this if possible to reflect real lines
1475 wxString content
= GetValue() ;
1479 for (size_t i
= 0; i
< content
.Length() ; i
++)
1481 if (count
== lineNo
)
1483 // Count chars in line then
1485 for (size_t j
= i
; j
< content
.Length(); j
++)
1488 if (content
[j
] == '\n') return count
;
1493 if (content
[i
] == '\n') count
++;
1498 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1500 // TODO change this if possible to reflect real lines
1501 wxString content
= GetValue() ;
1505 for (size_t i
= 0; i
< content
.Length() ; i
++)
1507 if (count
== lineNo
)
1509 // Add chars in line then
1512 for (size_t j
= i
; j
< content
.Length(); j
++)
1514 if (content
[j
] == '\n')
1522 if (content
[i
] == '\n') count
++;
1524 return wxEmptyString
;
1531 void wxTextCtrl::Command(wxCommandEvent
& event
)
1533 SetValue (event
.GetString());
1534 ProcessCommand (event
);
1537 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1539 // By default, load the first file into the text window.
1540 if (event
.GetNumberOfFiles() > 0)
1542 LoadFile(event
.GetFiles()[0]);
1546 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1548 int key
= event
.GetKeyCode() ;
1549 bool eat_key
= false ;
1551 if ( key
== 'c' && event
.MetaDown() )
1558 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1559 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1560 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1567 // assume that any key not processed yet is going to modify the control
1570 if ( key
== 'v' && event
.MetaDown() )
1576 if ( key
== 'x' && event
.MetaDown() )
1585 if (m_windowStyle
& wxPROCESS_ENTER
)
1587 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1588 event
.SetEventObject( this );
1589 event
.SetString( GetValue() );
1590 if ( GetEventHandler()->ProcessEvent(event
) )
1593 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1595 wxWindow
*parent
= GetParent();
1596 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1597 parent
= parent
->GetParent() ;
1599 if ( parent
&& parent
->GetDefaultItem() )
1601 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1603 if ( def
&& def
->IsEnabled() )
1605 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1606 event
.SetEventObject(def
);
1607 def
->Command(event
);
1612 // this will make wxWindows eat the ENTER key so that
1613 // we actually prevent line wrapping in a single line
1621 // always produce navigation event - even if we process TAB
1622 // ourselves the fact that we got here means that the user code
1623 // decided to skip processing of this TAB - probably to let it
1624 // do its default job.
1626 wxNavigationKeyEvent eventNav
;
1627 eventNav
.SetDirection(!event
.ShiftDown());
1628 eventNav
.SetWindowChange(event
.ControlDown());
1629 eventNav
.SetEventObject(this);
1631 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1642 // perform keystroke handling
1644 if ( m_macUsesTXN
&& wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1645 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1649 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1651 EventRecord
*ev
= &rec
;
1654 keychar
= short(ev
->message
& charCodeMask
);
1655 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1657 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1661 EventRecord
*ev
= (EventRecord
*) wxTheApp
->MacGetCurrentEvent() ;
1664 keychar
= short(ev
->message
& charCodeMask
);
1665 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1667 ::HandleControlKey( (ControlHandle
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1670 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1671 key
== WXK_RETURN
||
1672 key
== WXK_DELETE
||
1675 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1676 event1
.SetString( GetValue() ) ;
1677 event1
.SetEventObject( this );
1678 wxPostEvent(GetEventHandler(),event1
);
1682 void wxTextCtrl::MacSuperShown( bool show
)
1684 bool former
= m_macControlIsShown
;
1685 wxControl::MacSuperShown( show
) ;
1686 if ( (former
!= m_macControlIsShown
) && m_macUsesTXN
)
1688 if ( m_macControlIsShown
)
1689 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1690 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1692 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1693 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1697 bool wxTextCtrl::Show(bool show
)
1699 bool former
= m_macControlIsShown
;
1701 bool retval
= wxControl::Show( show
) ;
1703 if ( former
!= m_macControlIsShown
&& m_macUsesTXN
)
1705 if ( m_macControlIsShown
)
1706 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1707 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
,(**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1709 TXNSetFrameBounds( (TXNObject
) m_macTXN
, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.top
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.left
,
1710 (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.bottom
+ 30000, (**(STPTextPaneVars
**)m_macTXNvars
).fRTextArea
.right
, (**(STPTextPaneVars
**)m_macTXNvars
).fTXNFrame
);
1716 // ----------------------------------------------------------------------------
1717 // standard handlers for standard edit menu events
1718 // ----------------------------------------------------------------------------
1720 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1725 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1730 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1735 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1740 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1745 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1747 event
.Enable( CanCut() );
1750 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1752 event
.Enable( CanCopy() );
1755 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1757 event
.Enable( CanPaste() );
1760 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1762 event
.Enable( CanUndo() );
1765 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1767 event
.Enable( CanRedo() );
1770 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1775 return wxWindow::MacSetupCursor( pt
) ;